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