Merge tag 'safesetid-5.13' of git://github.com/micah-morton/linux
[linux-2.6-microblaze.git] / drivers / staging / rtl8192u / ieee80211 / ieee80211_softmac.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* IEEE 802.11 SoftMAC layer
3  * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
4  *
5  * Mostly extracted from the rtl8180-sa2400 driver for the
6  * in-kernel generic ieee802.11 stack.
7  *
8  * Few lines might be stolen from other part of the ieee80211
9  * stack. Copyright who own it's copyright
10  *
11  * WPA code stolen from the ipw2200 driver.
12  * Copyright who own it's copyright.
13  */
14 #include "ieee80211.h"
15
16 #include <linux/random.h>
17 #include <linux/delay.h>
18 #include <linux/slab.h>
19 #include <linux/uaccess.h>
20 #include <linux/etherdevice.h>
21
22 #include "dot11d.h"
23
24 short ieee80211_is_54g(const struct ieee80211_network *net)
25 {
26         return (net->rates_ex_len > 0) || (net->rates_len > 4);
27 }
28 EXPORT_SYMBOL(ieee80211_is_54g);
29
30 short ieee80211_is_shortslot(const struct ieee80211_network *net)
31 {
32         return net->capability & WLAN_CAPABILITY_SHORT_SLOT;
33 }
34 EXPORT_SYMBOL(ieee80211_is_shortslot);
35
36 /* returns the total length needed for pleacing the RATE MFIE
37  * tag and the EXTENDED RATE MFIE tag if needed.
38  * It encludes two bytes per tag for the tag itself and its len
39  */
40 static unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
41 {
42         unsigned int rate_len = 0;
43
44         if (ieee->modulation & IEEE80211_CCK_MODULATION)
45                 rate_len = IEEE80211_CCK_RATE_LEN + 2;
46
47         if (ieee->modulation & IEEE80211_OFDM_MODULATION)
48                 rate_len += IEEE80211_OFDM_RATE_LEN + 2;
49
50         return rate_len;
51 }
52
53 /* pleace the MFIE rate, tag to the memory (double) poined.
54  * Then it updates the pointer so that
55  * it points after the new MFIE tag added.
56  */
57 static void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
58 {
59         u8 *tag = *tag_p;
60
61         if (ieee->modulation & IEEE80211_CCK_MODULATION) {
62                 *tag++ = MFIE_TYPE_RATES;
63                 *tag++ = 4;
64                 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
65                 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
66                 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
67                 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
68         }
69
70         /* We may add an option for custom rates that specific HW might support */
71         *tag_p = tag;
72 }
73
74 static void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
75 {
76         u8 *tag = *tag_p;
77
78         if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
79                 *tag++ = MFIE_TYPE_RATES_EX;
80                 *tag++ = 8;
81                 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
82                 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
83                 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
84                 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
85                 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
86                 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
87                 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
88                 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
89         }
90
91         /* We may add an option for custom rates that specific HW might support */
92         *tag_p = tag;
93 }
94
95 static void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p)
96 {
97         u8 *tag = *tag_p;
98
99         *tag++ = MFIE_TYPE_GENERIC; /* 0 */
100         *tag++ = 7;
101         *tag++ = 0x00;
102         *tag++ = 0x50;
103         *tag++ = 0xf2;
104         *tag++ = 0x02;  /* 5 */
105         *tag++ = 0x00;
106         *tag++ = 0x01;
107 #ifdef SUPPORT_USPD
108         if (ieee->current_network.wmm_info & 0x80)
109                 *tag++ = 0x0f | MAX_SP_Len;
110         else
111                 *tag++ = MAX_SP_Len;
112 #else
113         *tag++ = MAX_SP_Len;
114 #endif
115         *tag_p = tag;
116 }
117
118 #ifdef THOMAS_TURBO
119 static void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p)
120 {
121         u8 *tag = *tag_p;
122
123         *tag++ = MFIE_TYPE_GENERIC; /* 0 */
124         *tag++ = 7;
125         *tag++ = 0x00;
126         *tag++ = 0xe0;
127         *tag++ = 0x4c;
128         *tag++ = 0x01;  /* 5 */
129         *tag++ = 0x02;
130         *tag++ = 0x11;
131         *tag++ = 0x00;
132
133         *tag_p = tag;
134         netdev_alert(ieee->dev, "This is enable turbo mode IE process\n");
135 }
136 #endif
137
138 static void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
139 {
140         int nh;
141
142         nh = (ieee->mgmt_queue_head + 1) % MGMT_QUEUE_NUM;
143
144 /*
145  * if the queue is full but we have newer frames then
146  * just overwrites the oldest.
147  *
148  * if (nh == ieee->mgmt_queue_tail)
149  *              return -1;
150  */
151         ieee->mgmt_queue_head = nh;
152         ieee->mgmt_queue_ring[nh] = skb;
153
154         //return 0;
155 }
156
157 static struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
158 {
159         struct sk_buff *ret;
160
161         if (ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
162                 return NULL;
163
164         ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
165
166         ieee->mgmt_queue_tail =
167                 (ieee->mgmt_queue_tail + 1) % MGMT_QUEUE_NUM;
168
169         return ret;
170 }
171
172 static void init_mgmt_queue(struct ieee80211_device *ieee)
173 {
174         ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
175 }
176
177 static u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
178 {
179         PRT_HIGH_THROUGHPUT      pHTInfo = ieee->pHTInfo;
180         u8 rate;
181
182         /* 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M. */
183         if (pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
184                 rate = 0x0c;
185         else
186                 rate = ieee->basic_rate & 0x7f;
187
188         if (rate == 0) {
189                 /* 2005.01.26, by rcnjko. */
190                 if (ieee->mode == IEEE_A ||
191                     ieee->mode == IEEE_N_5G ||
192                     (ieee->mode == IEEE_N_24G && !pHTInfo->bCurSuppCCK))
193                         rate = 0x0c;
194                 else
195                         rate = 0x02;
196         }
197
198         /*
199         // Data rate of ProbeReq is already decided. Annie, 2005-03-31
200         if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) ) {
201         if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
202         rate = 0x0c;
203         else
204         rate = 0x02;
205         }
206          */
207         return rate;
208 }
209
210 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
211
212 inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
213 {
214         unsigned long flags;
215         short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
216         struct rtl_80211_hdr_3addr  *header =
217                 (struct rtl_80211_hdr_3addr  *)skb->data;
218
219         struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
220
221         spin_lock_irqsave(&ieee->lock, flags);
222
223         /* called with 2nd param 0, no mgmt lock required */
224         ieee80211_sta_wakeup(ieee, 0);
225
226         tcb_desc->queue_index = MGNT_QUEUE;
227         tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
228         tcb_desc->RATRIndex = 7;
229         tcb_desc->bTxDisableRateFallBack = 1;
230         tcb_desc->bTxUseDriverAssingedRate = 1;
231
232         if (single) {
233                 if (ieee->queue_stop) {
234                         enqueue_mgmt(ieee, skb);
235                 } else {
236                         header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
237
238                         if (ieee->seq_ctrl[0] == 0xFFF)
239                                 ieee->seq_ctrl[0] = 0;
240                         else
241                                 ieee->seq_ctrl[0]++;
242
243                         /* avoid watchdog triggers */
244                         netif_trans_update(ieee->dev);
245                         ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
246                         //dev_kfree_skb_any(skb);//edit by thomas
247                 }
248
249                 spin_unlock_irqrestore(&ieee->lock, flags);
250         } else {
251                 spin_unlock_irqrestore(&ieee->lock, flags);
252                 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
253
254                 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
255
256                 if (ieee->seq_ctrl[0] == 0xFFF)
257                         ieee->seq_ctrl[0] = 0;
258                 else
259                         ieee->seq_ctrl[0]++;
260
261                 /* check whether the managed packet queued greater than 5 */
262                 if (!ieee->check_nic_enough_desc(ieee->dev, tcb_desc->queue_index) || \
263                     (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0) || \
264                     (ieee->queue_stop)) {
265                         /* insert the skb packet to the management queue */
266                         /* as for the completion function, it does not need
267                          * to check it any more.
268                          * */
269                         printk("%s():insert to waitqueue!\n", __func__);
270                         skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
271                 } else {
272                         ieee->softmac_hard_start_xmit(skb, ieee->dev);
273                         //dev_kfree_skb_any(skb);//edit by thomas
274                 }
275                 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
276         }
277 }
278
279 static inline void
280 softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
281 {
282         short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
283         struct rtl_80211_hdr_3addr  *header =
284                 (struct rtl_80211_hdr_3addr  *)skb->data;
285
286         if (single) {
287                 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
288
289                 if (ieee->seq_ctrl[0] == 0xFFF)
290                         ieee->seq_ctrl[0] = 0;
291                 else
292                         ieee->seq_ctrl[0]++;
293
294                 /* avoid watchdog triggers */
295                 netif_trans_update(ieee->dev);
296                 ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
297         } else {
298                 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
299
300                 if (ieee->seq_ctrl[0] == 0xFFF)
301                         ieee->seq_ctrl[0] = 0;
302                 else
303                         ieee->seq_ctrl[0]++;
304
305                 ieee->softmac_hard_start_xmit(skb, ieee->dev);
306         }
307         //dev_kfree_skb_any(skb);//edit by thomas
308 }
309
310 static inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
311 {
312         unsigned int len, rate_len;
313         u8 *tag;
314         struct sk_buff *skb;
315         struct ieee80211_probe_request *req;
316
317         len = ieee->current_network.ssid_len;
318
319         rate_len = ieee80211_MFIE_rate_len(ieee);
320
321         skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
322                             2 + len + rate_len + ieee->tx_headroom);
323         if (!skb)
324                 return NULL;
325
326         skb_reserve(skb, ieee->tx_headroom);
327
328         req = skb_put(skb, sizeof(struct ieee80211_probe_request));
329         req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
330         req->header.duration_id = 0; /* FIXME: is this OK? */
331
332         eth_broadcast_addr(req->header.addr1);
333         memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
334         eth_broadcast_addr(req->header.addr3);
335
336         tag = skb_put(skb, len + 2 + rate_len);
337
338         *tag++ = MFIE_TYPE_SSID;
339         *tag++ = len;
340         memcpy(tag, ieee->current_network.ssid, len);
341         tag += len;
342
343         ieee80211_MFIE_Brate(ieee, &tag);
344         ieee80211_MFIE_Grate(ieee, &tag);
345         return skb;
346 }
347
348 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
349
350 static void ieee80211_send_beacon(struct ieee80211_device *ieee)
351 {
352         struct sk_buff *skb;
353
354         if (!ieee->ieee_up)
355                 return;
356         //unsigned long flags;
357         skb = ieee80211_get_beacon_(ieee);
358
359         if (skb) {
360                 softmac_mgmt_xmit(skb, ieee);
361                 ieee->softmac_stats.tx_beacons++;
362                 //dev_kfree_skb_any(skb);//edit by thomas
363         }
364 //      ieee->beacon_timer.expires = jiffies +
365 //              (MSECS( ieee->current_network.beacon_interval -5));
366
367         //spin_lock_irqsave(&ieee->beacon_lock,flags);
368         if (ieee->beacon_txing && ieee->ieee_up) {
369 //              if(!timer_pending(&ieee->beacon_timer))
370 //                      add_timer(&ieee->beacon_timer);
371                 mod_timer(&ieee->beacon_timer,
372                           jiffies + msecs_to_jiffies(ieee->current_network.beacon_interval - 5));
373         }
374         //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
375 }
376
377 static void ieee80211_send_beacon_cb(struct timer_list *t)
378 {
379         struct ieee80211_device *ieee =
380                 from_timer(ieee, t, beacon_timer);
381         unsigned long flags;
382
383         spin_lock_irqsave(&ieee->beacon_lock, flags);
384         ieee80211_send_beacon(ieee);
385         spin_unlock_irqrestore(&ieee->beacon_lock, flags);
386 }
387
388 static void ieee80211_send_probe(struct ieee80211_device *ieee)
389 {
390         struct sk_buff *skb;
391
392         skb = ieee80211_probe_req(ieee);
393         if (skb) {
394                 softmac_mgmt_xmit(skb, ieee);
395                 ieee->softmac_stats.tx_probe_rq++;
396                 //dev_kfree_skb_any(skb);//edit by thomas
397         }
398 }
399
400 static void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
401 {
402         if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)) {
403                 ieee80211_send_probe(ieee);
404                 ieee80211_send_probe(ieee);
405         }
406 }
407
408 /* this performs syncro scan blocking the caller until all channels
409  * in the allowed channel map has been checked.
410  */
411 void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
412 {
413         short ch = 0;
414         u8 channel_map[MAX_CHANNEL_NUMBER + 1];
415
416         memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER + 1);
417         mutex_lock(&ieee->scan_mutex);
418
419         while (1) {
420                 do {
421                         ch++;
422                         if (ch > MAX_CHANNEL_NUMBER)
423                                 goto out; /* scan completed */
424                 } while (!channel_map[ch]);
425
426                 /* this function can be called in two situations
427                  * 1- We have switched to ad-hoc mode and we are
428                  *    performing a complete syncro scan before conclude
429                  *    there are no interesting cell and to create a
430                  *    new one. In this case the link state is
431                  *    IEEE80211_NOLINK until we found an interesting cell.
432                  *    If so the ieee8021_new_net, called by the RX path
433                  *    will set the state to IEEE80211_LINKED, so we stop
434                  *    scanning
435                  * 2- We are linked and the root uses run iwlist scan.
436                  *    So we switch to IEEE80211_LINKED_SCANNING to remember
437                  *    that we are still logically linked (not interested in
438                  *    new network events, despite for updating the net list,
439                  *    but we are temporarly 'unlinked' as the driver shall
440                  *    not filter RX frames and the channel is changing.
441                  * So the only situation in witch are interested is to check
442                  * if the state become LINKED because of the #1 situation
443                  */
444
445                 if (ieee->state == IEEE80211_LINKED)
446                         goto out;
447                 ieee->set_chan(ieee->dev, ch);
448                 if (channel_map[ch] == 1)
449                         ieee80211_send_probe_requests(ieee);
450
451                 /* this prevent excessive time wait when we
452                  * need to wait for a syncro scan to end..
453                  */
454                 if (ieee->state >= IEEE80211_LINKED && ieee->sync_scan_hurryup)
455                         goto out;
456
457                 msleep_interruptible(IEEE80211_SOFTMAC_SCAN_TIME);
458         }
459 out:
460         if (ieee->state < IEEE80211_LINKED) {
461                 ieee->actscanning = false;
462                 mutex_unlock(&ieee->scan_mutex);
463         } else {
464                 ieee->sync_scan_hurryup = 0;
465                 if (IS_DOT11D_ENABLE(ieee))
466                         dot11d_scan_complete(ieee);
467                 mutex_unlock(&ieee->scan_mutex);
468         }
469 }
470 EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
471
472 static void ieee80211_softmac_scan_wq(struct work_struct *work)
473 {
474         struct delayed_work *dwork = to_delayed_work(work);
475         struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
476         static short watchdog;
477         u8 channel_map[MAX_CHANNEL_NUMBER + 1];
478
479         memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER + 1);
480         if (!ieee->ieee_up)
481                 return;
482         mutex_lock(&ieee->scan_mutex);
483         do {
484                 ieee->current_network.channel =
485                         (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
486                 if (watchdog++ > MAX_CHANNEL_NUMBER) {
487                 //if current channel is not in channel map, set to default channel.
488                         if (!channel_map[ieee->current_network.channel]) {
489                                 ieee->current_network.channel = 6;
490                                 goto out; /* no good chans */
491                         }
492                 }
493         } while (!channel_map[ieee->current_network.channel]);
494         if (ieee->scanning == 0)
495                 goto out;
496         ieee->set_chan(ieee->dev, ieee->current_network.channel);
497         if (channel_map[ieee->current_network.channel] == 1)
498                 ieee80211_send_probe_requests(ieee);
499
500         schedule_delayed_work(&ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
501
502         mutex_unlock(&ieee->scan_mutex);
503         return;
504 out:
505         if (IS_DOT11D_ENABLE(ieee))
506                 dot11d_scan_complete(ieee);
507         ieee->actscanning = false;
508         watchdog = 0;
509         ieee->scanning = 0;
510         mutex_unlock(&ieee->scan_mutex);
511 }
512
513 static void ieee80211_beacons_start(struct ieee80211_device *ieee)
514 {
515         unsigned long flags;
516         spin_lock_irqsave(&ieee->beacon_lock, flags);
517
518         ieee->beacon_txing = 1;
519         ieee80211_send_beacon(ieee);
520
521         spin_unlock_irqrestore(&ieee->beacon_lock, flags);
522 }
523
524 static void ieee80211_beacons_stop(struct ieee80211_device *ieee)
525 {
526         unsigned long flags;
527
528         spin_lock_irqsave(&ieee->beacon_lock, flags);
529
530         ieee->beacon_txing = 0;
531         del_timer_sync(&ieee->beacon_timer);
532
533         spin_unlock_irqrestore(&ieee->beacon_lock, flags);
534 }
535
536 void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
537 {
538         if (ieee->stop_send_beacons)
539                 ieee->stop_send_beacons(ieee->dev);
540         if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
541                 ieee80211_beacons_stop(ieee);
542 }
543 EXPORT_SYMBOL(ieee80211_stop_send_beacons);
544
545 void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
546 {
547         if (ieee->start_send_beacons)
548                 ieee->start_send_beacons(ieee->dev, ieee->basic_rate);
549         if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
550                 ieee80211_beacons_start(ieee);
551 }
552 EXPORT_SYMBOL(ieee80211_start_send_beacons);
553
554 static void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
555 {
556 //      unsigned long flags;
557
558         //ieee->sync_scan_hurryup = 1;
559
560         mutex_lock(&ieee->scan_mutex);
561 //      spin_lock_irqsave(&ieee->lock, flags);
562
563         if (ieee->scanning == 1) {
564                 ieee->scanning = 0;
565
566                 cancel_delayed_work(&ieee->softmac_scan_wq);
567         }
568
569 //      spin_unlock_irqrestore(&ieee->lock, flags);
570         mutex_unlock(&ieee->scan_mutex);
571 }
572
573 void ieee80211_stop_scan(struct ieee80211_device *ieee)
574 {
575         if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
576                 ieee80211_softmac_stop_scan(ieee);
577         else
578                 ieee->stop_scan(ieee->dev);
579 }
580 EXPORT_SYMBOL(ieee80211_stop_scan);
581
582 /* called with ieee->lock held */
583 static void ieee80211_start_scan(struct ieee80211_device *ieee)
584 {
585         if (IS_DOT11D_ENABLE(ieee)) {
586                 if (IS_COUNTRY_IE_VALID(ieee))
587                         RESET_CIE_WATCHDOG(ieee);
588         }
589         if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
590                 if (ieee->scanning == 0) {
591                         ieee->scanning = 1;
592                         schedule_delayed_work(&ieee->softmac_scan_wq, 0);
593                 }
594         } else {
595                 ieee->start_scan(ieee->dev);
596         }
597 }
598
599 /* called with wx_mutex held */
600 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
601 {
602         if (IS_DOT11D_ENABLE(ieee)) {
603                 if (IS_COUNTRY_IE_VALID(ieee))
604                         RESET_CIE_WATCHDOG(ieee);
605         }
606         ieee->sync_scan_hurryup = 0;
607         if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
608                 ieee80211_softmac_scan_syncro(ieee);
609         else
610                 ieee->scan_syncro(ieee->dev);
611 }
612 EXPORT_SYMBOL(ieee80211_start_scan_syncro);
613
614 static inline struct sk_buff *
615 ieee80211_authentication_req(struct ieee80211_network *beacon,
616                              struct ieee80211_device *ieee, int challengelen)
617 {
618         struct sk_buff *skb;
619         struct ieee80211_authentication *auth;
620         int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
621
622         skb = dev_alloc_skb(len);
623         if (!skb)
624                 return NULL;
625
626         skb_reserve(skb, ieee->tx_headroom);
627         auth = skb_put(skb, sizeof(struct ieee80211_authentication));
628
629         if (challengelen)
630                 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH
631                                                      | IEEE80211_FCTL_WEP);
632         else
633                 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
634
635         auth->header.duration_id = cpu_to_le16(0x013a);
636
637         memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
638         memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
639         memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
640
641         //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
642         if (ieee->auth_mode == 0)
643                 auth->algorithm = WLAN_AUTH_OPEN;
644         else if (ieee->auth_mode == 1)
645                 auth->algorithm = cpu_to_le16(WLAN_AUTH_SHARED_KEY);
646         else if (ieee->auth_mode == 2)
647                 auth->algorithm = WLAN_AUTH_OPEN; /* 0x80; */
648         printk("=================>%s():auth->algorithm is %d\n", __func__, auth->algorithm);
649         auth->transaction = cpu_to_le16(ieee->associate_seq);
650         ieee->associate_seq++;
651
652         auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
653
654         return skb;
655 }
656
657 static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
658 {
659         u8 *tag;
660         int beacon_size;
661         struct ieee80211_probe_response *beacon_buf;
662         struct sk_buff *skb = NULL;
663         int encrypt;
664         int atim_len, erp_len;
665         struct ieee80211_crypt_data *crypt;
666
667         char *ssid = ieee->current_network.ssid;
668         int ssid_len = ieee->current_network.ssid_len;
669         int rate_len = ieee->current_network.rates_len + 2;
670         int rate_ex_len = ieee->current_network.rates_ex_len;
671         int wpa_ie_len = ieee->wpa_ie_len;
672         u8 erpinfo_content = 0;
673
674         u8 *tmp_ht_cap_buf;
675         u8 tmp_ht_cap_len = 0;
676         u8 *tmp_ht_info_buf;
677         u8 tmp_ht_info_len = 0;
678         PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
679         u8 *tmp_generic_ie_buf = NULL;
680         u8 tmp_generic_ie_len = 0;
681
682         if (rate_ex_len > 0)
683                 rate_ex_len += 2;
684
685         if (ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
686                 atim_len = 4;
687         else
688                 atim_len = 0;
689
690         if (ieee80211_is_54g(&ieee->current_network))
691                 erp_len = 3;
692         else
693                 erp_len = 0;
694
695         crypt = ieee->crypt[ieee->tx_keyidx];
696
697         encrypt = ieee->host_encrypt && crypt && crypt->ops &&
698                 ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
699         /* HT ralated element */
700         tmp_ht_cap_buf = (u8 *)&ieee->pHTInfo->SelfHTCap;
701         tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
702         tmp_ht_info_buf = (u8 *)&ieee->pHTInfo->SelfHTInfo;
703         tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
704         HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len, encrypt);
705         HTConstructInfoElement(ieee, tmp_ht_info_buf, &tmp_ht_info_len, encrypt);
706
707         if (pHTInfo->bRegRT2RTAggregation) {
708                 tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
709                 tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
710                 HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
711         }
712 //      printk("===============>tmp_ht_cap_len is %d,tmp_ht_info_len is %d, tmp_generic_ie_len is %d\n",tmp_ht_cap_len,tmp_ht_info_len,tmp_generic_ie_len);
713         beacon_size = sizeof(struct ieee80211_probe_response) + 2
714                 + ssid_len
715                 + 3 //channel
716                 + rate_len
717                 + rate_ex_len
718                 + atim_len
719                 + erp_len
720                 + wpa_ie_len
721         //      + tmp_ht_cap_len
722         //      + tmp_ht_info_len
723         //      + tmp_generic_ie_len
724 //              + wmm_len+2
725                 + ieee->tx_headroom;
726         skb = dev_alloc_skb(beacon_size);
727         if (!skb)
728                 return NULL;
729         skb_reserve(skb, ieee->tx_headroom);
730         beacon_buf = skb_put(skb, (beacon_size - ieee->tx_headroom));
731         memcpy(beacon_buf->header.addr1, dest, ETH_ALEN);
732         memcpy(beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
733         memcpy(beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
734
735         beacon_buf->header.duration_id = 0; /* FIXME */
736         beacon_buf->beacon_interval =
737                 cpu_to_le16(ieee->current_network.beacon_interval);
738         beacon_buf->capability =
739                 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
740         beacon_buf->capability |=
741                 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); /* add short preamble here */
742
743         if (ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
744                 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
745
746         if (encrypt)
747                 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
748
749         beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
750         beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
751         beacon_buf->info_element[0].len = ssid_len;
752
753         tag = (u8 *)beacon_buf->info_element[0].data;
754
755         memcpy(tag, ssid, ssid_len);
756
757         tag += ssid_len;
758
759         *(tag++) = MFIE_TYPE_RATES;
760         *(tag++) = rate_len - 2;
761         memcpy(tag, ieee->current_network.rates, rate_len - 2);
762         tag += rate_len - 2;
763
764         *(tag++) = MFIE_TYPE_DS_SET;
765         *(tag++) = 1;
766         *(tag++) = ieee->current_network.channel;
767
768         if (atim_len) {
769                 *(tag++) = MFIE_TYPE_IBSS_SET;
770                 *(tag++) = 2;
771
772                 put_unaligned_le16(ieee->current_network.atim_window,
773                                    tag);
774                 tag += 2;
775         }
776
777         if (erp_len) {
778                 *(tag++) = MFIE_TYPE_ERP;
779                 *(tag++) = 1;
780                 *(tag++) = erpinfo_content;
781         }
782         if (rate_ex_len) {
783                 *(tag++) = MFIE_TYPE_RATES_EX;
784                 *(tag++) = rate_ex_len - 2;
785                 memcpy(tag, ieee->current_network.rates_ex, rate_ex_len - 2);
786                 tag += rate_ex_len - 2;
787         }
788
789         if (wpa_ie_len) {
790                 if (ieee->iw_mode == IW_MODE_ADHOC) {
791                         //as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07
792                         memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
793                 }
794                 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
795                 tag += wpa_ie_len;
796         }
797
798         //skb->dev = ieee->dev;
799         return skb;
800 }
801
802 static struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee,
803                                             u8 *dest)
804 {
805         struct sk_buff *skb;
806         u8 *tag;
807
808         struct ieee80211_crypt_data *crypt;
809         struct ieee80211_assoc_response_frame *assoc;
810         short encrypt;
811
812         unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
813         int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
814
815         skb = dev_alloc_skb(len);
816
817         if (!skb)
818                 return NULL;
819
820         skb_reserve(skb, ieee->tx_headroom);
821
822         assoc = skb_put(skb, sizeof(struct ieee80211_assoc_response_frame));
823
824         assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
825         memcpy(assoc->header.addr1, dest, ETH_ALEN);
826         memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
827         memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
828         assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
829                 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
830
831         if (ieee->short_slot)
832                 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
833
834         if (ieee->host_encrypt)
835                 crypt = ieee->crypt[ieee->tx_keyidx];
836         else
837                 crypt = NULL;
838
839         encrypt = crypt && crypt->ops;
840
841         if (encrypt)
842                 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
843
844         assoc->status = 0;
845         assoc->aid = cpu_to_le16(ieee->assoc_id);
846         if (ieee->assoc_id == 0x2007)
847                 ieee->assoc_id = 0;
848         else
849                 ieee->assoc_id++;
850
851         tag = skb_put(skb, rate_len);
852
853         ieee80211_MFIE_Brate(ieee, &tag);
854         ieee80211_MFIE_Grate(ieee, &tag);
855
856         return skb;
857 }
858
859 static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee,
860                                            int status, u8 *dest)
861 {
862         struct sk_buff *skb;
863         struct ieee80211_authentication *auth;
864         int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication) + 1;
865
866         skb = dev_alloc_skb(len);
867
868         if (!skb)
869                 return NULL;
870
871         skb->len = sizeof(struct ieee80211_authentication);
872
873         auth = (struct ieee80211_authentication *)skb->data;
874
875         auth->status = cpu_to_le16(status);
876         auth->transaction = cpu_to_le16(2);
877         auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
878
879         memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
880         memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
881         memcpy(auth->header.addr1, dest, ETH_ALEN);
882         auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
883         return skb;
884 }
885
886 static struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee,
887                                            short pwr)
888 {
889         struct sk_buff *skb;
890         struct rtl_80211_hdr_3addr *hdr;
891
892         skb = dev_alloc_skb(sizeof(struct rtl_80211_hdr_3addr));
893
894         if (!skb)
895                 return NULL;
896
897         hdr = skb_put(skb, sizeof(struct rtl_80211_hdr_3addr));
898
899         memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
900         memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
901         memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
902
903         hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
904                                      IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
905                                      (pwr ? IEEE80211_FCTL_PM : 0));
906
907         return skb;
908 }
909
910 static void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest)
911 {
912         struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
913
914         if (buf)
915                 softmac_mgmt_xmit(buf, ieee);
916 }
917
918 static void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s,
919                                    u8 *dest)
920 {
921         struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
922
923         if (buf)
924                 softmac_mgmt_xmit(buf, ieee);
925 }
926
927 static void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
928 {
929         struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
930         if (buf)
931                 softmac_mgmt_xmit(buf, ieee);
932 }
933
934 static inline struct sk_buff *
935 ieee80211_association_req(struct ieee80211_network *beacon,
936                           struct ieee80211_device *ieee)
937 {
938         struct sk_buff *skb;
939         //unsigned long flags;
940
941         struct ieee80211_assoc_request_frame *hdr;
942         u8 *tag;//,*rsn_ie;
943         //short info_addr = 0;
944         //int i;
945         //u16 suite_count = 0;
946         //u8 suit_select = 0;
947         //unsigned int wpa_len = beacon->wpa_ie_len;
948         //for HT
949         u8 *ht_cap_buf = NULL;
950         u8 ht_cap_len = 0;
951         u8 *realtek_ie_buf = NULL;
952         u8 realtek_ie_len = 0;
953         int wpa_ie_len = ieee->wpa_ie_len;
954         unsigned int ckip_ie_len = 0;
955         unsigned int ccxrm_ie_len = 0;
956         unsigned int cxvernum_ie_len = 0;
957         struct ieee80211_crypt_data *crypt;
958         int encrypt;
959
960         unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
961         unsigned int wmm_info_len = beacon->qos_data.supported ? 9 : 0;
962 #ifdef THOMAS_TURBO
963         unsigned int turbo_info_len = beacon->Turbo_Enable ? 9 : 0;
964 #endif
965
966         int len = 0;
967
968         crypt = ieee->crypt[ieee->tx_keyidx];
969         encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
970
971         /* Include High Throuput capability && Realtek proprietary */
972         if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
973                 ht_cap_buf = (u8 *)&ieee->pHTInfo->SelfHTCap;
974                 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
975                 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
976                 if (ieee->pHTInfo->bCurrentRT2RTAggregation) {
977                         realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
978                         realtek_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
979                         HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
980                 }
981         }
982         if (ieee->qos_support)
983                 wmm_info_len = beacon->qos_data.supported ? 9 : 0;
984
985         if (beacon->bCkipSupported)
986                 ckip_ie_len = 30 + 2;
987
988         if (beacon->bCcxRmEnable)
989                 ccxrm_ie_len = 6 + 2;
990
991         if (beacon->BssCcxVerNumber >= 2)
992                 cxvernum_ie_len = 5 + 2;
993
994 #ifdef THOMAS_TURBO
995         len = sizeof(struct ieee80211_assoc_request_frame) + 2
996                 + beacon->ssid_len      /* essid tagged val */
997                 + rate_len      /* rates tagged val */
998                 + wpa_ie_len
999                 + wmm_info_len
1000                 + turbo_info_len
1001                 + ht_cap_len
1002                 + realtek_ie_len
1003                 + ckip_ie_len
1004                 + ccxrm_ie_len
1005                 + cxvernum_ie_len
1006                 + ieee->tx_headroom;
1007 #else
1008         len = sizeof(struct ieee80211_assoc_request_frame) + 2
1009                 + beacon->ssid_len      /* essid tagged val */
1010                 + rate_len      /* rates tagged val */
1011                 + wpa_ie_len
1012                 + wmm_info_len
1013                 + ht_cap_len
1014                 + realtek_ie_len
1015                 + ckip_ie_len
1016                 + ccxrm_ie_len
1017                 + cxvernum_ie_len
1018                 + ieee->tx_headroom;
1019 #endif
1020         skb = dev_alloc_skb(len);
1021
1022         if (!skb)
1023                 return NULL;
1024
1025         skb_reserve(skb, ieee->tx_headroom);
1026
1027         hdr = skb_put(skb, sizeof(struct ieee80211_assoc_request_frame) + 2);
1028
1029         hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
1030         hdr->header.duration_id = cpu_to_le16(37);
1031         memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1032         memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1033         memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1034
1035         memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
1036
1037         hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1038         if (beacon->capability & WLAN_CAPABILITY_PRIVACY)
1039                 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1040
1041         if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1042                 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
1043
1044         if (ieee->short_slot)
1045                 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1046         if (wmm_info_len) //QOS
1047                 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
1048
1049         hdr->listen_interval = cpu_to_le16(0xa);
1050
1051         hdr->info_element[0].id = MFIE_TYPE_SSID;
1052
1053         hdr->info_element[0].len = beacon->ssid_len;
1054         skb_put_data(skb, beacon->ssid, beacon->ssid_len);
1055
1056         tag = skb_put(skb, rate_len);
1057
1058         ieee80211_MFIE_Brate(ieee, &tag);
1059         ieee80211_MFIE_Grate(ieee, &tag);
1060         // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
1061         if (beacon->bCkipSupported) {
1062                 static u8       AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
1063                 u8      CcxAironetBuf[30];
1064                 struct octet_string     osCcxAironetIE;
1065
1066                 memset(CcxAironetBuf, 0, 30);
1067                 osCcxAironetIE.octet = CcxAironetBuf;
1068                 osCcxAironetIE.length = sizeof(CcxAironetBuf);
1069                 //
1070                 // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1071                 // We want to make the device type as "4500-client". 060926, by CCW.
1072                 //
1073                 memcpy(osCcxAironetIE.octet, AironetIeOui, sizeof(AironetIeOui));
1074
1075                 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1076                 // "The CKIP negotiation is started with the associate request from the client to the access point,
1077                 //  containing an Aironet element with both the MIC and KP bits set."
1078                 osCcxAironetIE.octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK | SUPPORT_CKIP_MIC);
1079                 tag = skb_put(skb, ckip_ie_len);
1080                 *tag++ = MFIE_TYPE_AIRONET;
1081                 *tag++ = osCcxAironetIE.length;
1082                 memcpy(tag, osCcxAironetIE.octet, osCcxAironetIE.length);
1083                 tag += osCcxAironetIE.length;
1084         }
1085
1086         if (beacon->bCcxRmEnable) {
1087                 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1088                 struct octet_string osCcxRmCap;
1089
1090                 osCcxRmCap.octet = CcxRmCapBuf;
1091                 osCcxRmCap.length = sizeof(CcxRmCapBuf);
1092                 tag = skb_put(skb, ccxrm_ie_len);
1093                 *tag++ = MFIE_TYPE_GENERIC;
1094                 *tag++ = osCcxRmCap.length;
1095                 memcpy(tag, osCcxRmCap.octet, osCcxRmCap.length);
1096                 tag += osCcxRmCap.length;
1097         }
1098
1099         if (beacon->BssCcxVerNumber >= 2) {
1100                 u8                      CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1101                 struct octet_string     osCcxVerNum;
1102                 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1103                 osCcxVerNum.octet = CcxVerNumBuf;
1104                 osCcxVerNum.length = sizeof(CcxVerNumBuf);
1105                 tag = skb_put(skb, cxvernum_ie_len);
1106                 *tag++ = MFIE_TYPE_GENERIC;
1107                 *tag++ = osCcxVerNum.length;
1108                 memcpy(tag, osCcxVerNum.octet, osCcxVerNum.length);
1109                 tag += osCcxVerNum.length;
1110         }
1111         //HT cap element
1112         if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1113                 if (ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC) {
1114                         tag = skb_put(skb, ht_cap_len);
1115                         *tag++ = MFIE_TYPE_HT_CAP;
1116                         *tag++ = ht_cap_len - 2;
1117                         memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1118                         tag += ht_cap_len - 2;
1119                 }
1120         }
1121
1122         //choose what wpa_supplicant gives to associate.
1123         if (wpa_ie_len)
1124                 skb_put_data(skb, ieee->wpa_ie, wpa_ie_len);
1125
1126         if (wmm_info_len) {
1127                 tag = skb_put(skb, wmm_info_len);
1128                 ieee80211_WMM_Info(ieee, &tag);
1129         }
1130 #ifdef THOMAS_TURBO
1131         if (turbo_info_len) {
1132                 tag = skb_put(skb, turbo_info_len);
1133                 ieee80211_TURBO_Info(ieee, &tag);
1134         }
1135 #endif
1136
1137         if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1138                 if (ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC) {
1139                         tag = skb_put(skb, ht_cap_len);
1140                         *tag++ = MFIE_TYPE_GENERIC;
1141                         *tag++ = ht_cap_len - 2;
1142                         memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1143                         tag += ht_cap_len - 2;
1144                 }
1145
1146                 if (ieee->pHTInfo->bCurrentRT2RTAggregation) {
1147                         tag = skb_put(skb, realtek_ie_len);
1148                         *tag++ = MFIE_TYPE_GENERIC;
1149                         *tag++ = realtek_ie_len - 2;
1150                         memcpy(tag, realtek_ie_buf, realtek_ie_len - 2);
1151                 }
1152         }
1153 //      printk("<=====%s(), %p, %p\n", __func__, ieee->dev, ieee->dev->dev_addr);
1154 //      IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
1155         return skb;
1156 }
1157
1158 void ieee80211_associate_abort(struct ieee80211_device *ieee)
1159 {
1160         unsigned long flags;
1161         spin_lock_irqsave(&ieee->lock, flags);
1162
1163         ieee->associate_seq++;
1164
1165         /* don't scan, and avoid to have the RX path possibily
1166          * try again to associate. Even do not react to AUTH or
1167          * ASSOC response. Just wait for the retry wq to be scheduled.
1168          * Here we will check if there are good nets to associate
1169          * with, so we retry or just get back to NO_LINK and scanning
1170          */
1171         if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING) {
1172                 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1173                 ieee->softmac_stats.no_auth_rs++;
1174         } else {
1175                 IEEE80211_DEBUG_MGMT("Association failed\n");
1176                 ieee->softmac_stats.no_ass_rs++;
1177         }
1178
1179         ieee->state = IEEE80211_ASSOCIATING_RETRY;
1180
1181         schedule_delayed_work(&ieee->associate_retry_wq, \
1182                               IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1183
1184         spin_unlock_irqrestore(&ieee->lock, flags);
1185 }
1186
1187 static void ieee80211_associate_abort_cb(struct timer_list *t)
1188 {
1189         struct ieee80211_device *dev = from_timer(dev, t, associate_timer);
1190
1191         ieee80211_associate_abort(dev);
1192 }
1193
1194 static void ieee80211_associate_step1(struct ieee80211_device *ieee)
1195 {
1196         struct ieee80211_network *beacon = &ieee->current_network;
1197         struct sk_buff *skb;
1198
1199         IEEE80211_DEBUG_MGMT("Stopping scan\n");
1200
1201         ieee->softmac_stats.tx_auth_rq++;
1202         skb = ieee80211_authentication_req(beacon, ieee, 0);
1203
1204         if (!skb) {
1205                 ieee80211_associate_abort(ieee);
1206         } else {
1207                 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING;
1208                 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1209                 softmac_mgmt_xmit(skb, ieee);
1210                 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1211                 if (!timer_pending(&ieee->associate_timer)) {
1212                         ieee->associate_timer.expires = jiffies + (HZ / 2);
1213                         add_timer(&ieee->associate_timer);
1214                 }
1215                 //dev_kfree_skb_any(skb);//edit by thomas
1216         }
1217 }
1218
1219 static void ieee80211_auth_challenge(struct ieee80211_device *ieee,
1220                                      u8 *challenge,
1221                                      int chlen)
1222 {
1223         u8 *c;
1224         struct sk_buff *skb;
1225         struct ieee80211_network *beacon = &ieee->current_network;
1226 //      int hlen = sizeof(struct ieee80211_authentication);
1227
1228         ieee->associate_seq++;
1229         ieee->softmac_stats.tx_auth_rq++;
1230
1231         skb = ieee80211_authentication_req(beacon, ieee, chlen + 2);
1232         if (!skb) {
1233                 ieee80211_associate_abort(ieee);
1234         } else {
1235                 c = skb_put(skb, chlen + 2);
1236                 *(c++) = MFIE_TYPE_CHALLENGE;
1237                 *(c++) = chlen;
1238                 memcpy(c, challenge, chlen);
1239
1240                 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1241
1242                 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct rtl_80211_hdr_3addr));
1243
1244                 softmac_mgmt_xmit(skb, ieee);
1245                 mod_timer(&ieee->associate_timer, jiffies + (HZ / 2));
1246                 //dev_kfree_skb_any(skb);//edit by thomas
1247         }
1248         kfree(challenge);
1249 }
1250
1251 static void ieee80211_associate_step2(struct ieee80211_device *ieee)
1252 {
1253         struct sk_buff *skb;
1254         struct ieee80211_network *beacon = &ieee->current_network;
1255
1256         del_timer_sync(&ieee->associate_timer);
1257
1258         IEEE80211_DEBUG_MGMT("Sending association request\n");
1259
1260         ieee->softmac_stats.tx_ass_rq++;
1261         skb = ieee80211_association_req(beacon, ieee);
1262         if (!skb) {
1263                 ieee80211_associate_abort(ieee);
1264         } else {
1265                 softmac_mgmt_xmit(skb, ieee);
1266                 mod_timer(&ieee->associate_timer, jiffies + (HZ / 2));
1267                 //dev_kfree_skb_any(skb);//edit by thomas
1268         }
1269 }
1270 static void ieee80211_associate_complete_wq(struct work_struct *work)
1271 {
1272         struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1273
1274         netdev_info(ieee->dev, "Associated successfully\n");
1275         if (ieee80211_is_54g(&ieee->current_network) &&
1276             (ieee->modulation & IEEE80211_OFDM_MODULATION)) {
1277                 ieee->rate = 108;
1278                 netdev_info(ieee->dev, "Using G rates:%d\n", ieee->rate);
1279         } else {
1280                 ieee->rate = 22;
1281                 netdev_info(ieee->dev, "Using B rates:%d\n", ieee->rate);
1282         }
1283         if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1284                 printk("Successfully associated, ht enabled\n");
1285                 HTOnAssocRsp(ieee);
1286         } else {
1287                 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1288                 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1289                 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1290         }
1291         ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval / 500);
1292         // To prevent the immediately calling watch_dog after association.
1293         if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 || ieee->LinkDetectInfo.NumRecvDataInPeriod == 0) {
1294                 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1295                 ieee->LinkDetectInfo.NumRecvDataInPeriod = 1;
1296         }
1297         ieee->link_change(ieee->dev);
1298         if (!ieee->is_silent_reset) {
1299                 printk("============>normal associate\n");
1300                 notify_wx_assoc_event(ieee);
1301         } else {
1302                 printk("==================>silent reset associate\n");
1303                 ieee->is_silent_reset = false;
1304         }
1305
1306         if (ieee->data_hard_resume)
1307                 ieee->data_hard_resume(ieee->dev);
1308         netif_carrier_on(ieee->dev);
1309 }
1310
1311 static void ieee80211_associate_complete(struct ieee80211_device *ieee)
1312 {
1313 //      int i;
1314 //      struct net_device* dev = ieee->dev;
1315         del_timer_sync(&ieee->associate_timer);
1316
1317         ieee->state = IEEE80211_LINKED;
1318         //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1319         schedule_work(&ieee->associate_complete_wq);
1320 }
1321
1322 static void ieee80211_associate_procedure_wq(struct work_struct *work)
1323 {
1324         struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1325         ieee->sync_scan_hurryup = 1;
1326         mutex_lock(&ieee->wx_mutex);
1327
1328         if (ieee->data_hard_stop)
1329                 ieee->data_hard_stop(ieee->dev);
1330
1331         ieee80211_stop_scan(ieee);
1332         printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
1333         //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1334         HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1335
1336         ieee->associate_seq = 1;
1337         ieee80211_associate_step1(ieee);
1338
1339         mutex_unlock(&ieee->wx_mutex);
1340 }
1341
1342 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1343 {
1344         u8 tmp_ssid[IW_ESSID_MAX_SIZE + 1];
1345         int tmp_ssid_len = 0;
1346
1347         short apset, ssidset, ssidbroad, apmatch, ssidmatch;
1348
1349         /* we are interested in new new only if we are not associated
1350          * and we are not associating / authenticating
1351          */
1352         if (ieee->state != IEEE80211_NOLINK)
1353                 return;
1354
1355         if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1356                 return;
1357
1358         if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1359                 return;
1360
1361         if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
1362                 /* if the user specified the AP MAC, we need also the essid
1363                  * This could be obtained by beacons or, if the network does not
1364                  * broadcast it, it can be put manually.
1365                  */
1366                 apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1367                 ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
1368                 ssidbroad =  !(net->ssid_len == 0 || net->ssid[0] == '\0');
1369                 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN) == 0);
1370                 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len) &&
1371                         (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1372
1373                 /* if the user set the AP check if match.
1374                  * if the network does not broadcast essid we check the user supplyed ANY essid
1375                  * if the network does broadcast and the user does not set essid it is OK
1376                  * if the network does broadcast and the user did set essid chech if essid match
1377                  */
1378                 if ((apset && apmatch &&
1379                      ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
1380                     /* if the ap is not set, check that the user set the bssid
1381                      * and the network does broadcast and that those two bssid matches
1382                      */
1383                     (!apset && ssidset && ssidbroad && ssidmatch)) {
1384                         /* if the essid is hidden replace it with the
1385                          * essid provided by the user.
1386                          */
1387                         if (!ssidbroad) {
1388                                 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1389                                 tmp_ssid_len = ieee->current_network.ssid_len;
1390                         }
1391                         memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1392
1393                         strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1394                         ieee->current_network.ssid_len = tmp_ssid_len;
1395                         netdev_info(ieee->dev,
1396                                     "Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n",
1397                                     ieee->current_network.ssid,
1398                                     ieee->current_network.channel,
1399                                     ieee->current_network.qos_data.supported,
1400                                     ieee->pHTInfo->bEnableHT,
1401                                     ieee->current_network.bssht.bdSupportHT);
1402
1403                         //ieee->pHTInfo->IOTAction = 0;
1404                         HTResetIOTSetting(ieee->pHTInfo);
1405                         if (ieee->iw_mode == IW_MODE_INFRA) {
1406                                 /* Join the network for the first time */
1407                                 ieee->AsocRetryCount = 0;
1408                                 //for HT by amy 080514
1409                                 if ((ieee->current_network.qos_data.supported == 1) &&
1410                                     // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1411                                     ieee->current_network.bssht.bdSupportHT) {
1412 /*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/
1413                                         //      ieee->pHTInfo->bCurrentHTSupport = true;
1414                                         HTResetSelfAndSavePeerSetting(ieee, &ieee->current_network);
1415                                 } else {
1416                                         ieee->pHTInfo->bCurrentHTSupport = false;
1417                                 }
1418
1419                                 ieee->state = IEEE80211_ASSOCIATING;
1420                                 schedule_work(&ieee->associate_procedure_wq);
1421                         } else {
1422                                 if (ieee80211_is_54g(&ieee->current_network) &&
1423                                     (ieee->modulation & IEEE80211_OFDM_MODULATION)) {
1424                                         ieee->rate = 108;
1425                                         ieee->SetWirelessMode(ieee->dev, IEEE_G);
1426                                         netdev_info(ieee->dev,
1427                                                     "Using G rates\n");
1428                                 } else {
1429                                         ieee->rate = 22;
1430                                         ieee->SetWirelessMode(ieee->dev, IEEE_B);
1431                                         netdev_info(ieee->dev,
1432                                                     "Using B rates\n");
1433                                 }
1434                                 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1435                                 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1436                                 ieee->state = IEEE80211_LINKED;
1437                         }
1438                 }
1439         }
1440 }
1441
1442 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1443 {
1444         unsigned long flags;
1445         struct ieee80211_network *target;
1446
1447         spin_lock_irqsave(&ieee->lock, flags);
1448
1449         list_for_each_entry(target, &ieee->network_list, list) {
1450                 /* if the state become different that NOLINK means
1451                  * we had found what we are searching for
1452                  */
1453
1454                 if (ieee->state != IEEE80211_NOLINK)
1455                         break;
1456
1457                 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1458                         ieee80211_softmac_new_net(ieee, target);
1459         }
1460
1461         spin_unlock_irqrestore(&ieee->lock, flags);
1462 }
1463
1464 static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
1465 {
1466         struct ieee80211_authentication *a;
1467         u8 *t;
1468         if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1469                 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1470                 return 0xcafe;
1471         }
1472         *challenge = NULL;
1473         a = (struct ieee80211_authentication *)skb->data;
1474         if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) {
1475                 t = skb->data + sizeof(struct ieee80211_authentication);
1476
1477                 if (*(t++) == MFIE_TYPE_CHALLENGE) {
1478                         *chlen = *(t++);
1479                         *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1480                         if (!*challenge)
1481                                 return -ENOMEM;
1482                 }
1483         }
1484
1485         return le16_to_cpu(a->status);
1486 }
1487
1488 static int auth_rq_parse(struct sk_buff *skb, u8 *dest)
1489 {
1490         struct ieee80211_authentication *a;
1491
1492         if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1493                 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n", skb->len);
1494                 return -1;
1495         }
1496         a = (struct ieee80211_authentication *)skb->data;
1497
1498         memcpy(dest, a->header.addr2, ETH_ALEN);
1499
1500         if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1501                 return  WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1502
1503         return WLAN_STATUS_SUCCESS;
1504 }
1505
1506 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1507 {
1508         u8 *tag;
1509         u8 *skbend;
1510         u8 *ssid = NULL;
1511         u8 ssidlen = 0;
1512
1513         struct rtl_80211_hdr_3addr   *header =
1514                 (struct rtl_80211_hdr_3addr   *)skb->data;
1515
1516         if (skb->len < sizeof(struct rtl_80211_hdr_3addr))
1517                 return -1; /* corrupted */
1518
1519         memcpy(src, header->addr2, ETH_ALEN);
1520
1521         skbend = (u8 *)skb->data + skb->len;
1522
1523         tag = skb->data + sizeof(struct rtl_80211_hdr_3addr);
1524
1525         while (tag + 1 < skbend) {
1526                 if (*tag == 0) {
1527                         ssid = tag + 2;
1528                         ssidlen = *(tag + 1);
1529                         break;
1530                 }
1531                 tag++; /* point to the len field */
1532                 tag = tag + *(tag); /* point to the last data byte of the tag */
1533                 tag++; /* point to the next tag */
1534         }
1535
1536         //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1537         if (ssidlen == 0)
1538                 return 1;
1539
1540         if (!ssid)
1541                 return 1; /* ssid not found in tagged param */
1542
1543         return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1544 }
1545
1546 static int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
1547 {
1548         struct ieee80211_assoc_request_frame *a;
1549
1550         if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1551                 sizeof(struct ieee80211_info_element))) {
1552                 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1553                 return -1;
1554         }
1555
1556         a = (struct ieee80211_assoc_request_frame *)skb->data;
1557
1558         memcpy(dest, a->header.addr2, ETH_ALEN);
1559
1560         return 0;
1561 }
1562
1563 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1564 {
1565         struct ieee80211_assoc_response_frame *response_head;
1566         u16 status_code;
1567
1568         if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) {
1569                 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1570                 return 0xcafe;
1571         }
1572
1573         response_head = (struct ieee80211_assoc_response_frame *)skb->data;
1574         *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1575
1576         status_code = le16_to_cpu(response_head->status);
1577         if ((status_code == WLAN_STATUS_ASSOC_DENIED_RATES ||
1578              status_code == WLAN_STATUS_CAPS_UNSUPPORTED) &&
1579             ((ieee->mode == IEEE_G) &&
1580              (ieee->current_network.mode == IEEE_N_24G) &&
1581              (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT - 1)))) {
1582                 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1583         } else {
1584                 ieee->AsocRetryCount = 0;
1585         }
1586
1587         return le16_to_cpu(response_head->status);
1588 }
1589
1590 static inline void
1591 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1592 {
1593         u8 dest[ETH_ALEN];
1594
1595         //IEEE80211DMESG("Rx probe");
1596         ieee->softmac_stats.rx_probe_rq++;
1597         //DMESG("Dest is "MACSTR, MAC2STR(dest));
1598         if (probe_rq_parse(ieee, skb, dest)) {
1599                 //IEEE80211DMESG("Was for me!");
1600                 ieee->softmac_stats.tx_probe_rs++;
1601                 ieee80211_resp_to_probe(ieee, dest);
1602         }
1603 }
1604
1605 static inline void
1606 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1607 {
1608         u8 dest[ETH_ALEN];
1609         int status;
1610         //IEEE80211DMESG("Rx probe");
1611         ieee->softmac_stats.rx_auth_rq++;
1612
1613         status = auth_rq_parse(skb, dest);
1614         if (status != -1)
1615                 ieee80211_resp_to_auth(ieee, status, dest);
1616         //DMESG("Dest is "MACSTR, MAC2STR(dest));
1617 }
1618
1619 static inline void
1620 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1621 {
1622         u8 dest[ETH_ALEN];
1623         //unsigned long flags;
1624
1625         ieee->softmac_stats.rx_ass_rq++;
1626         if (assoc_rq_parse(skb, dest) != -1)
1627                 ieee80211_resp_to_assoc_rq(ieee, dest);
1628
1629         netdev_info(ieee->dev, "New client associated: %pM\n", dest);
1630         //FIXME
1631 }
1632
1633 static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
1634                                              short pwr)
1635 {
1636         struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1637
1638         if (buf)
1639                 softmac_ps_mgmt_xmit(buf, ieee);
1640 }
1641 /* EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); */
1642
1643 static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
1644                                     u32 *time_l)
1645 {
1646         int timeout;
1647         u8 dtim;
1648         /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1649                 ieee->iw_mode != IW_MODE_INFRA ||
1650                 ieee->state != IEEE80211_LINKED)
1651
1652                 return 0;
1653         */
1654         dtim = ieee->current_network.dtim_data;
1655         if (!(dtim & IEEE80211_DTIM_VALID))
1656                 return 0;
1657         timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1658         ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1659
1660         if (dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST) & ieee->ps))
1661                 return 2;
1662
1663         if (!time_after(jiffies,
1664                         dev_trans_start(ieee->dev) + msecs_to_jiffies(timeout)))
1665                 return 0;
1666
1667         if (!time_after(jiffies,
1668                         ieee->last_rx_ps_time + msecs_to_jiffies(timeout)))
1669                 return 0;
1670
1671         if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) &&
1672             (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1673                 return 0;
1674
1675         if (time_l) {
1676                 *time_l = ieee->current_network.last_dtim_sta_time[0]
1677                         + (ieee->current_network.beacon_interval
1678                            * ieee->current_network.dtim_period) * 1000;
1679         }
1680
1681         if (time_h) {
1682                 *time_h = ieee->current_network.last_dtim_sta_time[1];
1683                 if (time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1684                         *time_h += 1;
1685         }
1686
1687         return 1;
1688 }
1689
1690 static inline void ieee80211_sta_ps(struct tasklet_struct *t)
1691 {
1692         struct ieee80211_device *ieee = from_tasklet(ieee, t, ps_task);
1693         u32 th, tl;
1694         short sleep;
1695
1696         unsigned long flags, flags2;
1697
1698         spin_lock_irqsave(&ieee->lock, flags);
1699
1700         if ((ieee->ps == IEEE80211_PS_DISABLED ||
1701              ieee->iw_mode != IW_MODE_INFRA ||
1702              ieee->state != IEEE80211_LINKED)) {
1703                 //      #warning CHECK_LOCK_HERE
1704                 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1705
1706                 ieee80211_sta_wakeup(ieee, 1);
1707
1708                 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1709         }
1710
1711         sleep = ieee80211_sta_ps_sleep(ieee, &th, &tl);
1712         /* 2 wake, 1 sleep, 0 do nothing */
1713         if (sleep == 0)
1714                 goto out;
1715
1716         if (sleep == 1) {
1717                 if (ieee->sta_sleep == 1) {
1718                         ieee->enter_sleep_state(ieee->dev, th, tl);
1719                 } else if (ieee->sta_sleep == 0) {
1720                 //      printk("send null 1\n");
1721                         spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1722
1723                         if (ieee->ps_is_queue_empty(ieee->dev)) {
1724                                 ieee->sta_sleep = 2;
1725
1726                                 ieee->ps_request_tx_ack(ieee->dev);
1727
1728                                 ieee80211_sta_ps_send_null_frame(ieee, 1);
1729
1730                                 ieee->ps_th = th;
1731                                 ieee->ps_tl = tl;
1732                         }
1733                         spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1734                 }
1735         } else if (sleep == 2) {
1736 //#warning CHECK_LOCK_HERE
1737                 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1738
1739                 ieee80211_sta_wakeup(ieee, 1);
1740
1741                 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1742         }
1743 out:
1744         spin_unlock_irqrestore(&ieee->lock, flags);
1745 }
1746
1747 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1748 {
1749         if (ieee->sta_sleep == 0) {
1750                 if (nl) {
1751                         printk("Warning: driver is probably failing to report TX ps error\n");
1752                         ieee->ps_request_tx_ack(ieee->dev);
1753                         ieee80211_sta_ps_send_null_frame(ieee, 0);
1754                 }
1755                 return;
1756         }
1757
1758         if (ieee->sta_sleep == 1)
1759                 ieee->sta_wake_up(ieee->dev);
1760
1761         ieee->sta_sleep = 0;
1762
1763         if (nl) {
1764                 ieee->ps_request_tx_ack(ieee->dev);
1765                 ieee80211_sta_ps_send_null_frame(ieee, 0);
1766         }
1767 }
1768
1769 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1770 {
1771         unsigned long flags, flags2;
1772
1773         spin_lock_irqsave(&ieee->lock, flags);
1774
1775         if (ieee->sta_sleep == 2) {
1776                 /* Null frame with PS bit set */
1777                 if (success) {
1778                         ieee->sta_sleep = 1;
1779                         ieee->enter_sleep_state(ieee->dev, ieee->ps_th, ieee->ps_tl);
1780                 }
1781                 /* if the card report not success we can't be sure the AP
1782                  * has not RXed so we can't assume the AP believe us awake
1783                  */
1784         } else {
1785                 /* 21112005 - tx again null without PS bit if lost */
1786                 if ((ieee->sta_sleep == 0) && !success) {
1787                         spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1788                         ieee80211_sta_ps_send_null_frame(ieee, 0);
1789                         spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1790                 }
1791         }
1792         spin_unlock_irqrestore(&ieee->lock, flags);
1793 }
1794 EXPORT_SYMBOL(ieee80211_ps_tx_ack);
1795
1796 static void ieee80211_process_action(struct ieee80211_device *ieee,
1797                                      struct sk_buff *skb)
1798 {
1799         struct rtl_80211_hdr *header = (struct rtl_80211_hdr *)skb->data;
1800         u8 *act = ieee80211_get_payload(header);
1801         u8 tmp = 0;
1802 //      IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1803         if (!act) {
1804                 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1805                 return;
1806         }
1807         tmp = *act;
1808         act++;
1809         switch (tmp) {
1810         case ACT_CAT_BA:
1811                 if (*act == ACT_ADDBAREQ)
1812                         ieee80211_rx_ADDBAReq(ieee, skb);
1813                 else if (*act == ACT_ADDBARSP)
1814                         ieee80211_rx_ADDBARsp(ieee, skb);
1815                 else if (*act == ACT_DELBA)
1816                         ieee80211_rx_DELBA(ieee, skb);
1817                 break;
1818         default:
1819                 break;
1820         }
1821         return;
1822 }
1823
1824 static void ieee80211_check_auth_response(struct ieee80211_device *ieee,
1825                                           struct sk_buff *skb)
1826 {
1827         /* default support N mode, disable halfNmode */
1828         bool bSupportNmode = true, bHalfSupportNmode = false;
1829         u16 errcode;
1830         u8 *challenge;
1831         int chlen = 0;
1832         u32 iotAction;
1833
1834         errcode = auth_parse(skb, &challenge, &chlen);
1835         if (!errcode) {
1836                 if (ieee->open_wep || !challenge) {
1837                         ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
1838                         ieee->softmac_stats.rx_auth_rs_ok++;
1839                         iotAction = ieee->pHTInfo->IOTAction;
1840                         if (!(iotAction & HT_IOT_ACT_PURE_N_MODE)) {
1841                                 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) {
1842                                         /* WEP or TKIP encryption */
1843                                         if (IsHTHalfNmodeAPs(ieee)) {
1844                                                 bSupportNmode = true;
1845                                                 bHalfSupportNmode = true;
1846                                         } else {
1847                                                 bSupportNmode = false;
1848                                                 bHalfSupportNmode = false;
1849                                         }
1850                                         netdev_dbg(ieee->dev, "SEC(%d, %d)\n",
1851                                                         bSupportNmode,
1852                                                         bHalfSupportNmode);
1853                                 }
1854                         }
1855                         /* Dummy wirless mode setting- avoid encryption issue */
1856                         if (bSupportNmode) {
1857                                 /* N mode setting */
1858                                 ieee->SetWirelessMode(ieee->dev,
1859                                                 ieee->current_network.mode);
1860                         } else {
1861                                 /* b/g mode setting - TODO */
1862                                 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1863                         }
1864
1865                         if (ieee->current_network.mode == IEEE_N_24G &&
1866                                         bHalfSupportNmode) {
1867                                 netdev_dbg(ieee->dev, "enter half N mode\n");
1868                                 ieee->bHalfWirelessN24GMode = true;
1869                         } else {
1870                                 ieee->bHalfWirelessN24GMode = false;
1871                         }
1872                         ieee80211_associate_step2(ieee);
1873                 } else {
1874                         ieee80211_auth_challenge(ieee, challenge, chlen);
1875                 }
1876         } else {
1877                 ieee->softmac_stats.rx_auth_rs_err++;
1878                 IEEE80211_DEBUG_MGMT("Auth response status code 0x%x", errcode);
1879                 ieee80211_associate_abort(ieee);
1880         }
1881 }
1882
1883 inline int
1884 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1885                            struct ieee80211_rx_stats *rx_stats, u16 type,
1886                            u16 stype)
1887 {
1888         struct rtl_80211_hdr_3addr *header = (struct rtl_80211_hdr_3addr *)skb->data;
1889         u16 errcode;
1890         int aid;
1891         struct ieee80211_assoc_response_frame *assoc_resp;
1892 //      struct ieee80211_info_element *info_element;
1893
1894         if (!ieee->proto_started)
1895                 return 0;
1896
1897         if (ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
1898                                 ieee->iw_mode == IW_MODE_INFRA &&
1899                                 ieee->state == IEEE80211_LINKED))
1900                 tasklet_schedule(&ieee->ps_task);
1901
1902         if (WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
1903             WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
1904                 ieee->last_rx_ps_time = jiffies;
1905
1906         switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1907         case IEEE80211_STYPE_ASSOC_RESP:
1908         case IEEE80211_STYPE_REASSOC_RESP:
1909                 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
1910                                 WLAN_FC_GET_STYPE(header->frame_ctl));
1911                 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1912                     ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
1913                     ieee->iw_mode == IW_MODE_INFRA) {
1914                         struct ieee80211_network network_resp;
1915                         struct ieee80211_network *network = &network_resp;
1916
1917                         errcode = assoc_parse(ieee, skb, &aid);
1918                         if (!errcode) {
1919                                 ieee->state = IEEE80211_LINKED;
1920                                 ieee->assoc_id = aid;
1921                                 ieee->softmac_stats.rx_ass_ok++;
1922                                 /* station support qos */
1923                                 /* Let the register setting defaultly with Legacy station */
1924                                 if (ieee->qos_support) {
1925                                         assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
1926                                         memset(network, 0, sizeof(*network));
1927                                         if (ieee80211_parse_info_param(ieee, assoc_resp->info_element,\
1928                                                                        rx_stats->len - sizeof(*assoc_resp), \
1929                                                                        network, rx_stats)) {
1930                                                 return 1;
1931                                         } else {
1932                                                 //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
1933                                                 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
1934                                                 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
1935                                         }
1936                                         if (ieee->handle_assoc_response)
1937                                                 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame *)header, network);
1938                                 }
1939                                 ieee80211_associate_complete(ieee);
1940                         } else {
1941                                 /* aid could not been allocated */
1942                                 ieee->softmac_stats.rx_ass_err++;
1943                                 printk("Association response status code 0x%x\n",
1944                                        errcode);
1945                                 IEEE80211_DEBUG_MGMT("Association response status code 0x%x\n",
1946                                                      errcode);
1947                                 if (ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT)
1948                                         schedule_work(&ieee->associate_procedure_wq);
1949                                 else
1950                                         ieee80211_associate_abort(ieee);
1951                         }
1952                 }
1953                 break;
1954
1955         case IEEE80211_STYPE_ASSOC_REQ:
1956         case IEEE80211_STYPE_REASSOC_REQ:
1957                 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1958                     ieee->iw_mode == IW_MODE_MASTER)
1959                         ieee80211_rx_assoc_rq(ieee, skb);
1960                 break;
1961
1962         case IEEE80211_STYPE_AUTH:
1963                 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
1964                         if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING
1965                             && ieee->iw_mode == IW_MODE_INFRA) {
1966                                 IEEE80211_DEBUG_MGMT("Received auth response");
1967                                 ieee80211_check_auth_response(ieee, skb);
1968                         } else if (ieee->iw_mode == IW_MODE_MASTER) {
1969                                 ieee80211_rx_auth_rq(ieee, skb);
1970                         }
1971                 }
1972                 break;
1973
1974         case IEEE80211_STYPE_PROBE_REQ:
1975                 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
1976                     ((ieee->iw_mode == IW_MODE_ADHOC ||
1977                       ieee->iw_mode == IW_MODE_MASTER) &&
1978                      ieee->state == IEEE80211_LINKED)) {
1979                         ieee80211_rx_probe_rq(ieee, skb);
1980                 }
1981                 break;
1982
1983         case IEEE80211_STYPE_DISASSOC:
1984         case IEEE80211_STYPE_DEAUTH:
1985                 /* FIXME for now repeat all the association procedure
1986                 * both for disassociation and deauthentication
1987                 */
1988                 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1989                     ieee->state == IEEE80211_LINKED &&
1990                     ieee->iw_mode == IW_MODE_INFRA) {
1991                         ieee->state = IEEE80211_ASSOCIATING;
1992                         ieee->softmac_stats.reassoc++;
1993
1994                         notify_wx_assoc_event(ieee);
1995                         //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1996                         RemovePeerTS(ieee, header->addr2);
1997                         schedule_work(&ieee->associate_procedure_wq);
1998                 }
1999                 break;
2000         case IEEE80211_STYPE_MANAGE_ACT:
2001                 ieee80211_process_action(ieee, skb);
2002                 break;
2003         default:
2004                 return -1;
2005         }
2006
2007         //dev_kfree_skb_any(skb);
2008         return 0;
2009 }
2010
2011 /* The following are for a simpler TX queue management.
2012  * Instead of using netif_[stop/wake]_queue, the driver
2013  * will use these two functions (plus a reset one) that
2014  * will internally call the kernel netif_* and take care
2015  * of the ieee802.11 fragmentation.
2016  * So, the driver receives a fragment at a time and might
2017  * call the stop function when it wants, without taking
2018  * care to have enough room to TX an entire packet.
2019  * This might be useful if each fragment needs its own
2020  * descriptor. Thus, just keeping a total free memory > than
2021  * the max fragmentation threshold is not enough. If the
2022  * ieee802.11 stack passed a TXB struct, then you would need
2023  * to keep N free descriptors where
2024  * N = MAX_PACKET_SIZE / MIN_FRAG_THRESHOLD.
2025  * In this way you need just one and the 802.11 stack
2026  * will take care of buffering fragments and pass them to
2027  * to the driver later, when it wakes the queue.
2028  */
2029 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2030 {
2031         unsigned int queue_index = txb->queue_index;
2032         unsigned long flags;
2033         int  i;
2034         struct cb_desc *tcb_desc = NULL;
2035
2036         spin_lock_irqsave(&ieee->lock, flags);
2037
2038         /* called with 2nd parm 0, no tx mgmt lock required */
2039         ieee80211_sta_wakeup(ieee, 0);
2040
2041         /* update the tx status */
2042         ieee->stats.tx_bytes += le16_to_cpu(txb->payload_size);
2043         ieee->stats.tx_packets++;
2044         tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2045         if (tcb_desc->bMulticast)
2046                 ieee->stats.multicast++;
2047
2048         /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2049         for (i = 0; i < txb->nr_frags; i++) {
2050 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2051                 if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
2052 #else
2053                 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2054 #endif
2055                     (!ieee->check_nic_enough_desc(ieee->dev, queue_index)) ||
2056                     (ieee->queue_stop)) {
2057                         /* insert the skb packet to the wait queue */
2058                         /* as for the completion function, it does not need
2059                          * to check it any more.
2060                          * */
2061                         //printk("error:no descriptor left@queue_index %d\n", queue_index);
2062                         //ieee80211_stop_queue(ieee);
2063 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2064                         skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2065 #else
2066                         skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2067 #endif
2068                 } else {
2069                         ieee->softmac_data_hard_start_xmit(txb->fragments[i],
2070                                                            ieee->dev, ieee->rate);
2071                         //ieee->stats.tx_packets++;
2072                         //ieee->stats.tx_bytes += txb->fragments[i]->len;
2073                         //ieee->dev->trans_start = jiffies;
2074                 }
2075         }
2076         ieee80211_txb_free(txb);
2077
2078 //exit:
2079         spin_unlock_irqrestore(&ieee->lock, flags);
2080 }
2081 EXPORT_SYMBOL(ieee80211_softmac_xmit);
2082
2083 /* called with ieee->lock acquired */
2084 static void ieee80211_resume_tx(struct ieee80211_device *ieee)
2085 {
2086         int i;
2087         for (i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2088                 if (ieee->queue_stop) {
2089                         ieee->tx_pending.frag = i;
2090                         return;
2091                 } else {
2092                         ieee->softmac_data_hard_start_xmit(ieee->tx_pending.txb->fragments[i],
2093                                                            ieee->dev, ieee->rate);
2094                         //(i+1)<ieee->tx_pending.txb->nr_frags);
2095                         ieee->stats.tx_packets++;
2096                         netif_trans_update(ieee->dev);
2097                 }
2098         }
2099
2100         ieee80211_txb_free(ieee->tx_pending.txb);
2101         ieee->tx_pending.txb = NULL;
2102 }
2103
2104 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2105 {
2106         unsigned long flags;
2107
2108         spin_lock_irqsave(&ieee->lock, flags);
2109         init_mgmt_queue(ieee);
2110         if (ieee->tx_pending.txb) {
2111                 ieee80211_txb_free(ieee->tx_pending.txb);
2112                 ieee->tx_pending.txb = NULL;
2113         }
2114         ieee->queue_stop = 0;
2115         spin_unlock_irqrestore(&ieee->lock, flags);
2116 }
2117 EXPORT_SYMBOL(ieee80211_reset_queue);
2118
2119 void ieee80211_wake_queue(struct ieee80211_device *ieee)
2120 {
2121         unsigned long flags;
2122         struct sk_buff *skb;
2123         struct rtl_80211_hdr_3addr  *header;
2124
2125         spin_lock_irqsave(&ieee->lock, flags);
2126         if (!ieee->queue_stop)
2127                 goto exit;
2128
2129         ieee->queue_stop = 0;
2130
2131         if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) {
2132                 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))) {
2133                         header = (struct rtl_80211_hdr_3addr  *)skb->data;
2134
2135                         header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2136
2137                         if (ieee->seq_ctrl[0] == 0xFFF)
2138                                 ieee->seq_ctrl[0] = 0;
2139                         else
2140                                 ieee->seq_ctrl[0]++;
2141
2142                         ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
2143                         //dev_kfree_skb_any(skb);//edit by thomas
2144                 }
2145         }
2146         if (!ieee->queue_stop && ieee->tx_pending.txb)
2147                 ieee80211_resume_tx(ieee);
2148
2149         if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) {
2150                 ieee->softmac_stats.swtxawake++;
2151                 netif_wake_queue(ieee->dev);
2152         }
2153 exit:
2154         spin_unlock_irqrestore(&ieee->lock, flags);
2155 }
2156 EXPORT_SYMBOL(ieee80211_wake_queue);
2157
2158 void ieee80211_stop_queue(struct ieee80211_device *ieee)
2159 {
2160         //unsigned long flags;
2161         //spin_lock_irqsave(&ieee->lock,flags);
2162
2163         if (!netif_queue_stopped(ieee->dev)) {
2164                 netif_stop_queue(ieee->dev);
2165                 ieee->softmac_stats.swtxstop++;
2166         }
2167         ieee->queue_stop = 1;
2168         //spin_unlock_irqrestore(&ieee->lock,flags);
2169 }
2170 EXPORT_SYMBOL(ieee80211_stop_queue);
2171
2172 /* called in user context only */
2173 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2174 {
2175         ieee->assoc_id = 1;
2176
2177         if (ieee->current_network.ssid_len == 0) {
2178                 strncpy(ieee->current_network.ssid,
2179                         IEEE80211_DEFAULT_TX_ESSID,
2180                         IW_ESSID_MAX_SIZE);
2181
2182                 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2183                 ieee->ssid_set = 1;
2184         }
2185
2186         memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2187
2188         ieee->set_chan(ieee->dev, ieee->current_network.channel);
2189         ieee->state = IEEE80211_LINKED;
2190         ieee->link_change(ieee->dev);
2191         notify_wx_assoc_event(ieee);
2192
2193         if (ieee->data_hard_resume)
2194                 ieee->data_hard_resume(ieee->dev);
2195
2196         netif_carrier_on(ieee->dev);
2197 }
2198
2199 static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2200 {
2201         if (ieee->raw_tx) {
2202                 if (ieee->data_hard_resume)
2203                         ieee->data_hard_resume(ieee->dev);
2204
2205                 netif_carrier_on(ieee->dev);
2206         }
2207 }
2208 static void ieee80211_start_ibss_wq(struct work_struct *work)
2209 {
2210         struct delayed_work *dwork = to_delayed_work(work);
2211         struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2212         /* iwconfig mode ad-hoc will schedule this and return
2213          * on the other hand this will block further iwconfig SET
2214          * operations because of the wx_mutex hold.
2215          * Anyway some most set operations set a flag to speed-up
2216          * (abort) this wq (when syncro scanning) before sleeping
2217          * on the semaphore
2218          */
2219         if (!ieee->proto_started) {
2220                 printk("==========oh driver down return\n");
2221                 return;
2222         }
2223         mutex_lock(&ieee->wx_mutex);
2224
2225         if (ieee->current_network.ssid_len == 0) {
2226                 strcpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID);
2227                 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2228                 ieee->ssid_set = 1;
2229         }
2230
2231         /* check if we have this cell in our network list */
2232         ieee80211_softmac_check_all_nets(ieee);
2233
2234 //      if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2235         if (ieee->state == IEEE80211_NOLINK)
2236                 ieee->current_network.channel = 6;
2237         /* if not then the state is not linked. Maybe the user switched to
2238          * ad-hoc mode just after being in monitor mode, or just after
2239          * being very few time in managed mode (so the card have had no
2240          * time to scan all the chans..) or we have just run up the iface
2241          * after setting ad-hoc mode. So we have to give another try..
2242          * Here, in ibss mode, should be safe to do this without extra care
2243          * (in bss mode we had to make sure no-one tryed to associate when
2244          * we had just checked the ieee->state and we was going to start the
2245          * scan) beacause in ibss mode the ieee80211_new_net function, when
2246          * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2247          * so, at worst, we waste a bit of time to initiate an unneeded syncro
2248          * scan, that will stop at the first round because it sees the state
2249          * associated.
2250          */
2251         if (ieee->state == IEEE80211_NOLINK)
2252                 ieee80211_start_scan_syncro(ieee);
2253
2254         /* the network definitively is not here.. create a new cell */
2255         if (ieee->state == IEEE80211_NOLINK) {
2256                 printk("creating new IBSS cell\n");
2257                 if (!ieee->wap_set)
2258                         eth_random_addr(ieee->current_network.bssid);
2259
2260                 if (ieee->modulation & IEEE80211_CCK_MODULATION) {
2261                         ieee->current_network.rates_len = 4;
2262
2263                         ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2264                         ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2265                         ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2266                         ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2267                 } else {
2268                         ieee->current_network.rates_len = 0;
2269                 }
2270                 if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
2271                         ieee->current_network.rates_ex_len = 8;
2272
2273                         ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2274                         ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2275                         ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2276                         ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2277                         ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2278                         ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2279                         ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2280                         ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2281
2282                         ieee->rate = 108;
2283                 } else {
2284                         ieee->current_network.rates_ex_len = 0;
2285                         ieee->rate = 22;
2286                 }
2287
2288                 // By default, WMM function will be disabled in IBSS mode
2289                 ieee->current_network.QoS_Enable = 0;
2290                 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2291                 ieee->current_network.atim_window = 0;
2292                 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2293                 if (ieee->short_slot)
2294                         ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2295         }
2296
2297         ieee->state = IEEE80211_LINKED;
2298
2299         ieee->set_chan(ieee->dev, ieee->current_network.channel);
2300         ieee->link_change(ieee->dev);
2301
2302         notify_wx_assoc_event(ieee);
2303
2304         ieee80211_start_send_beacons(ieee);
2305
2306         if (ieee->data_hard_resume)
2307                 ieee->data_hard_resume(ieee->dev);
2308         netif_carrier_on(ieee->dev);
2309
2310         mutex_unlock(&ieee->wx_mutex);
2311 }
2312
2313 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2314 {
2315         schedule_delayed_work(&ieee->start_ibss_wq, 150);
2316 }
2317
2318 /* this is called only in user context, with wx_mutex held */
2319 void ieee80211_start_bss(struct ieee80211_device *ieee)
2320 {
2321         unsigned long flags;
2322         //
2323         // Ref: 802.11d 11.1.3.3
2324         // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2325         //
2326         if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) {
2327                 if (!ieee->bGlobalDomain)
2328                         return;
2329         }
2330         /* check if we have already found the net we
2331          * are interested in (if any).
2332          * if not (we are disassociated and we are not
2333          * in associating / authenticating phase) start the background scanning.
2334          */
2335         ieee80211_softmac_check_all_nets(ieee);
2336
2337         /* ensure no-one start an associating process (thus setting
2338          * the ieee->state to ieee80211_ASSOCIATING) while we
2339          * have just checked it and we are going to enable scan.
2340          * The ieee80211_new_net function is always called with
2341          * lock held (from both ieee80211_softmac_check_all_nets and
2342          * the rx path), so we cannot be in the middle of such function
2343          */
2344         spin_lock_irqsave(&ieee->lock, flags);
2345
2346         if (ieee->state == IEEE80211_NOLINK) {
2347                 ieee->actscanning = true;
2348                 ieee80211_start_scan(ieee);
2349         }
2350         spin_unlock_irqrestore(&ieee->lock, flags);
2351 }
2352
2353 /* called only in userspace context */
2354 void ieee80211_disassociate(struct ieee80211_device *ieee)
2355 {
2356         netif_carrier_off(ieee->dev);
2357         if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2358                 ieee80211_reset_queue(ieee);
2359
2360         if (ieee->data_hard_stop)
2361                 ieee->data_hard_stop(ieee->dev);
2362         if (IS_DOT11D_ENABLE(ieee))
2363                 dot11d_reset(ieee);
2364         ieee->state = IEEE80211_NOLINK;
2365         ieee->is_set_key = false;
2366         ieee->link_change(ieee->dev);
2367         //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2368         notify_wx_assoc_event(ieee);
2369 }
2370 EXPORT_SYMBOL(ieee80211_disassociate);
2371
2372 static void ieee80211_associate_retry_wq(struct work_struct *work)
2373 {
2374         struct delayed_work *dwork = to_delayed_work(work);
2375         struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2376         unsigned long flags;
2377
2378         mutex_lock(&ieee->wx_mutex);
2379         if (!ieee->proto_started)
2380                 goto exit;
2381
2382         if (ieee->state != IEEE80211_ASSOCIATING_RETRY)
2383                 goto exit;
2384
2385         /* until we do not set the state to IEEE80211_NOLINK
2386         * there are no possibility to have someone else trying
2387         * to start an association procedure (we get here with
2388         * ieee->state = IEEE80211_ASSOCIATING).
2389         * When we set the state to IEEE80211_NOLINK it is possible
2390         * that the RX path run an attempt to associate, but
2391         * both ieee80211_softmac_check_all_nets and the
2392         * RX path works with ieee->lock held so there are no
2393         * problems. If we are still disassociated then start a scan.
2394         * the lock here is necessary to ensure no one try to start
2395         * an association procedure when we have just checked the
2396         * state and we are going to start the scan.
2397         */
2398         ieee->state = IEEE80211_NOLINK;
2399
2400         ieee80211_softmac_check_all_nets(ieee);
2401
2402         spin_lock_irqsave(&ieee->lock, flags);
2403
2404         if (ieee->state == IEEE80211_NOLINK)
2405                 ieee80211_start_scan(ieee);
2406
2407         spin_unlock_irqrestore(&ieee->lock, flags);
2408
2409 exit:
2410         mutex_unlock(&ieee->wx_mutex);
2411 }
2412
2413 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2414 {
2415         u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2416
2417         struct sk_buff *skb;
2418         struct ieee80211_probe_response *b;
2419
2420         skb = ieee80211_probe_resp(ieee, broadcast_addr);
2421
2422         if (!skb)
2423                 return NULL;
2424
2425         b = (struct ieee80211_probe_response *)skb->data;
2426         b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2427
2428         return skb;
2429 }
2430
2431 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2432 {
2433         struct sk_buff *skb;
2434         struct ieee80211_probe_response *b;
2435
2436         skb = ieee80211_get_beacon_(ieee);
2437         if (!skb)
2438                 return NULL;
2439
2440         b = (struct ieee80211_probe_response *)skb->data;
2441         b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2442
2443         if (ieee->seq_ctrl[0] == 0xFFF)
2444                 ieee->seq_ctrl[0] = 0;
2445         else
2446                 ieee->seq_ctrl[0]++;
2447
2448         return skb;
2449 }
2450 EXPORT_SYMBOL(ieee80211_get_beacon);
2451
2452 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2453 {
2454         ieee->sync_scan_hurryup = 1;
2455         mutex_lock(&ieee->wx_mutex);
2456         ieee80211_stop_protocol(ieee);
2457         mutex_unlock(&ieee->wx_mutex);
2458 }
2459 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
2460
2461 void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2462 {
2463         if (!ieee->proto_started)
2464                 return;
2465
2466         ieee->proto_started = 0;
2467
2468         ieee80211_stop_send_beacons(ieee);
2469         del_timer_sync(&ieee->associate_timer);
2470         cancel_delayed_work(&ieee->associate_retry_wq);
2471         cancel_delayed_work(&ieee->start_ibss_wq);
2472         ieee80211_stop_scan(ieee);
2473
2474         ieee80211_disassociate(ieee);
2475         RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2476 }
2477
2478 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2479 {
2480         ieee->sync_scan_hurryup = 0;
2481         mutex_lock(&ieee->wx_mutex);
2482         ieee80211_start_protocol(ieee);
2483         mutex_unlock(&ieee->wx_mutex);
2484 }
2485 EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
2486
2487 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2488 {
2489         short ch = 0;
2490         int i = 0;
2491
2492         if (ieee->proto_started)
2493                 return;
2494
2495         ieee->proto_started = 1;
2496
2497         if (ieee->current_network.channel == 0) {
2498                 do {
2499                         ch++;
2500                         if (ch > MAX_CHANNEL_NUMBER)
2501                                 return; /* no channel found */
2502                 } while (!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2503                 ieee->current_network.channel = ch;
2504         }
2505
2506         if (ieee->current_network.beacon_interval == 0)
2507                 ieee->current_network.beacon_interval = 100;
2508 //      printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
2509 //      ieee->set_chan(ieee->dev,ieee->current_network.channel);
2510
2511         for (i = 0; i < 17; i++) {
2512                 ieee->last_rxseq_num[i] = -1;
2513                 ieee->last_rxfrag_num[i] = -1;
2514                 ieee->last_packet_time[i] = 0;
2515         }
2516
2517         ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2518
2519         /* if the user set the MAC of the ad-hoc cell and then
2520          * switch to managed mode, shall we  make sure that association
2521          * attempts does not fail just because the user provide the essid
2522          * and the nic is still checking for the AP MAC ??
2523          */
2524         if (ieee->iw_mode == IW_MODE_INFRA)
2525                 ieee80211_start_bss(ieee);
2526
2527         else if (ieee->iw_mode == IW_MODE_ADHOC)
2528                 ieee80211_start_ibss(ieee);
2529
2530         else if (ieee->iw_mode == IW_MODE_MASTER)
2531                 ieee80211_start_master_bss(ieee);
2532
2533         else if (ieee->iw_mode == IW_MODE_MONITOR)
2534                 ieee80211_start_monitor_mode(ieee);
2535 }
2536
2537 #define DRV_NAME  "Ieee80211"
2538 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2539 {
2540         int i;
2541         memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2542
2543         ieee->state = IEEE80211_NOLINK;
2544         ieee->sync_scan_hurryup = 0;
2545         for (i = 0; i < 5; i++)
2546                 ieee->seq_ctrl[i] = 0;
2547
2548         ieee->dot11d_info = kzalloc(sizeof(struct rt_dot11d_info), GFP_KERNEL);
2549         if (!ieee->dot11d_info)
2550                 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2551         //added for  AP roaming
2552         ieee->LinkDetectInfo.SlotNum = 2;
2553         ieee->LinkDetectInfo.NumRecvBcnInPeriod = 0;
2554         ieee->LinkDetectInfo.NumRecvDataInPeriod = 0;
2555
2556         ieee->assoc_id = 0;
2557         ieee->queue_stop = 0;
2558         ieee->scanning = 0;
2559         ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2560         ieee->wap_set = 0;
2561         ieee->ssid_set = 0;
2562         ieee->proto_started = 0;
2563         ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2564         ieee->rate = 22;
2565         ieee->ps = IEEE80211_PS_DISABLED;
2566         ieee->sta_sleep = 0;
2567         ieee->Regdot11HTOperationalRateSet[0] = 0xff;//support MCS 0~7
2568         ieee->Regdot11HTOperationalRateSet[1] = 0xff;//support MCS 8~15
2569         ieee->Regdot11HTOperationalRateSet[4] = 0x01;
2570         //added by amy
2571         ieee->actscanning = false;
2572         ieee->beinretry = false;
2573         ieee->is_set_key = false;
2574         init_mgmt_queue(ieee);
2575
2576         ieee->sta_edca_param[0] = 0x0000A403;
2577         ieee->sta_edca_param[1] = 0x0000A427;
2578         ieee->sta_edca_param[2] = 0x005E4342;
2579         ieee->sta_edca_param[3] = 0x002F3262;
2580         ieee->aggregation = true;
2581         ieee->enable_rx_imm_BA = true;
2582         ieee->tx_pending.txb = NULL;
2583
2584         timer_setup(&ieee->associate_timer, ieee80211_associate_abort_cb, 0);
2585
2586         timer_setup(&ieee->beacon_timer, ieee80211_send_beacon_cb, 0);
2587
2588         INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
2589         INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2590         INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2591         INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
2592         INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2593         INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
2594
2595         mutex_init(&ieee->wx_mutex);
2596         mutex_init(&ieee->scan_mutex);
2597
2598         spin_lock_init(&ieee->mgmt_tx_lock);
2599         spin_lock_init(&ieee->beacon_lock);
2600
2601         tasklet_setup(&ieee->ps_task, ieee80211_sta_ps);
2602 }
2603
2604 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2605 {
2606         mutex_lock(&ieee->wx_mutex);
2607         kfree(ieee->dot11d_info);
2608         ieee->dot11d_info = NULL;
2609         del_timer_sync(&ieee->associate_timer);
2610
2611         cancel_delayed_work(&ieee->associate_retry_wq);
2612
2613         mutex_unlock(&ieee->wx_mutex);
2614 }
2615
2616 /********************************************************
2617  * Start of WPA code.                                   *
2618  * this is stolen from the ipw2200 driver               *
2619  ********************************************************/
2620 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2621 {
2622         /* This is called when wpa_supplicant loads and closes the driver
2623          * interface. */
2624         printk("%s WPA\n", value ? "enabling" : "disabling");
2625         ieee->wpa_enabled = value;
2626         return 0;
2627 }
2628
2629 static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee,
2630                                       char *wpa_ie, int wpa_ie_len)
2631 {
2632         /* make sure WPA is enabled */
2633         ieee80211_wpa_enable(ieee, 1);
2634
2635         ieee80211_disassociate(ieee);
2636 }
2637
2638 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2639 {
2640         int ret = 0;
2641
2642         switch (command) {
2643         case IEEE_MLME_STA_DEAUTH:
2644                 // silently ignore
2645                 break;
2646
2647         case IEEE_MLME_STA_DISASSOC:
2648                 ieee80211_disassociate(ieee);
2649                 break;
2650
2651         default:
2652                 printk("Unknown MLME request: %d\n", command);
2653                 ret = -EOPNOTSUPP;
2654         }
2655
2656         return ret;
2657 }
2658
2659 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2660                               struct ieee_param *param, int plen)
2661 {
2662         u8 *buf;
2663
2664         if (param->u.wpa_ie.len > MAX_WPA_IE_LEN)
2665                 return -EINVAL;
2666
2667         if (param->u.wpa_ie.len) {
2668                 buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
2669                               GFP_KERNEL);
2670                 if (!buf)
2671                         return -ENOMEM;
2672
2673                 kfree(ieee->wpa_ie);
2674                 ieee->wpa_ie = buf;
2675                 ieee->wpa_ie_len = param->u.wpa_ie.len;
2676         } else {
2677                 kfree(ieee->wpa_ie);
2678                 ieee->wpa_ie = NULL;
2679                 ieee->wpa_ie_len = 0;
2680         }
2681
2682         ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2683         return 0;
2684 }
2685
2686 #define AUTH_ALG_OPEN_SYSTEM                    0x1
2687 #define AUTH_ALG_SHARED_KEY                     0x2
2688
2689 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2690 {
2691         struct ieee80211_security sec = {
2692                 .flags = SEC_AUTH_MODE,
2693         };
2694
2695         if (value & AUTH_ALG_SHARED_KEY) {
2696                 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2697                 ieee->open_wep = 0;
2698                 ieee->auth_mode = 1;
2699         } else if (value & AUTH_ALG_OPEN_SYSTEM) {
2700                 sec.auth_mode = WLAN_AUTH_OPEN;
2701                 ieee->open_wep = 1;
2702                 ieee->auth_mode = 0;
2703         } else if (value & IW_AUTH_ALG_LEAP) {
2704                 sec.auth_mode = WLAN_AUTH_LEAP;
2705                 ieee->open_wep = 1;
2706                 ieee->auth_mode = 2;
2707         }
2708
2709         if (ieee->set_security)
2710                 ieee->set_security(ieee->dev, &sec);
2711         //else
2712         //      ret = -EOPNOTSUPP;
2713
2714         return 0;
2715 }
2716
2717 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2718 {
2719         int ret = 0;
2720         unsigned long flags;
2721
2722         switch (name) {
2723         case IEEE_PARAM_WPA_ENABLED:
2724                 ret = ieee80211_wpa_enable(ieee, value);
2725                 break;
2726
2727         case IEEE_PARAM_TKIP_COUNTERMEASURES:
2728                 ieee->tkip_countermeasures = value;
2729                 break;
2730
2731         case IEEE_PARAM_DROP_UNENCRYPTED: {
2732                 /* HACK:
2733                  *
2734                  * wpa_supplicant calls set_wpa_enabled when the driver
2735                  * is loaded and unloaded, regardless of if WPA is being
2736                  * used.  No other calls are made which can be used to
2737                  * determine if encryption will be used or not prior to
2738                  * association being expected.  If encryption is not being
2739                  * used, drop_unencrypted is set to false, else true -- we
2740                  * can use this to determine if the CAP_PRIVACY_ON bit should
2741                  * be set.
2742                  */
2743                 struct ieee80211_security sec = {
2744                         .flags = SEC_ENABLED,
2745                         .enabled = value,
2746                 };
2747                 ieee->drop_unencrypted = value;
2748                 /* We only change SEC_LEVEL for open mode. Others
2749                  * are set by ipw_wpa_set_encryption.
2750                  */
2751                 if (!value) {
2752                         sec.flags |= SEC_LEVEL;
2753                         sec.level = SEC_LEVEL_0;
2754                 } else {
2755                         sec.flags |= SEC_LEVEL;
2756                         sec.level = SEC_LEVEL_1;
2757                 }
2758                 if (ieee->set_security)
2759                         ieee->set_security(ieee->dev, &sec);
2760                 break;
2761         }
2762
2763         case IEEE_PARAM_PRIVACY_INVOKED:
2764                 ieee->privacy_invoked = value;
2765                 break;
2766
2767         case IEEE_PARAM_AUTH_ALGS:
2768                 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2769                 break;
2770
2771         case IEEE_PARAM_IEEE_802_1X:
2772                 ieee->ieee802_1x = value;
2773                 break;
2774         case IEEE_PARAM_WPAX_SELECT:
2775                 // added for WPA2 mixed mode
2776                 spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
2777                 ieee->wpax_type_set = 1;
2778                 ieee->wpax_type_notify = value;
2779                 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
2780                 break;
2781
2782         default:
2783                 printk("Unknown WPA param: %d\n", name);
2784                 ret = -EOPNOTSUPP;
2785         }
2786
2787         return ret;
2788 }
2789
2790 /* implementation borrowed from hostap driver */
2791 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2792                                   struct ieee_param *param, int param_len)
2793 {
2794         int ret = 0;
2795         const char *module = NULL;
2796
2797         struct ieee80211_crypto_ops *ops = NULL;
2798         struct ieee80211_crypt_data **crypt;
2799
2800         struct ieee80211_security sec = {
2801                 .flags = 0,
2802         };
2803
2804         param->u.crypt.err = 0;
2805         param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2806
2807         if (param_len !=
2808             (int)((char *)param->u.crypt.key - (char *)param) +
2809             param->u.crypt.key_len) {
2810                 printk("Len mismatch %d, %d\n", param_len,
2811                                param->u.crypt.key_len);
2812                 return -EINVAL;
2813         }
2814         if (is_broadcast_ether_addr(param->sta_addr)) {
2815                 if (param->u.crypt.idx >= WEP_KEYS)
2816                         return -EINVAL;
2817                 crypt = &ieee->crypt[param->u.crypt.idx];
2818         } else {
2819                 return -EINVAL;
2820         }
2821
2822         if (strcmp(param->u.crypt.alg, "none") == 0) {
2823                 if (crypt) {
2824                         sec.enabled = 0;
2825                         // FIXME FIXME
2826                         //sec.encrypt = 0;
2827                         sec.level = SEC_LEVEL_0;
2828                         sec.flags |= SEC_ENABLED | SEC_LEVEL;
2829                         ieee80211_crypt_delayed_deinit(ieee, crypt);
2830                 }
2831                 goto done;
2832         }
2833         sec.enabled = 1;
2834 // FIXME FIXME
2835 //      sec.encrypt = 1;
2836         sec.flags |= SEC_ENABLED;
2837
2838         /* IPW HW cannot build TKIP MIC, host decryption still needed. */
2839         if (!(ieee->host_encrypt || ieee->host_decrypt) &&
2840             strcmp(param->u.crypt.alg, "TKIP"))
2841                 goto skip_host_crypt;
2842
2843         //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
2844         if (!strcmp(param->u.crypt.alg, "WEP"))
2845                 module = "ieee80211_crypt_wep";
2846         else if (!strcmp(param->u.crypt.alg, "TKIP"))
2847                 module = "ieee80211_crypt_tkip";
2848         else if (!strcmp(param->u.crypt.alg, "CCMP"))
2849                 module = "ieee80211_crypt_ccmp";
2850         if (module)
2851                 ops = try_then_request_module(ieee80211_get_crypto_ops(param->u.crypt.alg),
2852                                               module);
2853         if (!ops) {
2854                 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
2855                 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
2856                 ret = -EINVAL;
2857                 goto done;
2858         }
2859
2860         if (!*crypt || (*crypt)->ops != ops) {
2861                 struct ieee80211_crypt_data *new_crypt;
2862
2863                 ieee80211_crypt_delayed_deinit(ieee, crypt);
2864
2865                 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
2866                 if (!new_crypt) {
2867                         ret = -ENOMEM;
2868                         goto done;
2869                 }
2870                 new_crypt->ops = ops;
2871                 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
2872                         new_crypt->priv =
2873                                 new_crypt->ops->init(param->u.crypt.idx);
2874
2875                 if (!new_crypt->priv) {
2876                         kfree(new_crypt);
2877                         param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
2878                         ret = -EINVAL;
2879                         goto done;
2880                 }
2881
2882                 *crypt = new_crypt;
2883         }
2884
2885         if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
2886             (*crypt)->ops->set_key(param->u.crypt.key,
2887                                    param->u.crypt.key_len, param->u.crypt.seq,
2888                                    (*crypt)->priv) < 0) {
2889                 printk("key setting failed\n");
2890                 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
2891                 ret = -EINVAL;
2892                 goto done;
2893         }
2894
2895  skip_host_crypt:
2896         if (param->u.crypt.set_tx) {
2897                 ieee->tx_keyidx = param->u.crypt.idx;
2898                 sec.active_key = param->u.crypt.idx;
2899                 sec.flags |= SEC_ACTIVE_KEY;
2900         } else {
2901                 sec.flags &= ~SEC_ACTIVE_KEY;
2902         }
2903         memcpy(sec.keys[param->u.crypt.idx],
2904                param->u.crypt.key,
2905                param->u.crypt.key_len);
2906         sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
2907         sec.flags |= (1 << param->u.crypt.idx);
2908
2909         if (strcmp(param->u.crypt.alg, "WEP") == 0) {
2910                 sec.flags |= SEC_LEVEL;
2911                 sec.level = SEC_LEVEL_1;
2912         } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
2913                 sec.flags |= SEC_LEVEL;
2914                 sec.level = SEC_LEVEL_2;
2915         } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
2916                 sec.flags |= SEC_LEVEL;
2917                 sec.level = SEC_LEVEL_3;
2918         }
2919  done:
2920         if (ieee->set_security)
2921                 ieee->set_security(ieee->dev, &sec);
2922
2923         /* Do not reset port if card is in Managed mode since resetting will
2924          * generate new IEEE 802.11 authentication which may end up in looping
2925          * with IEEE 802.1X.  If your hardware requires a reset after WEP
2926          * configuration (for example... Prism2), implement the reset_port in
2927          * the callbacks structures used to initialize the 802.11 stack. */
2928         if (ieee->reset_on_keychange &&
2929             ieee->iw_mode != IW_MODE_INFRA &&
2930             ieee->reset_port &&
2931             ieee->reset_port(ieee->dev)) {
2932                 printk("reset_port failed\n");
2933                 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
2934                 return -EINVAL;
2935         }
2936
2937         return ret;
2938 }
2939
2940 static inline struct sk_buff *ieee80211_disassociate_skb(struct ieee80211_network *beacon,
2941                                                          struct ieee80211_device *ieee,
2942                                                          u8     asRsn)
2943 {
2944         struct sk_buff *skb;
2945         struct ieee80211_disassoc *disass;
2946
2947         skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
2948         if (!skb)
2949                 return NULL;
2950
2951         disass = skb_put(skb, sizeof(struct ieee80211_disassoc));
2952         disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
2953         disass->header.duration_id = 0;
2954
2955         memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
2956         memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
2957         memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
2958
2959         disass->reason = cpu_to_le16(asRsn);
2960         return skb;
2961 }
2962
2963 void
2964 SendDisassociation(struct ieee80211_device *ieee,
2965                    u8                      *asSta,
2966                    u8                       asRsn
2967 )
2968 {
2969         struct ieee80211_network *beacon = &ieee->current_network;
2970         struct sk_buff *skb;
2971
2972         skb = ieee80211_disassociate_skb(beacon, ieee, asRsn);
2973         if (skb) {
2974                 softmac_mgmt_xmit(skb, ieee);
2975                 //dev_kfree_skb_any(skb);//edit by thomas
2976         }
2977 }
2978 EXPORT_SYMBOL(SendDisassociation);
2979
2980 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
2981 {
2982         struct ieee_param *param;
2983         int ret = 0;
2984
2985         mutex_lock(&ieee->wx_mutex);
2986         //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
2987
2988         if (p->length < sizeof(struct ieee_param) || !p->pointer) {
2989                 ret = -EINVAL;
2990                 goto out;
2991         }
2992
2993         param = memdup_user(p->pointer, p->length);
2994         if (IS_ERR(param)) {
2995                 ret = PTR_ERR(param);
2996                 goto out;
2997         }
2998
2999         switch (param->cmd) {
3000         case IEEE_CMD_SET_WPA_PARAM:
3001                 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3002                                         param->u.wpa_param.value);
3003                 break;
3004
3005         case IEEE_CMD_SET_WPA_IE:
3006                 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3007                 break;
3008
3009         case IEEE_CMD_SET_ENCRYPTION:
3010                 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3011                 break;
3012
3013         case IEEE_CMD_MLME:
3014                 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3015                                    param->u.mlme.reason_code);
3016                 break;
3017
3018         default:
3019                 printk("Unknown WPA supplicant request: %d\n", param->cmd);
3020                 ret = -EOPNOTSUPP;
3021                 break;
3022         }
3023
3024         if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3025                 ret = -EFAULT;
3026
3027         kfree(param);
3028 out:
3029         mutex_unlock(&ieee->wx_mutex);
3030
3031         return ret;
3032 }
3033 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3034
3035 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3036 {
3037         union iwreq_data wrqu;
3038
3039         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3040         if (ieee->state == IEEE80211_LINKED)
3041                 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3042         else
3043                 eth_zero_addr(wrqu.ap_addr.sa_data);
3044         wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3045 }
3046 EXPORT_SYMBOL(notify_wx_assoc_event);