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
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
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>
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"
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 '-----------------------------------------------------------------------------------------'
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 |
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 |
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.
135 * | ETHERNET HEADER ,-<-- PAYLOAD
136 * | | 14 bytes from skb->data
137 * | 2 bytes for Type --> ,T. | (sizeof ethhdr)
139 * |,-Dest.--. ,--Src.---. | | |
140 * | 6 bytes| | 6 bytes | | | |
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
146 * | | | | `T' <---- 2 bytes for Type
148 * | | '---SNAP--' <-------- 6 bytes for SNAP
150 * `-IV--' <-------------------- 4 bytes for IV (WEP)
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
;
164 snap
= (struct ieee80211_snap_hdr
*)data
;
169 if (h_proto
== 0x8137 || h_proto
== 0x80f3)
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
,
187 struct ieee80211_crypt_data
* crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
190 if (!(crypt
&& crypt
->ops
))
192 printk("=========>%s(), crypt is null\n", __FUNCTION__
);
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
);
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
);
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
);
223 printk(KERN_INFO
"%s: Encryption failed: len=%d.\n",
224 ieee
->dev
->name
, frag
->len
);
225 ieee
->ieee_stats
.tx_discards
++;
233 void ieee80211_txb_free(struct ieee80211_txb
*txb
) {
240 struct ieee80211_txb
*ieee80211_alloc_txb(int nr_frags
, int txb_size
,
243 struct ieee80211_txb
*txb
;
246 sizeof(struct ieee80211_txb
) + (sizeof(u8
*) * nr_frags
),
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
])) {
261 memset(txb
->fragments
[i
]->cb
, 0, sizeof(txb
->fragments
[i
]->cb
));
263 if (unlikely(i
!= nr_frags
)) {
265 dev_kfree_skb_any(txb
->fragments
[i
--]);
272 // Classify the to-be send data packet
273 // Need to acquire the sent queue index.
275 ieee80211_classify(struct sk_buff
*skb
, struct ieee80211_network
*network
)
279 eth
= (struct ethhdr
*)skb
->data
;
280 if (eth
->h_proto
!= htons(ETH_P_IP
))
284 switch (ip
->tos
& 0xfc) {
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
)
313 if (!IsQoSDataFrame(skb
->data
))
316 if (is_multicast_ether_addr(hdr
->addr1
) || is_broadcast_ether_addr(hdr
->addr1
))
318 //check packet and mode later
320 if(pTcb
->PacketLength
>= 4096)
322 // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
323 if(!Adapter
->HalFunc
.GetNmodeSupportBySecCfgHandler(Adapter
))
327 if(tcb_desc
->bdhcp
)// || ieee->CntAfterLink<2)
333 if(!ieee
->GetNmodeSupportBySecCfg(ieee
->dev
))
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");
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
))
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;
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
;
369 switch(pHTInfo
->ForcedAMPDUMode
)
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
;
380 case HT_AGG_FORCE_DISABLE
:
381 tcb_desc
->bAMPDUEnable
= false;
382 tcb_desc
->ampdu_density
= 0;
383 tcb_desc
->ampdu_factor
= 0;
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
397 else if (ieee
->current_network
.capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
399 tcb_desc
->bUseShortPreamble
= true;
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
)
413 if(pHTInfo
->bForcedShortGI
)
415 tcb_desc
->bUseShortGI
= true;
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
)
434 if(tcb_desc
->bMulticast
|| tcb_desc
->bBroadcast
)
437 if((tcb_desc
->data_rate
& 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
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;
445 void ieee80211_query_protectionmode(struct ieee80211_device
* ieee
, cb_desc
* tcb_desc
, struct sk_buff
* skb
)
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
457 if (is_broadcast_ether_addr(skb
->data
+16)) //check addr3 as infrastructure add3 is DA.
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
;
482 {// 11n High throughput case.
483 PRT_HIGH_THROUGHPUT pHTInfo
= ieee
->pHTInfo
;
486 //check ERP protection
487 if (ieee
->current_network
.buseprotection
)
489 tcb_desc
->bRTSEnable
= true;
490 tcb_desc
->bCTSEnable
= true;
491 tcb_desc
->rts_rate
= MGN_24M
;
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;
507 if (skb
->len
> ieee
->rts
)
509 tcb_desc
->rts_rate
= MGN_24M
; // Rate is 24Mbps.
510 tcb_desc
->bRTSEnable
= true;
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;
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;
531 // Totally no protection case!!
535 // For test , CTS replace with RTS
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
)
548 tcb_desc
->bRTSEnable
= false;
549 tcb_desc
->bCTSEnable
= false;
550 tcb_desc
->rts_rate
= 0;
552 tcb_desc
->bRTSBW
= false;
556 void ieee80211_txrate_selectmode(struct ieee80211_device
* ieee
, cb_desc
* tcb_desc
)
559 if(!IsDataFrame(pFrame
))
561 pTcb
->bTxDisableRateFallBack
= TRUE
;
562 pTcb
->bTxUseDriverAssingedRate
= TRUE
;
567 if(pMgntInfo
->ForcedDataRate
!= 0)
569 pTcb
->bTxDisableRateFallBack
= TRUE
;
570 pTcb
->bTxUseDriverAssingedRate
= TRUE
;
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
))
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))
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
;
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 */
617 u8 dest
[ETH_ALEN
], src
[ETH_ALEN
];
618 int qos_actived
= ieee
->current_network
.qos_data
.active
;
620 struct ieee80211_crypt_data
* crypt
;
625 spin_lock_irqsave(&ieee
->lock
, flags
);
627 /* If there is no driver handler to take the TXB, dont' bother
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",
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
);
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
) {
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
));
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;
687 //pTcb->DataRate = Adapter->MgntInfo.LowestBasicRate;
688 //RTPRINT(FDM, WA_IOT, ("DHCP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate));
691 #ifdef _RTL8192_EXT_PATCH_
692 ieee
->LPSDelayCnt
= 100;//pPSC->LPSAwakeIntvl*2; //AMY,090701
694 ieee
->LPSDelayCnt
= 100;//pPSC->LPSAwakeIntvl*2;
698 }else if(ETH_P_ARP
== ether_type
){// IP ARP packet
699 printk("=================>DHCP Protocol start tx ARP pkt!!\n");
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;
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
);
726 fc
= IEEE80211_FTYPE_DATA
| IEEE80211_FCTL_WEP
;
729 fc
= IEEE80211_FTYPE_DATA
;
731 //if(ieee->current_network.QoS_Enable)
733 fc
|= IEEE80211_STYPE_QOS_DATA
;
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,
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,
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
;
762 frag_size
= ieee
->fts
;//default:392
766 //if (ieee->current_network.QoS_Enable)
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
);
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
;
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 */
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
;
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",
809 txb
->encrypted
= encrypt
;
810 txb
->payload_size
= bytes
;
812 //if (ieee->current_network.QoS_Enable)
815 txb
->queue_index
= UP2AC(skb
->priority
);
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
);
826 skb_frag
->priority
= skb
->priority
;//UP2AC(skb->priority);
827 tcb_desc
->queue_index
= UP2AC(skb
->priority
);
829 skb_frag
->priority
= WME_AC_BK
;
830 tcb_desc
->queue_index
= WME_AC_BK
;
832 skb_reserve(skb_frag
, ieee
->tx_headroom
);
835 if (ieee
->hwsec_active
)
836 tcb_desc
->bHwSec
= 1;
838 tcb_desc
->bHwSec
= 0;
839 skb_reserve(skb_frag
, crypt
->ops
->extra_prefix_len
);
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
;
856 /* The last fragment takes the remaining length */
857 bytes
= bytes_last_frag
;
859 //if(ieee->current_network.QoS_Enable)
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
);
865 frag_hdr
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0]<<4 | i
);
868 /* Put a SNAP header on the first fragment */
871 skb_put(skb_frag
, SNAP_SIZE
+ sizeof(u16
)),
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 */
884 ieee80211_encrypt_fragment(ieee
, skb_frag
, hdr_len
);
886 (CFG_IEEE80211_COMPUTE_FCS
| CFG_IEEE80211_RESERVE_FCS
))
887 skb_put(skb_frag
, 4);
892 if (ieee
->seq_ctrl
[UP2AC(skb
->priority
) + 1] == 0xFFF)
893 ieee
->seq_ctrl
[UP2AC(skb
->priority
) + 1] = 0;
895 ieee
->seq_ctrl
[UP2AC(skb
->priority
) + 1]++;
897 if (ieee
->seq_ctrl
[0] == 0xFFF)
898 ieee
->seq_ctrl
[0] = 0;
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
);
909 txb
= ieee80211_alloc_txb(1, skb
->len
, GFP_ATOMIC
);
911 printk(KERN_WARNING
"%s: Could not allocate TXB\n",
917 txb
->payload_size
= skb
->len
;
918 memcpy(skb_put(txb
->fragments
[0],skb
->len
), skb
->data
, skb
->len
);
922 //WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
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
;
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
);
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;
946 tcb_desc
->data_rate
= MGN_1M
;
947 tcb_desc
->bTxDisableRateFallBack
= 1;
950 tcb_desc
->RATRIndex
= 7;
951 tcb_desc
->bTxUseDriverAssingedRate
= 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
);
968 if (ieee
->softmac_features
& IEEE_SOFTMAC_TX_QUEUE
){
969 ieee80211_softmac_xmit(txb
, ieee
);
971 if ((*ieee
->hard_start_xmit
)(txb
, dev
) == 0) {
973 stats
->tx_bytes
+= txb
->payload_size
;
976 ieee80211_txb_free(txb
);
983 spin_unlock_irqrestore(&ieee
->lock
, flags
);
984 netif_stop_queue(dev
);
990 //EXPORT_SYMBOL(ieee80211_txb_free);