1/* IEEE 802.11 SoftMAC layer
2 * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
3 *
4 * Mostly extracted from the rtl8180-sa2400 driver for the
5 * in-kernel generic ieee802.11 stack.
6 *
7 * Few lines might be stolen from other part of the rtllib
8 * stack. Copyright who own it's copyright
9 *
10 * WPA code stolen from the ipw2200 driver.
11 * Copyright who own it's copyright.
12 *
13 * released under the GPL
14 */
15
16
17#include "rtllib.h"
18
19#include <linux/random.h>
20#include <linux/delay.h>
21#include <linux/uaccess.h>
22#include <linux/etherdevice.h>
23#include <linux/ieee80211.h>
24#include "dot11d.h"
25
26static void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl);
27
28
29static short rtllib_is_54g(struct rtllib_network *net)
30{
31	return (net->rates_ex_len > 0) || (net->rates_len > 4);
32}
33
34/* returns the total length needed for placing the RATE MFIE
35 * tag and the EXTENDED RATE MFIE tag if needed.
36 * It encludes two bytes per tag for the tag itself and its len
37 */
38static unsigned int rtllib_MFIE_rate_len(struct rtllib_device *ieee)
39{
40	unsigned int rate_len = 0;
41
42	if (ieee->modulation & RTLLIB_CCK_MODULATION)
43		rate_len = RTLLIB_CCK_RATE_LEN + 2;
44
45	if (ieee->modulation & RTLLIB_OFDM_MODULATION)
46
47		rate_len += RTLLIB_OFDM_RATE_LEN + 2;
48
49	return rate_len;
50}
51
52/* place the MFIE rate, tag to the memory (double) pointed.
53 * Then it updates the pointer so that
54 * it points after the new MFIE tag added.
55 */
56static void rtllib_MFIE_Brate(struct rtllib_device *ieee, u8 **tag_p)
57{
58	u8 *tag = *tag_p;
59
60	if (ieee->modulation & RTLLIB_CCK_MODULATION) {
61		*tag++ = MFIE_TYPE_RATES;
62		*tag++ = 4;
63		*tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB;
64		*tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB;
65		*tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB;
66		*tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB;
67	}
68
69	/* We may add an option for custom rates that specific HW
70	 * might support
71	 */
72	*tag_p = tag;
73}
74
75static void rtllib_MFIE_Grate(struct rtllib_device *ieee, u8 **tag_p)
76{
77	u8 *tag = *tag_p;
78
79	if (ieee->modulation & RTLLIB_OFDM_MODULATION) {
80		*tag++ = MFIE_TYPE_RATES_EX;
81		*tag++ = 8;
82		*tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_6MB;
83		*tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_9MB;
84		*tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_12MB;
85		*tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_18MB;
86		*tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_24MB;
87		*tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_36MB;
88		*tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_48MB;
89		*tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_54MB;
90	}
91	/* We may add an option for custom rates that specific HW might
92	 * support
93	 */
94	*tag_p = tag;
95}
96
97static void rtllib_WMM_Info(struct rtllib_device *ieee, u8 **tag_p)
98{
99	u8 *tag = *tag_p;
100
101	*tag++ = MFIE_TYPE_GENERIC;
102	*tag++ = 7;
103	*tag++ = 0x00;
104	*tag++ = 0x50;
105	*tag++ = 0xf2;
106	*tag++ = 0x02;
107	*tag++ = 0x00;
108	*tag++ = 0x01;
109	*tag++ = MAX_SP_Len;
110	*tag_p = tag;
111}
112
113static void rtllib_TURBO_Info(struct rtllib_device *ieee, u8 **tag_p)
114{
115	u8 *tag = *tag_p;
116
117	*tag++ = MFIE_TYPE_GENERIC;
118	*tag++ = 7;
119	*tag++ = 0x00;
120	*tag++ = 0xe0;
121	*tag++ = 0x4c;
122	*tag++ = 0x01;
123	*tag++ = 0x02;
124	*tag++ = 0x11;
125	*tag++ = 0x00;
126
127	*tag_p = tag;
128	netdev_alert(ieee->dev, "This is enable turbo mode IE process\n");
129}
130
131static void enqueue_mgmt(struct rtllib_device *ieee, struct sk_buff *skb)
132{
133	int nh;
134
135	nh = (ieee->mgmt_queue_head + 1) % MGMT_QUEUE_NUM;
136
137/* if the queue is full but we have newer frames then
138 * just overwrites the oldest.
139 *
140 * if (nh == ieee->mgmt_queue_tail)
141 *		return -1;
142 */
143	ieee->mgmt_queue_head = nh;
144	ieee->mgmt_queue_ring[nh] = skb;
145
146}
147
148static void init_mgmt_queue(struct rtllib_device *ieee)
149{
150	ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
151}
152
153
154u8
155MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee)
156{
157	u16	i;
158	u8	QueryRate = 0;
159	u8	BasicRate;
160
161
162	for (i = 0; i < ieee->current_network.rates_len; i++) {
163		BasicRate = ieee->current_network.rates[i]&0x7F;
164		if (!rtllib_is_cck_rate(BasicRate)) {
165			if (QueryRate == 0) {
166				QueryRate = BasicRate;
167			} else {
168				if (BasicRate < QueryRate)
169					QueryRate = BasicRate;
170			}
171		}
172	}
173
174	if (QueryRate == 0) {
175		QueryRate = 12;
176		netdev_info(ieee->dev, "No BasicRate found!!\n");
177	}
178	return QueryRate;
179}
180
181static u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee)
182{
183	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
184	u8 rate;
185
186	if (pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
187		rate = 0x0c;
188	else
189		rate = ieee->basic_rate & 0x7f;
190
191	if (rate == 0) {
192		if (ieee->mode == IEEE_A ||
193		   ieee->mode == IEEE_N_5G ||
194		   (ieee->mode == IEEE_N_24G && !pHTInfo->bCurSuppCCK))
195			rate = 0x0c;
196		else
197			rate = 0x02;
198	}
199
200	return rate;
201}
202
203inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee)
204{
205	unsigned long flags;
206	short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
207	struct rtllib_hdr_3addr  *header =
208		(struct rtllib_hdr_3addr  *) skb->data;
209
210	struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
211
212	spin_lock_irqsave(&ieee->lock, flags);
213
214	/* called with 2nd param 0, no mgmt lock required */
215	rtllib_sta_wakeup(ieee, 0);
216
217	if (le16_to_cpu(header->frame_ctl) == RTLLIB_STYPE_BEACON)
218		tcb_desc->queue_index = BEACON_QUEUE;
219	else
220		tcb_desc->queue_index = MGNT_QUEUE;
221
222	if (ieee->disable_mgnt_queue)
223		tcb_desc->queue_index = HIGH_QUEUE;
224
225	tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
226	tcb_desc->RATRIndex = 7;
227	tcb_desc->bTxDisableRateFallBack = 1;
228	tcb_desc->bTxUseDriverAssingedRate = 1;
229	if (single) {
230		if (ieee->queue_stop) {
231			enqueue_mgmt(ieee, skb);
232		} else {
233			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
234
235			if (ieee->seq_ctrl[0] == 0xFFF)
236				ieee->seq_ctrl[0] = 0;
237			else
238				ieee->seq_ctrl[0]++;
239
240			/* avoid watchdog triggers */
241			ieee->softmac_data_hard_start_xmit(skb, ieee->dev,
242							   ieee->basic_rate);
243		}
244
245		spin_unlock_irqrestore(&ieee->lock, flags);
246	} else {
247		spin_unlock_irqrestore(&ieee->lock, flags);
248		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
249
250		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
251
252		if (ieee->seq_ctrl[0] == 0xFFF)
253			ieee->seq_ctrl[0] = 0;
254		else
255			ieee->seq_ctrl[0]++;
256
257		/* check whether the managed packet queued greater than 5 */
258		if (!ieee->check_nic_enough_desc(ieee->dev,
259						 tcb_desc->queue_index) ||
260		    skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) ||
261		    ieee->queue_stop) {
262			/* insert the skb packet to the management queue
263			 *
264			 * as for the completion function, it does not need
265			 * to check it any more.
266			 */
267			netdev_info(ieee->dev,
268			       "%s():insert to waitqueue, queue_index:%d!\n",
269			       __func__, tcb_desc->queue_index);
270			skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index],
271				       skb);
272		} else {
273			ieee->softmac_hard_start_xmit(skb, ieee->dev);
274		}
275		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
276	}
277}
278
279inline void softmac_ps_mgmt_xmit(struct sk_buff *skb,
280		struct rtllib_device *ieee)
281{
282	short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
283	struct rtllib_hdr_3addr  *header =
284		(struct rtllib_hdr_3addr  *) skb->data;
285	u16 fc, type, stype;
286	struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
287
288	fc = le16_to_cpu(header->frame_ctl);
289	type = WLAN_FC_GET_TYPE(fc);
290	stype = WLAN_FC_GET_STYPE(fc);
291
292
293	if (stype != RTLLIB_STYPE_PSPOLL)
294		tcb_desc->queue_index = MGNT_QUEUE;
295	else
296		tcb_desc->queue_index = HIGH_QUEUE;
297
298	if (ieee->disable_mgnt_queue)
299		tcb_desc->queue_index = HIGH_QUEUE;
300
301
302	tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
303	tcb_desc->RATRIndex = 7;
304	tcb_desc->bTxDisableRateFallBack = 1;
305	tcb_desc->bTxUseDriverAssingedRate = 1;
306	if (single) {
307		if (type != RTLLIB_FTYPE_CTL) {
308			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
309
310			if (ieee->seq_ctrl[0] == 0xFFF)
311				ieee->seq_ctrl[0] = 0;
312			else
313				ieee->seq_ctrl[0]++;
314
315		}
316		/* avoid watchdog triggers */
317		ieee->softmac_data_hard_start_xmit(skb, ieee->dev,
318						   ieee->basic_rate);
319
320	} else {
321		if (type != RTLLIB_FTYPE_CTL) {
322			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
323
324			if (ieee->seq_ctrl[0] == 0xFFF)
325				ieee->seq_ctrl[0] = 0;
326			else
327				ieee->seq_ctrl[0]++;
328		}
329		ieee->softmac_hard_start_xmit(skb, ieee->dev);
330
331	}
332}
333
334static inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee)
335{
336	unsigned int len, rate_len;
337	u8 *tag;
338	struct sk_buff *skb;
339	struct rtllib_probe_request *req;
340
341	len = ieee->current_network.ssid_len;
342
343	rate_len = rtllib_MFIE_rate_len(ieee);
344
345	skb = dev_alloc_skb(sizeof(struct rtllib_probe_request) +
346			    2 + len + rate_len + ieee->tx_headroom);
347
348	if (!skb)
349		return NULL;
350
351	skb_reserve(skb, ieee->tx_headroom);
352
353	req = (struct rtllib_probe_request *) skb_put(skb,
354	      sizeof(struct rtllib_probe_request));
355	req->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_REQ);
356	req->header.duration_id = 0;
357
358	memset(req->header.addr1, 0xff, ETH_ALEN);
359	ether_addr_copy(req->header.addr2, ieee->dev->dev_addr);
360	memset(req->header.addr3, 0xff, ETH_ALEN);
361
362	tag = (u8 *) skb_put(skb, len + 2 + rate_len);
363
364	*tag++ = MFIE_TYPE_SSID;
365	*tag++ = len;
366	memcpy(tag, ieee->current_network.ssid, len);
367	tag += len;
368
369	rtllib_MFIE_Brate(ieee, &tag);
370	rtllib_MFIE_Grate(ieee, &tag);
371
372	return skb;
373}
374
375static struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee);
376
377static void rtllib_send_beacon(struct rtllib_device *ieee)
378{
379	struct sk_buff *skb;
380
381	if (!ieee->ieee_up)
382		return;
383	skb = rtllib_get_beacon_(ieee);
384
385	if (skb) {
386		softmac_mgmt_xmit(skb, ieee);
387		ieee->softmac_stats.tx_beacons++;
388	}
389
390	if (ieee->beacon_txing && ieee->ieee_up)
391		mod_timer(&ieee->beacon_timer, jiffies +
392			  (msecs_to_jiffies(ieee->current_network.beacon_interval - 5)));
393}
394
395
396static void rtllib_send_beacon_cb(unsigned long _ieee)
397{
398	struct rtllib_device *ieee =
399		(struct rtllib_device *) _ieee;
400	unsigned long flags;
401
402	spin_lock_irqsave(&ieee->beacon_lock, flags);
403	rtllib_send_beacon(ieee);
404	spin_unlock_irqrestore(&ieee->beacon_lock, flags);
405}
406
407/* Enables network monitor mode, all rx packets will be received. */
408void rtllib_EnableNetMonitorMode(struct net_device *dev,
409		bool bInitState)
410{
411	struct rtllib_device *ieee = netdev_priv_rsl(dev);
412
413	netdev_info(dev, "========>Enter Monitor Mode\n");
414
415	ieee->AllowAllDestAddrHandler(dev, true, !bInitState);
416}
417
418
419/* Disables network monitor mode. Only packets destinated to
420 * us will be received.
421 */
422void rtllib_DisableNetMonitorMode(struct net_device *dev,
423		bool bInitState)
424{
425	struct rtllib_device *ieee = netdev_priv_rsl(dev);
426
427	netdev_info(dev, "========>Exit Monitor Mode\n");
428
429	ieee->AllowAllDestAddrHandler(dev, false, !bInitState);
430}
431
432
433/* Enables the specialized promiscuous mode required by Intel.
434 * In this mode, Intel intends to hear traffics from/to other STAs in the
435 * same BSS. Therefore we don't have to disable checking BSSID and we only need
436 * to allow all dest. BUT: if we enable checking BSSID then we can't recv
437 * packets from other STA.
438 */
439void rtllib_EnableIntelPromiscuousMode(struct net_device *dev,
440		bool bInitState)
441{
442	bool bFilterOutNonAssociatedBSSID = false;
443
444	struct rtllib_device *ieee = netdev_priv_rsl(dev);
445
446	netdev_info(dev, "========>Enter Intel Promiscuous Mode\n");
447
448	ieee->AllowAllDestAddrHandler(dev, true, !bInitState);
449	ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID,
450			     (u8 *)&bFilterOutNonAssociatedBSSID);
451
452	ieee->bNetPromiscuousMode = true;
453}
454EXPORT_SYMBOL(rtllib_EnableIntelPromiscuousMode);
455
456
457/* Disables the specialized promiscuous mode required by Intel.
458 * See MgntEnableIntelPromiscuousMode for detail.
459 */
460void rtllib_DisableIntelPromiscuousMode(struct net_device *dev,
461		bool bInitState)
462{
463	bool bFilterOutNonAssociatedBSSID = true;
464
465	struct rtllib_device *ieee = netdev_priv_rsl(dev);
466
467	netdev_info(dev, "========>Exit Intel Promiscuous Mode\n");
468
469	ieee->AllowAllDestAddrHandler(dev, false, !bInitState);
470	ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID,
471			     (u8 *)&bFilterOutNonAssociatedBSSID);
472
473	ieee->bNetPromiscuousMode = false;
474}
475EXPORT_SYMBOL(rtllib_DisableIntelPromiscuousMode);
476
477static void rtllib_send_probe(struct rtllib_device *ieee, u8 is_mesh)
478{
479	struct sk_buff *skb;
480
481	skb = rtllib_probe_req(ieee);
482	if (skb) {
483		softmac_mgmt_xmit(skb, ieee);
484		ieee->softmac_stats.tx_probe_rq++;
485	}
486}
487
488
489static void rtllib_send_probe_requests(struct rtllib_device *ieee, u8 is_mesh)
490{
491	if (ieee->active_scan && (ieee->softmac_features &
492	    IEEE_SOFTMAC_PROBERQ)) {
493		rtllib_send_probe(ieee, 0);
494		rtllib_send_probe(ieee, 0);
495	}
496}
497
498static void rtllib_update_active_chan_map(struct rtllib_device *ieee)
499{
500	memcpy(ieee->active_channel_map, GET_DOT11D_INFO(ieee)->channel_map,
501	       MAX_CHANNEL_NUMBER+1);
502}
503
504/* this performs syncro scan blocking the caller until all channels
505 * in the allowed channel map has been checked.
506 */
507static void rtllib_softmac_scan_syncro(struct rtllib_device *ieee, u8 is_mesh)
508{
509	union iwreq_data wrqu;
510	short ch = 0;
511
512	rtllib_update_active_chan_map(ieee);
513
514	ieee->be_scan_inprogress = true;
515
516	down(&ieee->scan_sem);
517
518	while (1) {
519		do {
520			ch++;
521			if (ch > MAX_CHANNEL_NUMBER)
522				goto out; /* scan completed */
523		} while (!ieee->active_channel_map[ch]);
524
525		/* this function can be called in two situations
526		 * 1- We have switched to ad-hoc mode and we are
527		 *    performing a complete syncro scan before conclude
528		 *    there are no interesting cell and to create a
529		 *    new one. In this case the link state is
530		 *    RTLLIB_NOLINK until we found an interesting cell.
531		 *    If so the ieee8021_new_net, called by the RX path
532		 *    will set the state to RTLLIB_LINKED, so we stop
533		 *    scanning
534		 * 2- We are linked and the root uses run iwlist scan.
535		 *    So we switch to RTLLIB_LINKED_SCANNING to remember
536		 *    that we are still logically linked (not interested in
537		 *    new network events, despite for updating the net list,
538		 *    but we are temporarly 'unlinked' as the driver shall
539		 *    not filter RX frames and the channel is changing.
540		 * So the only situation in which are interested is to check
541		 * if the state become LINKED because of the #1 situation
542		 */
543
544		if (ieee->state == RTLLIB_LINKED)
545			goto out;
546		if (ieee->sync_scan_hurryup) {
547			netdev_info(ieee->dev,
548				    "============>sync_scan_hurryup out\n");
549			goto out;
550		}
551
552		ieee->set_chan(ieee->dev, ch);
553		if (ieee->active_channel_map[ch] == 1)
554			rtllib_send_probe_requests(ieee, 0);
555
556		/* this prevent excessive time wait when we
557		 * need to wait for a syncro scan to end..
558		 */
559		msleep_interruptible_rsl(RTLLIB_SOFTMAC_SCAN_TIME);
560	}
561out:
562	ieee->actscanning = false;
563	ieee->sync_scan_hurryup = 0;
564
565	if (ieee->state >= RTLLIB_LINKED) {
566		if (IS_DOT11D_ENABLE(ieee))
567			DOT11D_ScanComplete(ieee);
568	}
569	up(&ieee->scan_sem);
570
571	ieee->be_scan_inprogress = false;
572
573	memset(&wrqu, 0, sizeof(wrqu));
574	wireless_send_event(ieee->dev, SIOCGIWSCAN, &wrqu, NULL);
575}
576
577static void rtllib_softmac_scan_wq(void *data)
578{
579	struct rtllib_device *ieee = container_of_dwork_rsl(data,
580				     struct rtllib_device, softmac_scan_wq);
581	u8 last_channel = ieee->current_network.channel;
582
583	rtllib_update_active_chan_map(ieee);
584
585	if (!ieee->ieee_up)
586		return;
587	if (rtllib_act_scanning(ieee, true))
588		return;
589
590	down(&ieee->scan_sem);
591
592	if (ieee->eRFPowerState == eRfOff) {
593		netdev_info(ieee->dev,
594			    "======>%s():rf state is eRfOff, return\n",
595			    __func__);
596		goto out1;
597	}
598
599	do {
600		ieee->current_network.channel =
601			(ieee->current_network.channel + 1) %
602			MAX_CHANNEL_NUMBER;
603		if (ieee->scan_watch_dog++ > MAX_CHANNEL_NUMBER) {
604			if (!ieee->active_channel_map[ieee->current_network.channel])
605				ieee->current_network.channel = 6;
606			goto out; /* no good chans */
607		}
608	} while (!ieee->active_channel_map[ieee->current_network.channel]);
609
610	if (ieee->scanning_continue == 0)
611		goto out;
612
613	ieee->set_chan(ieee->dev, ieee->current_network.channel);
614
615	if (ieee->active_channel_map[ieee->current_network.channel] == 1)
616		rtllib_send_probe_requests(ieee, 0);
617
618	queue_delayed_work_rsl(ieee->wq, &ieee->softmac_scan_wq,
619			       msecs_to_jiffies(RTLLIB_SOFTMAC_SCAN_TIME));
620
621	up(&ieee->scan_sem);
622	return;
623
624out:
625	if (IS_DOT11D_ENABLE(ieee))
626		DOT11D_ScanComplete(ieee);
627	ieee->current_network.channel = last_channel;
628
629out1:
630	ieee->actscanning = false;
631	ieee->scan_watch_dog = 0;
632	ieee->scanning_continue = 0;
633	up(&ieee->scan_sem);
634}
635
636
637
638static void rtllib_beacons_start(struct rtllib_device *ieee)
639{
640	unsigned long flags;
641
642	spin_lock_irqsave(&ieee->beacon_lock, flags);
643
644	ieee->beacon_txing = 1;
645	rtllib_send_beacon(ieee);
646
647	spin_unlock_irqrestore(&ieee->beacon_lock, flags);
648}
649
650static void rtllib_beacons_stop(struct rtllib_device *ieee)
651{
652	unsigned long flags;
653
654	spin_lock_irqsave(&ieee->beacon_lock, flags);
655
656	ieee->beacon_txing = 0;
657	del_timer_sync(&ieee->beacon_timer);
658
659	spin_unlock_irqrestore(&ieee->beacon_lock, flags);
660
661}
662
663
664void rtllib_stop_send_beacons(struct rtllib_device *ieee)
665{
666	if (ieee->stop_send_beacons)
667		ieee->stop_send_beacons(ieee->dev);
668	if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
669		rtllib_beacons_stop(ieee);
670}
671EXPORT_SYMBOL(rtllib_stop_send_beacons);
672
673
674void rtllib_start_send_beacons(struct rtllib_device *ieee)
675{
676	if (ieee->start_send_beacons)
677		ieee->start_send_beacons(ieee->dev);
678	if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
679		rtllib_beacons_start(ieee);
680}
681EXPORT_SYMBOL(rtllib_start_send_beacons);
682
683
684static void rtllib_softmac_stop_scan(struct rtllib_device *ieee)
685{
686	down(&ieee->scan_sem);
687	ieee->scan_watch_dog = 0;
688	if (ieee->scanning_continue == 1) {
689		ieee->scanning_continue = 0;
690		ieee->actscanning = false;
691
692		cancel_delayed_work(&ieee->softmac_scan_wq);
693	}
694
695	up(&ieee->scan_sem);
696}
697
698void rtllib_stop_scan(struct rtllib_device *ieee)
699{
700	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
701		rtllib_softmac_stop_scan(ieee);
702	} else {
703		if (ieee->rtllib_stop_hw_scan)
704			ieee->rtllib_stop_hw_scan(ieee->dev);
705	}
706}
707EXPORT_SYMBOL(rtllib_stop_scan);
708
709void rtllib_stop_scan_syncro(struct rtllib_device *ieee)
710{
711	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
712		ieee->sync_scan_hurryup = 1;
713	} else {
714		if (ieee->rtllib_stop_hw_scan)
715			ieee->rtllib_stop_hw_scan(ieee->dev);
716	}
717}
718EXPORT_SYMBOL(rtllib_stop_scan_syncro);
719
720bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan)
721{
722	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
723		if (sync_scan)
724			return ieee->be_scan_inprogress;
725		else
726			return ieee->actscanning || ieee->be_scan_inprogress;
727	} else {
728		return test_bit(STATUS_SCANNING, &ieee->status);
729	}
730}
731EXPORT_SYMBOL(rtllib_act_scanning);
732
733/* called with ieee->lock held */
734static void rtllib_start_scan(struct rtllib_device *ieee)
735{
736	RT_TRACE(COMP_DBG, "===>%s()\n", __func__);
737	if (ieee->rtllib_ips_leave_wq != NULL)
738		ieee->rtllib_ips_leave_wq(ieee->dev);
739
740	if (IS_DOT11D_ENABLE(ieee)) {
741		if (IS_COUNTRY_IE_VALID(ieee))
742			RESET_CIE_WATCHDOG(ieee);
743	}
744	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
745		if (ieee->scanning_continue == 0) {
746			ieee->actscanning = true;
747			ieee->scanning_continue = 1;
748			queue_delayed_work_rsl(ieee->wq,
749					       &ieee->softmac_scan_wq, 0);
750		}
751	} else {
752		if (ieee->rtllib_start_hw_scan)
753			ieee->rtllib_start_hw_scan(ieee->dev);
754	}
755}
756
757/* called with wx_sem held */
758void rtllib_start_scan_syncro(struct rtllib_device *ieee, u8 is_mesh)
759{
760	if (IS_DOT11D_ENABLE(ieee)) {
761		if (IS_COUNTRY_IE_VALID(ieee))
762			RESET_CIE_WATCHDOG(ieee);
763	}
764	ieee->sync_scan_hurryup = 0;
765	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
766		rtllib_softmac_scan_syncro(ieee, is_mesh);
767	} else {
768		if (ieee->rtllib_start_hw_scan)
769			ieee->rtllib_start_hw_scan(ieee->dev);
770	}
771}
772EXPORT_SYMBOL(rtllib_start_scan_syncro);
773
774inline struct sk_buff *rtllib_authentication_req(struct rtllib_network *beacon,
775	struct rtllib_device *ieee, int challengelen, u8 *daddr)
776{
777	struct sk_buff *skb;
778	struct rtllib_authentication *auth;
779	int  len = 0;
780
781	len = sizeof(struct rtllib_authentication) + challengelen +
782		     ieee->tx_headroom + 4;
783	skb = dev_alloc_skb(len);
784
785	if (!skb)
786		return NULL;
787
788	skb_reserve(skb, ieee->tx_headroom);
789
790	auth = (struct rtllib_authentication *)
791		skb_put(skb, sizeof(struct rtllib_authentication));
792
793	auth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_AUTH);
794	if (challengelen)
795		auth->header.frame_ctl |= cpu_to_le16(RTLLIB_FCTL_WEP);
796
797	auth->header.duration_id = cpu_to_le16(0x013a);
798	ether_addr_copy(auth->header.addr1, beacon->bssid);
799	ether_addr_copy(auth->header.addr2, ieee->dev->dev_addr);
800	ether_addr_copy(auth->header.addr3, beacon->bssid);
801	if (ieee->auth_mode == 0)
802		auth->algorithm = WLAN_AUTH_OPEN;
803	else if (ieee->auth_mode == 1)
804		auth->algorithm = cpu_to_le16(WLAN_AUTH_SHARED_KEY);
805	else if (ieee->auth_mode == 2)
806		auth->algorithm = WLAN_AUTH_OPEN;
807	auth->transaction = cpu_to_le16(ieee->associate_seq);
808	ieee->associate_seq++;
809
810	auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
811
812	return skb;
813}
814
815static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee,
816					 const u8 *dest)
817{
818	u8 *tag;
819	int beacon_size;
820	struct rtllib_probe_response *beacon_buf;
821	struct sk_buff *skb = NULL;
822	int encrypt;
823	int atim_len, erp_len;
824	struct lib80211_crypt_data *crypt;
825
826	char *ssid = ieee->current_network.ssid;
827	int ssid_len = ieee->current_network.ssid_len;
828	int rate_len = ieee->current_network.rates_len+2;
829	int rate_ex_len = ieee->current_network.rates_ex_len;
830	int wpa_ie_len = ieee->wpa_ie_len;
831	u8 erpinfo_content = 0;
832
833	u8 *tmp_ht_cap_buf = NULL;
834	u8 tmp_ht_cap_len = 0;
835	u8 *tmp_ht_info_buf = NULL;
836	u8 tmp_ht_info_len = 0;
837	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
838	u8 *tmp_generic_ie_buf = NULL;
839	u8 tmp_generic_ie_len = 0;
840
841	if (rate_ex_len > 0)
842		rate_ex_len += 2;
843
844	if (ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
845		atim_len = 4;
846	else
847		atim_len = 0;
848
849	if ((ieee->current_network.mode == IEEE_G) ||
850	   (ieee->current_network.mode == IEEE_N_24G &&
851	   ieee->pHTInfo->bCurSuppCCK)) {
852		erp_len = 3;
853		erpinfo_content = 0;
854		if (ieee->current_network.buseprotection)
855			erpinfo_content |= ERP_UseProtection;
856	} else
857		erp_len = 0;
858
859	crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
860	encrypt = ieee->host_encrypt && crypt && crypt->ops &&
861		((strcmp(crypt->ops->name, "R-WEP") == 0 || wpa_ie_len));
862	if (ieee->pHTInfo->bCurrentHTSupport) {
863		tmp_ht_cap_buf = (u8 *) &(ieee->pHTInfo->SelfHTCap);
864		tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
865		tmp_ht_info_buf = (u8 *) &(ieee->pHTInfo->SelfHTInfo);
866		tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
867		HTConstructCapabilityElement(ieee, tmp_ht_cap_buf,
868					     &tmp_ht_cap_len, encrypt, false);
869		HTConstructInfoElement(ieee, tmp_ht_info_buf, &tmp_ht_info_len,
870				       encrypt);
871
872		if (pHTInfo->bRegRT2RTAggregation) {
873			tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
874			tmp_generic_ie_len =
875				 sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
876			HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf,
877						   &tmp_generic_ie_len);
878		}
879	}
880
881	beacon_size = sizeof(struct rtllib_probe_response)+2+
882		ssid_len + 3 + rate_len + rate_ex_len + atim_len + erp_len
883		+ wpa_ie_len + ieee->tx_headroom;
884	skb = dev_alloc_skb(beacon_size);
885	if (!skb)
886		return NULL;
887
888	skb_reserve(skb, ieee->tx_headroom);
889
890	beacon_buf = (struct rtllib_probe_response *) skb_put(skb,
891		     (beacon_size - ieee->tx_headroom));
892	ether_addr_copy(beacon_buf->header.addr1, dest);
893	ether_addr_copy(beacon_buf->header.addr2, ieee->dev->dev_addr);
894	ether_addr_copy(beacon_buf->header.addr3, ieee->current_network.bssid);
895
896	beacon_buf->header.duration_id = 0;
897	beacon_buf->beacon_interval =
898		cpu_to_le16(ieee->current_network.beacon_interval);
899	beacon_buf->capability =
900		cpu_to_le16(ieee->current_network.capability &
901		WLAN_CAPABILITY_IBSS);
902	beacon_buf->capability |=
903		cpu_to_le16(ieee->current_network.capability &
904		WLAN_CAPABILITY_SHORT_PREAMBLE);
905
906	if (ieee->short_slot && (ieee->current_network.capability &
907	    WLAN_CAPABILITY_SHORT_SLOT_TIME))
908		beacon_buf->capability |=
909			cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
910
911	crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
912	if (encrypt)
913		beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
914
915
916	beacon_buf->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_RESP);
917	beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
918	beacon_buf->info_element[0].len = ssid_len;
919
920	tag = (u8 *) beacon_buf->info_element[0].data;
921
922	memcpy(tag, ssid, ssid_len);
923
924	tag += ssid_len;
925
926	*(tag++) = MFIE_TYPE_RATES;
927	*(tag++) = rate_len-2;
928	memcpy(tag, ieee->current_network.rates, rate_len-2);
929	tag += rate_len-2;
930
931	*(tag++) = MFIE_TYPE_DS_SET;
932	*(tag++) = 1;
933	*(tag++) = ieee->current_network.channel;
934
935	if (atim_len) {
936		u16 val16;
937		*(tag++) = MFIE_TYPE_IBSS_SET;
938		*(tag++) = 2;
939		val16 = ieee->current_network.atim_window;
940		memcpy((u8 *)tag, (u8 *)&val16, 2);
941		tag += 2;
942	}
943
944	if (erp_len) {
945		*(tag++) = MFIE_TYPE_ERP;
946		*(tag++) = 1;
947		*(tag++) = erpinfo_content;
948	}
949	if (rate_ex_len) {
950		*(tag++) = MFIE_TYPE_RATES_EX;
951		*(tag++) = rate_ex_len-2;
952		memcpy(tag, ieee->current_network.rates_ex, rate_ex_len-2);
953		tag += rate_ex_len-2;
954	}
955
956	if (wpa_ie_len) {
957		if (ieee->iw_mode == IW_MODE_ADHOC)
958			memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
959		memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
960		tag += ieee->wpa_ie_len;
961	}
962	return skb;
963}
964
965static struct sk_buff *rtllib_assoc_resp(struct rtllib_device *ieee, u8 *dest)
966{
967	struct sk_buff *skb;
968	u8 *tag;
969
970	struct lib80211_crypt_data *crypt;
971	struct rtllib_assoc_response_frame *assoc;
972	short encrypt;
973
974	unsigned int rate_len = rtllib_MFIE_rate_len(ieee);
975	int len = sizeof(struct rtllib_assoc_response_frame) + rate_len +
976		  ieee->tx_headroom;
977
978	skb = dev_alloc_skb(len);
979
980	if (!skb)
981		return NULL;
982
983	skb_reserve(skb, ieee->tx_headroom);
984
985	assoc = (struct rtllib_assoc_response_frame *)
986		skb_put(skb, sizeof(struct rtllib_assoc_response_frame));
987
988	assoc->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_ASSOC_RESP);
989	ether_addr_copy(assoc->header.addr1, dest);
990	ether_addr_copy(assoc->header.addr3, ieee->dev->dev_addr);
991	ether_addr_copy(assoc->header.addr2, ieee->dev->dev_addr);
992	assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
993		WLAN_CAPABILITY_ESS : WLAN_CAPABILITY_IBSS);
994
995
996	if (ieee->short_slot)
997		assoc->capability |=
998				 cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
999
1000	if (ieee->host_encrypt)
1001		crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
1002	else
1003		crypt = NULL;
1004
1005	encrypt = (crypt && crypt->ops);
1006
1007	if (encrypt)
1008		assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1009
1010	assoc->status = 0;
1011	assoc->aid = cpu_to_le16(ieee->assoc_id);
1012	if (ieee->assoc_id == 0x2007)
1013		ieee->assoc_id = 0;
1014	else
1015		ieee->assoc_id++;
1016
1017	tag = (u8 *) skb_put(skb, rate_len);
1018	rtllib_MFIE_Brate(ieee, &tag);
1019	rtllib_MFIE_Grate(ieee, &tag);
1020
1021	return skb;
1022}
1023
1024static struct sk_buff *rtllib_auth_resp(struct rtllib_device *ieee, int status,
1025				 u8 *dest)
1026{
1027	struct sk_buff *skb = NULL;
1028	struct rtllib_authentication *auth;
1029	int len = ieee->tx_headroom + sizeof(struct rtllib_authentication) + 1;
1030
1031	skb = dev_alloc_skb(len);
1032	if (!skb)
1033		return NULL;
1034
1035	skb->len = sizeof(struct rtllib_authentication);
1036
1037	skb_reserve(skb, ieee->tx_headroom);
1038
1039	auth = (struct rtllib_authentication *)
1040		skb_put(skb, sizeof(struct rtllib_authentication));
1041
1042	auth->status = cpu_to_le16(status);
1043	auth->transaction = cpu_to_le16(2);
1044	auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
1045
1046	ether_addr_copy(auth->header.addr3, ieee->dev->dev_addr);
1047	ether_addr_copy(auth->header.addr2, ieee->dev->dev_addr);
1048	ether_addr_copy(auth->header.addr1, dest);
1049	auth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_AUTH);
1050	return skb;
1051
1052
1053}
1054
1055static struct sk_buff *rtllib_null_func(struct rtllib_device *ieee, short pwr)
1056{
1057	struct sk_buff *skb;
1058	struct rtllib_hdr_3addr *hdr;
1059
1060	skb = dev_alloc_skb(sizeof(struct rtllib_hdr_3addr)+ieee->tx_headroom);
1061	if (!skb)
1062		return NULL;
1063
1064	skb_reserve(skb, ieee->tx_headroom);
1065
1066	hdr = (struct rtllib_hdr_3addr *)skb_put(skb,
1067	      sizeof(struct rtllib_hdr_3addr));
1068
1069	ether_addr_copy(hdr->addr1, ieee->current_network.bssid);
1070	ether_addr_copy(hdr->addr2, ieee->dev->dev_addr);
1071	ether_addr_copy(hdr->addr3, ieee->current_network.bssid);
1072
1073	hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_DATA |
1074		RTLLIB_STYPE_NULLFUNC | RTLLIB_FCTL_TODS |
1075		(pwr ? RTLLIB_FCTL_PM : 0));
1076
1077	return skb;
1078
1079
1080}
1081
1082static struct sk_buff *rtllib_pspoll_func(struct rtllib_device *ieee)
1083{
1084	struct sk_buff *skb;
1085	struct rtllib_pspoll_hdr *hdr;
1086
1087	skb = dev_alloc_skb(sizeof(struct rtllib_pspoll_hdr)+ieee->tx_headroom);
1088	if (!skb)
1089		return NULL;
1090
1091	skb_reserve(skb, ieee->tx_headroom);
1092
1093	hdr = (struct rtllib_pspoll_hdr *)skb_put(skb,
1094	      sizeof(struct rtllib_pspoll_hdr));
1095
1096	ether_addr_copy(hdr->bssid, ieee->current_network.bssid);
1097	ether_addr_copy(hdr->ta, ieee->dev->dev_addr);
1098
1099	hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000);
1100	hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_CTL | RTLLIB_STYPE_PSPOLL |
1101			 RTLLIB_FCTL_PM);
1102
1103	return skb;
1104
1105}
1106
1107static void rtllib_resp_to_assoc_rq(struct rtllib_device *ieee, u8 *dest)
1108{
1109	struct sk_buff *buf = rtllib_assoc_resp(ieee, dest);
1110
1111	if (buf)
1112		softmac_mgmt_xmit(buf, ieee);
1113}
1114
1115
1116static void rtllib_resp_to_auth(struct rtllib_device *ieee, int s, u8 *dest)
1117{
1118	struct sk_buff *buf = rtllib_auth_resp(ieee, s, dest);
1119
1120	if (buf)
1121		softmac_mgmt_xmit(buf, ieee);
1122}
1123
1124
1125static void rtllib_resp_to_probe(struct rtllib_device *ieee, u8 *dest)
1126{
1127	struct sk_buff *buf = rtllib_probe_resp(ieee, dest);
1128
1129	if (buf)
1130		softmac_mgmt_xmit(buf, ieee);
1131}
1132
1133
1134inline int SecIsInPMKIDList(struct rtllib_device *ieee, u8 *bssid)
1135{
1136	int i = 0;
1137
1138	do {
1139		if ((ieee->PMKIDList[i].bUsed) &&
1140		   (memcmp(ieee->PMKIDList[i].Bssid, bssid, ETH_ALEN) == 0))
1141			break;
1142		i++;
1143	} while (i < NUM_PMKID_CACHE);
1144
1145	if (i == NUM_PMKID_CACHE)
1146		i = -1;
1147	return i;
1148}
1149
1150inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon,
1151					      struct rtllib_device *ieee)
1152{
1153	struct sk_buff *skb;
1154	struct rtllib_assoc_request_frame *hdr;
1155	u8 *tag, *ies;
1156	int i;
1157	u8 *ht_cap_buf = NULL;
1158	u8 ht_cap_len = 0;
1159	u8 *realtek_ie_buf = NULL;
1160	u8 realtek_ie_len = 0;
1161	int wpa_ie_len = ieee->wpa_ie_len;
1162	int wps_ie_len = ieee->wps_ie_len;
1163	unsigned int ckip_ie_len = 0;
1164	unsigned int ccxrm_ie_len = 0;
1165	unsigned int cxvernum_ie_len = 0;
1166	struct lib80211_crypt_data *crypt;
1167	int encrypt;
1168	int	PMKCacheIdx;
1169
1170	unsigned int rate_len = (beacon->rates_len ?
1171				(beacon->rates_len + 2) : 0) +
1172				(beacon->rates_ex_len ? (beacon->rates_ex_len) +
1173				2 : 0);
1174
1175	unsigned int wmm_info_len = beacon->qos_data.supported ? 9 : 0;
1176	unsigned int turbo_info_len = beacon->Turbo_Enable ? 9 : 0;
1177
1178	int len = 0;
1179
1180	crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
1181	if (crypt != NULL)
1182		encrypt = ieee->host_encrypt && crypt && crypt->ops &&
1183			  ((strcmp(crypt->ops->name, "R-WEP") == 0 ||
1184			  wpa_ie_len));
1185	else
1186		encrypt = 0;
1187
1188	if ((ieee->rtllib_ap_sec_type &&
1189	    (ieee->rtllib_ap_sec_type(ieee) & SEC_ALG_TKIP)) ||
1190	    ieee->bForcedBgMode) {
1191		ieee->pHTInfo->bEnableHT = 0;
1192		ieee->mode = WIRELESS_MODE_G;
1193	}
1194
1195	if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1196		ht_cap_buf = (u8 *)&(ieee->pHTInfo->SelfHTCap);
1197		ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1198		HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len,
1199					     encrypt, true);
1200		if (ieee->pHTInfo->bCurrentRT2RTAggregation) {
1201			realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1202			realtek_ie_len =
1203				 sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
1204			HTConstructRT2RTAggElement(ieee, realtek_ie_buf,
1205						   &realtek_ie_len);
1206		}
1207	}
1208
1209	if (beacon->bCkipSupported)
1210		ckip_ie_len = 30+2;
1211	if (beacon->bCcxRmEnable)
1212		ccxrm_ie_len = 6+2;
1213	if (beacon->BssCcxVerNumber >= 2)
1214		cxvernum_ie_len = 5+2;
1215
1216	PMKCacheIdx = SecIsInPMKIDList(ieee, ieee->current_network.bssid);
1217	if (PMKCacheIdx >= 0) {
1218		wpa_ie_len += 18;
1219		netdev_info(ieee->dev, "[PMK cache]: WPA2 IE length: %x\n",
1220			    wpa_ie_len);
1221	}
1222	len = sizeof(struct rtllib_assoc_request_frame) + 2
1223		+ beacon->ssid_len
1224		+ rate_len
1225		+ wpa_ie_len
1226		+ wps_ie_len
1227		+ wmm_info_len
1228		+ turbo_info_len
1229		+ ht_cap_len
1230		+ realtek_ie_len
1231		+ ckip_ie_len
1232		+ ccxrm_ie_len
1233		+ cxvernum_ie_len
1234		+ ieee->tx_headroom;
1235
1236	skb = dev_alloc_skb(len);
1237
1238	if (!skb)
1239		return NULL;
1240
1241	skb_reserve(skb, ieee->tx_headroom);
1242
1243	hdr = (struct rtllib_assoc_request_frame *)
1244		skb_put(skb, sizeof(struct rtllib_assoc_request_frame) + 2);
1245
1246
1247	hdr->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_ASSOC_REQ);
1248	hdr->header.duration_id = cpu_to_le16(37);
1249	ether_addr_copy(hdr->header.addr1, beacon->bssid);
1250	ether_addr_copy(hdr->header.addr2, ieee->dev->dev_addr);
1251	ether_addr_copy(hdr->header.addr3, beacon->bssid);
1252
1253	ether_addr_copy(ieee->ap_mac_addr, beacon->bssid);
1254
1255	hdr->capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
1256	if (beacon->capability & WLAN_CAPABILITY_PRIVACY)
1257		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1258
1259	if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1260		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
1261
1262	if (ieee->short_slot &&
1263	   (beacon->capability&WLAN_CAPABILITY_SHORT_SLOT_TIME))
1264		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
1265
1266
1267	hdr->listen_interval = cpu_to_le16(beacon->listen_interval);
1268
1269	hdr->info_element[0].id = MFIE_TYPE_SSID;
1270
1271	hdr->info_element[0].len = beacon->ssid_len;
1272	tag = skb_put(skb, beacon->ssid_len);
1273	memcpy(tag, beacon->ssid, beacon->ssid_len);
1274
1275	tag = skb_put(skb, rate_len);
1276
1277	if (beacon->rates_len) {
1278		*tag++ = MFIE_TYPE_RATES;
1279		*tag++ = beacon->rates_len;
1280		for (i = 0; i < beacon->rates_len; i++)
1281			*tag++ = beacon->rates[i];
1282	}
1283
1284	if (beacon->rates_ex_len) {
1285		*tag++ = MFIE_TYPE_RATES_EX;
1286		*tag++ = beacon->rates_ex_len;
1287		for (i = 0; i < beacon->rates_ex_len; i++)
1288			*tag++ = beacon->rates_ex[i];
1289	}
1290
1291	if (beacon->bCkipSupported) {
1292		static const u8 AironetIeOui[] = {0x00, 0x01, 0x66};
1293		u8	CcxAironetBuf[30];
1294		struct octet_string osCcxAironetIE;
1295
1296		memset(CcxAironetBuf, 0, 30);
1297		osCcxAironetIE.Octet = CcxAironetBuf;
1298		osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1299		memcpy(osCcxAironetIE.Octet, AironetIeOui,
1300		       sizeof(AironetIeOui));
1301
1302		osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |=
1303					 (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC);
1304		tag = skb_put(skb, ckip_ie_len);
1305		*tag++ = MFIE_TYPE_AIRONET;
1306		*tag++ = osCcxAironetIE.Length;
1307		memcpy(tag, osCcxAironetIE.Octet, osCcxAironetIE.Length);
1308		tag += osCcxAironetIE.Length;
1309	}
1310
1311	if (beacon->bCcxRmEnable) {
1312		static const u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01,
1313			0x00};
1314		struct octet_string osCcxRmCap;
1315
1316		osCcxRmCap.Octet = (u8 *) CcxRmCapBuf;
1317		osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1318		tag = skb_put(skb, ccxrm_ie_len);
1319		*tag++ = MFIE_TYPE_GENERIC;
1320		*tag++ = osCcxRmCap.Length;
1321		memcpy(tag, osCcxRmCap.Octet, osCcxRmCap.Length);
1322		tag += osCcxRmCap.Length;
1323	}
1324
1325	if (beacon->BssCcxVerNumber >= 2) {
1326		u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1327		struct octet_string osCcxVerNum;
1328
1329		CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1330		osCcxVerNum.Octet = CcxVerNumBuf;
1331		osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1332		tag = skb_put(skb, cxvernum_ie_len);
1333		*tag++ = MFIE_TYPE_GENERIC;
1334		*tag++ = osCcxVerNum.Length;
1335		memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length);
1336		tag += osCcxVerNum.Length;
1337	}
1338	if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1339		if (ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC) {
1340			tag = skb_put(skb, ht_cap_len);
1341			*tag++ = MFIE_TYPE_HT_CAP;
1342			*tag++ = ht_cap_len - 2;
1343			memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1344			tag += ht_cap_len - 2;
1345		}
1346	}
1347
1348	if (wpa_ie_len) {
1349		tag = skb_put(skb, ieee->wpa_ie_len);
1350		memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1351
1352		if (PMKCacheIdx >= 0) {
1353			tag = skb_put(skb, 18);
1354			*tag = 1;
1355			*(tag + 1) = 0;
1356			memcpy((tag + 2), &ieee->PMKIDList[PMKCacheIdx].PMKID,
1357			       16);
1358		}
1359	}
1360	if (wmm_info_len) {
1361		tag = skb_put(skb, wmm_info_len);
1362		rtllib_WMM_Info(ieee, &tag);
1363	}
1364
1365	if (wps_ie_len && ieee->wps_ie) {
1366		tag = skb_put(skb, wps_ie_len);
1367		memcpy(tag, ieee->wps_ie, wps_ie_len);
1368	}
1369
1370	tag = skb_put(skb, turbo_info_len);
1371	if (turbo_info_len)
1372		rtllib_TURBO_Info(ieee, &tag);
1373
1374	if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1375		if (ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC) {
1376			tag = skb_put(skb, ht_cap_len);
1377			*tag++ = MFIE_TYPE_GENERIC;
1378			*tag++ = ht_cap_len - 2;
1379			memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1380			tag += ht_cap_len - 2;
1381		}
1382
1383		if (ieee->pHTInfo->bCurrentRT2RTAggregation) {
1384			tag = skb_put(skb, realtek_ie_len);
1385			*tag++ = MFIE_TYPE_GENERIC;
1386			*tag++ = realtek_ie_len - 2;
1387			memcpy(tag, realtek_ie_buf, realtek_ie_len - 2);
1388		}
1389	}
1390
1391	kfree(ieee->assocreq_ies);
1392	ieee->assocreq_ies = NULL;
1393	ies = &(hdr->info_element[0].id);
1394	ieee->assocreq_ies_len = (skb->data + skb->len) - ies;
1395	ieee->assocreq_ies = kmalloc(ieee->assocreq_ies_len, GFP_ATOMIC);
1396	if (ieee->assocreq_ies)
1397		memcpy(ieee->assocreq_ies, ies, ieee->assocreq_ies_len);
1398	else {
1399		netdev_info(ieee->dev,
1400			    "%s()Warning: can't alloc memory for assocreq_ies\n",
1401			    __func__);
1402		ieee->assocreq_ies_len = 0;
1403	}
1404	return skb;
1405}
1406
1407static void rtllib_associate_abort(struct rtllib_device *ieee)
1408{
1409	unsigned long flags;
1410
1411	spin_lock_irqsave(&ieee->lock, flags);
1412
1413	ieee->associate_seq++;
1414
1415	/* don't scan, and avoid to have the RX path possibily
1416	 * try again to associate. Even do not react to AUTH or
1417	 * ASSOC response. Just wait for the retry wq to be scheduled.
1418	 * Here we will check if there are good nets to associate
1419	 * with, so we retry or just get back to NO_LINK and scanning
1420	 */
1421	if (ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATING) {
1422		netdev_dbg(ieee->dev, "Authentication failed\n");
1423		ieee->softmac_stats.no_auth_rs++;
1424	} else {
1425		netdev_dbg(ieee->dev, "Association failed\n");
1426		ieee->softmac_stats.no_ass_rs++;
1427	}
1428
1429	ieee->state = RTLLIB_ASSOCIATING_RETRY;
1430
1431	queue_delayed_work_rsl(ieee->wq, &ieee->associate_retry_wq,
1432			   RTLLIB_SOFTMAC_ASSOC_RETRY_TIME);
1433
1434	spin_unlock_irqrestore(&ieee->lock, flags);
1435}
1436
1437static void rtllib_associate_abort_cb(unsigned long dev)
1438{
1439	rtllib_associate_abort((struct rtllib_device *) dev);
1440}
1441
1442static void rtllib_associate_step1(struct rtllib_device *ieee, u8 *daddr)
1443{
1444	struct rtllib_network *beacon = &ieee->current_network;
1445	struct sk_buff *skb;
1446
1447	netdev_dbg(ieee->dev, "Stopping scan\n");
1448
1449	ieee->softmac_stats.tx_auth_rq++;
1450
1451	skb = rtllib_authentication_req(beacon, ieee, 0, daddr);
1452
1453	if (!skb)
1454		rtllib_associate_abort(ieee);
1455	else {
1456		ieee->state = RTLLIB_ASSOCIATING_AUTHENTICATING;
1457		netdev_dbg(ieee->dev, "Sending authentication request\n");
1458		softmac_mgmt_xmit(skb, ieee);
1459		if (!timer_pending(&ieee->associate_timer)) {
1460			ieee->associate_timer.expires = jiffies + (HZ / 2);
1461			add_timer(&ieee->associate_timer);
1462		}
1463	}
1464}
1465
1466static void rtllib_auth_challenge(struct rtllib_device *ieee, u8 *challenge,
1467				  int chlen)
1468{
1469	u8 *c;
1470	struct sk_buff *skb;
1471	struct rtllib_network *beacon = &ieee->current_network;
1472
1473	ieee->associate_seq++;
1474	ieee->softmac_stats.tx_auth_rq++;
1475
1476	skb = rtllib_authentication_req(beacon, ieee, chlen + 2, beacon->bssid);
1477
1478	if (!skb)
1479		rtllib_associate_abort(ieee);
1480	else {
1481		c = skb_put(skb, chlen+2);
1482		*(c++) = MFIE_TYPE_CHALLENGE;
1483		*(c++) = chlen;
1484		memcpy(c, challenge, chlen);
1485
1486		netdev_dbg(ieee->dev,
1487			   "Sending authentication challenge response\n");
1488
1489		rtllib_encrypt_fragment(ieee, skb,
1490					sizeof(struct rtllib_hdr_3addr));
1491
1492		softmac_mgmt_xmit(skb, ieee);
1493		mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1494	}
1495	kfree(challenge);
1496}
1497
1498static void rtllib_associate_step2(struct rtllib_device *ieee)
1499{
1500	struct sk_buff *skb;
1501	struct rtllib_network *beacon = &ieee->current_network;
1502
1503	del_timer_sync(&ieee->associate_timer);
1504
1505	netdev_dbg(ieee->dev, "Sending association request\n");
1506
1507	ieee->softmac_stats.tx_ass_rq++;
1508	skb = rtllib_association_req(beacon, ieee);
1509	if (!skb)
1510		rtllib_associate_abort(ieee);
1511	else {
1512		softmac_mgmt_xmit(skb, ieee);
1513		mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1514	}
1515}
1516
1517static void rtllib_associate_complete_wq(void *data)
1518{
1519	struct rtllib_device *ieee = (struct rtllib_device *)
1520				     container_of_work_rsl(data,
1521				     struct rtllib_device,
1522				     associate_complete_wq);
1523	struct rt_pwr_save_ctrl *pPSC = &(ieee->PowerSaveControl);
1524	netdev_info(ieee->dev, "Associated successfully\n");
1525	if (!ieee->is_silent_reset) {
1526		netdev_info(ieee->dev, "normal associate\n");
1527		notify_wx_assoc_event(ieee);
1528	}
1529
1530	netif_carrier_on(ieee->dev);
1531	ieee->is_roaming = false;
1532	if (rtllib_is_54g(&ieee->current_network) &&
1533	   (ieee->modulation & RTLLIB_OFDM_MODULATION)) {
1534		ieee->rate = 108;
1535		netdev_info(ieee->dev, "Using G rates:%d\n", ieee->rate);
1536	} else {
1537		ieee->rate = 22;
1538		ieee->SetWirelessMode(ieee->dev, IEEE_B);
1539		netdev_info(ieee->dev, "Using B rates:%d\n", ieee->rate);
1540	}
1541	if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1542		netdev_info(ieee->dev, "Successfully associated, ht enabled\n");
1543		HTOnAssocRsp(ieee);
1544	} else {
1545		netdev_info(ieee->dev,
1546			    "Successfully associated, ht not enabled(%d, %d)\n",
1547			    ieee->pHTInfo->bCurrentHTSupport,
1548			    ieee->pHTInfo->bEnableHT);
1549		memset(ieee->dot11HTOperationalRateSet, 0, 16);
1550	}
1551	ieee->LinkDetectInfo.SlotNum = 2 * (1 +
1552				       ieee->current_network.beacon_interval /
1553				       500);
1554	if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 ||
1555	    ieee->LinkDetectInfo.NumRecvDataInPeriod == 0) {
1556		ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1557		ieee->LinkDetectInfo.NumRecvDataInPeriod = 1;
1558	}
1559	pPSC->LpsIdleCount = 0;
1560	ieee->link_change(ieee->dev);
1561
1562	if (ieee->is_silent_reset) {
1563		netdev_info(ieee->dev, "silent reset associate\n");
1564		ieee->is_silent_reset = false;
1565	}
1566
1567	if (ieee->data_hard_resume)
1568		ieee->data_hard_resume(ieee->dev);
1569
1570}
1571
1572static void rtllib_sta_send_associnfo(struct rtllib_device *ieee)
1573{
1574}
1575
1576static void rtllib_associate_complete(struct rtllib_device *ieee)
1577{
1578	del_timer_sync(&ieee->associate_timer);
1579
1580	ieee->state = RTLLIB_LINKED;
1581	rtllib_sta_send_associnfo(ieee);
1582
1583	queue_work_rsl(ieee->wq, &ieee->associate_complete_wq);
1584}
1585
1586static void rtllib_associate_procedure_wq(void *data)
1587{
1588	struct rtllib_device *ieee = container_of_dwork_rsl(data,
1589				     struct rtllib_device,
1590				     associate_procedure_wq);
1591	rtllib_stop_scan_syncro(ieee);
1592	if (ieee->rtllib_ips_leave != NULL)
1593		ieee->rtllib_ips_leave(ieee->dev);
1594	down(&ieee->wx_sem);
1595
1596	if (ieee->data_hard_stop)
1597		ieee->data_hard_stop(ieee->dev);
1598
1599	rtllib_stop_scan(ieee);
1600	RT_TRACE(COMP_DBG, "===>%s(), chan:%d\n", __func__,
1601		 ieee->current_network.channel);
1602	HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1603	if (ieee->eRFPowerState == eRfOff) {
1604		RT_TRACE(COMP_DBG,
1605			 "=============>%s():Rf state is eRfOff, schedule ipsleave wq again,return\n",
1606			 __func__);
1607		if (ieee->rtllib_ips_leave_wq != NULL)
1608			ieee->rtllib_ips_leave_wq(ieee->dev);
1609		up(&ieee->wx_sem);
1610		return;
1611	}
1612	ieee->associate_seq = 1;
1613
1614	rtllib_associate_step1(ieee, ieee->current_network.bssid);
1615
1616	up(&ieee->wx_sem);
1617}
1618
1619inline void rtllib_softmac_new_net(struct rtllib_device *ieee,
1620				   struct rtllib_network *net)
1621{
1622	u8 tmp_ssid[IW_ESSID_MAX_SIZE + 1];
1623	int tmp_ssid_len = 0;
1624
1625	short apset, ssidset, ssidbroad, apmatch, ssidmatch;
1626
1627	/* we are interested in new new only if we are not associated
1628	 * and we are not associating / authenticating
1629	 */
1630	if (ieee->state != RTLLIB_NOLINK)
1631		return;
1632
1633	if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability &
1634	    WLAN_CAPABILITY_ESS))
1635		return;
1636
1637	if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability &
1638	     WLAN_CAPABILITY_IBSS))
1639		return;
1640
1641	if ((ieee->iw_mode == IW_MODE_ADHOC) &&
1642	    (net->channel > ieee->ibss_maxjoin_chal))
1643		return;
1644	if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
1645		/* if the user specified the AP MAC, we need also the essid
1646		 * This could be obtained by beacons or, if the network does not
1647		 * broadcast it, it can be put manually.
1648		 */
1649		apset = ieee->wap_set;
1650		ssidset = ieee->ssid_set;
1651		ssidbroad =  !(net->ssid_len == 0 || net->ssid[0] == '\0');
1652		apmatch = (memcmp(ieee->current_network.bssid, net->bssid,
1653				  ETH_ALEN) == 0);
1654		if (!ssidbroad) {
1655			ssidmatch = (ieee->current_network.ssid_len ==
1656				    net->hidden_ssid_len) &&
1657				    (!strncmp(ieee->current_network.ssid,
1658				    net->hidden_ssid, net->hidden_ssid_len));
1659			if (net->hidden_ssid_len > 0) {
1660				strncpy(net->ssid, net->hidden_ssid,
1661					net->hidden_ssid_len);
1662				net->ssid_len = net->hidden_ssid_len;
1663				ssidbroad = 1;
1664			}
1665		} else
1666			ssidmatch =
1667			   (ieee->current_network.ssid_len == net->ssid_len) &&
1668			   (!strncmp(ieee->current_network.ssid, net->ssid,
1669			   net->ssid_len));
1670
1671		/* if the user set the AP check if match.
1672		 * if the network does not broadcast essid we check the
1673		 *	 user supplied ANY essid
1674		 * if the network does broadcast and the user does not set
1675		 *	 essid it is OK
1676		 * if the network does broadcast and the user did set essid
1677		 * check if essid match
1678		 * if the ap is not set, check that the user set the bssid
1679		 * and the network does broadcast and that those two bssid match
1680		 */
1681		if ((apset && apmatch &&
1682		   ((ssidset && ssidbroad && ssidmatch) ||
1683		   (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
1684		   (!apset && ssidset && ssidbroad && ssidmatch) ||
1685		   (ieee->is_roaming && ssidset && ssidbroad && ssidmatch)) {
1686			/* if the essid is hidden replace it with the
1687			 * essid provided by the user.
1688			 */
1689			if (!ssidbroad) {
1690				strncpy(tmp_ssid, ieee->current_network.ssid,
1691					IW_ESSID_MAX_SIZE);
1692				tmp_ssid_len = ieee->current_network.ssid_len;
1693			}
1694			memcpy(&ieee->current_network, net,
1695			       sizeof(struct rtllib_network));
1696			if (!ssidbroad) {
1697				strncpy(ieee->current_network.ssid, tmp_ssid,
1698					IW_ESSID_MAX_SIZE);
1699				ieee->current_network.ssid_len = tmp_ssid_len;
1700			}
1701			netdev_info(ieee->dev,
1702				    "Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d, mode:%x cur_net.flags:0x%x\n",
1703				    ieee->current_network.ssid,
1704				    ieee->current_network.channel,
1705				    ieee->current_network.qos_data.supported,
1706				    ieee->pHTInfo->bEnableHT,
1707				    ieee->current_network.bssht.bdSupportHT,
1708				    ieee->current_network.mode,
1709				    ieee->current_network.flags);
1710
1711			if ((rtllib_act_scanning(ieee, false)) &&
1712			   !(ieee->softmac_features & IEEE_SOFTMAC_SCAN))
1713				rtllib_stop_scan_syncro(ieee);
1714
1715			HTResetIOTSetting(ieee->pHTInfo);
1716			ieee->wmm_acm = 0;
1717			if (ieee->iw_mode == IW_MODE_INFRA) {
1718				/* Join the network for the first time */
1719				ieee->AsocRetryCount = 0;
1720				if ((ieee->current_network.qos_data.supported == 1) &&
1721				    ieee->current_network.bssht.bdSupportHT)
1722					HTResetSelfAndSavePeerSetting(ieee,
1723						 &(ieee->current_network));
1724				else
1725					ieee->pHTInfo->bCurrentHTSupport =
1726								 false;
1727
1728				ieee->state = RTLLIB_ASSOCIATING;
1729				if (ieee->LedControlHandler != NULL)
1730					ieee->LedControlHandler(ieee->dev,
1731							 LED_CTL_START_TO_LINK);
1732				queue_delayed_work_rsl(ieee->wq,
1733					   &ieee->associate_procedure_wq, 0);
1734			} else {
1735				if (rtllib_is_54g(&ieee->current_network) &&
1736				    (ieee->modulation &
1737				     RTLLIB_OFDM_MODULATION)) {
1738					ieee->rate = 108;
1739					ieee->SetWirelessMode(ieee->dev,
1740							      IEEE_G);
1741					netdev_info(ieee->dev,
1742						    "Using G rates\n");
1743				} else {
1744					ieee->rate = 22;
1745					ieee->SetWirelessMode(ieee->dev,
1746							      IEEE_B);
1747					netdev_info(ieee->dev,
1748						    "Using B rates\n");
1749				}
1750				memset(ieee->dot11HTOperationalRateSet, 0, 16);
1751				ieee->state = RTLLIB_LINKED;
1752			}
1753		}
1754	}
1755}
1756
1757static void rtllib_softmac_check_all_nets(struct rtllib_device *ieee)
1758{
1759	unsigned long flags;
1760	struct rtllib_network *target;
1761
1762	spin_lock_irqsave(&ieee->lock, flags);
1763
1764	list_for_each_entry(target, &ieee->network_list, list) {
1765
1766		/* if the state become different that NOLINK means
1767		 * we had found what we are searching for
1768		 */
1769
1770		if (ieee->state != RTLLIB_NOLINK)
1771			break;
1772
1773		if (ieee->scan_age == 0 || time_after(target->last_scanned +
1774		    ieee->scan_age, jiffies))
1775			rtllib_softmac_new_net(ieee, target);
1776	}
1777	spin_unlock_irqrestore(&ieee->lock, flags);
1778}
1779
1780static inline u16 auth_parse(struct net_device *dev, struct sk_buff *skb,
1781			     u8 **challenge, int *chlen)
1782{
1783	struct rtllib_authentication *a;
1784	u8 *t;
1785
1786	if (skb->len <  (sizeof(struct rtllib_authentication) -
1787	    sizeof(struct rtllib_info_element))) {
1788		netdev_dbg(dev, "invalid len in auth resp: %d\n", skb->len);
1789		return 0xcafe;
1790	}
1791	*challenge = NULL;
1792	a = (struct rtllib_authentication *) skb->data;
1793	if (skb->len > (sizeof(struct rtllib_authentication) + 3)) {
1794		t = skb->data + sizeof(struct rtllib_authentication);
1795
1796		if (*(t++) == MFIE_TYPE_CHALLENGE) {
1797			*chlen = *(t++);
1798			*challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1799			if (!*challenge)
1800				return -ENOMEM;
1801		}
1802	}
1803	return le16_to_cpu(a->status);
1804}
1805
1806static int auth_rq_parse(struct net_device *dev, struct sk_buff *skb, u8 *dest)
1807{
1808	struct rtllib_authentication *a;
1809
1810	if (skb->len <  (sizeof(struct rtllib_authentication) -
1811	    sizeof(struct rtllib_info_element))) {
1812		netdev_dbg(dev, "invalid len in auth request: %d\n", skb->len);
1813		return -1;
1814	}
1815	a = (struct rtllib_authentication *) skb->data;
1816
1817	ether_addr_copy(dest, a->header.addr2);
1818
1819	if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1820		return  WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1821
1822	return WLAN_STATUS_SUCCESS;
1823}
1824
1825static short probe_rq_parse(struct rtllib_device *ieee, struct sk_buff *skb,
1826			    u8 *src)
1827{
1828	u8 *tag;
1829	u8 *skbend;
1830	u8 *ssid = NULL;
1831	u8 ssidlen = 0;
1832	struct rtllib_hdr_3addr   *header =
1833		(struct rtllib_hdr_3addr   *) skb->data;
1834	bool bssid_match;
1835
1836	if (skb->len < sizeof(struct rtllib_hdr_3addr))
1837		return -1; /* corrupted */
1838
1839	bssid_match =
1840	  (!ether_addr_equal(header->addr3, ieee->current_network.bssid)) &&
1841	  (!is_broadcast_ether_addr(header->addr3));
1842	if (bssid_match)
1843		return -1;
1844
1845	ether_addr_copy(src, header->addr2);
1846
1847	skbend = (u8 *)skb->data + skb->len;
1848
1849	tag = skb->data + sizeof(struct rtllib_hdr_3addr);
1850
1851	while (tag + 1 < skbend) {
1852		if (*tag == 0) {
1853			ssid = tag + 2;
1854			ssidlen = *(tag + 1);
1855			break;
1856		}
1857		tag++; /* point to the len field */
1858		tag = tag + *(tag); /* point to the last data byte of the tag */
1859		tag++; /* point to the next tag */
1860	}
1861
1862	if (ssidlen == 0)
1863		return 1;
1864
1865	if (!ssid)
1866		return 1; /* ssid not found in tagged param */
1867
1868	return !strncmp(ssid, ieee->current_network.ssid, ssidlen);
1869}
1870
1871static int assoc_rq_parse(struct net_device *dev, struct sk_buff *skb, u8 *dest)
1872{
1873	struct rtllib_assoc_request_frame *a;
1874
1875	if (skb->len < (sizeof(struct rtllib_assoc_request_frame) -
1876		sizeof(struct rtllib_info_element))) {
1877		netdev_dbg(dev, "invalid len in auth request:%d\n", skb->len);
1878		return -1;
1879	}
1880
1881	a = (struct rtllib_assoc_request_frame *) skb->data;
1882
1883	ether_addr_copy(dest, a->header.addr2);
1884
1885	return 0;
1886}
1887
1888static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb,
1889			      int *aid)
1890{
1891	struct rtllib_assoc_response_frame *response_head;
1892	u16 status_code;
1893
1894	if (skb->len <  sizeof(struct rtllib_assoc_response_frame)) {
1895		netdev_dbg(ieee->dev, "Invalid len in auth resp: %d\n",
1896			   skb->len);
1897		return 0xcafe;
1898	}
1899
1900	response_head = (struct rtllib_assoc_response_frame *) skb->data;
1901	*aid = le16_to_cpu(response_head->aid) & 0x3fff;
1902
1903	status_code = le16_to_cpu(response_head->status);
1904	if ((status_code == WLAN_STATUS_ASSOC_DENIED_RATES ||
1905	   status_code == WLAN_STATUS_CAPS_UNSUPPORTED) &&
1906	   ((ieee->mode == IEEE_G) &&
1907	   (ieee->current_network.mode == IEEE_N_24G) &&
1908	   (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1909		ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1910	} else {
1911		ieee->AsocRetryCount = 0;
1912	}
1913
1914	return le16_to_cpu(response_head->status);
1915}
1916
1917void rtllib_rx_probe_rq(struct rtllib_device *ieee, struct sk_buff *skb)
1918{
1919	u8 dest[ETH_ALEN];
1920
1921	ieee->softmac_stats.rx_probe_rq++;
1922	if (probe_rq_parse(ieee, skb, dest) > 0) {
1923		ieee->softmac_stats.tx_probe_rs++;
1924		rtllib_resp_to_probe(ieee, dest);
1925	}
1926}
1927
1928static inline void rtllib_rx_auth_rq(struct rtllib_device *ieee,
1929				     struct sk_buff *skb)
1930{
1931	u8 dest[ETH_ALEN];
1932	int status;
1933
1934	ieee->softmac_stats.rx_auth_rq++;
1935
1936	status = auth_rq_parse(ieee->dev, skb, dest);
1937	if (status != -1)
1938		rtllib_resp_to_auth(ieee, status, dest);
1939}
1940
1941static inline void rtllib_rx_assoc_rq(struct rtllib_device *ieee,
1942				      struct sk_buff *skb)
1943{
1944	u8 dest[ETH_ALEN];
1945
1946
1947	ieee->softmac_stats.rx_ass_rq++;
1948	if (assoc_rq_parse(ieee->dev, skb, dest) != -1)
1949		rtllib_resp_to_assoc_rq(ieee, dest);
1950
1951	netdev_info(ieee->dev, "New client associated: %pM\n", dest);
1952}
1953
1954void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr)
1955{
1956
1957	struct sk_buff *buf = rtllib_null_func(ieee, pwr);
1958
1959	if (buf)
1960		softmac_ps_mgmt_xmit(buf, ieee);
1961}
1962EXPORT_SYMBOL(rtllib_sta_ps_send_null_frame);
1963
1964void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee)
1965{
1966	struct sk_buff *buf = rtllib_pspoll_func(ieee);
1967
1968	if (buf)
1969		softmac_ps_mgmt_xmit(buf, ieee);
1970}
1971
1972static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time)
1973{
1974	int timeout = ieee->ps_timeout;
1975	u8 dtim;
1976	struct rt_pwr_save_ctrl *pPSC = &(ieee->PowerSaveControl);
1977
1978	if (ieee->LPSDelayCnt) {
1979		ieee->LPSDelayCnt--;
1980		return 0;
1981	}
1982
1983	dtim = ieee->current_network.dtim_data;
1984	if (!(dtim & RTLLIB_DTIM_VALID))
1985		return 0;
1986	timeout = ieee->current_network.beacon_interval;
1987	ieee->current_network.dtim_data = RTLLIB_DTIM_INVALID;
1988	/* there's no need to nofity AP that I find you buffered
1989	 * with broadcast packet
1990	 */
1991	if (dtim & (RTLLIB_DTIM_UCAST & ieee->ps))
1992		return 2;
1993
1994	if (!time_after(jiffies,
1995			ieee->dev->trans_start + msecs_to_jiffies(timeout)))
1996		return 0;
1997	if (!time_after(jiffies,
1998			ieee->last_rx_ps_time + msecs_to_jiffies(timeout)))
1999		return 0;
2000	if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) &&
2001	    (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
2002		return 0;
2003
2004	if (time) {
2005		if (ieee->bAwakePktSent) {
2006			pPSC->LPSAwakeIntvl = 1;
2007		} else {
2008			u8 MaxPeriod = 1;
2009
2010			if (pPSC->LPSAwakeIntvl == 0)
2011				pPSC->LPSAwakeIntvl = 1;
2012			if (pPSC->RegMaxLPSAwakeIntvl == 0)
2013				MaxPeriod = 1;
2014			else if (pPSC->RegMaxLPSAwakeIntvl == 0xFF)
2015				MaxPeriod = ieee->current_network.dtim_period;
2016			else
2017				MaxPeriod = pPSC->RegMaxLPSAwakeIntvl;
2018			pPSC->LPSAwakeIntvl = (pPSC->LPSAwakeIntvl >=
2019					       MaxPeriod) ? MaxPeriod :
2020					       (pPSC->LPSAwakeIntvl + 1);
2021		}
2022		{
2023			u8 LPSAwakeIntvl_tmp = 0;
2024			u8 period = ieee->current_network.dtim_period;
2025			u8 count = ieee->current_network.tim.tim_count;
2026
2027			if (count == 0) {
2028				if (pPSC->LPSAwakeIntvl > period)
2029					LPSAwakeIntvl_tmp = period +
2030						 (pPSC->LPSAwakeIntvl -
2031						 period) -
2032						 ((pPSC->LPSAwakeIntvl-period) %
2033						 period);
2034				else
2035					LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl;
2036
2037			} else {
2038				if (pPSC->LPSAwakeIntvl >
2039				    ieee->current_network.tim.tim_count)
2040					LPSAwakeIntvl_tmp = count +
2041					(pPSC->LPSAwakeIntvl - count) -
2042					((pPSC->LPSAwakeIntvl-count)%period);
2043				else
2044					LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl;
2045			}
2046
2047		*time = ieee->current_network.last_dtim_sta_time
2048			+ msecs_to_jiffies(ieee->current_network.beacon_interval *
2049			LPSAwakeIntvl_tmp);
2050	}
2051	}
2052
2053	return 1;
2054
2055
2056}
2057
2058static inline void rtllib_sta_ps(struct rtllib_device *ieee)
2059{
2060	u64 time;
2061	short sleep;
2062	unsigned long flags, flags2;
2063
2064	spin_lock_irqsave(&ieee->lock, flags);
2065
2066	if ((ieee->ps == RTLLIB_PS_DISABLED ||
2067	     ieee->iw_mode != IW_MODE_INFRA ||
2068	     ieee->state != RTLLIB_LINKED)) {
2069		RT_TRACE(COMP_DBG,
2070			 "=====>%s(): no need to ps,wake up!! ieee->ps is %d, ieee->iw_mode is %d, ieee->state is %d\n",
2071			 __func__, ieee->ps, ieee->iw_mode, ieee->state);
2072		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2073		rtllib_sta_wakeup(ieee, 1);
2074
2075		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2076	}
2077	sleep = rtllib_sta_ps_sleep(ieee, &time);
2078	/* 2 wake, 1 sleep, 0 do nothing */
2079	if (sleep == 0)
2080		goto out;
2081	if (sleep == 1) {
2082		if (ieee->sta_sleep == LPS_IS_SLEEP) {
2083			ieee->enter_sleep_state(ieee->dev, time);
2084		} else if (ieee->sta_sleep == LPS_IS_WAKE) {
2085			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2086
2087			if (ieee->ps_is_queue_empty(ieee->dev)) {
2088				ieee->sta_sleep = LPS_WAIT_NULL_DATA_SEND;
2089				ieee->ack_tx_to_ieee = 1;
2090				rtllib_sta_ps_send_null_frame(ieee, 1);
2091				ieee->ps_time = time;
2092			}
2093			spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2094
2095		}
2096
2097		ieee->bAwakePktSent = false;
2098
2099	} else if (sleep == 2) {
2100		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2101
2102		rtllib_sta_wakeup(ieee, 1);
2103
2104		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2105	}
2106
2107out:
2108	spin_unlock_irqrestore(&ieee->lock, flags);
2109
2110}
2111
2112static void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl)
2113{
2114	if (ieee->sta_sleep == LPS_IS_WAKE) {
2115		if (nl) {
2116			if (ieee->pHTInfo->IOTAction &
2117			    HT_IOT_ACT_NULL_DATA_POWER_SAVING) {
2118				ieee->ack_tx_to_ieee = 1;
2119				rtllib_sta_ps_send_null_frame(ieee, 0);
2120			} else {
2121				ieee->ack_tx_to_ieee = 1;
2122				rtllib_sta_ps_send_pspoll_frame(ieee);
2123			}
2124		}
2125		return;
2126
2127	}
2128
2129	if (ieee->sta_sleep == LPS_IS_SLEEP)
2130		ieee->sta_wake_up(ieee->dev);
2131	if (nl) {
2132		if (ieee->pHTInfo->IOTAction &
2133		    HT_IOT_ACT_NULL_DATA_POWER_SAVING) {
2134			ieee->ack_tx_to_ieee = 1;
2135			rtllib_sta_ps_send_null_frame(ieee, 0);
2136		} else {
2137			ieee->ack_tx_to_ieee = 1;
2138			ieee->polling = true;
2139			rtllib_sta_ps_send_pspoll_frame(ieee);
2140		}
2141
2142	} else {
2143		ieee->sta_sleep = LPS_IS_WAKE;
2144		ieee->polling = false;
2145	}
2146}
2147
2148void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success)
2149{
2150	unsigned long flags, flags2;
2151
2152	spin_lock_irqsave(&ieee->lock, flags);
2153
2154	if (ieee->sta_sleep == LPS_WAIT_NULL_DATA_SEND) {
2155		/* Null frame with PS bit set */
2156		if (success) {
2157			ieee->sta_sleep = LPS_IS_SLEEP;
2158			ieee->enter_sleep_state(ieee->dev, ieee->ps_time);
2159		}
2160		/* if the card report not success we can't be sure the AP
2161		 * has not RXed so we can't assume the AP believe us awake
2162		 */
2163	} else {/* 21112005 - tx again null without PS bit if lost */
2164
2165		if ((ieee->sta_sleep == LPS_IS_WAKE) && !success) {
2166			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2167			if (ieee->pHTInfo->IOTAction &
2168			    HT_IOT_ACT_NULL_DATA_POWER_SAVING)
2169				rtllib_sta_ps_send_null_frame(ieee, 0);
2170			else
2171				rtllib_sta_ps_send_pspoll_frame(ieee);
2172			spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2173		}
2174	}
2175	spin_unlock_irqrestore(&ieee->lock, flags);
2176}
2177EXPORT_SYMBOL(rtllib_ps_tx_ack);
2178
2179static void rtllib_process_action(struct rtllib_device *ieee,
2180				  struct sk_buff *skb)
2181{
2182	struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data;
2183	u8 *act = rtllib_get_payload((struct rtllib_hdr *)header);
2184	u8 category = 0;
2185
2186	if (act == NULL) {
2187		netdev_warn(ieee->dev,
2188			    "Error getting payload of action frame\n");
2189		return;
2190	}
2191
2192	category = *act;
2193	act++;
2194	switch (category) {
2195	case ACT_CAT_BA:
2196		switch (*act) {
2197		case ACT_ADDBAREQ:
2198			rtllib_rx_ADDBAReq(ieee, skb);
2199			break;
2200		case ACT_ADDBARSP:
2201			rtllib_rx_ADDBARsp(ieee, skb);
2202			break;
2203		case ACT_DELBA:
2204			rtllib_rx_DELBA(ieee, skb);
2205			break;
2206		}
2207		break;
2208	default:
2209		break;
2210	}
2211}
2212
2213inline int rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb,
2214				struct rtllib_rx_stats *rx_stats)
2215{
2216	u16 errcode;
2217	int aid;
2218	u8 *ies;
2219	struct rtllib_assoc_response_frame *assoc_resp;
2220	struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data;
2221	u16 frame_ctl = le16_to_cpu(header->frame_ctl);
2222
2223	netdev_dbg(ieee->dev, "received [RE]ASSOCIATION RESPONSE (%d)\n",
2224		   WLAN_FC_GET_STYPE(frame_ctl));
2225
2226	if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2227	     ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATED &&
2228	     (ieee->iw_mode == IW_MODE_INFRA)) {
2229		errcode = assoc_parse(ieee, skb, &aid);
2230		if (!errcode) {
2231			struct rtllib_network *network =
2232				 kzalloc(sizeof(struct rtllib_network),
2233				 GFP_ATOMIC);
2234
2235			if (!network)
2236				return 1;
2237			ieee->state = RTLLIB_LINKED;
2238			ieee->assoc_id = aid;
2239			ieee->softmac_stats.rx_ass_ok++;
2240			/* station support qos */
2241			/* Let the register setting default with Legacy station */
2242			assoc_resp = (struct rtllib_assoc_response_frame *)skb->data;
2243			if (ieee->current_network.qos_data.supported == 1) {
2244				if (rtllib_parse_info_param(ieee, assoc_resp->info_element,
2245							rx_stats->len - sizeof(*assoc_resp),
2246							network, rx_stats)) {
2247					kfree(network);
2248					return 1;
2249				}
2250				memcpy(ieee->pHTInfo->PeerHTCapBuf,
2251				       network->bssht.bdHTCapBuf,
2252				       network->bssht.bdHTCapLen);
2253				memcpy(ieee->pHTInfo->PeerHTInfoBuf,
2254				       network->bssht.bdHTInfoBuf,
2255				       network->bssht.bdHTInfoLen);
2256				if (ieee->handle_assoc_response != NULL)
2257					ieee->handle_assoc_response(ieee->dev,
2258						 (struct rtllib_assoc_response_frame *)header,
2259						 network);
2260			}
2261			kfree(network);
2262
2263			kfree(ieee->assocresp_ies);
2264			ieee->assocresp_ies = NULL;
2265			ies = &(assoc_resp->info_element[0].id);
2266			ieee->assocresp_ies_len = (skb->data + skb->len) - ies;
2267			ieee->assocresp_ies = kmalloc(ieee->assocresp_ies_len,
2268						      GFP_ATOMIC);
2269			if (ieee->assocresp_ies)
2270				memcpy(ieee->assocresp_ies, ies,
2271				       ieee->assocresp_ies_len);
2272			else {
2273				netdev_info(ieee->dev,
2274					    "%s()Warning: can't alloc memory for assocresp_ies\n",
2275					    __func__);
2276				ieee->assocresp_ies_len = 0;
2277			}
2278			rtllib_associate_complete(ieee);
2279		} else {
2280			/* aid could not been allocated */
2281			ieee->softmac_stats.rx_ass_err++;
2282			netdev_info(ieee->dev,
2283				    "Association response status code 0x%x\n",
2284				    errcode);
2285			if (ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT)
2286				queue_delayed_work_rsl(ieee->wq,
2287					 &ieee->associate_procedure_wq, 0);
2288			else
2289				rtllib_associate_abort(ieee);
2290		}
2291	}
2292	return 0;
2293}
2294
2295static void rtllib_rx_auth_resp(struct rtllib_device *ieee, struct sk_buff *skb)
2296{
2297	u16 errcode;
2298	u8 *challenge;
2299	int chlen = 0;
2300	bool bSupportNmode = true, bHalfSupportNmode = false;
2301
2302	errcode = auth_parse(ieee->dev, skb, &challenge, &chlen);
2303
2304	if (errcode) {
2305		ieee->softmac_stats.rx_auth_rs_err++;
2306		netdev_info(ieee->dev,
2307			    "Authentication respose status code 0x%x", errcode);
2308		rtllib_associate_abort(ieee);
2309		return;
2310	}
2311
2312	if (ieee->open_wep || !challenge) {
2313		ieee->state = RTLLIB_ASSOCIATING_AUTHENTICATED;
2314		ieee->softmac_stats.rx_auth_rs_ok++;
2315		if (!(ieee->pHTInfo->IOTAction & HT_IOT_ACT_PURE_N_MODE)) {
2316			if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) {
2317				if (IsHTHalfNmodeAPs(ieee)) {
2318					bSupportNmode = true;
2319					bHalfSupportNmode = true;
2320				} else {
2321					bSupportNmode = false;
2322					bHalfSupportNmode = false;
2323				}
2324			}
2325		}
2326		/* Dummy wirless mode setting to avoid encryption issue */
2327		if (bSupportNmode) {
2328			ieee->SetWirelessMode(ieee->dev,
2329					      ieee->current_network.mode);
2330		} else {
2331			/*TODO*/
2332			ieee->SetWirelessMode(ieee->dev, IEEE_G);
2333		}
2334
2335		if ((ieee->current_network.mode == IEEE_N_24G) &&
2336		    bHalfSupportNmode) {
2337			netdev_info(ieee->dev, "======>enter half N mode\n");
2338			ieee->bHalfWirelessN24GMode = true;
2339		} else {
2340			ieee->bHalfWirelessN24GMode = false;
2341		}
2342		rtllib_associate_step2(ieee);
2343	} else {
2344		rtllib_auth_challenge(ieee, challenge,  chlen);
2345	}
2346}
2347
2348inline int rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb,
2349			  struct rtllib_rx_stats *rx_stats)
2350{
2351
2352	if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
2353		if (ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATING &&
2354		    (ieee->iw_mode == IW_MODE_INFRA)) {
2355			netdev_dbg(ieee->dev,
2356				   "Received authentication response");
2357			rtllib_rx_auth_resp(ieee, skb);
2358		} else if (ieee->iw_mode == IW_MODE_MASTER) {
2359			rtllib_rx_auth_rq(ieee, skb);
2360		}
2361	}
2362	return 0;
2363}
2364
2365inline int rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb)
2366{
2367	struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data;
2368	u16 frame_ctl;
2369
2370	if (memcmp(header->addr3, ieee->current_network.bssid, ETH_ALEN) != 0)
2371		return 0;
2372
2373	/* FIXME for now repeat all the association procedure
2374	 * both for disassociation and deauthentication
2375	 */
2376	if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2377	    ieee->state == RTLLIB_LINKED &&
2378	    (ieee->iw_mode == IW_MODE_INFRA)) {
2379		frame_ctl = le16_to_cpu(header->frame_ctl);
2380		netdev_info(ieee->dev,
2381			    "==========>received disassoc/deauth(%x) frame, reason code:%x\n",
2382			    WLAN_FC_GET_STYPE(frame_ctl),
2383			    ((struct rtllib_disassoc *)skb->data)->reason);
2384		ieee->state = RTLLIB_ASSOCIATING;
2385		ieee->softmac_stats.reassoc++;
2386		ieee->is_roaming = true;
2387		ieee->LinkDetectInfo.bBusyTraffic = false;
2388		rtllib_disassociate(ieee);
2389		RemovePeerTS(ieee, header->addr2);
2390		if (ieee->LedControlHandler != NULL)
2391			ieee->LedControlHandler(ieee->dev,
2392						LED_CTL_START_TO_LINK);
2393
2394		if (!(ieee->rtllib_ap_sec_type(ieee) &
2395		    (SEC_ALG_CCMP|SEC_ALG_TKIP)))
2396			queue_delayed_work_rsl(ieee->wq,
2397				       &ieee->associate_procedure_wq, 5);
2398	}
2399	return 0;
2400}
2401
2402inline int rtllib_rx_frame_softmac(struct rtllib_device *ieee,
2403				   struct sk_buff *skb,
2404				   struct rtllib_rx_stats *rx_stats, u16 type,
2405				   u16 stype)
2406{
2407	struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data;
2408	u16 frame_ctl;
2409
2410	if (!ieee->proto_started)
2411		return 0;
2412
2413	frame_ctl = le16_to_cpu(header->frame_ctl);
2414	switch (WLAN_FC_GET_STYPE(frame_ctl)) {
2415	case RTLLIB_STYPE_ASSOC_RESP:
2416	case RTLLIB_STYPE_REASSOC_RESP:
2417		if (rtllib_rx_assoc_resp(ieee, skb, rx_stats) == 1)
2418			return 1;
2419		break;
2420	case RTLLIB_STYPE_ASSOC_REQ:
2421	case RTLLIB_STYPE_REASSOC_REQ:
2422		if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2423		     ieee->iw_mode == IW_MODE_MASTER)
2424			rtllib_rx_assoc_rq(ieee, skb);
2425		break;
2426	case RTLLIB_STYPE_AUTH:
2427		rtllib_rx_auth(ieee, skb, rx_stats);
2428		break;
2429	case RTLLIB_STYPE_DISASSOC:
2430	case RTLLIB_STYPE_DEAUTH:
2431		rtllib_rx_deauth(ieee, skb);
2432		break;
2433	case RTLLIB_STYPE_MANAGE_ACT:
2434		rtllib_process_action(ieee, skb);
2435		break;
2436	default:
2437		return -1;
2438	}
2439	return 0;
2440}
2441
2442/* following are for a simpler TX queue management.
2443 * Instead of using netif_[stop/wake]_queue the driver
2444 * will use these two functions (plus a reset one), that
2445 * will internally use the kernel netif_* and takes
2446 * care of the ieee802.11 fragmentation.
2447 * So the driver receives a fragment per time and might
2448 * call the stop function when it wants to not
2449 * have enough room to TX an entire packet.
2450 * This might be useful if each fragment needs it's own
2451 * descriptor, thus just keep a total free memory > than
2452 * the max fragmentation threshold is not enough.. If the
2453 * ieee802.11 stack passed a TXB struct then you need
2454 * to keep N free descriptors where
2455 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2456 * In this way you need just one and the 802.11 stack
2457 * will take care of buffering fragments and pass them to
2458 * to the driver later, when it wakes the queue.
2459 */
2460void rtllib_softmac_xmit(struct rtllib_txb *txb, struct rtllib_device *ieee)
2461{
2462
2463	unsigned int queue_index = txb->queue_index;
2464	unsigned long flags;
2465	int  i;
2466	struct cb_desc *tcb_desc = NULL;
2467	unsigned long queue_len = 0;
2468
2469	spin_lock_irqsave(&ieee->lock, flags);
2470
2471	/* called with 2nd parm 0, no tx mgmt lock required */
2472	rtllib_sta_wakeup(ieee, 0);
2473
2474	/* update the tx status */
2475	tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb +
2476		   MAX_DEV_ADDR_SIZE);
2477	if (tcb_desc->bMulticast)
2478		ieee->stats.multicast++;
2479
2480	/* if xmit available, just xmit it immediately, else just insert it to
2481	 * the wait queue
2482	 */
2483	for (i = 0; i < txb->nr_frags; i++) {
2484		queue_len = skb_queue_len(&ieee->skb_waitQ[queue_index]);
2485		if ((queue_len  != 0) ||
2486		    (!ieee->check_nic_enough_desc(ieee->dev, queue_index)) ||
2487		    (ieee->queue_stop)) {
2488			/* insert the skb packet to the wait queue
2489			 * as for the completion function, it does not need
2490			 * to check it any more.
2491			 */
2492			if (queue_len < 200)
2493				skb_queue_tail(&ieee->skb_waitQ[queue_index],
2494					       txb->fragments[i]);
2495			else
2496				kfree_skb(txb->fragments[i]);
2497		} else {
2498			ieee->softmac_data_hard_start_xmit(
2499					txb->fragments[i],
2500					ieee->dev, ieee->rate);
2501		}
2502	}
2503
2504	rtllib_txb_free(txb);
2505
2506	spin_unlock_irqrestore(&ieee->lock, flags);
2507
2508}
2509
2510void rtllib_reset_queue(struct rtllib_device *ieee)
2511{
2512	unsigned long flags;
2513
2514	spin_lock_irqsave(&ieee->lock, flags);
2515	init_mgmt_queue(ieee);
2516	if (ieee->tx_pending.txb) {
2517		rtllib_txb_free(ieee->tx_pending.txb);
2518		ieee->tx_pending.txb = NULL;
2519	}
2520	ieee->queue_stop = 0;
2521	spin_unlock_irqrestore(&ieee->lock, flags);
2522
2523}
2524EXPORT_SYMBOL(rtllib_reset_queue);
2525
2526void rtllib_stop_all_queues(struct rtllib_device *ieee)
2527{
2528	unsigned int i;
2529
2530	for (i = 0; i < ieee->dev->num_tx_queues; i++)
2531		netdev_get_tx_queue(ieee->dev, i)->trans_start = jiffies;
2532
2533	netif_tx_stop_all_queues(ieee->dev);
2534}
2535
2536void rtllib_wake_all_queues(struct rtllib_device *ieee)
2537{
2538	netif_tx_wake_all_queues(ieee->dev);
2539}
2540
2541inline void rtllib_randomize_cell(struct rtllib_device *ieee)
2542{
2543
2544	random_ether_addr(ieee->current_network.bssid);
2545}
2546
2547/* called in user context only */
2548static void rtllib_start_master_bss(struct rtllib_device *ieee)
2549{
2550	ieee->assoc_id = 1;
2551
2552	if (ieee->current_network.ssid_len == 0) {
2553		strncpy(ieee->current_network.ssid,
2554			RTLLIB_DEFAULT_TX_ESSID,
2555			IW_ESSID_MAX_SIZE);
2556
2557		ieee->current_network.ssid_len =
2558				 strlen(RTLLIB_DEFAULT_TX_ESSID);
2559		ieee->ssid_set = 1;
2560	}
2561
2562	ether_addr_copy(ieee->current_network.bssid, ieee->dev->dev_addr);
2563
2564	ieee->set_chan(ieee->dev, ieee->current_network.channel);
2565	ieee->state = RTLLIB_LINKED;
2566	ieee->link_change(ieee->dev);
2567	notify_wx_assoc_event(ieee);
2568
2569	if (ieee->data_hard_resume)
2570		ieee->data_hard_resume(ieee->dev);
2571
2572	netif_carrier_on(ieee->dev);
2573}
2574
2575static void rtllib_start_monitor_mode(struct rtllib_device *ieee)
2576{
2577	/* reset hardware status */
2578	if (ieee->raw_tx) {
2579		if (ieee->data_hard_resume)
2580			ieee->data_hard_resume(ieee->dev);
2581
2582		netif_carrier_on(ieee->dev);
2583	}
2584}
2585
2586static void rtllib_start_ibss_wq(void *data)
2587{
2588	struct rtllib_device *ieee = container_of_dwork_rsl(data,
2589				     struct rtllib_device, start_ibss_wq);
2590	/* iwconfig mode ad-hoc will schedule this and return
2591	 * on the other hand this will block further iwconfig SET
2592	 * operations because of the wx_sem hold.
2593	 * Anyway some most set operations set a flag to speed-up
2594	 * (abort) this wq (when syncro scanning) before sleeping
2595	 * on the semaphore
2596	 */
2597	if (!ieee->proto_started) {
2598		netdev_info(ieee->dev, "==========oh driver down return\n");
2599		return;
2600	}
2601	down(&ieee->wx_sem);
2602
2603	if (ieee->current_network.ssid_len == 0) {
2604		strcpy(ieee->current_network.ssid, RTLLIB_DEFAULT_TX_ESSID);
2605		ieee->current_network.ssid_len = strlen(RTLLIB_DEFAULT_TX_ESSID);
2606		ieee->ssid_set = 1;
2607	}
2608
2609	ieee->state = RTLLIB_NOLINK;
2610	ieee->mode = IEEE_G;
2611	/* check if we have this cell in our network list */
2612	rtllib_softmac_check_all_nets(ieee);
2613
2614
2615	/* if not then the state is not linked. Maybe the user switched to
2616	 * ad-hoc mode just after being in monitor mode, or just after
2617	 * being very few time in managed mode (so the card have had no
2618	 * time to scan all the chans..) or we have just run up the iface
2619	 * after setting ad-hoc mode. So we have to give another try..
2620	 * Here, in ibss mode, should be safe to do this without extra care
2621	 * (in bss mode we had to make sure no-one tried to associate when
2622	 * we had just checked the ieee->state and we was going to start the
2623	 * scan) because in ibss mode the rtllib_new_net function, when
2624	 * finds a good net, just set the ieee->state to RTLLIB_LINKED,
2625	 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2626	 * scan, that will stop at the first round because it sees the state
2627	 * associated.
2628	 */
2629	if (ieee->state == RTLLIB_NOLINK)
2630		rtllib_start_scan_syncro(ieee, 0);
2631
2632	/* the network definitively is not here.. create a new cell */
2633	if (ieee->state == RTLLIB_NOLINK) {
2634		netdev_info(ieee->dev, "creating new IBSS cell\n");
2635		ieee->current_network.channel = ieee->IbssStartChnl;
2636		if (!ieee->wap_set)
2637			rtllib_randomize_cell(ieee);
2638
2639		if (ieee->modulation & RTLLIB_CCK_MODULATION) {
2640
2641			ieee->current_network.rates_len = 4;
2642
2643			ieee->current_network.rates[0] =
2644				 RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB;
2645			ieee->current_network.rates[1] =
2646				 RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB;
2647			ieee->current_network.rates[2] =
2648				 RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB;
2649			ieee->current_network.rates[3] =
2650				 RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB;
2651
2652		} else
2653			ieee->current_network.rates_len = 0;
2654
2655		if (ieee->modulation & RTLLIB_OFDM_MODULATION) {
2656			ieee->current_network.rates_ex_len = 8;
2657
2658			ieee->current_network.rates_ex[0] =
2659						 RTLLIB_OFDM_RATE_6MB;
2660			ieee->current_network.rates_ex[1] =
2661						 RTLLIB_OFDM_RATE_9MB;
2662			ieee->current_network.rates_ex[2] =
2663						 RTLLIB_OFDM_RATE_12MB;
2664			ieee->current_network.rates_ex[3] =
2665						 RTLLIB_OFDM_RATE_18MB;
2666			ieee->current_network.rates_ex[4] =
2667						 RTLLIB_OFDM_RATE_24MB;
2668			ieee->current_network.rates_ex[5] =
2669						 RTLLIB_OFDM_RATE_36MB;
2670			ieee->current_network.rates_ex[6] =
2671						 RTLLIB_OFDM_RATE_48MB;
2672			ieee->current_network.rates_ex[7] =
2673						 RTLLIB_OFDM_RATE_54MB;
2674
2675			ieee->rate = 108;
2676		} else {
2677			ieee->current_network.rates_ex_len = 0;
2678			ieee->rate = 22;
2679		}
2680
2681		ieee->current_network.qos_data.supported = 0;
2682		ieee->SetWirelessMode(ieee->dev, IEEE_G);
2683		ieee->current_network.mode = ieee->mode;
2684		ieee->current_network.atim_window = 0;
2685		ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2686	}
2687
2688	netdev_info(ieee->dev, "%s(): ieee->mode = %d\n", __func__, ieee->mode);
2689	if ((ieee->mode == IEEE_N_24G) || (ieee->mode == IEEE_N_5G))
2690		HTUseDefaultSetting(ieee);
2691	else
2692		ieee->pHTInfo->bCurrentHTSupport = false;
2693
2694	ieee->SetHwRegHandler(ieee->dev, HW_VAR_MEDIA_STATUS,
2695			      (u8 *)(&ieee->state));
2696
2697	ieee->state = RTLLIB_LINKED;
2698	ieee->link_change(ieee->dev);
2699
2700	HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2701	if (ieee->LedControlHandler != NULL)
2702		ieee->LedControlHandler(ieee->dev, LED_CTL_LINK);
2703
2704	rtllib_start_send_beacons(ieee);
2705
2706	notify_wx_assoc_event(ieee);
2707
2708	if (ieee->data_hard_resume)
2709		ieee->data_hard_resume(ieee->dev);
2710
2711	netif_carrier_on(ieee->dev);
2712
2713	up(&ieee->wx_sem);
2714}
2715
2716inline void rtllib_start_ibss(struct rtllib_device *ieee)
2717{
2718	queue_delayed_work_rsl(ieee->wq, &ieee->start_ibss_wq,
2719			       msecs_to_jiffies(150));
2720}
2721
2722/* this is called only in user context, with wx_sem held */
2723static void rtllib_start_bss(struct rtllib_device *ieee)
2724{
2725	unsigned long flags;
2726
2727	if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) {
2728		if (!ieee->bGlobalDomain)
2729			return;
2730	}
2731	/* check if we have already found the net we
2732	 * are interested in (if any).
2733	 * if not (we are disassociated and we are not
2734	 * in associating / authenticating phase) start the background scanning.
2735	 */
2736	rtllib_softmac_check_all_nets(ieee);
2737
2738	/* ensure no-one start an associating process (thus setting
2739	 * the ieee->state to rtllib_ASSOCIATING) while we
2740	 * have just checked it and we are going to enable scan.
2741	 * The rtllib_new_net function is always called with
2742	 * lock held (from both rtllib_softmac_check_all_nets and
2743	 * the rx path), so we cannot be in the middle of such function
2744	 */
2745	spin_lock_irqsave(&ieee->lock, flags);
2746
2747	if (ieee->state == RTLLIB_NOLINK)
2748		rtllib_start_scan(ieee);
2749	spin_unlock_irqrestore(&ieee->lock, flags);
2750}
2751
2752static void rtllib_link_change_wq(void *data)
2753{
2754	struct rtllib_device *ieee = container_of_dwork_rsl(data,
2755				     struct rtllib_device, link_change_wq);
2756	ieee->link_change(ieee->dev);
2757}
2758/* called only in userspace context */
2759void rtllib_disassociate(struct rtllib_device *ieee)
2760{
2761	netif_carrier_off(ieee->dev);
2762	if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2763		rtllib_reset_queue(ieee);
2764
2765	if (ieee->data_hard_stop)
2766		ieee->data_hard_stop(ieee->dev);
2767	if (IS_DOT11D_ENABLE(ieee))
2768		Dot11d_Reset(ieee);
2769	ieee->state = RTLLIB_NOLINK;
2770	ieee->is_set_key = false;
2771	ieee->wap_set = 0;
2772
2773	queue_delayed_work_rsl(ieee->wq, &ieee->link_change_wq, 0);
2774
2775	notify_wx_assoc_event(ieee);
2776}
2777
2778static void rtllib_associate_retry_wq(void *data)
2779{
2780	struct rtllib_device *ieee = container_of_dwork_rsl(data,
2781				     struct rtllib_device, associate_retry_wq);
2782	unsigned long flags;
2783
2784	down(&ieee->wx_sem);
2785	if (!ieee->proto_started)
2786		goto exit;
2787
2788	if (ieee->state != RTLLIB_ASSOCIATING_RETRY)
2789		goto exit;
2790
2791	/* until we do not set the state to RTLLIB_NOLINK
2792	 * there are no possibility to have someone else trying
2793	 * to start an association procedure (we get here with
2794	 * ieee->state = RTLLIB_ASSOCIATING).
2795	 * When we set the state to RTLLIB_NOLINK it is possible
2796	 * that the RX path run an attempt to associate, but
2797	 * both rtllib_softmac_check_all_nets and the
2798	 * RX path works with ieee->lock held so there are no
2799	 * problems. If we are still disassociated then start a scan.
2800	 * the lock here is necessary to ensure no one try to start
2801	 * an association procedure when we have just checked the
2802	 * state and we are going to start the scan.
2803	 */
2804	ieee->beinretry = true;
2805	ieee->state = RTLLIB_NOLINK;
2806
2807	rtllib_softmac_check_all_nets(ieee);
2808
2809	spin_lock_irqsave(&ieee->lock, flags);
2810
2811	if (ieee->state == RTLLIB_NOLINK)
2812		rtllib_start_scan(ieee);
2813	spin_unlock_irqrestore(&ieee->lock, flags);
2814
2815	ieee->beinretry = false;
2816exit:
2817	up(&ieee->wx_sem);
2818}
2819
2820static struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee)
2821{
2822	const u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2823
2824	struct sk_buff *skb;
2825	struct rtllib_probe_response *b;
2826
2827	skb = rtllib_probe_resp(ieee, broadcast_addr);
2828
2829	if (!skb)
2830		return NULL;
2831
2832	b = (struct rtllib_probe_response *) skb->data;
2833	b->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_BEACON);
2834
2835	return skb;
2836
2837}
2838
2839struct sk_buff *rtllib_get_beacon(struct rtllib_device *ieee)
2840{
2841	struct sk_buff *skb;
2842	struct rtllib_probe_response *b;
2843
2844	skb = rtllib_get_beacon_(ieee);
2845	if (!skb)
2846		return NULL;
2847
2848	b = (struct rtllib_probe_response *) skb->data;
2849	b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2850
2851	if (ieee->seq_ctrl[0] == 0xFFF)
2852		ieee->seq_ctrl[0] = 0;
2853	else
2854		ieee->seq_ctrl[0]++;
2855
2856	return skb;
2857}
2858EXPORT_SYMBOL(rtllib_get_beacon);
2859
2860void rtllib_softmac_stop_protocol(struct rtllib_device *ieee, u8 mesh_flag,
2861				  u8 shutdown)
2862{
2863	rtllib_stop_scan_syncro(ieee);
2864	down(&ieee->wx_sem);
2865	rtllib_stop_protocol(ieee, shutdown);
2866	up(&ieee->wx_sem);
2867}
2868EXPORT_SYMBOL(rtllib_softmac_stop_protocol);
2869
2870
2871void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown)
2872{
2873	if (!ieee->proto_started)
2874		return;
2875
2876	if (shutdown) {
2877		ieee->proto_started = 0;
2878		ieee->proto_stoppping = 1;
2879		if (ieee->rtllib_ips_leave != NULL)
2880			ieee->rtllib_ips_leave(ieee->dev);
2881	}
2882
2883	rtllib_stop_send_beacons(ieee);
2884	del_timer_sync(&ieee->associate_timer);
2885	cancel_delayed_work(&ieee->associate_retry_wq);
2886	cancel_delayed_work(&ieee->start_ibss_wq);
2887	cancel_delayed_work(&ieee->link_change_wq);
2888	rtllib_stop_scan(ieee);
2889
2890	if (ieee->state <= RTLLIB_ASSOCIATING_AUTHENTICATED)
2891		ieee->state = RTLLIB_NOLINK;
2892
2893	if (ieee->state == RTLLIB_LINKED) {
2894		if (ieee->iw_mode == IW_MODE_INFRA)
2895			SendDisassociation(ieee, 1, WLAN_REASON_DEAUTH_LEAVING);
2896		rtllib_disassociate(ieee);
2897	}
2898
2899	if (shutdown) {
2900		RemoveAllTS(ieee);
2901		ieee->proto_stoppping = 0;
2902	}
2903	kfree(ieee->assocreq_ies);
2904	ieee->assocreq_ies = NULL;
2905	ieee->assocreq_ies_len = 0;
2906	kfree(ieee->assocresp_ies);
2907	ieee->assocresp_ies = NULL;
2908	ieee->assocresp_ies_len = 0;
2909}
2910
2911void rtllib_softmac_start_protocol(struct rtllib_device *ieee, u8 mesh_flag)
2912{
2913	down(&ieee->wx_sem);
2914	rtllib_start_protocol(ieee);
2915	up(&ieee->wx_sem);
2916}
2917EXPORT_SYMBOL(rtllib_softmac_start_protocol);
2918
2919void rtllib_start_protocol(struct rtllib_device *ieee)
2920{
2921	short ch = 0;
2922	int i = 0;
2923
2924	rtllib_update_active_chan_map(ieee);
2925
2926	if (ieee->proto_started)
2927		return;
2928
2929	ieee->proto_started = 1;
2930
2931	if (ieee->current_network.channel == 0) {
2932		do {
2933			ch++;
2934			if (ch > MAX_CHANNEL_NUMBER)
2935				return; /* no channel found */
2936		} while (!ieee->active_channel_map[ch]);
2937		ieee->current_network.channel = ch;
2938	}
2939
2940	if (ieee->current_network.beacon_interval == 0)
2941		ieee->current_network.beacon_interval = 100;
2942
2943	for (i = 0; i < 17; i++) {
2944		ieee->last_rxseq_num[i] = -1;
2945		ieee->last_rxfrag_num[i] = -1;
2946		ieee->last_packet_time[i] = 0;
2947	}
2948
2949	if (ieee->UpdateBeaconInterruptHandler)
2950		ieee->UpdateBeaconInterruptHandler(ieee->dev, false);
2951
2952	ieee->wmm_acm = 0;
2953	/* if the user set the MAC of the ad-hoc cell and then
2954	 * switch to managed mode, shall we  make sure that association
2955	 * attempts does not fail just because the user provide the essid
2956	 * and the nic is still checking for the AP MAC ??
2957	 */
2958	if (ieee->iw_mode == IW_MODE_INFRA) {
2959		rtllib_start_bss(ieee);
2960	} else if (ieee->iw_mode == IW_MODE_ADHOC) {
2961		if (ieee->UpdateBeaconInterruptHandler)
2962			ieee->UpdateBeaconInterruptHandler(ieee->dev, true);
2963
2964		rtllib_start_ibss(ieee);
2965
2966	} else if (ieee->iw_mode == IW_MODE_MASTER) {
2967		rtllib_start_master_bss(ieee);
2968	} else if (ieee->iw_mode == IW_MODE_MONITOR) {
2969		rtllib_start_monitor_mode(ieee);
2970	}
2971}
2972
2973void rtllib_softmac_init(struct rtllib_device *ieee)
2974{
2975	int i;
2976
2977	memset(&ieee->current_network, 0, sizeof(struct rtllib_network));
2978
2979	ieee->state = RTLLIB_NOLINK;
2980	for (i = 0; i < 5; i++)
2981		ieee->seq_ctrl[i] = 0;
2982	ieee->pDot11dInfo = kzalloc(sizeof(struct rt_dot11d_info), GFP_ATOMIC);
2983	if (!ieee->pDot11dInfo)
2984		netdev_err(ieee->dev, "Can't alloc memory for DOT11D\n");
2985	ieee->LinkDetectInfo.SlotIndex = 0;
2986	ieee->LinkDetectInfo.SlotNum = 2;
2987	ieee->LinkDetectInfo.NumRecvBcnInPeriod = 0;
2988	ieee->LinkDetectInfo.NumRecvDataInPeriod = 0;
2989	ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
2990	ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
2991	ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
2992	ieee->bIsAggregateFrame = false;
2993	ieee->assoc_id = 0;
2994	ieee->queue_stop = 0;
2995	ieee->scanning_continue = 0;
2996	ieee->softmac_features = 0;
2997	ieee->wap_set = 0;
2998	ieee->ssid_set = 0;
2999	ieee->proto_started = 0;
3000	ieee->proto_stoppping = 0;
3001	ieee->basic_rate = RTLLIB_DEFAULT_BASIC_RATE;
3002	ieee->rate = 22;
3003	ieee->ps = RTLLIB_PS_DISABLED;
3004	ieee->sta_sleep = LPS_IS_WAKE;
3005
3006	ieee->Regdot11HTOperationalRateSet[0] = 0xff;
3007	ieee->Regdot11HTOperationalRateSet[1] = 0xff;
3008	ieee->Regdot11HTOperationalRateSet[4] = 0x01;
3009
3010	ieee->Regdot11TxHTOperationalRateSet[0] = 0xff;
3011	ieee->Regdot11TxHTOperationalRateSet[1] = 0xff;
3012	ieee->Regdot11TxHTOperationalRateSet[4] = 0x01;
3013
3014	ieee->FirstIe_InScan = false;
3015	ieee->actscanning = false;
3016	ieee->beinretry = false;
3017	ieee->is_set_key = false;
3018	init_mgmt_queue(ieee);
3019
3020	ieee->tx_pending.txb = NULL;
3021
3022	setup_timer(&ieee->associate_timer,
3023		    rtllib_associate_abort_cb,
3024		    (unsigned long) ieee);
3025
3026	setup_timer(&ieee->beacon_timer,
3027		    rtllib_send_beacon_cb,
3028		    (unsigned long) ieee);
3029
3030
3031	ieee->wq = create_workqueue(DRV_NAME);
3032
3033	INIT_DELAYED_WORK_RSL(&ieee->link_change_wq,
3034			      (void *)rtllib_link_change_wq, ieee);
3035	INIT_DELAYED_WORK_RSL(&ieee->start_ibss_wq,
3036			      (void *)rtllib_start_ibss_wq, ieee);
3037	INIT_WORK_RSL(&ieee->associate_complete_wq,
3038		      (void *)rtllib_associate_complete_wq, ieee);
3039	INIT_DELAYED_WORK_RSL(&ieee->associate_procedure_wq,
3040			      (void *)rtllib_associate_procedure_wq, ieee);
3041	INIT_DELAYED_WORK_RSL(&ieee->softmac_scan_wq,
3042			      (void *)rtllib_softmac_scan_wq, ieee);
3043	INIT_DELAYED_WORK_RSL(&ieee->associate_retry_wq,
3044			      (void *)rtllib_associate_retry_wq, ieee);
3045	INIT_WORK_RSL(&ieee->wx_sync_scan_wq, (void *)rtllib_wx_sync_scan_wq,
3046		      ieee);
3047
3048	sema_init(&ieee->wx_sem, 1);
3049	sema_init(&ieee->scan_sem, 1);
3050	sema_init(&ieee->ips_sem, 1);
3051
3052	spin_lock_init(&ieee->mgmt_tx_lock);
3053	spin_lock_init(&ieee->beacon_lock);
3054
3055	tasklet_init(&ieee->ps_task,
3056	     (void(*)(unsigned long)) rtllib_sta_ps,
3057	     (unsigned long)ieee);
3058
3059}
3060
3061void rtllib_softmac_free(struct rtllib_device *ieee)
3062{
3063	down(&ieee->wx_sem);
3064	kfree(ieee->pDot11dInfo);
3065	ieee->pDot11dInfo = NULL;
3066	del_timer_sync(&ieee->associate_timer);
3067
3068	cancel_delayed_work(&ieee->associate_retry_wq);
3069	destroy_workqueue(ieee->wq);
3070	up(&ieee->wx_sem);
3071	tasklet_kill(&ieee->ps_task);
3072}
3073
3074/********************************************************
3075 * Start of WPA code.				        *
3076 * this is stolen from the ipw2200 driver	        *
3077 ********************************************************/
3078
3079
3080static int rtllib_wpa_enable(struct rtllib_device *ieee, int value)
3081{
3082	/* This is called when wpa_supplicant loads and closes the driver
3083	 * interface.
3084	 */
3085	netdev_info(ieee->dev, "%s WPA\n", value ? "enabling" : "disabling");
3086	ieee->wpa_enabled = value;
3087	eth_zero_addr(ieee->ap_mac_addr);
3088	return 0;
3089}
3090
3091
3092static void rtllib_wpa_assoc_frame(struct rtllib_device *ieee, char *wpa_ie,
3093				   int wpa_ie_len)
3094{
3095	/* make sure WPA is enabled */
3096	rtllib_wpa_enable(ieee, 1);
3097
3098	rtllib_disassociate(ieee);
3099}
3100
3101
3102static int rtllib_wpa_mlme(struct rtllib_device *ieee, int command, int reason)
3103{
3104
3105	int ret = 0;
3106
3107	switch (command) {
3108	case IEEE_MLME_STA_DEAUTH:
3109		break;
3110
3111	case IEEE_MLME_STA_DISASSOC:
3112		rtllib_disassociate(ieee);
3113		break;
3114
3115	default:
3116		netdev_info(ieee->dev, "Unknown MLME request: %d\n", command);
3117		ret = -EOPNOTSUPP;
3118	}
3119
3120	return ret;
3121}
3122
3123
3124static int rtllib_wpa_set_wpa_ie(struct rtllib_device *ieee,
3125			      struct ieee_param *param, int plen)
3126{
3127	u8 *buf;
3128
3129	if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
3130	    (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
3131		return -EINVAL;
3132
3133	if (param->u.wpa_ie.len) {
3134		buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
3135			      GFP_KERNEL);
3136		if (buf == NULL)
3137			return -ENOMEM;
3138
3139		kfree(ieee->wpa_ie);
3140		ieee->wpa_ie = buf;
3141		ieee->wpa_ie_len = param->u.wpa_ie.len;
3142	} else {
3143		kfree(ieee->wpa_ie);
3144		ieee->wpa_ie = NULL;
3145		ieee->wpa_ie_len = 0;
3146	}
3147
3148	rtllib_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
3149	return 0;
3150}
3151
3152#define AUTH_ALG_OPEN_SYSTEM			0x1
3153#define AUTH_ALG_SHARED_KEY			0x2
3154#define AUTH_ALG_LEAP				0x4
3155static int rtllib_wpa_set_auth_algs(struct rtllib_device *ieee, int value)
3156{
3157
3158	struct rtllib_security sec = {
3159		.flags = SEC_AUTH_MODE,
3160	};
3161
3162	if (value & AUTH_ALG_SHARED_KEY) {
3163		sec.auth_mode = WLAN_AUTH_SHARED_KEY;
3164		ieee->open_wep = 0;
3165		ieee->auth_mode = 1;
3166	} else if (value & AUTH_ALG_OPEN_SYSTEM) {
3167		sec.auth_mode = WLAN_AUTH_OPEN;
3168		ieee->open_wep = 1;
3169		ieee->auth_mode = 0;
3170	} else if (value & AUTH_ALG_LEAP) {
3171		sec.auth_mode = WLAN_AUTH_LEAP  >> 6;
3172		ieee->open_wep = 1;
3173		ieee->auth_mode = 2;
3174	}
3175
3176
3177	if (ieee->set_security)
3178		ieee->set_security(ieee->dev, &sec);
3179
3180	return 0;
3181}
3182
3183static int rtllib_wpa_set_param(struct rtllib_device *ieee, u8 name, u32 value)
3184{
3185	int ret = 0;
3186	unsigned long flags;
3187
3188	switch (name) {
3189	case IEEE_PARAM_WPA_ENABLED:
3190		ret = rtllib_wpa_enable(ieee, value);
3191		break;
3192
3193	case IEEE_PARAM_TKIP_COUNTERMEASURES:
3194		ieee->tkip_countermeasures = value;
3195		break;
3196
3197	case IEEE_PARAM_DROP_UNENCRYPTED:
3198	{
3199		/* HACK:
3200		 *
3201		 * wpa_supplicant calls set_wpa_enabled when the driver
3202		 * is loaded and unloaded, regardless of if WPA is being
3203		 * used.  No other calls are made which can be used to
3204		 * determine if encryption will be used or not prior to
3205		 * association being expected.  If encryption is not being
3206		 * used, drop_unencrypted is set to false, else true -- we
3207		 * can use this to determine if the CAP_PRIVACY_ON bit should
3208		 * be set.
3209		 */
3210		struct rtllib_security sec = {
3211			.flags = SEC_ENABLED,
3212			.enabled = value,
3213		};
3214		ieee->drop_unencrypted = value;
3215		/* We only change SEC_LEVEL for open mode. Others
3216		 * are set by ipw_wpa_set_encryption.
3217		 */
3218		if (!value) {
3219			sec.flags |= SEC_LEVEL;
3220			sec.level = SEC_LEVEL_0;
3221		} else {
3222			sec.flags |= SEC_LEVEL;
3223			sec.level = SEC_LEVEL_1;
3224		}
3225		if (ieee->set_security)
3226			ieee->set_security(ieee->dev, &sec);
3227		break;
3228	}
3229
3230	case IEEE_PARAM_PRIVACY_INVOKED:
3231		ieee->privacy_invoked = value;
3232		break;
3233
3234	case IEEE_PARAM_AUTH_ALGS:
3235		ret = rtllib_wpa_set_auth_algs(ieee, value);
3236		break;
3237
3238	case IEEE_PARAM_IEEE_802_1X:
3239		ieee->ieee802_1x = value;
3240		break;
3241	case IEEE_PARAM_WPAX_SELECT:
3242		spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
3243		spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
3244		break;
3245
3246	default:
3247		netdev_info(ieee->dev, "Unknown WPA param: %d\n", name);
3248		ret = -EOPNOTSUPP;
3249	}
3250
3251	return ret;
3252}
3253
3254/* implementation borrowed from hostap driver */
3255static int rtllib_wpa_set_encryption(struct rtllib_device *ieee,
3256				  struct ieee_param *param, int param_len,
3257				  u8 is_mesh)
3258{
3259	int ret = 0;
3260	struct lib80211_crypto_ops *ops;
3261	struct lib80211_crypt_data **crypt;
3262
3263	struct rtllib_security sec = {
3264		.flags = 0,
3265	};
3266
3267	param->u.crypt.err = 0;
3268	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
3269
3270	if (param_len !=
3271	    (int) ((char *) param->u.crypt.key - (char *) param) +
3272	    param->u.crypt.key_len) {
3273		netdev_info(ieee->dev, "Len mismatch %d, %d\n", param_len,
3274			    param->u.crypt.key_len);
3275		return -EINVAL;
3276	}
3277	if (is_broadcast_ether_addr(param->sta_addr)) {
3278		if (param->u.crypt.idx >= NUM_WEP_KEYS)
3279			return -EINVAL;
3280		crypt = &ieee->crypt_info.crypt[param->u.crypt.idx];
3281	} else {
3282		return -EINVAL;
3283	}
3284
3285	if (strcmp(param->u.crypt.alg, "none") == 0) {
3286		if (crypt) {
3287			sec.enabled = 0;
3288			sec.level = SEC_LEVEL_0;
3289			sec.flags |= SEC_ENABLED | SEC_LEVEL;
3290			lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
3291		}
3292		goto done;
3293	}
3294	sec.enabled = 1;
3295	sec.flags |= SEC_ENABLED;
3296
3297	/* IPW HW cannot build TKIP MIC, host decryption still needed. */
3298	if (!(ieee->host_encrypt || ieee->host_decrypt) &&
3299	    strcmp(param->u.crypt.alg, "R-TKIP"))
3300		goto skip_host_crypt;
3301
3302	ops = lib80211_get_crypto_ops(param->u.crypt.alg);
3303	if (ops == NULL && strcmp(param->u.crypt.alg, "R-WEP") == 0) {
3304		request_module("rtllib_crypt_wep");
3305		ops = lib80211_get_crypto_ops(param->u.crypt.alg);
3306	} else if (ops == NULL && strcmp(param->u.crypt.alg, "R-TKIP") == 0) {
3307		request_module("rtllib_crypt_tkip");
3308		ops = lib80211_get_crypto_ops(param->u.crypt.alg);
3309	} else if (ops == NULL && strcmp(param->u.crypt.alg, "R-CCMP") == 0) {
3310		request_module("rtllib_crypt_ccmp");
3311		ops = lib80211_get_crypto_ops(param->u.crypt.alg);
3312	}
3313	if (ops == NULL) {
3314		netdev_info(ieee->dev, "unknown crypto alg '%s'\n",
3315			    param->u.crypt.alg);
3316		param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3317		ret = -EINVAL;
3318		goto done;
3319	}
3320	if (*crypt == NULL || (*crypt)->ops != ops) {
3321		struct lib80211_crypt_data *new_crypt;
3322
3323		lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
3324
3325		new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
3326		if (new_crypt == NULL) {
3327			ret = -ENOMEM;
3328			goto done;
3329		}
3330		new_crypt->ops = ops;
3331		if (new_crypt->ops)
3332			new_crypt->priv =
3333				new_crypt->ops->init(param->u.crypt.idx);
3334
3335		if (new_crypt->priv == NULL) {
3336			kfree(new_crypt);
3337			param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3338			ret = -EINVAL;
3339			goto done;
3340		}
3341
3342		*crypt = new_crypt;
3343	}
3344
3345	if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3346	    (*crypt)->ops->set_key(param->u.crypt.key,
3347	    param->u.crypt.key_len, param->u.crypt.seq,
3348	    (*crypt)->priv) < 0) {
3349		netdev_info(ieee->dev, "key setting failed\n");
3350		param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3351		ret = -EINVAL;
3352		goto done;
3353	}
3354
3355 skip_host_crypt:
3356	if (param->u.crypt.set_tx) {
3357		ieee->crypt_info.tx_keyidx = param->u.crypt.idx;
3358		sec.active_key = param->u.crypt.idx;
3359		sec.flags |= SEC_ACTIVE_KEY;
3360	} else
3361		sec.flags &= ~SEC_ACTIVE_KEY;
3362
3363	if (param->u.crypt.alg != NULL) {
3364		memcpy(sec.keys[param->u.crypt.idx],
3365		       param->u.crypt.key,
3366		       param->u.crypt.key_len);
3367		sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3368		sec.flags |= (1 << param->u.crypt.idx);
3369
3370		if (strcmp(param->u.crypt.alg, "R-WEP") == 0) {
3371			sec.flags |= SEC_LEVEL;
3372			sec.level = SEC_LEVEL_1;
3373		} else if (strcmp(param->u.crypt.alg, "R-TKIP") == 0) {
3374			sec.flags |= SEC_LEVEL;
3375			sec.level = SEC_LEVEL_2;
3376		} else if (strcmp(param->u.crypt.alg, "R-CCMP") == 0) {
3377			sec.flags |= SEC_LEVEL;
3378			sec.level = SEC_LEVEL_3;
3379		}
3380	}
3381 done:
3382	if (ieee->set_security)
3383		ieee->set_security(ieee->dev, &sec);
3384
3385	/* Do not reset port if card is in Managed mode since resetting will
3386	 * generate new IEEE 802.11 authentication which may end up in looping
3387	 * with IEEE 802.1X.  If your hardware requires a reset after WEP
3388	 * configuration (for example... Prism2), implement the reset_port in
3389	 * the callbacks structures used to initialize the 802.11 stack.
3390	 */
3391	if (ieee->reset_on_keychange &&
3392	    ieee->iw_mode != IW_MODE_INFRA &&
3393	    ieee->reset_port &&
3394	    ieee->reset_port(ieee->dev)) {
3395		netdev_info(ieee->dev, "reset_port failed\n");
3396		param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3397		return -EINVAL;
3398	}
3399
3400	return ret;
3401}
3402
3403inline struct sk_buff *rtllib_disauth_skb(struct rtllib_network *beacon,
3404		struct rtllib_device *ieee, u16 asRsn)
3405{
3406	struct sk_buff *skb;
3407	struct rtllib_disauth *disauth;
3408	int len = sizeof(struct rtllib_disauth) + ieee->tx_headroom;
3409
3410	skb = dev_alloc_skb(len);
3411	if (!skb)
3412		return NULL;
3413
3414	skb_reserve(skb, ieee->tx_headroom);
3415
3416	disauth = (struct rtllib_disauth *) skb_put(skb,
3417		  sizeof(struct rtllib_disauth));
3418	disauth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DEAUTH);
3419	disauth->header.duration_id = 0;
3420
3421	ether_addr_copy(disauth->header.addr1, beacon->bssid);
3422	ether_addr_copy(disauth->header.addr2, ieee->dev->dev_addr);
3423	ether_addr_copy(disauth->header.addr3, beacon->bssid);
3424
3425	disauth->reason = cpu_to_le16(asRsn);
3426	return skb;
3427}
3428
3429inline struct sk_buff *rtllib_disassociate_skb(struct rtllib_network *beacon,
3430		struct rtllib_device *ieee, u16 asRsn)
3431{
3432	struct sk_buff *skb;
3433	struct rtllib_disassoc *disass;
3434	int len = sizeof(struct rtllib_disassoc) + ieee->tx_headroom;
3435
3436	skb = dev_alloc_skb(len);
3437
3438	if (!skb)
3439		return NULL;
3440
3441	skb_reserve(skb, ieee->tx_headroom);
3442
3443	disass = (struct rtllib_disassoc *) skb_put(skb,
3444					 sizeof(struct rtllib_disassoc));
3445	disass->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DISASSOC);
3446	disass->header.duration_id = 0;
3447
3448	ether_addr_copy(disass->header.addr1, beacon->bssid);
3449	ether_addr_copy(disass->header.addr2, ieee->dev->dev_addr);
3450	ether_addr_copy(disass->header.addr3, beacon->bssid);
3451
3452	disass->reason = cpu_to_le16(asRsn);
3453	return skb;
3454}
3455
3456void SendDisassociation(struct rtllib_device *ieee, bool deauth, u16 asRsn)
3457{
3458	struct rtllib_network *beacon = &ieee->current_network;
3459	struct sk_buff *skb;
3460
3461	if (deauth)
3462		skb = rtllib_disauth_skb(beacon, ieee, asRsn);
3463	else
3464		skb = rtllib_disassociate_skb(beacon, ieee, asRsn);
3465
3466	if (skb)
3467		softmac_mgmt_xmit(skb, ieee);
3468}
3469
3470u8 rtllib_ap_sec_type(struct rtllib_device *ieee)
3471{
3472	static u8 ccmp_ie[4] = {0x00, 0x50, 0xf2, 0x04};
3473	static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
3474	int wpa_ie_len = ieee->wpa_ie_len;
3475	struct lib80211_crypt_data *crypt;
3476	int encrypt;
3477
3478	crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
3479	encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY)
3480		  || (ieee->host_encrypt && crypt && crypt->ops &&
3481		  (strcmp(crypt->ops->name, "R-WEP") == 0));
3482
3483	/* simply judge  */
3484	if (encrypt && (wpa_ie_len == 0)) {
3485		return SEC_ALG_WEP;
3486	} else if ((wpa_ie_len != 0)) {
3487		if (((ieee->wpa_ie[0] == 0xdd) &&
3488		    (!memcmp(&(ieee->wpa_ie[14]), ccmp_ie, 4))) ||
3489		    ((ieee->wpa_ie[0] == 0x30) &&
3490		    (!memcmp(&ieee->wpa_ie[10], ccmp_rsn_ie, 4))))
3491			return SEC_ALG_CCMP;
3492		else
3493			return SEC_ALG_TKIP;
3494	} else {
3495		return SEC_ALG_NONE;
3496	}
3497}
3498
3499int rtllib_wpa_supplicant_ioctl(struct rtllib_device *ieee, struct iw_point *p,
3500				u8 is_mesh)
3501{
3502	struct ieee_param *param;
3503	int ret = 0;
3504
3505	down(&ieee->wx_sem);
3506
3507	if (p->length < sizeof(struct ieee_param) || !p->pointer) {
3508		ret = -EINVAL;
3509		goto out;
3510	}
3511
3512	param = memdup_user(p->pointer, p->length);
3513	if (IS_ERR(param)) {
3514		ret = PTR_ERR(param);
3515		goto out;
3516	}
3517
3518	switch (param->cmd) {
3519	case IEEE_CMD_SET_WPA_PARAM:
3520		ret = rtllib_wpa_set_param(ieee, param->u.wpa_param.name,
3521					param->u.wpa_param.value);
3522		break;
3523
3524	case IEEE_CMD_SET_WPA_IE:
3525		ret = rtllib_wpa_set_wpa_ie(ieee, param, p->length);
3526		break;
3527
3528	case IEEE_CMD_SET_ENCRYPTION:
3529		ret = rtllib_wpa_set_encryption(ieee, param, p->length, 0);
3530		break;
3531
3532	case IEEE_CMD_MLME:
3533		ret = rtllib_wpa_mlme(ieee, param->u.mlme.command,
3534				   param->u.mlme.reason_code);
3535		break;
3536
3537	default:
3538		netdev_info(ieee->dev, "Unknown WPA supplicant request: %d\n",
3539			    param->cmd);
3540		ret = -EOPNOTSUPP;
3541		break;
3542	}
3543
3544	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3545		ret = -EFAULT;
3546
3547	kfree(param);
3548out:
3549	up(&ieee->wx_sem);
3550
3551	return ret;
3552}
3553EXPORT_SYMBOL(rtllib_wpa_supplicant_ioctl);
3554
3555static void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib)
3556{
3557	u8	OpMode;
3558	u8	i;
3559	bool	bFilterOutNonAssociatedBSSID = false;
3560
3561	rtllib->state = RTLLIB_NOLINK;
3562
3563	for (i = 0; i < 6; i++)
3564		rtllib->current_network.bssid[i] = 0x55;
3565
3566	rtllib->OpMode = RT_OP_MODE_NO_LINK;
3567	rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_BSSID,
3568				rtllib->current_network.bssid);
3569	OpMode = RT_OP_MODE_NO_LINK;
3570	rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_MEDIA_STATUS, &OpMode);
3571	rtllib_stop_send_beacons(rtllib);
3572
3573	bFilterOutNonAssociatedBSSID = false;
3574	rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_CECHK_BSSID,
3575				(u8 *)(&bFilterOutNonAssociatedBSSID));
3576	notify_wx_assoc_event(rtllib);
3577
3578}
3579
3580static void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib,
3581					   u8 *asSta, u8 asRsn)
3582{
3583	u8 i;
3584	u8	OpMode;
3585
3586	RemovePeerTS(rtllib, asSta);
3587
3588	if (memcmp(rtllib->current_network.bssid, asSta, 6) == 0) {
3589		rtllib->state = RTLLIB_NOLINK;
3590
3591		for (i = 0; i < 6; i++)
3592			rtllib->current_network.bssid[i] = 0x22;
3593		OpMode = RT_OP_MODE_NO_LINK;
3594		rtllib->OpMode = RT_OP_MODE_NO_LINK;
3595		rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_MEDIA_STATUS,
3596					(u8 *)(&OpMode));
3597		rtllib_disassociate(rtllib);
3598
3599		rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_BSSID,
3600					rtllib->current_network.bssid);
3601
3602	}
3603
3604}
3605
3606static void
3607rtllib_MgntDisconnectAP(
3608	struct rtllib_device *rtllib,
3609	u8 asRsn
3610)
3611{
3612	bool bFilterOutNonAssociatedBSSID = false;
3613
3614	bFilterOutNonAssociatedBSSID = false;
3615	rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_CECHK_BSSID,
3616				(u8 *)(&bFilterOutNonAssociatedBSSID));
3617	rtllib_MlmeDisassociateRequest(rtllib, rtllib->current_network.bssid,
3618				       asRsn);
3619
3620	rtllib->state = RTLLIB_NOLINK;
3621}
3622
3623bool rtllib_MgntDisconnect(struct rtllib_device *rtllib, u8 asRsn)
3624{
3625	if (rtllib->ps != RTLLIB_PS_DISABLED)
3626		rtllib->sta_wake_up(rtllib->dev);
3627
3628	if (rtllib->state == RTLLIB_LINKED) {
3629		if (rtllib->iw_mode == IW_MODE_ADHOC)
3630			rtllib_MgntDisconnectIBSS(rtllib);
3631		if (rtllib->iw_mode == IW_MODE_INFRA)
3632			rtllib_MgntDisconnectAP(rtllib, asRsn);
3633
3634	}
3635
3636	return true;
3637}
3638EXPORT_SYMBOL(rtllib_MgntDisconnect);
3639
3640void notify_wx_assoc_event(struct rtllib_device *ieee)
3641{
3642	union iwreq_data wrqu;
3643
3644	if (ieee->cannot_notify)
3645		return;
3646
3647	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3648	if (ieee->state == RTLLIB_LINKED)
3649		memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid,
3650		       ETH_ALEN);
3651	else {
3652
3653		netdev_info(ieee->dev, "%s(): Tell user space disconnected\n",
3654			    __func__);
3655		eth_zero_addr(wrqu.ap_addr.sa_data);
3656	}
3657	wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3658}
3659EXPORT_SYMBOL(notify_wx_assoc_event);
3660