Remove unneeded version.h includes from drivers/staging/rtl*/
[firefly-linux-kernel-4.4.55.git] / drivers / staging / rtl8192e / ieee80211 / ieee80211_rx.c
1 /*
2  * Original code based Host AP (software wireless LAN access point) driver
3  * for Intersil Prism2/2.5/3 - hostap.o module, common routines
4  *
5  * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6  * <jkmaline@cc.hut.fi>
7  * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
8  * Copyright (c) 2004, Intel Corporation
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation. See README and COPYING for
13  * more details.
14  ******************************************************************************
15
16   Few modifications for Realtek's Wi-Fi drivers by
17   Andrea Merello <andreamrl@tiscali.it>
18
19   A special thanks goes to Realtek for their support !
20
21 ******************************************************************************/
22
23
24 #include <linux/compiler.h>
25 #include <linux/errno.h>
26 #include <linux/if_arp.h>
27 #include <linux/in6.h>
28 #include <linux/in.h>
29 #include <linux/ip.h>
30 #include <linux/kernel.h>
31 #include <linux/module.h>
32 #include <linux/netdevice.h>
33 #include <linux/pci.h>
34 #include <linux/proc_fs.h>
35 #include <linux/skbuff.h>
36 #include <linux/slab.h>
37 #include <linux/tcp.h>
38 #include <linux/types.h>
39 #include <linux/wireless.h>
40 #include <linux/etherdevice.h>
41 #include <asm/uaccess.h>
42 #include <linux/ctype.h>
43
44 #include "ieee80211.h"
45 #ifdef ENABLE_DOT11D
46 #include "dot11d.h"
47 #endif
48 static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
49                                         struct sk_buff *skb,
50                                         struct ieee80211_rx_stats *rx_stats)
51 {
52         struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *)skb->data;
53         u16 fc = le16_to_cpu(hdr->frame_ctl);
54
55         skb->dev = ieee->dev;
56         skb_reset_mac_header(skb);
57
58         skb_pull(skb, ieee80211_get_hdrlen(fc));
59         skb->pkt_type = PACKET_OTHERHOST;
60         skb->protocol = __constant_htons(ETH_P_80211_RAW);
61         memset(skb->cb, 0, sizeof(skb->cb));
62         netif_rx(skb);
63 }
64
65
66 /* Called only as a tasklet (software IRQ) */
67 static struct ieee80211_frag_entry *
68 ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
69                           unsigned int frag, u8 tid,u8 *src, u8 *dst)
70 {
71         struct ieee80211_frag_entry *entry;
72         int i;
73
74         for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
75                 entry = &ieee->frag_cache[tid][i];
76                 if (entry->skb != NULL &&
77                     time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
78                         IEEE80211_DEBUG_FRAG(
79                                 "expiring fragment cache entry "
80                                 "seq=%u last_frag=%u\n",
81                                 entry->seq, entry->last_frag);
82                         dev_kfree_skb_any(entry->skb);
83                         entry->skb = NULL;
84                 }
85
86                 if (entry->skb != NULL && entry->seq == seq &&
87                     (entry->last_frag + 1 == frag || frag == -1) &&
88                     memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
89                     memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
90                         return entry;
91         }
92
93         return NULL;
94 }
95
96 /* Called only as a tasklet (software IRQ) */
97 static struct sk_buff *
98 ieee80211_frag_cache_get(struct ieee80211_device *ieee,
99                          struct ieee80211_hdr_4addr *hdr)
100 {
101         struct sk_buff *skb = NULL;
102         u16 fc = le16_to_cpu(hdr->frame_ctl);
103         u16 sc = le16_to_cpu(hdr->seq_ctl);
104         unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
105         unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
106         struct ieee80211_frag_entry *entry;
107         struct ieee80211_hdr_3addrqos *hdr_3addrqos;
108         struct ieee80211_hdr_4addrqos *hdr_4addrqos;
109         u8 tid;
110
111         if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
112           hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
113           tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID;
114           tid = UP2AC(tid);
115           tid ++;
116         } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
117           hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
118           tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID;
119           tid = UP2AC(tid);
120           tid ++;
121         } else {
122           tid = 0;
123         }
124
125         if (frag == 0) {
126                 /* Reserve enough space to fit maximum frame length */
127                 skb = dev_alloc_skb(ieee->dev->mtu +
128                                     sizeof(struct ieee80211_hdr_4addr) +
129                                     8 /* LLC */ +
130                                     2 /* alignment */ +
131                                     8 /* WEP */ +
132                                     ETH_ALEN /* WDS */ +
133                                     (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
134                 if (skb == NULL)
135                         return NULL;
136
137                 entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
138                 ieee->frag_next_idx[tid]++;
139                 if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
140                         ieee->frag_next_idx[tid] = 0;
141
142                 if (entry->skb != NULL)
143                         dev_kfree_skb_any(entry->skb);
144
145                 entry->first_frag_time = jiffies;
146                 entry->seq = seq;
147                 entry->last_frag = frag;
148                 entry->skb = skb;
149                 memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
150                 memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
151         } else {
152                 /* received a fragment of a frame for which the head fragment
153                  * should have already been received */
154                 entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
155                                                   hdr->addr1);
156                 if (entry != NULL) {
157                         entry->last_frag = frag;
158                         skb = entry->skb;
159                 }
160         }
161
162         return skb;
163 }
164
165
166 /* Called only as a tasklet (software IRQ) */
167 static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
168                                            struct ieee80211_hdr_4addr *hdr)
169 {
170         u16 fc = le16_to_cpu(hdr->frame_ctl);
171         u16 sc = le16_to_cpu(hdr->seq_ctl);
172         unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
173         struct ieee80211_frag_entry *entry;
174         struct ieee80211_hdr_3addrqos *hdr_3addrqos;
175         struct ieee80211_hdr_4addrqos *hdr_4addrqos;
176         u8 tid;
177
178         if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
179           hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
180           tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID;
181           tid = UP2AC(tid);
182           tid ++;
183         } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
184           hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
185           tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID;
186           tid = UP2AC(tid);
187           tid ++;
188         } else {
189           tid = 0;
190         }
191
192         entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
193                                           hdr->addr1);
194
195         if (entry == NULL) {
196                 IEEE80211_DEBUG_FRAG(
197                         "could not invalidate fragment cache "
198                         "entry (seq=%u)\n", seq);
199                 return -1;
200         }
201
202         entry->skb = NULL;
203         return 0;
204 }
205
206
207
208 /* ieee80211_rx_frame_mgtmt
209  *
210  * Responsible for handling management control frames
211  *
212  * Called by ieee80211_rx */
213 static inline int
214 ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
215                         struct ieee80211_rx_stats *rx_stats, u16 type,
216                         u16 stype)
217 {
218         /* On the struct stats definition there is written that
219          * this is not mandatory.... but seems that the probe
220          * response parser uses it
221          */
222         struct ieee80211_hdr_3addr * hdr = (struct ieee80211_hdr_3addr *)skb->data;
223
224         rx_stats->len = skb->len;
225         ieee80211_rx_mgt(ieee,(struct ieee80211_hdr_4addr *)skb->data,rx_stats);
226         if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN)))//use ADDR1 to perform address matching for Management frames
227         {
228                 dev_kfree_skb_any(skb);
229                 return 0;
230         }
231
232         ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
233
234         dev_kfree_skb_any(skb);
235
236         return 0;
237
238         #ifdef NOT_YET
239         if (ieee->iw_mode == IW_MODE_MASTER) {
240                 printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
241                        ieee->dev->name);
242                 return 0;
243         }
244
245         if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) {
246                 if (stype == WLAN_FC_STYPE_BEACON &&
247                     ieee->iw_mode == IW_MODE_MASTER) {
248                         struct sk_buff *skb2;
249                         /* Process beacon frames also in kernel driver to
250                          * update STA(AP) table statistics */
251                         skb2 = skb_clone(skb, GFP_ATOMIC);
252                         if (skb2)
253                                 hostap_rx(skb2->dev, skb2, rx_stats);
254                 }
255
256                 /* send management frames to the user space daemon for
257                  * processing */
258                 ieee->apdevstats.rx_packets++;
259                 ieee->apdevstats.rx_bytes += skb->len;
260                 prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
261                 return 0;
262         }
263
264             if (ieee->iw_mode == IW_MODE_MASTER) {
265                 if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
266                         printk(KERN_DEBUG "%s: unknown management frame "
267                                "(type=0x%02x, stype=0x%02x) dropped\n",
268                                skb->dev->name, type, stype);
269                         return -1;
270                 }
271
272                 hostap_rx(skb->dev, skb, rx_stats);
273                 return 0;
274         }
275
276         printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
277                "received in non-Host AP mode\n", skb->dev->name);
278         return -1;
279         #endif
280 }
281
282
283
284 /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
285 /* Ethernet-II snap header (RFC1042 for most EtherTypes) */
286 static unsigned char rfc1042_header[] =
287 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
288 /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
289 static unsigned char bridge_tunnel_header[] =
290 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
291 /* No encapsulation header if EtherType < 0x600 (=length) */
292
293 /* Called by ieee80211_rx_frame_decrypt */
294 static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
295                                     struct sk_buff *skb, size_t hdrlen)
296 {
297         struct net_device *dev = ieee->dev;
298         u16 fc, ethertype;
299         struct ieee80211_hdr_4addr *hdr;
300         u8 *pos;
301
302         if (skb->len < 24)
303                 return 0;
304
305         if (ieee->hwsec_active)
306         {
307                 cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
308                 tcb_desc->bHwSec = 1;
309
310                 if(ieee->need_sw_enc)
311                         tcb_desc->bHwSec = 0;
312         }
313
314         hdr = (struct ieee80211_hdr_4addr *) skb->data;
315         fc = le16_to_cpu(hdr->frame_ctl);
316
317         /* check that the frame is unicast frame to us */
318         if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
319             IEEE80211_FCTL_TODS &&
320             memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
321             memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
322                 /* ToDS frame with own addr BSSID and DA */
323         } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
324                    IEEE80211_FCTL_FROMDS &&
325                    memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
326                 /* FromDS frame with own addr as DA */
327         } else
328                 return 0;
329
330         if (skb->len < 24 + 8)
331                 return 0;
332
333         /* check for port access entity Ethernet type */
334         pos = skb->data + hdrlen;
335         ethertype = (pos[6] << 8) | pos[7];
336         if (ethertype == ETH_P_PAE)
337                 return 1;
338
339         return 0;
340 }
341
342 /* Called only as a tasklet (software IRQ), by ieee80211_rx */
343 static inline int
344 ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
345                            struct ieee80211_crypt_data *crypt)
346 {
347         struct ieee80211_hdr_4addr *hdr;
348         int res, hdrlen;
349
350         if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
351                 return 0;
352
353         if (ieee->hwsec_active)
354         {
355                 cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
356                 tcb_desc->bHwSec = 1;
357         }
358
359         hdr = (struct ieee80211_hdr_4addr *) skb->data;
360         hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
361
362 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
363         if (ieee->tkip_countermeasures &&
364             strcmp(crypt->ops->name, "TKIP") == 0) {
365                 if (net_ratelimit()) {
366                         printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
367                                "received packet from %pM\n",
368                                ieee->dev->name, hdr->addr2);
369                 }
370                 return -1;
371         }
372 #endif
373
374         atomic_inc(&crypt->refcnt);
375         res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
376         atomic_dec(&crypt->refcnt);
377         if (res < 0) {
378                 IEEE80211_DEBUG_DROP(
379                         "decryption failed (SA=%pM"
380                         ") res=%d\n", hdr->addr2, res);
381                 if (res == -2)
382                         IEEE80211_DEBUG_DROP("Decryption failed ICV "
383                                              "mismatch (key %d)\n",
384                                              skb->data[hdrlen + 3] >> 6);
385                 ieee->ieee_stats.rx_discards_undecryptable++;
386                 return -1;
387         }
388
389         return res;
390 }
391
392
393 /* Called only as a tasklet (software IRQ), by ieee80211_rx */
394 static inline int
395 ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
396                              int keyidx, struct ieee80211_crypt_data *crypt)
397 {
398         struct ieee80211_hdr_4addr *hdr;
399         int res, hdrlen;
400
401         if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
402                 return 0;
403         if (ieee->hwsec_active)
404         {
405                 cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
406                 tcb_desc->bHwSec = 1;
407
408                 if(ieee->need_sw_enc)
409                         tcb_desc->bHwSec = 0;
410
411         }
412
413         hdr = (struct ieee80211_hdr_4addr *) skb->data;
414         hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
415
416         atomic_inc(&crypt->refcnt);
417         res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
418         atomic_dec(&crypt->refcnt);
419         if (res < 0) {
420                 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
421                        " (SA=%pM keyidx=%d)\n",
422                        ieee->dev->name, hdr->addr2, keyidx);
423                 return -1;
424         }
425
426         return 0;
427 }
428
429
430 /* this function is stolen from ipw2200 driver*/
431 #define IEEE_PACKET_RETRY_TIME (5*HZ)
432 static int is_duplicate_packet(struct ieee80211_device *ieee,
433                                       struct ieee80211_hdr_4addr *header)
434 {
435         u16 fc = le16_to_cpu(header->frame_ctl);
436         u16 sc = le16_to_cpu(header->seq_ctl);
437         u16 seq = WLAN_GET_SEQ_SEQ(sc);
438         u16 frag = WLAN_GET_SEQ_FRAG(sc);
439         u16 *last_seq, *last_frag;
440         unsigned long *last_time;
441         struct ieee80211_hdr_3addrqos *hdr_3addrqos;
442         struct ieee80211_hdr_4addrqos *hdr_4addrqos;
443         u8 tid;
444
445
446         //TO2DS and QoS
447         if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
448           hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header;
449           tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID;
450           tid = UP2AC(tid);
451           tid ++;
452         } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
453           hdr_3addrqos = (struct ieee80211_hdr_3addrqos*)header;
454           tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID;
455           tid = UP2AC(tid);
456           tid ++;
457         } else { // no QoS
458           tid = 0;
459         }
460
461         switch (ieee->iw_mode) {
462         case IW_MODE_ADHOC:
463         {
464                 struct list_head *p;
465                 struct ieee_ibss_seq *entry = NULL;
466                 u8 *mac = header->addr2;
467                 int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
468
469                 list_for_each(p, &ieee->ibss_mac_hash[index]) {
470                         entry = list_entry(p, struct ieee_ibss_seq, list);
471                         if (!memcmp(entry->mac, mac, ETH_ALEN))
472                                 break;
473                 }
474
475                 if (p == &ieee->ibss_mac_hash[index]) {
476                         entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
477                         if (!entry) {
478                                 printk(KERN_WARNING "Cannot malloc new mac entry\n");
479                                 return 0;
480                         }
481                         memcpy(entry->mac, mac, ETH_ALEN);
482                         entry->seq_num[tid] = seq;
483                         entry->frag_num[tid] = frag;
484                         entry->packet_time[tid] = jiffies;
485                         list_add(&entry->list, &ieee->ibss_mac_hash[index]);
486                         return 0;
487                 }
488                 last_seq = &entry->seq_num[tid];
489                 last_frag = &entry->frag_num[tid];
490                 last_time = &entry->packet_time[tid];
491                 break;
492         }
493
494         case IW_MODE_INFRA:
495                 last_seq = &ieee->last_rxseq_num[tid];
496                 last_frag = &ieee->last_rxfrag_num[tid];
497                 last_time = &ieee->last_packet_time[tid];
498
499                 break;
500         default:
501                 return 0;
502         }
503
504         if ((*last_seq == seq) &&
505             time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
506                 if (*last_frag == frag){
507                         goto drop;
508
509                 }
510                 if (*last_frag + 1 != frag)
511                         /* out-of-order fragment */
512                         goto drop;
513         } else
514                 *last_seq = seq;
515
516         *last_frag = frag;
517         *last_time = jiffies;
518         return 0;
519
520 drop:
521         return 1;
522 }
523 bool
524 AddReorderEntry(
525         PRX_TS_RECORD                   pTS,
526         PRX_REORDER_ENTRY               pReorderEntry
527         )
528 {
529         struct list_head *pList = &pTS->RxPendingPktList;
530
531         while(pList->next != &pTS->RxPendingPktList)
532         {
533                 if( SN_LESS(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
534                 {
535                         pList = pList->next;
536                 }
537                 else if( SN_EQUAL(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
538                 {
539                         return false;
540                 }
541                 else
542                 {
543                         break;
544                 }
545         }
546
547         pReorderEntry->List.next = pList->next;
548         pReorderEntry->List.next->prev = &pReorderEntry->List;
549         pReorderEntry->List.prev = pList;
550         pList->next = &pReorderEntry->List;
551
552         return true;
553 }
554
555 void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8  index)
556 {
557         u8 i = 0 , j=0;
558         u16 ethertype;
559
560         for(j = 0; j<index; j++)
561         {
562 //added by amy for reorder
563                 struct ieee80211_rxb* prxb = prxbIndicateArray[j];
564                 for(i = 0; i<prxb->nr_subframes; i++) {
565                         struct sk_buff *sub_skb = prxb->subframes[i];
566
567                 /* convert hdr + possible LLC headers into Ethernet header */
568                         ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
569                         if (sub_skb->len >= 8 &&
570                                 ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
571                                   ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
572                                  memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
573                         /* remove RFC1042 or Bridge-Tunnel encapsulation and
574                          * replace EtherType */
575                                 skb_pull(sub_skb, SNAP_SIZE);
576                                 memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
577                                 memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
578                         } else {
579                                 u16 len;
580                         /* Leave Ethernet header part of hdr and full payload */
581                                 len = htons(sub_skb->len);
582                                 memcpy(skb_push(sub_skb, 2), &len, 2);
583                                 memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
584                                 memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
585                         }
586
587                 /* Indicat the packets to upper layer */
588                         if (sub_skb) {
589                                 sub_skb->protocol = eth_type_trans(sub_skb, ieee->dev);
590                                 memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
591                                 sub_skb->dev = ieee->dev;
592                                 sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
593                                 ieee->last_rx_ps_time = jiffies;
594                                 netif_rx(sub_skb);
595                         }
596                 }
597                 kfree(prxb);
598                 prxb = NULL;
599         }
600 }
601
602
603 void RxReorderIndicatePacket( struct ieee80211_device *ieee,
604                 struct ieee80211_rxb* prxb,
605                 PRX_TS_RECORD           pTS,
606                 u16                     SeqNum)
607 {
608         PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
609         PRX_REORDER_ENTRY       pReorderEntry = NULL;
610         struct ieee80211_rxb* prxbIndicateArray[REORDER_WIN_SIZE];
611         u8                      WinSize = pHTInfo->RxReorderWinSize;
612         u16                     WinEnd = (pTS->RxIndicateSeq + WinSize -1)%4096;
613         u8                      index = 0;
614         bool                    bMatchWinStart = false, bPktInBuf = false;
615         IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): Seq is %d,pTS->RxIndicateSeq is %d, WinSize is %d\n",__FUNCTION__,SeqNum,pTS->RxIndicateSeq,WinSize);
616
617         /* Rx Reorder initialize condition.*/
618         if(pTS->RxIndicateSeq == 0xffff) {
619                 pTS->RxIndicateSeq = SeqNum;
620         }
621
622         /* Drop out the packet which SeqNum is smaller than WinStart */
623         if(SN_LESS(SeqNum, pTS->RxIndicateSeq)) {
624                 IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packet Drop! IndicateSeq: %d, NewSeq: %d\n",
625                                  pTS->RxIndicateSeq, SeqNum);
626                 pHTInfo->RxReorderDropCounter++;
627                 {
628                         int i;
629                         for(i =0; i < prxb->nr_subframes; i++) {
630                                 dev_kfree_skb(prxb->subframes[i]);
631                         }
632                         kfree(prxb);
633                         prxb = NULL;
634                 }
635                 return;
636         }
637
638         /*
639          * Sliding window manipulation. Conditions includes:
640          * 1. Incoming SeqNum is equal to WinStart =>Window shift 1
641          * 2. Incoming SeqNum is larger than the WinEnd => Window shift N
642          */
643         if(SN_EQUAL(SeqNum, pTS->RxIndicateSeq)) {
644                 pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
645                 bMatchWinStart = true;
646         } else if(SN_LESS(WinEnd, SeqNum)) {
647                 if(SeqNum >= (WinSize - 1)) {
648                         pTS->RxIndicateSeq = SeqNum + 1 -WinSize;
649                 } else {
650                         pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum +1)) + 1;
651                 }
652                 IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
653         }
654
655         /*
656          * Indication process.
657          * After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets
658          * with the SeqNum smaller than latest WinStart and buffer other packets.
659          */
660         /* For Rx Reorder condition:
661          * 1. All packets with SeqNum smaller than WinStart => Indicate
662          * 2. All packets with SeqNum larger than or equal to WinStart => Buffer it.
663          */
664         if(bMatchWinStart) {
665                 /* Current packet is going to be indicated.*/
666                 IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",\
667                                 pTS->RxIndicateSeq, SeqNum);
668                 prxbIndicateArray[0] = prxb;
669                 index = 1;
670         } else {
671                 /* Current packet is going to be inserted into pending list.*/
672                 if(!list_empty(&ieee->RxReorder_Unused_List)) {
673                         pReorderEntry = (PRX_REORDER_ENTRY)list_entry(ieee->RxReorder_Unused_List.next,RX_REORDER_ENTRY,List);
674                         list_del_init(&pReorderEntry->List);
675
676                         /* Make a reorder entry and insert into a the packet list.*/
677                         pReorderEntry->SeqNum = SeqNum;
678                         pReorderEntry->prxb = prxb;
679
680                         if(!AddReorderEntry(pTS, pReorderEntry)) {
681                                 IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n",
682                                         __FUNCTION__, pTS->RxIndicateSeq, SeqNum);
683                                 list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
684                                 {
685                                         int i;
686                                         for(i =0; i < prxb->nr_subframes; i++) {
687                                                 dev_kfree_skb(prxb->subframes[i]);
688                                         }
689                                         kfree(prxb);
690                                         prxb = NULL;
691                                 }
692                         } else {
693                                 IEEE80211_DEBUG(IEEE80211_DL_REORDER,
694                                          "Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
695                         }
696                 }
697                 else {
698                         /*
699                          * Packets are dropped if there is not enough reorder entries.
700                          * This part shall be modified!! We can just indicate all the
701                          * packets in buffer and get reorder entries.
702                          */
703                         IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n");
704                         {
705                                 int i;
706                                 for(i =0; i < prxb->nr_subframes; i++) {
707                                         dev_kfree_skb(prxb->subframes[i]);
708                                 }
709                                 kfree(prxb);
710                                 prxb = NULL;
711                         }
712                 }
713         }
714
715         /* Check if there is any packet need indicate.*/
716         while(!list_empty(&pTS->RxPendingPktList)) {
717                 IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): start RREORDER indicate\n",__FUNCTION__);
718 #if 1
719                 pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
720                 if( SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) ||
721                                 SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
722                 {
723                         /* This protect buffer from overflow. */
724                         if(index >= REORDER_WIN_SIZE) {
725                                 IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!! \n");
726                                 bPktInBuf = true;
727                                 break;
728                         }
729
730                         list_del_init(&pReorderEntry->List);
731
732                         if(SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
733                                 pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
734
735                         IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packets indication!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
736                         prxbIndicateArray[index] = pReorderEntry->prxb;
737                         index++;
738
739                         list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
740                 } else {
741                         bPktInBuf = true;
742                         break;
743                 }
744 #endif
745         }
746
747         /* Handling pending timer. Set this timer to prevent from long time Rx buffering.*/
748         if(index>0) {
749                 // Cancel previous pending timer.
750                 if (timer_pending(&pTS->RxPktPendingTimer))
751                         del_timer_sync(&pTS->RxPktPendingTimer);
752                 pTS->RxTimeoutIndicateSeq = 0xffff;
753
754                 // Indicate packets
755                 if(index>REORDER_WIN_SIZE){
756                         IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
757                         return;
758                 }
759                 ieee80211_indicate_packets(ieee, prxbIndicateArray, index);
760                 bPktInBuf = false;
761         }
762
763         if(bPktInBuf && pTS->RxTimeoutIndicateSeq==0xffff) {
764                 // Set new pending timer.
765                 IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): SET rx timeout timer\n", __FUNCTION__);
766                 pTS->RxTimeoutIndicateSeq = pTS->RxIndicateSeq;
767
768                 mod_timer(&pTS->RxPktPendingTimer,  jiffies + MSECS(pHTInfo->RxReorderPendingTime));
769         }
770 }
771
772 u8 parse_subframe(struct ieee80211_device* ieee,struct sk_buff *skb,
773                   struct ieee80211_rx_stats *rx_stats,
774                   struct ieee80211_rxb *rxb,u8* src,u8* dst)
775 {
776         struct ieee80211_hdr_3addr  *hdr = (struct ieee80211_hdr_3addr* )skb->data;
777         u16             fc = le16_to_cpu(hdr->frame_ctl);
778
779         u16             LLCOffset= sizeof(struct ieee80211_hdr_3addr);
780         u16             ChkLength;
781         bool            bIsAggregateFrame = false;
782         u16             nSubframe_Length;
783         u8              nPadding_Length = 0;
784         u16             SeqNum=0;
785
786         struct sk_buff *sub_skb;
787         u8             *data_ptr;
788         /* just for debug purpose */
789         SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctl));
790
791         if((IEEE80211_QOS_HAS_SEQ(fc))&&\
792                         (((frameqos *)(skb->data + IEEE80211_3ADDR_LEN))->field.reserved)) {
793                 bIsAggregateFrame = true;
794         }
795
796         if(IEEE80211_QOS_HAS_SEQ(fc)) {
797                 LLCOffset += 2;
798         }
799
800         if(rx_stats->bContainHTC) {
801                 LLCOffset += sHTCLng;
802         }
803         // Null packet, don't indicate it to upper layer
804         ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/
805
806         if( skb->len <= ChkLength ) {
807                 return 0;
808         }
809
810         skb_pull(skb, LLCOffset);
811         ieee->bIsAggregateFrame = bIsAggregateFrame;//added by amy for Leisure PS
812
813         if(!bIsAggregateFrame) {
814                 rxb->nr_subframes = 1;
815 #ifdef JOHN_NOCPY
816                 rxb->subframes[0] = skb;
817 #else
818                 rxb->subframes[0] = skb_copy(skb, GFP_ATOMIC);
819 #endif
820
821                 memcpy(rxb->src,src,ETH_ALEN);
822                 memcpy(rxb->dst,dst,ETH_ALEN);
823                 //IEEE80211_DEBUG_DATA(IEEE80211_DL_RX,skb->data,skb->len);
824                 return 1;
825         } else {
826                 rxb->nr_subframes = 0;
827                 memcpy(rxb->src,src,ETH_ALEN);
828                 memcpy(rxb->dst,dst,ETH_ALEN);
829                 while(skb->len > ETHERNET_HEADER_SIZE) {
830                         /* Offset 12 denote 2 mac address */
831                         nSubframe_Length = *((u16*)(skb->data + 12));
832                         //==m==>change the length order
833                         nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8);
834
835                         if(skb->len<(ETHERNET_HEADER_SIZE + nSubframe_Length)) {
836                                 printk("%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\
837                                                 __FUNCTION__,rxb->nr_subframes);
838                                 printk("%s: A-MSDU parse error!! Subframe Length: %d\n",__FUNCTION__, nSubframe_Length);
839                                 printk("nRemain_Length is %d and nSubframe_Length is : %d\n",skb->len,nSubframe_Length);
840                                 printk("The Packet SeqNum is %d\n",SeqNum);
841                                 return 0;
842                         }
843
844                         /* move the data point to data content */
845                         skb_pull(skb, ETHERNET_HEADER_SIZE);
846
847 #ifdef JOHN_NOCPY
848                         sub_skb = skb_clone(skb, GFP_ATOMIC);
849                         sub_skb->len = nSubframe_Length;
850                         sub_skb->tail = sub_skb->data + nSubframe_Length;
851 #else
852                         /* Allocate new skb for releasing to upper layer */
853                         sub_skb = dev_alloc_skb(nSubframe_Length + 12);
854                         skb_reserve(sub_skb, 12);
855                         data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length);
856                         memcpy(data_ptr,skb->data,nSubframe_Length);
857 #endif
858                         rxb->subframes[rxb->nr_subframes++] = sub_skb;
859                         if(rxb->nr_subframes >= MAX_SUBFRAME_COUNT) {
860                                 IEEE80211_DEBUG_RX("ParseSubframe(): Too many Subframes! Packets dropped!\n");
861                                 break;
862                         }
863                         skb_pull(skb,nSubframe_Length);
864
865                         if(skb->len != 0) {
866                                 nPadding_Length = 4 - ((nSubframe_Length + ETHERNET_HEADER_SIZE) % 4);
867                                 if(nPadding_Length == 4) {
868                                         nPadding_Length = 0;
869                                 }
870
871                                 if(skb->len < nPadding_Length) {
872                                         return 0;
873                                 }
874
875                                 skb_pull(skb,nPadding_Length);
876                         }
877                 }
878 #ifdef JOHN_NOCPY
879                 dev_kfree_skb(skb);
880 #endif
881                 return rxb->nr_subframes;
882         }
883 }
884
885 /* All received frames are sent to this function. @skb contains the frame in
886  * IEEE 802.11 format, i.e., in the format it was sent over air.
887  * This function is called only as a tasklet (software IRQ). */
888 int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
889                  struct ieee80211_rx_stats *rx_stats)
890 {
891         struct net_device *dev = ieee->dev;
892         struct ieee80211_hdr_4addr *hdr;
893
894         size_t hdrlen;
895         u16 fc, type, stype, sc;
896         struct net_device_stats *stats;
897         unsigned int frag;
898         u8 *payload;
899         u16 ethertype;
900         //added by amy for reorder
901         u8      TID = 0;
902         u16     SeqNum = 0;
903         PRX_TS_RECORD pTS = NULL;
904         bool unicast_packet = false;
905         //added by amy for reorder
906 #ifdef NOT_YET
907         struct net_device *wds = NULL;
908         struct sk_buff *skb2 = NULL;
909         struct net_device *wds = NULL;
910         int frame_authorized = 0;
911         int from_assoc_ap = 0;
912         void *sta = NULL;
913 #endif
914         u8 dst[ETH_ALEN];
915         u8 src[ETH_ALEN];
916         u8 bssid[ETH_ALEN];
917         struct ieee80211_crypt_data *crypt = NULL;
918         int keyidx = 0;
919
920         int i;
921         struct ieee80211_rxb* rxb = NULL;
922         // cheat the the hdr type
923         hdr = (struct ieee80211_hdr_4addr *)skb->data;
924         stats = &ieee->stats;
925
926         if (skb->len < 10) {
927                 printk(KERN_INFO "%s: SKB length < 10\n",
928                        dev->name);
929                 goto rx_dropped;
930         }
931
932         fc = le16_to_cpu(hdr->frame_ctl);
933         type = WLAN_FC_GET_TYPE(fc);
934         stype = WLAN_FC_GET_STYPE(fc);
935         sc = le16_to_cpu(hdr->seq_ctl);
936
937         frag = WLAN_GET_SEQ_FRAG(sc);
938         hdrlen = ieee80211_get_hdrlen(fc);
939
940         if(HTCCheck(ieee, skb->data))
941         {
942                 if(net_ratelimit())
943                 printk("find HTCControl\n");
944                 hdrlen += 4;
945                 rx_stats->bContainHTC = 1;
946         }
947
948 #ifdef NOT_YET
949 #if WIRELESS_EXT > 15
950         /* Put this code here so that we avoid duplicating it in all
951          * Rx paths. - Jean II */
952 #ifdef IW_WIRELESS_SPY          /* defined in iw_handler.h */
953         /* If spy monitoring on */
954         if (iface->spy_data.spy_number > 0) {
955                 struct iw_quality wstats;
956                 wstats.level = rx_stats->rssi;
957                 wstats.noise = rx_stats->noise;
958                 wstats.updated = 6;     /* No qual value */
959                 /* Update spy records */
960                 wireless_spy_update(dev, hdr->addr2, &wstats);
961         }
962 #endif /* IW_WIRELESS_SPY */
963 #endif /* WIRELESS_EXT > 15 */
964         hostap_update_rx_stats(local->ap, hdr, rx_stats);
965 #endif
966
967 #if WIRELESS_EXT > 15
968         if (ieee->iw_mode == IW_MODE_MONITOR) {
969                 ieee80211_monitor_rx(ieee, skb, rx_stats);
970                 stats->rx_packets++;
971                 stats->rx_bytes += skb->len;
972                 return 1;
973         }
974 #endif
975         if (ieee->host_decrypt) {
976                 int idx = 0;
977                 if (skb->len >= hdrlen + 3)
978                         idx = skb->data[hdrlen + 3] >> 6;
979                 crypt = ieee->crypt[idx];
980 #ifdef NOT_YET
981                 sta = NULL;
982
983                 /* Use station specific key to override default keys if the
984                  * receiver address is a unicast address ("individual RA"). If
985                  * bcrx_sta_key parameter is set, station specific key is used
986                  * even with broad/multicast targets (this is against IEEE
987                  * 802.11, but makes it easier to use different keys with
988                  * stations that do not support WEP key mapping). */
989
990                 if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
991                         (void) hostap_handle_sta_crypto(local, hdr, &crypt,
992                                                         &sta);
993 #endif
994
995                 /* allow NULL decrypt to indicate an station specific override
996                  * for default encryption */
997                 if (crypt && (crypt->ops == NULL ||
998                               crypt->ops->decrypt_mpdu == NULL))
999                         crypt = NULL;
1000
1001                 if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
1002                         /* This seems to be triggered by some (multicast?)
1003                          * frames from other than current BSS, so just drop the
1004                          * frames silently instead of filling system log with
1005                          * these reports. */
1006                         IEEE80211_DEBUG_DROP("Decryption failed (not set)"
1007                                              " (SA=%pM)\n",
1008                                              hdr->addr2);
1009                         ieee->ieee_stats.rx_discards_undecryptable++;
1010                         goto rx_dropped;
1011                 }
1012         }
1013
1014         if (skb->len < IEEE80211_DATA_HDR3_LEN)
1015                 goto rx_dropped;
1016
1017         // if QoS enabled, should check the sequence for each of the AC
1018         if( (ieee->pHTInfo->bCurRxReorderEnable == false) || !ieee->current_network.qos_data.active|| !IsDataFrame(skb->data) || IsLegacyDataFrame(skb->data)){
1019                 if (is_duplicate_packet(ieee, hdr))
1020                 goto rx_dropped;
1021
1022         }
1023         else
1024         {
1025                 PRX_TS_RECORD pRxTS = NULL;
1026
1027                 if(GetTs(
1028                                 ieee,
1029                                 (PTS_COMMON_INFO*) &pRxTS,
1030                                 hdr->addr2,
1031                                 (u8)Frame_QoSTID((u8*)(skb->data)),
1032                                 RX_DIR,
1033                                 true))
1034                 {
1035
1036                         if(     (fc & (1<<11))  &&
1037                                         (frag == pRxTS->RxLastFragNum) &&
1038                                         (WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum)   )
1039                         {
1040                                 goto rx_dropped;
1041                         }
1042                         else
1043                         {
1044                                 pRxTS->RxLastFragNum = frag;
1045                                 pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc);
1046                         }
1047                 }
1048                 else
1049                 {
1050                         IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s(): No TS!! Skip the check!!\n",__FUNCTION__);
1051                         goto rx_dropped;
1052                 }
1053         }
1054
1055         if (type == IEEE80211_FTYPE_MGMT) {
1056
1057                 if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
1058                         goto rx_dropped;
1059                 else
1060                         goto rx_exit;
1061         }
1062
1063         /* Data frame - extract src/dst addresses */
1064         switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
1065         case IEEE80211_FCTL_FROMDS:
1066                 memcpy(dst, hdr->addr1, ETH_ALEN);
1067                 memcpy(src, hdr->addr3, ETH_ALEN);
1068                 memcpy(bssid, hdr->addr2, ETH_ALEN);
1069                 break;
1070         case IEEE80211_FCTL_TODS:
1071                 memcpy(dst, hdr->addr3, ETH_ALEN);
1072                 memcpy(src, hdr->addr2, ETH_ALEN);
1073                 memcpy(bssid, hdr->addr1, ETH_ALEN);
1074                 break;
1075         case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
1076                 if (skb->len < IEEE80211_DATA_HDR4_LEN)
1077                         goto rx_dropped;
1078                 memcpy(dst, hdr->addr3, ETH_ALEN);
1079                 memcpy(src, hdr->addr4, ETH_ALEN);
1080                 memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
1081                 break;
1082         case 0:
1083                 memcpy(dst, hdr->addr1, ETH_ALEN);
1084                 memcpy(src, hdr->addr2, ETH_ALEN);
1085                 memcpy(bssid, hdr->addr3, ETH_ALEN);
1086                 break;
1087         }
1088
1089 #ifdef NOT_YET
1090         if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
1091                 goto rx_dropped;
1092         if (wds) {
1093                 skb->dev = dev = wds;
1094                 stats = hostap_get_stats(dev);
1095         }
1096
1097         if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
1098             (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
1099             ieee->stadev &&
1100             memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
1101                 /* Frame from BSSID of the AP for which we are a client */
1102                 skb->dev = dev = ieee->stadev;
1103                 stats = hostap_get_stats(dev);
1104                 from_assoc_ap = 1;
1105         }
1106 #endif
1107
1108         dev->last_rx = jiffies;
1109
1110 #ifdef NOT_YET
1111         if ((ieee->iw_mode == IW_MODE_MASTER ||
1112              ieee->iw_mode == IW_MODE_REPEAT) &&
1113             !from_assoc_ap) {
1114                 switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
1115                                              wds != NULL)) {
1116                 case AP_RX_CONTINUE_NOT_AUTHORIZED:
1117                         frame_authorized = 0;
1118                         break;
1119                 case AP_RX_CONTINUE:
1120                         frame_authorized = 1;
1121                         break;
1122                 case AP_RX_DROP:
1123                         goto rx_dropped;
1124                 case AP_RX_EXIT:
1125                         goto rx_exit;
1126                 }
1127         }
1128 #endif
1129         /* Nullfunc frames may have PS-bit set, so they must be passed to
1130          * hostap_handle_sta_rx() before being dropped here. */
1131         if (stype != IEEE80211_STYPE_DATA &&
1132             stype != IEEE80211_STYPE_DATA_CFACK &&
1133             stype != IEEE80211_STYPE_DATA_CFPOLL &&
1134             stype != IEEE80211_STYPE_DATA_CFACKPOLL&&
1135             stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
1136             ) {
1137                 if (stype != IEEE80211_STYPE_NULLFUNC)
1138                         IEEE80211_DEBUG_DROP(
1139                                 "RX: dropped data frame "
1140                                 "with no data (type=0x%02x, "
1141                                 "subtype=0x%02x, len=%d)\n",
1142                                 type, stype, skb->len);
1143                 goto rx_dropped;
1144         }
1145         if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
1146                 goto rx_dropped;
1147
1148 #ifdef ENABLE_LPS
1149         if ((ieee->iw_mode == IW_MODE_INFRA)  && (ieee->sta_sleep == 1)
1150                 && (ieee->polling)) {
1151                 if (WLAN_FC_MORE_DATA(fc)) {
1152                         /* more data bit is set, let's request a new frame from the AP */
1153                         ieee80211_sta_ps_send_pspoll_frame(ieee);
1154                 } else {
1155                         ieee->polling =  false;
1156                 }
1157         }
1158 #endif
1159
1160         ieee->need_sw_enc = 0;
1161
1162         if((!rx_stats->Decrypted)){
1163                 ieee->need_sw_enc = 1;
1164         }
1165
1166         /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
1167
1168         if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
1169             (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
1170         {
1171                 printk("decrypt frame error\n");
1172                 goto rx_dropped;
1173         }
1174
1175
1176         hdr = (struct ieee80211_hdr_4addr *) skb->data;
1177
1178         /* skb: hdr + (possibly fragmented) plaintext payload */
1179         // PR: FIXME: hostap has additional conditions in the "if" below:
1180         // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
1181         if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
1182                 int flen;
1183                 struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
1184                 IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
1185
1186                 if (!frag_skb) {
1187                         IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
1188                                         "Rx cannot get skb from fragment "
1189                                         "cache (morefrag=%d seq=%u frag=%u)\n",
1190                                         (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
1191                                         WLAN_GET_SEQ_SEQ(sc), frag);
1192                         goto rx_dropped;
1193                 }
1194                 flen = skb->len;
1195                 if (frag != 0)
1196                         flen -= hdrlen;
1197
1198                 if (frag_skb->tail + flen > frag_skb->end) {
1199                         printk(KERN_WARNING "%s: host decrypted and "
1200                                "reassembled frame did not fit skb\n",
1201                                dev->name);
1202                         ieee80211_frag_cache_invalidate(ieee, hdr);
1203                         goto rx_dropped;
1204                 }
1205
1206                 if (frag == 0) {
1207                         /* copy first fragment (including full headers) into
1208                          * beginning of the fragment cache skb */
1209                         memcpy(skb_put(frag_skb, flen), skb->data, flen);
1210                 } else {
1211                         /* append frame payload to the end of the fragment
1212                          * cache skb */
1213                         memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
1214                                flen);
1215                 }
1216                 dev_kfree_skb_any(skb);
1217                 skb = NULL;
1218
1219                 if (fc & IEEE80211_FCTL_MOREFRAGS) {
1220                         /* more fragments expected - leave the skb in fragment
1221                          * cache for now; it will be delivered to upper layers
1222                          * after all fragments have been received */
1223                         goto rx_exit;
1224                 }
1225
1226                 /* this was the last fragment and the frame will be
1227                  * delivered, so remove skb from fragment cache */
1228                 skb = frag_skb;
1229                 hdr = (struct ieee80211_hdr_4addr *) skb->data;
1230                 ieee80211_frag_cache_invalidate(ieee, hdr);
1231         }
1232
1233         /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
1234          * encrypted/authenticated */
1235         if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
1236             ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
1237         {
1238                 printk("==>decrypt msdu error\n");
1239                 goto rx_dropped;
1240         }
1241
1242         //added by amy for AP roaming
1243         ieee->LinkDetectInfo.NumRecvDataInPeriod++;
1244         ieee->LinkDetectInfo.NumRxOkInPeriod++;
1245
1246         hdr = (struct ieee80211_hdr_4addr *) skb->data;
1247         if((!is_multicast_ether_addr(hdr->addr1)) && (!is_broadcast_ether_addr(hdr->addr1)))
1248                 unicast_packet = true;
1249
1250         if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
1251                 if (/*ieee->ieee802_1x &&*/
1252                     ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
1253
1254 #ifdef CONFIG_IEEE80211_DEBUG
1255                         /* pass unencrypted EAPOL frames even if encryption is
1256                          * configured */
1257                         struct eapol *eap = (struct eapol *)(skb->data +
1258                                 24);
1259                         IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
1260                                                 eap_get_type(eap->type));
1261 #endif
1262                 } else {
1263                         IEEE80211_DEBUG_DROP(
1264                                 "encryption configured, but RX "
1265                                 "frame not encrypted (SA=%pM)\n",
1266                                 hdr->addr2);
1267                         goto rx_dropped;
1268                 }
1269         }
1270
1271 #ifdef CONFIG_IEEE80211_DEBUG
1272         if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
1273             ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
1274                         struct eapol *eap = (struct eapol *)(skb->data +
1275                                 24);
1276                         IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
1277                                                 eap_get_type(eap->type));
1278         }
1279 #endif
1280
1281         if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
1282             !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
1283                 IEEE80211_DEBUG_DROP(
1284                         "dropped unencrypted RX data "
1285                         "frame from %pM"
1286                         " (drop_unencrypted=1)\n",
1287                         hdr->addr2);
1288                 goto rx_dropped;
1289         }
1290 //added by amy for reorder
1291         if(ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data)
1292                 && !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1))
1293         {
1294                 TID = Frame_QoSTID(skb->data);
1295                 SeqNum = WLAN_GET_SEQ_SEQ(sc);
1296                 GetTs(ieee,(PTS_COMMON_INFO*) &pTS,hdr->addr2,TID,RX_DIR,true);
1297                 if(TID !=0 && TID !=3)
1298                 {
1299                         ieee->bis_any_nonbepkts = true;
1300                 }
1301         }
1302
1303 //added by amy for reorder
1304         /* skb: hdr + (possible reassembled) full plaintext payload */
1305         payload = skb->data + hdrlen;
1306
1307         rxb = kmalloc(sizeof(struct ieee80211_rxb), GFP_ATOMIC);
1308         if(rxb == NULL)
1309         {
1310                 IEEE80211_DEBUG(IEEE80211_DL_ERR,"%s(): kmalloc rxb error\n",__FUNCTION__);
1311                 goto rx_dropped;
1312         }
1313         /* to parse amsdu packets */
1314         /* qos data packets & reserved bit is 1 */
1315         if(parse_subframe(ieee, skb,rx_stats,rxb,src,dst) == 0) {
1316                 /* only to free rxb, and not submit the packets to upper layer */
1317                 for(i =0; i < rxb->nr_subframes; i++) {
1318                         dev_kfree_skb(rxb->subframes[i]);
1319                 }
1320                 kfree(rxb);
1321                 rxb = NULL;
1322                 goto rx_dropped;
1323         }
1324
1325 #ifdef ENABLE_LPS
1326                 if(unicast_packet)
1327                 {
1328                         if (type == IEEE80211_FTYPE_DATA)
1329                         {
1330
1331                                 if(ieee->bIsAggregateFrame)
1332                                         ieee->LinkDetectInfo.NumRxUnicastOkInPeriod+=rxb->nr_subframes;
1333                                 else
1334                                         ieee->LinkDetectInfo.NumRxUnicastOkInPeriod++;
1335
1336                                 // 2009.03.03 Leave DC mode immediately when detect high traffic
1337                                 if((ieee->state == IEEE80211_LINKED) /*&& !MgntInitAdapterInProgress(pMgntInfo)*/)
1338                                 {
1339                                         if(     ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod +ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
1340                                                 (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
1341                                         {
1342                                                 if(ieee->LeisurePSLeave)
1343                                                         ieee->LeisurePSLeave(ieee);
1344                                         }
1345                                 }
1346                         }
1347                 }
1348 #endif
1349
1350         ieee->last_rx_ps_time = jiffies;
1351 //added by amy for reorder
1352         if(ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL){
1353 //added by amy for reorder
1354                 for(i = 0; i<rxb->nr_subframes; i++) {
1355                         struct sk_buff *sub_skb = rxb->subframes[i];
1356
1357                         if (sub_skb) {
1358                                 /* convert hdr + possible LLC headers into Ethernet header */
1359                                 ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
1360                                 if (sub_skb->len >= 8 &&
1361                                                 ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
1362                                                   ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
1363                                                  memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
1364                                         /* remove RFC1042 or Bridge-Tunnel encapsulation and
1365                                          * replace EtherType */
1366                                         skb_pull(sub_skb, SNAP_SIZE);
1367                                         memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
1368                                         memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
1369                                 } else {
1370                                         u16 len;
1371                                         /* Leave Ethernet header part of hdr and full payload */
1372                                         len = htons(sub_skb->len);
1373                                         memcpy(skb_push(sub_skb, 2), &len, 2);
1374                                         memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
1375                                         memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
1376                                 }
1377
1378                                 stats->rx_packets++;
1379                                 stats->rx_bytes += sub_skb->len;
1380                                 if(is_multicast_ether_addr(dst)) {
1381                                         stats->multicast++;
1382                                 }
1383
1384                                 /* Indicat the packets to upper layer */
1385                                 sub_skb->protocol = eth_type_trans(sub_skb, dev);
1386                                 memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
1387                                 sub_skb->dev = dev;
1388                                 sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
1389                                 netif_rx(sub_skb);
1390                         }
1391                 }
1392                 kfree(rxb);
1393                 rxb = NULL;
1394
1395         }
1396         else
1397         {
1398                 IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): REORDER ENABLE AND PTS not NULL, and we will enter RxReorderIndicatePacket()\n",__FUNCTION__);
1399                 RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum);
1400         }
1401 #ifndef JOHN_NOCPY
1402         dev_kfree_skb(skb);
1403 #endif
1404
1405  rx_exit:
1406 #ifdef NOT_YET
1407         if (sta)
1408                 hostap_handle_sta_release(sta);
1409 #endif
1410         return 1;
1411
1412  rx_dropped:
1413         kfree(rxb);
1414         rxb = NULL;
1415         stats->rx_dropped++;
1416
1417         /* Returning 0 indicates to caller that we have not handled the SKB--
1418          * so it is still allocated and can be used again by underlying
1419          * hardware as a DMA target */
1420         return 0;
1421 }
1422
1423 #define MGMT_FRAME_FIXED_PART_LENGTH            0x24
1424
1425 static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
1426
1427 /*
1428 * Make the structure we read from the beacon packet to have
1429 * the right values
1430 */
1431 static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
1432                                      *info_element, int sub_type)
1433 {
1434
1435         if (info_element->qui_subtype != sub_type)
1436                 return -1;
1437         if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
1438                 return -1;
1439         if (info_element->qui_type != QOS_OUI_TYPE)
1440                 return -1;
1441         if (info_element->version != QOS_VERSION_1)
1442                 return -1;
1443
1444         return 0;
1445 }
1446
1447
1448 /*
1449  * Parse a QoS parameter element
1450  */
1451 static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
1452                                             *element_param, struct ieee80211_info_element
1453                                             *info_element)
1454 {
1455         int ret = 0;
1456         u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2;
1457
1458         if ((info_element == NULL) || (element_param == NULL))
1459                 return -1;
1460
1461         if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
1462                 memcpy(element_param->info_element.qui, info_element->data,
1463                        info_element->len);
1464                 element_param->info_element.elementID = info_element->id;
1465                 element_param->info_element.length = info_element->len;
1466         } else
1467                 ret = -1;
1468         if (ret == 0)
1469                 ret = ieee80211_verify_qos_info(&element_param->info_element,
1470                                                 QOS_OUI_PARAM_SUB_TYPE);
1471         return ret;
1472 }
1473
1474 /*
1475  * Parse a QoS information element
1476  */
1477 static int ieee80211_read_qos_info_element(struct
1478                                            ieee80211_qos_information_element
1479                                            *element_info, struct ieee80211_info_element
1480                                            *info_element)
1481 {
1482         int ret = 0;
1483         u16 size = sizeof(struct ieee80211_qos_information_element) - 2;
1484
1485         if (element_info == NULL)
1486                 return -1;
1487         if (info_element == NULL)
1488                 return -1;
1489
1490         if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
1491                 memcpy(element_info->qui, info_element->data,
1492                        info_element->len);
1493                 element_info->elementID = info_element->id;
1494                 element_info->length = info_element->len;
1495         } else
1496                 ret = -1;
1497
1498         if (ret == 0)
1499                 ret = ieee80211_verify_qos_info(element_info,
1500                                                 QOS_OUI_INFO_SUB_TYPE);
1501         return ret;
1502 }
1503
1504
1505 /*
1506  * Write QoS parameters from the ac parameters.
1507  */
1508 static int ieee80211_qos_convert_ac_to_parameters(struct
1509                                                   ieee80211_qos_parameter_info
1510                                                   *param_elm, struct
1511                                                   ieee80211_qos_parameters
1512                                                   *qos_param)
1513 {
1514         int rc = 0;
1515         int i;
1516         struct ieee80211_qos_ac_parameter *ac_params;
1517         u8 aci;
1518
1519         for (i = 0; i < QOS_QUEUE_NUM; i++) {
1520                 ac_params = &(param_elm->ac_params_record[i]);
1521
1522                 aci = (ac_params->aci_aifsn & 0x60) >> 5;
1523
1524                 if(aci >= QOS_QUEUE_NUM)
1525                         continue;
1526                 qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f;
1527
1528                 /* WMM spec P.11: The minimum value for AIFSN shall be 2 */
1529                 qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2:qos_param->aifs[aci];
1530
1531                 qos_param->cw_min[aci] = ac_params->ecw_min_max & 0x0F;
1532
1533                 qos_param->cw_max[aci] = (ac_params->ecw_min_max & 0xF0) >> 4;
1534
1535                 qos_param->flag[aci] =
1536                     (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
1537                 qos_param->tx_op_limit[aci] = le16_to_cpu(ac_params->tx_op_limit);
1538         }
1539         return rc;
1540 }
1541
1542 /*
1543  * we have a generic data element which it may contain QoS information or
1544  * parameters element. check the information element length to decide
1545  * which type to read
1546  */
1547 static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
1548                                              *info_element,
1549                                              struct ieee80211_network *network)
1550 {
1551         int rc = 0;
1552         struct ieee80211_qos_parameters *qos_param = NULL;
1553         struct ieee80211_qos_information_element qos_info_element;
1554
1555         rc = ieee80211_read_qos_info_element(&qos_info_element, info_element);
1556
1557         if (rc == 0) {
1558                 network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
1559                 network->flags |= NETWORK_HAS_QOS_INFORMATION;
1560         } else {
1561                 struct ieee80211_qos_parameter_info param_element;
1562
1563                 rc = ieee80211_read_qos_param_element(&param_element,
1564                                                       info_element);
1565                 if (rc == 0) {
1566                         qos_param = &(network->qos_data.parameters);
1567                         ieee80211_qos_convert_ac_to_parameters(&param_element,
1568                                                                qos_param);
1569                         network->flags |= NETWORK_HAS_QOS_PARAMETERS;
1570                         network->qos_data.param_count =
1571                             param_element.info_element.ac_info & 0x0F;
1572                 }
1573         }
1574
1575         if (rc == 0) {
1576                 IEEE80211_DEBUG_QOS("QoS is supported\n");
1577                 network->qos_data.supported = 1;
1578         }
1579         return rc;
1580 }
1581
1582 #ifdef CONFIG_IEEE80211_DEBUG
1583 #define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
1584
1585 static const char *get_info_element_string(u16 id)
1586 {
1587         switch (id) {
1588                 MFIE_STRING(SSID);
1589                 MFIE_STRING(RATES);
1590                 MFIE_STRING(FH_SET);
1591                 MFIE_STRING(DS_SET);
1592                 MFIE_STRING(CF_SET);
1593                 MFIE_STRING(TIM);
1594                 MFIE_STRING(IBSS_SET);
1595                 MFIE_STRING(COUNTRY);
1596                 MFIE_STRING(HOP_PARAMS);
1597                 MFIE_STRING(HOP_TABLE);
1598                 MFIE_STRING(REQUEST);
1599                 MFIE_STRING(CHALLENGE);
1600                 MFIE_STRING(POWER_CONSTRAINT);
1601                 MFIE_STRING(POWER_CAPABILITY);
1602                 MFIE_STRING(TPC_REQUEST);
1603                 MFIE_STRING(TPC_REPORT);
1604                 MFIE_STRING(SUPP_CHANNELS);
1605                 MFIE_STRING(CSA);
1606                 MFIE_STRING(MEASURE_REQUEST);
1607                 MFIE_STRING(MEASURE_REPORT);
1608                 MFIE_STRING(QUIET);
1609                 MFIE_STRING(IBSS_DFS);
1610                // MFIE_STRING(ERP_INFO);
1611                 MFIE_STRING(RSN);
1612                 MFIE_STRING(RATES_EX);
1613                 MFIE_STRING(GENERIC);
1614                 MFIE_STRING(QOS_PARAMETER);
1615         default:
1616                 return "UNKNOWN";
1617         }
1618 }
1619 #endif
1620
1621 #ifdef ENABLE_DOT11D
1622 static inline void ieee80211_extract_country_ie(
1623         struct ieee80211_device *ieee,
1624         struct ieee80211_info_element *info_element,
1625         struct ieee80211_network *network,
1626         u8 * addr2
1627 )
1628 {
1629         if(IS_DOT11D_ENABLE(ieee))
1630         {
1631                 if(info_element->len!= 0)
1632                 {
1633                         memcpy(network->CountryIeBuf, info_element->data, info_element->len);
1634                         network->CountryIeLen = info_element->len;
1635
1636                         if(!IS_COUNTRY_IE_VALID(ieee))
1637                         {
1638                                 Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
1639                         }
1640                 }
1641
1642                 //
1643                 // 070305, rcnjko: I update country IE watch dog here because
1644                 // some AP (e.g. Cisco 1242) don't include country IE in their
1645                 // probe response frame.
1646                 //
1647                 if(IS_EQUAL_CIE_SRC(ieee, addr2) )
1648                 {
1649                         UPDATE_CIE_WATCHDOG(ieee);
1650                 }
1651         }
1652
1653 }
1654 #endif
1655
1656 int ieee80211_parse_info_param(struct ieee80211_device *ieee,
1657                 struct ieee80211_info_element *info_element,
1658                 u16 length,
1659                 struct ieee80211_network *network,
1660                 struct ieee80211_rx_stats *stats)
1661 {
1662         u8 i;
1663         short offset;
1664         u16     tmp_htcap_len=0;
1665         u16     tmp_htinfo_len=0;
1666         u16 ht_realtek_agg_len=0;
1667         u8  ht_realtek_agg_buf[MAX_IE_LEN];
1668 #ifdef CONFIG_IEEE80211_DEBUG
1669         char rates_str[64];
1670         char *p;
1671 #endif
1672
1673         while (length >= sizeof(*info_element)) {
1674                 if (sizeof(*info_element) + info_element->len > length) {
1675                         IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
1676                                              "info_element->len + 2 > left : "
1677                                              "info_element->len+2=%zd left=%d, id=%d.\n",
1678                                              info_element->len +
1679                                              sizeof(*info_element),
1680                                              length, info_element->id);
1681                         /* We stop processing but don't return an error here
1682                          * because some misbehaviour APs break this rule. ie.
1683                          * Orinoco AP1000. */
1684                         break;
1685                 }
1686
1687                 switch (info_element->id) {
1688                 case MFIE_TYPE_SSID:
1689                         if (ieee80211_is_empty_essid(info_element->data,
1690                                                      info_element->len)) {
1691                                 network->flags |= NETWORK_EMPTY_ESSID;
1692                                 break;
1693                         }
1694
1695                         network->ssid_len = min(info_element->len,
1696                                                 (u8) IW_ESSID_MAX_SIZE);
1697                         memcpy(network->ssid, info_element->data, network->ssid_len);
1698                         if (network->ssid_len < IW_ESSID_MAX_SIZE)
1699                                 memset(network->ssid + network->ssid_len, 0,
1700                                        IW_ESSID_MAX_SIZE - network->ssid_len);
1701
1702                         IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
1703                                              network->ssid, network->ssid_len);
1704                         break;
1705
1706                 case MFIE_TYPE_RATES:
1707 #ifdef CONFIG_IEEE80211_DEBUG
1708                         p = rates_str;
1709 #endif
1710                         network->rates_len = min(info_element->len,
1711                                                  MAX_RATES_LENGTH);
1712                         for (i = 0; i < network->rates_len; i++) {
1713                                 network->rates[i] = info_element->data[i];
1714 #ifdef CONFIG_IEEE80211_DEBUG
1715                                 p += snprintf(p, sizeof(rates_str) -
1716                                               (p - rates_str), "%02X ",
1717                                               network->rates[i]);
1718 #endif
1719                                 if (ieee80211_is_ofdm_rate
1720                                     (info_element->data[i])) {
1721                                         network->flags |= NETWORK_HAS_OFDM;
1722                                         if (info_element->data[i] &
1723                                             IEEE80211_BASIC_RATE_MASK)
1724                                                 network->flags &=
1725                                                     ~NETWORK_HAS_CCK;
1726                                 }
1727                         }
1728
1729                         IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
1730                                              rates_str, network->rates_len);
1731                         break;
1732
1733                 case MFIE_TYPE_RATES_EX:
1734 #ifdef CONFIG_IEEE80211_DEBUG
1735                         p = rates_str;
1736 #endif
1737                         network->rates_ex_len = min(info_element->len,
1738                                                     MAX_RATES_EX_LENGTH);
1739                         for (i = 0; i < network->rates_ex_len; i++) {
1740                                 network->rates_ex[i] = info_element->data[i];
1741 #ifdef CONFIG_IEEE80211_DEBUG
1742                                 p += snprintf(p, sizeof(rates_str) -
1743                                               (p - rates_str), "%02X ",
1744                                               network->rates[i]);
1745 #endif
1746                                 if (ieee80211_is_ofdm_rate
1747                                     (info_element->data[i])) {
1748                                         network->flags |= NETWORK_HAS_OFDM;
1749                                         if (info_element->data[i] &
1750                                             IEEE80211_BASIC_RATE_MASK)
1751                                                 network->flags &=
1752                                                     ~NETWORK_HAS_CCK;
1753                                 }
1754                         }
1755
1756                         IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
1757                                              rates_str, network->rates_ex_len);
1758                         break;
1759
1760                 case MFIE_TYPE_DS_SET:
1761                         IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
1762                                              info_element->data[0]);
1763                         network->channel = info_element->data[0];
1764                         break;
1765
1766                 case MFIE_TYPE_FH_SET:
1767                         IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
1768                         break;
1769
1770                 case MFIE_TYPE_CF_SET:
1771                         IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
1772                         break;
1773
1774                 case MFIE_TYPE_TIM:
1775                         if(info_element->len < 4)
1776                                 break;
1777
1778                         network->tim.tim_count = info_element->data[0];
1779                         network->tim.tim_period = info_element->data[1];
1780
1781                         network->dtim_period = info_element->data[1];
1782                         if(ieee->state != IEEE80211_LINKED)
1783                                 break;
1784                         //we use jiffies for legacy Power save
1785                         network->last_dtim_sta_time[0] = jiffies;
1786                         network->last_dtim_sta_time[1] = stats->mac_time[1];
1787
1788                         network->dtim_data = IEEE80211_DTIM_VALID;
1789
1790                         if(info_element->data[0] != 0)
1791                                 break;
1792
1793                         if(info_element->data[2] & 1)
1794                                 network->dtim_data |= IEEE80211_DTIM_MBCAST;
1795
1796                         offset = (info_element->data[2] >> 1)*2;
1797
1798                         if(ieee->assoc_id < 8*offset ||
1799                                 ieee->assoc_id > 8*(offset + info_element->len -3))
1800
1801                                 break;
1802
1803                         offset = (ieee->assoc_id / 8) - offset;// + ((aid % 8)? 0 : 1) ;
1804
1805                         if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
1806                                 network->dtim_data |= IEEE80211_DTIM_UCAST;
1807
1808                         break;
1809
1810                 case MFIE_TYPE_ERP:
1811                         network->erp_value = info_element->data[0];
1812                         network->flags |= NETWORK_HAS_ERP_VALUE;
1813                         IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
1814                                              network->erp_value);
1815                         break;
1816                 case MFIE_TYPE_IBSS_SET:
1817                         network->atim_window = info_element->data[0];
1818                         IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
1819                                              network->atim_window);
1820                         break;
1821
1822                 case MFIE_TYPE_CHALLENGE:
1823                         IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
1824                         break;
1825
1826                 case MFIE_TYPE_GENERIC:
1827                         IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
1828                                              info_element->len);
1829                         if (!ieee80211_parse_qos_info_param_IE(info_element,
1830                                                                network))
1831                                 break;
1832
1833                         if (info_element->len >= 4 &&
1834                             info_element->data[0] == 0x00 &&
1835                             info_element->data[1] == 0x50 &&
1836                             info_element->data[2] == 0xf2 &&
1837                             info_element->data[3] == 0x01) {
1838                                 network->wpa_ie_len = min(info_element->len + 2,
1839                                                           MAX_WPA_IE_LEN);
1840                                 memcpy(network->wpa_ie, info_element,
1841                                        network->wpa_ie_len);
1842                                 break;
1843                         }
1844
1845 #ifdef THOMAS_TURBO
1846                         if (info_element->len == 7 &&
1847                             info_element->data[0] == 0x00 &&
1848                             info_element->data[1] == 0xe0 &&
1849                             info_element->data[2] == 0x4c &&
1850                             info_element->data[3] == 0x01 &&
1851                             info_element->data[4] == 0x02) {
1852                                 network->Turbo_Enable = 1;
1853                         }
1854 #endif
1855
1856                         //for HTcap and HTinfo parameters
1857                         if(tmp_htcap_len == 0){
1858                                 if(info_element->len >= 4 &&
1859                                    info_element->data[0] == 0x00 &&
1860                                    info_element->data[1] == 0x90 &&
1861                                    info_element->data[2] == 0x4c &&
1862                                    info_element->data[3] == 0x033){
1863
1864                                                 tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
1865                                                 if(tmp_htcap_len != 0){
1866                                                         network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
1867                                                         network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
1868                                                                 sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
1869                                                         memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);
1870                                                 }
1871                                 }
1872                                 if(tmp_htcap_len != 0)
1873                                         network->bssht.bdSupportHT = true;
1874                                 else
1875                                         network->bssht.bdSupportHT = false;
1876                         }
1877
1878
1879                         if(tmp_htinfo_len == 0){
1880                                 if(info_element->len >= 4 &&
1881                                         info_element->data[0] == 0x00 &&
1882                                         info_element->data[1] == 0x90 &&
1883                                         info_element->data[2] == 0x4c &&
1884                                         info_element->data[3] == 0x034){
1885
1886                                                 tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
1887                                                 if(tmp_htinfo_len != 0){
1888                                                         network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
1889                                                         if(tmp_htinfo_len){
1890                                                                 network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
1891                                                                         sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
1892                                                                 memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
1893                                                         }
1894
1895                                                 }
1896
1897                                 }
1898                         }
1899
1900                         if(ieee->aggregation){
1901                                 if(network->bssht.bdSupportHT){
1902                                         if(info_element->len >= 4 &&
1903                                                 info_element->data[0] == 0x00 &&
1904                                                 info_element->data[1] == 0xe0 &&
1905                                                 info_element->data[2] == 0x4c &&
1906                                                 info_element->data[3] == 0x02){
1907
1908                                                 ht_realtek_agg_len = min(info_element->len,(u8)MAX_IE_LEN);
1909                                                 memcpy(ht_realtek_agg_buf,info_element->data,info_element->len);
1910
1911                                         }
1912                                         if(ht_realtek_agg_len >= 5){
1913                                                 network->bssht.bdRT2RTAggregation = true;
1914
1915                                                 if((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02))
1916                                                 network->bssht.bdRT2RTLongSlotTime = true;
1917                                         }
1918                                 }
1919
1920                         }
1921
1922                                 if((info_element->len >= 3 &&
1923                                          info_element->data[0] == 0x00 &&
1924                                          info_element->data[1] == 0x05 &&
1925                                          info_element->data[2] == 0xb5) ||
1926                                          (info_element->len >= 3 &&
1927                                          info_element->data[0] == 0x00 &&
1928                                          info_element->data[1] == 0x0a &&
1929                                          info_element->data[2] == 0xf7) ||
1930                                          (info_element->len >= 3 &&
1931                                          info_element->data[0] == 0x00 &&
1932                                          info_element->data[1] == 0x10 &&
1933                                          info_element->data[2] == 0x18)){
1934
1935                                                 network->broadcom_cap_exist = true;
1936
1937                                 }
1938
1939                         if(info_element->len >= 3 &&
1940                                 info_element->data[0] == 0x00 &&
1941                                 info_element->data[1] == 0x0c &&
1942                                 info_element->data[2] == 0x43)
1943                         {
1944                                 network->ralink_cap_exist = true;
1945                         }
1946                         else
1947                                 network->ralink_cap_exist = false;
1948                         //added by amy for atheros AP
1949                         if((info_element->len >= 3 &&
1950                                 info_element->data[0] == 0x00 &&
1951                                 info_element->data[1] == 0x03 &&
1952                                 info_element->data[2] == 0x7f) ||
1953                                 (info_element->len >= 3 &&
1954                                 info_element->data[0] == 0x00 &&
1955                                 info_element->data[1] == 0x13 &&
1956                                 info_element->data[2] == 0x74))
1957                         {
1958                                 network->atheros_cap_exist = true;
1959                         }
1960                         else
1961                                 network->atheros_cap_exist = false;
1962
1963                         if ((info_element->len >= 3 &&
1964                                                 info_element->data[0] == 0x00 &&
1965                                                 info_element->data[1] == 0x50 &&
1966                                                 info_element->data[2] == 0x43) )
1967                         {
1968                                 network->marvell_cap_exist = true;
1969                         }
1970
1971
1972                         if(info_element->len >= 3 &&
1973                                 info_element->data[0] == 0x00 &&
1974                                 info_element->data[1] == 0x40 &&
1975                                 info_element->data[2] == 0x96)
1976                         {
1977                                 network->cisco_cap_exist = true;
1978                         }
1979                         else
1980                                 network->cisco_cap_exist = false;
1981                         //added by amy for LEAP of cisco
1982                         if(info_element->len > 4 &&
1983                                 info_element->data[0] == 0x00 &&
1984                                 info_element->data[1] == 0x40 &&
1985                                 info_element->data[2] == 0x96 &&
1986                                 info_element->data[3] == 0x01)
1987                         {
1988                                 if(info_element->len == 6)
1989                                 {
1990                                         memcpy(network->CcxRmState, &info_element[4], 2);
1991                                         if(network->CcxRmState[0] != 0)
1992                                         {
1993                                                 network->bCcxRmEnable = true;
1994                                         }
1995                                         else
1996                                                 network->bCcxRmEnable = false;
1997                                         //
1998                                         // CCXv4 Table 59-1 MBSSID Masks.
1999                                         //
2000                                         network->MBssidMask = network->CcxRmState[1] & 0x07;
2001                                         if(network->MBssidMask != 0)
2002                                         {
2003                                                 network->bMBssidValid = true;
2004                                                 network->MBssidMask = 0xff << (network->MBssidMask);
2005                                                 cpMacAddr(network->MBssid, network->bssid);
2006                                                 network->MBssid[5] &= network->MBssidMask;
2007                                         }
2008                                         else
2009                                         {
2010                                                 network->bMBssidValid = false;
2011                                         }
2012                                 }
2013                                 else
2014                                 {
2015                                         network->bCcxRmEnable = false;
2016                                 }
2017                         }
2018                         if(info_element->len > 4  &&
2019                                 info_element->data[0] == 0x00 &&
2020                                 info_element->data[1] == 0x40 &&
2021                                 info_element->data[2] == 0x96 &&
2022                                 info_element->data[3] == 0x03)
2023                         {
2024                                 if(info_element->len == 5)
2025                                 {
2026                                         network->bWithCcxVerNum = true;
2027                                         network->BssCcxVerNumber = info_element->data[4];
2028                                 }
2029                                 else
2030                                 {
2031                                         network->bWithCcxVerNum = false;
2032                                         network->BssCcxVerNumber = 0;
2033                                 }
2034                         }
2035                         break;
2036
2037                 case MFIE_TYPE_RSN:
2038                         IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
2039                                              info_element->len);
2040                         network->rsn_ie_len = min(info_element->len + 2,
2041                                                   MAX_WPA_IE_LEN);
2042                         memcpy(network->rsn_ie, info_element,
2043                                network->rsn_ie_len);
2044                         break;
2045
2046                         //HT related element.
2047                 case MFIE_TYPE_HT_CAP:
2048                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n",
2049                                              info_element->len);
2050                         tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
2051                         if(tmp_htcap_len != 0){
2052                                 network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
2053                                 network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
2054                                         sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
2055                                 memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);
2056
2057                                 //If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT()
2058                                 // windows driver will update WMM parameters each beacon received once connected
2059                                 // Linux driver is a bit different.
2060                                 network->bssht.bdSupportHT = true;
2061                         }
2062                         else
2063                                 network->bssht.bdSupportHT = false;
2064                         break;
2065
2066
2067                 case MFIE_TYPE_HT_INFO:
2068                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n",
2069                                              info_element->len);
2070                         tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
2071                         if(tmp_htinfo_len){
2072                                 network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE;
2073                                 network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
2074                                         sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
2075                                 memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
2076                         }
2077                         break;
2078
2079                 case MFIE_TYPE_AIRONET:
2080                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n",
2081                                              info_element->len);
2082                         if(info_element->len >IE_CISCO_FLAG_POSITION)
2083                         {
2084                                 network->bWithAironetIE = true;
2085
2086                                 // CCX 1 spec v1.13, A01.1 CKIP Negotiation (page23):
2087                                 // "A Cisco access point advertises support for CKIP in beacon and probe response packets,
2088                                 //  by adding an Aironet element and setting one or both of the CKIP negotiation bits."
2089                                 if(     (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_MIC)   ||
2090                                         (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_PK)    )
2091                                 {
2092                                         network->bCkipSupported = true;
2093                                 }
2094                                 else
2095                                 {
2096                                         network->bCkipSupported = false;
2097                                 }
2098                         }
2099                         else
2100                         {
2101                                 network->bWithAironetIE = false;
2102                                 network->bCkipSupported = false;
2103                         }
2104                         break;
2105                 case MFIE_TYPE_QOS_PARAMETER:
2106                         printk(KERN_ERR
2107                                "QoS Error need to parse QOS_PARAMETER IE\n");
2108                         break;
2109
2110 #ifdef ENABLE_DOT11D
2111                 case MFIE_TYPE_COUNTRY:
2112                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
2113                                              info_element->len);
2114                         ieee80211_extract_country_ie(ieee, info_element, network, network->bssid);//addr2 is same as addr3 when from an AP
2115                         break;
2116 #endif
2117
2118                 default:
2119                         IEEE80211_DEBUG_MGMT
2120                             ("Unsupported info element: %s (%d)\n",
2121                              get_info_element_string(info_element->id),
2122                              info_element->id);
2123                         break;
2124                 }
2125
2126                 length -= sizeof(*info_element) + info_element->len;
2127                 info_element =
2128                     (struct ieee80211_info_element *)&info_element->
2129                     data[info_element->len];
2130         }
2131
2132         if(!network->atheros_cap_exist && !network->broadcom_cap_exist &&
2133                 !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation &&
2134                 !network->marvell_cap_exist)
2135         {
2136                 network->unknown_cap_exist = true;
2137         }
2138         else
2139         {
2140                 network->unknown_cap_exist = false;
2141         }
2142         return 0;
2143 }
2144
2145 static inline u8 ieee80211_SignalStrengthTranslate(
2146         u8  CurrSS
2147         )
2148 {
2149         u8 RetSS;
2150
2151         // Step 1. Scale mapping.
2152         if(CurrSS >= 71 && CurrSS <= 100)
2153         {
2154                 RetSS = 90 + ((CurrSS - 70) / 3);
2155         }
2156         else if(CurrSS >= 41 && CurrSS <= 70)
2157         {
2158                 RetSS = 78 + ((CurrSS - 40) / 3);
2159         }
2160         else if(CurrSS >= 31 && CurrSS <= 40)
2161         {
2162                 RetSS = 66 + (CurrSS - 30);
2163         }
2164         else if(CurrSS >= 21 && CurrSS <= 30)
2165         {
2166                 RetSS = 54 + (CurrSS - 20);
2167         }
2168         else if(CurrSS >= 5 && CurrSS <= 20)
2169         {
2170                 RetSS = 42 + (((CurrSS - 5) * 2) / 3);
2171         }
2172         else if(CurrSS == 4)
2173         {
2174                 RetSS = 36;
2175         }
2176         else if(CurrSS == 3)
2177         {
2178                 RetSS = 27;
2179         }
2180         else if(CurrSS == 2)
2181         {
2182                 RetSS = 18;
2183         }
2184         else if(CurrSS == 1)
2185         {
2186                 RetSS = 9;
2187         }
2188         else
2189         {
2190                 RetSS = CurrSS;
2191         }
2192
2193         return RetSS;
2194 }
2195
2196 long ieee80211_translate_todbm(u8 signal_strength_index )// 0-100 index.
2197 {
2198         long    signal_power; // in dBm.
2199
2200         // Translate to dBm (x=0.5y-95).
2201         signal_power = (long)((signal_strength_index + 1) >> 1);
2202         signal_power -= 95;
2203
2204         return signal_power;
2205 }
2206
2207 static inline int ieee80211_network_init(
2208         struct ieee80211_device *ieee,
2209         struct ieee80211_probe_response *beacon,
2210         struct ieee80211_network *network,
2211         struct ieee80211_rx_stats *stats)
2212 {
2213         network->qos_data.active = 0;
2214         network->qos_data.supported = 0;
2215         network->qos_data.param_count = 0;
2216         network->qos_data.old_param_count = 0;
2217
2218         /* Pull out fixed field data */
2219         memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
2220         network->capability = le16_to_cpu(beacon->capability);
2221         network->last_scanned = jiffies;
2222         network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
2223         network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
2224         network->beacon_interval = le32_to_cpu(beacon->beacon_interval);
2225         /* Where to pull this? beacon->listen_interval;*/
2226         network->listen_interval = 0x0A;
2227         network->rates_len = network->rates_ex_len = 0;
2228         network->last_associate = 0;
2229         network->ssid_len = 0;
2230         network->flags = 0;
2231         network->atim_window = 0;
2232         network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
2233             0x3 : 0x0;
2234         network->berp_info_valid = false;
2235         network->broadcom_cap_exist = false;
2236         network->ralink_cap_exist = false;
2237         network->atheros_cap_exist = false;
2238         network->marvell_cap_exist = false;
2239         network->cisco_cap_exist = false;
2240         network->unknown_cap_exist = false;
2241 #ifdef THOMAS_TURBO
2242         network->Turbo_Enable = 0;
2243 #endif
2244 #ifdef ENABLE_DOT11D
2245         network->CountryIeLen = 0;
2246         memset(network->CountryIeBuf, 0, MAX_IE_LEN);
2247 #endif
2248 //Initialize HT parameters
2249         HTInitializeBssDesc(&network->bssht);
2250         if (stats->freq == IEEE80211_52GHZ_BAND) {
2251                 /* for A band (No DS info) */
2252                 network->channel = stats->received_channel;
2253         } else
2254                 network->flags |= NETWORK_HAS_CCK;
2255
2256         network->wpa_ie_len = 0;
2257         network->rsn_ie_len = 0;
2258
2259         if (ieee80211_parse_info_param
2260             (ieee,beacon->info_element, stats->len - sizeof(*beacon), network, stats))
2261                 return 1;
2262
2263         network->mode = 0;
2264         if (stats->freq == IEEE80211_52GHZ_BAND)
2265                 network->mode = IEEE_A;
2266         else {
2267                 if (network->flags & NETWORK_HAS_OFDM)
2268                         network->mode |= IEEE_G;
2269                 if (network->flags & NETWORK_HAS_CCK)
2270                         network->mode |= IEEE_B;
2271         }
2272
2273         if (network->mode == 0) {
2274                 IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
2275                                      "network.\n",
2276                                      escape_essid(network->ssid,
2277                                                   network->ssid_len),
2278                                      network->bssid);
2279                 return 1;
2280         }
2281
2282         if(network->bssht.bdSupportHT){
2283                 if(network->mode == IEEE_A)
2284                         network->mode = IEEE_N_5G;
2285                 else if(network->mode & (IEEE_G | IEEE_B))
2286                         network->mode = IEEE_N_24G;
2287         }
2288         if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
2289                 network->flags |= NETWORK_EMPTY_ESSID;
2290
2291         stats->signal = 30 + (stats->SignalStrength * 70) / 100;
2292         stats->noise = ieee80211_translate_todbm((u8)(100-stats->signal)) -25;
2293
2294         memcpy(&network->stats, stats, sizeof(network->stats));
2295
2296         return 0;
2297 }
2298
2299 static inline int is_same_network(struct ieee80211_network *src,
2300                                   struct ieee80211_network *dst, struct ieee80211_device* ieee)
2301 {
2302         /* A network is only a duplicate if the channel, BSSID, ESSID
2303          * and the capability field (in particular IBSS and BSS) all match.
2304          * We treat all <hidden> with the same BSSID and channel
2305          * as one network */
2306         return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&
2307                 (src->channel == dst->channel) &&
2308                 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
2309                 (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&
2310                 ((src->capability & WLAN_CAPABILITY_IBSS) ==
2311                 (dst->capability & WLAN_CAPABILITY_IBSS)) &&
2312                 ((src->capability & WLAN_CAPABILITY_BSS) ==
2313                 (dst->capability & WLAN_CAPABILITY_BSS)));
2314 }
2315
2316 static inline void update_network(struct ieee80211_network *dst,
2317                                   struct ieee80211_network *src)
2318 {
2319         int qos_active;
2320         u8 old_param;
2321
2322         memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
2323         dst->capability = src->capability;
2324         memcpy(dst->rates, src->rates, src->rates_len);
2325         dst->rates_len = src->rates_len;
2326         memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
2327         dst->rates_ex_len = src->rates_ex_len;
2328         if(src->ssid_len > 0)
2329         {
2330                 memset(dst->ssid, 0, dst->ssid_len);
2331                 dst->ssid_len = src->ssid_len;
2332                 memcpy(dst->ssid, src->ssid, src->ssid_len);
2333         }
2334         dst->mode = src->mode;
2335         dst->flags = src->flags;
2336         dst->time_stamp[0] = src->time_stamp[0];
2337         dst->time_stamp[1] = src->time_stamp[1];
2338         if (src->flags & NETWORK_HAS_ERP_VALUE)
2339         {
2340                 dst->erp_value = src->erp_value;
2341                 dst->berp_info_valid = src->berp_info_valid = true;
2342         }
2343         dst->beacon_interval = src->beacon_interval;
2344         dst->listen_interval = src->listen_interval;
2345         dst->atim_window = src->atim_window;
2346         dst->dtim_period = src->dtim_period;
2347         dst->dtim_data = src->dtim_data;
2348         dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
2349         dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
2350         memcpy(&dst->tim, &src->tim, sizeof(struct ieee80211_tim_parameters));
2351
2352         dst->bssht.bdSupportHT = src->bssht.bdSupportHT;
2353         dst->bssht.bdRT2RTAggregation = src->bssht.bdRT2RTAggregation;
2354         dst->bssht.bdHTCapLen= src->bssht.bdHTCapLen;
2355         memcpy(dst->bssht.bdHTCapBuf,src->bssht.bdHTCapBuf,src->bssht.bdHTCapLen);
2356         dst->bssht.bdHTInfoLen= src->bssht.bdHTInfoLen;
2357         memcpy(dst->bssht.bdHTInfoBuf,src->bssht.bdHTInfoBuf,src->bssht.bdHTInfoLen);
2358         dst->bssht.bdHTSpecVer = src->bssht.bdHTSpecVer;
2359         dst->bssht.bdRT2RTLongSlotTime = src->bssht.bdRT2RTLongSlotTime;
2360         dst->broadcom_cap_exist = src->broadcom_cap_exist;
2361         dst->ralink_cap_exist = src->ralink_cap_exist;
2362         dst->atheros_cap_exist = src->atheros_cap_exist;
2363         dst->marvell_cap_exist = src->marvell_cap_exist;
2364         dst->cisco_cap_exist = src->cisco_cap_exist;
2365         dst->unknown_cap_exist = src->unknown_cap_exist;
2366         memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
2367         dst->wpa_ie_len = src->wpa_ie_len;
2368         memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
2369         dst->rsn_ie_len = src->rsn_ie_len;
2370
2371         dst->last_scanned = jiffies;
2372         /* qos related parameters */
2373         qos_active = dst->qos_data.active;
2374         old_param = dst->qos_data.param_count;
2375         if(dst->flags & NETWORK_HAS_QOS_MASK){
2376         //not update QOS paramter in beacon, as most AP will set all these parameter to 0.//WB
2377         }
2378         else {
2379                 dst->qos_data.supported = src->qos_data.supported;
2380                 dst->qos_data.param_count = src->qos_data.param_count;
2381         }
2382
2383         if(dst->qos_data.supported == 1) {
2384                 dst->QoS_Enable = 1;
2385                 if(dst->ssid_len)
2386                         IEEE80211_DEBUG_QOS
2387                                 ("QoS the network %s is QoS supported\n",
2388                                 dst->ssid);
2389                 else
2390                         IEEE80211_DEBUG_QOS
2391                                 ("QoS the network is QoS supported\n");
2392         }
2393         dst->qos_data.active = qos_active;
2394         dst->qos_data.old_param_count = old_param;
2395
2396         /* dst->last_associate is not overwritten */
2397         dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
2398         if(src->wmm_param[0].ac_aci_acm_aifsn|| \
2399            src->wmm_param[1].ac_aci_acm_aifsn|| \
2400            src->wmm_param[2].ac_aci_acm_aifsn|| \
2401            src->wmm_param[3].ac_aci_acm_aifsn) {
2402           memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
2403         }
2404 #ifdef THOMAS_TURBO
2405         dst->Turbo_Enable = src->Turbo_Enable;
2406 #endif
2407
2408 #ifdef ENABLE_DOT11D
2409         dst->CountryIeLen = src->CountryIeLen;
2410         memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
2411 #endif
2412
2413         //added by amy for LEAP
2414         dst->bWithAironetIE = src->bWithAironetIE;
2415         dst->bCkipSupported = src->bCkipSupported;
2416         memcpy(dst->CcxRmState,src->CcxRmState,2);
2417         dst->bCcxRmEnable = src->bCcxRmEnable;
2418         dst->MBssidMask = src->MBssidMask;
2419         dst->bMBssidValid = src->bMBssidValid;
2420         memcpy(dst->MBssid,src->MBssid,6);
2421         dst->bWithCcxVerNum = src->bWithCcxVerNum;
2422         dst->BssCcxVerNumber = src->BssCcxVerNumber;
2423
2424 }
2425
2426 static inline int is_beacon(__le16 fc)
2427 {
2428         return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
2429 }
2430
2431 static inline void ieee80211_process_probe_response(
2432         struct ieee80211_device *ieee,
2433         struct ieee80211_probe_response *beacon,
2434         struct ieee80211_rx_stats *stats)
2435 {
2436         struct ieee80211_network network;
2437         struct ieee80211_network *target;
2438         struct ieee80211_network *oldest = NULL;
2439 #ifdef CONFIG_IEEE80211_DEBUG
2440         struct ieee80211_info_element *info_element = &beacon->info_element[0];
2441 #endif
2442         unsigned long flags;
2443         short renew;
2444
2445         memset(&network, 0, sizeof(struct ieee80211_network));
2446         IEEE80211_DEBUG_SCAN(
2447                 "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
2448                 escape_essid(info_element->data, info_element->len),
2449                 beacon->header.addr3,
2450                 (beacon->capability & (1<<0xf)) ? '1' : '0',
2451                 (beacon->capability & (1<<0xe)) ? '1' : '0',
2452                 (beacon->capability & (1<<0xd)) ? '1' : '0',
2453                 (beacon->capability & (1<<0xc)) ? '1' : '0',
2454                 (beacon->capability & (1<<0xb)) ? '1' : '0',
2455                 (beacon->capability & (1<<0xa)) ? '1' : '0',
2456                 (beacon->capability & (1<<0x9)) ? '1' : '0',
2457                 (beacon->capability & (1<<0x8)) ? '1' : '0',
2458                 (beacon->capability & (1<<0x7)) ? '1' : '0',
2459                 (beacon->capability & (1<<0x6)) ? '1' : '0',
2460                 (beacon->capability & (1<<0x5)) ? '1' : '0',
2461                 (beacon->capability & (1<<0x4)) ? '1' : '0',
2462                 (beacon->capability & (1<<0x3)) ? '1' : '0',
2463                 (beacon->capability & (1<<0x2)) ? '1' : '0',
2464                 (beacon->capability & (1<<0x1)) ? '1' : '0',
2465                 (beacon->capability & (1<<0x0)) ? '1' : '0');
2466
2467         if (ieee80211_network_init(ieee, beacon, &network, stats)) {
2468                 IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
2469                                      escape_essid(info_element->data,
2470                                                   info_element->len),
2471                                      beacon->header.addr3,
2472                                      WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2473                                      IEEE80211_STYPE_PROBE_RESP ?
2474                                      "PROBE RESPONSE" : "BEACON");
2475                 return;
2476         }
2477
2478 #ifdef ENABLE_DOT11D
2479         // For Asus EeePc request,
2480         // (1) if wireless adapter receive get any 802.11d country code in AP beacon,
2481         //         wireless adapter should follow the country code.
2482         // (2)  If there is no any country code in beacon,
2483         //       then wireless adapter should do active scan from ch1~11 and
2484         //       passive scan from ch12~14
2485
2486         if( !IsLegalChannel(ieee, network.channel) )
2487                 return;
2488         if(ieee->bGlobalDomain)
2489         {
2490                 if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
2491                 {
2492                         // Case 1: Country code
2493                         if(IS_COUNTRY_IE_VALID(ieee) )
2494                         {
2495                                 if( !IsLegalChannel(ieee, network.channel) )
2496                                 {
2497                                         printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
2498                                         return;
2499                                 }
2500                         }
2501                         // Case 2: No any country code.
2502                         else
2503                         {
2504                                 // Filter over channel ch12~14
2505                                 if(network.channel > 11)
2506                                 {
2507                                         printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
2508                                         return;
2509                                 }
2510                         }
2511                 }
2512                 else
2513                 {
2514                         // Case 1: Country code
2515                         if(IS_COUNTRY_IE_VALID(ieee) )
2516                         {
2517                                 if( !IsLegalChannel(ieee, network.channel) )
2518                                 {
2519                                         printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
2520                                         return;
2521                                 }
2522                         }
2523                         // Case 2: No any country code.
2524                         else
2525                         {
2526                                 // Filter over channel ch12~14
2527                                 if(network.channel > 14)
2528                                 {
2529                                         printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
2530                                         return;
2531                                 }
2532                         }
2533                 }
2534         }
2535 #endif
2536
2537         /* The network parsed correctly -- so now we scan our known networks
2538          * to see if we can find it in our list.
2539          *
2540          * NOTE:  This search is definitely not optimized.  Once its doing
2541          *        the "right thing" we'll optimize it for efficiency if
2542          *        necessary */
2543
2544         /* Search for this entry in the list and update it if it is
2545          * already there. */
2546
2547         spin_lock_irqsave(&ieee->lock, flags);
2548
2549         if(is_same_network(&ieee->current_network, &network, ieee)) {
2550                 update_network(&ieee->current_network, &network);
2551                 if((ieee->current_network.mode == IEEE_N_24G || ieee->current_network.mode == IEEE_G)
2552                 && ieee->current_network.berp_info_valid){
2553                 if(ieee->current_network.erp_value& ERP_UseProtection)
2554                         ieee->current_network.buseprotection = true;
2555                 else
2556                         ieee->current_network.buseprotection = false;
2557                 }
2558                 if(is_beacon(beacon->header.frame_ctl))
2559                 {
2560                         if(ieee->state == IEEE80211_LINKED)
2561                                 ieee->LinkDetectInfo.NumRecvBcnInPeriod++;
2562                 }
2563                 else //hidden AP
2564                         network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
2565         }
2566
2567         list_for_each_entry(target, &ieee->network_list, list) {
2568                 if (is_same_network(target, &network, ieee))
2569                         break;
2570                 if ((oldest == NULL) ||
2571                     (target->last_scanned < oldest->last_scanned))
2572                         oldest = target;
2573         }
2574
2575         /* If we didn't find a match, then get a new network slot to initialize
2576          * with this beacon's information */
2577         if (&target->list == &ieee->network_list) {
2578                 if (list_empty(&ieee->network_free_list)) {
2579                         /* If there are no more slots, expire the oldest */
2580                         list_del(&oldest->list);
2581                         target = oldest;
2582                         IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
2583                                              "network list.\n",
2584                                              escape_essid(target->ssid,
2585                                                           target->ssid_len),
2586                                              target->bssid);
2587                 } else {
2588                         /* Otherwise just pull from the free list */
2589                         target = list_entry(ieee->network_free_list.next,
2590                                             struct ieee80211_network, list);
2591                         list_del(ieee->network_free_list.next);
2592                 }
2593
2594
2595 #ifdef CONFIG_IEEE80211_DEBUG
2596                 IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
2597                                      escape_essid(network.ssid,
2598                                                   network.ssid_len),
2599                                      network.bssid,
2600                                      WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2601                                      IEEE80211_STYPE_PROBE_RESP ?
2602                                      "PROBE RESPONSE" : "BEACON");
2603 #endif
2604                 memcpy(target, &network, sizeof(*target));
2605                 list_add_tail(&target->list, &ieee->network_list);
2606         } else {
2607                 IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
2608                                      escape_essid(target->ssid,
2609                                                   target->ssid_len),
2610                                      target->bssid,
2611                                      WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2612                                      IEEE80211_STYPE_PROBE_RESP ?
2613                                      "PROBE RESPONSE" : "BEACON");
2614
2615                 /* we have an entry and we are going to update it. But this entry may
2616                  * be already expired. In this case we do the same as we found a new
2617                  * net and call the new_net handler
2618                  */
2619                 renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
2620                 //YJ,add,080819,for hidden ap
2621                 if(is_beacon(beacon->header.frame_ctl) == 0)
2622                         network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
2623                 if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
2624                     && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
2625                     ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
2626                         renew = 1;
2627                 //YJ,add,080819,for hidden ap,end
2628
2629                 update_network(target, &network);
2630         }
2631
2632         spin_unlock_irqrestore(&ieee->lock, flags);
2633         if (is_beacon(beacon->header.frame_ctl)&&is_same_network(&ieee->current_network, &network, ieee)&&\
2634                 (ieee->state == IEEE80211_LINKED)) {
2635                 if(ieee->handle_beacon != NULL) {
2636                         ieee->handle_beacon(ieee, beacon, &ieee->current_network);
2637                 }
2638         }
2639 }
2640
2641 void ieee80211_rx_mgt(struct ieee80211_device *ieee,
2642                       struct ieee80211_hdr_4addr *header,
2643                       struct ieee80211_rx_stats *stats)
2644 {
2645         if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
2646                 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
2647                 ieee->last_rx_ps_time = jiffies;
2648
2649         switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
2650
2651         case IEEE80211_STYPE_BEACON:
2652                 IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
2653                                      WLAN_FC_GET_STYPE(header->frame_ctl));
2654                 IEEE80211_DEBUG_SCAN("Beacon\n");
2655                 ieee80211_process_probe_response(
2656                         ieee, (struct ieee80211_probe_response *)header, stats);
2657
2658                 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
2659                                         ieee->iw_mode == IW_MODE_INFRA &&
2660                                         ieee->state == IEEE80211_LINKED))
2661                 {
2662                         tasklet_schedule(&ieee->ps_task);
2663                 }
2664
2665                 break;
2666
2667         case IEEE80211_STYPE_PROBE_RESP:
2668                 IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
2669                                      WLAN_FC_GET_STYPE(header->frame_ctl));
2670                 IEEE80211_DEBUG_SCAN("Probe response\n");
2671                 ieee80211_process_probe_response(
2672                         ieee, (struct ieee80211_probe_response *)header, stats);
2673                 break;
2674
2675         }
2676 }