GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / rtl8192e / ieee80211 / ieee80211_tx.c
blob1dcf2db6c6280d627fe82b7f62cd25db581ed348
1 /******************************************************************************
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
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.
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.
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.
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
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
25 ******************************************************************************
27 Few modifications for Realtek's Wi-Fi drivers by
28 Andrea Merello <andreamrl@tiscali.it>
30 A special thanks goes to Realtek for their support !
32 ******************************************************************************/
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>
56 #include "ieee80211.h"
62 802.11 Data Frame
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 '-----------------------------------------------------------------------------------------'
76 802.11 Data Frame |
77 ,--------- 'ctrl' expands to >-----------'
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 `----.----'
87 .- 'Frame data' expands to <---------------------------'
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 `----.----'
99 .- 'IP Packet' expands, if WEP enabled, to <--'
102 ,-----------------------.
103 Bytes | 4 | 0-2296 | 4 |
104 |-----|-----------|-----|
105 Desc. | IV | Encrypted | ICV |
106 | | IP Packet | |
107 `-----------------------'
108 Total: 8 non-data bytes
111 802.3 Ethernet Data Frame
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
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.
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.
131 * SKB visualization
133 * ,- skb->data
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)
152 * SNAP HEADER
156 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
157 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
159 static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
161 struct ieee80211_snap_hdr *snap;
162 u8 *oui;
164 snap = (struct ieee80211_snap_hdr *)data;
165 snap->dsap = 0xaa;
166 snap->ssap = 0xaa;
167 snap->ctrl = 0x03;
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];
177 *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
179 return SNAP_SIZE + sizeof(u16);
182 int ieee80211_encrypt_fragment(
183 struct ieee80211_device *ieee,
184 struct sk_buff *frag,
185 int hdr_len)
187 struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
188 int res;
190 if (!(crypt && crypt->ops))
192 printk("=========>%s(), crypt is null\n", __FUNCTION__);
193 return -1;
195 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
196 struct ieee80211_hdr *header;
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);
206 return -1;
208 #endif
209 /* To encrypt, frame format is:
210 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
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);
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;
229 return 0;
233 void ieee80211_txb_free(struct ieee80211_txb *txb) {
234 //int i;
235 if (unlikely(!txb))
236 return;
237 kfree(txb);
240 struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
241 int gfp_mask)
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;
251 memset(txb, 0, sizeof(struct ieee80211_txb));
252 txb->nr_frags = nr_frags;
253 txb->frag_size = txb_size;
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;
261 memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
263 if (unlikely(i != nr_frags)) {
264 while (i >= 0)
265 dev_kfree_skb_any(txb->fragments[i--]);
266 kfree(txb);
267 return NULL;
269 return txb;
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)
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;
283 ip = ip_hdr(skb);
284 switch (ip->tos & 0xfc) {
285 case 0x20:
286 return 2;
287 case 0x40:
288 return 1;
289 case 0x60:
290 return 3;
291 case 0x80:
292 return 4;
293 case 0xa0:
294 return 5;
295 case 0xc0:
296 return 6;
297 case 0xe0:
298 return 7;
299 default:
300 return 0;
304 #define SN_LESS(a, b) (((a-b)&0x800)!=0)
305 void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
307 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
308 PTX_TS_RECORD pTxTs = NULL;
309 struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data;
311 if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
312 return;
313 if (!IsQoSDataFrame(skb->data))
314 return;
316 if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1))
317 return;
318 //check packet and mode later
319 #ifdef TO_DO_LIST
320 if(pTcb->PacketLength >= 4096)
321 return;
322 // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
323 if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
324 return;
325 #endif
327 if(tcb_desc->bdhcp)// || ieee->CntAfterLink<2)
329 return;
333 if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
335 return;
337 if(pHTInfo->bCurrentAMPDUEnable)
339 if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
341 printk("===>can't get TS\n");
342 return;
344 if (pTxTs->TxAdmittedBARecord.bValid == false)
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))
349 else
350 TsStartAddBaProcess(ieee, pTxTs);
351 goto FORCED_AGG_SETTING;
353 else if (pTxTs->bUsingBa == false)
355 if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
356 pTxTs->bUsingBa = true;
357 else
358 goto FORCED_AGG_SETTING;
361 if (ieee->iw_mode == IW_MODE_INFRA)
363 tcb_desc->bAMPDUEnable = true;
364 tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
365 tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
368 FORCED_AGG_SETTING:
369 switch(pHTInfo->ForcedAMPDUMode )
371 case HT_AGG_AUTO:
372 break;
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;
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;
387 return;
390 extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
392 tcb_desc->bUseShortPreamble = false;
393 if (tcb_desc->data_rate == 2)
394 {//// 1M can only use Long Preamble. 11B spec
395 return;
397 else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
399 tcb_desc->bUseShortPreamble = true;
401 return;
403 extern void
404 ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
406 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
408 tcb_desc->bUseShortGI = false;
410 if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
411 return;
413 if(pHTInfo->bForcedShortGI)
415 tcb_desc->bUseShortGI = true;
416 return;
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;
425 void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
427 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
429 tcb_desc->bPacketBW = false;
431 if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
432 return;
434 if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
435 return;
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;
445 void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
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
454 if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
455 return;
457 if (is_broadcast_ether_addr(skb->data+16)) //check addr3 as infrastructure add3 is DA.
458 return;
460 if (ieee->mode < IEEE_N_24G) //b, g mode
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)
468 tcb_desc->bRTSEnable = true;
469 tcb_desc->rts_rate = MGN_24M;
471 else if (ieee->current_network.buseprotection)
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;
478 //otherwise return;
479 return;
481 else
482 {// 11n High throughput case.
483 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
484 while (true)
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;
494 //check HT op mode
495 if(pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT)
497 u8 HTOpMode = pHTInfo->CurrentOpMode;
498 if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
499 (!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
501 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
502 tcb_desc->bRTSEnable = true;
503 break;
506 //check rts
507 if (skb->len > ieee->rts)
509 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
510 tcb_desc->bRTSEnable = true;
511 break;
513 //to do list: check MIMO power save condition.
514 //check AMPDU aggregation for TXOP
515 if(tcb_desc->bAMPDUEnable)
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;
523 //check IOT action
524 if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
526 tcb_desc->bCTSEnable = true;
527 tcb_desc->rts_rate = MGN_24M;
528 tcb_desc->bRTSEnable = true;
529 break;
531 // Totally no protection case!!
532 goto NO_PROTECTION;
535 // For test , CTS replace with RTS
536 if( 0 )
538 tcb_desc->bCTSEnable = true;
539 tcb_desc->rts_rate = MGN_24M;
540 tcb_desc->bRTSEnable = true;
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;
556 void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
558 #ifdef TO_DO_LIST
559 if(!IsDataFrame(pFrame))
561 pTcb->bTxDisableRateFallBack = TRUE;
562 pTcb->bTxUseDriverAssingedRate = TRUE;
563 pTcb->RATRIndex = 7;
564 return;
567 if(pMgntInfo->ForcedDataRate!= 0)
569 pTcb->bTxDisableRateFallBack = TRUE;
570 pTcb->bTxUseDriverAssingedRate = TRUE;
571 return;
573 #endif
574 if(ieee->bTxDisableRateFallBack)
575 tcb_desc->bTxDisableRateFallBack = true;
577 if(ieee->bTxUseDriverAssingedRate)
578 tcb_desc->bTxUseDriverAssingedRate = true;
579 if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
581 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
582 tcb_desc->RATRIndex = 0;
586 void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst)
588 if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
589 return;
590 if (IsQoSDataFrame(skb->data)) //we deal qos data only
592 PTX_TS_RECORD pTS = NULL;
593 if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true))
595 return;
597 pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
601 int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
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
617 u8 dest[ETH_ALEN], src[ETH_ALEN];
618 int qos_actived = ieee->current_network.qos_data.active;
620 struct ieee80211_crypt_data* crypt;
621 bool bdhcp =false;
623 cb_desc *tcb_desc;
625 spin_lock_irqsave(&ieee->lock, flags);
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;
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;
644 memset(skb->cb, 0, sizeof(skb->cb));
645 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
647 crypt = ieee->crypt[ieee->tx_keyidx];
649 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
650 ieee->host_encrypt && crypt && crypt->ops;
652 if (!encrypt && ieee->ieee802_1x &&
653 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
654 stats->tx_dropped++;
655 goto success;
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));
664 #endif
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) {
672 struct udphdr *udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
673 //if(((ntohs(udp->source) == 68) && (ntohs(udp->dest) == 67)) ||
674 /// ((ntohs(udp->source) == 67) && (ntohs(udp->dest) == 68))) {
675 if(((((u8 *)udp)[1] == 68) && (((u8 *)udp)[3] == 67)) ||
676 ((((u8 *)udp)[1] == 67) && (((u8 *)udp)[3] == 68))) {
677 // 68 : UDP BOOTP client
678 // 67 : UDP BOOTP server
679 printk("DHCP pkt src port:%d, dest port:%d!!\n", ((u8 *)udp)[1],((u8 *)udp)[3]);
680 // Use low rate to send DHCP packet.
681 //if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom)
683 // tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m
684 // tcb_desc->bTxDisableRateFallBack = false;
686 //else
687 //pTcb->DataRate = Adapter->MgntInfo.LowestBasicRate;
688 //RTPRINT(FDM, WA_IOT, ("DHCP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate));
690 bdhcp = true;
691 #ifdef _RTL8192_EXT_PATCH_
692 ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2; //AMY,090701
693 #else
694 ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2;
695 #endif
698 }else if(ETH_P_ARP == ether_type){// IP ARP packet
699 printk("=================>DHCP Protocol start tx ARP pkt!!\n");
700 bdhcp = true;
701 ieee->LPSDelayCnt = ieee->current_network.tim.tim_count;
703 //if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom)
705 // tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(Adapter->MgntInfo.mBrates);//0xc;//ofdm 6m
706 // tcb_desc->bTxDisableRateFallBack = FALSE;
708 //else
709 // tcb_desc->DataRate = Adapter->MgntInfo.LowestBasicRate;
710 //RTPRINT(FDM, WA_IOT, ("ARP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate));
715 /* Save source and destination addresses */
716 memcpy(&dest, skb->data, ETH_ALEN);
717 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
719 /* Advance the SKB to the start of the payload */
720 skb_pull(skb, sizeof(struct ethhdr));
722 /* Determine total amount of storage required for TXB packets */
723 bytes = skb->len + SNAP_SIZE + sizeof(u16);
725 if (encrypt)
726 fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
727 else
729 fc = IEEE80211_FTYPE_DATA;
731 //if(ieee->current_network.QoS_Enable)
732 if(qos_actived)
733 fc |= IEEE80211_STYPE_QOS_DATA;
734 else
735 fc |= IEEE80211_STYPE_DATA;
737 if (ieee->iw_mode == IW_MODE_INFRA) {
738 fc |= IEEE80211_FCTL_TODS;
739 /* To DS: Addr1 = BSSID, Addr2 = SA,
740 Addr3 = DA */
741 memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
742 memcpy(&header.addr2, &src, ETH_ALEN);
743 memcpy(&header.addr3, &dest, ETH_ALEN);
744 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
745 /* not From/To DS: Addr1 = DA, Addr2 = SA,
746 Addr3 = BSSID */
747 memcpy(&header.addr1, dest, ETH_ALEN);
748 memcpy(&header.addr2, src, ETH_ALEN);
749 memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
752 header.frame_ctl = cpu_to_le16(fc);
754 /* Determine fragmentation size based on destination (multicast
755 * and broadcast are not fragmented) */
756 if (is_multicast_ether_addr(header.addr1) ||
757 is_broadcast_ether_addr(header.addr1)) {
758 frag_size = MAX_FRAG_THRESHOLD;
759 qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
761 else {
762 frag_size = ieee->fts;//default:392
763 qos_ctl = 0;
766 //if (ieee->current_network.QoS_Enable)
767 if(qos_actived)
769 hdr_len = IEEE80211_3ADDR_LEN + 2;
771 skb->priority = ieee80211_classify(skb, &ieee->current_network);
772 qos_ctl |= skb->priority; //set in the ieee80211_classify
773 header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
774 } else {
775 hdr_len = IEEE80211_3ADDR_LEN;
777 /* Determine amount of payload per fragment. Regardless of if
778 * this stack is providing the full 802.11 header, one will
779 * eventually be affixed to this fragment -- so we must account for
780 * it when determining the amount of payload space. */
781 bytes_per_frag = frag_size - hdr_len;
782 if (ieee->config &
783 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
784 bytes_per_frag -= IEEE80211_FCS_LEN;
786 /* Each fragment may need to have room for encryptiong pre/postfix */
787 if (encrypt)
788 bytes_per_frag -= crypt->ops->extra_prefix_len +
789 crypt->ops->extra_postfix_len;
791 /* Number of fragments is the total bytes_per_frag /
792 * payload_per_fragment */
793 nr_frags = bytes / bytes_per_frag;
794 bytes_last_frag = bytes % bytes_per_frag;
795 if (bytes_last_frag)
796 nr_frags++;
797 else
798 bytes_last_frag = bytes_per_frag;
800 /* When we allocate the TXB we allocate enough space for the reserve
801 * and full fragment bytes (bytes_per_frag doesn't include prefix,
802 * postfix, header, FCS, etc.) */
803 txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
804 if (unlikely(!txb)) {
805 printk(KERN_WARNING "%s: Could not allocate TXB\n",
806 ieee->dev->name);
807 goto failed;
809 txb->encrypted = encrypt;
810 txb->payload_size = bytes;
812 //if (ieee->current_network.QoS_Enable)
813 if(qos_actived)
815 txb->queue_index = UP2AC(skb->priority);
816 } else {
817 txb->queue_index = WME_AC_BK;;
822 for (i = 0; i < nr_frags; i++) {
823 skb_frag = txb->fragments[i];
824 tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
825 if(qos_actived){
826 skb_frag->priority = skb->priority;//UP2AC(skb->priority);
827 tcb_desc->queue_index = UP2AC(skb->priority);
828 } else {
829 skb_frag->priority = WME_AC_BK;
830 tcb_desc->queue_index = WME_AC_BK;
832 skb_reserve(skb_frag, ieee->tx_headroom);
834 if (encrypt){
835 if (ieee->hwsec_active)
836 tcb_desc->bHwSec = 1;
837 else
838 tcb_desc->bHwSec = 0;
839 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
841 else
843 tcb_desc->bHwSec = 0;
845 frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
846 memcpy(frag_hdr, &header, hdr_len);
848 /* If this is not the last fragment, then add the MOREFRAGS
849 * bit to the frame control */
850 if (i != nr_frags - 1) {
851 frag_hdr->frame_ctl = cpu_to_le16(
852 fc | IEEE80211_FCTL_MOREFRAGS);
853 bytes = bytes_per_frag;
855 } else {
856 /* The last fragment takes the remaining length */
857 bytes = bytes_last_frag;
859 //if(ieee->current_network.QoS_Enable)
860 if(qos_actived)
862 // add 1 only indicate to corresponding seq number control 2006/7/12
863 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
864 } else {
865 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
868 /* Put a SNAP header on the first fragment */
869 if (i == 0) {
870 ieee80211_put_snap(
871 skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
872 ether_type);
873 bytes -= SNAP_SIZE + sizeof(u16);
876 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
878 /* Advance the SKB... */
879 skb_pull(skb, bytes);
881 /* Encryption routine will move the header forward in order
882 * to insert the IV between the header and the payload */
883 if (encrypt)
884 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
885 if (ieee->config &
886 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
887 skb_put(skb_frag, 4);
890 if(qos_actived)
892 if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
893 ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
894 else
895 ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
896 } else {
897 if (ieee->seq_ctrl[0] == 0xFFF)
898 ieee->seq_ctrl[0] = 0;
899 else
900 ieee->seq_ctrl[0]++;
902 }else{
903 if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
904 printk(KERN_WARNING "%s: skb too small (%d).\n",
905 ieee->dev->name, skb->len);
906 goto success;
909 txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
910 if(!txb){
911 printk(KERN_WARNING "%s: Could not allocate TXB\n",
912 ieee->dev->name);
913 goto failed;
916 txb->encrypted = 0;
917 txb->payload_size = skb->len;
918 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
921 success:
922 //WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
923 if (txb)
925 cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
926 tcb_desc->bTxEnableFwCalcDur = 1;
927 if (is_multicast_ether_addr(header.addr1))
928 tcb_desc->bMulticast = 1;
929 if (is_broadcast_ether_addr(header.addr1))
930 tcb_desc->bBroadcast = 1;
931 ieee80211_txrate_selectmode(ieee, tcb_desc);
932 if ( tcb_desc->bMulticast || tcb_desc->bBroadcast)
933 tcb_desc->data_rate = ieee->basic_rate;
934 else
935 //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
936 tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
938 if(bdhcp == true){
939 // Use low rate to send DHCP packet.
940 //if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) {
941 // tcb_desc->data_rate = MGN_1M;//MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m
942 // tcb_desc->bTxDisableRateFallBack = false;
944 //else
946 tcb_desc->data_rate = MGN_1M;
947 tcb_desc->bTxDisableRateFallBack = 1;
950 tcb_desc->RATRIndex = 7;
951 tcb_desc->bTxUseDriverAssingedRate = 1;
952 tcb_desc->bdhcp = 1;
956 ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
957 ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
958 ieee80211_query_HTCapShortGI(ieee, tcb_desc);
959 ieee80211_query_BandwidthMode(ieee, tcb_desc);
960 ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
961 ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
962 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len);
963 //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc));
965 spin_unlock_irqrestore(&ieee->lock, flags);
966 dev_kfree_skb_any(skb);
967 if (txb) {
968 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
969 ieee80211_softmac_xmit(txb, ieee);
970 }else{
971 if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
972 stats->tx_packets++;
973 stats->tx_bytes += txb->payload_size;
974 return 0;
976 ieee80211_txb_free(txb);
980 return 0;
982 failed:
983 spin_unlock_irqrestore(&ieee->lock, flags);
984 netif_stop_queue(dev);
985 stats->tx_errors++;
986 return 1;
990 //EXPORT_SYMBOL(ieee80211_txb_free);