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 / rtl8192su / ieee80211 / ieee80211_tx.c
blob330770b05c515f0b1430daa3f3ac382d069e9a62
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/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>
54 #include "ieee80211.h"
60 802.11 Data Frame
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 '-----------------------------------------------------------------------------------------'
74 802.11 Data Frame |
75 ,--------- 'ctrl' expands to >-----------'
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 `----.----'
85 .- 'Frame data' expands to <---------------------------'
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 `----.----'
97 .- 'IP Packet' expands, if WEP enabled, to <--'
100 ,-----------------------.
101 Bytes | 4 | 0-2296 | 4 |
102 |-----|-----------|-----|
103 Desc. | IV | Encrypted | ICV |
104 | | IP Packet | |
105 `-----------------------'
106 Total: 8 non-data bytes
109 802.3 Ethernet Data Frame
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
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.
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.
129 * SKB visualization
131 * ,- skb->data
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)
150 * SNAP HEADER
154 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
155 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
157 static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
159 struct ieee80211_snap_hdr *snap;
160 u8 *oui;
162 snap = (struct ieee80211_snap_hdr *)data;
163 snap->dsap = 0xaa;
164 snap->ssap = 0xaa;
165 snap->ctrl = 0x03;
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];
175 *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
177 return SNAP_SIZE + sizeof(u16);
180 int ieee80211_encrypt_fragment(
181 struct ieee80211_device *ieee,
182 struct sk_buff *frag,
183 int hdr_len)
185 struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
186 int res;
188 if (!(crypt && crypt->ops))
190 printk("=========>%s(), crypt is null\n", __FUNCTION__);
191 return -1;
193 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
194 struct rtl_ieee80211_hdr *header;
196 if (ieee->tkip_countermeasures &&
197 crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
198 header = (struct rtl_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);
204 return -1;
206 #endif
207 /* To encrypt, frame format is:
208 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
210 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
211 * call both MSDU and MPDU encryption functions from here. */
212 atomic_inc(&crypt->refcnt);
213 res = 0;
214 if (crypt->ops->encrypt_msdu)
215 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
216 if (res == 0 && crypt->ops->encrypt_mpdu)
217 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
219 atomic_dec(&crypt->refcnt);
220 if (res < 0) {
221 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
222 ieee->dev->name, frag->len);
223 ieee->ieee_stats.tx_discards++;
224 return -1;
227 return 0;
231 void ieee80211_txb_free(struct ieee80211_txb *txb) {
232 if (unlikely(!txb))
233 return;
234 kfree(txb);
237 struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
238 int gfp_mask)
240 struct ieee80211_txb *txb;
241 int i;
242 txb = kmalloc(
243 sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
244 gfp_mask);
245 if (!txb)
246 return NULL;
248 memset(txb, 0, sizeof(struct ieee80211_txb));
249 txb->nr_frags = nr_frags;
250 txb->frag_size = txb_size;
252 for (i = 0; i < nr_frags; i++) {
253 txb->fragments[i] = dev_alloc_skb(txb_size);
254 if (unlikely(!txb->fragments[i])) {
255 i--;
256 break;
258 memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
260 if (unlikely(i != nr_frags)) {
261 while (i >= 0)
262 dev_kfree_skb_any(txb->fragments[i--]);
263 kfree(txb);
264 return NULL;
266 return txb;
269 // Classify the to-be send data packet
270 // Need to acquire the sent queue index.
271 static int
272 ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
274 struct ethhdr *eth;
275 struct iphdr *ip;
276 eth = (struct ethhdr *)skb->data;
277 if (eth->h_proto != htons(ETH_P_IP))
278 return 0;
280 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;
302 void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
304 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
305 PTX_TS_RECORD pTxTs = NULL;
306 struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data;
308 if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
309 return;
310 if (!IsQoSDataFrame(skb->data))
311 return;
313 if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1))
314 return;
315 //check packet and mode later
316 #ifdef TO_DO_LIST
317 if(pTcb->PacketLength >= 4096)
318 return;
319 // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
320 if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
321 return;
322 #endif
324 if(pHTInfo->IOTAction & HT_IOT_ACT_TX_NO_AGGREGATION)
325 return;
327 if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
329 return;
331 if(pHTInfo->bCurrentAMPDUEnable)
333 if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
335 printk("===>can't get TS\n");
336 return;
338 if (pTxTs->TxAdmittedBARecord.bValid == false)
340 //as some AP will refuse our action frame until key handshake has been finished. WB
341 if (ieee->wpa_ie_len && (ieee->pairwise_key_type == KEY_TYPE_NA))
343 else
344 TsStartAddBaProcess(ieee, pTxTs);
345 goto FORCED_AGG_SETTING;
347 else if (pTxTs->bUsingBa == false)
349 if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
350 pTxTs->bUsingBa = true;
351 else
352 goto FORCED_AGG_SETTING;
355 if (ieee->iw_mode == IW_MODE_INFRA)
357 tcb_desc->bAMPDUEnable = true;
358 tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
359 tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
362 FORCED_AGG_SETTING:
363 switch(pHTInfo->ForcedAMPDUMode )
365 case HT_AGG_AUTO:
366 break;
368 case HT_AGG_FORCE_ENABLE:
369 tcb_desc->bAMPDUEnable = true;
370 tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
371 tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
372 break;
374 case HT_AGG_FORCE_DISABLE:
375 tcb_desc->bAMPDUEnable = false;
376 tcb_desc->ampdu_density = 0;
377 tcb_desc->ampdu_factor = 0;
378 break;
381 return;
384 extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
386 tcb_desc->bUseShortPreamble = false;
387 if (tcb_desc->data_rate == 2)
388 {//// 1M can only use Long Preamble. 11B spec
389 return;
391 else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
393 tcb_desc->bUseShortPreamble = true;
395 return;
397 extern void
398 ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
400 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
402 tcb_desc->bUseShortGI = false;
404 if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
405 return;
407 if(pHTInfo->bForcedShortGI)
409 tcb_desc->bUseShortGI = true;
410 return;
413 if((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz)
414 tcb_desc->bUseShortGI = true;
415 else if((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz)
416 tcb_desc->bUseShortGI = true;
419 void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
421 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
423 tcb_desc->bPacketBW = false;
425 if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
426 return;
428 if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
429 return;
431 if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
432 return;
433 //BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
434 if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
435 tcb_desc->bPacketBW = true;
436 return;
439 void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
441 // Common Settings
442 tcb_desc->bRTSSTBC = false;
443 tcb_desc->bRTSUseShortGI = false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
444 tcb_desc->bCTSEnable = false; // Most of protection using RTS/CTS
445 tcb_desc->RTSSC = 0; // 20MHz: Don't care; 40MHz: Duplicate.
446 tcb_desc->bRTSBW = false; // RTS frame bandwidth is always 20MHz
448 if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
449 return;
451 if (is_broadcast_ether_addr(skb->data+16)) //check addr3 as infrastructure add3 is DA.
452 return;
454 if (ieee->mode < IEEE_N_24G) //b, g mode
456 // (1) RTS_Threshold is compared to the MPDU, not MSDU.
457 // (2) If there are more than one frag in this MSDU, only the first frag uses protection frame.
458 // Other fragments are protected by previous fragment.
459 // So we only need to check the length of first fragment.
460 if (skb->len > ieee->rts)
462 tcb_desc->bRTSEnable = true;
463 tcb_desc->rts_rate = MGN_24M;
465 else if (ieee->current_network.buseprotection)
467 // Use CTS-to-SELF in protection mode.
468 tcb_desc->bRTSEnable = true;
469 tcb_desc->bCTSEnable = true;
470 tcb_desc->rts_rate = MGN_24M;
472 //otherwise return;
473 return;
475 else
476 {// 11n High throughput case.
477 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
478 while (true)
480 //check IOT action
481 if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
483 tcb_desc->bCTSEnable = true;
484 tcb_desc->rts_rate = MGN_24M;
485 tcb_desc->bRTSEnable = false;
486 break;
488 else if(pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_PURE_N_MODE))
490 tcb_desc->bRTSEnable = true;
491 tcb_desc->rts_rate = MGN_24M;
492 break;
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;
502 //check HT op mode
503 if(pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT)
505 u8 HTOpMode = pHTInfo->CurrentOpMode;
506 if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
507 (!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
509 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
510 tcb_desc->bRTSEnable = true;
511 break;
514 //check rts
515 if (skb->len > ieee->rts)
517 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
518 tcb_desc->bRTSEnable = true;
519 break;
521 //to do list: check MIMO power save condition.
522 //check AMPDU aggregation for TXOP
523 if(tcb_desc->bAMPDUEnable)
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;
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 rtl8192_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;
622 cb_desc *tcb_desc;
624 spin_lock_irqsave(&ieee->lock, flags);
626 /* If there is no driver handler to take the TXB, dont' bother
627 * creating it... */
628 if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
629 ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
630 printk(KERN_WARNING "%s: No xmit handler.\n",
631 ieee->dev->name);
632 goto success;
636 if(likely(ieee->raw_tx == 0)){
637 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
638 printk(KERN_WARNING "%s: skb too small (%d).\n",
639 ieee->dev->name, skb->len);
640 goto success;
643 memset(skb->cb, 0, sizeof(skb->cb));
644 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
646 crypt = ieee->crypt[ieee->tx_keyidx];
648 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
649 ieee->host_encrypt && crypt && crypt->ops;
651 if (!encrypt && ieee->ieee802_1x &&
652 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
653 stats->tx_dropped++;
654 goto success;
656 #ifdef CONFIG_IEEE80211_DEBUG
657 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
658 struct eapol *eap = (struct eapol *)(skb->data +
659 sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
660 IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
661 eap_get_type(eap->type));
663 #endif
665 /* Save source and destination addresses */
666 memcpy(&dest, skb->data, ETH_ALEN);
667 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
669 /* Advance the SKB to the start of the payload */
670 skb_pull(skb, sizeof(struct ethhdr));
672 /* Determine total amount of storage required for TXB packets */
673 bytes = skb->len + SNAP_SIZE + sizeof(u16);
675 if (encrypt)
676 fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
677 else
678 fc = IEEE80211_FTYPE_DATA;
680 if(qos_actived)
681 fc |= IEEE80211_STYPE_QOS_DATA;
682 else
683 fc |= IEEE80211_STYPE_DATA;
685 if (ieee->iw_mode == IW_MODE_INFRA) {
686 fc |= IEEE80211_FCTL_TODS;
687 /* To DS: Addr1 = BSSID, Addr2 = SA,
688 Addr3 = DA */
689 memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
690 memcpy(&header.addr2, &src, ETH_ALEN);
691 memcpy(&header.addr3, &dest, ETH_ALEN);
692 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
693 /* not From/To DS: Addr1 = DA, Addr2 = SA,
694 Addr3 = BSSID */
695 memcpy(&header.addr1, dest, ETH_ALEN);
696 memcpy(&header.addr2, src, ETH_ALEN);
697 memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
700 header.frame_ctl = cpu_to_le16(fc);
702 /* Determine fragmentation size based on destination (multicast
703 * and broadcast are not fragmented) */
704 if (is_multicast_ether_addr(header.addr1) ||
705 is_broadcast_ether_addr(header.addr1)) {
706 frag_size = MAX_FRAG_THRESHOLD;
707 qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
709 else {
710 frag_size = ieee->fts;//default:392
711 qos_ctl = 0;
714 //if (ieee->current_network.QoS_Enable)
715 if(qos_actived)
717 hdr_len = IEEE80211_3ADDR_LEN + 2;
719 skb->priority = ieee80211_classify(skb, &ieee->current_network);
720 qos_ctl |= skb->priority; //set in the ieee80211_classify
721 header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
722 } else {
723 hdr_len = IEEE80211_3ADDR_LEN;
725 /* Determine amount of payload per fragment. Regardless of if
726 * this stack is providing the full 802.11 header, one will
727 * eventually be affixed to this fragment -- so we must account for
728 * it when determining the amount of payload space. */
729 bytes_per_frag = frag_size - hdr_len;
730 if (ieee->config &
731 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
732 bytes_per_frag -= IEEE80211_FCS_LEN;
734 /* Each fragment may need to have room for encryptiong pre/postfix */
735 if (encrypt)
736 bytes_per_frag -= crypt->ops->extra_prefix_len +
737 crypt->ops->extra_postfix_len;
739 /* Number of fragments is the total bytes_per_frag /
740 * payload_per_fragment */
741 nr_frags = bytes / bytes_per_frag;
742 bytes_last_frag = bytes % bytes_per_frag;
743 if (bytes_last_frag)
744 nr_frags++;
745 else
746 bytes_last_frag = bytes_per_frag;
748 /* When we allocate the TXB we allocate enough space for the reserve
749 * and full fragment bytes (bytes_per_frag doesn't include prefix,
750 * postfix, header, FCS, etc.) */
751 txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
752 if (unlikely(!txb)) {
753 printk(KERN_WARNING "%s: Could not allocate TXB\n",
754 ieee->dev->name);
755 goto failed;
757 txb->encrypted = encrypt;
758 txb->payload_size = bytes;
760 if(qos_actived)
762 txb->queue_index = UP2AC(skb->priority);
763 } else {
764 txb->queue_index = WME_AC_BK;;
769 for (i = 0; i < nr_frags; i++) {
770 skb_frag = txb->fragments[i];
771 tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
772 if(qos_actived){
773 skb_frag->priority = skb->priority;//UP2AC(skb->priority);
774 tcb_desc->queue_index = UP2AC(skb->priority);
775 } else {
776 skb_frag->priority = WME_AC_BK;
777 tcb_desc->queue_index = WME_AC_BK;
779 skb_reserve(skb_frag, ieee->tx_headroom);
781 if (encrypt){
782 if (ieee->hwsec_active)
783 tcb_desc->bHwSec = 1;
784 else
785 tcb_desc->bHwSec = 0;
786 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
788 else
790 tcb_desc->bHwSec = 0;
792 frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
793 memcpy(frag_hdr, &header, hdr_len);
795 /* If this is not the last fragment, then add the MOREFRAGS
796 * bit to the frame control */
797 if (i != nr_frags - 1) {
798 frag_hdr->frame_ctl = cpu_to_le16(
799 fc | IEEE80211_FCTL_MOREFRAGS);
800 bytes = bytes_per_frag;
802 } else {
803 /* The last fragment takes the remaining length */
804 bytes = bytes_last_frag;
806 if(qos_actived)
808 // add 1 only indicate to corresponding seq number control 2006/7/12
809 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
810 } else {
811 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
814 /* Put a SNAP header on the first fragment */
815 if (i == 0) {
816 ieee80211_put_snap(
817 skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
818 ether_type);
819 bytes -= SNAP_SIZE + sizeof(u16);
822 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
824 /* Advance the SKB... */
825 skb_pull(skb, bytes);
827 /* Encryption routine will move the header forward in order
828 * to insert the IV between the header and the payload */
829 if (encrypt)
830 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
831 if (ieee->config &
832 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
833 skb_put(skb_frag, 4);
836 if(qos_actived)
838 if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
839 ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
840 else
841 ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
842 } else {
843 if (ieee->seq_ctrl[0] == 0xFFF)
844 ieee->seq_ctrl[0] = 0;
845 else
846 ieee->seq_ctrl[0]++;
848 }else{
849 if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
850 printk(KERN_WARNING "%s: skb too small (%d).\n",
851 ieee->dev->name, skb->len);
852 goto success;
855 txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
856 if(!txb){
857 printk(KERN_WARNING "%s: Could not allocate TXB\n",
858 ieee->dev->name);
859 goto failed;
862 txb->encrypted = 0;
863 txb->payload_size = skb->len;
864 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
867 success:
868 //WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
869 if (txb)
871 cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
872 tcb_desc->bTxEnableFwCalcDur = 1;
873 if (is_multicast_ether_addr(header.addr1))
874 tcb_desc->bMulticast = 1;
875 if (is_broadcast_ether_addr(header.addr1))
876 tcb_desc->bBroadcast = 1;
877 ieee80211_txrate_selectmode(ieee, tcb_desc);
878 if ( tcb_desc->bMulticast || tcb_desc->bBroadcast)
879 tcb_desc->data_rate = ieee->basic_rate;
880 else
881 tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
882 ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
883 ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
884 ieee80211_query_HTCapShortGI(ieee, tcb_desc);
885 ieee80211_query_BandwidthMode(ieee, tcb_desc);
886 ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
887 ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
889 spin_unlock_irqrestore(&ieee->lock, flags);
890 dev_kfree_skb_any(skb);
891 if (txb) {
892 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
893 ieee80211_softmac_xmit(txb, ieee);
894 }else{
895 if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
896 stats->tx_packets++;
897 stats->tx_bytes += txb->payload_size;
898 return 0;
900 ieee80211_txb_free(txb);
904 return 0;
906 failed:
907 spin_unlock_irqrestore(&ieee->lock, flags);
908 netif_stop_queue(dev);
909 stats->tx_errors++;
910 return 1;