c76ffb131449d6406301d19629cc0138a9adbabb
[safe/jmp/linux-2.6] / drivers / staging / rtl8187se / 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/config.h>
26 #include <linux/errno.h>
27 #include <linux/if_arp.h>
28 #include <linux/in6.h>
29 #include <linux/in.h>
30 #include <linux/ip.h>
31 #include <linux/kernel.h>
32 #include <linux/module.h>
33 #include <linux/netdevice.h>
34 #include <linux/pci.h>
35 #include <linux/proc_fs.h>
36 #include <linux/skbuff.h>
37 #include <linux/slab.h>
38 #include <linux/tcp.h>
39 #include <linux/types.h>
40 #include <linux/version.h>
41 #include <linux/wireless.h>
42 #include <linux/etherdevice.h>
43 #include <asm/uaccess.h>
44 #include <linux/ctype.h>
45
46 #include "ieee80211.h"
47 #include "dot11d.h"
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 *hdr = (struct ieee80211_hdr *)skb->data;
53         u16 fc = le16_to_cpu(hdr->frame_ctl);
54
55         skb->dev = ieee->dev;
56         skb_reset_mac_header(skb);
57         skb_pull(skb, ieee80211_get_hdrlen(fc));
58         skb->pkt_type = PACKET_OTHERHOST;
59         skb->protocol = __constant_htons(ETH_P_80211_RAW);
60         memset(skb->cb, 0, sizeof(skb->cb));
61         netif_rx(skb);
62 }
63
64
65 /* Called only as a tasklet (software IRQ) */
66 static struct ieee80211_frag_entry *
67 ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
68                           unsigned int frag, u8 tid,u8 *src, u8 *dst)
69 {
70         struct ieee80211_frag_entry *entry;
71         int i;
72
73         for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
74                 entry = &ieee->frag_cache[tid][i];
75                 if (entry->skb != NULL &&
76                     time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
77                         IEEE80211_DEBUG_FRAG(
78                                 "expiring fragment cache entry "
79                                 "seq=%u last_frag=%u\n",
80                                 entry->seq, entry->last_frag);
81                         dev_kfree_skb_any(entry->skb);
82                         entry->skb = NULL;
83                 }
84
85                 if (entry->skb != NULL && entry->seq == seq &&
86                     (entry->last_frag + 1 == frag || frag == -1) &&
87                     memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
88                     memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
89                         return entry;
90         }
91
92         return NULL;
93 }
94
95 /* Called only as a tasklet (software IRQ) */
96 static struct sk_buff *
97 ieee80211_frag_cache_get(struct ieee80211_device *ieee,
98                          struct ieee80211_hdr *hdr)
99 {
100         struct sk_buff *skb = NULL;
101         u16 fc = le16_to_cpu(hdr->frame_ctl);
102         u16 sc = le16_to_cpu(hdr->seq_ctl);
103         unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
104         unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
105         struct ieee80211_frag_entry *entry;
106         struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
107         struct ieee80211_hdr_QOS *hdr_4addr_QoS;
108         u8 tid;
109
110         if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
111           hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
112           tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
113           tid = UP2AC(tid);
114           tid ++;
115         } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
116           hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
117           tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
118           tid = UP2AC(tid);
119           tid ++;
120         } else {
121           tid = 0;
122         }
123
124         if (frag == 0) {
125                 /* Reserve enough space to fit maximum frame length */
126                 skb = dev_alloc_skb(ieee->dev->mtu +
127                                     sizeof(struct ieee80211_hdr) +
128                                     8 /* LLC */ +
129                                     2 /* alignment */ +
130                                     8 /* WEP */ +
131                                     ETH_ALEN /* WDS */ +
132                                     (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
133                 if (skb == NULL)
134                         return NULL;
135
136                 entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
137                 ieee->frag_next_idx[tid]++;
138                 if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
139                         ieee->frag_next_idx[tid] = 0;
140
141                 if (entry->skb != NULL)
142                         dev_kfree_skb_any(entry->skb);
143
144                 entry->first_frag_time = jiffies;
145                 entry->seq = seq;
146                 entry->last_frag = frag;
147                 entry->skb = skb;
148                 memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
149                 memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
150         } else {
151                 /* received a fragment of a frame for which the head fragment
152                  * should have already been received */
153                 entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
154                                                   hdr->addr1);
155                 if (entry != NULL) {
156                         entry->last_frag = frag;
157                         skb = entry->skb;
158                 }
159         }
160
161         return skb;
162 }
163
164
165 /* Called only as a tasklet (software IRQ) */
166 static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
167                                            struct ieee80211_hdr *hdr)
168 {
169         u16 fc = le16_to_cpu(hdr->frame_ctl);
170         u16 sc = le16_to_cpu(hdr->seq_ctl);
171         unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
172         struct ieee80211_frag_entry *entry;
173         struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
174         struct ieee80211_hdr_QOS *hdr_4addr_QoS;
175         u8 tid;
176
177         if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
178           hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
179           tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
180           tid = UP2AC(tid);
181           tid ++;
182         } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
183           hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
184           tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
185           tid = UP2AC(tid);
186           tid ++;
187         } else {
188           tid = 0;
189         }
190
191         entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
192                                           hdr->addr1);
193
194         if (entry == NULL) {
195                 IEEE80211_DEBUG_FRAG(
196                         "could not invalidate fragment cache "
197                         "entry (seq=%u)\n", seq);
198                 return -1;
199         }
200
201         entry->skb = NULL;
202         return 0;
203 }
204
205
206
207 /* ieee80211_rx_frame_mgtmt
208  *
209  * Responsible for handling management control frames
210  *
211  * Called by ieee80211_rx */
212 static inline int
213 ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
214                         struct ieee80211_rx_stats *rx_stats, u16 type,
215                         u16 stype)
216 {
217         struct ieee80211_hdr *hdr;
218
219         // cheat the the hdr type
220         hdr = (struct ieee80211_hdr *)skb->data;
221
222         /* On the struct stats definition there is written that
223          * this is not mandatory.... but seems that the probe
224          * response parser uses it
225          */
226         rx_stats->len = skb->len;
227         ieee80211_rx_mgt(ieee,(struct ieee80211_hdr *)skb->data,rx_stats);
228
229         if((ieee->state == IEEE80211_LINKED)&&(memcmp(hdr->addr3,ieee->current_network.bssid,ETH_ALEN))) {
230                 dev_kfree_skb_any(skb);
231                 return 0;
232         }
233
234         ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
235
236         dev_kfree_skb_any(skb);
237
238         return 0;
239
240         #ifdef NOT_YET
241         if (ieee->iw_mode == IW_MODE_MASTER) {
242                 printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
243                        ieee->dev->name);
244                 return 0;
245 /*
246   hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
247   skb->data);*/
248         }
249
250         if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) {
251                 if (stype == WLAN_FC_STYPE_BEACON &&
252                     ieee->iw_mode == IW_MODE_MASTER) {
253                         struct sk_buff *skb2;
254                         /* Process beacon frames also in kernel driver to
255                          * update STA(AP) table statistics */
256                         skb2 = skb_clone(skb, GFP_ATOMIC);
257                         if (skb2)
258                                 hostap_rx(skb2->dev, skb2, rx_stats);
259                 }
260
261                 /* send management frames to the user space daemon for
262                  * processing */
263                 ieee->apdevstats.rx_packets++;
264                 ieee->apdevstats.rx_bytes += skb->len;
265                 prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
266                 return 0;
267         }
268
269             if (ieee->iw_mode == IW_MODE_MASTER) {
270                 if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
271                         printk(KERN_DEBUG "%s: unknown management frame "
272                                "(type=0x%02x, stype=0x%02x) dropped\n",
273                                skb->dev->name, type, stype);
274                         return -1;
275                 }
276
277                 hostap_rx(skb->dev, skb, rx_stats);
278                 return 0;
279         }
280
281         printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
282                "received in non-Host AP mode\n", skb->dev->name);
283         return -1;
284         #endif
285 }
286
287
288
289 /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
290 /* Ethernet-II snap header (RFC1042 for most EtherTypes) */
291 static unsigned char rfc1042_header[] =
292 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
293 /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
294 static unsigned char bridge_tunnel_header[] =
295 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
296 /* No encapsulation header if EtherType < 0x600 (=length) */
297
298 /* Called by ieee80211_rx_frame_decrypt */
299 static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
300                                     struct sk_buff *skb, size_t hdrlen)
301 {
302         struct net_device *dev = ieee->dev;
303         u16 fc, ethertype;
304         struct ieee80211_hdr *hdr;
305         u8 *pos;
306
307         if (skb->len < 24)
308                 return 0;
309
310         hdr = (struct ieee80211_hdr *) skb->data;
311         fc = le16_to_cpu(hdr->frame_ctl);
312
313         /* check that the frame is unicast frame to us */
314         if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
315             IEEE80211_FCTL_TODS &&
316             memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
317             memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
318                 /* ToDS frame with own addr BSSID and DA */
319         } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
320                    IEEE80211_FCTL_FROMDS &&
321                    memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
322                 /* FromDS frame with own addr as DA */
323         } else
324                 return 0;
325
326         if (skb->len < 24 + 8)
327                 return 0;
328
329         /* check for port access entity Ethernet type */
330 //      pos = skb->data + 24;
331         pos = skb->data + hdrlen;
332         ethertype = (pos[6] << 8) | pos[7];
333         if (ethertype == ETH_P_PAE)
334                 return 1;
335
336         return 0;
337 }
338
339 /* Called only as a tasklet (software IRQ), by ieee80211_rx */
340 static inline int
341 ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
342                            struct ieee80211_crypt_data *crypt)
343 {
344         struct ieee80211_hdr *hdr;
345         int res, hdrlen;
346
347         if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
348                 return 0;
349
350         hdr = (struct ieee80211_hdr *) skb->data;
351         hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
352
353 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
354         if (ieee->tkip_countermeasures &&
355             strcmp(crypt->ops->name, "TKIP") == 0) {
356                 if (net_ratelimit()) {
357                         printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
358                                "received packet from " MAC_FMT "\n",
359                                ieee->dev->name, MAC_ARG(hdr->addr2));
360                 }
361                 return -1;
362         }
363 #endif
364
365         atomic_inc(&crypt->refcnt);
366         res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
367         atomic_dec(&crypt->refcnt);
368         if (res < 0) {
369                 IEEE80211_DEBUG_DROP(
370                         "decryption failed (SA=" MAC_FMT
371                         ") res=%d\n", MAC_ARG(hdr->addr2), res);
372                 if (res == -2)
373                         IEEE80211_DEBUG_DROP("Decryption failed ICV "
374                                              "mismatch (key %d)\n",
375                                              skb->data[hdrlen + 3] >> 6);
376                 ieee->ieee_stats.rx_discards_undecryptable++;
377                 return -1;
378         }
379
380         return res;
381 }
382
383
384 /* Called only as a tasklet (software IRQ), by ieee80211_rx */
385 static inline int
386 ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
387                              int keyidx, struct ieee80211_crypt_data *crypt)
388 {
389         struct ieee80211_hdr *hdr;
390         int res, hdrlen;
391
392         if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
393                 return 0;
394
395         hdr = (struct ieee80211_hdr *) skb->data;
396         hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
397
398         atomic_inc(&crypt->refcnt);
399         res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
400         atomic_dec(&crypt->refcnt);
401         if (res < 0) {
402                 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
403                        " (SA=" MAC_FMT " keyidx=%d)\n",
404                        ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
405                 return -1;
406         }
407
408         return 0;
409 }
410
411
412 /* this function is stolen from ipw2200 driver*/
413 #define IEEE_PACKET_RETRY_TIME (5*HZ)
414 static int is_duplicate_packet(struct ieee80211_device *ieee,
415                                       struct ieee80211_hdr *header)
416 {
417         u16 fc = le16_to_cpu(header->frame_ctl);
418         u16 sc = le16_to_cpu(header->seq_ctl);
419         u16 seq = WLAN_GET_SEQ_SEQ(sc);
420         u16 frag = WLAN_GET_SEQ_FRAG(sc);
421         u16 *last_seq, *last_frag;
422         unsigned long *last_time;
423         struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
424         struct ieee80211_hdr_QOS *hdr_4addr_QoS;
425         u8 tid;
426
427         //TO2DS and QoS
428         if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
429           hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)header;
430           tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
431           tid = UP2AC(tid);
432           tid ++;
433         } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
434           hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS*)header;
435           tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
436           tid = UP2AC(tid);
437           tid ++;
438         } else { // no QoS
439           tid = 0;
440         }
441         switch (ieee->iw_mode) {
442         case IW_MODE_ADHOC:
443         {
444                 struct list_head *p;
445                 struct ieee_ibss_seq *entry = NULL;
446                 u8 *mac = header->addr2;
447                 int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
448                 //for (pos = (head)->next; pos != (head); pos = pos->next)
449                 __list_for_each(p, &ieee->ibss_mac_hash[index]) {
450                         entry = list_entry(p, struct ieee_ibss_seq, list);
451                         if (!memcmp(entry->mac, mac, ETH_ALEN))
452                                 break;
453                 }
454         //      if (memcmp(entry->mac, mac, ETH_ALEN)){
455                 if (p == &ieee->ibss_mac_hash[index]) {
456                         entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
457                         if (!entry) {
458                                 printk(KERN_WARNING "Cannot malloc new mac entry\n");
459                                 return 0;
460                         }
461                         memcpy(entry->mac, mac, ETH_ALEN);
462                         entry->seq_num[tid] = seq;
463                         entry->frag_num[tid] = frag;
464                         entry->packet_time[tid] = jiffies;
465                         list_add(&entry->list, &ieee->ibss_mac_hash[index]);
466                         return 0;
467                 }
468                 last_seq = &entry->seq_num[tid];
469                 last_frag = &entry->frag_num[tid];
470                 last_time = &entry->packet_time[tid];
471                 break;
472         }
473
474         case IW_MODE_INFRA:
475                 last_seq = &ieee->last_rxseq_num[tid];
476                 last_frag = &ieee->last_rxfrag_num[tid];
477                 last_time = &ieee->last_packet_time[tid];
478
479                 break;
480         default:
481                 return 0;
482         }
483
484 //      if(tid != 0) {
485 //              printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
486 //      }
487         if ((*last_seq == seq) &&
488             time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
489                 if (*last_frag == frag){
490                         //printk(KERN_WARNING "[1] go drop!\n");
491                         goto drop;
492
493                 }
494                 if (*last_frag + 1 != frag)
495                         /* out-of-order fragment */
496                         //printk(KERN_WARNING "[2] go drop!\n");
497                         goto drop;
498         } else
499                 *last_seq = seq;
500
501         *last_frag = frag;
502         *last_time = jiffies;
503         return 0;
504
505 drop:
506 //      BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
507 //      printk("DUP\n");
508
509         return 1;
510 }
511
512
513 /* All received frames are sent to this function. @skb contains the frame in
514  * IEEE 802.11 format, i.e., in the format it was sent over air.
515  * This function is called only as a tasklet (software IRQ). */
516 int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
517                  struct ieee80211_rx_stats *rx_stats)
518 {
519         struct net_device *dev = ieee->dev;
520         //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
521         struct ieee80211_hdr *hdr;
522         //struct ieee80211_hdr_3addr_QOS *hdr;
523
524         size_t hdrlen;
525         u16 fc, type, stype, sc;
526         struct net_device_stats *stats;
527         unsigned int frag;
528         u8 *payload;
529         u16 ethertype;
530 #ifdef NOT_YET
531         struct net_device *wds = NULL;
532         struct sk_buff *skb2 = NULL;
533         struct net_device *wds = NULL;
534         int frame_authorized = 0;
535         int from_assoc_ap = 0;
536         void *sta = NULL;
537 #endif
538 //      u16 QOS_ctl = 0;
539         u8 dst[ETH_ALEN];
540         u8 src[ETH_ALEN];
541         u8 bssid[ETH_ALEN];
542         struct ieee80211_crypt_data *crypt = NULL;
543         int keyidx = 0;
544
545         // cheat the the hdr type
546         hdr = (struct ieee80211_hdr *)skb->data;
547         stats = &ieee->stats;
548
549         if (skb->len < 10) {
550                 printk(KERN_INFO "%s: SKB length < 10\n",
551                        dev->name);
552                 goto rx_dropped;
553         }
554
555         fc = le16_to_cpu(hdr->frame_ctl);
556         type = WLAN_FC_GET_TYPE(fc);
557         stype = WLAN_FC_GET_STYPE(fc);
558         sc = le16_to_cpu(hdr->seq_ctl);
559
560         frag = WLAN_GET_SEQ_FRAG(sc);
561
562 //YJ,add,080828,for keep alive
563         if((fc & IEEE80211_FCTL_TODS) != IEEE80211_FCTL_TODS)
564         {
565                 if(!memcmp(hdr->addr1,dev->dev_addr, ETH_ALEN))
566                 {
567                         ieee->NumRxUnicast++;
568                 }
569         }
570         else
571         {
572                 if(!memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN))
573                 {
574                         ieee->NumRxUnicast++;
575                 }
576         }
577 //YJ,add,080828,for keep alive,end
578
579         hdrlen = ieee80211_get_hdrlen(fc);
580
581 #ifdef NOT_YET
582         /* Put this code here so that we avoid duplicating it in all
583          * Rx paths. - Jean II */
584 #ifdef IW_WIRELESS_SPY          /* defined in iw_handler.h */
585         /* If spy monitoring on */
586         if (iface->spy_data.spy_number > 0) {
587                 struct iw_quality wstats;
588                 wstats.level = rx_stats->signal;
589                 wstats.noise = rx_stats->noise;
590                 wstats.updated = 6;     /* No qual value */
591                 /* Update spy records */
592                 wireless_spy_update(dev, hdr->addr2, &wstats);
593         }
594 #endif /* IW_WIRELESS_SPY */
595         hostap_update_rx_stats(local->ap, hdr, rx_stats);
596 #endif
597
598         if (ieee->iw_mode == IW_MODE_MONITOR) {
599                 ieee80211_monitor_rx(ieee, skb, rx_stats);
600                 stats->rx_packets++;
601                 stats->rx_bytes += skb->len;
602                 return 1;
603         }
604
605         if (ieee->host_decrypt) {
606                 int idx = 0;
607                 if (skb->len >= hdrlen + 3)
608                         idx = skb->data[hdrlen + 3] >> 6;
609                 crypt = ieee->crypt[idx];
610 #ifdef NOT_YET
611                 sta = NULL;
612
613                 /* Use station specific key to override default keys if the
614                  * receiver address is a unicast address ("individual RA"). If
615                  * bcrx_sta_key parameter is set, station specific key is used
616                  * even with broad/multicast targets (this is against IEEE
617                  * 802.11, but makes it easier to use different keys with
618                  * stations that do not support WEP key mapping). */
619
620                 if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
621                         (void) hostap_handle_sta_crypto(local, hdr, &crypt,
622                                                         &sta);
623 #endif
624
625                 /* allow NULL decrypt to indicate an station specific override
626                  * for default encryption */
627                 if (crypt && (crypt->ops == NULL ||
628                               crypt->ops->decrypt_mpdu == NULL))
629                         crypt = NULL;
630
631                 if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
632                         /* This seems to be triggered by some (multicast?)
633                          * frames from other than current BSS, so just drop the
634                          * frames silently instead of filling system log with
635                          * these reports. */
636                         IEEE80211_DEBUG_DROP("Decryption failed (not set)"
637                                              " (SA=" MAC_FMT ")\n",
638                                              MAC_ARG(hdr->addr2));
639                         ieee->ieee_stats.rx_discards_undecryptable++;
640                         goto rx_dropped;
641                 }
642         }
643
644         if (skb->len < IEEE80211_DATA_HDR3_LEN)
645                 goto rx_dropped;
646
647         // if QoS enabled, should check the sequence for each of the AC
648         if (is_duplicate_packet(ieee, hdr))
649                 goto rx_dropped;
650
651
652         if (type == IEEE80211_FTYPE_MGMT) {
653                 if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
654                         goto rx_dropped;
655                 else
656                         goto rx_exit;
657         }
658
659         /* Data frame - extract src/dst addresses */
660         switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
661         case IEEE80211_FCTL_FROMDS:
662                 memcpy(dst, hdr->addr1, ETH_ALEN);
663                 memcpy(src, hdr->addr3, ETH_ALEN);
664                 memcpy(bssid,hdr->addr2,ETH_ALEN);
665                 break;
666         case IEEE80211_FCTL_TODS:
667                 memcpy(dst, hdr->addr3, ETH_ALEN);
668                 memcpy(src, hdr->addr2, ETH_ALEN);
669                 memcpy(bssid,hdr->addr1,ETH_ALEN);
670                 break;
671         case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
672                 if (skb->len < IEEE80211_DATA_HDR4_LEN)
673                         goto rx_dropped;
674                 memcpy(dst, hdr->addr3, ETH_ALEN);
675                 memcpy(src, hdr->addr4, ETH_ALEN);
676                 memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
677                 break;
678         case 0:
679                 memcpy(dst, hdr->addr1, ETH_ALEN);
680                 memcpy(src, hdr->addr2, ETH_ALEN);
681                 memcpy(bssid,hdr->addr3,ETH_ALEN);
682                 break;
683         }
684
685 #ifdef NOT_YET
686         if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
687                 goto rx_dropped;
688         if (wds) {
689                 skb->dev = dev = wds;
690                 stats = hostap_get_stats(dev);
691         }
692
693         if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
694             (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
695             ieee->stadev &&
696             memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
697                 /* Frame from BSSID of the AP for which we are a client */
698                 skb->dev = dev = ieee->stadev;
699                 stats = hostap_get_stats(dev);
700                 from_assoc_ap = 1;
701         }
702 #endif
703
704         dev->last_rx = jiffies;
705
706 #ifdef NOT_YET
707         if ((ieee->iw_mode == IW_MODE_MASTER ||
708              ieee->iw_mode == IW_MODE_REPEAT) &&
709             !from_assoc_ap) {
710                 switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
711                                              wds != NULL)) {
712                 case AP_RX_CONTINUE_NOT_AUTHORIZED:
713                         frame_authorized = 0;
714                         break;
715                 case AP_RX_CONTINUE:
716                         frame_authorized = 1;
717                         break;
718                 case AP_RX_DROP:
719                         goto rx_dropped;
720                 case AP_RX_EXIT:
721                         goto rx_exit;
722                 }
723         }
724 #endif
725
726         /* Nullfunc frames may have PS-bit set, so they must be passed to
727          * hostap_handle_sta_rx() before being dropped here. */
728         if (stype != IEEE80211_STYPE_DATA &&
729             stype != IEEE80211_STYPE_DATA_CFACK &&
730             stype != IEEE80211_STYPE_DATA_CFPOLL &&
731             stype != IEEE80211_STYPE_DATA_CFACKPOLL&&
732             stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
733             ) {
734                 if (stype != IEEE80211_STYPE_NULLFUNC)
735                         IEEE80211_DEBUG_DROP(
736                                 "RX: dropped data frame "
737                                 "with no data (type=0x%02x, "
738                                 "subtype=0x%02x, len=%d)\n",
739                                 type, stype, skb->len);
740                 goto rx_dropped;
741         }
742         if(memcmp(bssid,ieee->current_network.bssid,ETH_ALEN)) {
743                 goto rx_dropped;
744         }
745
746         ieee->NumRxDataInPeriod++;
747         ieee->NumRxOkTotal++;
748         /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
749
750         if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
751             (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
752                 goto rx_dropped;
753
754         hdr = (struct ieee80211_hdr *) skb->data;
755
756         /* skb: hdr + (possibly fragmented) plaintext payload */
757         // PR: FIXME: hostap has additional conditions in the "if" below:
758         // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
759         if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
760                 int flen;
761                 struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
762                 IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
763
764                 if (!frag_skb) {
765                         IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
766                                         "Rx cannot get skb from fragment "
767                                         "cache (morefrag=%d seq=%u frag=%u)\n",
768                                         (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
769                                         WLAN_GET_SEQ_SEQ(sc), frag);
770                         goto rx_dropped;
771                 }
772                 flen = skb->len;
773                 if (frag != 0)
774                         flen -= hdrlen;
775
776                 if (frag_skb->tail + flen > frag_skb->end) {
777                         printk(KERN_WARNING "%s: host decrypted and "
778                                "reassembled frame did not fit skb\n",
779                                dev->name);
780                         ieee80211_frag_cache_invalidate(ieee, hdr);
781                         goto rx_dropped;
782                 }
783
784                 if (frag == 0) {
785                         /* copy first fragment (including full headers) into
786                          * beginning of the fragment cache skb */
787                         memcpy(skb_put(frag_skb, flen), skb->data, flen);
788                 } else {
789                         /* append frame payload to the end of the fragment
790                          * cache skb */
791                         memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
792                                flen);
793                 }
794                 dev_kfree_skb_any(skb);
795                 skb = NULL;
796
797                 if (fc & IEEE80211_FCTL_MOREFRAGS) {
798                         /* more fragments expected - leave the skb in fragment
799                          * cache for now; it will be delivered to upper layers
800                          * after all fragments have been received */
801                         goto rx_exit;
802                 }
803
804                 /* this was the last fragment and the frame will be
805                  * delivered, so remove skb from fragment cache */
806                 skb = frag_skb;
807                 hdr = (struct ieee80211_hdr *) skb->data;
808                 ieee80211_frag_cache_invalidate(ieee, hdr);
809         }
810
811         /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
812          * encrypted/authenticated */
813         if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
814             ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
815                 goto rx_dropped;
816
817         hdr = (struct ieee80211_hdr *) skb->data;
818         if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
819                 if (/*ieee->ieee802_1x &&*/
820                     ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
821
822 #ifdef CONFIG_IEEE80211_DEBUG
823                         /* pass unencrypted EAPOL frames even if encryption is
824                          * configured */
825                         struct eapol *eap = (struct eapol *)(skb->data +
826                                 24);
827                         IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
828                                                 eap_get_type(eap->type));
829 #endif
830                 } else {
831                         IEEE80211_DEBUG_DROP(
832                                 "encryption configured, but RX "
833                                 "frame not encrypted (SA=" MAC_FMT ")\n",
834                                 MAC_ARG(hdr->addr2));
835                         goto rx_dropped;
836                 }
837         }
838
839 #ifdef CONFIG_IEEE80211_DEBUG
840         if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
841             ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
842                         struct eapol *eap = (struct eapol *)(skb->data +
843                                 24);
844                         IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
845                                                 eap_get_type(eap->type));
846         }
847 #endif
848
849         if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
850             !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
851                 IEEE80211_DEBUG_DROP(
852                         "dropped unencrypted RX data "
853                         "frame from " MAC_FMT
854                         " (drop_unencrypted=1)\n",
855                         MAC_ARG(hdr->addr2));
856                 goto rx_dropped;
857         }
858 /*
859         if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
860                 printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
861         }
862 */
863         /* skb: hdr + (possible reassembled) full plaintext payload */
864         payload = skb->data + hdrlen;
865         ethertype = (payload[6] << 8) | payload[7];
866
867 #ifdef NOT_YET
868         /* If IEEE 802.1X is used, check whether the port is authorized to send
869          * the received frame. */
870         if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
871                 if (ethertype == ETH_P_PAE) {
872                         printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
873                                dev->name);
874                         if (ieee->hostapd && ieee->apdev) {
875                                 /* Send IEEE 802.1X frames to the user
876                                  * space daemon for processing */
877                                 prism2_rx_80211(ieee->apdev, skb, rx_stats,
878                                                 PRISM2_RX_MGMT);
879                                 ieee->apdevstats.rx_packets++;
880                                 ieee->apdevstats.rx_bytes += skb->len;
881                                 goto rx_exit;
882                         }
883                 } else if (!frame_authorized) {
884                         printk(KERN_DEBUG "%s: dropped frame from "
885                                "unauthorized port (IEEE 802.1X): "
886                                "ethertype=0x%04x\n",
887                                dev->name, ethertype);
888                         goto rx_dropped;
889                 }
890         }
891 #endif
892
893         /* convert hdr + possible LLC headers into Ethernet header */
894         if (skb->len - hdrlen >= 8 &&
895             ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
896               ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
897              memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
898                 /* remove RFC1042 or Bridge-Tunnel encapsulation and
899                  * replace EtherType */
900                 skb_pull(skb, hdrlen + SNAP_SIZE);
901                 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
902                 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
903         } else {
904                 u16 len;
905                 /* Leave Ethernet header part of hdr and full payload */
906                 skb_pull(skb, hdrlen);
907                 len = htons(skb->len);
908                 memcpy(skb_push(skb, 2), &len, 2);
909                 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
910                 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
911         }
912
913 #ifdef NOT_YET
914         if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
915                     IEEE80211_FCTL_TODS) &&
916             skb->len >= ETH_HLEN + ETH_ALEN) {
917                 /* Non-standard frame: get addr4 from its bogus location after
918                  * the payload */
919                 memcpy(skb->data + ETH_ALEN,
920                        skb->data + skb->len - ETH_ALEN, ETH_ALEN);
921                 skb_trim(skb, skb->len - ETH_ALEN);
922         }
923 #endif
924
925         stats->rx_packets++;
926         stats->rx_bytes += skb->len;
927
928 #ifdef NOT_YET
929         if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
930             ieee->ap->bridge_packets) {
931                 if (dst[0] & 0x01) {
932                         /* copy multicast frame both to the higher layers and
933                          * to the wireless media */
934                         ieee->ap->bridged_multicast++;
935                         skb2 = skb_clone(skb, GFP_ATOMIC);
936                         if (skb2 == NULL)
937                                 printk(KERN_DEBUG "%s: skb_clone failed for "
938                                        "multicast frame\n", dev->name);
939                 } else if (hostap_is_sta_assoc(ieee->ap, dst)) {
940                         /* send frame directly to the associated STA using
941                          * wireless media and not passing to higher layers */
942                         ieee->ap->bridged_unicast++;
943                         skb2 = skb;
944                         skb = NULL;
945                 }
946         }
947
948         if (skb2 != NULL) {
949                 /* send to wireless media */
950                 skb2->protocol = __constant_htons(ETH_P_802_3);
951                 skb2->mac.raw = skb2->nh.raw = skb2->data;
952                 /* skb2->nh.raw = skb2->data + ETH_HLEN; */
953                 skb2->dev = dev;
954                 dev_queue_xmit(skb2);
955         }
956
957 #endif
958         if (skb) {
959                 skb->protocol = eth_type_trans(skb, dev);
960                 memset(skb->cb, 0, sizeof(skb->cb));
961                 skb->dev = dev;
962                 skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
963                 ieee->last_rx_ps_time = jiffies;
964                 netif_rx(skb);
965         }
966
967  rx_exit:
968 #ifdef NOT_YET
969         if (sta)
970                 hostap_handle_sta_release(sta);
971 #endif
972         return 1;
973
974  rx_dropped:
975         stats->rx_dropped++;
976
977         /* Returning 0 indicates to caller that we have not handled the SKB--
978          * so it is still allocated and can be used again by underlying
979          * hardware as a DMA target */
980         return 0;
981 }
982
983 #define MGMT_FRAME_FIXED_PART_LENGTH            0x24
984
985 static inline int ieee80211_is_ofdm_rate(u8 rate)
986 {
987         switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
988         case IEEE80211_OFDM_RATE_6MB:
989         case IEEE80211_OFDM_RATE_9MB:
990         case IEEE80211_OFDM_RATE_12MB:
991         case IEEE80211_OFDM_RATE_18MB:
992         case IEEE80211_OFDM_RATE_24MB:
993         case IEEE80211_OFDM_RATE_36MB:
994         case IEEE80211_OFDM_RATE_48MB:
995         case IEEE80211_OFDM_RATE_54MB:
996                 return 1;
997         }
998         return 0;
999 }
1000
1001 static inline int ieee80211_SignalStrengthTranslate(
1002         int  CurrSS
1003         )
1004 {
1005         int RetSS;
1006
1007         // Step 1. Scale mapping.
1008         if(CurrSS >= 71 && CurrSS <= 100)
1009         {
1010                 RetSS = 90 + ((CurrSS - 70) / 3);
1011         }
1012         else if(CurrSS >= 41 && CurrSS <= 70)
1013         {
1014                 RetSS = 78 + ((CurrSS - 40) / 3);
1015         }
1016         else if(CurrSS >= 31 && CurrSS <= 40)
1017         {
1018                 RetSS = 66 + (CurrSS - 30);
1019         }
1020         else if(CurrSS >= 21 && CurrSS <= 30)
1021         {
1022                 RetSS = 54 + (CurrSS - 20);
1023         }
1024         else if(CurrSS >= 5 && CurrSS <= 20)
1025         {
1026                 RetSS = 42 + (((CurrSS - 5) * 2) / 3);
1027         }
1028         else if(CurrSS == 4)
1029         {
1030                 RetSS = 36;
1031         }
1032         else if(CurrSS == 3)
1033         {
1034                 RetSS = 27;
1035         }
1036         else if(CurrSS == 2)
1037         {
1038                 RetSS = 18;
1039         }
1040         else if(CurrSS == 1)
1041         {
1042                 RetSS = 9;
1043         }
1044         else
1045         {
1046                 RetSS = CurrSS;
1047         }
1048         //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping:  LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
1049
1050         // Step 2. Smoothing.
1051
1052         //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing:  LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
1053
1054         return RetSS;
1055 }
1056
1057 static inline void ieee80211_extract_country_ie(
1058         struct ieee80211_device *ieee,
1059         struct ieee80211_info_element *info_element,
1060         struct ieee80211_network *network,
1061         u8 * addr2
1062 )
1063 {
1064         if(IS_DOT11D_ENABLE(ieee))
1065         {
1066                 if(info_element->len!= 0)
1067                 {
1068                         memcpy(network->CountryIeBuf, info_element->data, info_element->len);
1069                         network->CountryIeLen = info_element->len;
1070
1071                         if(!IS_COUNTRY_IE_VALID(ieee))
1072                         {
1073                                 Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
1074                         }
1075                 }
1076
1077                 //
1078                 // 070305, rcnjko: I update country IE watch dog here because
1079                 // some AP (e.g. Cisco 1242) don't include country IE in their
1080                 // probe response frame.
1081                 //
1082                 if(IS_EQUAL_CIE_SRC(ieee, addr2) )
1083                 {
1084                         UPDATE_CIE_WATCHDOG(ieee);
1085                 }
1086         }
1087
1088 }
1089
1090 int
1091 ieee80211_TranslateToDbm(
1092         unsigned char SignalStrengthIndex       // 0-100 index.
1093         )
1094 {
1095         unsigned char SignalPower; // in dBm.
1096
1097         // Translate to dBm (x=0.5y-95).
1098         SignalPower = (int)SignalStrengthIndex * 7 / 10;
1099         SignalPower -= 95;
1100
1101         return SignalPower;
1102 }
1103 inline int ieee80211_network_init(
1104         struct ieee80211_device *ieee,
1105         struct ieee80211_probe_response *beacon,
1106         struct ieee80211_network *network,
1107         struct ieee80211_rx_stats *stats)
1108 {
1109 #ifdef CONFIG_IEEE80211_DEBUG
1110         char rates_str[64];
1111         char *p;
1112 #endif
1113         struct ieee80211_info_element *info_element;
1114         u16 left;
1115         u8 i;
1116         short offset;
1117         u8 curRate = 0,hOpRate = 0,curRate_ex = 0;
1118
1119         /* Pull out fixed field data */
1120         memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
1121         network->capability = beacon->capability;
1122         network->last_scanned = jiffies;
1123         network->time_stamp[0] = beacon->time_stamp[0];
1124         network->time_stamp[1] = beacon->time_stamp[1];
1125         network->beacon_interval = beacon->beacon_interval;
1126         /* Where to pull this? beacon->listen_interval;*/
1127         network->listen_interval = 0x0A;
1128         network->rates_len = network->rates_ex_len = 0;
1129         network->last_associate = 0;
1130         network->ssid_len = 0;
1131         network->flags = 0;
1132         network->atim_window = 0;
1133         network->QoS_Enable = 0;
1134 //by amy 080312
1135         network->HighestOperaRate = 0;
1136 //by amy 080312
1137         network->Turbo_Enable = 0;
1138         network->CountryIeLen = 0;
1139         memset(network->CountryIeBuf, 0, MAX_IE_LEN);
1140
1141         if (stats->freq == IEEE80211_52GHZ_BAND) {
1142                 /* for A band (No DS info) */
1143                 network->channel = stats->received_channel;
1144         } else
1145                 network->flags |= NETWORK_HAS_CCK;
1146
1147         network->wpa_ie_len = 0;
1148         network->rsn_ie_len = 0;
1149
1150         info_element = &beacon->info_element;
1151         left = stats->len - ((void *)info_element - (void *)beacon);
1152         while (left >= sizeof(struct ieee80211_info_element_hdr)) {
1153                 if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
1154                         IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
1155                                              info_element->len + sizeof(struct ieee80211_info_element),
1156                                              left);
1157                         return 1;
1158                 }
1159
1160                 switch (info_element->id) {
1161                 case MFIE_TYPE_SSID:
1162                         if (ieee80211_is_empty_essid(info_element->data,
1163                                                      info_element->len)) {
1164                                 network->flags |= NETWORK_EMPTY_ESSID;
1165                                 break;
1166                         }
1167
1168                         network->ssid_len = min(info_element->len,
1169                                                 (u8)IW_ESSID_MAX_SIZE);
1170                         memcpy(network->ssid, info_element->data, network->ssid_len);
1171                         if (network->ssid_len < IW_ESSID_MAX_SIZE)
1172                                 memset(network->ssid + network->ssid_len, 0,
1173                                        IW_ESSID_MAX_SIZE - network->ssid_len);
1174
1175                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
1176                                              network->ssid, network->ssid_len);
1177                         break;
1178
1179                 case MFIE_TYPE_RATES:
1180 #ifdef CONFIG_IEEE80211_DEBUG
1181                         p = rates_str;
1182 #endif
1183                         network->rates_len = min(info_element->len, MAX_RATES_LENGTH);
1184                         for (i = 0; i < network->rates_len; i++) {
1185                                 network->rates[i] = info_element->data[i];
1186                                 curRate = network->rates[i] & 0x7f;
1187                                 if( hOpRate < curRate )
1188                                         hOpRate = curRate;
1189 #ifdef CONFIG_IEEE80211_DEBUG
1190                                 p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
1191 #endif
1192                                 if (ieee80211_is_ofdm_rate(info_element->data[i])) {
1193                                         network->flags |= NETWORK_HAS_OFDM;
1194                                         if (info_element->data[i] &
1195                                             IEEE80211_BASIC_RATE_MASK)
1196                                                 network->flags &=
1197                                                         ~NETWORK_HAS_CCK;
1198                                 }
1199                         }
1200
1201                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
1202                                              rates_str, network->rates_len);
1203                         break;
1204
1205                 case MFIE_TYPE_RATES_EX:
1206 #ifdef CONFIG_IEEE80211_DEBUG
1207                         p = rates_str;
1208 #endif
1209                         network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH);
1210                         for (i = 0; i < network->rates_ex_len; i++) {
1211                                 network->rates_ex[i] = info_element->data[i];
1212                                 curRate_ex = network->rates_ex[i] & 0x7f;
1213                                 if( hOpRate < curRate_ex )
1214                                         hOpRate = curRate_ex;
1215 #ifdef CONFIG_IEEE80211_DEBUG
1216                                 p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
1217 #endif
1218                                 if (ieee80211_is_ofdm_rate(info_element->data[i])) {
1219                                         network->flags |= NETWORK_HAS_OFDM;
1220                                         if (info_element->data[i] &
1221                                             IEEE80211_BASIC_RATE_MASK)
1222                                                 network->flags &=
1223                                                         ~NETWORK_HAS_CCK;
1224                                 }
1225                         }
1226
1227                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
1228                                              rates_str, network->rates_ex_len);
1229                         break;
1230
1231                 case MFIE_TYPE_DS_SET:
1232                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
1233                                              info_element->data[0]);
1234                         if (stats->freq == IEEE80211_24GHZ_BAND)
1235                                 network->channel = info_element->data[0];
1236                         break;
1237
1238                 case MFIE_TYPE_FH_SET:
1239                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
1240                         break;
1241
1242                 case MFIE_TYPE_CF_SET:
1243                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
1244                         break;
1245
1246                 case MFIE_TYPE_TIM:
1247
1248                         if(info_element->len < 4)
1249                                 break;
1250
1251                         network->dtim_period = info_element->data[1];
1252
1253                         if(ieee->state != IEEE80211_LINKED)
1254                                 break;
1255
1256                         network->last_dtim_sta_time[0] = jiffies;
1257                         network->last_dtim_sta_time[1] = stats->mac_time[1];
1258
1259                         network->dtim_data = IEEE80211_DTIM_VALID;
1260
1261                         if(info_element->data[0] != 0)
1262                                 break;
1263
1264                         if(info_element->data[2] & 1)
1265                                 network->dtim_data |= IEEE80211_DTIM_MBCAST;
1266
1267                         offset = (info_element->data[2] >> 1)*2;
1268
1269                         //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
1270
1271                         /* add and modified for ps 2008.1.22 */
1272                         if(ieee->assoc_id < 8*offset ||
1273                                 ieee->assoc_id > 8*(offset + info_element->len -3)) {
1274                                 break;
1275                         }
1276
1277                         offset = (ieee->assoc_id/8) - offset;// + ((aid % 8)? 0 : 1) ;
1278
1279                 //      printk("offset:%x data:%x, ucast:%d\n", offset,
1280                         //      info_element->data[3+offset] ,
1281                         //      info_element->data[3+offset] & (1<<(ieee->assoc_id%8)));
1282
1283                         if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8))) {
1284                                 network->dtim_data |= IEEE80211_DTIM_UCAST;
1285                         }
1286                         break;
1287
1288                 case MFIE_TYPE_IBSS_SET:
1289                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
1290                         break;
1291
1292                 case MFIE_TYPE_CHALLENGE:
1293                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
1294                         break;
1295
1296                 case MFIE_TYPE_GENERIC:
1297                         //nic is 87B
1298                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
1299                                              info_element->len);
1300                         if (info_element->len >= 4  &&
1301                             info_element->data[0] == 0x00 &&
1302                             info_element->data[1] == 0x50 &&
1303                             info_element->data[2] == 0xf2 &&
1304                             info_element->data[3] == 0x01) {
1305                                 network->wpa_ie_len = min(info_element->len + 2,
1306                                                          MAX_WPA_IE_LEN);
1307                                 memcpy(network->wpa_ie, info_element,
1308                                        network->wpa_ie_len);
1309                         }
1310
1311                         if (info_element->len == 7 &&
1312                             info_element->data[0] == 0x00 &&
1313                             info_element->data[1] == 0xe0 &&
1314                             info_element->data[2] == 0x4c &&
1315                             info_element->data[3] == 0x01 &&
1316                             info_element->data[4] == 0x02) {
1317                                 network->Turbo_Enable = 1;
1318                         }
1319                         if (1 == stats->nic_type) {//nic 87
1320                                 break;
1321                         }
1322
1323                         if (info_element->len >= 5  &&
1324                             info_element->data[0] == 0x00 &&
1325                             info_element->data[1] == 0x50 &&
1326                             info_element->data[2] == 0xf2 &&
1327                             info_element->data[3] == 0x02 &&
1328                             info_element->data[4] == 0x00) {
1329                                 //printk(KERN_WARNING "wmm info updated: %x\n", info_element->data[6]);
1330                                 //WMM Information Element
1331                                 network->wmm_info = info_element->data[6];
1332                                 network->QoS_Enable = 1;
1333                         }
1334
1335                         if (info_element->len >= 8  &&
1336                             info_element->data[0] == 0x00 &&
1337                             info_element->data[1] == 0x50 &&
1338                             info_element->data[2] == 0xf2 &&
1339                             info_element->data[3] == 0x02 &&
1340                             info_element->data[4] == 0x01) {
1341                                 // Not care about version at present.
1342                                 //WMM Information Element
1343                                 //printk(KERN_WARNING "wmm info&param updated: %x\n", info_element->data[6]);
1344                                 network->wmm_info = info_element->data[6];
1345                                 //WMM Parameter Element
1346                                 memcpy(network->wmm_param, (u8 *)(info_element->data + 8),(info_element->len - 8));
1347                                 network->QoS_Enable = 1;
1348                         }
1349                         break;
1350
1351                 case MFIE_TYPE_RSN:
1352                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
1353                                              info_element->len);
1354                         network->rsn_ie_len = min(info_element->len + 2,
1355                                                  MAX_WPA_IE_LEN);
1356                         memcpy(network->rsn_ie, info_element,
1357                                network->rsn_ie_len);
1358                         break;
1359                 case MFIE_TYPE_COUNTRY:
1360                         IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
1361                                              info_element->len);
1362 //                      printk("=====>Receive <%s> Country IE\n",network->ssid);
1363                         ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2);
1364                         break;
1365                 default:
1366                         IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
1367                                              info_element->id);
1368                         break;
1369                 }
1370
1371                 left -= sizeof(struct ieee80211_info_element_hdr) +
1372                         info_element->len;
1373                 info_element = (struct ieee80211_info_element *)
1374                         &info_element->data[info_element->len];
1375         }
1376 //by amy 080312
1377         network->HighestOperaRate = hOpRate;
1378 //by amy 080312
1379         network->mode = 0;
1380         if (stats->freq == IEEE80211_52GHZ_BAND)
1381                 network->mode = IEEE_A;
1382         else {
1383                 if (network->flags & NETWORK_HAS_OFDM)
1384                         network->mode |= IEEE_G;
1385                 if (network->flags & NETWORK_HAS_CCK)
1386                         network->mode |= IEEE_B;
1387         }
1388
1389         if (network->mode == 0) {
1390                 IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
1391                                      "network.\n",
1392                                      escape_essid(network->ssid,
1393                                                   network->ssid_len),
1394                                      MAC_ARG(network->bssid));
1395                 return 1;
1396         }
1397
1398         if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
1399                 network->flags |= NETWORK_EMPTY_ESSID;
1400
1401         stats->signal = ieee80211_TranslateToDbm(stats->signalstrength);
1402         //stats->noise = stats->signal - stats->noise;
1403         stats->noise = ieee80211_TranslateToDbm(100 - stats->signalstrength) - 25;
1404         memcpy(&network->stats, stats, sizeof(network->stats));
1405
1406         return 0;
1407 }
1408
1409 static inline int is_same_network(struct ieee80211_network *src,
1410                                   struct ieee80211_network *dst,
1411                                   struct ieee80211_device * ieee)
1412 {
1413         /* A network is only a duplicate if the channel, BSSID, ESSID
1414          * and the capability field (in particular IBSS and BSS) all match.
1415          * We treat all <hidden> with the same BSSID and channel
1416          * as one network */
1417         return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&  //YJ,mod,080819,for hidden ap
1418                 //((src->ssid_len == dst->ssid_len) &&
1419                 (src->channel == dst->channel) &&
1420                 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1421                 (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
1422                 //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
1423                 ((src->capability & WLAN_CAPABILITY_IBSS) ==
1424                 (dst->capability & WLAN_CAPABILITY_IBSS)) &&
1425                 ((src->capability & WLAN_CAPABILITY_BSS) ==
1426                 (dst->capability & WLAN_CAPABILITY_BSS)));
1427 }
1428
1429 inline void update_network(struct ieee80211_network *dst,
1430                                   struct ieee80211_network *src)
1431 {
1432         unsigned char quality = src->stats.signalstrength;
1433         unsigned char signal = 0;
1434         unsigned char noise = 0;
1435         if(dst->stats.signalstrength > 0) {
1436                 quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6;
1437         }
1438         signal = ieee80211_TranslateToDbm(quality);
1439         //noise = signal - src->stats.noise;
1440         if(dst->stats.noise > 0)
1441                 noise = (dst->stats.noise * 5 + src->stats.noise)/6;
1442         //if(strcmp(dst->ssid, "linksys_lzm000") == 0)
1443 //      printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal);
1444         memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
1445         dst->stats.signalstrength = quality;
1446         dst->stats.signal = signal;
1447 //      printk("==================>stats.signal is %d\n",dst->stats.signal);
1448         dst->stats.noise = noise;
1449
1450
1451         dst->capability = src->capability;
1452         memcpy(dst->rates, src->rates, src->rates_len);
1453         dst->rates_len = src->rates_len;
1454         memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
1455         dst->rates_ex_len = src->rates_ex_len;
1456         dst->HighestOperaRate= src->HighestOperaRate;
1457         //printk("==========>in %s: src->ssid is %s,chan is %d\n",__func__,src->ssid,src->channel);
1458
1459         //YJ,add,080819,for hidden ap
1460         if(src->ssid_len > 0)
1461         {
1462                 //if(src->ssid_len == 13)
1463                 //      printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid);
1464                 memset(dst->ssid, 0, dst->ssid_len);
1465                 dst->ssid_len = src->ssid_len;
1466                 memcpy(dst->ssid, src->ssid, src->ssid_len);
1467         }
1468         //YJ,add,080819,for hidden ap,end
1469
1470         dst->channel = src->channel;
1471         dst->mode = src->mode;
1472         dst->flags = src->flags;
1473         dst->time_stamp[0] = src->time_stamp[0];
1474         dst->time_stamp[1] = src->time_stamp[1];
1475
1476         dst->beacon_interval = src->beacon_interval;
1477         dst->listen_interval = src->listen_interval;
1478         dst->atim_window = src->atim_window;
1479         dst->dtim_period = src->dtim_period;
1480         dst->dtim_data = src->dtim_data;
1481         dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
1482         dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
1483 //      printk("update:%s, dtim_period:%x, dtim_data:%x\n", src->ssid, src->dtim_period, src->dtim_data);
1484         memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
1485         dst->wpa_ie_len = src->wpa_ie_len;
1486         memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
1487         dst->rsn_ie_len = src->rsn_ie_len;
1488
1489         dst->last_scanned = jiffies;
1490         /* dst->last_associate is not overwritten */
1491 // disable QoS process now, added by David 2006/7/25
1492 #if 1
1493         dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
1494 /*
1495         if((dst->wmm_info^src->wmm_info)&0x0f) {//Param Set Count change, update Parameter
1496           memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN);
1497         }
1498 */
1499         if(src->wmm_param[0].ac_aci_acm_aifsn|| \
1500            src->wmm_param[1].ac_aci_acm_aifsn|| \
1501            src->wmm_param[2].ac_aci_acm_aifsn|| \
1502            src->wmm_param[3].ac_aci_acm_aifsn) {
1503           memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
1504         }
1505         dst->QoS_Enable = src->QoS_Enable;
1506 #else
1507         dst->QoS_Enable = 1;//for Rtl8187 simulation
1508 #endif
1509         dst->SignalStrength = src->SignalStrength;
1510         dst->Turbo_Enable = src->Turbo_Enable;
1511         dst->CountryIeLen = src->CountryIeLen;
1512         memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
1513 }
1514
1515
1516 inline void ieee80211_process_probe_response(
1517         struct ieee80211_device *ieee,
1518         struct ieee80211_probe_response *beacon,
1519         struct ieee80211_rx_stats *stats)
1520 {
1521         struct ieee80211_network network;
1522         struct ieee80211_network *target;
1523         struct ieee80211_network *oldest = NULL;
1524 #ifdef CONFIG_IEEE80211_DEBUG
1525         struct ieee80211_info_element *info_element = &beacon->info_element;
1526 #endif
1527         unsigned long flags;
1528         short renew;
1529         u8 wmm_info;
1530         u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)? 1:0;  //YJ,add,080819,for hidden ap
1531
1532         memset(&network, 0, sizeof(struct ieee80211_network));
1533
1534         IEEE80211_DEBUG_SCAN(
1535                 "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
1536                 escape_essid(info_element->data, info_element->len),
1537                 MAC_ARG(beacon->header.addr3),
1538                 (beacon->capability & (1<<0xf)) ? '1' : '0',
1539                 (beacon->capability & (1<<0xe)) ? '1' : '0',
1540                 (beacon->capability & (1<<0xd)) ? '1' : '0',
1541                 (beacon->capability & (1<<0xc)) ? '1' : '0',
1542                 (beacon->capability & (1<<0xb)) ? '1' : '0',
1543                 (beacon->capability & (1<<0xa)) ? '1' : '0',
1544                 (beacon->capability & (1<<0x9)) ? '1' : '0',
1545                 (beacon->capability & (1<<0x8)) ? '1' : '0',
1546                 (beacon->capability & (1<<0x7)) ? '1' : '0',
1547                 (beacon->capability & (1<<0x6)) ? '1' : '0',
1548                 (beacon->capability & (1<<0x5)) ? '1' : '0',
1549                 (beacon->capability & (1<<0x4)) ? '1' : '0',
1550                 (beacon->capability & (1<<0x3)) ? '1' : '0',
1551                 (beacon->capability & (1<<0x2)) ? '1' : '0',
1552                 (beacon->capability & (1<<0x1)) ? '1' : '0',
1553                 (beacon->capability & (1<<0x0)) ? '1' : '0');
1554
1555         if (ieee80211_network_init(ieee, beacon, &network, stats)) {
1556                 IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
1557                                      escape_essid(info_element->data,
1558                                                   info_element->len),
1559                                      MAC_ARG(beacon->header.addr3),
1560                                      WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
1561                                      IEEE80211_STYPE_PROBE_RESP ?
1562                                      "PROBE RESPONSE" : "BEACON");
1563                 return;
1564         }
1565
1566         // For Asus EeePc request,
1567         // (1) if wireless adapter receive get any 802.11d country code in AP beacon,
1568         //         wireless adapter should follow the country code.
1569         // (2)  If there is no any country code in beacon,
1570         //       then wireless adapter should do active scan from ch1~11 and
1571         //       passive scan from ch12~14
1572         if(ieee->bGlobalDomain)
1573         {
1574                 if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
1575                 {
1576                         // Case 1: Country code
1577                         if(IS_COUNTRY_IE_VALID(ieee) )
1578                         {
1579                                 if( !IsLegalChannel(ieee, network.channel) )
1580                                 {
1581                                         printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
1582                                         return;
1583                                 }
1584                         }
1585                         // Case 2: No any country code.
1586                         else
1587                         {
1588                                 // Filter over channel ch12~14
1589                                 if(network.channel > 11)
1590                                 {
1591                                         printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
1592                                         return;
1593                                 }
1594                         }
1595                 }
1596                 else
1597                 {
1598                         // Case 1: Country code
1599                         if(IS_COUNTRY_IE_VALID(ieee) )
1600                         {
1601                                 if( !IsLegalChannel(ieee, network.channel) )
1602                                 {
1603                                         printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
1604                                         return;
1605                                 }
1606                         }
1607                         // Case 2: No any country code.
1608                         else
1609                         {
1610                                 // Filter over channel ch12~14
1611                                 if(network.channel > 14)
1612                                 {
1613                                         printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
1614                                         return;
1615                                 }
1616                         }
1617                 }
1618         }
1619         /* The network parsed correctly -- so now we scan our known networks
1620          * to see if we can find it in our list.
1621          *
1622          * NOTE:  This search is definitely not optimized.  Once its doing
1623          *        the "right thing" we'll optimize it for efficiency if
1624          *        necessary */
1625
1626         /* Search for this entry in the list and update it if it is
1627          * already there. */
1628
1629         spin_lock_irqsave(&ieee->lock, flags);
1630
1631         if(is_same_network(&ieee->current_network, &network, ieee)) {
1632                 wmm_info = ieee->current_network.wmm_info;
1633                 //YJ,add,080819,for hidden ap
1634                 if(is_beacon == 0)
1635                         network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
1636                 else if(ieee->state == IEEE80211_LINKED)
1637                         ieee->NumRxBcnInPeriod++;
1638                 //YJ,add,080819,for hidden ap,end
1639                 //printk("====>network.ssid=%s cur_ssid=%s\n", network.ssid, ieee->current_network.ssid);
1640                 update_network(&ieee->current_network, &network);
1641         }
1642
1643         list_for_each_entry(target, &ieee->network_list, list) {
1644                 if (is_same_network(target, &network, ieee))
1645                         break;
1646                 if ((oldest == NULL) ||
1647                     (target->last_scanned < oldest->last_scanned))
1648                         oldest = target;
1649         }
1650
1651         /* If we didn't find a match, then get a new network slot to initialize
1652          * with this beacon's information */
1653         if (&target->list == &ieee->network_list) {
1654                 if (list_empty(&ieee->network_free_list)) {
1655                         /* If there are no more slots, expire the oldest */
1656                         list_del(&oldest->list);
1657                         target = oldest;
1658                         IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
1659                                              "network list.\n",
1660                                              escape_essid(target->ssid,
1661                                                           target->ssid_len),
1662                                              MAC_ARG(target->bssid));
1663                 } else {
1664                         /* Otherwise just pull from the free list */
1665                         target = list_entry(ieee->network_free_list.next,
1666                                             struct ieee80211_network, list);
1667                         list_del(ieee->network_free_list.next);
1668                 }
1669
1670
1671 #ifdef CONFIG_IEEE80211_DEBUG
1672                 IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
1673                                      escape_essid(network.ssid,
1674                                                   network.ssid_len),
1675                                      MAC_ARG(network.bssid),
1676                                      WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
1677                                      IEEE80211_STYPE_PROBE_RESP ?
1678                                      "PROBE RESPONSE" : "BEACON");
1679 #endif
1680
1681                 memcpy(target, &network, sizeof(*target));
1682                 list_add_tail(&target->list, &ieee->network_list);
1683                 if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
1684                         ieee80211_softmac_new_net(ieee,&network);
1685         } else {
1686                 IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
1687                                      escape_essid(target->ssid,
1688                                                   target->ssid_len),
1689                                      MAC_ARG(target->bssid),
1690                                      WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
1691                                      IEEE80211_STYPE_PROBE_RESP ?
1692                                      "PROBE RESPONSE" : "BEACON");
1693
1694                 /* we have an entry and we are going to update it. But this entry may
1695                  * be already expired. In this case we do the same as we found a new
1696                  * net and call the new_net handler
1697                  */
1698                 renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
1699                 //YJ,add,080819,for hidden ap
1700                 if(is_beacon == 0)
1701                         network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
1702                 //if(strncmp(network.ssid, "linksys-c",9) == 0)
1703                 //      printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
1704                 if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
1705                     && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
1706                     ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
1707                         renew = 1;
1708                 //YJ,add,080819,for hidden ap,end
1709                 update_network(target, &network);
1710                 if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
1711                         ieee80211_softmac_new_net(ieee,&network);
1712         }
1713
1714         spin_unlock_irqrestore(&ieee->lock, flags);
1715 }
1716
1717 void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1718                       struct ieee80211_hdr *header,
1719                       struct ieee80211_rx_stats *stats)
1720 {
1721         switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1722
1723         case IEEE80211_STYPE_BEACON:
1724                 IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
1725                                      WLAN_FC_GET_STYPE(header->frame_ctl));
1726                 IEEE80211_DEBUG_SCAN("Beacon\n");
1727                 ieee80211_process_probe_response(
1728                         ieee, (struct ieee80211_probe_response *)header, stats);
1729                 break;
1730
1731         case IEEE80211_STYPE_PROBE_RESP:
1732                 IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
1733                                      WLAN_FC_GET_STYPE(header->frame_ctl));
1734                 IEEE80211_DEBUG_SCAN("Probe response\n");
1735                 ieee80211_process_probe_response(
1736                         ieee, (struct ieee80211_probe_response *)header, stats);
1737                 break;
1738         }
1739 }