• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  * rtl871x_mlme.c
3  *
4  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5  * Linux device driver for RTL8192SU
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of version 2 of the GNU General Public License as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19  *
20  * Modifications for inclusion into the Linux staging tree are
21  * Copyright(c) 2010 Larry Finger. All rights reserved.
22  *
23  * Contact information:
24  * WLAN FAE <wlanfae@realtek.com>
25  * Larry Finger <Larry.Finger@lwfinger.net>
26  *
27  ******************************************************************************/
28 
29 #define _RTL871X_MLME_C_
30 
31 #include <linux/etherdevice.h>
32 
33 #include "osdep_service.h"
34 #include "drv_types.h"
35 #include "recv_osdep.h"
36 #include "xmit_osdep.h"
37 #include "mlme_osdep.h"
38 #include "sta_info.h"
39 #include "wifi.h"
40 #include "wlan_bssdef.h"
41 
42 static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len);
43 
_init_mlme_priv(struct _adapter * padapter)44 static sint _init_mlme_priv(struct _adapter *padapter)
45 {
46 	sint	i;
47 	u8	*pbuf;
48 	struct wlan_network	*pnetwork;
49 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
50 
51 	memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv));
52 	pmlmepriv->nic_hdl = (u8 *)padapter;
53 	pmlmepriv->pscanned = NULL;
54 	pmlmepriv->fw_state = 0;
55 	pmlmepriv->cur_network.network.InfrastructureMode =
56 				 Ndis802_11AutoUnknown;
57 	/* Maybe someday we should rename this variable to "active_mode"(Jeff)*/
58 	pmlmepriv->passive_mode = 1; /* 1: active, 0: passive. */
59 	spin_lock_init(&(pmlmepriv->lock));
60 	spin_lock_init(&(pmlmepriv->lock2));
61 	_init_queue(&(pmlmepriv->free_bss_pool));
62 	_init_queue(&(pmlmepriv->scanned_queue));
63 	set_scanned_network_val(pmlmepriv, 0);
64 	memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
65 	pbuf = kmalloc_array(MAX_BSS_CNT, sizeof(struct wlan_network),
66 			     GFP_ATOMIC);
67 	if (!pbuf)
68 		return _FAIL;
69 	pmlmepriv->free_bss_buf = pbuf;
70 	pnetwork = (struct wlan_network *)pbuf;
71 	for (i = 0; i < MAX_BSS_CNT; i++) {
72 		INIT_LIST_HEAD(&(pnetwork->list));
73 		list_add_tail(&(pnetwork->list),
74 				 &(pmlmepriv->free_bss_pool.queue));
75 		pnetwork++;
76 	}
77 	pmlmepriv->sitesurveyctrl.last_rx_pkts = 0;
78 	pmlmepriv->sitesurveyctrl.last_tx_pkts = 0;
79 	pmlmepriv->sitesurveyctrl.traffic_busy = false;
80 	/* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
81 	r8712_init_mlme_timer(padapter);
82 	return _SUCCESS;
83 }
84 
_r8712_alloc_network(struct mlme_priv * pmlmepriv)85 struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv)
86 {
87 	unsigned long irqL;
88 	struct wlan_network *pnetwork;
89 	struct  __queue *free_queue = &pmlmepriv->free_bss_pool;
90 
91 	spin_lock_irqsave(&free_queue->lock, irqL);
92 	pnetwork = list_first_entry_or_null(&free_queue->queue,
93 					    struct wlan_network, list);
94 	if (pnetwork) {
95 		list_del_init(&pnetwork->list);
96 		pnetwork->last_scanned = jiffies;
97 		pmlmepriv->num_of_scanned++;
98 	}
99 	spin_unlock_irqrestore(&free_queue->lock, irqL);
100 	return pnetwork;
101 }
102 
_free_network(struct mlme_priv * pmlmepriv,struct wlan_network * pnetwork)103 static void _free_network(struct mlme_priv *pmlmepriv,
104 			  struct wlan_network *pnetwork)
105 {
106 	u32 curr_time, delta_time;
107 	unsigned long irqL;
108 	struct  __queue *free_queue = &(pmlmepriv->free_bss_pool);
109 
110 	if (pnetwork == NULL)
111 		return;
112 	if (pnetwork->fixed)
113 		return;
114 	curr_time = jiffies;
115 	delta_time = (curr_time - (u32)pnetwork->last_scanned) / HZ;
116 	if (delta_time < SCANQUEUE_LIFETIME)
117 		return;
118 	spin_lock_irqsave(&free_queue->lock, irqL);
119 	list_del_init(&pnetwork->list);
120 	list_add_tail(&pnetwork->list, &free_queue->queue);
121 	pmlmepriv->num_of_scanned--;
122 	spin_unlock_irqrestore(&free_queue->lock, irqL);
123 }
124 
free_network_nolock(struct mlme_priv * pmlmepriv,struct wlan_network * pnetwork)125 static void free_network_nolock(struct mlme_priv *pmlmepriv,
126 			  struct wlan_network *pnetwork)
127 {
128 	struct  __queue *free_queue = &pmlmepriv->free_bss_pool;
129 
130 	if (pnetwork == NULL)
131 		return;
132 	if (pnetwork->fixed)
133 		return;
134 	list_del_init(&pnetwork->list);
135 	list_add_tail(&pnetwork->list, &free_queue->queue);
136 	pmlmepriv->num_of_scanned--;
137 }
138 
139 
140 /* return the wlan_network with the matching addr
141  * Shall be called under atomic context...
142  * to avoid possible racing condition...
143  */
_r8712_find_network(struct __queue * scanned_queue,u8 * addr)144 static struct wlan_network *_r8712_find_network(struct  __queue *scanned_queue,
145 					 u8 *addr)
146 {
147 	unsigned long irqL;
148 	struct list_head *phead, *plist;
149 	struct wlan_network *pnetwork = NULL;
150 
151 	if (is_zero_ether_addr(addr))
152 		return NULL;
153 	spin_lock_irqsave(&scanned_queue->lock, irqL);
154 	phead = &scanned_queue->queue;
155 	plist = phead->next;
156 	while (plist != phead) {
157 		pnetwork = container_of(plist, struct wlan_network, list);
158 		plist = plist->next;
159 		if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN))
160 			break;
161 	}
162 	spin_unlock_irqrestore(&scanned_queue->lock, irqL);
163 	return pnetwork;
164 }
165 
_free_network_queue(struct _adapter * padapter)166 static void _free_network_queue(struct _adapter *padapter)
167 {
168 	unsigned long irqL;
169 	struct list_head *phead, *plist;
170 	struct wlan_network *pnetwork;
171 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
172 	struct  __queue *scanned_queue = &pmlmepriv->scanned_queue;
173 
174 	spin_lock_irqsave(&scanned_queue->lock, irqL);
175 	phead = &scanned_queue->queue;
176 	plist = phead->next;
177 	while (!end_of_queue_search(phead, plist)) {
178 		pnetwork = container_of(plist, struct wlan_network, list);
179 		plist = plist->next;
180 		_free_network(pmlmepriv, pnetwork);
181 	}
182 	spin_unlock_irqrestore(&scanned_queue->lock, irqL);
183 }
184 
r8712_if_up(struct _adapter * padapter)185 sint r8712_if_up(struct _adapter *padapter)
186 {
187 	sint res;
188 
189 	if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
190 	    !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
191 		res = false;
192 	} else {
193 		res = true;
194 	}
195 	return res;
196 }
197 
r8712_generate_random_ibss(u8 * pibss)198 void r8712_generate_random_ibss(u8 *pibss)
199 {
200 	u32 curtime = jiffies;
201 
202 	pibss[0] = 0x02; /*in ad-hoc mode bit1 must set to 1 */
203 	pibss[1] = 0x11;
204 	pibss[2] = 0x87;
205 	pibss[3] = (u8)(curtime & 0xff);
206 	pibss[4] = (u8)((curtime >> 8) & 0xff);
207 	pibss[5] = (u8)((curtime >> 16) & 0xff);
208 }
209 
r8712_get_wlan_bssid_ex_sz(struct wlan_bssid_ex * bss)210 uint r8712_get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss)
211 {
212 	return sizeof(*bss) + bss->IELength - MAX_IE_SZ;
213 }
214 
r8712_get_capability_from_ie(u8 * ie)215 u8 *r8712_get_capability_from_ie(u8 *ie)
216 {
217 	return ie + 8 + 2;
218 }
219 
r8712_init_mlme_priv(struct _adapter * padapter)220 int r8712_init_mlme_priv(struct _adapter *padapter)
221 {
222 	return _init_mlme_priv(padapter);
223 }
224 
r8712_free_mlme_priv(struct mlme_priv * pmlmepriv)225 void r8712_free_mlme_priv(struct mlme_priv *pmlmepriv)
226 {
227 	kfree(pmlmepriv->free_bss_buf);
228 }
229 
alloc_network(struct mlme_priv * pmlmepriv)230 static struct	wlan_network *alloc_network(struct mlme_priv *pmlmepriv)
231 {
232 	return _r8712_alloc_network(pmlmepriv);
233 }
234 
r8712_free_network_queue(struct _adapter * dev)235 void r8712_free_network_queue(struct _adapter *dev)
236 {
237 	_free_network_queue(dev);
238 }
239 
240 /*
241  * return the wlan_network with the matching addr
242  * Shall be called under atomic context...
243  * to avoid possible racing condition...
244  */
r8712_find_network(struct __queue * scanned_queue,u8 * addr)245 static struct wlan_network *r8712_find_network(struct  __queue *scanned_queue,
246 					       u8 *addr)
247 {
248 	struct wlan_network *pnetwork = _r8712_find_network(scanned_queue,
249 							    addr);
250 
251 	return pnetwork;
252 }
253 
r8712_is_same_ibss(struct _adapter * adapter,struct wlan_network * pnetwork)254 int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork)
255 {
256 	int ret = true;
257 	struct security_priv *psecuritypriv = &adapter->securitypriv;
258 
259 	if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) &&
260 		    (pnetwork->network.Privacy == cpu_to_le32(0)))
261 		ret = false;
262 	else if ((psecuritypriv->PrivacyAlgrthm == _NO_PRIVACY_) &&
263 		 (pnetwork->network.Privacy == cpu_to_le32(1)))
264 		ret = false;
265 	else
266 		ret = true;
267 	return ret;
268 
269 }
270 
is_same_network(struct wlan_bssid_ex * src,struct wlan_bssid_ex * dst)271 static int is_same_network(struct wlan_bssid_ex *src,
272 			   struct wlan_bssid_ex *dst)
273 {
274 	 u16 s_cap, d_cap;
275 
276 	memcpy((u8 *)&s_cap, r8712_get_capability_from_ie(src->IEs), 2);
277 	memcpy((u8 *)&d_cap, r8712_get_capability_from_ie(dst->IEs), 2);
278 	return (src->Ssid.SsidLength == dst->Ssid.SsidLength) &&
279 			(src->Configuration.DSConfig ==
280 			dst->Configuration.DSConfig) &&
281 			((!memcmp(src->MacAddress, dst->MacAddress,
282 			ETH_ALEN))) &&
283 			((!memcmp(src->Ssid.Ssid,
284 			  dst->Ssid.Ssid,
285 			  src->Ssid.SsidLength))) &&
286 			((s_cap & WLAN_CAPABILITY_IBSS) ==
287 			(d_cap & WLAN_CAPABILITY_IBSS)) &&
288 			((s_cap & WLAN_CAPABILITY_BSS) ==
289 			(d_cap & WLAN_CAPABILITY_BSS));
290 
291 }
292 
r8712_get_oldest_wlan_network(struct __queue * scanned_queue)293 struct	wlan_network *r8712_get_oldest_wlan_network(
294 				struct  __queue *scanned_queue)
295 {
296 	struct list_head *plist, *phead;
297 	struct	wlan_network	*pwlan = NULL;
298 	struct	wlan_network	*oldest = NULL;
299 
300 	phead = &scanned_queue->queue;
301 	plist = phead->next;
302 	while (1) {
303 		if (end_of_queue_search(phead, plist) ==  true)
304 			break;
305 		pwlan = container_of(plist, struct wlan_network, list);
306 		if (pwlan->fixed != true) {
307 			if (oldest == NULL ||
308 			    time_after((unsigned long)oldest->last_scanned,
309 			    (unsigned long)pwlan->last_scanned))
310 				oldest = pwlan;
311 		}
312 		plist = plist->next;
313 	}
314 	return oldest;
315 }
316 
update_network(struct wlan_bssid_ex * dst,struct wlan_bssid_ex * src,struct _adapter * padapter)317 static void update_network(struct wlan_bssid_ex *dst,
318 			   struct wlan_bssid_ex *src,
319 			   struct _adapter *padapter)
320 {
321 	u32 last_evm = 0, tmpVal;
322 
323 	if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) &&
324 	    is_same_network(&(padapter->mlmepriv.cur_network.network), src)) {
325 		if (padapter->recvpriv.signal_qual_data.total_num++ >=
326 		    PHY_LINKQUALITY_SLID_WIN_MAX) {
327 			padapter->recvpriv.signal_qual_data.total_num =
328 				   PHY_LINKQUALITY_SLID_WIN_MAX;
329 			last_evm = padapter->recvpriv.signal_qual_data.
330 				   elements[padapter->recvpriv.
331 				   signal_qual_data.index];
332 			padapter->recvpriv.signal_qual_data.total_val -=
333 				 last_evm;
334 		}
335 		padapter->recvpriv.signal_qual_data.total_val += src->Rssi;
336 
337 		padapter->recvpriv.signal_qual_data.
338 			  elements[padapter->recvpriv.signal_qual_data.
339 			  index++] = src->Rssi;
340 		if (padapter->recvpriv.signal_qual_data.index >=
341 		    PHY_LINKQUALITY_SLID_WIN_MAX)
342 			padapter->recvpriv.signal_qual_data.index = 0;
343 		/* <1> Showed on UI for user, in percentage. */
344 		tmpVal = padapter->recvpriv.signal_qual_data.total_val /
345 			 padapter->recvpriv.signal_qual_data.total_num;
346 		padapter->recvpriv.signal = (u8)tmpVal;
347 
348 		src->Rssi = padapter->recvpriv.signal;
349 	} else {
350 		src->Rssi = (src->Rssi + dst->Rssi) / 2;
351 	}
352 	memcpy((u8 *)dst, (u8 *)src, r8712_get_wlan_bssid_ex_sz(src));
353 }
354 
update_current_network(struct _adapter * adapter,struct wlan_bssid_ex * pnetwork)355 static void update_current_network(struct _adapter *adapter,
356 				   struct wlan_bssid_ex *pnetwork)
357 {
358 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
359 
360 	if (is_same_network(&(pmlmepriv->cur_network.network), pnetwork)) {
361 		update_network(&(pmlmepriv->cur_network.network),
362 			       pnetwork, adapter);
363 		r8712_update_protection(adapter,
364 			       (pmlmepriv->cur_network.network.IEs) +
365 			       sizeof(struct NDIS_802_11_FIXED_IEs),
366 			       pmlmepriv->cur_network.network.IELength);
367 	}
368 }
369 
370 /* Caller must hold pmlmepriv->lock first */
update_scanned_network(struct _adapter * adapter,struct wlan_bssid_ex * target)371 static void update_scanned_network(struct _adapter *adapter,
372 			    struct wlan_bssid_ex *target)
373 {
374 	struct list_head *plist, *phead;
375 
376 	u32 bssid_ex_sz;
377 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
378 	struct  __queue *queue = &pmlmepriv->scanned_queue;
379 	struct wlan_network *pnetwork = NULL;
380 	struct wlan_network *oldest = NULL;
381 
382 	phead = &queue->queue;
383 	plist = phead->next;
384 
385 	while (1) {
386 		if (end_of_queue_search(phead, plist))
387 			break;
388 
389 		pnetwork = container_of(plist, struct wlan_network, list);
390 		if (is_same_network(&pnetwork->network, target))
391 			break;
392 		if ((oldest == ((struct wlan_network *)0)) ||
393 		    time_after((unsigned long)oldest->last_scanned,
394 				(unsigned long)pnetwork->last_scanned))
395 			oldest = pnetwork;
396 
397 		plist = plist->next;
398 	}
399 
400 
401 	/* If we didn't find a match, then get a new network slot to initialize
402 	 * with this beacon's information
403 	 */
404 	if (end_of_queue_search(phead, plist)) {
405 		if (list_empty(&pmlmepriv->free_bss_pool.queue)) {
406 			/* If there are no more slots, expire the oldest */
407 			pnetwork = oldest;
408 			target->Rssi = (pnetwork->network.Rssi +
409 					target->Rssi) / 2;
410 			memcpy(&pnetwork->network, target,
411 				r8712_get_wlan_bssid_ex_sz(target));
412 			pnetwork->last_scanned = jiffies;
413 		} else {
414 			/* Otherwise just pull from the free list */
415 			/* update scan_time */
416 			pnetwork = alloc_network(pmlmepriv);
417 			if (pnetwork == NULL)
418 				return;
419 			bssid_ex_sz = r8712_get_wlan_bssid_ex_sz(target);
420 			target->Length = bssid_ex_sz;
421 			memcpy(&pnetwork->network, target, bssid_ex_sz);
422 			list_add_tail(&pnetwork->list, &queue->queue);
423 		}
424 	} else {
425 		/* we have an entry and we are going to update it. But
426 		 * this entry may be already expired. In this case we
427 		 * do the same as we found a new net and call the new_net
428 		 * handler
429 		 */
430 		update_network(&pnetwork->network, target, adapter);
431 		pnetwork->last_scanned = jiffies;
432 	}
433 }
434 
rtl8711_add_network(struct _adapter * adapter,struct wlan_bssid_ex * pnetwork)435 static void rtl8711_add_network(struct _adapter *adapter,
436 			 struct wlan_bssid_ex *pnetwork)
437 {
438 	unsigned long irqL;
439 	struct mlme_priv *pmlmepriv = &(((struct _adapter *)adapter)->mlmepriv);
440 	struct  __queue *queue = &pmlmepriv->scanned_queue;
441 
442 	spin_lock_irqsave(&queue->lock, irqL);
443 	update_current_network(adapter, pnetwork);
444 	update_scanned_network(adapter, pnetwork);
445 	spin_unlock_irqrestore(&queue->lock, irqL);
446 }
447 
448 /*select the desired network based on the capability of the (i)bss.
449  * check items:		(1) security
450  *			(2) network_type
451  *			(3) WMM
452  *			(4) HT
453  *			(5) others
454  */
is_desired_network(struct _adapter * adapter,struct wlan_network * pnetwork)455 static int is_desired_network(struct _adapter *adapter,
456 				struct wlan_network *pnetwork)
457 {
458 	u8 wps_ie[512];
459 	uint wps_ielen;
460 	int bselected = true;
461 	struct	security_priv *psecuritypriv = &adapter->securitypriv;
462 
463 	if (psecuritypriv->wps_phase) {
464 		if (r8712_get_wps_ie(pnetwork->network.IEs,
465 		    pnetwork->network.IELength, wps_ie,
466 		    &wps_ielen))
467 			return true;
468 		return false;
469 	}
470 	if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) &&
471 		    (pnetwork->network.Privacy == 0))
472 		bselected = false;
473 	if (check_fwstate(&adapter->mlmepriv, WIFI_ADHOC_STATE)) {
474 		if (pnetwork->network.InfrastructureMode !=
475 			adapter->mlmepriv.cur_network.network.
476 			InfrastructureMode)
477 			bselected = false;
478 	}
479 	return bselected;
480 }
481 
482 /* TODO: Perry : For Power Management */
r8712_atimdone_event_callback(struct _adapter * adapter,u8 * pbuf)483 void r8712_atimdone_event_callback(struct _adapter *adapter, u8 *pbuf)
484 {
485 }
486 
r8712_survey_event_callback(struct _adapter * adapter,u8 * pbuf)487 void r8712_survey_event_callback(struct _adapter *adapter, u8 *pbuf)
488 {
489 	unsigned long flags;
490 	u32 len;
491 	struct wlan_bssid_ex *pnetwork;
492 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
493 
494 	pnetwork = (struct wlan_bssid_ex *)pbuf;
495 #ifdef __BIG_ENDIAN
496 	/* endian_convert */
497 	pnetwork->Length = le32_to_cpu(pnetwork->Length);
498 	pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);
499 	pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy);
500 	pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
501 	pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse);
502 	pnetwork->Configuration.ATIMWindow =
503 		 le32_to_cpu(pnetwork->Configuration.ATIMWindow);
504 	pnetwork->Configuration.BeaconPeriod =
505 		 le32_to_cpu(pnetwork->Configuration.BeaconPeriod);
506 	pnetwork->Configuration.DSConfig =
507 		 le32_to_cpu(pnetwork->Configuration.DSConfig);
508 	pnetwork->Configuration.FHConfig.DwellTime =
509 		 le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime);
510 	pnetwork->Configuration.FHConfig.HopPattern =
511 		 le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern);
512 	pnetwork->Configuration.FHConfig.HopSet =
513 		 le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet);
514 	pnetwork->Configuration.FHConfig.Length =
515 		 le32_to_cpu(pnetwork->Configuration.FHConfig.Length);
516 	pnetwork->Configuration.Length =
517 		 le32_to_cpu(pnetwork->Configuration.Length);
518 	pnetwork->InfrastructureMode =
519 		 le32_to_cpu(pnetwork->InfrastructureMode);
520 	pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
521 #endif
522 	len = r8712_get_wlan_bssid_ex_sz(pnetwork);
523 	if (len > sizeof(struct wlan_bssid_ex))
524 		return;
525 	spin_lock_irqsave(&pmlmepriv->lock2, flags);
526 	/* update IBSS_network 's timestamp */
527 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
528 		if (!memcmp(&(pmlmepriv->cur_network.network.MacAddress),
529 		    pnetwork->MacAddress, ETH_ALEN)) {
530 			struct wlan_network *ibss_wlan = NULL;
531 
532 			memcpy(pmlmepriv->cur_network.network.IEs,
533 				pnetwork->IEs, 8);
534 			ibss_wlan = r8712_find_network(
535 						&pmlmepriv->scanned_queue,
536 						pnetwork->MacAddress);
537 			if (ibss_wlan) {
538 				memcpy(ibss_wlan->network.IEs,
539 					pnetwork->IEs, 8);
540 				goto exit;
541 			}
542 		}
543 	}
544 	/* lock pmlmepriv->lock when you accessing network_q */
545 	if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
546 		if (pnetwork->Ssid.Ssid[0] != 0) {
547 			rtl8711_add_network(adapter, pnetwork);
548 		} else {
549 			pnetwork->Ssid.SsidLength = 8;
550 			memcpy(pnetwork->Ssid.Ssid, "<hidden>", 8);
551 			rtl8711_add_network(adapter, pnetwork);
552 		}
553 	}
554 exit:
555 	spin_unlock_irqrestore(&pmlmepriv->lock2, flags);
556 }
557 
r8712_surveydone_event_callback(struct _adapter * adapter,u8 * pbuf)558 void r8712_surveydone_event_callback(struct _adapter *adapter, u8 *pbuf)
559 {
560 	unsigned long irqL;
561 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
562 
563 	spin_lock_irqsave(&pmlmepriv->lock, irqL);
564 
565 	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
566 		del_timer(&pmlmepriv->scan_to_timer);
567 
568 		_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
569 	}
570 
571 	if (pmlmepriv->to_join) {
572 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
573 			if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
574 				set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
575 
576 				if (r8712_select_and_join_from_scan(pmlmepriv)
577 				    == _SUCCESS)
578 					mod_timer(&pmlmepriv->assoc_timer, jiffies +
579 						  msecs_to_jiffies(MAX_JOIN_TIMEOUT));
580 				else {
581 					struct wlan_bssid_ex *pdev_network =
582 					  &(adapter->registrypriv.dev_network);
583 					u8 *pibss =
584 						 adapter->registrypriv.
585 							dev_network.MacAddress;
586 					pmlmepriv->fw_state ^= _FW_UNDER_SURVEY;
587 					memcpy(&pdev_network->Ssid,
588 						&pmlmepriv->assoc_ssid,
589 						sizeof(struct
590 							 ndis_802_11_ssid));
591 					r8712_update_registrypriv_dev_network
592 						(adapter);
593 					r8712_generate_random_ibss(pibss);
594 					pmlmepriv->fw_state =
595 						 WIFI_ADHOC_MASTER_STATE;
596 					pmlmepriv->to_join = false;
597 				}
598 			}
599 		} else {
600 			pmlmepriv->to_join = false;
601 			set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
602 			if (r8712_select_and_join_from_scan(pmlmepriv) ==
603 			    _SUCCESS)
604 				mod_timer(&pmlmepriv->assoc_timer, jiffies +
605 					  msecs_to_jiffies(MAX_JOIN_TIMEOUT));
606 			else
607 				_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
608 		}
609 	}
610 	spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
611 }
612 
613 /*
614  *r8712_free_assoc_resources: the caller has to lock pmlmepriv->lock
615  */
r8712_free_assoc_resources(struct _adapter * adapter)616 void r8712_free_assoc_resources(struct _adapter *adapter)
617 {
618 	unsigned long irqL;
619 	struct wlan_network *pwlan = NULL;
620 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
621 	struct sta_priv *pstapriv = &adapter->stapriv;
622 	struct wlan_network *tgt_network = &pmlmepriv->cur_network;
623 
624 	pwlan = r8712_find_network(&pmlmepriv->scanned_queue,
625 				   tgt_network->network.MacAddress);
626 
627 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) {
628 		struct sta_info *psta;
629 
630 		psta = r8712_get_stainfo(&adapter->stapriv,
631 					 tgt_network->network.MacAddress);
632 
633 		spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
634 		r8712_free_stainfo(adapter,  psta);
635 		spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
636 	}
637 
638 	if (check_fwstate(pmlmepriv,
639 	    WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
640 		r8712_free_all_stainfo(adapter);
641 	if (pwlan)
642 		pwlan->fixed = false;
643 
644 	if (((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) &&
645 	     (adapter->stapriv.asoc_sta_count == 1)))
646 		free_network_nolock(pmlmepriv, pwlan);
647 }
648 
649 /*
650  * r8712_indicate_connect: the caller has to lock pmlmepriv->lock
651  */
r8712_indicate_connect(struct _adapter * padapter)652 void r8712_indicate_connect(struct _adapter *padapter)
653 {
654 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
655 
656 	pmlmepriv->to_join = false;
657 	set_fwstate(pmlmepriv, _FW_LINKED);
658 	padapter->ledpriv.LedControlHandler(padapter, LED_CTL_LINK);
659 	r8712_os_indicate_connect(padapter);
660 	if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE)
661 		mod_timer(&pmlmepriv->dhcp_timer,
662 			  jiffies + msecs_to_jiffies(60000));
663 }
664 
665 
666 /*
667  * r8712_ind_disconnect: the caller has to lock pmlmepriv->lock
668  */
r8712_ind_disconnect(struct _adapter * padapter)669 void r8712_ind_disconnect(struct _adapter *padapter)
670 {
671 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
672 
673 	if (check_fwstate(pmlmepriv, _FW_LINKED)) {
674 		_clr_fwstate_(pmlmepriv, _FW_LINKED);
675 		padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK);
676 		r8712_os_indicate_disconnect(padapter);
677 	}
678 	if (padapter->pwrctrlpriv.pwr_mode !=
679 	    padapter->registrypriv.power_mgnt) {
680 		del_timer(&pmlmepriv->dhcp_timer);
681 		r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt,
682 				  padapter->registrypriv.smart_ps);
683 	}
684 }
685 
686 /*Notes:
687  *pnetwork : returns from r8712_joinbss_event_callback
688  *ptarget_wlan: found from scanned_queue
689  *if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if
690  *  "ptarget_sta" & "ptarget_wlan" exist.
691  *if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check
692  * if "ptarget_wlan" exist.
693  *if join_res > 0, update "cur_network->network" from
694  * "pnetwork->network" if (ptarget_wlan !=NULL).
695  */
r8712_joinbss_event_callback(struct _adapter * adapter,u8 * pbuf)696 void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf)
697 {
698 	unsigned long irqL = 0, irqL2;
699 	struct sta_info	*ptarget_sta = NULL, *pcur_sta = NULL;
700 	struct sta_priv	*pstapriv = &adapter->stapriv;
701 	struct mlme_priv	*pmlmepriv = &adapter->mlmepriv;
702 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
703 	struct wlan_network	*pcur_wlan = NULL, *ptarget_wlan = NULL;
704 	unsigned int		the_same_macaddr = false;
705 	struct wlan_network *pnetwork;
706 
707 	if (sizeof(struct list_head) == 4 * sizeof(u32)) {
708 		pnetwork = kmalloc(sizeof(struct wlan_network), GFP_ATOMIC);
709 		if (!pnetwork)
710 			return;
711 		memcpy((u8 *)pnetwork + 16, (u8 *)pbuf + 8,
712 		       sizeof(struct wlan_network) - 16);
713 	} else {
714 		pnetwork = (struct wlan_network *)pbuf;
715 	}
716 
717 #ifdef __BIG_ENDIAN
718 	/* endian_convert */
719 	pnetwork->join_res = le32_to_cpu(pnetwork->join_res);
720 	pnetwork->network_type = le32_to_cpu(pnetwork->network_type);
721 	pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length);
722 	pnetwork->network.Ssid.SsidLength =
723 		 le32_to_cpu(pnetwork->network.Ssid.SsidLength);
724 	pnetwork->network.Privacy = le32_to_cpu(pnetwork->network.Privacy);
725 	pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi);
726 	pnetwork->network.NetworkTypeInUse =
727 		 le32_to_cpu(pnetwork->network.NetworkTypeInUse);
728 	pnetwork->network.Configuration.ATIMWindow =
729 		 le32_to_cpu(pnetwork->network.Configuration.ATIMWindow);
730 	pnetwork->network.Configuration.BeaconPeriod =
731 		 le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod);
732 	pnetwork->network.Configuration.DSConfig =
733 		 le32_to_cpu(pnetwork->network.Configuration.DSConfig);
734 	pnetwork->network.Configuration.FHConfig.DwellTime =
735 		 le32_to_cpu(pnetwork->network.Configuration.FHConfig.
736 			     DwellTime);
737 	pnetwork->network.Configuration.FHConfig.HopPattern =
738 		 le32_to_cpu(pnetwork->network.Configuration.
739 			     FHConfig.HopPattern);
740 	pnetwork->network.Configuration.FHConfig.HopSet =
741 		 le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet);
742 	pnetwork->network.Configuration.FHConfig.Length =
743 		 le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length);
744 	pnetwork->network.Configuration.Length =
745 		 le32_to_cpu(pnetwork->network.Configuration.Length);
746 	pnetwork->network.InfrastructureMode =
747 		 le32_to_cpu(pnetwork->network.InfrastructureMode);
748 	pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength);
749 #endif
750 
751 	the_same_macaddr = !memcmp(pnetwork->network.MacAddress,
752 				   cur_network->network.MacAddress, ETH_ALEN);
753 	pnetwork->network.Length =
754 		 r8712_get_wlan_bssid_ex_sz(&pnetwork->network);
755 	spin_lock_irqsave(&pmlmepriv->lock, irqL);
756 	if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex))
757 		goto ignore_joinbss_callback;
758 	if (pnetwork->join_res > 0) {
759 		if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
760 			/*s1. find ptarget_wlan*/
761 			if (check_fwstate(pmlmepriv, _FW_LINKED)) {
762 				if (the_same_macaddr) {
763 					ptarget_wlan =
764 					    r8712_find_network(&pmlmepriv->
765 					    scanned_queue,
766 					    cur_network->network.MacAddress);
767 				} else {
768 					pcur_wlan =
769 					     r8712_find_network(&pmlmepriv->
770 					     scanned_queue,
771 					     cur_network->network.MacAddress);
772 					pcur_wlan->fixed = false;
773 
774 					pcur_sta = r8712_get_stainfo(pstapriv,
775 					     cur_network->network.MacAddress);
776 					spin_lock_irqsave(&pstapriv->
777 						sta_hash_lock, irqL2);
778 					r8712_free_stainfo(adapter, pcur_sta);
779 					spin_unlock_irqrestore(&(pstapriv->
780 						sta_hash_lock), irqL2);
781 
782 					ptarget_wlan =
783 						 r8712_find_network(&pmlmepriv->
784 						 scanned_queue,
785 						 pnetwork->network.
786 						 MacAddress);
787 					if (ptarget_wlan)
788 						ptarget_wlan->fixed = true;
789 				}
790 			} else {
791 				ptarget_wlan = r8712_find_network(&pmlmepriv->
792 						scanned_queue,
793 						pnetwork->network.MacAddress);
794 				if (ptarget_wlan)
795 					ptarget_wlan->fixed = true;
796 			}
797 
798 			if (ptarget_wlan == NULL) {
799 				if (check_fwstate(pmlmepriv,
800 					_FW_UNDER_LINKING))
801 					pmlmepriv->fw_state ^=
802 						 _FW_UNDER_LINKING;
803 				goto ignore_joinbss_callback;
804 			}
805 
806 			/*s2. find ptarget_sta & update ptarget_sta*/
807 			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
808 				if (the_same_macaddr) {
809 					ptarget_sta =
810 						 r8712_get_stainfo(pstapriv,
811 						 pnetwork->network.MacAddress);
812 					if (ptarget_sta == NULL)
813 						ptarget_sta =
814 						 r8712_alloc_stainfo(pstapriv,
815 						 pnetwork->network.MacAddress);
816 				} else {
817 					ptarget_sta =
818 						 r8712_alloc_stainfo(pstapriv,
819 						 pnetwork->network.MacAddress);
820 				}
821 				if (ptarget_sta) /*update ptarget_sta*/ {
822 					ptarget_sta->aid = pnetwork->join_res;
823 					ptarget_sta->qos_option = 1;
824 					ptarget_sta->mac_id = 5;
825 					if (adapter->securitypriv.
826 					    AuthAlgrthm == 2) {
827 						adapter->securitypriv.
828 							binstallGrpkey =
829 							 false;
830 						adapter->securitypriv.
831 							busetkipkey =
832 							 false;
833 						adapter->securitypriv.
834 							bgrpkey_handshake =
835 							 false;
836 						ptarget_sta->ieee8021x_blocked
837 							 = true;
838 						ptarget_sta->XPrivacy =
839 							 adapter->securitypriv.
840 							 PrivacyAlgrthm;
841 						memset((u8 *)&ptarget_sta->
842 							 x_UncstKey,
843 							 0,
844 							 sizeof(union Keytype));
845 						memset((u8 *)&ptarget_sta->
846 							 tkiprxmickey,
847 							 0,
848 							 sizeof(union Keytype));
849 						memset((u8 *)&ptarget_sta->
850 							 tkiptxmickey,
851 							 0,
852 							 sizeof(union Keytype));
853 						memset((u8 *)&ptarget_sta->
854 							 txpn, 0,
855 							 sizeof(union pn48));
856 						memset((u8 *)&ptarget_sta->
857 							 rxpn, 0,
858 							 sizeof(union pn48));
859 					}
860 				} else {
861 					if (check_fwstate(pmlmepriv,
862 					    _FW_UNDER_LINKING))
863 						pmlmepriv->fw_state ^=
864 							 _FW_UNDER_LINKING;
865 					goto ignore_joinbss_callback;
866 				}
867 			}
868 
869 			/*s3. update cur_network & indicate connect*/
870 			memcpy(&cur_network->network, &pnetwork->network,
871 				pnetwork->network.Length);
872 			cur_network->aid = pnetwork->join_res;
873 			/*update fw_state will clr _FW_UNDER_LINKING*/
874 			switch (pnetwork->network.InfrastructureMode) {
875 			case Ndis802_11Infrastructure:
876 				pmlmepriv->fw_state = WIFI_STATION_STATE;
877 				break;
878 			case Ndis802_11IBSS:
879 				pmlmepriv->fw_state = WIFI_ADHOC_STATE;
880 				break;
881 			default:
882 				pmlmepriv->fw_state = WIFI_NULL_STATE;
883 				break;
884 			}
885 			r8712_update_protection(adapter,
886 					  (cur_network->network.IEs) +
887 					  sizeof(struct NDIS_802_11_FIXED_IEs),
888 					  (cur_network->network.IELength));
889 			/*TODO: update HT_Capability*/
890 			update_ht_cap(adapter, cur_network->network.IEs,
891 				      cur_network->network.IELength);
892 			/*indicate connect*/
893 			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
894 				r8712_indicate_connect(adapter);
895 			del_timer(&pmlmepriv->assoc_timer);
896 		} else {
897 			goto ignore_joinbss_callback;
898 		}
899 	} else {
900 		if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
901 			mod_timer(&pmlmepriv->assoc_timer,
902 				  jiffies + msecs_to_jiffies(1));
903 			_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
904 		}
905 	}
906 ignore_joinbss_callback:
907 	spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
908 	if (sizeof(struct list_head) == 4 * sizeof(u32))
909 		kfree(pnetwork);
910 }
911 
r8712_stassoc_event_callback(struct _adapter * adapter,u8 * pbuf)912 void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf)
913 {
914 	unsigned long irqL;
915 	struct sta_info *psta;
916 	struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
917 	struct stassoc_event *pstassoc	= (struct stassoc_event *)pbuf;
918 
919 	/* to do: */
920 	if (!r8712_access_ctrl(&adapter->acl_list, pstassoc->macaddr))
921 		return;
922 	psta = r8712_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
923 	if (psta != NULL) {
924 		/*the sta have been in sta_info_queue => do nothing
925 		 *(between drv has received this event before and
926 		 * fw have not yet to set key to CAM_ENTRY)
927 		 */
928 		return;
929 	}
930 
931 	psta = r8712_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr);
932 	if (psta == NULL)
933 		return;
934 	/* to do : init sta_info variable */
935 	psta->qos_option = 0;
936 	psta->mac_id = le32_to_cpu(pstassoc->cam_id);
937 	/* psta->aid = (uint)pstassoc->cam_id; */
938 
939 	if (adapter->securitypriv.AuthAlgrthm == 2)
940 		psta->XPrivacy = adapter->securitypriv.PrivacyAlgrthm;
941 	psta->ieee8021x_blocked = false;
942 	spin_lock_irqsave(&pmlmepriv->lock, irqL);
943 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
944 	    check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
945 		if (adapter->stapriv.asoc_sta_count == 2) {
946 			/* a sta + bc/mc_stainfo (not Ibss_stainfo) */
947 			r8712_indicate_connect(adapter);
948 		}
949 	}
950 	spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
951 }
952 
r8712_stadel_event_callback(struct _adapter * adapter,u8 * pbuf)953 void r8712_stadel_event_callback(struct _adapter *adapter, u8 *pbuf)
954 {
955 	unsigned long irqL, irqL2;
956 	struct sta_info *psta;
957 	struct wlan_network *pwlan = NULL;
958 	struct wlan_bssid_ex *pdev_network = NULL;
959 	u8 *pibss = NULL;
960 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
961 	struct stadel_event *pstadel = (struct stadel_event *)pbuf;
962 	struct sta_priv *pstapriv = &adapter->stapriv;
963 	struct wlan_network *tgt_network = &pmlmepriv->cur_network;
964 
965 	spin_lock_irqsave(&pmlmepriv->lock, irqL2);
966 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
967 		r8712_ind_disconnect(adapter);
968 		r8712_free_assoc_resources(adapter);
969 	}
970 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE |
971 	    WIFI_ADHOC_STATE)) {
972 		psta = r8712_get_stainfo(&adapter->stapriv, pstadel->macaddr);
973 		spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
974 		r8712_free_stainfo(adapter, psta);
975 		spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
976 		if (adapter->stapriv.asoc_sta_count == 1) {
977 			/*a sta + bc/mc_stainfo (not Ibss_stainfo) */
978 			pwlan = r8712_find_network(&pmlmepriv->scanned_queue,
979 				tgt_network->network.MacAddress);
980 			if (pwlan) {
981 				pwlan->fixed = false;
982 				free_network_nolock(pmlmepriv, pwlan);
983 			}
984 			/*re-create ibss*/
985 			pdev_network = &(adapter->registrypriv.dev_network);
986 			pibss = adapter->registrypriv.dev_network.MacAddress;
987 			memcpy(pdev_network, &tgt_network->network,
988 				r8712_get_wlan_bssid_ex_sz(&tgt_network->
989 							network));
990 			memcpy(&pdev_network->Ssid,
991 				&pmlmepriv->assoc_ssid,
992 				sizeof(struct ndis_802_11_ssid));
993 			r8712_update_registrypriv_dev_network(adapter);
994 			r8712_generate_random_ibss(pibss);
995 			if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
996 				_clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
997 				set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
998 			}
999 		}
1000 	}
1001 	spin_unlock_irqrestore(&pmlmepriv->lock, irqL2);
1002 }
1003 
r8712_cpwm_event_callback(struct _adapter * adapter,u8 * pbuf)1004 void r8712_cpwm_event_callback(struct _adapter *adapter, u8 *pbuf)
1005 {
1006 	struct reportpwrstate_parm *preportpwrstate =
1007 			 (struct reportpwrstate_parm *)pbuf;
1008 
1009 	preportpwrstate->state |= (u8)(adapter->pwrctrlpriv.cpwm_tog + 0x80);
1010 	r8712_cpwm_int_hdl(adapter, preportpwrstate);
1011 }
1012 
1013 /*	When the Netgear 3500 AP is with WPA2PSK-AES mode, it will send
1014  *	 the ADDBA req frame with start seq control = 0 to wifi client after
1015  *	 the WPA handshake and the seqence number of following data packet
1016  *	will be 0. In this case, the Rx reorder sequence is not longer than 0
1017  *	 and the WiFi client will drop the data with seq number 0.
1018  *	So, the 8712 firmware has to inform driver with receiving the
1019  *	 ADDBA-Req frame so that the driver can reset the
1020  *	sequence value of Rx reorder control.
1021  */
r8712_got_addbareq_event_callback(struct _adapter * adapter,u8 * pbuf)1022 void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf)
1023 {
1024 	struct	ADDBA_Req_Report_parm *pAddbareq_pram =
1025 			 (struct ADDBA_Req_Report_parm *)pbuf;
1026 	struct	sta_info *psta;
1027 	struct	sta_priv *pstapriv = &adapter->stapriv;
1028 	struct	recv_reorder_ctrl *precvreorder_ctrl = NULL;
1029 
1030 	psta = r8712_get_stainfo(pstapriv, pAddbareq_pram->MacAddress);
1031 	if (psta) {
1032 		precvreorder_ctrl =
1033 			 &psta->recvreorder_ctrl[pAddbareq_pram->tid];
1034 		/* set the indicate_seq to 0xffff so that the rx reorder
1035 		 * can store any following data packet.
1036 		 */
1037 		precvreorder_ctrl->indicate_seq = 0xffff;
1038 	}
1039 }
1040 
r8712_wpspbc_event_callback(struct _adapter * adapter,u8 * pbuf)1041 void r8712_wpspbc_event_callback(struct _adapter *adapter, u8 *pbuf)
1042 {
1043 	if (!adapter->securitypriv.wps_hw_pbc_pressed)
1044 		adapter->securitypriv.wps_hw_pbc_pressed = true;
1045 }
1046 
_r8712_sitesurvey_ctrl_handler(struct _adapter * adapter)1047 void _r8712_sitesurvey_ctrl_handler(struct _adapter *adapter)
1048 {
1049 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1050 	struct sitesurvey_ctrl	*psitesurveyctrl = &pmlmepriv->sitesurveyctrl;
1051 	struct registry_priv	*pregistrypriv = &adapter->registrypriv;
1052 	u64 current_tx_pkts;
1053 	uint current_rx_pkts;
1054 
1055 	current_tx_pkts = (adapter->xmitpriv.tx_pkts) -
1056 			  (psitesurveyctrl->last_tx_pkts);
1057 	current_rx_pkts = (adapter->recvpriv.rx_pkts) -
1058 			  (psitesurveyctrl->last_rx_pkts);
1059 	psitesurveyctrl->last_tx_pkts = adapter->xmitpriv.tx_pkts;
1060 	psitesurveyctrl->last_rx_pkts = adapter->recvpriv.rx_pkts;
1061 	if ((current_tx_pkts > pregistrypriv->busy_thresh) ||
1062 	    (current_rx_pkts > pregistrypriv->busy_thresh))
1063 		psitesurveyctrl->traffic_busy = true;
1064 	else
1065 		psitesurveyctrl->traffic_busy = false;
1066 }
1067 
_r8712_join_timeout_handler(struct _adapter * adapter)1068 void _r8712_join_timeout_handler(struct _adapter *adapter)
1069 {
1070 	unsigned long irqL;
1071 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1072 
1073 	if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
1074 		return;
1075 	spin_lock_irqsave(&pmlmepriv->lock, irqL);
1076 	_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1077 	pmlmepriv->to_join = false;
1078 	if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1079 		r8712_os_indicate_disconnect(adapter);
1080 		_clr_fwstate_(pmlmepriv, _FW_LINKED);
1081 	}
1082 	if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt) {
1083 		r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt,
1084 				  adapter->registrypriv.smart_ps);
1085 	}
1086 	spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1087 }
1088 
r8712_scan_timeout_handler(struct _adapter * adapter)1089 void r8712_scan_timeout_handler (struct _adapter *adapter)
1090 {
1091 	unsigned long irqL;
1092 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1093 
1094 	spin_lock_irqsave(&pmlmepriv->lock, irqL);
1095 	_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1096 	pmlmepriv->to_join = false;	/* scan fail, so clear to_join flag */
1097 	spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1098 }
1099 
_r8712_dhcp_timeout_handler(struct _adapter * adapter)1100 void _r8712_dhcp_timeout_handler (struct _adapter *adapter)
1101 {
1102 	if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
1103 		return;
1104 	if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt)
1105 		r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt,
1106 			    adapter->registrypriv.smart_ps);
1107 }
1108 
_r8712_wdg_timeout_handler(struct _adapter * adapter)1109 void _r8712_wdg_timeout_handler(struct _adapter *adapter)
1110 {
1111 	r8712_wdg_wk_cmd(adapter);
1112 }
1113 
r8712_select_and_join_from_scan(struct mlme_priv * pmlmepriv)1114 int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv)
1115 {
1116 	struct list_head *phead;
1117 	unsigned char *dst_ssid, *src_ssid;
1118 	struct _adapter *adapter;
1119 	struct  __queue *queue = NULL;
1120 	struct wlan_network *pnetwork = NULL;
1121 	struct wlan_network *pnetwork_max_rssi = NULL;
1122 
1123 	adapter = (struct _adapter *)pmlmepriv->nic_hdl;
1124 	queue = &pmlmepriv->scanned_queue;
1125 	phead = &queue->queue;
1126 	pmlmepriv->pscanned = phead->next;
1127 	while (1) {
1128 		if (end_of_queue_search(phead, pmlmepriv->pscanned)) {
1129 			if ((pmlmepriv->assoc_by_rssi) &&
1130 			    (pnetwork_max_rssi != NULL)) {
1131 				pnetwork = pnetwork_max_rssi;
1132 				goto ask_for_joinbss;
1133 			}
1134 			return _FAIL;
1135 		}
1136 		pnetwork = container_of(pmlmepriv->pscanned,
1137 					struct wlan_network, list);
1138 		if (pnetwork == NULL)
1139 			return _FAIL;
1140 		pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1141 		if (pmlmepriv->assoc_by_bssid) {
1142 			dst_ssid = pnetwork->network.MacAddress;
1143 			src_ssid = pmlmepriv->assoc_bssid;
1144 			if (!memcmp(dst_ssid, src_ssid, ETH_ALEN)) {
1145 				if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1146 					if (is_same_network(&pmlmepriv->
1147 					    cur_network.network,
1148 					    &pnetwork->network)) {
1149 						_clr_fwstate_(pmlmepriv,
1150 							_FW_UNDER_LINKING);
1151 						/*r8712_indicate_connect again*/
1152 						r8712_indicate_connect(adapter);
1153 						return 2;
1154 					}
1155 					r8712_disassoc_cmd(adapter);
1156 					r8712_ind_disconnect(adapter);
1157 					r8712_free_assoc_resources(adapter);
1158 				}
1159 				goto ask_for_joinbss;
1160 			}
1161 		} else if (pmlmepriv->assoc_ssid.SsidLength == 0) {
1162 			goto ask_for_joinbss;
1163 		}
1164 		dst_ssid = pnetwork->network.Ssid.Ssid;
1165 		src_ssid = pmlmepriv->assoc_ssid.Ssid;
1166 		if ((pnetwork->network.Ssid.SsidLength ==
1167 		    pmlmepriv->assoc_ssid.SsidLength) &&
1168 		    (!memcmp(dst_ssid, src_ssid,
1169 		     pmlmepriv->assoc_ssid.SsidLength))) {
1170 			if (pmlmepriv->assoc_by_rssi) {
1171 				/* if the ssid is the same, select the bss
1172 				 * which has the max rssi
1173 				 */
1174 				if (pnetwork_max_rssi) {
1175 					if (pnetwork->network.Rssi >
1176 					    pnetwork_max_rssi->network.Rssi)
1177 						pnetwork_max_rssi = pnetwork;
1178 				} else {
1179 					pnetwork_max_rssi = pnetwork;
1180 				}
1181 			} else if (is_desired_network(adapter, pnetwork)) {
1182 				if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1183 					r8712_disassoc_cmd(adapter);
1184 					r8712_free_assoc_resources(adapter);
1185 				}
1186 				goto ask_for_joinbss;
1187 			}
1188 		}
1189 	}
1190 
1191 ask_for_joinbss:
1192 	return r8712_joinbss_cmd(adapter, pnetwork);
1193 }
1194 
r8712_set_auth(struct _adapter * adapter,struct security_priv * psecuritypriv)1195 sint r8712_set_auth(struct _adapter *adapter,
1196 		    struct security_priv *psecuritypriv)
1197 {
1198 	struct cmd_priv	*pcmdpriv = &adapter->cmdpriv;
1199 	struct cmd_obj *pcmd;
1200 	struct setauth_parm *psetauthparm;
1201 
1202 	pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
1203 	if (!pcmd)
1204 		return _FAIL;
1205 
1206 	psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_ATOMIC);
1207 	if (!psetauthparm) {
1208 		kfree(pcmd);
1209 		return _FAIL;
1210 	}
1211 	psetauthparm->mode = (u8)psecuritypriv->AuthAlgrthm;
1212 	pcmd->cmdcode = _SetAuth_CMD_;
1213 	pcmd->parmbuf = (unsigned char *)psetauthparm;
1214 	pcmd->cmdsz = sizeof(struct setauth_parm);
1215 	pcmd->rsp = NULL;
1216 	pcmd->rspsz = 0;
1217 	INIT_LIST_HEAD(&pcmd->list);
1218 	r8712_enqueue_cmd(pcmdpriv, pcmd);
1219 	return _SUCCESS;
1220 }
1221 
r8712_set_key(struct _adapter * adapter,struct security_priv * psecuritypriv,sint keyid)1222 sint r8712_set_key(struct _adapter *adapter,
1223 		   struct security_priv *psecuritypriv,
1224 	     sint keyid)
1225 {
1226 	struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1227 	struct cmd_obj *pcmd;
1228 	struct setkey_parm *psetkeyparm;
1229 	u8 keylen;
1230 	sint ret = _SUCCESS;
1231 
1232 	pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
1233 	if (!pcmd)
1234 		return _FAIL;
1235 	psetkeyparm = kzalloc(sizeof(*psetkeyparm), GFP_ATOMIC);
1236 	if (!psetkeyparm) {
1237 		ret = _FAIL;
1238 		goto err_free_cmd;
1239 	}
1240 	if (psecuritypriv->AuthAlgrthm == 2) { /* 802.1X */
1241 		psetkeyparm->algorithm =
1242 			 (u8)psecuritypriv->XGrpPrivacy;
1243 	} else { /* WEP */
1244 		psetkeyparm->algorithm =
1245 			 (u8)psecuritypriv->PrivacyAlgrthm;
1246 	}
1247 	psetkeyparm->keyid = (u8)keyid;
1248 
1249 	switch (psetkeyparm->algorithm) {
1250 	case _WEP40_:
1251 		keylen = 5;
1252 		memcpy(psetkeyparm->key,
1253 			psecuritypriv->DefKey[keyid].skey, keylen);
1254 		break;
1255 	case _WEP104_:
1256 		keylen = 13;
1257 		memcpy(psetkeyparm->key,
1258 			psecuritypriv->DefKey[keyid].skey, keylen);
1259 		break;
1260 	case _TKIP_:
1261 		if (keyid < 1 || keyid > 2) {
1262 			ret = _FAIL;
1263 			goto err_free_parm;
1264 		}
1265 		keylen = 16;
1266 		memcpy(psetkeyparm->key,
1267 			&psecuritypriv->XGrpKey[keyid - 1], keylen);
1268 		psetkeyparm->grpkey = 1;
1269 		break;
1270 	case _AES_:
1271 		if (keyid < 1 || keyid > 2) {
1272 			ret = _FAIL;
1273 			goto err_free_parm;
1274 		}
1275 		keylen = 16;
1276 		memcpy(psetkeyparm->key,
1277 			&psecuritypriv->XGrpKey[keyid - 1], keylen);
1278 		psetkeyparm->grpkey = 1;
1279 		break;
1280 	default:
1281 		ret = _FAIL;
1282 		goto err_free_parm;
1283 	}
1284 	pcmd->cmdcode = _SetKey_CMD_;
1285 	pcmd->parmbuf = (u8 *)psetkeyparm;
1286 	pcmd->cmdsz =  (sizeof(struct setkey_parm));
1287 	pcmd->rsp = NULL;
1288 	pcmd->rspsz = 0;
1289 	INIT_LIST_HEAD(&pcmd->list);
1290 	r8712_enqueue_cmd(pcmdpriv, pcmd);
1291 	return ret;
1292 
1293 err_free_parm:
1294 	kfree(psetkeyparm);
1295 err_free_cmd:
1296 	kfree(pcmd);
1297 	return ret;
1298 }
1299 
1300 /* adjust IEs for r8712_joinbss_cmd in WMM */
r8712_restruct_wmm_ie(struct _adapter * adapter,u8 * in_ie,u8 * out_ie,uint in_len,uint initial_out_len)1301 int r8712_restruct_wmm_ie(struct _adapter *adapter, u8 *in_ie, u8 *out_ie,
1302 		    uint in_len, uint initial_out_len)
1303 {
1304 	unsigned int ielength = 0;
1305 	unsigned int i, j;
1306 
1307 	i = 12; /* after the fixed IE */
1308 	while (i < in_len) {
1309 		ielength = initial_out_len;
1310 		if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 &&
1311 		    in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 &&
1312 		    in_ie[i + 5] == 0x02 && i + 5 < in_len) {
1313 			/*WMM element ID and OUI*/
1314 			for (j = i; j < i + 9; j++) {
1315 				out_ie[ielength] = in_ie[j];
1316 				ielength++;
1317 			}
1318 			out_ie[initial_out_len + 1] = 0x07;
1319 			out_ie[initial_out_len + 6] = 0x00;
1320 			out_ie[initial_out_len + 8] = 0x00;
1321 			break;
1322 		}
1323 		i += (in_ie[i + 1] + 2); /* to the next IE element */
1324 	}
1325 	return ielength;
1326 }
1327 
1328 /*
1329  * Ported from 8185: IsInPreAuthKeyList().
1330  *
1331  * Search by BSSID,
1332  * Return Value:
1333  *	-1		:if there is no pre-auth key in the  table
1334  *	>=0		:if there is pre-auth key, and   return the entry id
1335  */
SecIsInPMKIDList(struct _adapter * Adapter,u8 * bssid)1336 static int SecIsInPMKIDList(struct _adapter *Adapter, u8 *bssid)
1337 {
1338 	struct security_priv *psecuritypriv = &Adapter->securitypriv;
1339 	int i = 0;
1340 
1341 	do {
1342 		if (psecuritypriv->PMKIDList[i].bUsed &&
1343 		   (!memcmp(psecuritypriv->PMKIDList[i].Bssid,
1344 			    bssid, ETH_ALEN)))
1345 			break;
1346 		i++;
1347 
1348 	} while (i < NUM_PMKID_CACHE);
1349 
1350 	if (i == NUM_PMKID_CACHE) {
1351 		i = -1; /* Could not find. */
1352 	} else {
1353 		; /* There is one Pre-Authentication Key for the
1354 		   * specific BSSID.
1355 		   */
1356 	}
1357 	return i;
1358 }
1359 
r8712_restruct_sec_ie(struct _adapter * adapter,u8 * in_ie,u8 * out_ie,uint in_len)1360 sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie,
1361 		     u8 *out_ie, uint in_len)
1362 {
1363 	u8 authmode = 0, match;
1364 	u8 sec_ie[IW_CUSTOM_MAX], uncst_oui[4], bkup_ie[255];
1365 	u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01};
1366 	uint ielength, cnt, remove_cnt;
1367 	int iEntry;
1368 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1369 	struct security_priv *psecuritypriv = &adapter->securitypriv;
1370 	uint ndisauthmode = psecuritypriv->ndisauthtype;
1371 	uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
1372 
1373 	if ((ndisauthmode == Ndis802_11AuthModeWPA) ||
1374 	    (ndisauthmode == Ndis802_11AuthModeWPAPSK)) {
1375 		authmode = _WPA_IE_ID_;
1376 		uncst_oui[0] = 0x0;
1377 		uncst_oui[1] = 0x50;
1378 		uncst_oui[2] = 0xf2;
1379 	}
1380 	if ((ndisauthmode == Ndis802_11AuthModeWPA2) ||
1381 	    (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) {
1382 		authmode = _WPA2_IE_ID_;
1383 		uncst_oui[0] = 0x0;
1384 		uncst_oui[1] = 0x0f;
1385 		uncst_oui[2] = 0xac;
1386 	}
1387 	switch (ndissecuritytype) {
1388 	case Ndis802_11Encryption1Enabled:
1389 	case Ndis802_11Encryption1KeyAbsent:
1390 		uncst_oui[3] = 0x1;
1391 		break;
1392 	case Ndis802_11Encryption2Enabled:
1393 	case Ndis802_11Encryption2KeyAbsent:
1394 		uncst_oui[3] = 0x2;
1395 		break;
1396 	case Ndis802_11Encryption3Enabled:
1397 	case Ndis802_11Encryption3KeyAbsent:
1398 		uncst_oui[3] = 0x4;
1399 		break;
1400 	default:
1401 		break;
1402 	}
1403 	/*Search required WPA or WPA2 IE and copy to sec_ie[] */
1404 	cnt = 12;
1405 	match = false;
1406 	while (cnt < in_len) {
1407 		if (in_ie[cnt] == authmode) {
1408 			if ((authmode == _WPA_IE_ID_) &&
1409 			    (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) {
1410 				memcpy(&sec_ie[0], &in_ie[cnt],
1411 					in_ie[cnt + 1] + 2);
1412 				match = true;
1413 				break;
1414 			}
1415 			if (authmode == _WPA2_IE_ID_) {
1416 				memcpy(&sec_ie[0], &in_ie[cnt],
1417 					in_ie[cnt + 1] + 2);
1418 				match = true;
1419 				break;
1420 			}
1421 			if (((authmode == _WPA_IE_ID_) &&
1422 			     (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) ||
1423 			     (authmode == _WPA2_IE_ID_))
1424 				memcpy(&bkup_ie[0], &in_ie[cnt],
1425 					in_ie[cnt + 1] + 2);
1426 		}
1427 		cnt += in_ie[cnt + 1] + 2; /*get next*/
1428 	}
1429 	/*restruct WPA IE or WPA2 IE in sec_ie[] */
1430 	if (match) {
1431 		if (sec_ie[0] == _WPA_IE_ID_) {
1432 			/* parsing SSN IE to select required encryption
1433 			 * algorithm, and set the bc/mc encryption algorithm
1434 			 */
1435 			while (true) {
1436 				/*check wpa_oui tag*/
1437 				if (memcmp(&sec_ie[2], &wpa_oui[0], 4)) {
1438 					match = false;
1439 					break;
1440 				}
1441 				if ((sec_ie[6] != 0x01) || (sec_ie[7] != 0x0)) {
1442 					/*IE Ver error*/
1443 					match = false;
1444 					break;
1445 				}
1446 				if (!memcmp(&sec_ie[8], &wpa_oui[0], 3)) {
1447 					/* get bc/mc encryption type (group
1448 					 * key type)
1449 					 */
1450 					switch (sec_ie[11]) {
1451 					case 0x0: /*none*/
1452 						psecuritypriv->XGrpPrivacy =
1453 								_NO_PRIVACY_;
1454 						break;
1455 					case 0x1: /*WEP_40*/
1456 						psecuritypriv->XGrpPrivacy =
1457 								_WEP40_;
1458 						break;
1459 					case 0x2: /*TKIP*/
1460 						psecuritypriv->XGrpPrivacy =
1461 								_TKIP_;
1462 						break;
1463 					case 0x3: /*AESCCMP*/
1464 					case 0x4:
1465 						psecuritypriv->XGrpPrivacy =
1466 								_AES_;
1467 						break;
1468 					case 0x5: /*WEP_104*/
1469 						psecuritypriv->XGrpPrivacy =
1470 								_WEP104_;
1471 						break;
1472 					}
1473 				} else {
1474 					match = false;
1475 					break;
1476 				}
1477 				if (sec_ie[12] == 0x01) {
1478 					/*check the unicast encryption type*/
1479 					if (memcmp(&sec_ie[14],
1480 					    &uncst_oui[0], 4)) {
1481 						match = false;
1482 						break;
1483 
1484 					} /*else the uncst_oui is match*/
1485 				} else { /*mixed mode, unicast_enc_type > 1*/
1486 					/*select the uncst_oui and remove
1487 					 * the other uncst_oui
1488 					 */
1489 					cnt = sec_ie[12];
1490 					remove_cnt = (cnt - 1) * 4;
1491 					sec_ie[12] = 0x01;
1492 					memcpy(&sec_ie[14], &uncst_oui[0], 4);
1493 					/*remove the other unicast suit*/
1494 					memcpy(&sec_ie[18],
1495 						&sec_ie[18 + remove_cnt],
1496 						sec_ie[1] - 18 + 2 -
1497 						remove_cnt);
1498 					sec_ie[1] = sec_ie[1] - remove_cnt;
1499 				}
1500 				break;
1501 			}
1502 		}
1503 		if (authmode == _WPA2_IE_ID_) {
1504 			/* parsing RSN IE to select required encryption
1505 			 * algorithm, and set the bc/mc encryption algorithm
1506 			 */
1507 			while (true) {
1508 				if ((sec_ie[2] != 0x01) || (sec_ie[3] != 0x0)) {
1509 					/*IE Ver error*/
1510 					match = false;
1511 					break;
1512 				}
1513 				if (!memcmp(&sec_ie[4], &uncst_oui[0], 3)) {
1514 					/*get bc/mc encryption type*/
1515 					switch (sec_ie[7]) {
1516 					case 0x1: /*WEP_40*/
1517 						psecuritypriv->XGrpPrivacy =
1518 								_WEP40_;
1519 						break;
1520 					case 0x2: /*TKIP*/
1521 						psecuritypriv->XGrpPrivacy =
1522 								_TKIP_;
1523 						break;
1524 					case 0x4: /*AESWRAP*/
1525 						psecuritypriv->XGrpPrivacy =
1526 								_AES_;
1527 						break;
1528 					case 0x5: /*WEP_104*/
1529 						psecuritypriv->XGrpPrivacy =
1530 								_WEP104_;
1531 						break;
1532 					default: /*one*/
1533 						psecuritypriv->XGrpPrivacy =
1534 								_NO_PRIVACY_;
1535 						break;
1536 					}
1537 				} else {
1538 					match = false;
1539 					break;
1540 				}
1541 				if (sec_ie[8] == 0x01) {
1542 					/*check the unicast encryption type*/
1543 					if (memcmp(&sec_ie[10],
1544 						     &uncst_oui[0], 4)) {
1545 						match = false;
1546 						break;
1547 					} /*else the uncst_oui is match*/
1548 				} else { /*mixed mode, unicast_enc_type > 1*/
1549 					/*select the uncst_oui and remove the
1550 					 * other uncst_oui
1551 					 */
1552 					cnt = sec_ie[8];
1553 					remove_cnt = (cnt - 1) * 4;
1554 					sec_ie[8] = 0x01;
1555 					memcpy(&sec_ie[10], &uncst_oui[0], 4);
1556 					/*remove the other unicast suit*/
1557 					memcpy(&sec_ie[14],
1558 						&sec_ie[14 + remove_cnt],
1559 						(sec_ie[1] - 14 + 2 -
1560 						remove_cnt));
1561 					sec_ie[1] = sec_ie[1] - remove_cnt;
1562 				}
1563 				break;
1564 			}
1565 		}
1566 	}
1567 	if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) {
1568 		/*copy fixed ie*/
1569 		memcpy(out_ie, in_ie, 12);
1570 		ielength = 12;
1571 		/*copy RSN or SSN*/
1572 		if (match) {
1573 			memcpy(&out_ie[ielength], &sec_ie[0], sec_ie[1] + 2);
1574 			ielength += sec_ie[1] + 2;
1575 			if (authmode == _WPA2_IE_ID_) {
1576 				/*the Pre-Authentication bit should be zero*/
1577 				out_ie[ielength - 1] = 0;
1578 				out_ie[ielength - 2] = 0;
1579 			}
1580 			r8712_report_sec_ie(adapter, authmode, sec_ie);
1581 		}
1582 	} else {
1583 		/*copy fixed ie only*/
1584 		memcpy(out_ie, in_ie, 12);
1585 		ielength = 12;
1586 		if (psecuritypriv->wps_phase) {
1587 			memcpy(out_ie + ielength, psecuritypriv->wps_ie,
1588 			       psecuritypriv->wps_ie_len);
1589 			ielength += psecuritypriv->wps_ie_len;
1590 		}
1591 	}
1592 	iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
1593 	if (iEntry < 0)
1594 		return ielength;
1595 	if (authmode == _WPA2_IE_ID_) {
1596 		out_ie[ielength] = 1;
1597 		ielength++;
1598 		out_ie[ielength] = 0;	/*PMKID count = 0x0100*/
1599 		ielength++;
1600 		memcpy(&out_ie[ielength],
1601 			&psecuritypriv->PMKIDList[iEntry].PMKID, 16);
1602 		ielength += 16;
1603 		out_ie[13] += 18;/*PMKID length = 2+16*/
1604 	}
1605 	return ielength;
1606 }
1607 
r8712_init_registrypriv_dev_network(struct _adapter * adapter)1608 void r8712_init_registrypriv_dev_network(struct _adapter *adapter)
1609 {
1610 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
1611 	struct eeprom_priv *peepriv = &adapter->eeprompriv;
1612 	struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
1613 	u8 *myhwaddr = myid(peepriv);
1614 
1615 	memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
1616 	memcpy(&pdev_network->Ssid, &pregistrypriv->ssid,
1617 		sizeof(struct ndis_802_11_ssid));
1618 	pdev_network->Configuration.Length =
1619 			 sizeof(struct NDIS_802_11_CONFIGURATION);
1620 	pdev_network->Configuration.BeaconPeriod = 100;
1621 	pdev_network->Configuration.FHConfig.Length = 0;
1622 	pdev_network->Configuration.FHConfig.HopPattern = 0;
1623 	pdev_network->Configuration.FHConfig.HopSet = 0;
1624 	pdev_network->Configuration.FHConfig.DwellTime = 0;
1625 }
1626 
r8712_update_registrypriv_dev_network(struct _adapter * adapter)1627 void r8712_update_registrypriv_dev_network(struct _adapter *adapter)
1628 {
1629 	int sz = 0;
1630 	struct registry_priv	*pregistrypriv = &adapter->registrypriv;
1631 	struct wlan_bssid_ex	*pdev_network = &pregistrypriv->dev_network;
1632 	struct security_priv	*psecuritypriv = &adapter->securitypriv;
1633 	struct wlan_network	*cur_network = &adapter->mlmepriv.cur_network;
1634 
1635 	pdev_network->Privacy = cpu_to_le32(psecuritypriv->PrivacyAlgrthm
1636 					    > 0 ? 1 : 0); /* adhoc no 802.1x */
1637 	pdev_network->Rssi = 0;
1638 	switch (pregistrypriv->wireless_mode) {
1639 	case WIRELESS_11B:
1640 		pdev_network->NetworkTypeInUse = Ndis802_11DS;
1641 		break;
1642 	case WIRELESS_11G:
1643 	case WIRELESS_11BG:
1644 		pdev_network->NetworkTypeInUse = Ndis802_11OFDM24;
1645 		break;
1646 	case WIRELESS_11A:
1647 		pdev_network->NetworkTypeInUse = Ndis802_11OFDM5;
1648 		break;
1649 	default:
1650 		/* TODO */
1651 		break;
1652 	}
1653 	pdev_network->Configuration.DSConfig = pregistrypriv->channel;
1654 	if (cur_network->network.InfrastructureMode == Ndis802_11IBSS)
1655 		pdev_network->Configuration.ATIMWindow = 3;
1656 	pdev_network->InfrastructureMode = cur_network->network.InfrastructureMode;
1657 	/* 1. Supported rates
1658 	 * 2. IE
1659 	 */
1660 	sz = r8712_generate_ie(pregistrypriv);
1661 	pdev_network->IELength = sz;
1662 	pdev_network->Length = r8712_get_wlan_bssid_ex_sz(pdev_network);
1663 }
1664 
1665 /*the function is at passive_level*/
r8712_joinbss_reset(struct _adapter * padapter)1666 void r8712_joinbss_reset(struct _adapter *padapter)
1667 {
1668 	int i;
1669 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1670 	struct ht_priv		*phtpriv = &pmlmepriv->htpriv;
1671 
1672 	/* todo: if you want to do something io/reg/hw setting before join_bss,
1673 	 * please add code here
1674 	 */
1675 	phtpriv->ampdu_enable = false;/*reset to disabled*/
1676 	for (i = 0; i < 16; i++)
1677 		phtpriv->baddbareq_issued[i] = false;/*reset it*/
1678 	if (phtpriv->ht_option) {
1679 		/* validate  usb rx aggregation */
1680 		r8712_write8(padapter, 0x102500D9, 48);/*TH = 48 pages, 6k*/
1681 	} else {
1682 		/* invalidate  usb rx aggregation */
1683 		/* TH=1 => means that invalidate usb rx aggregation */
1684 		r8712_write8(padapter, 0x102500D9, 1);
1685 	}
1686 }
1687 
1688 /*the function is >= passive_level*/
r8712_restructure_ht_ie(struct _adapter * padapter,u8 * in_ie,u8 * out_ie,uint in_len,uint * pout_len)1689 unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie,
1690 				     u8 *out_ie, uint in_len, uint *pout_len)
1691 {
1692 	u32 ielen, out_len;
1693 	unsigned char *p;
1694 	struct ieee80211_ht_cap ht_capie;
1695 	unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
1696 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1697 	struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1698 	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1699 
1700 	phtpriv->ht_option = 0;
1701 	p = r8712_get_ie(in_ie + 12, _HT_CAPABILITY_IE_, &ielen, in_len - 12);
1702 	if (p && (ielen > 0)) {
1703 		if (pqospriv->qos_option == 0) {
1704 			out_len = *pout_len;
1705 			r8712_set_ie(out_ie + out_len, _VENDOR_SPECIFIC_IE_,
1706 				     _WMM_IE_Length_, WMM_IE, pout_len);
1707 			pqospriv->qos_option = 1;
1708 		}
1709 		out_len = *pout_len;
1710 		memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap));
1711 		ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH |
1712 				    IEEE80211_HT_CAP_SGI_20 |
1713 				    IEEE80211_HT_CAP_SGI_40 |
1714 				    IEEE80211_HT_CAP_TX_STBC |
1715 				    IEEE80211_HT_CAP_MAX_AMSDU |
1716 				    IEEE80211_HT_CAP_DSSSCCK40);
1717 		ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR &
1718 				0x03) | (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00);
1719 		r8712_set_ie(out_ie + out_len, _HT_CAPABILITY_IE_,
1720 			     sizeof(struct ieee80211_ht_cap),
1721 			     (unsigned char *)&ht_capie, pout_len);
1722 		phtpriv->ht_option = 1;
1723 	}
1724 	return phtpriv->ht_option;
1725 }
1726 
1727 /* the function is > passive_level (in critical_section) */
update_ht_cap(struct _adapter * padapter,u8 * pie,uint ie_len)1728 static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len)
1729 {
1730 	u8 *p, max_ampdu_sz;
1731 	int i, len;
1732 	struct sta_info *bmc_sta, *psta;
1733 	struct ieee80211_ht_cap *pht_capie;
1734 	struct recv_reorder_ctrl *preorder_ctrl;
1735 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1736 	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1737 	struct registry_priv *pregistrypriv = &padapter->registrypriv;
1738 	struct wlan_network *pcur_network = &(pmlmepriv->cur_network);
1739 
1740 	if (!phtpriv->ht_option)
1741 		return;
1742 	/* maybe needs check if ap supports rx ampdu. */
1743 	if (!phtpriv->ampdu_enable &&
1744 	    (pregistrypriv->ampdu_enable == 1))
1745 		phtpriv->ampdu_enable = true;
1746 	/*check Max Rx A-MPDU Size*/
1747 	len = 0;
1748 	p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs),
1749 				_HT_CAPABILITY_IE_,
1750 				&len, ie_len -
1751 				sizeof(struct NDIS_802_11_FIXED_IEs));
1752 	if (p && len > 0) {
1753 		pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1754 		max_ampdu_sz = (pht_capie->ampdu_params_info &
1755 				IEEE80211_HT_CAP_AMPDU_FACTOR);
1756 		/* max_ampdu_sz (kbytes); */
1757 		max_ampdu_sz = 1 << (max_ampdu_sz + 3);
1758 		phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
1759 	}
1760 	/* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info
1761 	 * if A-MPDU Rx is enabled, resetting rx_ordering_ctrl
1762 	 * wstart_b(indicate_seq) to default value=0xffff
1763 	 * todo: check if AP can send A-MPDU packets
1764 	 */
1765 	bmc_sta = r8712_get_bcmc_stainfo(padapter);
1766 	if (bmc_sta) {
1767 		for (i = 0; i < 16; i++) {
1768 			preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
1769 			preorder_ctrl->indicate_seq = 0xffff;
1770 			preorder_ctrl->wend_b = 0xffff;
1771 		}
1772 	}
1773 	psta = r8712_get_stainfo(&padapter->stapriv,
1774 				 pcur_network->network.MacAddress);
1775 	if (psta) {
1776 		for (i = 0; i < 16; i++) {
1777 			preorder_ctrl = &psta->recvreorder_ctrl[i];
1778 			preorder_ctrl->indicate_seq = 0xffff;
1779 			preorder_ctrl->wend_b = 0xffff;
1780 		}
1781 	}
1782 	len = 0;
1783 	p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs),
1784 		   _HT_ADD_INFO_IE_, &len,
1785 		   ie_len - sizeof(struct NDIS_802_11_FIXED_IEs));
1786 }
1787 
r8712_issue_addbareq_cmd(struct _adapter * padapter,int priority)1788 void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority)
1789 {
1790 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1791 	struct ht_priv	 *phtpriv = &pmlmepriv->htpriv;
1792 
1793 	if ((phtpriv->ht_option == 1) && (phtpriv->ampdu_enable)) {
1794 		if (!phtpriv->baddbareq_issued[priority]) {
1795 			r8712_addbareq_cmd(padapter, (u8)priority);
1796 			phtpriv->baddbareq_issued[priority] = true;
1797 		}
1798 	}
1799 }
1800