• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/staging/rtl8192u/ieee80211/
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/wireless.h>
51#include <linux/etherdevice.h>
52#include <asm/uaccess.h>
53#include <linux/if_vlan.h>
54
55#include "ieee80211.h"
56
57
58/*
59
60
61802.11 Data Frame
62
63
64802.11 frame_contorl for data frames - 2 bytes
65     ,-----------------------------------------------------------------------------------------.
66bits | 0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |  a  |  b  |  c  |  d  |  e   |
67     |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
68val  | 0  |  0  |  0  |  1  |  x  |  0  |  0  |  0  |  1  |  0  |  x  |  x  |  x  |  x  |  x   |
69     |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
70desc | ^-ver-^  |  ^type-^  |  ^-----subtype-----^  | to  |from |more |retry| pwr |more |wep   |
71     |          |           | x=0 data,x=1 data+ack | DS  | DS  |frag |     | mgm |data |      |
72     '-----------------------------------------------------------------------------------------'
73		                                    /\
74                                                    |
75802.11 Data Frame                                   |
76           ,--------- 'ctrl' expands to >-----------'
77          |
78      ,--'---,-------------------------------------------------------------.
79Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
80      |------|------|---------|---------|---------|------|---------|------|
81Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  Frame  |  fcs |
82      |      | tion | (BSSID) |         |         | ence |  data   |      |
83      `--------------------------------------------------|         |------'
84Total: 28 non-data bytes                                 `----.----'
85                                                              |
86       .- 'Frame data' expands to <---------------------------'
87       |
88       V
89      ,---------------------------------------------------.
90Bytes |  1   |  1   |    1    |    3     |  2   |  0-2304 |
91      |------|------|---------|----------|------|---------|
92Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP      |
93      | DSAP | SSAP |         |          |      | Packet  |
94      | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8|      |         |
95      `-----------------------------------------|         |
96Total: 8 non-data bytes                         `----.----'
97                                                     |
98       .- 'IP Packet' expands, if WEP enabled, to <--'
99       |
100       V
101      ,-----------------------.
102Bytes |  4  |   0-2296  |  4  |
103      |-----|-----------|-----|
104Desc. | IV  | Encrypted | ICV |
105      |     | IP Packet |     |
106      `-----------------------'
107Total: 8 non-data bytes
108
109
110802.3 Ethernet Data Frame
111
112      ,-----------------------------------------.
113Bytes |   6   |   6   |  2   |  Variable |   4  |
114      |-------|-------|------|-----------|------|
115Desc. | Dest. | Source| Type | IP Packet |  fcs |
116      |  MAC  |  MAC  |      |           |      |
117      `-----------------------------------------'
118Total: 18 non-data bytes
119
120In the event that fragmentation is required, the incoming payload is split into
121N parts of size ieee->fts.  The first fragment contains the SNAP header and the
122remaining packets are just data.
123
124If encryption is enabled, each fragment payload size is reduced by enough space
125to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
126So if you have 1500 bytes of payload with ieee->fts set to 500 without
127encryption it will take 3 frames.  With WEP it will take 4 frames as the
128payload of each frame is reduced to 492 bytes.
129
130* SKB visualization
131*
132*  ,- skb->data
133* |
134* |    ETHERNET HEADER        ,-<-- PAYLOAD
135* |                           |     14 bytes from skb->data
136* |  2 bytes for Type --> ,T. |     (sizeof ethhdr)
137* |                       | | |
138* |,-Dest.--. ,--Src.---. | | |
139* |  6 bytes| | 6 bytes | | | |
140* v         | |         | | | |
141* 0         | v       1 | v | v           2
142* 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
143*     ^     | ^         | ^ |
144*     |     | |         | | |
145*     |     | |         | `T' <---- 2 bytes for Type
146*     |     | |         |
147*     |     | '---SNAP--' <-------- 6 bytes for SNAP
148*     |     |
149*     `-IV--' <-------------------- 4 bytes for IV (WEP)
150*
151*      SNAP HEADER
152*
153*/
154
155static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
156static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
157
158static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
159{
160	struct ieee80211_snap_hdr *snap;
161	u8 *oui;
162
163	snap = (struct ieee80211_snap_hdr *)data;
164	snap->dsap = 0xaa;
165	snap->ssap = 0xaa;
166	snap->ctrl = 0x03;
167
168	if (h_proto == 0x8137 || h_proto == 0x80f3)
169		oui = P802_1H_OUI;
170	else
171		oui = RFC1042_OUI;
172	snap->oui[0] = oui[0];
173	snap->oui[1] = oui[1];
174	snap->oui[2] = oui[2];
175
176	*(u16 *)(data + SNAP_SIZE) = htons(h_proto);
177
178	return SNAP_SIZE + sizeof(u16);
179}
180
181int ieee80211_encrypt_fragment(
182	struct ieee80211_device *ieee,
183	struct sk_buff *frag,
184	int hdr_len)
185{
186	struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
187	int res;
188
189	if (!(crypt && crypt->ops))
190	{
191		printk("=========>%s(), crypt is null\n", __FUNCTION__);
192		return -1;
193	}
194#ifdef CONFIG_IEEE80211_CRYPT_TKIP
195	struct ieee80211_hdr *header;
196
197	if (ieee->tkip_countermeasures &&
198	    crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
199		header = (struct ieee80211_hdr *) frag->data;
200		if (net_ratelimit()) {
201			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
202			       "TX packet to %pM\n",
203			       ieee->dev->name, header->addr1);
204		}
205		return -1;
206	}
207#endif
208	/* To encrypt, frame format is:
209	 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
210
211	/* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
212	 * call both MSDU and MPDU encryption functions from here. */
213	atomic_inc(&crypt->refcnt);
214	res = 0;
215	if (crypt->ops->encrypt_msdu)
216		res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
217	if (res == 0 && crypt->ops->encrypt_mpdu)
218		res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
219
220	atomic_dec(&crypt->refcnt);
221	if (res < 0) {
222		printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
223		       ieee->dev->name, frag->len);
224		ieee->ieee_stats.tx_discards++;
225		return -1;
226	}
227
228	return 0;
229}
230
231
232void ieee80211_txb_free(struct ieee80211_txb *txb) {
233	//int i;
234	if (unlikely(!txb))
235		return;
236	kfree(txb);
237}
238
239struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
240					  int gfp_mask)
241{
242	struct ieee80211_txb *txb;
243	int i;
244	txb = kmalloc(
245		sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
246		gfp_mask);
247	if (!txb)
248		return NULL;
249
250	memset(txb, 0, sizeof(struct ieee80211_txb));
251	txb->nr_frags = nr_frags;
252	txb->frag_size = txb_size;
253
254	for (i = 0; i < nr_frags; i++) {
255		txb->fragments[i] = dev_alloc_skb(txb_size);
256		if (unlikely(!txb->fragments[i])) {
257			i--;
258			break;
259		}
260		memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
261	}
262	if (unlikely(i != nr_frags)) {
263		while (i >= 0)
264			dev_kfree_skb_any(txb->fragments[i--]);
265		kfree(txb);
266		return NULL;
267	}
268	return txb;
269}
270
271// Classify the to-be send data packet
272// Need to acquire the sent queue index.
273static int
274ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
275{
276	struct ethhdr *eth;
277	struct iphdr *ip;
278	eth = (struct ethhdr *)skb->data;
279	if (eth->h_proto != htons(ETH_P_IP))
280		return 0;
281
282//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
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;
301	}
302}
303
304#define SN_LESS(a, b)		(((a-b)&0x800)!=0)
305void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
306{
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;
310
311	if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
312		return;
313	if (!IsQoSDataFrame(skb->data))
314		return;
315
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
326	if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
327	{
328		return;
329	}
330	if(pHTInfo->bCurrentAMPDUEnable)
331	{
332		if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
333		{
334			printk("===>can't get TS\n");
335			return;
336		}
337		if (pTxTs->TxAdmittedBARecord.bValid == false)
338		{
339			TsStartAddBaProcess(ieee, pTxTs);
340			goto FORCED_AGG_SETTING;
341		}
342		else if (pTxTs->bUsingBa == false)
343		{
344			if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
345				pTxTs->bUsingBa = true;
346			else
347				goto FORCED_AGG_SETTING;
348		}
349
350		if (ieee->iw_mode == IW_MODE_INFRA)
351		{
352			tcb_desc->bAMPDUEnable = true;
353			tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
354			tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
355		}
356	}
357FORCED_AGG_SETTING:
358	switch(pHTInfo->ForcedAMPDUMode )
359	{
360		case HT_AGG_AUTO:
361			break;
362
363		case HT_AGG_FORCE_ENABLE:
364			tcb_desc->bAMPDUEnable = true;
365			tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
366			tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
367			break;
368
369		case HT_AGG_FORCE_DISABLE:
370			tcb_desc->bAMPDUEnable = false;
371			tcb_desc->ampdu_density = 0;
372			tcb_desc->ampdu_factor = 0;
373			break;
374
375	}
376		return;
377}
378
379extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
380{
381	tcb_desc->bUseShortPreamble = false;
382	if (tcb_desc->data_rate == 2)
383	{//// 1M can only use Long Preamble. 11B spec
384		return;
385	}
386	else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
387	{
388		tcb_desc->bUseShortPreamble = true;
389	}
390	return;
391}
392extern	void
393ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
394{
395	PRT_HIGH_THROUGHPUT		pHTInfo = ieee->pHTInfo;
396
397	tcb_desc->bUseShortGI 		= false;
398
399	if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
400		return;
401
402	if(pHTInfo->bForcedShortGI)
403	{
404		tcb_desc->bUseShortGI = true;
405		return;
406	}
407
408	if((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz)
409		tcb_desc->bUseShortGI = true;
410	else if((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz)
411		tcb_desc->bUseShortGI = true;
412}
413
414void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
415{
416	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
417
418	tcb_desc->bPacketBW = false;
419
420	if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
421		return;
422
423	if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
424		return;
425
426	if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
427		return;
428	//BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
429	if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
430		tcb_desc->bPacketBW = true;
431	return;
432}
433
434void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
435{
436	// Common Settings
437	tcb_desc->bRTSSTBC			= false;
438	tcb_desc->bRTSUseShortGI		= false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
439	tcb_desc->bCTSEnable			= false; // Most of protection using RTS/CTS
440	tcb_desc->RTSSC				= 0;		// 20MHz: Don't care;  40MHz: Duplicate.
441	tcb_desc->bRTSBW			= false; // RTS frame bandwidth is always 20MHz
442
443	if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
444		return;
445
446	if (is_broadcast_ether_addr(skb->data+16))  //check addr3 as infrastructure add3 is DA.
447		return;
448
449	if (ieee->mode < IEEE_N_24G) //b, g mode
450	{
451			// (1) RTS_Threshold is compared to the MPDU, not MSDU.
452			// (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame.
453			//		Other fragments are protected by previous fragment.
454			//		So we only need to check the length of first fragment.
455		if (skb->len > ieee->rts)
456		{
457			tcb_desc->bRTSEnable = true;
458			tcb_desc->rts_rate = MGN_24M;
459		}
460		else if (ieee->current_network.buseprotection)
461		{
462			// Use CTS-to-SELF in protection mode.
463			tcb_desc->bRTSEnable = true;
464			tcb_desc->bCTSEnable = true;
465			tcb_desc->rts_rate = MGN_24M;
466		}
467		//otherwise return;
468		return;
469	}
470	else
471	{// 11n High throughput case.
472		PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
473		while (true)
474		{
475			//check ERP protection
476			if (ieee->current_network.buseprotection)
477			{// CTS-to-SELF
478				tcb_desc->bRTSEnable = true;
479				tcb_desc->bCTSEnable = true;
480				tcb_desc->rts_rate = MGN_24M;
481				break;
482			}
483			//check HT op mode
484			if(pHTInfo->bCurrentHTSupport  && pHTInfo->bEnableHT)
485			{
486				u8 HTOpMode = pHTInfo->CurrentOpMode;
487				if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
488							(!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
489				{
490					tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
491					tcb_desc->bRTSEnable = true;
492					break;
493				}
494			}
495			//check rts
496			if (skb->len > ieee->rts)
497			{
498				tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
499				tcb_desc->bRTSEnable = true;
500				break;
501			}
502			//to do list: check MIMO power save condition.
503			//check AMPDU aggregation for TXOP
504			if(tcb_desc->bAMPDUEnable)
505			{
506				tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
507				// According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
508				// throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
509				tcb_desc->bRTSEnable = false;
510				break;
511			}
512			//check IOT action
513			if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
514			{
515				tcb_desc->bCTSEnable	= true;
516				tcb_desc->rts_rate  = 	MGN_24M;
517				tcb_desc->bRTSEnable = true;
518				break;
519			}
520			// Totally no protection case!!
521			goto NO_PROTECTION;
522		}
523		}
524	// For test , CTS replace with RTS
525	if( 0 )
526	{
527		tcb_desc->bCTSEnable	= true;
528		tcb_desc->rts_rate = MGN_24M;
529		tcb_desc->bRTSEnable 	= true;
530	}
531	if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
532		tcb_desc->bUseShortPreamble = true;
533	if (ieee->mode == IW_MODE_MASTER)
534			goto NO_PROTECTION;
535	return;
536NO_PROTECTION:
537	tcb_desc->bRTSEnable	= false;
538	tcb_desc->bCTSEnable	= false;
539	tcb_desc->rts_rate		= 0;
540	tcb_desc->RTSSC		= 0;
541	tcb_desc->bRTSBW		= false;
542}
543
544
545void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
546{
547#ifdef TO_DO_LIST
548	if(!IsDataFrame(pFrame))
549	{
550		pTcb->bTxDisableRateFallBack = TRUE;
551		pTcb->bTxUseDriverAssingedRate = TRUE;
552		pTcb->RATRIndex = 7;
553		return;
554	}
555
556	if(pMgntInfo->ForcedDataRate!= 0)
557	{
558		pTcb->bTxDisableRateFallBack = TRUE;
559		pTcb->bTxUseDriverAssingedRate = TRUE;
560		return;
561	}
562#endif
563	if(ieee->bTxDisableRateFallBack)
564		tcb_desc->bTxDisableRateFallBack = true;
565
566	if(ieee->bTxUseDriverAssingedRate)
567		tcb_desc->bTxUseDriverAssingedRate = true;
568	if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
569	{
570		if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
571			tcb_desc->RATRIndex = 0;
572	}
573}
574
575void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst)
576{
577	if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
578		return;
579	if (IsQoSDataFrame(skb->data)) //we deal qos data only
580	{
581		PTX_TS_RECORD pTS = NULL;
582		if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true))
583		{
584			return;
585		}
586		pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
587	}
588}
589
590int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
591{
592	struct ieee80211_device *ieee = netdev_priv(dev);
593	struct ieee80211_txb *txb = NULL;
594	struct ieee80211_hdr_3addrqos *frag_hdr;
595	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
596	unsigned long flags;
597	struct net_device_stats *stats = &ieee->stats;
598	int ether_type = 0, encrypt;
599	int bytes, fc, qos_ctl = 0, hdr_len;
600	struct sk_buff *skb_frag;
601	struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
602		.duration_id = 0,
603		.seq_ctl = 0,
604		.qos_ctl = 0
605	};
606	u8 dest[ETH_ALEN], src[ETH_ALEN];
607	int qos_actived = ieee->current_network.qos_data.active;
608
609	struct ieee80211_crypt_data* crypt;
610
611	cb_desc *tcb_desc;
612
613	spin_lock_irqsave(&ieee->lock, flags);
614
615	/* If there is no driver handler to take the TXB, dont' bother
616	 * creating it... */
617	if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
618	   ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
619		printk(KERN_WARNING "%s: No xmit handler.\n",
620		       ieee->dev->name);
621		goto success;
622	}
623
624
625	if(likely(ieee->raw_tx == 0)){
626		if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
627			printk(KERN_WARNING "%s: skb too small (%d).\n",
628			ieee->dev->name, skb->len);
629			goto success;
630		}
631
632		memset(skb->cb, 0, sizeof(skb->cb));
633		ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
634
635		crypt = ieee->crypt[ieee->tx_keyidx];
636
637		encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
638			ieee->host_encrypt && crypt && crypt->ops;
639
640		if (!encrypt && ieee->ieee802_1x &&
641		ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
642			stats->tx_dropped++;
643			goto success;
644		}
645	#ifdef CONFIG_IEEE80211_DEBUG
646		if (crypt && !encrypt && ether_type == ETH_P_PAE) {
647			struct eapol *eap = (struct eapol *)(skb->data +
648				sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
649			IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
650				eap_get_type(eap->type));
651		}
652	#endif
653
654		/* Save source and destination addresses */
655		memcpy(&dest, skb->data, ETH_ALEN);
656		memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
657
658                /* Advance the SKB to the start of the payload */
659                skb_pull(skb, sizeof(struct ethhdr));
660
661                /* Determine total amount of storage required for TXB packets */
662                bytes = skb->len + SNAP_SIZE + sizeof(u16);
663
664		if (encrypt)
665			fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
666		else
667
668                        fc = IEEE80211_FTYPE_DATA;
669
670		//if(ieee->current_network.QoS_Enable)
671		if(qos_actived)
672			fc |= IEEE80211_STYPE_QOS_DATA;
673		else
674			fc |= IEEE80211_STYPE_DATA;
675
676		if (ieee->iw_mode == IW_MODE_INFRA) {
677			fc |= IEEE80211_FCTL_TODS;
678			/* To DS: Addr1 = BSSID, Addr2 = SA,
679			Addr3 = DA */
680			memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
681			memcpy(&header.addr2, &src, ETH_ALEN);
682			memcpy(&header.addr3, &dest, ETH_ALEN);
683		} else if (ieee->iw_mode == IW_MODE_ADHOC) {
684			/* not From/To DS: Addr1 = DA, Addr2 = SA,
685			Addr3 = BSSID */
686			memcpy(&header.addr1, dest, ETH_ALEN);
687			memcpy(&header.addr2, src, ETH_ALEN);
688			memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
689		}
690
691                header.frame_ctl = cpu_to_le16(fc);
692
693		/* Determine fragmentation size based on destination (multicast
694		* and broadcast are not fragmented) */
695		if (is_multicast_ether_addr(header.addr1) ||
696		is_broadcast_ether_addr(header.addr1)) {
697			frag_size = MAX_FRAG_THRESHOLD;
698			qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
699		}
700		else {
701			frag_size = ieee->fts;//default:392
702			qos_ctl = 0;
703		}
704
705		//if (ieee->current_network.QoS_Enable)
706		if(qos_actived)
707		{
708			hdr_len = IEEE80211_3ADDR_LEN + 2;
709
710			skb->priority = ieee80211_classify(skb, &ieee->current_network);
711			qos_ctl |= skb->priority; //set in the ieee80211_classify
712			header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
713		} else {
714			hdr_len = IEEE80211_3ADDR_LEN;
715		}
716		/* Determine amount of payload per fragment.  Regardless of if
717		* this stack is providing the full 802.11 header, one will
718		* eventually be affixed to this fragment -- so we must account for
719		* it when determining the amount of payload space. */
720		bytes_per_frag = frag_size - hdr_len;
721		if (ieee->config &
722		(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
723			bytes_per_frag -= IEEE80211_FCS_LEN;
724
725		/* Each fragment may need to have room for encryptiong pre/postfix */
726		if (encrypt)
727			bytes_per_frag -= crypt->ops->extra_prefix_len +
728				crypt->ops->extra_postfix_len;
729
730		/* Number of fragments is the total bytes_per_frag /
731		* payload_per_fragment */
732		nr_frags = bytes / bytes_per_frag;
733		bytes_last_frag = bytes % bytes_per_frag;
734		if (bytes_last_frag)
735			nr_frags++;
736		else
737			bytes_last_frag = bytes_per_frag;
738
739		/* When we allocate the TXB we allocate enough space for the reserve
740		* and full fragment bytes (bytes_per_frag doesn't include prefix,
741		* postfix, header, FCS, etc.) */
742		txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
743		if (unlikely(!txb)) {
744			printk(KERN_WARNING "%s: Could not allocate TXB\n",
745			ieee->dev->name);
746			goto failed;
747		}
748		txb->encrypted = encrypt;
749		txb->payload_size = bytes;
750
751		//if (ieee->current_network.QoS_Enable)
752		if(qos_actived)
753		{
754			txb->queue_index = UP2AC(skb->priority);
755		} else {
756			txb->queue_index = WME_AC_BK;;
757		}
758
759
760
761		for (i = 0; i < nr_frags; i++) {
762			skb_frag = txb->fragments[i];
763			tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
764			if(qos_actived){
765				skb_frag->priority = skb->priority;//UP2AC(skb->priority);
766				tcb_desc->queue_index =  UP2AC(skb->priority);
767			} else {
768				skb_frag->priority = WME_AC_BK;
769				tcb_desc->queue_index = WME_AC_BK;
770			}
771			skb_reserve(skb_frag, ieee->tx_headroom);
772
773			if (encrypt){
774				if (ieee->hwsec_active)
775					tcb_desc->bHwSec = 1;
776				else
777					tcb_desc->bHwSec = 0;
778				skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
779			}
780			else
781			{
782				tcb_desc->bHwSec = 0;
783			}
784			frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
785			memcpy(frag_hdr, &header, hdr_len);
786
787			/* If this is not the last fragment, then add the MOREFRAGS
788			* bit to the frame control */
789			if (i != nr_frags - 1) {
790				frag_hdr->frame_ctl = cpu_to_le16(
791					fc | IEEE80211_FCTL_MOREFRAGS);
792				bytes = bytes_per_frag;
793
794			} else {
795				/* The last fragment takes the remaining length */
796				bytes = bytes_last_frag;
797			}
798			//if(ieee->current_network.QoS_Enable)
799			if(qos_actived)
800			{
801				// add 1 only indicate to corresponding seq number control 2006/7/12
802				frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
803			} else {
804				frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
805			}
806
807			/* Put a SNAP header on the first fragment */
808			if (i == 0) {
809				ieee80211_put_snap(
810					skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
811					ether_type);
812				bytes -= SNAP_SIZE + sizeof(u16);
813			}
814
815			memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
816
817			/* Advance the SKB... */
818			skb_pull(skb, bytes);
819
820			/* Encryption routine will move the header forward in order
821			* to insert the IV between the header and the payload */
822			if (encrypt)
823				ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
824			if (ieee->config &
825			(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
826				skb_put(skb_frag, 4);
827		}
828
829		if(qos_actived)
830		{
831		  if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
832			ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
833		  else
834			ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
835		} else {
836  		  if (ieee->seq_ctrl[0] == 0xFFF)
837			ieee->seq_ctrl[0] = 0;
838		  else
839			ieee->seq_ctrl[0]++;
840		}
841	}else{
842		if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
843			printk(KERN_WARNING "%s: skb too small (%d).\n",
844			ieee->dev->name, skb->len);
845			goto success;
846		}
847
848		txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
849		if(!txb){
850			printk(KERN_WARNING "%s: Could not allocate TXB\n",
851			ieee->dev->name);
852			goto failed;
853		}
854
855		txb->encrypted = 0;
856		txb->payload_size = skb->len;
857		memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
858	}
859
860 success:
861//WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
862	if (txb)
863	{
864		cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
865		tcb_desc->bTxEnableFwCalcDur = 1;
866		if (is_multicast_ether_addr(header.addr1))
867			tcb_desc->bMulticast = 1;
868		if (is_broadcast_ether_addr(header.addr1))
869			tcb_desc->bBroadcast = 1;
870		ieee80211_txrate_selectmode(ieee, tcb_desc);
871		if ( tcb_desc->bMulticast ||  tcb_desc->bBroadcast)
872			tcb_desc->data_rate = ieee->basic_rate;
873		else
874			//tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
875			tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
876		ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
877		ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
878		ieee80211_query_HTCapShortGI(ieee, tcb_desc);
879		ieee80211_query_BandwidthMode(ieee, tcb_desc);
880		ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
881		ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
882//		IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len);
883		//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc));
884	}
885	spin_unlock_irqrestore(&ieee->lock, flags);
886	dev_kfree_skb_any(skb);
887	if (txb) {
888		if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
889			ieee80211_softmac_xmit(txb, ieee);
890		}else{
891			if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
892				stats->tx_packets++;
893				stats->tx_bytes += txb->payload_size;
894				return 0;
895			}
896			ieee80211_txb_free(txb);
897		}
898	}
899
900	return 0;
901
902 failed:
903	spin_unlock_irqrestore(&ieee->lock, flags);
904	netif_stop_queue(dev);
905	stats->tx_errors++;
906	return 1;
907
908}
909
910EXPORT_SYMBOL(ieee80211_txb_free);
911