]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
48537d948945eb5f5a68f05b77cb0fe343f5bc3d
[mv-sheeva.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/version.h>
51 #include <linux/wireless.h>
52 #include <linux/etherdevice.h>
53 #include <asm/uaccess.h>
54 #include <linux/if_vlan.h>
55
56 #include "ieee80211.h"
57
58
59 /*
60
61
62 802.11 Data Frame
63
64
65 802.11 frame_contorl for data frames - 2 bytes
66      ,-----------------------------------------------------------------------------------------.
67 bits | 0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |  a  |  b  |  c  |  d  |  e   |
68      |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
69 val  | 0  |  0  |  0  |  1  |  x  |  0  |  0  |  0  |  1  |  0  |  x  |  x  |  x  |  x  |  x   |
70      |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
71 desc | ^-ver-^  |  ^type-^  |  ^-----subtype-----^  | to  |from |more |retry| pwr |more |wep   |
72      |          |           | x=0 data,x=1 data+ack | DS  | DS  |frag |     | mgm |data |      |
73      '-----------------------------------------------------------------------------------------'
74                                                     /\
75                                                     |
76 802.11 Data Frame                                   |
77            ,--------- 'ctrl' expands to >-----------'
78           |
79       ,--'---,-------------------------------------------------------------.
80 Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
81       |------|------|---------|---------|---------|------|---------|------|
82 Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  Frame  |  fcs |
83       |      | tion | (BSSID) |         |         | ence |  data   |      |
84       `--------------------------------------------------|         |------'
85 Total: 28 non-data bytes                                 `----.----'
86                                                               |
87        .- 'Frame data' expands to <---------------------------'
88        |
89        V
90       ,---------------------------------------------------.
91 Bytes |  1   |  1   |    1    |    3     |  2   |  0-2304 |
92       |------|------|---------|----------|------|---------|
93 Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP      |
94       | DSAP | SSAP |         |          |      | Packet  |
95       | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8|      |         |
96       `-----------------------------------------|         |
97 Total: 8 non-data bytes                         `----.----'
98                                                      |
99        .- 'IP Packet' expands, if WEP enabled, to <--'
100        |
101        V
102       ,-----------------------.
103 Bytes |  4  |   0-2296  |  4  |
104       |-----|-----------|-----|
105 Desc. | IV  | Encrypted | ICV |
106       |     | IP Packet |     |
107       `-----------------------'
108 Total: 8 non-data bytes
109
110
111 802.3 Ethernet Data Frame
112
113       ,-----------------------------------------.
114 Bytes |   6   |   6   |  2   |  Variable |   4  |
115       |-------|-------|------|-----------|------|
116 Desc. | Dest. | Source| Type | IP Packet |  fcs |
117       |  MAC  |  MAC  |      |           |      |
118       `-----------------------------------------'
119 Total: 18 non-data bytes
120
121 In the event that fragmentation is required, the incoming payload is split into
122 N parts of size ieee->fts.  The first fragment contains the SNAP header and the
123 remaining packets are just data.
124
125 If encryption is enabled, each fragment payload size is reduced by enough space
126 to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
127 So if you have 1500 bytes of payload with ieee->fts set to 500 without
128 encryption it will take 3 frames.  With WEP it will take 4 frames as the
129 payload of each frame is reduced to 492 bytes.
130
131 * SKB visualization
132 *
133 *  ,- skb->data
134 * |
135 * |    ETHERNET HEADER        ,-<-- PAYLOAD
136 * |                           |     14 bytes from skb->data
137 * |  2 bytes for Type --> ,T. |     (sizeof ethhdr)
138 * |                       | | |
139 * |,-Dest.--. ,--Src.---. | | |
140 * |  6 bytes| | 6 bytes | | | |
141 * v         | |         | | | |
142 * 0         | v       1 | v | v           2
143 * 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
144 *     ^     | ^         | ^ |
145 *     |     | |         | | |
146 *     |     | |         | `T' <---- 2 bytes for Type
147 *     |     | |         |
148 *     |     | '---SNAP--' <-------- 6 bytes for SNAP
149 *     |     |
150 *     `-IV--' <-------------------- 4 bytes for IV (WEP)
151 *
152 *      SNAP HEADER
153 *
154 */
155
156 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
157 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
158
159 static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
160 {
161         struct ieee80211_snap_hdr *snap;
162         u8 *oui;
163
164         snap = (struct ieee80211_snap_hdr *)data;
165         snap->dsap = 0xaa;
166         snap->ssap = 0xaa;
167         snap->ctrl = 0x03;
168
169         if (h_proto == 0x8137 || h_proto == 0x80f3)
170                 oui = P802_1H_OUI;
171         else
172                 oui = RFC1042_OUI;
173         snap->oui[0] = oui[0];
174         snap->oui[1] = oui[1];
175         snap->oui[2] = oui[2];
176
177         *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
178
179         return SNAP_SIZE + sizeof(u16);
180 }
181
182 int ieee80211_encrypt_fragment(
183         struct ieee80211_device *ieee,
184         struct sk_buff *frag,
185         int hdr_len)
186 {
187         struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
188         int res;
189
190         if (!(crypt && crypt->ops))
191         {
192                 printk("=========>%s(), crypt is null\n", __FUNCTION__);
193                 return -1;
194         }
195 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
196         struct ieee80211_hdr *header;
197
198         if (ieee->tkip_countermeasures &&
199             crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
200                 header = (struct ieee80211_hdr *) frag->data;
201                 if (net_ratelimit()) {
202                         printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
203                                "TX packet to %pM\n",
204                                ieee->dev->name, header->addr1);
205                 }
206                 return -1;
207         }
208 #endif
209         /* To encrypt, frame format is:
210          * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
211
212         // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
213         /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
214          * call both MSDU and MPDU encryption functions from here. */
215         atomic_inc(&crypt->refcnt);
216         res = 0;
217         if (crypt->ops->encrypt_msdu)
218                 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
219         if (res == 0 && crypt->ops->encrypt_mpdu)
220                 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
221
222         atomic_dec(&crypt->refcnt);
223         if (res < 0) {
224                 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
225                        ieee->dev->name, frag->len);
226                 ieee->ieee_stats.tx_discards++;
227                 return -1;
228         }
229
230         return 0;
231 }
232
233
234 void ieee80211_txb_free(struct ieee80211_txb *txb) {
235         //int i;
236         if (unlikely(!txb))
237                 return;
238         kfree(txb);
239 }
240
241 struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
242                                           int 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 void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, 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) || is_broadcast_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 void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
417 {
418         PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
419
420         tcb_desc->bPacketBW = false;
421
422         if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
423                 return;
424
425         if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
426                 return;
427
428         if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
429                 return;
430         //BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
431         if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
432                 tcb_desc->bPacketBW = true;
433         return;
434 }
435
436 void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
437 {
438         // Common Settings
439         tcb_desc->bRTSSTBC                      = false;
440         tcb_desc->bRTSUseShortGI                = false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
441         tcb_desc->bCTSEnable                    = false; // Most of protection using RTS/CTS
442         tcb_desc->RTSSC                         = 0;            // 20MHz: Don't care;  40MHz: Duplicate.
443         tcb_desc->bRTSBW                        = false; // RTS frame bandwidth is always 20MHz
444
445         if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
446                 return;
447
448         if (is_broadcast_ether_addr(skb->data+16))  //check addr3 as infrastructure add3 is DA.
449                 return;
450
451         if (ieee->mode < IEEE_N_24G) //b, g mode
452         {
453                         // (1) RTS_Threshold is compared to the MPDU, not MSDU.
454                         // (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame.
455                         //              Other fragments are protected by previous fragment.
456                         //              So we only need to check the length of first fragment.
457                 if (skb->len > ieee->rts)
458                 {
459                         tcb_desc->bRTSEnable = true;
460                         tcb_desc->rts_rate = MGN_24M;
461                 }
462                 else if (ieee->current_network.buseprotection)
463                 {
464                         // Use CTS-to-SELF in protection mode.
465                         tcb_desc->bRTSEnable = true;
466                         tcb_desc->bCTSEnable = true;
467                         tcb_desc->rts_rate = MGN_24M;
468                 }
469                 //otherwise return;
470                 return;
471         }
472         else
473         {// 11n High throughput case.
474                 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
475                 while (true)
476                 {
477                         //check ERP protection
478                         if (ieee->current_network.buseprotection)
479                         {// CTS-to-SELF
480                                 tcb_desc->bRTSEnable = true;
481                                 tcb_desc->bCTSEnable = true;
482                                 tcb_desc->rts_rate = MGN_24M;
483                                 break;
484                         }
485                         //check HT op mode
486                         if(pHTInfo->bCurrentHTSupport  && pHTInfo->bEnableHT)
487                         {
488                                 u8 HTOpMode = pHTInfo->CurrentOpMode;
489                                 if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
490                                                         (!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
491                                 {
492                                         tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
493                                         tcb_desc->bRTSEnable = true;
494                                         break;
495                                 }
496                         }
497                         //check rts
498                         if (skb->len > ieee->rts)
499                         {
500                                 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
501                                 tcb_desc->bRTSEnable = true;
502                                 break;
503                         }
504                         //to do list: check MIMO power save condition.
505                         //check AMPDU aggregation for TXOP
506                         if(tcb_desc->bAMPDUEnable)
507                         {
508                                 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
509                                 // According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
510                                 // throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
511                                 tcb_desc->bRTSEnable = false;
512                                 break;
513                         }
514                         //check IOT action
515                         if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
516                         {
517                                 tcb_desc->bCTSEnable    = true;
518                                 tcb_desc->rts_rate  =   MGN_24M;
519                                 tcb_desc->bRTSEnable = true;
520                                 break;
521                         }
522                         // Totally no protection case!!
523                         goto NO_PROTECTION;
524                 }
525                 }
526         // For test , CTS replace with RTS
527         if( 0 )
528         {
529                 tcb_desc->bCTSEnable    = true;
530                 tcb_desc->rts_rate = MGN_24M;
531                 tcb_desc->bRTSEnable    = true;
532         }
533         if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
534                 tcb_desc->bUseShortPreamble = true;
535         if (ieee->mode == IW_MODE_MASTER)
536                         goto NO_PROTECTION;
537         return;
538 NO_PROTECTION:
539         tcb_desc->bRTSEnable    = false;
540         tcb_desc->bCTSEnable    = false;
541         tcb_desc->rts_rate              = 0;
542         tcb_desc->RTSSC         = 0;
543         tcb_desc->bRTSBW                = false;
544 }
545
546
547 void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
548 {
549 #ifdef TO_DO_LIST
550         if(!IsDataFrame(pFrame))
551         {
552                 pTcb->bTxDisableRateFallBack = TRUE;
553                 pTcb->bTxUseDriverAssingedRate = TRUE;
554                 pTcb->RATRIndex = 7;
555                 return;
556         }
557
558         if(pMgntInfo->ForcedDataRate!= 0)
559         {
560                 pTcb->bTxDisableRateFallBack = TRUE;
561                 pTcb->bTxUseDriverAssingedRate = TRUE;
562                 return;
563         }
564 #endif
565         if(ieee->bTxDisableRateFallBack)
566                 tcb_desc->bTxDisableRateFallBack = true;
567
568         if(ieee->bTxUseDriverAssingedRate)
569                 tcb_desc->bTxUseDriverAssingedRate = true;
570         if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
571         {
572                 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
573                         tcb_desc->RATRIndex = 0;
574         }
575 }
576
577 void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst)
578 {
579         if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
580                 return;
581         if (IsQoSDataFrame(skb->data)) //we deal qos data only
582         {
583                 PTX_TS_RECORD pTS = NULL;
584                 if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true))
585                 {
586                         return;
587                 }
588                 pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
589         }
590 }
591
592 int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
593 {
594         struct ieee80211_device *ieee = netdev_priv(dev);
595         struct ieee80211_txb *txb = NULL;
596         struct ieee80211_hdr_3addrqos *frag_hdr;
597         int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
598         unsigned long flags;
599         struct net_device_stats *stats = &ieee->stats;
600         int ether_type = 0, encrypt;
601         int bytes, fc, qos_ctl = 0, hdr_len;
602         struct sk_buff *skb_frag;
603         struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
604                 .duration_id = 0,
605                 .seq_ctl = 0,
606                 .qos_ctl = 0
607         };
608         u8 dest[ETH_ALEN], src[ETH_ALEN];
609         int qos_actived = ieee->current_network.qos_data.active;
610
611         struct ieee80211_crypt_data* crypt;
612
613         cb_desc *tcb_desc;
614
615         spin_lock_irqsave(&ieee->lock, flags);
616
617         /* If there is no driver handler to take the TXB, dont' bother
618          * creating it... */
619         if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
620            ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
621                 printk(KERN_WARNING "%s: No xmit handler.\n",
622                        ieee->dev->name);
623                 goto success;
624         }
625
626
627         if(likely(ieee->raw_tx == 0)){
628                 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
629                         printk(KERN_WARNING "%s: skb too small (%d).\n",
630                         ieee->dev->name, skb->len);
631                         goto success;
632                 }
633
634                 memset(skb->cb, 0, sizeof(skb->cb));
635                 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
636
637                 crypt = ieee->crypt[ieee->tx_keyidx];
638
639                 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
640                         ieee->host_encrypt && crypt && crypt->ops;
641
642                 if (!encrypt && ieee->ieee802_1x &&
643                 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
644                         stats->tx_dropped++;
645                         goto success;
646                 }
647         #ifdef CONFIG_IEEE80211_DEBUG
648                 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
649                         struct eapol *eap = (struct eapol *)(skb->data +
650                                 sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
651                         IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
652                                 eap_get_type(eap->type));
653                 }
654         #endif
655
656                 /* Save source and destination addresses */
657                 memcpy(&dest, skb->data, ETH_ALEN);
658                 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
659
660                 /* Advance the SKB to the start of the payload */
661                 skb_pull(skb, sizeof(struct ethhdr));
662
663                 /* Determine total amount of storage required for TXB packets */
664                 bytes = skb->len + SNAP_SIZE + sizeof(u16);
665
666                 if (encrypt)
667                         fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
668                 else
669
670                         fc = IEEE80211_FTYPE_DATA;
671
672                 //if(ieee->current_network.QoS_Enable)
673                 if(qos_actived)
674                         fc |= IEEE80211_STYPE_QOS_DATA;
675                 else
676                         fc |= IEEE80211_STYPE_DATA;
677
678                 if (ieee->iw_mode == IW_MODE_INFRA) {
679                         fc |= IEEE80211_FCTL_TODS;
680                         /* To DS: Addr1 = BSSID, Addr2 = SA,
681                         Addr3 = DA */
682                         memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
683                         memcpy(&header.addr2, &src, ETH_ALEN);
684                         memcpy(&header.addr3, &dest, ETH_ALEN);
685                 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
686                         /* not From/To DS: Addr1 = DA, Addr2 = SA,
687                         Addr3 = BSSID */
688                         memcpy(&header.addr1, dest, ETH_ALEN);
689                         memcpy(&header.addr2, src, ETH_ALEN);
690                         memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
691                 }
692
693                 header.frame_ctl = cpu_to_le16(fc);
694
695                 /* Determine fragmentation size based on destination (multicast
696                 * and broadcast are not fragmented) */
697                 if (is_multicast_ether_addr(header.addr1) ||
698                 is_broadcast_ether_addr(header.addr1)) {
699                         frag_size = MAX_FRAG_THRESHOLD;
700                         qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
701                 }
702                 else {
703                         frag_size = ieee->fts;//default:392
704                         qos_ctl = 0;
705                 }
706
707                 //if (ieee->current_network.QoS_Enable)
708                 if(qos_actived)
709                 {
710                         hdr_len = IEEE80211_3ADDR_LEN + 2;
711
712                         skb->priority = ieee80211_classify(skb, &ieee->current_network);
713                         qos_ctl |= skb->priority; //set in the ieee80211_classify
714                         header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
715                 } else {
716                         hdr_len = IEEE80211_3ADDR_LEN;
717                 }
718                 /* Determine amount of payload per fragment.  Regardless of if
719                 * this stack is providing the full 802.11 header, one will
720                 * eventually be affixed to this fragment -- so we must account for
721                 * it when determining the amount of payload space. */
722                 bytes_per_frag = frag_size - hdr_len;
723                 if (ieee->config &
724                 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
725                         bytes_per_frag -= IEEE80211_FCS_LEN;
726
727                 /* Each fragment may need to have room for encryptiong pre/postfix */
728                 if (encrypt)
729                         bytes_per_frag -= crypt->ops->extra_prefix_len +
730                                 crypt->ops->extra_postfix_len;
731
732                 /* Number of fragments is the total bytes_per_frag /
733                 * payload_per_fragment */
734                 nr_frags = bytes / bytes_per_frag;
735                 bytes_last_frag = bytes % bytes_per_frag;
736                 if (bytes_last_frag)
737                         nr_frags++;
738                 else
739                         bytes_last_frag = bytes_per_frag;
740
741                 /* When we allocate the TXB we allocate enough space for the reserve
742                 * and full fragment bytes (bytes_per_frag doesn't include prefix,
743                 * postfix, header, FCS, etc.) */
744                 txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
745                 if (unlikely(!txb)) {
746                         printk(KERN_WARNING "%s: Could not allocate TXB\n",
747                         ieee->dev->name);
748                         goto failed;
749                 }
750                 txb->encrypted = encrypt;
751                 txb->payload_size = bytes;
752
753                 //if (ieee->current_network.QoS_Enable)
754                 if(qos_actived)
755                 {
756                         txb->queue_index = UP2AC(skb->priority);
757                 } else {
758                         txb->queue_index = WME_AC_BK;;
759                 }
760
761
762
763                 for (i = 0; i < nr_frags; i++) {
764                         skb_frag = txb->fragments[i];
765                         tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
766                         if(qos_actived){
767                                 skb_frag->priority = skb->priority;//UP2AC(skb->priority);
768                                 tcb_desc->queue_index =  UP2AC(skb->priority);
769                         } else {
770                                 skb_frag->priority = WME_AC_BK;
771                                 tcb_desc->queue_index = WME_AC_BK;
772                         }
773                         skb_reserve(skb_frag, ieee->tx_headroom);
774
775                         if (encrypt){
776                                 if (ieee->hwsec_active)
777                                         tcb_desc->bHwSec = 1;
778                                 else
779                                         tcb_desc->bHwSec = 0;
780                                 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
781                         }
782                         else
783                         {
784                                 tcb_desc->bHwSec = 0;
785                         }
786                         frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
787                         memcpy(frag_hdr, &header, hdr_len);
788
789                         /* If this is not the last fragment, then add the MOREFRAGS
790                         * bit to the frame control */
791                         if (i != nr_frags - 1) {
792                                 frag_hdr->frame_ctl = cpu_to_le16(
793                                         fc | IEEE80211_FCTL_MOREFRAGS);
794                                 bytes = bytes_per_frag;
795
796                         } else {
797                                 /* The last fragment takes the remaining length */
798                                 bytes = bytes_last_frag;
799                         }
800                         //if(ieee->current_network.QoS_Enable)
801                         if(qos_actived)
802                         {
803                                 // add 1 only indicate to corresponding seq number control 2006/7/12
804                                 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
805                         } else {
806                                 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
807                         }
808
809                         /* Put a SNAP header on the first fragment */
810                         if (i == 0) {
811                                 ieee80211_put_snap(
812                                         skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
813                                         ether_type);
814                                 bytes -= SNAP_SIZE + sizeof(u16);
815                         }
816
817                         memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
818
819                         /* Advance the SKB... */
820                         skb_pull(skb, bytes);
821
822                         /* Encryption routine will move the header forward in order
823                         * to insert the IV between the header and the payload */
824                         if (encrypt)
825                                 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
826                         if (ieee->config &
827                         (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
828                                 skb_put(skb_frag, 4);
829                 }
830
831                 if(qos_actived)
832                 {
833                   if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
834                         ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
835                   else
836                         ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
837                 } else {
838                   if (ieee->seq_ctrl[0] == 0xFFF)
839                         ieee->seq_ctrl[0] = 0;
840                   else
841                         ieee->seq_ctrl[0]++;
842                 }
843         }else{
844                 if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
845                         printk(KERN_WARNING "%s: skb too small (%d).\n",
846                         ieee->dev->name, skb->len);
847                         goto success;
848                 }
849
850                 txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
851                 if(!txb){
852                         printk(KERN_WARNING "%s: Could not allocate TXB\n",
853                         ieee->dev->name);
854                         goto failed;
855                 }
856
857                 txb->encrypted = 0;
858                 txb->payload_size = skb->len;
859                 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
860         }
861
862  success:
863 //WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
864         if (txb)
865         {
866                 cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
867                 tcb_desc->bTxEnableFwCalcDur = 1;
868                 if (is_multicast_ether_addr(header.addr1))
869                         tcb_desc->bMulticast = 1;
870                 if (is_broadcast_ether_addr(header.addr1))
871                         tcb_desc->bBroadcast = 1;
872                 ieee80211_txrate_selectmode(ieee, tcb_desc);
873                 if ( tcb_desc->bMulticast ||  tcb_desc->bBroadcast)
874                         tcb_desc->data_rate = ieee->basic_rate;
875                 else
876                         //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
877                         tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
878                 ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
879                 ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
880                 ieee80211_query_HTCapShortGI(ieee, tcb_desc);
881                 ieee80211_query_BandwidthMode(ieee, tcb_desc);
882                 ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
883                 ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
884 //              IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len);
885                 //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc));
886         }
887         spin_unlock_irqrestore(&ieee->lock, flags);
888         dev_kfree_skb_any(skb);
889         if (txb) {
890                 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
891                         ieee80211_softmac_xmit(txb, ieee);
892                 }else{
893                         if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
894                                 stats->tx_packets++;
895                                 stats->tx_bytes += txb->payload_size;
896                                 return 0;
897                         }
898                         ieee80211_txb_free(txb);
899                 }
900         }
901
902         return 0;
903
904  failed:
905         spin_unlock_irqrestore(&ieee->lock, flags);
906         netif_stop_queue(dev);
907         stats->tx_errors++;
908         return 1;
909
910 }
911
912 EXPORT_SYMBOL(ieee80211_txb_free);