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