Merge branch 'classmate' into release
[safe/jmp/linux-2.6] / drivers / staging / rtl8192su / ieee80211 / ieee80211_tx.c
1 /******************************************************************************
2
3   Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4
5   This program is free software; you can redistribute it and/or modify it
6   under the terms of version 2 of the GNU General Public License as
7   published by the Free Software Foundation.
8
9   This program is distributed in the hope that it will be useful, but WITHOUT
10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12   more details.
13
14   You should have received a copy of the GNU General Public License along with
15   this program; if not, write to the Free Software Foundation, Inc., 59
16   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17
18   The full GNU General Public License is included in this distribution in the
19   file called LICENSE.
20
21   Contact Information:
22   James P. Ketrenos <ipw2100-admin@linux.intel.com>
23   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25 ******************************************************************************
26
27   Few modifications for Realtek's Wi-Fi drivers by
28   Andrea Merello <andreamrl@tiscali.it>
29
30   A special thanks goes to Realtek for their support !
31
32 ******************************************************************************/
33
34 #include <linux/compiler.h>
35 //#include <linux/config.h>
36 #include <linux/errno.h>
37 #include <linux/if_arp.h>
38 #include <linux/in6.h>
39 #include <linux/in.h>
40 #include <linux/ip.h>
41 #include <linux/kernel.h>
42 #include <linux/module.h>
43 #include <linux/netdevice.h>
44 #include <linux/pci.h>
45 #include <linux/proc_fs.h>
46 #include <linux/skbuff.h>
47 #include <linux/slab.h>
48 #include <linux/tcp.h>
49 #include <linux/types.h>
50 #include <linux/wireless.h>
51 #include <linux/etherdevice.h>
52 #include <asm/uaccess.h>
53 #include <linux/if_vlan.h>
54
55 #include "ieee80211.h"
56
57
58 /*
59
60
61 802.11 Data Frame
62
63
64 802.11 frame_contorl for data frames - 2 bytes
65      ,-----------------------------------------------------------------------------------------.
66 bits | 0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |  a  |  b  |  c  |  d  |  e   |
67      |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
68 val  | 0  |  0  |  0  |  1  |  x  |  0  |  0  |  0  |  1  |  0  |  x  |  x  |  x  |  x  |  x   |
69      |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
70 desc | ^-ver-^  |  ^type-^  |  ^-----subtype-----^  | to  |from |more |retry| pwr |more |wep   |
71      |          |           | x=0 data,x=1 data+ack | DS  | DS  |frag |     | mgm |data |      |
72      '-----------------------------------------------------------------------------------------'
73                                                     /\
74                                                     |
75 802.11 Data Frame                                   |
76            ,--------- 'ctrl' expands to >-----------'
77           |
78       ,--'---,-------------------------------------------------------------.
79 Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
80       |------|------|---------|---------|---------|------|---------|------|
81 Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  Frame  |  fcs |
82       |      | tion | (BSSID) |         |         | ence |  data   |      |
83       `--------------------------------------------------|         |------'
84 Total: 28 non-data bytes                                 `----.----'
85                                                               |
86        .- 'Frame data' expands to <---------------------------'
87        |
88        V
89       ,---------------------------------------------------.
90 Bytes |  1   |  1   |    1    |    3     |  2   |  0-2304 |
91       |------|------|---------|----------|------|---------|
92 Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP      |
93       | DSAP | SSAP |         |          |      | Packet  |
94       | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8|      |         |
95       `-----------------------------------------|         |
96 Total: 8 non-data bytes                         `----.----'
97                                                      |
98        .- 'IP Packet' expands, if WEP enabled, to <--'
99        |
100        V
101       ,-----------------------.
102 Bytes |  4  |   0-2296  |  4  |
103       |-----|-----------|-----|
104 Desc. | IV  | Encrypted | ICV |
105       |     | IP Packet |     |
106       `-----------------------'
107 Total: 8 non-data bytes
108
109
110 802.3 Ethernet Data Frame
111
112       ,-----------------------------------------.
113 Bytes |   6   |   6   |  2   |  Variable |   4  |
114       |-------|-------|------|-----------|------|
115 Desc. | Dest. | Source| Type | IP Packet |  fcs |
116       |  MAC  |  MAC  |      |           |      |
117       `-----------------------------------------'
118 Total: 18 non-data bytes
119
120 In the event that fragmentation is required, the incoming payload is split into
121 N parts of size ieee->fts.  The first fragment contains the SNAP header and the
122 remaining packets are just data.
123
124 If encryption is enabled, each fragment payload size is reduced by enough space
125 to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
126 So if you have 1500 bytes of payload with ieee->fts set to 500 without
127 encryption it will take 3 frames.  With WEP it will take 4 frames as the
128 payload of each frame is reduced to 492 bytes.
129
130 * SKB visualization
131 *
132 *  ,- skb->data
133 * |
134 * |    ETHERNET HEADER        ,-<-- PAYLOAD
135 * |                           |     14 bytes from skb->data
136 * |  2 bytes for Type --> ,T. |     (sizeof ethhdr)
137 * |                       | | |
138 * |,-Dest.--. ,--Src.---. | | |
139 * |  6 bytes| | 6 bytes | | | |
140 * v         | |         | | | |
141 * 0         | v       1 | v | v           2
142 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
143 *     ^     | ^         | ^ |
144 *     |     | |         | | |
145 *     |     | |         | `T' <---- 2 bytes for Type
146 *     |     | |         |
147 *     |     | '---SNAP--' <-------- 6 bytes for SNAP
148 *     |     |
149 *     `-IV--' <-------------------- 4 bytes for IV (WEP)
150 *
151 *      SNAP HEADER
152 *
153 */
154
155 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
156 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
157
158 static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
159 {
160         struct ieee80211_snap_hdr *snap;
161         u8 *oui;
162
163         snap = (struct ieee80211_snap_hdr *)data;
164         snap->dsap = 0xaa;
165         snap->ssap = 0xaa;
166         snap->ctrl = 0x03;
167
168         if (h_proto == 0x8137 || h_proto == 0x80f3)
169                 oui = P802_1H_OUI;
170         else
171                 oui = RFC1042_OUI;
172         snap->oui[0] = oui[0];
173         snap->oui[1] = oui[1];
174         snap->oui[2] = oui[2];
175
176         *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
177
178         return SNAP_SIZE + sizeof(u16);
179 }
180
181 int ieee80211_encrypt_fragment(
182         struct ieee80211_device *ieee,
183         struct sk_buff *frag,
184         int hdr_len)
185 {
186         struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
187         int res;
188
189         if (!(crypt && crypt->ops))
190         {
191                 printk("=========>%s(), crypt is null\n", __FUNCTION__);
192                 return -1;
193         }
194 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
195         struct rtl_ieee80211_hdr *header;
196
197         if (ieee->tkip_countermeasures &&
198             crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
199                 header = (struct rtl_ieee80211_hdr *)frag->data;
200                 if (net_ratelimit()) {
201                         printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
202                                "TX packet to " MAC_FMT "\n",
203                                ieee->dev->name, MAC_ARG(header->addr1));
204                 }
205                 return -1;
206         }
207 #endif
208         /* To encrypt, frame format is:
209          * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
210
211         // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
212         /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
213          * call both MSDU and MPDU encryption functions from here. */
214         atomic_inc(&crypt->refcnt);
215         res = 0;
216         if (crypt->ops->encrypt_msdu)
217                 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
218         if (res == 0 && crypt->ops->encrypt_mpdu)
219                 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
220
221         atomic_dec(&crypt->refcnt);
222         if (res < 0) {
223                 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
224                        ieee->dev->name, frag->len);
225                 ieee->ieee_stats.tx_discards++;
226                 return -1;
227         }
228
229         return 0;
230 }
231
232
233 void ieee80211_txb_free(struct ieee80211_txb *txb) {
234         //int i;
235         if (unlikely(!txb))
236                 return;
237         kfree(txb);
238 }
239
240 struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
241                                           int gfp_mask)
242 {
243         struct ieee80211_txb *txb;
244         int i;
245         txb = kmalloc(
246                 sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
247                 gfp_mask);
248         if (!txb)
249                 return NULL;
250
251         memset(txb, 0, sizeof(struct ieee80211_txb));
252         txb->nr_frags = nr_frags;
253         txb->frag_size = txb_size;
254
255         for (i = 0; i < nr_frags; i++) {
256                 txb->fragments[i] = dev_alloc_skb(txb_size);
257                 if (unlikely(!txb->fragments[i])) {
258                         i--;
259                         break;
260                 }
261                 memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
262         }
263         if (unlikely(i != nr_frags)) {
264                 while (i >= 0)
265                         dev_kfree_skb_any(txb->fragments[i--]);
266                 kfree(txb);
267                 return NULL;
268         }
269         return txb;
270 }
271
272 // Classify the to-be send data packet
273 // Need to acquire the sent queue index.
274 static int
275 ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
276 {
277         struct ethhdr *eth;
278         struct iphdr *ip;
279         eth = (struct ethhdr *)skb->data;
280         if (eth->h_proto != htons(ETH_P_IP))
281                 return 0;
282
283 //      IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
284         ip = ip_hdr(skb);
285
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 void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
307 {
308         PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
309         PTX_TS_RECORD                   pTxTs = NULL;
310         struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data;
311
312         if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
313                 return;
314         if (!IsQoSDataFrame(skb->data))
315                 return;
316
317         if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1))
318                 return;
319         //check packet and mode later
320 #ifdef TO_DO_LIST
321         if(pTcb->PacketLength >= 4096)
322                 return;
323         // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
324         if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
325                 return;
326 #endif
327
328         if(pHTInfo->IOTAction & HT_IOT_ACT_TX_NO_AGGREGATION)
329                 return;
330
331 #if 1
332         if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
333         {
334                 return;
335         }
336 #endif
337         if(pHTInfo->bCurrentAMPDUEnable)
338         {
339                 if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
340                 {
341                         printk("===>can't get TS\n");
342                         return;
343                 }
344                 if (pTxTs->TxAdmittedBARecord.bValid == false)
345                 {
346                         //as some AP will refuse our action frame until key handshake has been finished. WB
347                         if (ieee->wpa_ie_len && (ieee->pairwise_key_type == KEY_TYPE_NA))
348                         ;
349                         else
350                         TsStartAddBaProcess(ieee, pTxTs);
351                         goto FORCED_AGG_SETTING;
352                 }
353                 else if (pTxTs->bUsingBa == false)
354                 {
355                         if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
356                                 pTxTs->bUsingBa = true;
357                         else
358                                 goto FORCED_AGG_SETTING;
359                 }
360
361                 if (ieee->iw_mode == IW_MODE_INFRA)
362                 {
363                         tcb_desc->bAMPDUEnable = true;
364                         tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
365                         tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
366                 }
367         }
368 FORCED_AGG_SETTING:
369         switch(pHTInfo->ForcedAMPDUMode )
370         {
371                 case HT_AGG_AUTO:
372                         break;
373
374                 case HT_AGG_FORCE_ENABLE:
375                         tcb_desc->bAMPDUEnable = true;
376                         tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
377                         tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
378                         break;
379
380                 case HT_AGG_FORCE_DISABLE:
381                         tcb_desc->bAMPDUEnable = false;
382                         tcb_desc->ampdu_density = 0;
383                         tcb_desc->ampdu_factor = 0;
384                         break;
385
386         }
387                 return;
388 }
389
390 extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
391 {
392         tcb_desc->bUseShortPreamble = false;
393         if (tcb_desc->data_rate == 2)
394         {//// 1M can only use Long Preamble. 11B spec
395                 return;
396         }
397         else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
398         {
399                 tcb_desc->bUseShortPreamble = true;
400         }
401         return;
402 }
403 extern  void
404 ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
405 {
406         PRT_HIGH_THROUGHPUT             pHTInfo = ieee->pHTInfo;
407
408         tcb_desc->bUseShortGI           = false;
409
410         if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
411                 return;
412
413         if(pHTInfo->bForcedShortGI)
414         {
415                 tcb_desc->bUseShortGI = true;
416                 return;
417         }
418
419         if((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz)
420                 tcb_desc->bUseShortGI = true;
421         else if((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz)
422                 tcb_desc->bUseShortGI = true;
423 }
424
425 void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
426 {
427         PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
428
429         tcb_desc->bPacketBW = false;
430
431         if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
432                 return;
433
434         if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
435                 return;
436
437         if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
438                 return;
439         //BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
440         if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
441                 tcb_desc->bPacketBW = true;
442         return;
443 }
444
445 void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
446 {
447         // Common Settings
448         tcb_desc->bRTSSTBC                      = false;
449         tcb_desc->bRTSUseShortGI                = false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
450         tcb_desc->bCTSEnable                    = false; // Most of protection using RTS/CTS
451         tcb_desc->RTSSC                         = 0;            // 20MHz: Don't care;  40MHz: Duplicate.
452         tcb_desc->bRTSBW                        = false; // RTS frame bandwidth is always 20MHz
453
454         if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
455                 return;
456
457         if (is_broadcast_ether_addr(skb->data+16))  //check addr3 as infrastructure add3 is DA.
458                 return;
459
460         if (ieee->mode < IEEE_N_24G) //b, g mode
461         {
462                         // (1) RTS_Threshold is compared to the MPDU, not MSDU.
463                         // (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame.
464                         //              Other fragments are protected by previous fragment.
465                         //              So we only need to check the length of first fragment.
466                 if (skb->len > ieee->rts)
467                 {
468                         tcb_desc->bRTSEnable = true;
469                         tcb_desc->rts_rate = MGN_24M;
470                 }
471                 else if (ieee->current_network.buseprotection)
472                 {
473                         // Use CTS-to-SELF in protection mode.
474                         tcb_desc->bRTSEnable = true;
475                         tcb_desc->bCTSEnable = true;
476                         tcb_desc->rts_rate = MGN_24M;
477                 }
478                 //otherwise return;
479                 return;
480         }
481         else
482         {// 11n High throughput case.
483                 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
484                 while (true)
485                 {
486                         //check IOT action
487                         if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
488                         {
489                                 tcb_desc->bCTSEnable    = true;
490                                 tcb_desc->rts_rate  =   MGN_24M;
491                                 tcb_desc->bRTSEnable = false;
492                                 break;
493                         }
494                         else if(pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_PURE_N_MODE))
495                         {
496                                 tcb_desc->bRTSEnable = true;
497                                 tcb_desc->rts_rate  =   MGN_24M;
498                                 break;
499                         }
500                         //check ERP protection
501                         if (ieee->current_network.buseprotection)
502                         {// CTS-to-SELF
503                                 tcb_desc->bRTSEnable = true;
504                                 tcb_desc->bCTSEnable = true;
505                                 tcb_desc->rts_rate = MGN_24M;
506                                 break;
507                         }
508                         //check HT op mode
509                         if(pHTInfo->bCurrentHTSupport  && pHTInfo->bEnableHT)
510                         {
511                                 u8 HTOpMode = pHTInfo->CurrentOpMode;
512                                 if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
513                                                         (!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
514                                 {
515                                         tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
516                                         tcb_desc->bRTSEnable = true;
517                                         break;
518                                 }
519                         }
520                         //check rts
521                         if (skb->len > ieee->rts)
522                         {
523                                 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
524                                 tcb_desc->bRTSEnable = true;
525                                 break;
526                         }
527                         //to do list: check MIMO power save condition.
528                         //check AMPDU aggregation for TXOP
529                         if(tcb_desc->bAMPDUEnable)
530                         {
531                                 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
532                                 // According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
533                                 // throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
534                                 tcb_desc->bRTSEnable = false;
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 rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
608 {
609         struct ieee80211_device *ieee = netdev_priv(dev);
610         struct ieee80211_txb *txb = NULL;
611         struct ieee80211_hdr_3addrqos *frag_hdr;
612         int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
613         unsigned long flags;
614         struct net_device_stats *stats = &ieee->stats;
615         int ether_type = 0, encrypt;
616         int bytes, fc, qos_ctl = 0, hdr_len;
617         struct sk_buff *skb_frag;
618         struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
619                 .duration_id = 0,
620                 .seq_ctl = 0,
621                 .qos_ctl = 0
622         };
623         u8 dest[ETH_ALEN], src[ETH_ALEN];
624         int qos_actived = ieee->current_network.qos_data.active;
625
626         struct ieee80211_crypt_data* crypt;
627
628         cb_desc *tcb_desc;
629
630         spin_lock_irqsave(&ieee->lock, flags);
631
632         /* If there is no driver handler to take the TXB, dont' bother
633          * creating it... */
634         if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
635            ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
636                 printk(KERN_WARNING "%s: No xmit handler.\n",
637                        ieee->dev->name);
638                 goto success;
639         }
640
641
642         if(likely(ieee->raw_tx == 0)){
643                 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
644                         printk(KERN_WARNING "%s: skb too small (%d).\n",
645                         ieee->dev->name, skb->len);
646                         goto success;
647                 }
648
649                 memset(skb->cb, 0, sizeof(skb->cb));
650                 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
651
652                 crypt = ieee->crypt[ieee->tx_keyidx];
653
654                 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
655                         ieee->host_encrypt && crypt && crypt->ops;
656
657                 if (!encrypt && ieee->ieee802_1x &&
658                 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
659                         stats->tx_dropped++;
660                         goto success;
661                 }
662         #ifdef CONFIG_IEEE80211_DEBUG
663                 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
664                         struct eapol *eap = (struct eapol *)(skb->data +
665                                 sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
666                         IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
667                                 eap_get_type(eap->type));
668                 }
669         #endif
670
671                 /* Save source and destination addresses */
672                 memcpy(&dest, skb->data, ETH_ALEN);
673                 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
674
675                 /* Advance the SKB to the start of the payload */
676                 skb_pull(skb, sizeof(struct ethhdr));
677
678                 /* Determine total amount of storage required for TXB packets */
679                 bytes = skb->len + SNAP_SIZE + sizeof(u16);
680
681                 if (encrypt)
682                         fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
683                 else
684
685                         fc = IEEE80211_FTYPE_DATA;
686
687                 //if(ieee->current_network.QoS_Enable)
688                 if(qos_actived)
689                         fc |= IEEE80211_STYPE_QOS_DATA;
690                 else
691                         fc |= IEEE80211_STYPE_DATA;
692
693                 if (ieee->iw_mode == IW_MODE_INFRA) {
694                         fc |= IEEE80211_FCTL_TODS;
695                         /* To DS: Addr1 = BSSID, Addr2 = SA,
696                         Addr3 = DA */
697                         memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
698                         memcpy(&header.addr2, &src, ETH_ALEN);
699                         memcpy(&header.addr3, &dest, ETH_ALEN);
700                 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
701                         /* not From/To DS: Addr1 = DA, Addr2 = SA,
702                         Addr3 = BSSID */
703                         memcpy(&header.addr1, dest, ETH_ALEN);
704                         memcpy(&header.addr2, src, ETH_ALEN);
705                         memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
706                 }
707
708                 header.frame_ctl = cpu_to_le16(fc);
709
710                 /* Determine fragmentation size based on destination (multicast
711                 * and broadcast are not fragmented) */
712                 if (is_multicast_ether_addr(header.addr1) ||
713                 is_broadcast_ether_addr(header.addr1)) {
714                         frag_size = MAX_FRAG_THRESHOLD;
715                         qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
716                 }
717                 else {
718                         frag_size = ieee->fts;//default:392
719                         qos_ctl = 0;
720                 }
721
722                 //if (ieee->current_network.QoS_Enable)
723                 if(qos_actived)
724                 {
725                         hdr_len = IEEE80211_3ADDR_LEN + 2;
726
727                         skb->priority = ieee80211_classify(skb, &ieee->current_network);
728                         qos_ctl |= skb->priority; //set in the ieee80211_classify
729                         header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
730                 } else {
731                         hdr_len = IEEE80211_3ADDR_LEN;
732                 }
733                 /* Determine amount of payload per fragment.  Regardless of if
734                 * this stack is providing the full 802.11 header, one will
735                 * eventually be affixed to this fragment -- so we must account for
736                 * it when determining the amount of payload space. */
737                 bytes_per_frag = frag_size - hdr_len;
738                 if (ieee->config &
739                 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
740                         bytes_per_frag -= IEEE80211_FCS_LEN;
741
742                 /* Each fragment may need to have room for encryptiong pre/postfix */
743                 if (encrypt)
744                         bytes_per_frag -= crypt->ops->extra_prefix_len +
745                                 crypt->ops->extra_postfix_len;
746
747                 /* Number of fragments is the total bytes_per_frag /
748                 * payload_per_fragment */
749                 nr_frags = bytes / bytes_per_frag;
750                 bytes_last_frag = bytes % bytes_per_frag;
751                 if (bytes_last_frag)
752                         nr_frags++;
753                 else
754                         bytes_last_frag = bytes_per_frag;
755
756                 /* When we allocate the TXB we allocate enough space for the reserve
757                 * and full fragment bytes (bytes_per_frag doesn't include prefix,
758                 * postfix, header, FCS, etc.) */
759                 txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
760                 if (unlikely(!txb)) {
761                         printk(KERN_WARNING "%s: Could not allocate TXB\n",
762                         ieee->dev->name);
763                         goto failed;
764                 }
765                 txb->encrypted = encrypt;
766                 txb->payload_size = bytes;
767
768                 //if (ieee->current_network.QoS_Enable)
769                 if(qos_actived)
770                 {
771                         txb->queue_index = UP2AC(skb->priority);
772                 } else {
773                         txb->queue_index = WME_AC_BK;;
774                 }
775
776
777
778                 for (i = 0; i < nr_frags; i++) {
779                         skb_frag = txb->fragments[i];
780                         tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
781                         if(qos_actived){
782                                 skb_frag->priority = skb->priority;//UP2AC(skb->priority);
783                                 tcb_desc->queue_index =  UP2AC(skb->priority);
784                         } else {
785                                 skb_frag->priority = WME_AC_BK;
786                                 tcb_desc->queue_index = WME_AC_BK;
787                         }
788                         skb_reserve(skb_frag, ieee->tx_headroom);
789
790                         if (encrypt){
791                                 if (ieee->hwsec_active)
792                                         tcb_desc->bHwSec = 1;
793                                 else
794                                         tcb_desc->bHwSec = 0;
795                                 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
796                         }
797                         else
798                         {
799                                 tcb_desc->bHwSec = 0;
800                         }
801                         frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
802                         memcpy(frag_hdr, &header, hdr_len);
803
804                         /* If this is not the last fragment, then add the MOREFRAGS
805                         * bit to the frame control */
806                         if (i != nr_frags - 1) {
807                                 frag_hdr->frame_ctl = cpu_to_le16(
808                                         fc | IEEE80211_FCTL_MOREFRAGS);
809                                 bytes = bytes_per_frag;
810
811                         } else {
812                                 /* The last fragment takes the remaining length */
813                                 bytes = bytes_last_frag;
814                         }
815                         //if(ieee->current_network.QoS_Enable)
816                         if(qos_actived)
817                         {
818                                 // add 1 only indicate to corresponding seq number control 2006/7/12
819                                 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
820                         } else {
821                                 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
822                         }
823
824                         /* Put a SNAP header on the first fragment */
825                         if (i == 0) {
826                                 ieee80211_put_snap(
827                                         skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
828                                         ether_type);
829                                 bytes -= SNAP_SIZE + sizeof(u16);
830                         }
831
832                         memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
833
834                         /* Advance the SKB... */
835                         skb_pull(skb, bytes);
836
837                         /* Encryption routine will move the header forward in order
838                         * to insert the IV between the header and the payload */
839                         if (encrypt)
840                                 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
841                         if (ieee->config &
842                         (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
843                                 skb_put(skb_frag, 4);
844                 }
845
846                 if(qos_actived)
847                 {
848                   if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
849                         ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
850                   else
851                         ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
852                 } else {
853                   if (ieee->seq_ctrl[0] == 0xFFF)
854                         ieee->seq_ctrl[0] = 0;
855                   else
856                         ieee->seq_ctrl[0]++;
857                 }
858         }else{
859                 if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
860                         printk(KERN_WARNING "%s: skb too small (%d).\n",
861                         ieee->dev->name, skb->len);
862                         goto success;
863                 }
864
865                 txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
866                 if(!txb){
867                         printk(KERN_WARNING "%s: Could not allocate TXB\n",
868                         ieee->dev->name);
869                         goto failed;
870                 }
871
872                 txb->encrypted = 0;
873                 txb->payload_size = skb->len;
874                 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
875         }
876
877  success:
878 //WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
879         if (txb)
880         {
881 #if 1
882                 cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
883                 tcb_desc->bTxEnableFwCalcDur = 1;
884                 if (is_multicast_ether_addr(header.addr1))
885                         tcb_desc->bMulticast = 1;
886                 if (is_broadcast_ether_addr(header.addr1))
887                         tcb_desc->bBroadcast = 1;
888                 ieee80211_txrate_selectmode(ieee, tcb_desc);
889                 if ( tcb_desc->bMulticast ||  tcb_desc->bBroadcast)
890                         tcb_desc->data_rate = ieee->basic_rate;
891                 else
892                         //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
893                         tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
894                 ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
895                 ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
896                 ieee80211_query_HTCapShortGI(ieee, tcb_desc);
897                 ieee80211_query_BandwidthMode(ieee, tcb_desc);
898                 ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
899                 ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
900 //              IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len);
901                 //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc));
902 #endif
903         }
904         spin_unlock_irqrestore(&ieee->lock, flags);
905         dev_kfree_skb_any(skb);
906         if (txb) {
907                 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
908                         ieee80211_softmac_xmit(txb, ieee);
909                 }else{
910                         if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
911                                 stats->tx_packets++;
912                                 stats->tx_bytes += txb->payload_size;
913                                 return 0;
914                         }
915                         ieee80211_txb_free(txb);
916                 }
917         }
918
919         return 0;
920
921  failed:
922         spin_unlock_irqrestore(&ieee->lock, flags);
923         netif_stop_queue(dev);
924         stats->tx_errors++;
925         return 1;
926
927 }