Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / drivers / staging / rtl8192u / ieee80211 / ieee80211_tx.c
1 /******************************************************************************
2
3   Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4
5   This program is free software; you can redistribute it and/or modify it
6   under the terms of version 2 of the GNU General Public License as
7   published by the Free Software Foundation.
8
9   This program is distributed in the hope that it will be useful, but WITHOUT
10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12   more details.
13
14   You should have received a copy of the GNU General Public License along with
15   this program; if not, write to the Free Software Foundation, Inc., 59
16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17
18   The full GNU General Public License is included in this distribution in the
19   file called LICENSE.
20
21   Contact Information:
22   James P. Ketrenos <ipw2100-admin@linux.intel.com>
23   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25 ******************************************************************************
26
27   Few modifications for Realtek's Wi-Fi drivers by
28   Andrea Merello <andrea.merello@gmail.com>
29
30   A special thanks goes to Realtek for their support !
31
32 ******************************************************************************/
33
34 #include <linux/compiler.h>
35 //#include <linux/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 static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
241                                                  gfp_t gfp_mask)
242 {
243         struct ieee80211_txb *txb;
244         int i;
245         txb = kmalloc(
246                 sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags),
247                 gfp_mask);
248         if (!txb)
249                 return NULL;
250
251         memset(txb, 0, sizeof(struct ieee80211_txb));
252         txb->nr_frags = nr_frags;
253         txb->frag_size = txb_size;
254
255         for (i = 0; i < nr_frags; i++) {
256                 txb->fragments[i] = dev_alloc_skb(txb_size);
257                 if (unlikely(!txb->fragments[i])) {
258                         i--;
259                         break;
260                 }
261                 memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
262         }
263         if (unlikely(i != nr_frags)) {
264                 while (i >= 0)
265                         dev_kfree_skb_any(txb->fragments[i--]);
266                 kfree(txb);
267                 return NULL;
268         }
269         return txb;
270 }
271
272 // Classify the to-be send data packet
273 // Need to acquire the sent queue index.
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 static void ieee80211_tx_query_agg_cap(struct ieee80211_device *ieee,
307                                        struct sk_buff *skb, cb_desc *tcb_desc)
308 {
309         PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
310         PTX_TS_RECORD                   pTxTs = NULL;
311         struct ieee80211_hdr_1addr *hdr = (struct ieee80211_hdr_1addr *)skb->data;
312
313         if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
314                 return;
315         if (!IsQoSDataFrame(skb->data))
316                 return;
317
318         if (is_multicast_ether_addr(hdr->addr1))
319                 return;
320         //check packet and mode later
321 #ifdef TO_DO_LIST
322         if(pTcb->PacketLength >= 4096)
323                 return;
324         // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
325         if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
326                 return;
327 #endif
328         if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
329         {
330                 return;
331         }
332         if(pHTInfo->bCurrentAMPDUEnable)
333         {
334                 if (!GetTs(ieee, (PTS_COMMON_INFO *)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
335                 {
336                         printk("===>can't get TS\n");
337                         return;
338                 }
339                 if (pTxTs->TxAdmittedBARecord.bValid == false)
340                 {
341                         TsStartAddBaProcess(ieee, pTxTs);
342                         goto FORCED_AGG_SETTING;
343                 }
344                 else if (pTxTs->bUsingBa == false)
345                 {
346                         if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
347                                 pTxTs->bUsingBa = true;
348                         else
349                                 goto FORCED_AGG_SETTING;
350                 }
351
352                 if (ieee->iw_mode == IW_MODE_INFRA)
353                 {
354                         tcb_desc->bAMPDUEnable = true;
355                         tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
356                         tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
357                 }
358         }
359 FORCED_AGG_SETTING:
360         switch (pHTInfo->ForcedAMPDUMode )
361         {
362                 case HT_AGG_AUTO:
363                         break;
364
365                 case HT_AGG_FORCE_ENABLE:
366                         tcb_desc->bAMPDUEnable = true;
367                         tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
368                         tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
369                         break;
370
371                 case HT_AGG_FORCE_DISABLE:
372                         tcb_desc->bAMPDUEnable = false;
373                         tcb_desc->ampdu_density = 0;
374                         tcb_desc->ampdu_factor = 0;
375                         break;
376
377         }
378                 return;
379 }
380
381 extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device *ieee, 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 }
394 extern  void
395 ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, 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
416 static void ieee80211_query_BandwidthMode(struct ieee80211_device *ieee,
417                                           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
437 static void ieee80211_query_protectionmode(struct ieee80211_device *ieee,
438                                            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         {
532                 tcb_desc->bCTSEnable    = true;
533                 tcb_desc->rts_rate = MGN_24M;
534                 tcb_desc->bRTSEnable    = true;
535         }
536         if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
537                 tcb_desc->bUseShortPreamble = true;
538         if (ieee->mode == IW_MODE_MASTER)
539                         goto NO_PROTECTION;
540         return;
541 NO_PROTECTION:
542         tcb_desc->bRTSEnable    = false;
543         tcb_desc->bCTSEnable    = false;
544         tcb_desc->rts_rate              = 0;
545         tcb_desc->RTSSC         = 0;
546         tcb_desc->bRTSBW                = false;
547 }
548
549
550 static void ieee80211_txrate_selectmode(struct ieee80211_device *ieee,
551                                         cb_desc *tcb_desc)
552 {
553 #ifdef TO_DO_LIST
554         if(!IsDataFrame(pFrame))
555         {
556                 pTcb->bTxDisableRateFallBack = TRUE;
557                 pTcb->bTxUseDriverAssingedRate = TRUE;
558                 pTcb->RATRIndex = 7;
559                 return;
560         }
561
562         if(pMgntInfo->ForcedDataRate!= 0)
563         {
564                 pTcb->bTxDisableRateFallBack = TRUE;
565                 pTcb->bTxUseDriverAssingedRate = TRUE;
566                 return;
567         }
568 #endif
569         if(ieee->bTxDisableRateFallBack)
570                 tcb_desc->bTxDisableRateFallBack = true;
571
572         if(ieee->bTxUseDriverAssingedRate)
573                 tcb_desc->bTxUseDriverAssingedRate = true;
574         if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
575         {
576                 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
577                         tcb_desc->RATRIndex = 0;
578         }
579 }
580
581 static void ieee80211_query_seqnum(struct ieee80211_device *ieee,
582                                    struct sk_buff *skb, u8 *dst)
583 {
584         if (is_multicast_ether_addr(dst))
585                 return;
586         if (IsQoSDataFrame(skb->data)) //we deal qos data only
587         {
588                 PTX_TS_RECORD pTS = NULL;
589                 if (!GetTs(ieee, (PTS_COMMON_INFO *)(&pTS), dst, skb->priority, TX_DIR, true))
590                 {
591                         return;
592                 }
593                 pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
594         }
595 }
596
597 int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
598 {
599         struct ieee80211_device *ieee = netdev_priv(dev);
600         struct ieee80211_txb *txb = NULL;
601         struct ieee80211_hdr_3addrqos *frag_hdr;
602         int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
603         unsigned long flags;
604         struct net_device_stats *stats = &ieee->stats;
605         int ether_type = 0, encrypt;
606         int bytes, fc, qos_ctl = 0, hdr_len;
607         struct sk_buff *skb_frag;
608         struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
609                 .duration_id = 0,
610                 .seq_ctl = 0,
611                 .qos_ctl = 0
612         };
613         u8 dest[ETH_ALEN], src[ETH_ALEN];
614         int qos_actived = ieee->current_network.qos_data.active;
615
616         struct ieee80211_crypt_data *crypt;
617
618         cb_desc *tcb_desc;
619
620         spin_lock_irqsave(&ieee->lock, flags);
621
622         /* If there is no driver handler to take the TXB, dont' bother
623          * creating it... */
624         if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
625            ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
626                 printk(KERN_WARNING "%s: No xmit handler.\n",
627                        ieee->dev->name);
628                 goto success;
629         }
630
631
632         if(likely(ieee->raw_tx == 0)){
633                 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
634                         printk(KERN_WARNING "%s: skb too small (%d).\n",
635                         ieee->dev->name, skb->len);
636                         goto success;
637                 }
638
639                 memset(skb->cb, 0, sizeof(skb->cb));
640                 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
641
642                 crypt = ieee->crypt[ieee->tx_keyidx];
643
644                 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
645                         ieee->host_encrypt && crypt && crypt->ops;
646
647                 if (!encrypt && ieee->ieee802_1x &&
648                 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
649                         stats->tx_dropped++;
650                         goto success;
651                 }
652         #ifdef CONFIG_IEEE80211_DEBUG
653                 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
654                         struct eapol *eap = (struct eapol *)(skb->data +
655                                 sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
656                         IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
657                                 eap_get_type(eap->type));
658                 }
659         #endif
660
661                 /* Save source and destination addresses */
662                 memcpy(&dest, skb->data, ETH_ALEN);
663                 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
664
665                 /* Advance the SKB to the start of the payload */
666                 skb_pull(skb, sizeof(struct ethhdr));
667
668                 /* Determine total amount of storage required for TXB packets */
669                 bytes = skb->len + SNAP_SIZE + sizeof(u16);
670
671                 if (encrypt)
672                         fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
673                 else
674
675                         fc = IEEE80211_FTYPE_DATA;
676
677                 //if(ieee->current_network.QoS_Enable)
678                 if(qos_actived)
679                         fc |= IEEE80211_STYPE_QOS_DATA;
680                 else
681                         fc |= IEEE80211_STYPE_DATA;
682
683                 if (ieee->iw_mode == IW_MODE_INFRA) {
684                         fc |= IEEE80211_FCTL_TODS;
685                         /* To DS: Addr1 = BSSID, Addr2 = SA,
686                         Addr3 = DA */
687                         memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
688                         memcpy(&header.addr2, &src, ETH_ALEN);
689                         memcpy(&header.addr3, &dest, ETH_ALEN);
690                 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
691                         /* not From/To DS: Addr1 = DA, Addr2 = SA,
692                         Addr3 = BSSID */
693                         memcpy(&header.addr1, dest, ETH_ALEN);
694                         memcpy(&header.addr2, src, ETH_ALEN);
695                         memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
696                 }
697
698                 header.frame_ctl = cpu_to_le16(fc);
699
700                 /* Determine fragmentation size based on destination (multicast
701                 * and broadcast are not fragmented) */
702                 if (is_multicast_ether_addr(header.addr1)) {
703                         frag_size = MAX_FRAG_THRESHOLD;
704                         qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
705                 }
706                 else {
707                         frag_size = ieee->fts;//default:392
708                         qos_ctl = 0;
709                 }
710
711                 //if (ieee->current_network.QoS_Enable)
712                 if(qos_actived)
713                 {
714                         hdr_len = IEEE80211_3ADDR_LEN + 2;
715
716                         skb->priority = ieee80211_classify(skb, &ieee->current_network);
717                         qos_ctl |= skb->priority; //set in the ieee80211_classify
718                         header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
719                 } else {
720                         hdr_len = IEEE80211_3ADDR_LEN;
721                 }
722                 /* Determine amount of payload per fragment.  Regardless of if
723                 * this stack is providing the full 802.11 header, one will
724                 * eventually be affixed to this fragment -- so we must account for
725                 * it when determining the amount of payload space. */
726                 bytes_per_frag = frag_size - hdr_len;
727                 if (ieee->config &
728                 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
729                         bytes_per_frag -= IEEE80211_FCS_LEN;
730
731                 /* Each fragment may need to have room for encryption pre/postfix */
732                 if (encrypt)
733                         bytes_per_frag -= crypt->ops->extra_prefix_len +
734                                 crypt->ops->extra_postfix_len;
735
736                 /* Number of fragments is the total bytes_per_frag /
737                 * payload_per_fragment */
738                 nr_frags = bytes / bytes_per_frag;
739                 bytes_last_frag = bytes % bytes_per_frag;
740                 if (bytes_last_frag)
741                         nr_frags++;
742                 else
743                         bytes_last_frag = bytes_per_frag;
744
745                 /* When we allocate the TXB we allocate enough space for the reserve
746                 * and full fragment bytes (bytes_per_frag doesn't include prefix,
747                 * postfix, header, FCS, etc.) */
748                 txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
749                 if (unlikely(!txb)) {
750                         printk(KERN_WARNING "%s: Could not allocate TXB\n",
751                         ieee->dev->name);
752                         goto failed;
753                 }
754                 txb->encrypted = encrypt;
755                 txb->payload_size = bytes;
756
757                 //if (ieee->current_network.QoS_Enable)
758                 if(qos_actived)
759                 {
760                         txb->queue_index = UP2AC(skb->priority);
761                 } else {
762                         txb->queue_index = WME_AC_BK;
763                 }
764
765
766
767                 for (i = 0; i < nr_frags; i++) {
768                         skb_frag = txb->fragments[i];
769                         tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
770                         if(qos_actived){
771                                 skb_frag->priority = skb->priority;//UP2AC(skb->priority);
772                                 tcb_desc->queue_index =  UP2AC(skb->priority);
773                         } else {
774                                 skb_frag->priority = WME_AC_BK;
775                                 tcb_desc->queue_index = WME_AC_BK;
776                         }
777                         skb_reserve(skb_frag, ieee->tx_headroom);
778
779                         if (encrypt){
780                                 if (ieee->hwsec_active)
781                                         tcb_desc->bHwSec = 1;
782                                 else
783                                         tcb_desc->bHwSec = 0;
784                                 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
785                         }
786                         else
787                         {
788                                 tcb_desc->bHwSec = 0;
789                         }
790                         frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
791                         memcpy(frag_hdr, &header, hdr_len);
792
793                         /* If this is not the last fragment, then add the MOREFRAGS
794                         * bit to the frame control */
795                         if (i != nr_frags - 1) {
796                                 frag_hdr->frame_ctl = cpu_to_le16(
797                                         fc | IEEE80211_FCTL_MOREFRAGS);
798                                 bytes = bytes_per_frag;
799
800                         } else {
801                                 /* The last fragment takes the remaining length */
802                                 bytes = bytes_last_frag;
803                         }
804                         //if(ieee->current_network.QoS_Enable)
805                         if(qos_actived)
806                         {
807                                 // add 1 only indicate to corresponding seq number control 2006/7/12
808                                 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
809                         } else {
810                                 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
811                         }
812
813                         /* Put a SNAP header on the first fragment */
814                         if (i == 0) {
815                                 ieee80211_put_snap(
816                                         skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
817                                         ether_type);
818                                 bytes -= SNAP_SIZE + sizeof(u16);
819                         }
820
821                         memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
822
823                         /* Advance the SKB... */
824                         skb_pull(skb, bytes);
825
826                         /* Encryption routine will move the header forward in order
827                         * to insert the IV between the header and the payload */
828                         if (encrypt)
829                                 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
830                         if (ieee->config &
831                         (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
832                                 skb_put(skb_frag, 4);
833                 }
834
835                 if(qos_actived)
836                 {
837                   if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
838                         ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
839                   else
840                         ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
841                 } else {
842                   if (ieee->seq_ctrl[0] == 0xFFF)
843                         ieee->seq_ctrl[0] = 0;
844                   else
845                         ieee->seq_ctrl[0]++;
846                 }
847         }else{
848                 if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
849                         printk(KERN_WARNING "%s: skb too small (%d).\n",
850                         ieee->dev->name, skb->len);
851                         goto success;
852                 }
853
854                 txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
855                 if(!txb){
856                         printk(KERN_WARNING "%s: Could not allocate TXB\n",
857                         ieee->dev->name);
858                         goto failed;
859                 }
860
861                 txb->encrypted = 0;
862                 txb->payload_size = skb->len;
863                 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
864         }
865
866  success:
867 //WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
868         if (txb)
869         {
870                 cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
871                 tcb_desc->bTxEnableFwCalcDur = 1;
872                 if (is_multicast_ether_addr(header.addr1))
873                         tcb_desc->bMulticast = 1;
874                 if (is_broadcast_ether_addr(header.addr1))
875                         tcb_desc->bBroadcast = 1;
876                 ieee80211_txrate_selectmode(ieee, tcb_desc);
877                 if ( tcb_desc->bMulticast ||  tcb_desc->bBroadcast)
878                         tcb_desc->data_rate = ieee->basic_rate;
879                 else
880                         //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
881                         tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
882                 ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
883                 ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
884                 ieee80211_query_HTCapShortGI(ieee, tcb_desc);
885                 ieee80211_query_BandwidthMode(ieee, tcb_desc);
886                 ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
887                 ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
888 //              IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len);
889                 //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc));
890         }
891         spin_unlock_irqrestore(&ieee->lock, flags);
892         dev_kfree_skb_any(skb);
893         if (txb) {
894                 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
895                         ieee80211_softmac_xmit(txb, ieee);
896                 }else{
897                         if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
898                                 stats->tx_packets++;
899                                 stats->tx_bytes += txb->payload_size;
900                                 return 0;
901                         }
902                         ieee80211_txb_free(txb);
903                 }
904         }
905
906         return 0;
907
908  failed:
909         spin_unlock_irqrestore(&ieee->lock, flags);
910         netif_stop_queue(dev);
911         stats->tx_errors++;
912         return 1;
913
914 }
915
916 EXPORT_SYMBOL(ieee80211_txb_free);