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