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        dev->last_rx = jiffies;
1315
1316        /* Data frame - extract src/dst addresses */
1317        rtllib_rx_extract_addr(ieee, hdr, dst, src, bssid);
1318
1319        /* Filter Data frames */
1320        ret = rtllib_rx_data_filter(ieee, fc, dst, src, bssid, hdr->addr2);
1321        if (ret < 0)
1322                goto rx_dropped;
1323
1324        if (skb->len == hdrlen)
1325                goto rx_dropped;
1326
1327        /* Send pspoll based on moredata */
1328        if ((ieee->iw_mode == IW_MODE_INFRA)  && (ieee->sta_sleep == LPS_IS_SLEEP)
1329                && (ieee->polling) && (!bToOtherSTA)) {
1330                if (WLAN_FC_MORE_DATA(fc)) {
1331                        /* more data bit is set, let's request a new frame from the AP */
1332                        rtllib_sta_ps_send_pspoll_frame(ieee);
1333                } else {
1334                        ieee->polling =  false;
1335                }
1336        }
1337
1338        /* Get crypt if encrypted */
1339        ret = rtllib_rx_get_crypt(ieee, skb, &crypt, hdrlen);
1340        if (ret == -1)
1341                goto rx_dropped;
1342
1343        /* Decrypt data frame (including reassemble) */
1344        ret = rtllib_rx_decrypt(ieee, skb, rx_stats, crypt, hdrlen);
1345        if (ret == -1)
1346                goto rx_dropped;
1347        else if (ret == -2)
1348                goto rx_exit;
1349
1350        /* Get TS for Rx Reorder  */
1351        hdr = (struct rtllib_hdr_4addr *) skb->data;
1352        if (ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data)
1353                && !is_multicast_ether_addr(hdr->addr1)
1354                && (!bToOtherSTA)) {
1355                TID = Frame_QoSTID(skb->data);
1356                SeqNum = WLAN_GET_SEQ_SEQ(sc);
1357                GetTs(ieee, (struct ts_common_info **) &pTS, hdr->addr2, TID, RX_DIR, true);
1358                if (TID != 0 && TID != 3)
1359                        ieee->bis_any_nonbepkts = true;
1360        }
1361
1362        /* Parse rx data frame (For AMSDU) */
1363        /* skb: hdr + (possible reassembled) full plaintext payload */
1364        payload = skb->data + hdrlen;
1365        rxb = kmalloc(sizeof(struct rtllib_rxb), GFP_ATOMIC);
1366        if (rxb == NULL) {
1367                RTLLIB_DEBUG(RTLLIB_DL_ERR,
1368                             "%s(): kmalloc rxb error\n", __func__);
1369                goto rx_dropped;
1370        }
1371        /* to parse amsdu packets */
1372        /* qos data packets & reserved bit is 1 */
1373        if (parse_subframe(ieee, skb, rx_stats, rxb, src, dst) == 0) {
1374                /* only to free rxb, and not submit the packets to upper layer */
1375                for (i = 0; i < rxb->nr_subframes; i++)
1376                        dev_kfree_skb(rxb->subframes[i]);
1377                kfree(rxb);
1378                rxb = NULL;
1379                goto rx_dropped;
1380        }
1381
1382        /* Update WAPI PN */
1383
1384        /* Check if leave LPS */
1385        if (!bToOtherSTA) {
1386                if (ieee->bIsAggregateFrame)
1387                        nr_subframes = rxb->nr_subframes;
1388                else
1389                        nr_subframes = 1;
1390                if (unicast)
1391                        ieee->LinkDetectInfo.NumRxUnicastOkInPeriod += nr_subframes;
1392                rtllib_rx_check_leave_lps(ieee, unicast, nr_subframes);
1393        }
1394
1395        /* Indicate packets to upper layer or Rx Reorder */
1396        if (ieee->pHTInfo->bCurRxReorderEnable == false || pTS == NULL || bToOtherSTA)
1397                rtllib_rx_indicate_pkt_legacy(ieee, rx_stats, rxb, dst, src);
1398        else
1399                RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum);
1400
1401        dev_kfree_skb(skb);
1402
1403 rx_exit:
1404        return 1;
1405
1406 rx_dropped:
1407        if (rxb != NULL) {
1408                kfree(rxb);
1409                rxb = NULL;
1410        }
1411        ieee->stats.rx_dropped++;
1412
1413        /* Returning 0 indicates to caller that we have not handled the SKB--
1414         * so it is still allocated and can be used again by underlying
1415         * hardware as a DMA target */
1416        return 0;
1417}
1418
1419static int rtllib_rx_Master(struct rtllib_device *ieee, struct sk_buff *skb,
1420                 struct rtllib_rx_stats *rx_stats)
1421{
1422        return 0;
1423}
1424
1425static int rtllib_rx_Monitor(struct rtllib_device *ieee, struct sk_buff *skb,
1426                 struct rtllib_rx_stats *rx_stats)
1427{
1428        struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data;
1429        u16 fc = le16_to_cpu(hdr->frame_ctl);
1430        size_t hdrlen = rtllib_get_hdrlen(fc);
1431
1432        if (skb->len < hdrlen) {
1433                printk(KERN_INFO "%s():ERR!!! skb->len is smaller than hdrlen\n", __func__);
1434                return 0;
1435        }
1436
1437        if (HTCCheck(ieee, skb->data)) {
1438                if (net_ratelimit())
1439                        printk(KERN_INFO "%s: Find HTCControl!\n", __func__);
1440                hdrlen += 4;
1441        }
1442
1443        rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen);
1444        ieee->stats.rx_packets++;
1445        ieee->stats.rx_bytes += skb->len;
1446
1447        return 1;
1448}
1449
1450static int rtllib_rx_Mesh(struct rtllib_device *ieee, struct sk_buff *skb,
1451                 struct rtllib_rx_stats *rx_stats)
1452{
1453        return 0;
1454}
1455
1456/* All received frames are sent to this function. @skb contains the frame in
1457 * IEEE 802.11 format, i.e., in the format it was sent over air.
1458 * This function is called only as a tasklet (software IRQ). */
1459int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb,
1460                 struct rtllib_rx_stats *rx_stats)
1461{
1462        int ret = 0;
1463
1464        if ((NULL == ieee) || (NULL == skb) || (NULL == rx_stats)) {
1465                printk(KERN_INFO "%s: Input parameters NULL!\n", __func__);
1466                goto rx_dropped;
1467        }
1468        if (skb->len < 10) {
1469                printk(KERN_INFO "%s: SKB length < 10\n", __func__);
1470                goto rx_dropped;
1471        }
1472
1473        switch (ieee->iw_mode) {
1474        case IW_MODE_ADHOC:
1475        case IW_MODE_INFRA:
1476                ret = rtllib_rx_InfraAdhoc(ieee, skb, rx_stats);
1477                break;
1478        case IW_MODE_MASTER:
1479        case IW_MODE_REPEAT:
1480                ret = rtllib_rx_Master(ieee, skb, rx_stats);
1481                break;
1482        case IW_MODE_MONITOR:
1483                ret = rtllib_rx_Monitor(ieee, skb, rx_stats);
1484                break;
1485        case IW_MODE_MESH:
1486                ret = rtllib_rx_Mesh(ieee, skb, rx_stats);
1487                break;
1488        default:
1489                printk(KERN_INFO"%s: ERR iw mode!!!\n", __func__);
1490                break;
1491        }
1492
1493        return ret;
1494
1495 rx_dropped:
1496        ieee->stats.rx_dropped++;
1497        return 0;
1498}
1499EXPORT_SYMBOL(rtllib_rx);
1500
1501static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
1502
1503/*
1504* Make ther structure we read from the beacon packet has
1505* the right values
1506*/
1507static int rtllib_verify_qos_info(struct rtllib_qos_information_element
1508                                     *info_element, int sub_type)
1509{
1510
1511        if (info_element->qui_subtype != sub_type)
1512                return -1;
1513        if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
1514                return -1;
1515        if (info_element->qui_type != QOS_OUI_TYPE)
1516                return -1;
1517        if (info_element->version != QOS_VERSION_1)
1518                return -1;
1519
1520        return 0;
1521}
1522
1523
1524/*
1525 * Parse a QoS parameter element
1526 */
1527static int rtllib_read_qos_param_element(struct rtllib_qos_parameter_info
1528                                            *element_param, struct rtllib_info_element
1529                                            *info_element)
1530{
1531        int ret = 0;
1532        u16 size = sizeof(struct rtllib_qos_parameter_info) - 2;
1533
1534        if ((info_element == NULL) || (element_param == NULL))
1535                return -1;
1536
1537        if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
1538                memcpy(element_param->info_element.qui, info_element->data,
1539                       info_element->len);
1540                element_param->info_element.elementID = info_element->id;
1541                element_param->info_element.length = info_element->len;
1542        } else
1543                ret = -1;
1544        if (ret == 0)
1545                ret = rtllib_verify_qos_info(&element_param->info_element,
1546                                                QOS_OUI_PARAM_SUB_TYPE);
1547        return ret;
1548}
1549
1550/*
1551 * Parse a QoS information element
1552 */
1553static int rtllib_read_qos_info_element(struct
1554                                           rtllib_qos_information_element
1555                                           *element_info, struct rtllib_info_element
1556                                           *info_element)
1557{
1558        int ret = 0;
1559        u16 size = sizeof(struct rtllib_qos_information_element) - 2;
1560
1561        if (element_info == NULL)
1562                return -1;
1563        if (info_element == NULL)
1564                return -1;
1565
1566        if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
1567                memcpy(element_info->qui, info_element->data,
1568                       info_element->len);
1569                element_info->elementID = info_element->id;
1570                element_info->length = info_element->len;
1571        } else
1572                ret = -1;
1573
1574        if (ret == 0)
1575                ret = rtllib_verify_qos_info(element_info,
1576                                                QOS_OUI_INFO_SUB_TYPE);
1577        return ret;
1578}
1579
1580
1581/*
1582 * Write QoS parameters from the ac parameters.
1583 */
1584static int rtllib_qos_convert_ac_to_parameters(struct rtllib_qos_parameter_info *param_elm,
1585                struct rtllib_qos_data *qos_data)
1586{
1587        struct rtllib_qos_ac_parameter *ac_params;
1588        struct rtllib_qos_parameters *qos_param = &(qos_data->parameters);
1589        int rc = 0;
1590        int i;
1591        u8 aci;
1592        u8 acm;
1593
1594        qos_data->wmm_acm = 0;
1595        for (i = 0; i < QOS_QUEUE_NUM; i++) {
1596                ac_params = &(param_elm->ac_params_record[i]);
1597
1598                aci = (ac_params->aci_aifsn & 0x60) >> 5;
1599                acm = (ac_params->aci_aifsn & 0x10) >> 4;
1600
1601                if (aci >= QOS_QUEUE_NUM)
1602                        continue;
1603                switch (aci) {
1604                case 1:
1605                        /* BIT(0) | BIT(3) */
1606                        if (acm)
1607                                qos_data->wmm_acm |= (0x01<<0)|(0x01<<3);
1608                        break;
1609                case 2:
1610                        /* BIT(4) | BIT(5) */
1611                        if (acm)
1612                                qos_data->wmm_acm |= (0x01<<4)|(0x01<<5);
1613                        break;
1614                case 3:
1615                        /* BIT(6) | BIT(7) */
1616                        if (acm)
1617                                qos_data->wmm_acm |= (0x01<<6)|(0x01<<7);
1618                        break;
1619                case 0:
1620                default:
1621                        /* BIT(1) | BIT(2) */
1622                        if (acm)
1623                                qos_data->wmm_acm |= (0x01<<1)|(0x01<<2);
1624                        break;
1625                }
1626
1627                qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f;
1628
1629                /* WMM spec P.11: The minimum value for AIFSN shall be 2 */
1630                qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2 : qos_param->aifs[aci];
1631
1632                qos_param->cw_min[aci] = ac_params->ecw_min_max & 0x0F;
1633
1634                qos_param->cw_max[aci] = (ac_params->ecw_min_max & 0xF0) >> 4;
1635
1636                qos_param->flag[aci] =
1637                    (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
1638                qos_param->tx_op_limit[aci] = le16_to_cpu(ac_params->tx_op_limit);
1639        }
1640        return rc;
1641}
1642
1643/*
1644 * we have a generic data element which it may contain QoS information or
1645 * parameters element. check the information element length to decide
1646 * which type to read
1647 */
1648static int rtllib_parse_qos_info_param_IE(struct rtllib_info_element
1649                                             *info_element,
1650                                             struct rtllib_network *network)
1651{
1652        int rc = 0;
1653        struct rtllib_qos_information_element qos_info_element;
1654
1655        rc = rtllib_read_qos_info_element(&qos_info_element, info_element);
1656
1657        if (rc == 0) {
1658                network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
1659                network->flags |= NETWORK_HAS_QOS_INFORMATION;
1660        } else {
1661                struct rtllib_qos_parameter_info param_element;
1662
1663                rc = rtllib_read_qos_param_element(&param_element,
1664                                                      info_element);
1665                if (rc == 0) {
1666                        rtllib_qos_convert_ac_to_parameters(&param_element,
1667                                                               &(network->qos_data));
1668                        network->flags |= NETWORK_HAS_QOS_PARAMETERS;
1669                        network->qos_data.param_count =
1670                            param_element.info_element.ac_info & 0x0F;
1671                }
1672        }
1673
1674        if (rc == 0) {
1675                RTLLIB_DEBUG_QOS("QoS is supported\n");
1676                network->qos_data.supported = 1;
1677        }
1678        return rc;
1679}
1680
1681#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
1682
1683static const char *get_info_element_string(u16 id)
1684{
1685        switch (id) {
1686        MFIE_STRING(SSID);
1687        MFIE_STRING(RATES);
1688        MFIE_STRING(FH_SET);
1689        MFIE_STRING(DS_SET);
1690        MFIE_STRING(CF_SET);
1691        MFIE_STRING(TIM);
1692        MFIE_STRING(IBSS_SET);
1693        MFIE_STRING(COUNTRY);
1694        MFIE_STRING(HOP_PARAMS);
1695        MFIE_STRING(HOP_TABLE);
1696        MFIE_STRING(REQUEST);
1697        MFIE_STRING(CHALLENGE);
1698        MFIE_STRING(POWER_CONSTRAINT);
1699        MFIE_STRING(POWER_CAPABILITY);
1700        MFIE_STRING(TPC_REQUEST);
1701        MFIE_STRING(TPC_REPORT);
1702        MFIE_STRING(SUPP_CHANNELS);
1703        MFIE_STRING(CSA);
1704        MFIE_STRING(MEASURE_REQUEST);
1705        MFIE_STRING(MEASURE_REPORT);
1706        MFIE_STRING(QUIET);
1707        MFIE_STRING(IBSS_DFS);
1708        MFIE_STRING(RSN);
1709        MFIE_STRING(RATES_EX);
1710        MFIE_STRING(GENERIC);
1711        MFIE_STRING(QOS_PARAMETER);
1712        default:
1713                return "UNKNOWN";
1714        }
1715}
1716
1717static inline void rtllib_extract_country_ie(
1718        struct rtllib_device *ieee,
1719        struct rtllib_info_element *info_element,
1720        struct rtllib_network *network,
1721        u8 *addr2)
1722{
1723        if (IS_DOT11D_ENABLE(ieee)) {
1724                if (info_element->len != 0) {
1725                        memcpy(network->CountryIeBuf, info_element->data, info_element->len);
1726                        network->CountryIeLen = info_element->len;
1727
1728                        if (!IS_COUNTRY_IE_VALID(ieee)) {
1729                                if ((rtllib_act_scanning(ieee, false) == true) && (ieee->FirstIe_InScan == 1))
1730                                        printk(KERN_INFO "Received beacon ContryIE, SSID: <%s>\n", network->ssid);
1731                                Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
1732                        }
1733                }
1734
1735                if (IS_EQUAL_CIE_SRC(ieee, addr2))
1736                        UPDATE_CIE_WATCHDOG(ieee);
1737        }
1738
1739}
1740
1741int rtllib_parse_info_param(struct rtllib_device *ieee,
1742                struct rtllib_info_element *info_element,
1743                u16 length,
1744                struct rtllib_network *network,
1745                struct rtllib_rx_stats *stats)
1746{
1747        u8 i;
1748        short offset;
1749        u16     tmp_htcap_len = 0;
1750        u16     tmp_htinfo_len = 0;
1751        u16 ht_realtek_agg_len = 0;
1752        u8  ht_realtek_agg_buf[MAX_IE_LEN];
1753        char rates_str[64];
1754        char *p;
1755
1756        while (length >= sizeof(*info_element)) {
1757                if (sizeof(*info_element) + info_element->len > length) {
1758                        RTLLIB_DEBUG_MGMT("Info elem: parse failed: "
1759                                             "info_element->len + 2 > left : "
1760                                             "info_element->len+2=%zd left=%d, id=%d.\n",
1761                                             info_element->len +
1762                                             sizeof(*info_element),
1763                                             length, info_element->id);
1764                        /* We stop processing but don't return an error here
1765                         * because some misbehaviour APs break this rule. ie.
1766                         * Orinoco AP1000. */
1767                        break;
1768                }
1769
1770                switch (info_element->id) {
1771                case MFIE_TYPE_SSID:
1772                        if (rtllib_is_empty_essid(info_element->data,
1773                                                     info_element->len)) {
1774                                network->flags |= NETWORK_EMPTY_ESSID;
1775                                break;
1776                        }
1777
1778                        network->ssid_len = min(info_element->len,
1779                                                (u8) IW_ESSID_MAX_SIZE);
1780                        memcpy(network->ssid, info_element->data, network->ssid_len);
1781                        if (network->ssid_len < IW_ESSID_MAX_SIZE)
1782                                memset(network->ssid + network->ssid_len, 0,
1783                                       IW_ESSID_MAX_SIZE - network->ssid_len);
1784
1785                        RTLLIB_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
1786                                             network->ssid, network->ssid_len);
1787                        break;
1788
1789                case MFIE_TYPE_RATES:
1790                        p = rates_str;
1791                        network->rates_len = min(info_element->len,
1792                                                 MAX_RATES_LENGTH);
1793                        for (i = 0; i < network->rates_len; i++) {
1794                                network->rates[i] = info_element->data[i];
1795                                p += snprintf(p, sizeof(rates_str) -
1796                                              (p - rates_str), "%02X ",
1797                                              network->rates[i]);
1798                                if (rtllib_is_ofdm_rate
1799                                    (info_element->data[i])) {
1800                                        network->flags |= NETWORK_HAS_OFDM;
1801                                        if (info_element->data[i] &
1802                                            RTLLIB_BASIC_RATE_MASK)
1803                                                network->flags &=
1804                                                    ~NETWORK_HAS_CCK;
1805                                }
1806
1807                                if (rtllib_is_cck_rate
1808                                    (info_element->data[i])) {
1809                                        network->flags |= NETWORK_HAS_CCK;
1810                                }
1811                        }
1812
1813                        RTLLIB_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
1814                                             rates_str, network->rates_len);
1815                        break;
1816
1817                case MFIE_TYPE_RATES_EX:
1818                        p = rates_str;
1819                        network->rates_ex_len = min(info_element->len,
1820                                                    MAX_RATES_EX_LENGTH);
1821                        for (i = 0; i < network->rates_ex_len; i++) {
1822                                network->rates_ex[i] = info_element->data[i];
1823                                p += snprintf(p, sizeof(rates_str) -
1824                                              (p - rates_str), "%02X ",
1825                                              network->rates[i]);
1826                                if (rtllib_is_ofdm_rate
1827                                    (info_element->data[i])) {
1828                                        network->flags |= NETWORK_HAS_OFDM;
1829                                        if (info_element->data[i] &
1830                                            RTLLIB_BASIC_RATE_MASK)
1831                                                network->flags &=
1832                                                    ~NETWORK_HAS_CCK;
1833                                }
1834                        }
1835
1836                        RTLLIB_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
1837                                             rates_str, network->rates_ex_len);
1838                        break;
1839
1840                case MFIE_TYPE_DS_SET:
1841                        RTLLIB_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
1842                                             info_element->data[0]);
1843                        network->channel = info_element->data[0];
1844                        break;
1845
1846                case MFIE_TYPE_FH_SET:
1847                        RTLLIB_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
1848                        break;
1849
1850                case MFIE_TYPE_CF_SET:
1851                        RTLLIB_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
1852                        break;
1853
1854                case MFIE_TYPE_TIM:
1855                        if (info_element->len < 4)
1856                                break;
1857
1858                        network->tim.tim_count = info_element->data[0];
1859                        network->tim.tim_period = info_element->data[1];
1860
1861                        network->dtim_period = info_element->data[1];
1862                        if (ieee->state != RTLLIB_LINKED)
1863                                break;
1864                        network->last_dtim_sta_time = jiffies;
1865
1866                        network->dtim_data = RTLLIB_DTIM_VALID;
1867
1868
1869                        if (info_element->data[2] & 1)
1870                                network->dtim_data |= RTLLIB_DTIM_MBCAST;
1871
1872                        offset = (info_element->data[2] >> 1)*2;
1873
1874
1875                        if (ieee->assoc_id < 8*offset ||
1876                            ieee->assoc_id > 8*(offset + info_element->len - 3))
1877                                break;
1878
1879                        offset = (ieee->assoc_id / 8) - offset;
1880                        if (info_element->data[3 + offset] &
1881                           (1 << (ieee->assoc_id % 8)))
1882                                network->dtim_data |= RTLLIB_DTIM_UCAST;
1883
1884                        network->listen_interval = network->dtim_period;
1885                        break;
1886
1887                case MFIE_TYPE_ERP:
1888                        network->erp_value = info_element->data[0];
1889                        network->flags |= NETWORK_HAS_ERP_VALUE;
1890                        RTLLIB_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
1891                                             network->erp_value);
1892                        break;
1893                case MFIE_TYPE_IBSS_SET:
1894                        network->atim_window = info_element->data[0];
1895                        RTLLIB_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
1896                                             network->atim_window);
1897                        break;
1898
1899                case MFIE_TYPE_CHALLENGE:
1900                        RTLLIB_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
1901                        break;
1902
1903                case MFIE_TYPE_GENERIC:
1904                        RTLLIB_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
1905                                             info_element->len);
1906                        if (!rtllib_parse_qos_info_param_IE(info_element,
1907                                                               network))
1908                                break;
1909                        if (info_element->len >= 4 &&
1910                            info_element->data[0] == 0x00 &&
1911                            info_element->data[1] == 0x50 &&
1912                            info_element->data[2] == 0xf2 &&
1913                            info_element->data[3] == 0x01) {
1914                                network->wpa_ie_len = min(info_element->len + 2,
1915                                                          MAX_WPA_IE_LEN);
1916                                memcpy(network->wpa_ie, info_element,
1917                                       network->wpa_ie_len);
1918                                break;
1919                        }
1920                        if (info_element->len == 7 &&
1921                            info_element->data[0] == 0x00 &&
1922                            info_element->data[1] == 0xe0 &&
1923                            info_element->data[2] == 0x4c &&
1924                            info_element->data[3] == 0x01 &&
1925                            info_element->data[4] == 0x02)
1926                                network->Turbo_Enable = 1;
1927
1928                        if (tmp_htcap_len == 0) {
1929                                if (info_element->len >= 4 &&
1930                                   info_element->data[0] == 0x00 &&
1931                                   info_element->data[1] == 0x90 &&
1932                                   info_element->data[2] == 0x4c &&
1933                                   info_element->data[3] == 0x033) {
1934
1935                                                tmp_htcap_len = min(info_element->len, (u8)MAX_IE_LEN);
1936                                                if (tmp_htcap_len != 0) {
1937                                                        network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
1938                                                        network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf) ?
1939                                                                sizeof(network->bssht.bdHTCapBuf) : tmp_htcap_len;
1940                                                        memcpy(network->bssht.bdHTCapBuf, info_element->data, network->bssht.bdHTCapLen);
1941                                                }
1942                                }
1943                                if (tmp_htcap_len != 0) {
1944                                        network->bssht.bdSupportHT = true;
1945                                        network->bssht.bdHT1R = ((((struct ht_capab_ele *)(network->bssht.bdHTCapBuf))->MCS[1]) == 0);
1946                                } else {
1947                                        network->bssht.bdSupportHT = false;
1948                                        network->bssht.bdHT1R = false;
1949                                }
1950                        }
1951
1952
1953                        if (tmp_htinfo_len == 0) {
1954                                if (info_element->len >= 4 &&
1955                                    info_element->data[0] == 0x00 &&
1956                                    info_element->data[1] == 0x90 &&
1957                                    info_element->data[2] == 0x4c &&
1958                                    info_element->data[3] == 0x034) {
1959                                        tmp_htinfo_len = min(info_element->len, (u8)MAX_IE_LEN);
1960                                        if (tmp_htinfo_len != 0) {
1961                                                network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
1962                                                if (tmp_htinfo_len) {
1963                                                        network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf) ?
1964                                                                sizeof(network->bssht.bdHTInfoBuf) : tmp_htinfo_len;
1965                                                        memcpy(network->bssht.bdHTInfoBuf, info_element->data, network->bssht.bdHTInfoLen);
1966                                                }
1967
1968                                        }
1969
1970                                }
1971                        }
1972
1973                        if (ieee->aggregation) {
1974                                if (network->bssht.bdSupportHT) {
1975                                        if (info_element->len >= 4 &&
1976                                            info_element->data[0] == 0x00 &&
1977                                            info_element->data[1] == 0xe0 &&
1978                                            info_element->data[2] == 0x4c &&
1979                                            info_element->data[3] == 0x02) {
1980                                                ht_realtek_agg_len = min(info_element->len, (u8)MAX_IE_LEN);
1981                                                memcpy(ht_realtek_agg_buf, info_element->data, info_element->len);
1982                                        }
1983                                        if (ht_realtek_agg_len >= 5) {
1984                                                network->realtek_cap_exit = true;
1985                                                network->bssht.bdRT2RTAggregation = true;
1986
1987                                                if ((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02))
1988                                                        network->bssht.bdRT2RTLongSlotTime = true;
1989
1990                                                if ((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & RT_HT_CAP_USE_92SE))
1991                                                        network->bssht.RT2RT_HT_Mode |= RT_HT_CAP_USE_92SE;
1992                                        }
1993                                }
1994                                if (ht_realtek_agg_len >= 5) {
1995                                        if ((ht_realtek_agg_buf[5] & RT_HT_CAP_USE_SOFTAP))
1996                                                network->bssht.RT2RT_HT_Mode |= RT_HT_CAP_USE_SOFTAP;
1997                                }
1998                        }
1999
2000                        if ((info_element->len >= 3 &&
2001                             info_element->data[0] == 0x00 &&
2002                             info_element->data[1] == 0x05 &&
2003                             info_element->data[2] == 0xb5) ||
2004                             (info_element->len >= 3 &&
2005                             info_element->data[0] == 0x00 &&
2006                             info_element->data[1] == 0x0a &&
2007                             info_element->data[2] == 0xf7) ||
2008                             (info_element->len >= 3 &&
2009                             info_element->data[0] == 0x00 &&
2010                             info_element->data[1] == 0x10 &&
2011                             info_element->data[2] == 0x18)) {
2012                                network->broadcom_cap_exist = true;
2013                        }
2014                        if (info_element->len >= 3 &&
2015                            info_element->data[0] == 0x00 &&
2016                            info_element->data[1] == 0x0c &&
2017                            info_element->data[2] == 0x43)
2018                                network->ralink_cap_exist = true;
2019                        if ((info_element->len >= 3 &&
2020                             info_element->data[0] == 0x00 &&
2021                             info_element->data[1] == 0x03 &&
2022                             info_element->data[2] == 0x7f) ||
2023                             (info_element->len >= 3 &&
2024                             info_element->data[0] == 0x00 &&
2025                             info_element->data[1] == 0x13 &&
2026                             info_element->data[2] == 0x74))
2027                                network->atheros_cap_exist = true;
2028
2029                        if ((info_element->len >= 3 &&
2030                             info_element->data[0] == 0x00 &&
2031                             info_element->data[1] == 0x50 &&
2032                             info_element->data[2] == 0x43))
2033                                network->marvell_cap_exist = true;
2034                        if (info_element->len >= 3 &&
2035                            info_element->data[0] == 0x00 &&
2036                            info_element->data[1] == 0x40 &&
2037                            info_element->data[2] == 0x96)
2038                                network->cisco_cap_exist = true;
2039
2040
2041                        if (info_element->len >= 3 &&
2042                            info_element->data[0] == 0x00 &&
2043                            info_element->data[1] == 0x0a &&
2044                            info_element->data[2] == 0xf5)
2045                                network->airgo_cap_exist = true;
2046
2047                        if (info_element->len > 4 &&
2048                            info_element->data[0] == 0x00 &&
2049                            info_element->data[1] == 0x40 &&
2050                            info_element->data[2] == 0x96 &&
2051                            info_element->data[3] == 0x01) {
2052                                if (info_element->len == 6) {
2053                                        memcpy(network->CcxRmState, &info_element[4], 2);
2054                                        if (network->CcxRmState[0] != 0)
2055                                                network->bCcxRmEnable = true;
2056                                        else
2057                                                network->bCcxRmEnable = false;
2058                                        network->MBssidMask = network->CcxRmState[1] & 0x07;
2059                                        if (network->MBssidMask != 0) {
2060                                                network->bMBssidValid = true;
2061                                                network->MBssidMask = 0xff << (network->MBssidMask);
2062                                                memcpy(network->MBssid, network->bssid, ETH_ALEN);
2063                                                network->MBssid[5] &= network->MBssidMask;
2064                                        } else {
2065                                                network->bMBssidValid = false;
2066                                        }
2067                                } else {
2068                                        network->bCcxRmEnable = false;
2069                                }
2070                        }
2071                        if (info_element->len > 4  &&
2072                            info_element->data[0] == 0x00 &&
2073                            info_element->data[1] == 0x40 &&
2074                            info_element->data[2] == 0x96 &&
2075                            info_element->data[3] == 0x03) {
2076                                if (info_element->len == 5) {
2077                                        network->bWithCcxVerNum = true;
2078                                        network->BssCcxVerNumber = info_element->data[4];
2079                                } else {
2080                                        network->bWithCcxVerNum = false;
2081                                        network->BssCcxVerNumber = 0;
2082                                }
2083                        }
2084                        if (info_element->len > 4  &&
2085                            info_element->data[0] == 0x00 &&
2086                            info_element->data[1] == 0x50 &&
2087                            info_element->data[2] == 0xf2 &&
2088                            info_element->data[3] == 0x04) {
2089                                RTLLIB_DEBUG_MGMT("MFIE_TYPE_WZC: %d bytes\n",
2090                                                     info_element->len);
2091                                network->wzc_ie_len = min(info_element->len+2,
2092                                                          MAX_WZC_IE_LEN);
2093                                memcpy(network->wzc_ie, info_element,
2094                                                network->wzc_ie_len);
2095                        }
2096                        break;
2097
2098                case MFIE_TYPE_RSN:
2099                        RTLLIB_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
2100                                             info_element->len);
2101                        network->rsn_ie_len = min(info_element->len + 2,
2102                                                  MAX_WPA_IE_LEN);
2103                        memcpy(network->rsn_ie, info_element,
2104                               network->rsn_ie_len);
2105                        break;
2106
2107                case MFIE_TYPE_HT_CAP:
2108                        RTLLIB_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n",
2109                                             info_element->len);
2110                        tmp_htcap_len = min(info_element->len, (u8)MAX_IE_LEN);
2111                        if (tmp_htcap_len != 0) {
2112                                network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
2113                                network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf) ?
2114                                        sizeof(network->bssht.bdHTCapBuf) : tmp_htcap_len;
2115                                memcpy(network->bssht.bdHTCapBuf,
2116                                       info_element->data,
2117                                       network->bssht.bdHTCapLen);
2118
2119                                network->bssht.bdSupportHT = true;
2120                                network->bssht.bdHT1R = ((((struct ht_capab_ele *)
2121                                                        network->bssht.bdHTCapBuf))->MCS[1]) == 0;
2122
2123                                network->bssht.bdBandWidth = (enum ht_channel_width)
2124                                                             (((struct ht_capab_ele *)
2125                                                             (network->bssht.bdHTCapBuf))->ChlWidth);
2126                        } else {
2127                                network->bssht.bdSupportHT = false;
2128                                network->bssht.bdHT1R = false;
2129                                network->bssht.bdBandWidth = HT_CHANNEL_WIDTH_20;
2130                        }
2131                        break;
2132
2133
2134                case MFIE_TYPE_HT_INFO:
2135                        RTLLIB_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n",
2136                                             info_element->len);
2137                        tmp_htinfo_len = min(info_element->len, (u8)MAX_IE_LEN);
2138                        if (tmp_htinfo_len) {
2139                                network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE;
2140                                network->bssht.bdHTInfoLen = tmp_htinfo_len >
2141                                        sizeof(network->bssht.bdHTInfoBuf) ?
2142                                        sizeof(network->bssht.bdHTInfoBuf) :
2143                                        tmp_htinfo_len;
2144                                memcpy(network->bssht.bdHTInfoBuf,
2145                                       info_element->data,
2146                                       network->bssht.bdHTInfoLen);
2147                        }
2148                        break;
2149
2150                case MFIE_TYPE_AIRONET:
2151                        RTLLIB_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n",
2152                                             info_element->len);
2153                        if (info_element->len > IE_CISCO_FLAG_POSITION) {
2154                                network->bWithAironetIE = true;
2155
2156                                if ((info_element->data[IE_CISCO_FLAG_POSITION]
2157                                     & SUPPORT_CKIP_MIC) ||
2158                                     (info_element->data[IE_CISCO_FLAG_POSITION]
2159                                     & SUPPORT_CKIP_PK))
2160                                        network->bCkipSupported = true;
2161                                else
2162                                        network->bCkipSupported = false;
2163                        } else {
2164                                network->bWithAironetIE = false;
2165                                network->bCkipSupported = false;
2166                        }
2167                        break;
2168                case MFIE_TYPE_QOS_PARAMETER:
2169                        printk(KERN_ERR
2170                               "QoS Error need to parse QOS_PARAMETER IE\n");
2171                        break;
2172
2173                case MFIE_TYPE_COUNTRY:
2174                        RTLLIB_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
2175                                             info_element->len);
2176                        rtllib_extract_country_ie(ieee, info_element, network,
2177                                                  network->bssid);
2178                        break;
2179/* TODO */
2180                default:
2181                        RTLLIB_DEBUG_MGMT
2182                            ("Unsupported info element: %s (%d)\n",
2183                             get_info_element_string(info_element->id),
2184                             info_element->id);
2185                        break;
2186                }
2187
2188                length -= sizeof(*info_element) + info_element->len;
2189                info_element =
2190                    (struct rtllib_info_element *)&info_element->
2191                    data[info_element->len];
2192        }
2193
2194        if (!network->atheros_cap_exist && !network->broadcom_cap_exist &&
2195            !network->cisco_cap_exist && !network->ralink_cap_exist &&
2196            !network->bssht.bdRT2RTAggregation)
2197                network->unknown_cap_exist = true;
2198        else
2199                network->unknown_cap_exist = false;
2200        return 0;
2201}
2202
2203static inline u8 rtllib_SignalStrengthTranslate(u8  CurrSS)
2204{
2205        u8 RetSS;
2206
2207        if (CurrSS >= 71 && CurrSS <= 100)
2208                RetSS = 90 + ((CurrSS - 70) / 3);
2209        else if (CurrSS >= 41 && CurrSS <= 70)
2210                RetSS = 78 + ((CurrSS - 40) / 3);
2211        else if (CurrSS >= 31 && CurrSS <= 40)
2212                RetSS = 66 + (CurrSS - 30);
2213        else if (CurrSS >= 21 && CurrSS <= 30)
2214                RetSS = 54 + (CurrSS - 20);
2215        else if (CurrSS >= 5 && CurrSS <= 20)
2216                RetSS = 42 + (((CurrSS - 5) * 2) / 3);
2217        else if (CurrSS == 4)
2218                RetSS = 36;
2219        else if (CurrSS == 3)
2220                RetSS = 27;
2221        else if (CurrSS == 2)
2222                RetSS = 18;
2223        else if (CurrSS == 1)
2224                RetSS = 9;
2225        else
2226                RetSS = CurrSS;
2227
2228        return RetSS;
2229}
2230
2231static long rtllib_translate_todbm(u8 signal_strength_index)
2232{
2233        long    signal_power;
2234
2235        signal_power = (long)((signal_strength_index + 1) >> 1);
2236        signal_power -= 95;
2237
2238        return signal_power;
2239}
2240
2241static inline int rtllib_network_init(
2242        struct rtllib_device *ieee,
2243        struct rtllib_probe_response *beacon,
2244        struct rtllib_network *network,
2245        struct rtllib_rx_stats *stats)
2246{
2247
2248        /*
2249        network->qos_data.active = 0;
2250        network->qos_data.supported = 0;
2251        network->qos_data.param_count = 0;
2252        network->qos_data.old_param_count = 0;
2253        */
2254        memset(&network->qos_data, 0, sizeof(struct rtllib_qos_data));
2255
2256        /* Pull out fixed field data */
2257        memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
2258        network->capability = le16_to_cpu(beacon->capability);
2259        network->last_scanned = jiffies;
2260        network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
2261        network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
2262        network->beacon_interval = le32_to_cpu(beacon->beacon_interval);
2263        /* Where to pull this? beacon->listen_interval;*/
2264        network->listen_interval = 0x0A;
2265        network->rates_len = network->rates_ex_len = 0;
2266        network->last_associate = 0;
2267        network->ssid_len = 0;
2268        network->hidden_ssid_len = 0;
2269        memset(network->hidden_ssid, 0, sizeof(network->hidden_ssid));
2270        network->flags = 0;
2271        network->atim_window = 0;
2272        network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
2273            0x3 : 0x0;
2274        network->berp_info_valid = false;
2275        network->broadcom_cap_exist = false;
2276        network->ralink_cap_exist = false;
2277        network->atheros_cap_exist = false;
2278        network->cisco_cap_exist = false;
2279        network->unknown_cap_exist = false;
2280        network->realtek_cap_exit = false;
2281        network->marvell_cap_exist = false;
2282        network->airgo_cap_exist = false;
2283        network->Turbo_Enable = 0;
2284        network->SignalStrength = stats->SignalStrength;
2285        network->RSSI = stats->SignalStrength;
2286        network->CountryIeLen = 0;
2287        memset(network->CountryIeBuf, 0, MAX_IE_LEN);
2288        HTInitializeBssDesc(&network->bssht);
2289        if (stats->freq == RTLLIB_52GHZ_BAND) {
2290                /* for A band (No DS info) */
2291                network->channel = stats->received_channel;
2292        } else
2293                network->flags |= NETWORK_HAS_CCK;
2294
2295        network->wpa_ie_len = 0;
2296        network->rsn_ie_len = 0;
2297        network->wzc_ie_len = 0;
2298
2299        if (rtllib_parse_info_param(ieee,
2300                        beacon->info_element,
2301                        (stats->len - sizeof(*beacon)),
2302                        network,
2303                        stats))
2304                return 1;
2305
2306        network->mode = 0;
2307        if (stats->freq == RTLLIB_52GHZ_BAND)
2308                network->mode = IEEE_A;
2309        else {
2310                if (network->flags & NETWORK_HAS_OFDM)
2311                        network->mode |= IEEE_G;
2312                if (network->flags & NETWORK_HAS_CCK)
2313                        network->mode |= IEEE_B;
2314        }
2315
2316        if (network->mode == 0) {
2317                RTLLIB_DEBUG_SCAN("Filtered out '%s (%pM)' "
2318                                     "network.\n",
2319                                     escape_essid(network->ssid,
2320                                                  network->ssid_len),
2321                                     network->bssid);
2322                return 1;
2323        }
2324
2325        if (network->bssht.bdSupportHT) {
2326                if (network->mode == IEEE_A)
2327                        network->mode = IEEE_N_5G;
2328                else if (network->mode & (IEEE_G | IEEE_B))
2329                        network->mode = IEEE_N_24G;
2330        }
2331        if (rtllib_is_empty_essid(network->ssid, network->ssid_len))
2332                network->flags |= NETWORK_EMPTY_ESSID;
2333        stats->signal = 30 + (stats->SignalStrength * 70) / 100;
2334        stats->noise = rtllib_translate_todbm((u8)(100-stats->signal)) - 25;
2335
2336        memcpy(&network->stats, stats, sizeof(network->stats));
2337
2338        return 0;
2339}
2340
2341static inline int is_same_network(struct rtllib_network *src,
2342                                  struct rtllib_network *dst, u8 ssidbroad)
2343{
2344        /* A network is only a duplicate if the channel, BSSID, ESSID
2345         * and the capability field (in particular IBSS and BSS) all match.
2346         * We treat all <hidden> with the same BSSID and channel
2347         * as one network */
2348        return (((src->ssid_len == dst->ssid_len) || (!ssidbroad)) &&
2349                (src->channel == dst->channel) &&
2350                !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
2351                (!memcmp(src->ssid, dst->ssid, src->ssid_len) ||
2352                (!ssidbroad)) &&
2353                ((src->capability & WLAN_CAPABILITY_IBSS) ==
2354                (dst->capability & WLAN_CAPABILITY_IBSS)) &&
2355                ((src->capability & WLAN_CAPABILITY_ESS) ==
2356                (dst->capability & WLAN_CAPABILITY_ESS)));
2357}
2358
2359static inline void update_ibss_network(struct rtllib_network *dst,
2360                                  struct rtllib_network *src)
2361{
2362        memcpy(&dst->stats, &src->stats, sizeof(struct rtllib_rx_stats));
2363        dst->last_scanned = jiffies;
2364}
2365
2366
2367static inline void update_network(struct rtllib_network *dst,
2368                                  struct rtllib_network *src)
2369{
2370        int qos_active;
2371        u8 old_param;
2372
2373        memcpy(&dst->stats, &src->stats, sizeof(struct rtllib_rx_stats));
2374        dst->capability = src->capability;
2375        memcpy(dst->rates, src->rates, src->rates_len);
2376        dst->rates_len = src->rates_len;
2377        memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
2378        dst->rates_ex_len = src->rates_ex_len;
2379        if (src->ssid_len > 0) {
2380                if (dst->ssid_len == 0) {
2381                        memset(dst->hidden_ssid, 0, sizeof(dst->hidden_ssid));
2382                        dst->hidden_ssid_len = src->ssid_len;
2383                        memcpy(dst->hidden_ssid, src->ssid, src->ssid_len);
2384                } else {
2385                        memset(dst->ssid, 0, dst->ssid_len);
2386                        dst->ssid_len = src->ssid_len;
2387                        memcpy(dst->ssid, src->ssid, src->ssid_len);
2388                }
2389        }
2390        dst->mode = src->mode;
2391        dst->flags = src->flags;
2392        dst->time_stamp[0] = src->time_stamp[0];
2393        dst->time_stamp[1] = src->time_stamp[1];
2394        if (src->flags & NETWORK_HAS_ERP_VALUE) {
2395                dst->erp_value = src->erp_value;
2396                dst->berp_info_valid = src->berp_info_valid = true;
2397        }
2398        dst->beacon_interval = src->beacon_interval;
2399        dst->listen_interval = src->listen_interval;
2400        dst->atim_window = src->atim_window;
2401        dst->dtim_period = src->dtim_period;
2402        dst->dtim_data = src->dtim_data;
2403        dst->last_dtim_sta_time = src->last_dtim_sta_time;
2404        memcpy(&dst->tim, &src->tim, sizeof(struct rtllib_tim_parameters));
2405
2406        dst->bssht.bdSupportHT = src->bssht.bdSupportHT;
2407        dst->bssht.bdRT2RTAggregation = src->bssht.bdRT2RTAggregation;
2408        dst->bssht.bdHTCapLen = src->bssht.bdHTCapLen;
2409        memcpy(dst->bssht.bdHTCapBuf, src->bssht.bdHTCapBuf,
2410               src->bssht.bdHTCapLen);
2411        dst->bssht.bdHTInfoLen = src->bssht.bdHTInfoLen;
2412        memcpy(dst->bssht.bdHTInfoBuf, src->bssht.bdHTInfoBuf,
2413               src->bssht.bdHTInfoLen);
2414        dst->bssht.bdHTSpecVer = src->bssht.bdHTSpecVer;
2415        dst->bssht.bdRT2RTLongSlotTime = src->bssht.bdRT2RTLongSlotTime;
2416        dst->broadcom_cap_exist = src->broadcom_cap_exist;
2417        dst->ralink_cap_exist = src->ralink_cap_exist;
2418        dst->atheros_cap_exist = src->atheros_cap_exist;
2419        dst->realtek_cap_exit = src->realtek_cap_exit;
2420        dst->marvell_cap_exist = src->marvell_cap_exist;
2421        dst->cisco_cap_exist = src->cisco_cap_exist;
2422        dst->airgo_cap_exist = src->airgo_cap_exist;
2423        dst->unknown_cap_exist = src->unknown_cap_exist;
2424        memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
2425        dst->wpa_ie_len = src->wpa_ie_len;
2426        memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
2427        dst->rsn_ie_len = src->rsn_ie_len;
2428        memcpy(dst->wzc_ie, src->wzc_ie, src->wzc_ie_len);
2429        dst->wzc_ie_len = src->wzc_ie_len;
2430
2431        dst->last_scanned = jiffies;
2432        /* qos related parameters */
2433        qos_active = dst->qos_data.active;
2434        old_param = dst->qos_data.param_count;
2435        dst->qos_data.supported = src->qos_data.supported;
2436        if (dst->flags & NETWORK_HAS_QOS_PARAMETERS)
2437                memcpy(&dst->qos_data, &src->qos_data,
2438                       sizeof(struct rtllib_qos_data));
2439        if (dst->qos_data.supported == 1) {
2440                if (dst->ssid_len)
2441                        RTLLIB_DEBUG_QOS
2442                                ("QoS the network %s is QoS supported\n",
2443                                dst->ssid);
2444                else
2445                        RTLLIB_DEBUG_QOS
2446                                ("QoS the network is QoS supported\n");
2447        }
2448        dst->qos_data.active = qos_active;
2449        dst->qos_data.old_param_count = old_param;
2450
2451        /* dst->last_associate is not overwritten */
2452        dst->wmm_info = src->wmm_info;
2453        if (src->wmm_param[0].ac_aci_acm_aifsn ||
2454           src->wmm_param[1].ac_aci_acm_aifsn ||
2455           src->wmm_param[2].ac_aci_acm_aifsn ||
2456           src->wmm_param[3].ac_aci_acm_aifsn)
2457                memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
2458
2459        dst->SignalStrength = src->SignalStrength;
2460        dst->RSSI = src->RSSI;
2461        dst->Turbo_Enable = src->Turbo_Enable;
2462
2463        dst->CountryIeLen = src->CountryIeLen;
2464        memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
2465
2466        dst->bWithAironetIE = src->bWithAironetIE;
2467        dst->bCkipSupported = src->bCkipSupported;
2468        memcpy(dst->CcxRmState, src->CcxRmState, 2);
2469        dst->bCcxRmEnable = src->bCcxRmEnable;
2470        dst->MBssidMask = src->MBssidMask;
2471        dst->bMBssidValid = src->bMBssidValid;
2472        memcpy(dst->MBssid, src->MBssid, 6);
2473        dst->bWithCcxVerNum = src->bWithCcxVerNum;
2474        dst->BssCcxVerNumber = src->BssCcxVerNumber;
2475}
2476
2477static inline int is_beacon(__le16 fc)
2478{
2479        return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == RTLLIB_STYPE_BEACON);
2480}
2481
2482static int IsPassiveChannel(struct rtllib_device *rtllib, u8 channel)
2483{
2484        if (MAX_CHANNEL_NUMBER < channel) {
2485                printk(KERN_INFO "%s(): Invalid Channel\n", __func__);
2486                return 0;
2487        }
2488
2489        if (rtllib->active_channel_map[channel] == 2)
2490                return 1;
2491
2492        return 0;
2493}
2494
2495int rtllib_legal_channel(struct rtllib_device *rtllib, u8 channel)
2496{
2497        if (MAX_CHANNEL_NUMBER < channel) {
2498                printk(KERN_INFO "%s(): Invalid Channel\n", __func__);
2499                return 0;
2500        }
2501        if (rtllib->active_channel_map[channel] > 0)
2502                return 1;
2503
2504        return 0;
2505}
2506EXPORT_SYMBOL(rtllib_legal_channel);
2507
2508static inline void rtllib_process_probe_response(
2509        struct rtllib_device *ieee,
2510        struct rtllib_probe_response *beacon,
2511        struct rtllib_rx_stats *stats)
2512{
2513        struct rtllib_network *target;
2514        struct rtllib_network *oldest = NULL;
2515        struct rtllib_info_element *info_element = &beacon->info_element[0];
2516        unsigned long flags;
2517        short renew;
2518        struct rtllib_network *network = kzalloc(sizeof(struct rtllib_network),
2519                                                 GFP_ATOMIC);
2520
2521        if (!network)
2522                return;
2523
2524        RTLLIB_DEBUG_SCAN(
2525                "'%s' ( %pM ): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
2526                escape_essid(info_element->data, info_element->len),
2527                beacon->header.addr3,
2528                (beacon->capability & (1<<0xf)) ? '1' : '0',
2529                (beacon->capability & (1<<0xe)) ? '1' : '0',
2530                (beacon->capability & (1<<0xd)) ? '1' : '0',
2531                (beacon->capability & (1<<0xc)) ? '1' : '0',
2532                (beacon->capability & (1<<0xb)) ? '1' : '0',
2533                (beacon->capability & (1<<0xa)) ? '1' : '0',
2534                (beacon->capability & (1<<0x9)) ? '1' : '0',
2535                (beacon->capability & (1<<0x8)) ? '1' : '0',
2536                (beacon->capability & (1<<0x7)) ? '1' : '0',
2537                (beacon->capability & (1<<0x6)) ? '1' : '0',
2538                (beacon->capability & (1<<0x5)) ? '1' : '0',
2539                (beacon->capability & (1<<0x4)) ? '1' : '0',
2540                (beacon->capability & (1<<0x3)) ? '1' : '0',
2541                (beacon->capability & (1<<0x2)) ? '1' : '0',
2542                (beacon->capability & (1<<0x1)) ? '1' : '0',
2543                (beacon->capability & (1<<0x0)) ? '1' : '0');
2544
2545        if (rtllib_network_init(ieee, beacon, network, stats)) {
2546                RTLLIB_DEBUG_SCAN("Dropped '%s' ( %pM) via %s.\n",
2547                                  escape_essid(info_element->data,
2548                                  info_element->len),
2549                                  beacon->header.addr3,
2550                                  WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2551                                  RTLLIB_STYPE_PROBE_RESP ?
2552                                  "PROBE RESPONSE" : "BEACON");
2553                goto free_network;
2554        }
2555
2556
2557        if (!rtllib_legal_channel(ieee, network->channel))
2558                goto free_network;
2559
2560        if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2561            RTLLIB_STYPE_PROBE_RESP) {
2562                if (IsPassiveChannel(ieee, network->channel)) {
2563                        printk(KERN_INFO "GetScanInfo(): For Global Domain, "
2564                               "filter probe response at channel(%d).\n",
2565                               network->channel);
2566                        goto free_network;
2567                }
2568        }
2569
2570        /* The network parsed correctly -- so now we scan our known networks
2571         * to see if we can find it in our list.
2572         *
2573         * NOTE:  This search is definitely not optimized.  Once its doing
2574         *      the "right thing" we'll optimize it for efficiency if
2575         *      necessary */
2576
2577        /* Search for this entry in the list and update it if it is
2578         * already there. */
2579
2580        spin_lock_irqsave(&ieee->lock, flags);
2581        if (is_same_network(&ieee->current_network, network,
2582           (network->ssid_len ? 1 : 0))) {
2583                update_network(&ieee->current_network, network);
2584                if ((ieee->current_network.mode == IEEE_N_24G ||
2585                     ieee->current_network.mode == IEEE_G)
2586                     && ieee->current_network.berp_info_valid) {
2587                        if (ieee->current_network.erp_value & ERP_UseProtection)
2588                                ieee->current_network.buseprotection = true;
2589                        else
2590                                ieee->current_network.buseprotection = false;
2591                }
2592                if (is_beacon(beacon->header.frame_ctl)) {
2593                        if (ieee->state >= RTLLIB_LINKED)
2594                                ieee->LinkDetectInfo.NumRecvBcnInPeriod++;
2595                }
2596        }
2597        list_for_each_entry(target, &ieee->network_list, list) {
2598                if (is_same_network(target, network,
2599                   (target->ssid_len ? 1 : 0)))
2600                        break;
2601                if ((oldest == NULL) ||
2602                    (target->last_scanned < oldest->last_scanned))
2603                        oldest = target;
2604        }
2605
2606        /* If we didn't find a match, then get a new network slot to initialize
2607         * with this beacon's information */
2608        if (&target->list == &ieee->network_list) {
2609                if (list_empty(&ieee->network_free_list)) {
2610                        /* If there are no more slots, expire the oldest */
2611                        list_del(&oldest->list);
2612                        target = oldest;
2613                        RTLLIB_DEBUG_SCAN("Expired '%s' ( %pM) from "
2614                                             "network list.\n",
2615                                             escape_essid(target->ssid,
2616                                                          target->ssid_len),
2617                                             target->bssid);
2618                } else {
2619                        /* Otherwise just pull from the free list */
2620                        target = list_entry(ieee->network_free_list.next,
2621                                            struct rtllib_network, list);
2622                        list_del(ieee->network_free_list.next);
2623                }
2624
2625
2626                RTLLIB_DEBUG_SCAN("Adding '%s' ( %pM) via %s.\n",
2627                                  escape_essid(network->ssid,
2628                                  network->ssid_len), network->bssid,
2629                                  WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2630                                  RTLLIB_STYPE_PROBE_RESP ?
2631                                  "PROBE RESPONSE" : "BEACON");
2632                memcpy(target, network, sizeof(*target));
2633                list_add_tail(&target->list, &ieee->network_list);
2634                if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
2635                        rtllib_softmac_new_net(ieee, network);
2636        } else {
2637                RTLLIB_DEBUG_SCAN("Updating '%s' ( %pM) via %s.\n",
2638                                  escape_essid(target->ssid,
2639                                  target->ssid_len), target->bssid,
2640                                  WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2641                                  RTLLIB_STYPE_PROBE_RESP ?
2642                                  "PROBE RESPONSE" : "BEACON");
2643
2644                /* we have an entry and we are going to update it. But this
2645                 *  entry may be already expired. In this case we do the same
2646                 * as we found a new net and call the new_net handler
2647                 */
2648                renew = !time_after(target->last_scanned + ieee->scan_age,
2649                                    jiffies);
2650                if ((!target->ssid_len) &&
2651                    (((network->ssid_len > 0) && (target->hidden_ssid_len == 0))
2652                    || ((ieee->current_network.ssid_len == network->ssid_len) &&
2653                    (strncmp(ieee->current_network.ssid, network->ssid,
2654                    network->ssid_len) == 0) &&
2655                    (ieee->state == RTLLIB_NOLINK))))
2656                        renew = 1;
2657                update_network(target, network);
2658                if (renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
2659                        rtllib_softmac_new_net(ieee, network);
2660        }
2661
2662        spin_unlock_irqrestore(&ieee->lock, flags);
2663        if (is_beacon(beacon->header.frame_ctl) &&
2664            is_same_network(&ieee->current_network, network,
2665            (network->ssid_len ? 1 : 0)) &&
2666            (ieee->state == RTLLIB_LINKED)) {
2667                if (ieee->handle_beacon != NULL)
2668                        ieee->handle_beacon(ieee->dev, beacon,
2669                                            &ieee->current_network);
2670        }
2671free_network:
2672        kfree(network);
2673        return;
2674}
2675
2676void rtllib_rx_mgt(struct rtllib_device *ieee,
2677                      struct sk_buff *skb,
2678                      struct rtllib_rx_stats *stats)
2679{
2680        struct rtllib_hdr_4addr *header = (struct rtllib_hdr_4addr *)skb->data ;
2681
2682        if (WLAN_FC_GET_STYPE(header->frame_ctl) != RTLLIB_STYPE_PROBE_RESP &&
2683            WLAN_FC_GET_STYPE(header->frame_ctl) != RTLLIB_STYPE_BEACON)
2684                ieee->last_rx_ps_time = jiffies;
2685
2686        switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
2687
2688        case RTLLIB_STYPE_BEACON:
2689                RTLLIB_DEBUG_MGMT("received BEACON (%d)\n",
2690                                  WLAN_FC_GET_STYPE(header->frame_ctl));
2691                RTLLIB_DEBUG_SCAN("Beacon\n");
2692                rtllib_process_probe_response(
2693                                ieee, (struct rtllib_probe_response *)header,
2694                                stats);
2695
2696                if (ieee->sta_sleep || (ieee->ps != RTLLIB_PS_DISABLED &&
2697                    ieee->iw_mode == IW_MODE_INFRA &&
2698                    ieee->state == RTLLIB_LINKED))
2699                        tasklet_schedule(&ieee->ps_task);
2700
2701                break;
2702
2703        case RTLLIB_STYPE_PROBE_RESP:
2704                RTLLIB_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
2705                        WLAN_FC_GET_STYPE(header->frame_ctl));
2706                RTLLIB_DEBUG_SCAN("Probe response\n");
2707                rtllib_process_probe_response(ieee,
2708                              (struct rtllib_probe_response *)header, stats);
2709                break;
2710        case RTLLIB_STYPE_PROBE_REQ:
2711                RTLLIB_DEBUG_MGMT("received PROBE RESQUEST (%d)\n",
2712                                  WLAN_FC_GET_STYPE(header->frame_ctl));
2713                RTLLIB_DEBUG_SCAN("Probe request\n");
2714                if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2715                    ((ieee->iw_mode == IW_MODE_ADHOC ||
2716                    ieee->iw_mode == IW_MODE_MASTER) &&
2717                    ieee->state == RTLLIB_LINKED))
2718                        rtllib_rx_probe_rq(ieee, skb);
2719                break;
2720        }
2721}
2722