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