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