Merge branch 'for-linus' of git://git.kernel.dk/linux-block
[pandora-kernel.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/errno.h>
36 #include <linux/if_arp.h>
37 #include <linux/in6.h>
38 #include <linux/in.h>
39 #include <linux/ip.h>
40 #include <linux/kernel.h>
41 #include <linux/module.h>
42 #include <linux/netdevice.h>
43 #include <linux/pci.h>
44 #include <linux/proc_fs.h>
45 #include <linux/skbuff.h>
46 #include <linux/slab.h>
47 #include <linux/tcp.h>
48 #include <linux/types.h>
49 #include <linux/wireless.h>
50 #include <linux/etherdevice.h>
51 #include <asm/uaccess.h>
52 #include <linux/if_vlan.h>
53
54 #include "ieee80211.h"
55
56
57 /*
58
59
60 802.11 Data Frame
61
62
63 802.11 frame_contorl for data frames - 2 bytes
64      ,-----------------------------------------------------------------------------------------.
65 bits | 0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |  a  |  b  |  c  |  d  |  e   |
66      |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
67 val  | 0  |  0  |  0  |  1  |  x  |  0  |  0  |  0  |  1  |  0  |  x  |  x  |  x  |  x  |  x   |
68      |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
69 desc | ^-ver-^  |  ^type-^  |  ^-----subtype-----^  | to  |from |more |retry| pwr |more |wep   |
70      |          |           | x=0 data,x=1 data+ack | DS  | DS  |frag |     | mgm |data |      |
71      '-----------------------------------------------------------------------------------------'
72                                                     /\
73                                                     |
74 802.11 Data Frame                                   |
75            ,--------- 'ctrl' expands to >-----------'
76           |
77       ,--'---,-------------------------------------------------------------.
78 Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
79       |------|------|---------|---------|---------|------|---------|------|
80 Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  Frame  |  fcs |
81       |      | tion | (BSSID) |         |         | ence |  data   |      |
82       `--------------------------------------------------|         |------'
83 Total: 28 non-data bytes                                 `----.----'
84                                                               |
85        .- 'Frame data' expands to <---------------------------'
86        |
87        V
88       ,---------------------------------------------------.
89 Bytes |  1   |  1   |    1    |    3     |  2   |  0-2304 |
90       |------|------|---------|----------|------|---------|
91 Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP      |
92       | DSAP | SSAP |         |          |      | Packet  |
93       | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8|      |         |
94       `-----------------------------------------|         |
95 Total: 8 non-data bytes                         `----.----'
96                                                      |
97        .- 'IP Packet' expands, if WEP enabled, to <--'
98        |
99        V
100       ,-----------------------.
101 Bytes |  4  |   0-2296  |  4  |
102       |-----|-----------|-----|
103 Desc. | IV  | Encrypted | ICV |
104       |     | IP Packet |     |
105       `-----------------------'
106 Total: 8 non-data bytes
107
108
109 802.3 Ethernet Data Frame
110
111       ,-----------------------------------------.
112 Bytes |   6   |   6   |  2   |  Variable |   4  |
113       |-------|-------|------|-----------|------|
114 Desc. | Dest. | Source| Type | IP Packet |  fcs |
115       |  MAC  |  MAC  |      |           |      |
116       `-----------------------------------------'
117 Total: 18 non-data bytes
118
119 In the event that fragmentation is required, the incoming payload is split into
120 N parts of size ieee->fts.  The first fragment contains the SNAP header and the
121 remaining packets are just data.
122
123 If encryption is enabled, each fragment payload size is reduced by enough space
124 to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
125 So if you have 1500 bytes of payload with ieee->fts set to 500 without
126 encryption it will take 3 frames.  With WEP it will take 4 frames as the
127 payload of each frame is reduced to 492 bytes.
128
129 * SKB visualization
130 *
131 *  ,- skb->data
132 * |
133 * |    ETHERNET HEADER        ,-<-- PAYLOAD
134 * |                           |     14 bytes from skb->data
135 * |  2 bytes for Type --> ,T. |     (sizeof ethhdr)
136 * |                       | | |
137 * |,-Dest.--. ,--Src.---. | | |
138 * |  6 bytes| | 6 bytes | | | |
139 * v         | |         | | | |
140 * 0         | v       1 | v | v           2
141 * 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
142 *     ^     | ^         | ^ |
143 *     |     | |         | | |
144 *     |     | |         | `T' <---- 2 bytes for Type
145 *     |     | |         |
146 *     |     | '---SNAP--' <-------- 6 bytes for SNAP
147 *     |     |
148 *     `-IV--' <-------------------- 4 bytes for IV (WEP)
149 *
150 *      SNAP HEADER
151 *
152 */
153
154 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
155 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
156
157 static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
158 {
159         struct ieee80211_snap_hdr *snap;
160         u8 *oui;
161
162         snap = (struct ieee80211_snap_hdr *)data;
163         snap->dsap = 0xaa;
164         snap->ssap = 0xaa;
165         snap->ctrl = 0x03;
166
167         if (h_proto == 0x8137 || h_proto == 0x80f3)
168                 oui = P802_1H_OUI;
169         else
170                 oui = RFC1042_OUI;
171         snap->oui[0] = oui[0];
172         snap->oui[1] = oui[1];
173         snap->oui[2] = oui[2];
174
175         *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
176
177         return SNAP_SIZE + sizeof(u16);
178 }
179
180 int ieee80211_encrypt_fragment(
181         struct ieee80211_device *ieee,
182         struct sk_buff *frag,
183         int hdr_len)
184 {
185         struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
186         int res;
187
188         if (!(crypt && crypt->ops))
189         {
190                 printk("=========>%s(), crypt is null\n", __FUNCTION__);
191                 return -1;
192         }
193 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
194         struct ieee80211_hdr *header;
195
196         if (ieee->tkip_countermeasures &&
197             crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
198                 header = (struct ieee80211_hdr *) frag->data;
199                 if (net_ratelimit()) {
200                         printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
201                                "TX packet to %pM\n",
202                                ieee->dev->name, header->addr1);
203                 }
204                 return -1;
205         }
206 #endif
207         /* To encrypt, frame format is:
208          * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
209
210         // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
211         /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
212          * call both MSDU and MPDU encryption functions from here. */
213         atomic_inc(&crypt->refcnt);
214         res = 0;
215         if (crypt->ops->encrypt_msdu)
216                 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
217         if (res == 0 && crypt->ops->encrypt_mpdu)
218                 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
219
220         atomic_dec(&crypt->refcnt);
221         if (res < 0) {
222                 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
223                        ieee->dev->name, frag->len);
224                 ieee->ieee_stats.tx_discards++;
225                 return -1;
226         }
227
228         return 0;
229 }
230
231
232 void ieee80211_txb_free(struct ieee80211_txb *txb) {
233         if (unlikely(!txb))
234                 return;
235         kfree(txb);
236 }
237
238 struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
239                                           int gfp_mask)
240 {
241         struct ieee80211_txb *txb;
242         int i;
243         txb = kmalloc(
244                 sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
245                 gfp_mask);
246         if (!txb)
247                 return NULL;
248
249         memset(txb, 0, sizeof(struct ieee80211_txb));
250         txb->nr_frags = nr_frags;
251         txb->frag_size = txb_size;
252
253         for (i = 0; i < nr_frags; i++) {
254                 txb->fragments[i] = dev_alloc_skb(txb_size);
255                 if (unlikely(!txb->fragments[i])) {
256                         i--;
257                         break;
258                 }
259                 memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
260         }
261         if (unlikely(i != nr_frags)) {
262                 while (i >= 0)
263                         dev_kfree_skb_any(txb->fragments[i--]);
264                 kfree(txb);
265                 return NULL;
266         }
267         return txb;
268 }
269
270 // Classify the to-be send data packet
271 // Need to acquire the sent queue index.
272 static int
273 ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
274 {
275         struct ethhdr *eth;
276         struct iphdr *ip;
277         eth = (struct ethhdr *)skb->data;
278         if (eth->h_proto != htons(ETH_P_IP))
279                 return 0;
280
281         ip = ip_hdr(skb);
282         switch (ip->tos & 0xfc) {
283                 case 0x20:
284                         return 2;
285                 case 0x40:
286                         return 1;
287                 case 0x60:
288                         return 3;
289                 case 0x80:
290                         return 4;
291                 case 0xa0:
292                         return 5;
293                 case 0xc0:
294                         return 6;
295                 case 0xe0:
296                         return 7;
297                 default:
298                         return 0;
299         }
300 }
301
302 #define SN_LESS(a, b)           (((a-b)&0x800)!=0)
303 void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
304 {
305         PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
306         PTX_TS_RECORD                   pTxTs = NULL;
307         struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data;
308
309         if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
310                 return;
311         if (!IsQoSDataFrame(skb->data))
312                 return;
313
314         if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1))
315                 return;
316         //check packet and mode later
317 #ifdef TO_DO_LIST
318         if(pTcb->PacketLength >= 4096)
319                 return;
320         // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
321         if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
322                 return;
323 #endif
324
325         if(tcb_desc->bdhcp)// || ieee->CntAfterLink<2)
326         {
327                 return;
328         }
329
330
331 #if 1
332         if (!ieee->GetNmodeSupportBySecCfg(ieee))
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 ERP protection
487                         if (ieee->current_network.buseprotection)
488                         {// CTS-to-SELF
489                                 tcb_desc->bRTSEnable = true;
490                                 tcb_desc->bCTSEnable = true;
491                                 tcb_desc->rts_rate = MGN_24M;
492                                 break;
493                         }
494                         //check HT op mode
495                         if(pHTInfo->bCurrentHTSupport  && pHTInfo->bEnableHT)
496                         {
497                                 u8 HTOpMode = pHTInfo->CurrentOpMode;
498                                 if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
499                                                         (!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
500                                 {
501                                         tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
502                                         tcb_desc->bRTSEnable = true;
503                                         break;
504                                 }
505                         }
506                         //check rts
507                         if (skb->len > ieee->rts)
508                         {
509                                 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
510                                 tcb_desc->bRTSEnable = true;
511                                 break;
512                         }
513                         //to do list: check MIMO power save condition.
514                         //check AMPDU aggregation for TXOP
515                         if(tcb_desc->bAMPDUEnable)
516                         {
517                                 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
518                                 // According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
519                                 // throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
520                                 tcb_desc->bRTSEnable = false;
521                                 break;
522                         }
523                         //check IOT action
524                         if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
525                         {
526                                 tcb_desc->bCTSEnable    = true;
527                                 tcb_desc->rts_rate  =   MGN_24M;
528                                 tcb_desc->bRTSEnable = true;
529                                 break;
530                         }
531                         // Totally no protection case!!
532                         goto NO_PROTECTION;
533                 }
534                 }
535         // For test , CTS replace with RTS
536         if( 0 )
537         {
538                 tcb_desc->bCTSEnable    = true;
539                 tcb_desc->rts_rate = MGN_24M;
540                 tcb_desc->bRTSEnable    = true;
541         }
542         if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
543                 tcb_desc->bUseShortPreamble = true;
544         if (ieee->mode == IW_MODE_MASTER)
545                         goto NO_PROTECTION;
546         return;
547 NO_PROTECTION:
548         tcb_desc->bRTSEnable    = false;
549         tcb_desc->bCTSEnable    = false;
550         tcb_desc->rts_rate              = 0;
551         tcb_desc->RTSSC         = 0;
552         tcb_desc->bRTSBW                = false;
553 }
554
555
556 void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
557 {
558 #ifdef TO_DO_LIST
559         if(!IsDataFrame(pFrame))
560         {
561                 pTcb->bTxDisableRateFallBack = TRUE;
562                 pTcb->bTxUseDriverAssingedRate = TRUE;
563                 pTcb->RATRIndex = 7;
564                 return;
565         }
566
567         if(pMgntInfo->ForcedDataRate!= 0)
568         {
569                 pTcb->bTxDisableRateFallBack = TRUE;
570                 pTcb->bTxUseDriverAssingedRate = TRUE;
571                 return;
572         }
573 #endif
574         if(ieee->bTxDisableRateFallBack)
575                 tcb_desc->bTxDisableRateFallBack = true;
576
577         if(ieee->bTxUseDriverAssingedRate)
578                 tcb_desc->bTxUseDriverAssingedRate = true;
579         if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
580         {
581                 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
582                         tcb_desc->RATRIndex = 0;
583         }
584 }
585
586 void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst)
587 {
588         if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
589                 return;
590         if (IsQoSDataFrame(skb->data)) //we deal qos data only
591         {
592                 PTX_TS_RECORD pTS = NULL;
593                 if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true))
594                 {
595                         return;
596                 }
597                 pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
598         }
599 }
600
601 int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
602 {
603         struct ieee80211_device *ieee = netdev_priv(dev);
604         struct ieee80211_txb *txb = NULL;
605         struct ieee80211_hdr_3addrqos *frag_hdr;
606         int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
607         unsigned long flags;
608         struct net_device_stats *stats = &ieee->stats;
609         int ether_type = 0, encrypt;
610         int bytes, fc, qos_ctl = 0, hdr_len;
611         struct sk_buff *skb_frag;
612         struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
613                 .duration_id = 0,
614                 .seq_ctl = 0,
615                 .qos_ctl = 0
616         };
617         u8 dest[ETH_ALEN], src[ETH_ALEN];
618         int qos_actived = ieee->current_network.qos_data.active;
619
620         struct ieee80211_crypt_data* crypt;
621         bool    bdhcp =false;
622
623         cb_desc *tcb_desc;
624
625         spin_lock_irqsave(&ieee->lock, flags);
626
627         /* If there is no driver handler to take the TXB, dont' bother
628          * creating it... */
629         if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
630            ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
631                 printk(KERN_WARNING "%s: No xmit handler.\n",
632                        ieee->dev->name);
633                 goto success;
634         }
635
636
637         if(likely(ieee->raw_tx == 0)){
638                 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
639                         printk(KERN_WARNING "%s: skb too small (%d).\n",
640                         ieee->dev->name, skb->len);
641                         goto success;
642                 }
643
644                 memset(skb->cb, 0, sizeof(skb->cb));
645                 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
646
647                 crypt = ieee->crypt[ieee->tx_keyidx];
648
649                 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
650                         ieee->host_encrypt && crypt && crypt->ops;
651
652                 if (!encrypt && ieee->ieee802_1x &&
653                 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
654                         stats->tx_dropped++;
655                         goto success;
656                 }
657         #ifdef CONFIG_IEEE80211_DEBUG
658                 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
659                         struct eapol *eap = (struct eapol *)(skb->data +
660                                 sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
661                         IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
662                                 eap_get_type(eap->type));
663                 }
664         #endif
665
666                 // The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time
667                 // to prevent DHCP protocol fail
668                 if (skb->len > 282){//MINIMUM_DHCP_PACKET_SIZE) {
669                         if (ETH_P_IP == ether_type) {// IP header
670                                 const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14);
671                                 if (IPPROTO_UDP == ip->protocol) {//FIXME windows is 11 but here UDP in linux kernel is 17.
672                                         struct udphdr *udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
673                                         if(((((u8 *)udp)[1] == 68) && (((u8 *)udp)[3] == 67)) ||
674                                                         ((((u8 *)udp)[1] == 67) && (((u8 *)udp)[3] == 68))) {
675                                                 // 68 : UDP BOOTP client
676                                                 // 67 : UDP BOOTP server
677                                                 printk("DHCP pkt src port:%d, dest port:%d!!\n", ((u8 *)udp)[1],((u8 *)udp)[3]);
678
679                                                 bdhcp = true;
680 #ifdef _RTL8192_EXT_PATCH_
681                                                 ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2; //AMY,090701
682 #else
683                                                 ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2;
684 #endif
685                                         }
686                                 }
687                                 }else if(ETH_P_ARP == ether_type){// IP ARP packet
688                                         printk("=================>DHCP Protocol start tx ARP pkt!!\n");
689                                         bdhcp = true;
690                                         ieee->LPSDelayCnt = ieee->current_network.tim.tim_count;
691
692                                 }
693                         }
694
695                 /* Save source and destination addresses */
696                 memcpy(&dest, skb->data, ETH_ALEN);
697                 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
698
699                 /* Advance the SKB to the start of the payload */
700                 skb_pull(skb, sizeof(struct ethhdr));
701
702                 /* Determine total amount of storage required for TXB packets */
703                 bytes = skb->len + SNAP_SIZE + sizeof(u16);
704
705                 if (encrypt)
706                         fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
707                 else
708
709                         fc = IEEE80211_FTYPE_DATA;
710
711                 if(qos_actived)
712                         fc |= IEEE80211_STYPE_QOS_DATA;
713                 else
714                         fc |= IEEE80211_STYPE_DATA;
715
716                 if (ieee->iw_mode == IW_MODE_INFRA) {
717                         fc |= IEEE80211_FCTL_TODS;
718                         /* To DS: Addr1 = BSSID, Addr2 = SA,
719                         Addr3 = DA */
720                         memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
721                         memcpy(&header.addr2, &src, ETH_ALEN);
722                         memcpy(&header.addr3, &dest, ETH_ALEN);
723                 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
724                         /* not From/To DS: Addr1 = DA, Addr2 = SA,
725                         Addr3 = BSSID */
726                         memcpy(&header.addr1, dest, ETH_ALEN);
727                         memcpy(&header.addr2, src, ETH_ALEN);
728                         memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
729                 }
730
731                 header.frame_ctl = cpu_to_le16(fc);
732
733                 /* Determine fragmentation size based on destination (multicast
734                 * and broadcast are not fragmented) */
735                 if (is_multicast_ether_addr(header.addr1) ||
736                 is_broadcast_ether_addr(header.addr1)) {
737                         frag_size = MAX_FRAG_THRESHOLD;
738                         qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
739                 }
740                 else {
741                         frag_size = ieee->fts;//default:392
742                         qos_ctl = 0;
743                 }
744
745                 if(qos_actived)
746                 {
747                         hdr_len = IEEE80211_3ADDR_LEN + 2;
748
749                         skb->priority = ieee80211_classify(skb, &ieee->current_network);
750                         qos_ctl |= skb->priority; //set in the ieee80211_classify
751                         header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
752                 } else {
753                         hdr_len = IEEE80211_3ADDR_LEN;
754                 }
755                 /* Determine amount of payload per fragment.  Regardless of if
756                 * this stack is providing the full 802.11 header, one will
757                 * eventually be affixed to this fragment -- so we must account for
758                 * it when determining the amount of payload space. */
759                 bytes_per_frag = frag_size - hdr_len;
760                 if (ieee->config &
761                 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
762                         bytes_per_frag -= IEEE80211_FCS_LEN;
763
764                 /* Each fragment may need to have room for encryption pre/postfix */
765                 if (encrypt)
766                         bytes_per_frag -= crypt->ops->extra_prefix_len +
767                                 crypt->ops->extra_postfix_len;
768
769                 /* Number of fragments is the total bytes_per_frag /
770                 * payload_per_fragment */
771                 nr_frags = bytes / bytes_per_frag;
772                 bytes_last_frag = bytes % bytes_per_frag;
773                 if (bytes_last_frag)
774                         nr_frags++;
775                 else
776                         bytes_last_frag = bytes_per_frag;
777
778                 /* When we allocate the TXB we allocate enough space for the reserve
779                 * and full fragment bytes (bytes_per_frag doesn't include prefix,
780                 * postfix, header, FCS, etc.) */
781                 txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
782                 if (unlikely(!txb)) {
783                         printk(KERN_WARNING "%s: Could not allocate TXB\n",
784                         ieee->dev->name);
785                         goto failed;
786                 }
787                 txb->encrypted = encrypt;
788                 txb->payload_size = bytes;
789
790                 if(qos_actived)
791                 {
792                         txb->queue_index = UP2AC(skb->priority);
793                 } else {
794                         txb->queue_index = WME_AC_BK;
795                 }
796
797
798
799                 for (i = 0; i < nr_frags; i++) {
800                         skb_frag = txb->fragments[i];
801                         tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
802                         if(qos_actived){
803                                 skb_frag->priority = skb->priority;//UP2AC(skb->priority);
804                                 tcb_desc->queue_index =  UP2AC(skb->priority);
805                         } else {
806                                 skb_frag->priority = WME_AC_BK;
807                                 tcb_desc->queue_index = WME_AC_BK;
808                         }
809                         skb_reserve(skb_frag, ieee->tx_headroom);
810
811                         if (encrypt){
812                                 if (ieee->hwsec_active)
813                                         tcb_desc->bHwSec = 1;
814                                 else
815                                         tcb_desc->bHwSec = 0;
816                                 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
817                         }
818                         else
819                         {
820                                 tcb_desc->bHwSec = 0;
821                         }
822                         frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
823                         memcpy(frag_hdr, &header, hdr_len);
824
825                         /* If this is not the last fragment, then add the MOREFRAGS
826                         * bit to the frame control */
827                         if (i != nr_frags - 1) {
828                                 frag_hdr->frame_ctl = cpu_to_le16(
829                                         fc | IEEE80211_FCTL_MOREFRAGS);
830                                 bytes = bytes_per_frag;
831
832                         } else {
833                                 /* The last fragment takes the remaining length */
834                                 bytes = bytes_last_frag;
835                         }
836
837                         if(qos_actived)
838                         {
839                                 // add 1 only indicate to corresponding seq number control 2006/7/12
840                                 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
841                         } else {
842                                 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
843                         }
844
845                         /* Put a SNAP header on the first fragment */
846                         if (i == 0) {
847                                 ieee80211_put_snap(
848                                         skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
849                                         ether_type);
850                                 bytes -= SNAP_SIZE + sizeof(u16);
851                         }
852
853                         memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
854
855                         /* Advance the SKB... */
856                         skb_pull(skb, bytes);
857
858                         /* Encryption routine will move the header forward in order
859                         * to insert the IV between the header and the payload */
860                         if (encrypt)
861                                 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
862                         if (ieee->config &
863                         (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
864                                 skb_put(skb_frag, 4);
865                 }
866
867                 if(qos_actived)
868                 {
869                   if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
870                         ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
871                   else
872                         ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
873                 } else {
874                   if (ieee->seq_ctrl[0] == 0xFFF)
875                         ieee->seq_ctrl[0] = 0;
876                   else
877                         ieee->seq_ctrl[0]++;
878                 }
879         }else{
880                 if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
881                         printk(KERN_WARNING "%s: skb too small (%d).\n",
882                         ieee->dev->name, skb->len);
883                         goto success;
884                 }
885
886                 txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
887                 if(!txb){
888                         printk(KERN_WARNING "%s: Could not allocate TXB\n",
889                         ieee->dev->name);
890                         goto failed;
891                 }
892
893                 txb->encrypted = 0;
894                 txb->payload_size = skb->len;
895                 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
896         }
897
898  success:
899 //WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
900         if (txb)
901         {
902                 cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
903                 tcb_desc->bTxEnableFwCalcDur = 1;
904                 if (is_multicast_ether_addr(header.addr1))
905                         tcb_desc->bMulticast = 1;
906                 if (is_broadcast_ether_addr(header.addr1))
907                         tcb_desc->bBroadcast = 1;
908                 ieee80211_txrate_selectmode(ieee, tcb_desc);
909                 if ( tcb_desc->bMulticast ||  tcb_desc->bBroadcast)
910                         tcb_desc->data_rate = ieee->basic_rate;
911                 else
912                         tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
913
914                 if(bdhcp == true){
915                                 tcb_desc->data_rate = MGN_1M;
916                                 tcb_desc->bTxDisableRateFallBack = 1;
917
918                         tcb_desc->RATRIndex = 7;
919                         tcb_desc->bTxUseDriverAssingedRate = 1;
920                         tcb_desc->bdhcp = 1;
921                 }
922
923
924                 ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
925                 ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
926                 ieee80211_query_HTCapShortGI(ieee, tcb_desc);
927                 ieee80211_query_BandwidthMode(ieee, tcb_desc);
928                 ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
929                 ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
930         }
931         spin_unlock_irqrestore(&ieee->lock, flags);
932         dev_kfree_skb_any(skb);
933         if (txb) {
934                 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
935                         ieee80211_softmac_xmit(txb, ieee);
936                 }else{
937                         if ((*ieee->hard_start_xmit)(txb, ieee) == 0) {
938                                 stats->tx_packets++;
939                                 stats->tx_bytes += txb->payload_size;
940                                 return 0;
941                         }
942                         ieee80211_txb_free(txb);
943                 }
944         }
945
946         return 0;
947
948  failed:
949         spin_unlock_irqrestore(&ieee->lock, flags);
950         netif_stop_queue(dev);
951         stats->tx_errors++;
952         return 1;
953
954 }
955