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 <andrea.merello@gmail.com>
  29
  30  A special thanks goes to Realtek for their support !
  31
  32******************************************************************************/
  33
  34#include <linux/compiler.h>
  35#include <linux/errno.h>
  36#include <linux/if_arp.h>
  37#include <linux/in6.h>
  38#include <linux/in.h>
  39#include <linux/ip.h>
  40#include <linux/kernel.h>
  41#include <linux/module.h>
  42#include <linux/netdevice.h>
  43#include <linux/pci.h>
  44#include <linux/proc_fs.h>
  45#include <linux/skbuff.h>
  46#include <linux/slab.h>
  47#include <linux/tcp.h>
  48#include <linux/types.h>
  49#include <linux/wireless.h>
  50#include <linux/etherdevice.h>
  51#include <linux/uaccess.h>
  52#include <linux/if_vlan.h>
  53
  54#include "ieee80211.h"
  55
  56
  57/*
  58
  59
  60802.11 Data Frame
  61
  62
  63802.11 frame_contorl for data frames - 2 bytes
  64     ,-----------------------------------------------------------------------------------------.
  65bits | 0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |  a  |  b  |  c  |  d  |  e   |
  66     |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
  67val  | 0  |  0  |  0  |  1  |  x  |  0  |  0  |  0  |  1  |  0  |  x  |  x  |  x  |  x  |  x   |
  68     |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
  69desc | ^-ver-^  |  ^type-^  |  ^-----subtype-----^  | to  |from |more |retry| pwr |more |wep   |
  70     |          |           | x=0 data,x=1 data+ack | DS  | DS  |frag |     | mgm |data |      |
  71     '-----------------------------------------------------------------------------------------'
  72                                                    /\
  73                                                    |
  74802.11 Data Frame                                   |
  75           ,--------- 'ctrl' expands to >-----------'
  76          |
  77      ,--'---,-------------------------------------------------------------.
  78Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
  79      |------|------|---------|---------|---------|------|---------|------|
  80Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  Frame  |  fcs |
  81      |      | tion | (BSSID) |         |         | ence |  data   |      |
  82      `--------------------------------------------------|         |------'
  83Total: 28 non-data bytes                                 `----.----'
  84                                                              |
  85       .- 'Frame data' expands to <---------------------------'
  86       |
  87       V
  88      ,---------------------------------------------------.
  89Bytes |  1   |  1   |    1    |    3     |  2   |  0-2304 |
  90      |------|------|---------|----------|------|---------|
  91Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP      |
  92      | DSAP | SSAP |         |          |      | Packet  |
  93      | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8|      |         |
  94      `-----------------------------------------|         |
  95Total: 8 non-data bytes                         `----.----'
  96                                                     |
  97       .- 'IP Packet' expands, if WEP enabled, to <--'
  98       |
  99       V
 100      ,-----------------------.
 101Bytes |  4  |   0-2296  |  4  |
 102      |-----|-----------|-----|
 103Desc. | IV  | Encrypted | ICV |
 104      |     | IP Packet |     |
 105      `-----------------------'
 106Total: 8 non-data bytes
 107
 108
 109802.3 Ethernet Data Frame
 110
 111      ,-----------------------------------------.
 112Bytes |   6   |   6   |  2   |  Variable |   4  |
 113      |-------|-------|------|-----------|------|
 114Desc. | Dest. | Source| Type | IP Packet |  fcs |
 115      |  MAC  |  MAC  |      |           |      |
 116      `-----------------------------------------'
 117Total: 18 non-data bytes
 118
 119In the event that fragmentation is required, the incoming payload is split into
 120N parts of size ieee->fts.  The first fragment contains the SNAP header and the
 121remaining packets are just data.
 122
 123If encryption is enabled, each fragment payload size is reduced by enough space
 124to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
 125So if you have 1500 bytes of payload with ieee->fts set to 500 without
 126encryption it will take 3 frames.  With WEP it will take 4 frames as the
 127payload of each frame is reduced to 492 bytes.
 128
 129* SKB visualization
 130*
 131*  ,- skb->data
 132* |
 133* |    ETHERNET HEADER        ,-<-- PAYLOAD
 134* |                           |     14 bytes from skb->data
 135* |  2 bytes for Type --> ,T. |     (sizeof ethhdr)
 136* |                       | | |
 137* |,-Dest.--. ,--Src.---. | | |
 138* |  6 bytes| | 6 bytes | | | |
 139* v         | |         | | | |
 140* 0         | v       1 | v | v           2
 141* 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
 142*     ^     | ^         | ^ |
 143*     |     | |         | | |
 144*     |     | |         | `T' <---- 2 bytes for Type
 145*     |     | |         |
 146*     |     | '---SNAP--' <-------- 6 bytes for SNAP
 147*     |     |
 148*     `-IV--' <-------------------- 4 bytes for IV (WEP)
 149*
 150*      SNAP HEADER
 151*
 152*/
 153
 154static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
 155static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
 156
 157static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
 158{
 159        struct ieee80211_snap_hdr *snap;
 160        u8 *oui;
 161
 162        snap = (struct ieee80211_snap_hdr *)data;
 163        snap->dsap = 0xaa;
 164        snap->ssap = 0xaa;
 165        snap->ctrl = 0x03;
 166
 167        if (h_proto == 0x8137 || h_proto == 0x80f3)
 168                oui = P802_1H_OUI;
 169        else
 170                oui = RFC1042_OUI;
 171        snap->oui[0] = oui[0];
 172        snap->oui[1] = oui[1];
 173        snap->oui[2] = oui[2];
 174
 175        *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
 176
 177        return SNAP_SIZE + sizeof(u16);
 178}
 179
 180int ieee80211_encrypt_fragment(
 181        struct ieee80211_device *ieee,
 182        struct sk_buff *frag,
 183        int hdr_len)
 184{
 185        struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
 186        int res;
 187
 188        if (!(crypt && crypt->ops))
 189        {
 190                printk("=========>%s(), crypt is null\n", __func__);
 191                return -1;
 192        }
 193
 194        if (ieee->tkip_countermeasures &&
 195            crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
 196                if (net_ratelimit()) {
 197                        struct rtl_80211_hdr_3addrqos *header;
 198
 199                        header = (struct rtl_80211_hdr_3addrqos *)frag->data;
 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
 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        kfree(txb);
 237}
 238EXPORT_SYMBOL(ieee80211_txb_free);
 239
 240static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
 241                                                 gfp_t 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)
 306static void ieee80211_tx_query_agg_cap(struct ieee80211_device *ieee,
 307                                       struct sk_buff *skb, cb_desc *tcb_desc)
 308{
 309        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
 310        PTX_TS_RECORD                   pTxTs = NULL;
 311        struct rtl_80211_hdr_1addr *hdr = (struct rtl_80211_hdr_1addr *)skb->data;
 312
 313        if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
 314                return;
 315        if (!IsQoSDataFrame(skb->data))
 316                return;
 317
 318        if (is_multicast_ether_addr(hdr->addr1))
 319                return;
 320        //check packet and mode later
 321#ifdef TO_DO_LIST
 322        if(pTcb->PacketLength >= 4096)
 323                return;
 324        // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
 325        if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
 326                return;
 327#endif
 328        if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
 329        {
 330                return;
 331        }
 332        if(pHTInfo->bCurrentAMPDUEnable)
 333        {
 334                if (!GetTs(ieee, (PTS_COMMON_INFO *)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
 335                {
 336                        printk("===>can't get TS\n");
 337                        return;
 338                }
 339                if (!pTxTs->TxAdmittedBARecord.bValid)
 340                {
 341                        TsStartAddBaProcess(ieee, pTxTs);
 342                        goto FORCED_AGG_SETTING;
 343                }
 344                else if (!pTxTs->bUsingBa)
 345                {
 346                        if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
 347                                pTxTs->bUsingBa = true;
 348                        else
 349                                goto FORCED_AGG_SETTING;
 350                }
 351
 352                if (ieee->iw_mode == IW_MODE_INFRA)
 353                {
 354                        tcb_desc->bAMPDUEnable = true;
 355                        tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
 356                        tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
 357                }
 358        }
 359FORCED_AGG_SETTING:
 360        switch (pHTInfo->ForcedAMPDUMode )
 361        {
 362                case HT_AGG_AUTO:
 363                        break;
 364
 365                case HT_AGG_FORCE_ENABLE:
 366                        tcb_desc->bAMPDUEnable = true;
 367                        tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
 368                        tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
 369                        break;
 370
 371                case HT_AGG_FORCE_DISABLE:
 372                        tcb_desc->bAMPDUEnable = false;
 373                        tcb_desc->ampdu_density = 0;
 374                        tcb_desc->ampdu_factor = 0;
 375                        break;
 376
 377        }
 378                return;
 379}
 380
 381static void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device *ieee,
 382                                              cb_desc *tcb_desc)
 383{
 384        tcb_desc->bUseShortPreamble = false;
 385        if (tcb_desc->data_rate == 2)
 386        {//// 1M can only use Long Preamble. 11B spec
 387                return;
 388        }
 389        else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
 390        {
 391                tcb_desc->bUseShortPreamble = true;
 392        }
 393        return;
 394}
 395static void
 396ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
 397{
 398        PRT_HIGH_THROUGHPUT             pHTInfo = ieee->pHTInfo;
 399
 400        tcb_desc->bUseShortGI           = false;
 401
 402        if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
 403                return;
 404
 405        if(pHTInfo->bForcedShortGI)
 406        {
 407                tcb_desc->bUseShortGI = true;
 408                return;
 409        }
 410
 411        if((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz)
 412                tcb_desc->bUseShortGI = true;
 413        else if((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz)
 414                tcb_desc->bUseShortGI = true;
 415}
 416
 417static void ieee80211_query_BandwidthMode(struct ieee80211_device *ieee,
 418                                          cb_desc *tcb_desc)
 419{
 420        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
 421
 422        tcb_desc->bPacketBW = false;
 423
 424        if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
 425                return;
 426
 427        if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
 428                return;
 429
 430        if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
 431                return;
 432        //BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
 433        if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
 434                tcb_desc->bPacketBW = true;
 435        return;
 436}
 437
 438static void ieee80211_query_protectionmode(struct ieee80211_device *ieee,
 439                                           cb_desc *tcb_desc,
 440                                           struct sk_buff *skb)
 441{
 442        // Common Settings
 443        tcb_desc->bRTSSTBC                      = false;
 444        tcb_desc->bRTSUseShortGI                = false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
 445        tcb_desc->bCTSEnable                    = false; // Most of protection using RTS/CTS
 446        tcb_desc->RTSSC                         = 0;            // 20MHz: Don't care;  40MHz: Duplicate.
 447        tcb_desc->bRTSBW                        = false; // RTS frame bandwidth is always 20MHz
 448
 449        if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
 450                return;
 451
 452        if (is_broadcast_ether_addr(skb->data+16))  //check addr3 as infrastructure add3 is DA.
 453                return;
 454
 455        if (ieee->mode < IEEE_N_24G) //b, g mode
 456        {
 457                        // (1) RTS_Threshold is compared to the MPDU, not MSDU.
 458                        // (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame.
 459                        //              Other fragments are protected by previous fragment.
 460                        //              So we only need to check the length of first fragment.
 461                if (skb->len > ieee->rts)
 462                {
 463                        tcb_desc->bRTSEnable = true;
 464                        tcb_desc->rts_rate = MGN_24M;
 465                }
 466                else if (ieee->current_network.buseprotection)
 467                {
 468                        // Use CTS-to-SELF in protection mode.
 469                        tcb_desc->bRTSEnable = true;
 470                        tcb_desc->bCTSEnable = true;
 471                        tcb_desc->rts_rate = MGN_24M;
 472                }
 473                //otherwise return;
 474                return;
 475        }
 476        else
 477        {// 11n High throughput case.
 478                PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
 479                while (true)
 480                {
 481                        //check ERP protection
 482                        if (ieee->current_network.buseprotection)
 483                        {// CTS-to-SELF
 484                                tcb_desc->bRTSEnable = true;
 485                                tcb_desc->bCTSEnable = true;
 486                                tcb_desc->rts_rate = MGN_24M;
 487                                break;
 488                        }
 489                        //check HT op mode
 490                        if(pHTInfo->bCurrentHTSupport  && pHTInfo->bEnableHT)
 491                        {
 492                                u8 HTOpMode = pHTInfo->CurrentOpMode;
 493                                if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
 494                                                        (!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
 495                                {
 496                                        tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
 497                                        tcb_desc->bRTSEnable = true;
 498                                        break;
 499                                }
 500                        }
 501                        //check rts
 502                        if (skb->len > ieee->rts)
 503                        {
 504                                tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
 505                                tcb_desc->bRTSEnable = true;
 506                                break;
 507                        }
 508                        //to do list: check MIMO power save condition.
 509                        //check AMPDU aggregation for TXOP
 510                        if(tcb_desc->bAMPDUEnable)
 511                        {
 512                                tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
 513                                // According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
 514                                // throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
 515                                tcb_desc->bRTSEnable = false;
 516                                break;
 517                        }
 518                        //check IOT action
 519                        if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
 520                        {
 521                                tcb_desc->bCTSEnable    = true;
 522                                tcb_desc->rts_rate  =   MGN_24M;
 523                                tcb_desc->bRTSEnable = true;
 524                                break;
 525                        }
 526                        // Totally no protection case!!
 527                        goto NO_PROTECTION;
 528                }
 529                }
 530        // For test , CTS replace with RTS
 531        if (0) {
 532                tcb_desc->bCTSEnable    = true;
 533                tcb_desc->rts_rate = MGN_24M;
 534                tcb_desc->bRTSEnable    = true;
 535        }
 536        if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
 537                tcb_desc->bUseShortPreamble = true;
 538        if (ieee->mode == IW_MODE_MASTER)
 539                        goto NO_PROTECTION;
 540        return;
 541NO_PROTECTION:
 542        tcb_desc->bRTSEnable    = false;
 543        tcb_desc->bCTSEnable    = false;
 544        tcb_desc->rts_rate              = 0;
 545        tcb_desc->RTSSC         = 0;
 546        tcb_desc->bRTSBW                = false;
 547}
 548
 549
 550static void ieee80211_txrate_selectmode(struct ieee80211_device *ieee,
 551                                        cb_desc *tcb_desc)
 552{
 553#ifdef TO_DO_LIST
 554        if(!IsDataFrame(pFrame))
 555        {
 556                pTcb->bTxDisableRateFallBack = true;
 557                pTcb->bTxUseDriverAssingedRate = true;
 558                pTcb->RATRIndex = 7;
 559                return;
 560        }
 561
 562        if(pMgntInfo->ForcedDataRate!= 0)
 563        {
 564                pTcb->bTxDisableRateFallBack = true;
 565                pTcb->bTxUseDriverAssingedRate = true;
 566                return;
 567        }
 568#endif
 569        if(ieee->bTxDisableRateFallBack)
 570                tcb_desc->bTxDisableRateFallBack = true;
 571
 572        if(ieee->bTxUseDriverAssingedRate)
 573                tcb_desc->bTxUseDriverAssingedRate = true;
 574        if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
 575        {
 576                if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
 577                        tcb_desc->RATRIndex = 0;
 578        }
 579}
 580
 581static void ieee80211_query_seqnum(struct ieee80211_device *ieee,
 582                                   struct sk_buff *skb, u8 *dst)
 583{
 584        if (is_multicast_ether_addr(dst))
 585                return;
 586        if (IsQoSDataFrame(skb->data)) //we deal qos data only
 587        {
 588                PTX_TS_RECORD pTS = NULL;
 589                if (!GetTs(ieee, (PTS_COMMON_INFO *)(&pTS), dst, skb->priority, TX_DIR, true))
 590                {
 591                        return;
 592                }
 593                pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
 594        }
 595}
 596
 597int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 598{
 599        struct ieee80211_device *ieee = netdev_priv(dev);
 600        struct ieee80211_txb *txb = NULL;
 601        struct rtl_80211_hdr_3addrqos *frag_hdr;
 602        int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
 603        unsigned long flags;
 604        struct net_device_stats *stats = &ieee->stats;
 605        int ether_type = 0, encrypt;
 606        int bytes, fc, qos_ctl = 0, hdr_len;
 607        struct sk_buff *skb_frag;
 608        struct rtl_80211_hdr_3addrqos header = { /* Ensure zero initialized */
 609                .duration_id = 0,
 610                .seq_ctl = 0,
 611                .qos_ctl = 0
 612        };
 613        u8 dest[ETH_ALEN], src[ETH_ALEN];
 614        int qos_actived = ieee->current_network.qos_data.active;
 615
 616        struct ieee80211_crypt_data *crypt;
 617
 618        cb_desc *tcb_desc;
 619
 620        spin_lock_irqsave(&ieee->lock, flags);
 621
 622        /* If there is no driver handler to take the TXB, dont' bother
 623         * creating it... */
 624        if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
 625           ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
 626                printk(KERN_WARNING "%s: No xmit handler.\n",
 627                       ieee->dev->name);
 628                goto success;
 629        }
 630
 631
 632        if(likely(ieee->raw_tx == 0)){
 633                if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
 634                        printk(KERN_WARNING "%s: skb too small (%d).\n",
 635                        ieee->dev->name, skb->len);
 636                        goto success;
 637                }
 638
 639                memset(skb->cb, 0, sizeof(skb->cb));
 640                ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
 641
 642                crypt = ieee->crypt[ieee->tx_keyidx];
 643
 644                encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
 645                        ieee->host_encrypt && crypt && crypt->ops;
 646
 647                if (!encrypt && ieee->ieee802_1x &&
 648                ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
 649                        stats->tx_dropped++;
 650                        goto success;
 651                }
 652        #ifdef CONFIG_IEEE80211_DEBUG
 653                if (crypt && !encrypt && ether_type == ETH_P_PAE) {
 654                        struct eapol *eap = (struct eapol *)(skb->data +
 655                                sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
 656                        IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
 657                                eap_get_type(eap->type));
 658                }
 659        #endif
 660
 661                /* Save source and destination addresses */
 662                memcpy(&dest, skb->data, ETH_ALEN);
 663                memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
 664
 665                /* Advance the SKB to the start of the payload */
 666                skb_pull(skb, sizeof(struct ethhdr));
 667
 668                /* Determine total amount of storage required for TXB packets */
 669                bytes = skb->len + SNAP_SIZE + sizeof(u16);
 670
 671                if (encrypt)
 672                        fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
 673                else
 674
 675                        fc = IEEE80211_FTYPE_DATA;
 676
 677                //if(ieee->current_network.QoS_Enable)
 678                if(qos_actived)
 679                        fc |= IEEE80211_STYPE_QOS_DATA;
 680                else
 681                        fc |= IEEE80211_STYPE_DATA;
 682
 683                if (ieee->iw_mode == IW_MODE_INFRA) {
 684                        fc |= IEEE80211_FCTL_TODS;
 685                        /* To DS: Addr1 = BSSID, Addr2 = SA,
 686                        Addr3 = DA */
 687                        memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
 688                        memcpy(&header.addr2, &src, ETH_ALEN);
 689                        memcpy(&header.addr3, &dest, ETH_ALEN);
 690                } else if (ieee->iw_mode == IW_MODE_ADHOC) {
 691                        /* not From/To DS: Addr1 = DA, Addr2 = SA,
 692                        Addr3 = BSSID */
 693                        memcpy(&header.addr1, dest, ETH_ALEN);
 694                        memcpy(&header.addr2, src, ETH_ALEN);
 695                        memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
 696                }
 697
 698                header.frame_ctl = cpu_to_le16(fc);
 699
 700                /* Determine fragmentation size based on destination (multicast
 701                * and broadcast are not fragmented) */
 702                if (is_multicast_ether_addr(header.addr1)) {
 703                        frag_size = MAX_FRAG_THRESHOLD;
 704                        qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
 705                }
 706                else {
 707                        frag_size = ieee->fts;//default:392
 708                        qos_ctl = 0;
 709                }
 710
 711                //if (ieee->current_network.QoS_Enable)
 712                if(qos_actived)
 713                {
 714                        hdr_len = IEEE80211_3ADDR_LEN + 2;
 715
 716                        skb->priority = ieee80211_classify(skb, &ieee->current_network);
 717                        qos_ctl |= skb->priority; //set in the ieee80211_classify
 718                        header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
 719                } else {
 720                        hdr_len = IEEE80211_3ADDR_LEN;
 721                }
 722                /* Determine amount of payload per fragment.  Regardless of if
 723                * this stack is providing the full 802.11 header, one will
 724                * eventually be affixed to this fragment -- so we must account for
 725                * it when determining the amount of payload space. */
 726                bytes_per_frag = frag_size - hdr_len;
 727                if (ieee->config &
 728                (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
 729                        bytes_per_frag -= IEEE80211_FCS_LEN;
 730
 731                /* Each fragment may need to have room for encryption pre/postfix */
 732                if (encrypt)
 733                        bytes_per_frag -= crypt->ops->extra_prefix_len +
 734                                crypt->ops->extra_postfix_len;
 735
 736                /* Number of fragments is the total bytes_per_frag /
 737                * payload_per_fragment */
 738                nr_frags = bytes / bytes_per_frag;
 739                bytes_last_frag = bytes % bytes_per_frag;
 740                if (bytes_last_frag)
 741                        nr_frags++;
 742                else
 743                        bytes_last_frag = bytes_per_frag;
 744
 745                /* When we allocate the TXB we allocate enough space for the reserve
 746                * and full fragment bytes (bytes_per_frag doesn't include prefix,
 747                * postfix, header, FCS, etc.) */
 748                txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
 749                if (unlikely(!txb)) {
 750                        printk(KERN_WARNING "%s: Could not allocate TXB\n",
 751                        ieee->dev->name);
 752                        goto failed;
 753                }
 754                txb->encrypted = encrypt;
 755                txb->payload_size = bytes;
 756
 757                //if (ieee->current_network.QoS_Enable)
 758                if(qos_actived)
 759                {
 760                        txb->queue_index = UP2AC(skb->priority);
 761                } else {
 762                        txb->queue_index = WME_AC_BK;
 763                }
 764
 765
 766
 767                for (i = 0; i < nr_frags; i++) {
 768                        skb_frag = txb->fragments[i];
 769                        tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
 770                        if(qos_actived){
 771                                skb_frag->priority = skb->priority;//UP2AC(skb->priority);
 772                                tcb_desc->queue_index =  UP2AC(skb->priority);
 773                        } else {
 774                                skb_frag->priority = WME_AC_BK;
 775                                tcb_desc->queue_index = WME_AC_BK;
 776                        }
 777                        skb_reserve(skb_frag, ieee->tx_headroom);
 778
 779                        if (encrypt){
 780                                if (ieee->hwsec_active)
 781                                        tcb_desc->bHwSec = 1;
 782                                else
 783                                        tcb_desc->bHwSec = 0;
 784                                skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
 785                        }
 786                        else
 787                        {
 788                                tcb_desc->bHwSec = 0;
 789                        }
 790                        frag_hdr = (struct rtl_80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
 791                        memcpy(frag_hdr, &header, hdr_len);
 792
 793                        /* If this is not the last fragment, then add the MOREFRAGS
 794                        * bit to the frame control */
 795                        if (i != nr_frags - 1) {
 796                                frag_hdr->frame_ctl = cpu_to_le16(
 797                                        fc | IEEE80211_FCTL_MOREFRAGS);
 798                                bytes = bytes_per_frag;
 799
 800                        } else {
 801                                /* The last fragment takes the remaining length */
 802                                bytes = bytes_last_frag;
 803                        }
 804                        //if(ieee->current_network.QoS_Enable)
 805                        if(qos_actived)
 806                        {
 807                                // add 1 only indicate to corresponding seq number control 2006/7/12
 808                                frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
 809                        } else {
 810                                frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
 811                        }
 812
 813                        /* Put a SNAP header on the first fragment */
 814                        if (i == 0) {
 815                                ieee80211_put_snap(
 816                                        skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
 817                                        ether_type);
 818                                bytes -= SNAP_SIZE + sizeof(u16);
 819                        }
 820
 821                        memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
 822
 823                        /* Advance the SKB... */
 824                        skb_pull(skb, bytes);
 825
 826                        /* Encryption routine will move the header forward in order
 827                        * to insert the IV between the header and the payload */
 828                        if (encrypt)
 829                                ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
 830                        if (ieee->config &
 831                        (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
 832                                skb_put(skb_frag, 4);
 833                }
 834
 835                if(qos_actived)
 836                {
 837                  if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
 838                        ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
 839                  else
 840                        ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
 841                } else {
 842                  if (ieee->seq_ctrl[0] == 0xFFF)
 843                        ieee->seq_ctrl[0] = 0;
 844                  else
 845                        ieee->seq_ctrl[0]++;
 846                }
 847        }else{
 848                if (unlikely(skb->len < sizeof(struct rtl_80211_hdr_3addr))) {
 849                        printk(KERN_WARNING "%s: skb too small (%d).\n",
 850                        ieee->dev->name, skb->len);
 851                        goto success;
 852                }
 853
 854                txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
 855                if(!txb){
 856                        printk(KERN_WARNING "%s: Could not allocate TXB\n",
 857                        ieee->dev->name);
 858                        goto failed;
 859                }
 860
 861                txb->encrypted = 0;
 862                txb->payload_size = skb->len;
 863                memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
 864        }
 865
 866 success:
 867//WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
 868        if (txb)
 869        {
 870                cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
 871                tcb_desc->bTxEnableFwCalcDur = 1;
 872                if (is_multicast_ether_addr(header.addr1))
 873                        tcb_desc->bMulticast = 1;
 874                if (is_broadcast_ether_addr(header.addr1))
 875                        tcb_desc->bBroadcast = 1;
 876                ieee80211_txrate_selectmode(ieee, tcb_desc);
 877                if (tcb_desc->bMulticast ||  tcb_desc->bBroadcast)
 878                        tcb_desc->data_rate = ieee->basic_rate;
 879                else
 880                        //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
 881                        tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
 882                ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
 883                ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
 884                ieee80211_query_HTCapShortGI(ieee, tcb_desc);
 885                ieee80211_query_BandwidthMode(ieee, tcb_desc);
 886                ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
 887                ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
 888//              IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len);
 889                //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc));
 890        }
 891        spin_unlock_irqrestore(&ieee->lock, flags);
 892        dev_kfree_skb_any(skb);
 893        if (txb) {
 894                if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
 895                        ieee80211_softmac_xmit(txb, ieee);
 896                }else{
 897                        if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
 898                                stats->tx_packets++;
 899                                stats->tx_bytes += txb->payload_size;
 900                                return 0;
 901                        }
 902                        ieee80211_txb_free(txb);
 903                }
 904        }
 905
 906        return 0;
 907
 908 failed:
 909        spin_unlock_irqrestore(&ieee->lock, flags);
 910        netif_stop_queue(dev);
 911        stats->tx_errors++;
 912        return 1;
 913
 914}
 915