linux/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
<<
>>
Prefs
   1/******************************************************************************
   2
   3  Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
   4
   5  This program is free software; you can redistribute it and/or modify it
   6  under the terms of version 2 of the GNU General Public License as
   7  published by the Free Software Foundation.
   8
   9  This program is distributed in the hope that it will be useful, but WITHOUT
  10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12  more details.
  13
  14  You should have received a copy of the GNU General Public License along with
  15  this program; if not, write to the Free Software Foundation, Inc., 59
  16  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17
  18  The full GNU General Public License is included in this distribution in the
  19  file called LICENSE.
  20
  21  Contact Information:
  22  James P. Ketrenos <ipw2100-admin@linux.intel.com>
  23  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  24
  25******************************************************************************
  26
  27  Few modifications for Realtek's Wi-Fi drivers by
  28  Andrea Merello <andreamrl@tiscali.it>
  29
  30  A special thanks goes to Realtek for their support !
  31
  32******************************************************************************/
  33
  34#include <linux/compiler.h>
  35//#include <linux/config.h>
  36#include <linux/errno.h>
  37#include <linux/if_arp.h>
  38#include <linux/in6.h>
  39#include <linux/in.h>
  40#include <linux/ip.h>
  41#include <linux/kernel.h>
  42#include <linux/module.h>
  43#include <linux/netdevice.h>
  44#include <linux/pci.h>
  45#include <linux/proc_fs.h>
  46#include <linux/skbuff.h>
  47#include <linux/slab.h>
  48#include <linux/tcp.h>
  49#include <linux/types.h>
  50#include <linux/wireless.h>
  51#include <linux/etherdevice.h>
  52#include <asm/uaccess.h>
  53#include <linux/if_vlan.h>
  54
  55#include "ieee80211.h"
  56
  57
  58/*
  59
  60
  61802.11 Data Frame
  62
  63
  64802.11 frame_contorl for data frames - 2 bytes
  65     ,-----------------------------------------------------------------------------------------.
  66bits | 0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |  a  |  b  |  c  |  d  |  e   |
  67     |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
  68val  | 0  |  0  |  0  |  1  |  x  |  0  |  0  |  0  |  1  |  0  |  x  |  x  |  x  |  x  |  x   |
  69     |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
  70desc | ^-ver-^  |  ^type-^  |  ^-----subtype-----^  | to  |from |more |retry| pwr |more |wep   |
  71     |          |           | x=0 data,x=1 data+ack | DS  | DS  |frag |     | mgm |data |      |
  72     '-----------------------------------------------------------------------------------------'
  73                                                    /\
  74                                                    |
  75802.11 Data Frame                                   |
  76           ,--------- 'ctrl' expands to >-----------'
  77          |
  78      ,--'---,-------------------------------------------------------------.
  79Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
  80      |------|------|---------|---------|---------|------|---------|------|
  81Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  Frame  |  fcs |
  82      |      | tion | (BSSID) |         |         | ence |  data   |      |
  83      `--------------------------------------------------|         |------'
  84Total: 28 non-data bytes                                 `----.----'
  85                                                              |
  86       .- 'Frame data' expands to <---------------------------'
  87       |
  88       V
  89      ,---------------------------------------------------.
  90Bytes |  1   |  1   |    1    |    3     |  2   |  0-2304 |
  91      |------|------|---------|----------|------|---------|
  92Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP      |
  93      | DSAP | SSAP |         |          |      | Packet  |
  94      | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8|      |         |
  95      `-----------------------------------------|         |
  96Total: 8 non-data bytes                         `----.----'
  97                                                     |
  98       .- 'IP Packet' expands, if WEP enabled, to <--'
  99       |
 100       V
 101      ,-----------------------.
 102Bytes |  4  |   0-2296  |  4  |
 103      |-----|-----------|-----|
 104Desc. | IV  | Encrypted | ICV |
 105      |     | IP Packet |     |
 106      `-----------------------'
 107Total: 8 non-data bytes
 108
 109
 110802.3 Ethernet Data Frame
 111
 112      ,-----------------------------------------.
 113Bytes |   6   |   6   |  2   |  Variable |   4  |
 114      |-------|-------|------|-----------|------|
 115Desc. | Dest. | Source| Type | IP Packet |  fcs |
 116      |  MAC  |  MAC  |      |           |      |
 117      `-----------------------------------------'
 118Total: 18 non-data bytes
 119
 120In the event that fragmentation is required, the incoming payload is split into
 121N parts of size ieee->fts.  The first fragment contains the SNAP header and the
 122remaining packets are just data.
 123
 124If encryption is enabled, each fragment payload size is reduced by enough space
 125to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
 126So if you have 1500 bytes of payload with ieee->fts set to 500 without
 127encryption it will take 3 frames.  With WEP it will take 4 frames as the
 128payload of each frame is reduced to 492 bytes.
 129
 130* SKB visualization
 131*
 132*  ,- skb->data
 133* |
 134* |    ETHERNET HEADER        ,-<-- PAYLOAD
 135* |                           |     14 bytes from skb->data
 136* |  2 bytes for Type --> ,T. |     (sizeof ethhdr)
 137* |                       | | |
 138* |,-Dest.--. ,--Src.---. | | |
 139* |  6 bytes| | 6 bytes | | | |
 140* v         | |         | | | |
 141* 0         | v       1 | v | v           2
 142* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
 143*     ^     | ^         | ^ |
 144*     |     | |         | | |
 145*     |     | |         | `T' <---- 2 bytes for Type
 146*     |     | |         |
 147*     |     | '---SNAP--' <-------- 6 bytes for SNAP
 148*     |     |
 149*     `-IV--' <-------------------- 4 bytes for IV (WEP)
 150*
 151*      SNAP HEADER
 152*
 153*/
 154
 155static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
 156static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
 157
 158static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
 159{
 160        struct ieee80211_snap_hdr *snap;
 161        u8 *oui;
 162
 163        snap = (struct ieee80211_snap_hdr *)data;
 164        snap->dsap = 0xaa;
 165        snap->ssap = 0xaa;
 166        snap->ctrl = 0x03;
 167
 168        if (h_proto == 0x8137 || h_proto == 0x80f3)
 169                oui = P802_1H_OUI;
 170        else
 171                oui = RFC1042_OUI;
 172        snap->oui[0] = oui[0];
 173        snap->oui[1] = oui[1];
 174        snap->oui[2] = oui[2];
 175
 176        *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
 177
 178        return SNAP_SIZE + sizeof(u16);
 179}
 180
 181int ieee80211_encrypt_fragment(
 182        struct ieee80211_device *ieee,
 183        struct sk_buff *frag,
 184        int hdr_len)
 185{
 186        struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
 187        int res;
 188
 189 /*added to care about null crypt condition, to solve that system hangs when shared keys error*/
 190        if (!crypt || !crypt->ops)
 191        return -1;
 192
 193#ifdef CONFIG_IEEE80211_CRYPT_TKIP
 194        struct ieee80211_hdr_4addr *header;
 195
 196        if (ieee->tkip_countermeasures &&
 197            crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
 198                header = (struct ieee80211_hdr_4addr *)frag->data;
 199                if (net_ratelimit()) {
 200                        printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
 201                               "TX packet to %pM\n",
 202                               ieee->dev->name, header->addr1);
 203                }
 204                return -1;
 205        }
 206#endif
 207        /* To encrypt, frame format is:
 208         * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
 209
 210        // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
 211        /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
 212         * call both MSDU and MPDU encryption functions from here. */
 213        atomic_inc(&crypt->refcnt);
 214        res = 0;
 215        if (crypt->ops->encrypt_msdu)
 216                res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
 217        if (res == 0 && crypt->ops->encrypt_mpdu)
 218                res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
 219
 220        atomic_dec(&crypt->refcnt);
 221        if (res < 0) {
 222                printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
 223                       ieee->dev->name, frag->len);
 224                ieee->ieee_stats.tx_discards++;
 225                return -1;
 226        }
 227
 228        return 0;
 229}
 230
 231
 232void ieee80211_txb_free(struct ieee80211_txb *txb) {
 233        int i;
 234        if (unlikely(!txb))
 235                return;
 236        for (i = 0; i < txb->nr_frags; i++)
 237                if (txb->fragments[i])
 238                        dev_kfree_skb_any(txb->fragments[i]);
 239        kfree(txb);
 240}
 241
 242struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
 243                                          int gfp_mask)
 244{
 245        struct ieee80211_txb *txb;
 246        int i;
 247        txb = kmalloc(
 248                sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
 249                gfp_mask);
 250        if (!txb)
 251                return NULL;
 252
 253        memset(txb, 0, sizeof(struct ieee80211_txb));
 254        txb->nr_frags = nr_frags;
 255        txb->frag_size = txb_size;
 256
 257        for (i = 0; i < nr_frags; i++) {
 258                txb->fragments[i] = dev_alloc_skb(txb_size);
 259                if (unlikely(!txb->fragments[i])) {
 260                        i--;
 261                        break;
 262                }
 263        }
 264        if (unlikely(i != nr_frags)) {
 265                while (i >= 0)
 266                        dev_kfree_skb_any(txb->fragments[i--]);
 267                kfree(txb);
 268                return NULL;
 269        }
 270        return txb;
 271}
 272
 273// Classify the to-be send data packet
 274// Need to acquire the sent queue index.
 275static int
 276ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
 277{
 278  struct ether_header *eh = (struct ether_header*)skb->data;
 279  unsigned int wme_UP = 0;
 280
 281  if(!network->QoS_Enable) {
 282     skb->priority = 0;
 283     return(wme_UP);
 284  }
 285
 286  if(eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
 287    const struct iphdr *ih = (struct iphdr*)(skb->data + \
 288                    sizeof(struct ether_header));
 289    wme_UP = (ih->tos >> 5)&0x07;
 290  } else if (skb_vlan_tag_present(skb)) {//vtag packet
 291#ifndef VLAN_PRI_SHIFT
 292#define VLAN_PRI_SHIFT  13              /* Shift to find VLAN user priority */
 293#define VLAN_PRI_MASK   7               /* Mask for user priority bits in VLAN */
 294#endif
 295        u32 tag = skb_vlan_tag_get(skb);
 296        wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
 297  } else if(ETH_P_PAE ==  ntohs(((struct ethhdr *)skb->data)->h_proto)) {
 298    //printk(KERN_WARNING "type = normal packet\n");
 299    wme_UP = 7;
 300  }
 301
 302  skb->priority = wme_UP;
 303  return(wme_UP);
 304}
 305
 306/* SKBs are added to the ieee->tx_queue. */
 307int ieee80211_rtl_xmit(struct sk_buff *skb,
 308                   struct net_device *dev)
 309{
 310        struct ieee80211_device *ieee = netdev_priv(dev);
 311        struct ieee80211_txb *txb = NULL;
 312        struct ieee80211_hdr_3addrqos *frag_hdr;
 313        int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
 314        unsigned long flags;
 315        struct net_device_stats *stats = &ieee->stats;
 316        int ether_type, encrypt;
 317        int bytes, fc, qos_ctl, hdr_len;
 318        struct sk_buff *skb_frag;
 319        struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
 320                .duration_id = 0,
 321                .seq_ctl = 0,
 322                .qos_ctl = 0
 323        };
 324        u8 dest[ETH_ALEN], src[ETH_ALEN];
 325
 326        struct ieee80211_crypt_data* crypt;
 327
 328        //printk(KERN_WARNING "upper layer packet!\n");
 329        spin_lock_irqsave(&ieee->lock, flags);
 330
 331        /* If there is no driver handler to take the TXB, don't bother
 332         * creating it... */
 333        if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
 334           ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
 335                printk(KERN_WARNING "%s: No xmit handler.\n",
 336                       ieee->dev->name);
 337                goto success;
 338        }
 339
 340        ieee80211_classify(skb,&ieee->current_network);
 341        if(likely(ieee->raw_tx == 0)){
 342
 343                if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
 344                        printk(KERN_WARNING "%s: skb too small (%d).\n",
 345                        ieee->dev->name, skb->len);
 346                        goto success;
 347                }
 348
 349                ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
 350
 351                crypt = ieee->crypt[ieee->tx_keyidx];
 352
 353                encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
 354                        ieee->host_encrypt && crypt && crypt->ops;
 355
 356                if (!encrypt && ieee->ieee802_1x &&
 357                ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
 358                        stats->tx_dropped++;
 359                        goto success;
 360                }
 361
 362        #ifdef CONFIG_IEEE80211_DEBUG
 363                if (crypt && !encrypt && ether_type == ETH_P_PAE) {
 364                        struct eapol *eap = (struct eapol *)(skb->data +
 365                                sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
 366                        IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
 367                                eap_get_type(eap->type));
 368                }
 369        #endif
 370
 371                /* Save source and destination addresses */
 372                memcpy(&dest, skb->data, ETH_ALEN);
 373                memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
 374
 375                /* Advance the SKB to the start of the payload */
 376                skb_pull(skb, sizeof(struct ethhdr));
 377
 378                /* Determine total amount of storage required for TXB packets */
 379                bytes = skb->len + SNAP_SIZE + sizeof(u16);
 380
 381                if(ieee->current_network.QoS_Enable) {
 382                        if (encrypt)
 383                                fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
 384                                        IEEE80211_FCTL_WEP;
 385                        else
 386                                fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
 387
 388                } else {
 389                        if (encrypt)
 390                                fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
 391                                        IEEE80211_FCTL_WEP;
 392                        else
 393                                fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
 394                }
 395
 396                if (ieee->iw_mode == IW_MODE_INFRA) {
 397                        fc |= IEEE80211_FCTL_TODS;
 398                        /* To DS: Addr1 = BSSID, Addr2 = SA,
 399                        Addr3 = DA */
 400                        memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
 401                        memcpy(&header.addr2, &src, ETH_ALEN);
 402                        memcpy(&header.addr3, &dest, ETH_ALEN);
 403                } else if (ieee->iw_mode == IW_MODE_ADHOC) {
 404                        /* not From/To DS: Addr1 = DA, Addr2 = SA,
 405                        Addr3 = BSSID */
 406                        memcpy(&header.addr1, dest, ETH_ALEN);
 407                        memcpy(&header.addr2, src, ETH_ALEN);
 408                        memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
 409                }
 410        //      printk(KERN_WARNING "essid MAC address is %pM", &header.addr1);
 411                header.frame_ctl = cpu_to_le16(fc);
 412                //hdr_len = IEEE80211_3ADDR_LEN;
 413
 414                /* Determine fragmentation size based on destination (multicast
 415                * and broadcast are not fragmented) */
 416                if (is_multicast_ether_addr(header.addr1)) {
 417                        frag_size = MAX_FRAG_THRESHOLD;
 418                        qos_ctl = QOS_CTL_NOTCONTAIN_ACK;
 419                }
 420                else {
 421                        //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
 422                        frag_size = ieee->fts;//default:392
 423                        qos_ctl = 0;
 424                }
 425
 426                if (ieee->current_network.QoS_Enable)   {
 427                        hdr_len = IEEE80211_3ADDR_LEN + 2;
 428                        /* skb->priority is set in the ieee80211_classify() */
 429                        qos_ctl |= skb->priority;
 430                        header.qos_ctl = cpu_to_le16(qos_ctl);
 431                } else {
 432                        hdr_len = IEEE80211_3ADDR_LEN;
 433                }
 434
 435                /* Determine amount of payload per fragment.  Regardless of if
 436                * this stack is providing the full 802.11 header, one will
 437                * eventually be affixed to this fragment -- so we must account for
 438                * it when determining the amount of payload space. */
 439                //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
 440                bytes_per_frag = frag_size - hdr_len;
 441                if (ieee->config &
 442                (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
 443                        bytes_per_frag -= IEEE80211_FCS_LEN;
 444
 445                /* Each fragment may need to have room for encryption pre/postfix */
 446                if (encrypt)
 447                        bytes_per_frag -= crypt->ops->extra_prefix_len +
 448                                crypt->ops->extra_postfix_len;
 449
 450                /* Number of fragments is the total bytes_per_frag /
 451                * payload_per_fragment */
 452                nr_frags = bytes / bytes_per_frag;
 453                bytes_last_frag = bytes % bytes_per_frag;
 454                if (bytes_last_frag)
 455                        nr_frags++;
 456                else
 457                        bytes_last_frag = bytes_per_frag;
 458
 459                /* When we allocate the TXB we allocate enough space for the reserve
 460                * and full fragment bytes (bytes_per_frag doesn't include prefix,
 461                * postfix, header, FCS, etc.) */
 462                txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
 463                if (unlikely(!txb)) {
 464                        printk(KERN_WARNING "%s: Could not allocate TXB\n",
 465                        ieee->dev->name);
 466                        goto failed;
 467                }
 468                txb->encrypted = encrypt;
 469                txb->payload_size = bytes;
 470
 471                for (i = 0; i < nr_frags; i++) {
 472                        skb_frag = txb->fragments[i];
 473                        skb_frag->priority = UP2AC(skb->priority);
 474                        if (encrypt)
 475                                skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
 476
 477                        frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
 478                        memcpy(frag_hdr, &header, hdr_len);
 479
 480                        /* If this is not the last fragment, then add the MOREFRAGS
 481                        * bit to the frame control */
 482                        if (i != nr_frags - 1) {
 483                                frag_hdr->frame_ctl = cpu_to_le16(
 484                                        fc | IEEE80211_FCTL_MOREFRAGS);
 485                                bytes = bytes_per_frag;
 486
 487                        } else {
 488                                /* The last fragment takes the remaining length */
 489                                bytes = bytes_last_frag;
 490                        }
 491                        if(ieee->current_network.QoS_Enable) {
 492                          // add 1 only indicate to corresponding seq number control 2006/7/12
 493                          frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
 494                          //printk(KERN_WARNING "skb->priority = %d,", skb->priority);
 495                          //printk(KERN_WARNING "type:%d: seq = %d\n",UP2AC(skb->priority),ieee->seq_ctrl[UP2AC(skb->priority)+1]);
 496                        } else {
 497                          frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
 498                        }
 499                        //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
 500                        //
 501
 502                        /* Put a SNAP header on the first fragment */
 503                        if (i == 0) {
 504                                ieee80211_put_snap(
 505                                        skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
 506                                        ether_type);
 507                                bytes -= SNAP_SIZE + sizeof(u16);
 508                        }
 509
 510                        memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
 511
 512                        /* Advance the SKB... */
 513                        skb_pull(skb, bytes);
 514
 515                        /* Encryption routine will move the header forward in order
 516                        * to insert the IV between the header and the payload */
 517                        if (encrypt)
 518                                ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
 519                        if (ieee->config &
 520                        (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
 521                                skb_put(skb_frag, 4);
 522                }
 523                // Advance sequence number in data frame.
 524                //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
 525                if (ieee->current_network.QoS_Enable) {
 526                  if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
 527                        ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
 528                  else
 529                        ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
 530                } else {
 531                  if (ieee->seq_ctrl[0] == 0xFFF)
 532                        ieee->seq_ctrl[0] = 0;
 533                  else
 534                        ieee->seq_ctrl[0]++;
 535                }
 536                //---
 537        }else{
 538                if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
 539                        printk(KERN_WARNING "%s: skb too small (%d).\n",
 540                        ieee->dev->name, skb->len);
 541                        goto success;
 542                }
 543
 544                txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
 545                if(!txb){
 546                        printk(KERN_WARNING "%s: Could not allocate TXB\n",
 547                        ieee->dev->name);
 548                        goto failed;
 549                }
 550
 551                txb->encrypted = 0;
 552                txb->payload_size = skb->len;
 553                memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
 554        }
 555
 556 success:
 557        spin_unlock_irqrestore(&ieee->lock, flags);
 558                dev_kfree_skb_any(skb);
 559        if (txb) {
 560                if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
 561                        ieee80211_softmac_xmit(txb, ieee);
 562                }else{
 563                        if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
 564                                stats->tx_packets++;
 565                                stats->tx_bytes += txb->payload_size;
 566                                return NETDEV_TX_OK;
 567                        }
 568                        ieee80211_txb_free(txb);
 569                }
 570        }
 571
 572        return NETDEV_TX_OK;
 573
 574 failed:
 575        spin_unlock_irqrestore(&ieee->lock, flags);
 576        netif_stop_queue(dev);
 577        stats->tx_errors++;
 578        return NETDEV_TX_BUSY;
 579
 580}
 581