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