~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

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