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