linux/drivers/staging/rtl8192u/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        if (!(crypt && crypt->ops))
 190        {
 191                printk("=========>%s(), crypt is null\n", __FUNCTION__);
 192                return -1;
 193        }
 194#ifdef CONFIG_IEEE80211_CRYPT_TKIP
 195        struct ieee80211_hdr *header;
 196
 197        if (ieee->tkip_countermeasures &&
 198            crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
 199                header = (struct ieee80211_hdr *) frag->data;
 200                if (net_ratelimit()) {
 201                        printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
 202                               "TX packet to %pM\n",
 203                               ieee->dev->name, header->addr1);
 204                }
 205                return -1;
 206        }
 207#endif
 208        /* To encrypt, frame format is:
 209         * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
 210
 211        // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
 212        /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
 213         * call both MSDU and MPDU encryption functions from here. */
 214        atomic_inc(&crypt->refcnt);
 215        res = 0;
 216        if (crypt->ops->encrypt_msdu)
 217                res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
 218        if (res == 0 && crypt->ops->encrypt_mpdu)
 219                res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
 220
 221        atomic_dec(&crypt->refcnt);
 222        if (res < 0) {
 223                printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
 224                       ieee->dev->name, frag->len);
 225                ieee->ieee_stats.tx_discards++;
 226                return -1;
 227        }
 228
 229        return 0;
 230}
 231
 232
 233void ieee80211_txb_free(struct ieee80211_txb *txb) {
 234        //int i;
 235        if (unlikely(!txb))
 236                return;
 237        kfree(txb);
 238}
 239
 240struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
 241                                          int gfp_mask)
 242{
 243        struct ieee80211_txb *txb;
 244        int i;
 245        txb = kmalloc(
 246                sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
 247                gfp_mask);
 248        if (!txb)
 249                return NULL;
 250
 251        memset(txb, 0, sizeof(struct ieee80211_txb));
 252        txb->nr_frags = nr_frags;
 253        txb->frag_size = txb_size;
 254
 255        for (i = 0; i < nr_frags; i++) {
 256                txb->fragments[i] = dev_alloc_skb(txb_size);
 257                if (unlikely(!txb->fragments[i])) {
 258                        i--;
 259                        break;
 260                }
 261                memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
 262        }
 263        if (unlikely(i != nr_frags)) {
 264                while (i >= 0)
 265                        dev_kfree_skb_any(txb->fragments[i--]);
 266                kfree(txb);
 267                return NULL;
 268        }
 269        return txb;
 270}
 271
 272// Classify the to-be send data packet
 273// Need to acquire the sent queue index.
 274static int
 275ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
 276{
 277        struct ethhdr *eth;
 278        struct iphdr *ip;
 279        eth = (struct ethhdr *)skb->data;
 280        if (eth->h_proto != htons(ETH_P_IP))
 281                return 0;
 282
 283//      IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
 284        ip = ip_hdr(skb);
 285        switch (ip->tos & 0xfc) {
 286                case 0x20:
 287                        return 2;
 288                case 0x40:
 289                        return 1;
 290                case 0x60:
 291                        return 3;
 292                case 0x80:
 293                        return 4;
 294                case 0xa0:
 295                        return 5;
 296                case 0xc0:
 297                        return 6;
 298                case 0xe0:
 299                        return 7;
 300                default:
 301                        return 0;
 302        }
 303}
 304
 305#define SN_LESS(a, b)           (((a-b)&0x800)!=0)
 306void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
 307{
 308        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
 309        PTX_TS_RECORD                   pTxTs = NULL;
 310        struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data;
 311
 312        if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
 313                return;
 314        if (!IsQoSDataFrame(skb->data))
 315                return;
 316
 317        if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1))
 318                return;
 319        //check packet and mode later
 320#ifdef TO_DO_LIST
 321        if(pTcb->PacketLength >= 4096)
 322                return;
 323        // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
 324        if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
 325                return;
 326#endif
 327        if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
 328        {
 329                return;
 330        }
 331        if(pHTInfo->bCurrentAMPDUEnable)
 332        {
 333                if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
 334                {
 335                        printk("===>can't get TS\n");
 336                        return;
 337                }
 338                if (pTxTs->TxAdmittedBARecord.bValid == false)
 339                {
 340                        TsStartAddBaProcess(ieee, pTxTs);
 341                        goto FORCED_AGG_SETTING;
 342                }
 343                else if (pTxTs->bUsingBa == false)
 344                {
 345                        if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
 346                                pTxTs->bUsingBa = true;
 347                        else
 348                                goto FORCED_AGG_SETTING;
 349                }
 350
 351                if (ieee->iw_mode == IW_MODE_INFRA)
 352                {
 353                        tcb_desc->bAMPDUEnable = true;
 354                        tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
 355                        tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
 356                }
 357        }
 358FORCED_AGG_SETTING:
 359        switch(pHTInfo->ForcedAMPDUMode )
 360        {
 361                case HT_AGG_AUTO:
 362                        break;
 363
 364                case HT_AGG_FORCE_ENABLE:
 365                        tcb_desc->bAMPDUEnable = true;
 366                        tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
 367                        tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
 368                        break;
 369
 370                case HT_AGG_FORCE_DISABLE:
 371                        tcb_desc->bAMPDUEnable = false;
 372                        tcb_desc->ampdu_density = 0;
 373                        tcb_desc->ampdu_factor = 0;
 374                        break;
 375
 376        }
 377                return;
 378}
 379
 380extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
 381{
 382        tcb_desc->bUseShortPreamble = false;
 383        if (tcb_desc->data_rate == 2)
 384        {//// 1M can only use Long Preamble. 11B spec
 385                return;
 386        }
 387        else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
 388        {
 389                tcb_desc->bUseShortPreamble = true;
 390        }
 391        return;
 392}
 393extern  void
 394ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
 395{
 396        PRT_HIGH_THROUGHPUT             pHTInfo = ieee->pHTInfo;
 397
 398        tcb_desc->bUseShortGI           = false;
 399
 400        if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
 401                return;
 402
 403        if(pHTInfo->bForcedShortGI)
 404        {
 405                tcb_desc->bUseShortGI = true;
 406                return;
 407        }
 408
 409        if((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz)
 410                tcb_desc->bUseShortGI = true;
 411        else if((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz)
 412                tcb_desc->bUseShortGI = true;
 413}
 414
 415void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
 416{
 417        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
 418
 419        tcb_desc->bPacketBW = false;
 420
 421        if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
 422                return;
 423
 424        if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
 425                return;
 426
 427        if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
 428                return;
 429        //BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
 430        if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
 431                tcb_desc->bPacketBW = true;
 432        return;
 433}
 434
 435void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
 436{
 437        // Common Settings
 438        tcb_desc->bRTSSTBC                      = false;
 439        tcb_desc->bRTSUseShortGI                = false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
 440        tcb_desc->bCTSEnable                    = false; // Most of protection using RTS/CTS
 441        tcb_desc->RTSSC                         = 0;            // 20MHz: Don't care;  40MHz: Duplicate.
 442        tcb_desc->bRTSBW                        = false; // RTS frame bandwidth is always 20MHz
 443
 444        if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
 445                return;
 446
 447        if (is_broadcast_ether_addr(skb->data+16))  //check addr3 as infrastructure add3 is DA.
 448                return;
 449
 450        if (ieee->mode < IEEE_N_24G) //b, g mode
 451        {
 452                        // (1) RTS_Threshold is compared to the MPDU, not MSDU.
 453                        // (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame.
 454                        //              Other fragments are protected by previous fragment.
 455                        //              So we only need to check the length of first fragment.
 456                if (skb->len > ieee->rts)
 457                {
 458                        tcb_desc->bRTSEnable = true;
 459                        tcb_desc->rts_rate = MGN_24M;
 460                }
 461                else if (ieee->current_network.buseprotection)
 462                {
 463                        // Use CTS-to-SELF in protection mode.
 464                        tcb_desc->bRTSEnable = true;
 465                        tcb_desc->bCTSEnable = true;
 466                        tcb_desc->rts_rate = MGN_24M;
 467                }
 468                //otherwise return;
 469                return;
 470        }
 471        else
 472        {// 11n High throughput case.
 473                PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
 474                while (true)
 475                {
 476                        //check ERP protection
 477                        if (ieee->current_network.buseprotection)
 478                        {// CTS-to-SELF
 479                                tcb_desc->bRTSEnable = true;
 480                                tcb_desc->bCTSEnable = true;
 481                                tcb_desc->rts_rate = MGN_24M;
 482                                break;
 483                        }
 484                        //check HT op mode
 485                        if(pHTInfo->bCurrentHTSupport  && pHTInfo->bEnableHT)
 486                        {
 487                                u8 HTOpMode = pHTInfo->CurrentOpMode;
 488                                if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
 489                                                        (!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
 490                                {
 491                                        tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
 492                                        tcb_desc->bRTSEnable = true;
 493                                        break;
 494                                }
 495                        }
 496                        //check rts
 497                        if (skb->len > ieee->rts)
 498                        {
 499                                tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
 500                                tcb_desc->bRTSEnable = true;
 501                                break;
 502                        }
 503                        //to do list: check MIMO power save condition.
 504                        //check AMPDU aggregation for TXOP
 505                        if(tcb_desc->bAMPDUEnable)
 506                        {
 507                                tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
 508                                // According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
 509                                // throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
 510                                tcb_desc->bRTSEnable = false;
 511                                break;
 512                        }
 513                        //check IOT action
 514                        if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
 515                        {
 516                                tcb_desc->bCTSEnable    = true;
 517                                tcb_desc->rts_rate  =   MGN_24M;
 518                                tcb_desc->bRTSEnable = true;
 519                                break;
 520                        }
 521                        // Totally no protection case!!
 522                        goto NO_PROTECTION;
 523                }
 524                }
 525        // For test , CTS replace with RTS
 526        if( 0 )
 527        {
 528                tcb_desc->bCTSEnable    = true;
 529                tcb_desc->rts_rate = MGN_24M;
 530                tcb_desc->bRTSEnable    = true;
 531        }
 532        if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
 533                tcb_desc->bUseShortPreamble = true;
 534        if (ieee->mode == IW_MODE_MASTER)
 535                        goto NO_PROTECTION;
 536        return;
 537NO_PROTECTION:
 538        tcb_desc->bRTSEnable    = false;
 539        tcb_desc->bCTSEnable    = false;
 540        tcb_desc->rts_rate              = 0;
 541        tcb_desc->RTSSC         = 0;
 542        tcb_desc->bRTSBW                = false;
 543}
 544
 545
 546void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
 547{
 548#ifdef TO_DO_LIST
 549        if(!IsDataFrame(pFrame))
 550        {
 551                pTcb->bTxDisableRateFallBack = TRUE;
 552                pTcb->bTxUseDriverAssingedRate = TRUE;
 553                pTcb->RATRIndex = 7;
 554                return;
 555        }
 556
 557        if(pMgntInfo->ForcedDataRate!= 0)
 558        {
 559                pTcb->bTxDisableRateFallBack = TRUE;
 560                pTcb->bTxUseDriverAssingedRate = TRUE;
 561                return;
 562        }
 563#endif
 564        if(ieee->bTxDisableRateFallBack)
 565                tcb_desc->bTxDisableRateFallBack = true;
 566
 567        if(ieee->bTxUseDriverAssingedRate)
 568                tcb_desc->bTxUseDriverAssingedRate = true;
 569        if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
 570        {
 571                if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
 572                        tcb_desc->RATRIndex = 0;
 573        }
 574}
 575
 576void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst)
 577{
 578        if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
 579                return;
 580        if (IsQoSDataFrame(skb->data)) //we deal qos data only
 581        {
 582                PTX_TS_RECORD pTS = NULL;
 583                if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true))
 584                {
 585                        return;
 586                }
 587                pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
 588        }
 589}
 590
 591int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 592{
 593        struct ieee80211_device *ieee = netdev_priv(dev);
 594        struct ieee80211_txb *txb = NULL;
 595        struct ieee80211_hdr_3addrqos *frag_hdr;
 596        int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
 597        unsigned long flags;
 598        struct net_device_stats *stats = &ieee->stats;
 599        int ether_type = 0, encrypt;
 600        int bytes, fc, qos_ctl = 0, hdr_len;
 601        struct sk_buff *skb_frag;
 602        struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
 603                .duration_id = 0,
 604                .seq_ctl = 0,
 605                .qos_ctl = 0
 606        };
 607        u8 dest[ETH_ALEN], src[ETH_ALEN];
 608        int qos_actived = ieee->current_network.qos_data.active;
 609
 610        struct ieee80211_crypt_data* crypt;
 611
 612        cb_desc *tcb_desc;
 613
 614        spin_lock_irqsave(&ieee->lock, flags);
 615
 616        /* If there is no driver handler to take the TXB, dont' bother
 617         * creating it... */
 618        if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
 619           ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
 620                printk(KERN_WARNING "%s: No xmit handler.\n",
 621                       ieee->dev->name);
 622                goto success;
 623        }
 624
 625
 626        if(likely(ieee->raw_tx == 0)){
 627                if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
 628                        printk(KERN_WARNING "%s: skb too small (%d).\n",
 629                        ieee->dev->name, skb->len);
 630                        goto success;
 631                }
 632
 633                memset(skb->cb, 0, sizeof(skb->cb));
 634                ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
 635
 636                crypt = ieee->crypt[ieee->tx_keyidx];
 637
 638                encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
 639                        ieee->host_encrypt && crypt && crypt->ops;
 640
 641                if (!encrypt && ieee->ieee802_1x &&
 642                ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
 643                        stats->tx_dropped++;
 644                        goto success;
 645                }
 646        #ifdef CONFIG_IEEE80211_DEBUG
 647                if (crypt && !encrypt && ether_type == ETH_P_PAE) {
 648                        struct eapol *eap = (struct eapol *)(skb->data +
 649                                sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
 650                        IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
 651                                eap_get_type(eap->type));
 652                }
 653        #endif
 654
 655                /* Save source and destination addresses */
 656                memcpy(&dest, skb->data, ETH_ALEN);
 657                memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
 658
 659                /* Advance the SKB to the start of the payload */
 660                skb_pull(skb, sizeof(struct ethhdr));
 661
 662                /* Determine total amount of storage required for TXB packets */
 663                bytes = skb->len + SNAP_SIZE + sizeof(u16);
 664
 665                if (encrypt)
 666                        fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
 667                else
 668
 669                        fc = IEEE80211_FTYPE_DATA;
 670
 671                //if(ieee->current_network.QoS_Enable)
 672                if(qos_actived)
 673                        fc |= IEEE80211_STYPE_QOS_DATA;
 674                else
 675                        fc |= IEEE80211_STYPE_DATA;
 676
 677                if (ieee->iw_mode == IW_MODE_INFRA) {
 678                        fc |= IEEE80211_FCTL_TODS;
 679                        /* To DS: Addr1 = BSSID, Addr2 = SA,
 680                        Addr3 = DA */
 681                        memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
 682                        memcpy(&header.addr2, &src, ETH_ALEN);
 683                        memcpy(&header.addr3, &dest, ETH_ALEN);
 684                } else if (ieee->iw_mode == IW_MODE_ADHOC) {
 685                        /* not From/To DS: Addr1 = DA, Addr2 = SA,
 686                        Addr3 = BSSID */
 687                        memcpy(&header.addr1, dest, ETH_ALEN);
 688                        memcpy(&header.addr2, src, ETH_ALEN);
 689                        memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
 690                }
 691
 692                header.frame_ctl = cpu_to_le16(fc);
 693
 694                /* Determine fragmentation size based on destination (multicast
 695                * and broadcast are not fragmented) */
 696                if (is_multicast_ether_addr(header.addr1) ||
 697                is_broadcast_ether_addr(header.addr1)) {
 698                        frag_size = MAX_FRAG_THRESHOLD;
 699                        qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
 700                }
 701                else {
 702                        frag_size = ieee->fts;//default:392
 703                        qos_ctl = 0;
 704                }
 705
 706                //if (ieee->current_network.QoS_Enable)
 707                if(qos_actived)
 708                {
 709                        hdr_len = IEEE80211_3ADDR_LEN + 2;
 710
 711                        skb->priority = ieee80211_classify(skb, &ieee->current_network);
 712                        qos_ctl |= skb->priority; //set in the ieee80211_classify
 713                        header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
 714                } else {
 715                        hdr_len = IEEE80211_3ADDR_LEN;
 716                }
 717                /* Determine amount of payload per fragment.  Regardless of if
 718                * this stack is providing the full 802.11 header, one will
 719                * eventually be affixed to this fragment -- so we must account for
 720                * it when determining the amount of payload space. */
 721                bytes_per_frag = frag_size - hdr_len;
 722                if (ieee->config &
 723                (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
 724                        bytes_per_frag -= IEEE80211_FCS_LEN;
 725
 726                /* Each fragment may need to have room for encryption pre/postfix */
 727                if (encrypt)
 728                        bytes_per_frag -= crypt->ops->extra_prefix_len +
 729                                crypt->ops->extra_postfix_len;
 730
 731                /* Number of fragments is the total bytes_per_frag /
 732                * payload_per_fragment */
 733                nr_frags = bytes / bytes_per_frag;
 734                bytes_last_frag = bytes % bytes_per_frag;
 735                if (bytes_last_frag)
 736                        nr_frags++;
 737                else
 738                        bytes_last_frag = bytes_per_frag;
 739
 740                /* When we allocate the TXB we allocate enough space for the reserve
 741                * and full fragment bytes (bytes_per_frag doesn't include prefix,
 742                * postfix, header, FCS, etc.) */
 743                txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
 744                if (unlikely(!txb)) {
 745                        printk(KERN_WARNING "%s: Could not allocate TXB\n",
 746                        ieee->dev->name);
 747                        goto failed;
 748                }
 749                txb->encrypted = encrypt;
 750                txb->payload_size = bytes;
 751
 752                //if (ieee->current_network.QoS_Enable)
 753                if(qos_actived)
 754                {
 755                        txb->queue_index = UP2AC(skb->priority);
 756                } else {
 757                        txb->queue_index = WME_AC_BK;
 758                }
 759
 760
 761
 762                for (i = 0; i < nr_frags; i++) {
 763                        skb_frag = txb->fragments[i];
 764                        tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
 765                        if(qos_actived){
 766                                skb_frag->priority = skb->priority;//UP2AC(skb->priority);
 767                                tcb_desc->queue_index =  UP2AC(skb->priority);
 768                        } else {
 769                                skb_frag->priority = WME_AC_BK;
 770                                tcb_desc->queue_index = WME_AC_BK;
 771                        }
 772                        skb_reserve(skb_frag, ieee->tx_headroom);
 773
 774                        if (encrypt){
 775                                if (ieee->hwsec_active)
 776                                        tcb_desc->bHwSec = 1;
 777                                else
 778                                        tcb_desc->bHwSec = 0;
 779                                skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
 780                        }
 781                        else
 782                        {
 783                                tcb_desc->bHwSec = 0;
 784                        }
 785                        frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
 786                        memcpy(frag_hdr, &header, hdr_len);
 787
 788                        /* If this is not the last fragment, then add the MOREFRAGS
 789                        * bit to the frame control */
 790                        if (i != nr_frags - 1) {
 791                                frag_hdr->frame_ctl = cpu_to_le16(
 792                                        fc | IEEE80211_FCTL_MOREFRAGS);
 793                                bytes = bytes_per_frag;
 794
 795                        } else {
 796                                /* The last fragment takes the remaining length */
 797                                bytes = bytes_last_frag;
 798                        }
 799                        //if(ieee->current_network.QoS_Enable)
 800                        if(qos_actived)
 801                        {
 802                                // add 1 only indicate to corresponding seq number control 2006/7/12
 803                                frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
 804                        } else {
 805                                frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
 806                        }
 807
 808                        /* Put a SNAP header on the first fragment */
 809                        if (i == 0) {
 810                                ieee80211_put_snap(
 811                                        skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
 812                                        ether_type);
 813                                bytes -= SNAP_SIZE + sizeof(u16);
 814                        }
 815
 816                        memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
 817
 818                        /* Advance the SKB... */
 819                        skb_pull(skb, bytes);
 820
 821                        /* Encryption routine will move the header forward in order
 822                        * to insert the IV between the header and the payload */
 823                        if (encrypt)
 824                                ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
 825                        if (ieee->config &
 826                        (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
 827                                skb_put(skb_frag, 4);
 828                }
 829
 830                if(qos_actived)
 831                {
 832                  if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
 833                        ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
 834                  else
 835                        ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
 836                } else {
 837                  if (ieee->seq_ctrl[0] == 0xFFF)
 838                        ieee->seq_ctrl[0] = 0;
 839                  else
 840                        ieee->seq_ctrl[0]++;
 841                }
 842        }else{
 843                if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
 844                        printk(KERN_WARNING "%s: skb too small (%d).\n",
 845                        ieee->dev->name, skb->len);
 846                        goto success;
 847                }
 848
 849                txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
 850                if(!txb){
 851                        printk(KERN_WARNING "%s: Could not allocate TXB\n",
 852                        ieee->dev->name);
 853                        goto failed;
 854                }
 855
 856                txb->encrypted = 0;
 857                txb->payload_size = skb->len;
 858                memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
 859        }
 860
 861 success:
 862//WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
 863        if (txb)
 864        {
 865                cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
 866                tcb_desc->bTxEnableFwCalcDur = 1;
 867                if (is_multicast_ether_addr(header.addr1))
 868                        tcb_desc->bMulticast = 1;
 869                if (is_broadcast_ether_addr(header.addr1))
 870                        tcb_desc->bBroadcast = 1;
 871                ieee80211_txrate_selectmode(ieee, tcb_desc);
 872                if ( tcb_desc->bMulticast ||  tcb_desc->bBroadcast)
 873                        tcb_desc->data_rate = ieee->basic_rate;
 874                else
 875                        //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
 876                        tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
 877                ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
 878                ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
 879                ieee80211_query_HTCapShortGI(ieee, tcb_desc);
 880                ieee80211_query_BandwidthMode(ieee, tcb_desc);
 881                ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
 882                ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
 883//              IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len);
 884                //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc));
 885        }
 886        spin_unlock_irqrestore(&ieee->lock, flags);
 887        dev_kfree_skb_any(skb);
 888        if (txb) {
 889                if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
 890                        ieee80211_softmac_xmit(txb, ieee);
 891                }else{
 892                        if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
 893                                stats->tx_packets++;
 894                                stats->tx_bytes += txb->payload_size;
 895                                return 0;
 896                        }
 897                        ieee80211_txb_free(txb);
 898                }
 899        }
 900
 901        return 0;
 902
 903 failed:
 904        spin_unlock_irqrestore(&ieee->lock, flags);
 905        netif_stop_queue(dev);
 906        stats->tx_errors++;
 907        return 1;
 908
 909}
 910
 911EXPORT_SYMBOL(ieee80211_txb_free);
 912