Merge branch 'for-linus' of git://neil.brown.name/md
[sfrench/cifs-2.6.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 <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);