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