• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/rtl8192su/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/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>
53
54#include "ieee80211.h"
55
56
57/*
58
59
60802.11 Data Frame
61
62
63802.11 frame_contorl for data frames - 2 bytes
64     ,-----------------------------------------------------------------------------------------.
65bits | 0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |  a  |  b  |  c  |  d  |  e   |
66     |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
67val  | 0  |  0  |  0  |  1  |  x  |  0  |  0  |  0  |  1  |  0  |  x  |  x  |  x  |  x  |  x   |
68     |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
69desc | ^-ver-^  |  ^type-^  |  ^-----subtype-----^  | to  |from |more |retry| pwr |more |wep   |
70     |          |           | x=0 data,x=1 data+ack | DS  | DS  |frag |     | mgm |data |      |
71     '-----------------------------------------------------------------------------------------'
72		                                    /\
73                                                    |
74802.11 Data Frame                                   |
75           ,--------- 'ctrl' expands to >-----------'
76          |
77      ,--'---,-------------------------------------------------------------.
78Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
79      |------|------|---------|---------|---------|------|---------|------|
80Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  Frame  |  fcs |
81      |      | tion | (BSSID) |         |         | ence |  data   |      |
82      `--------------------------------------------------|         |------'
83Total: 28 non-data bytes                                 `----.----'
84                                                              |
85       .- 'Frame data' expands to <---------------------------'
86       |
87       V
88      ,---------------------------------------------------.
89Bytes |  1   |  1   |    1    |    3     |  2   |  0-2304 |
90      |------|------|---------|----------|------|---------|
91Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP      |
92      | DSAP | SSAP |         |          |      | Packet  |
93      | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8|      |         |
94      `-----------------------------------------|         |
95Total: 8 non-data bytes                         `----.----'
96                                                     |
97       .- 'IP Packet' expands, if WEP enabled, to <--'
98       |
99       V
100      ,-----------------------.
101Bytes |  4  |   0-2296  |  4  |
102      |-----|-----------|-----|
103Desc. | IV  | Encrypted | ICV |
104      |     | IP Packet |     |
105      `-----------------------'
106Total: 8 non-data bytes
107
108
109802.3 Ethernet Data Frame
110
111      ,-----------------------------------------.
112Bytes |   6   |   6   |  2   |  Variable |   4  |
113      |-------|-------|------|-----------|------|
114Desc. | Dest. | Source| Type | IP Packet |  fcs |
115      |  MAC  |  MAC  |      |           |      |
116      `-----------------------------------------'
117Total: 18 non-data bytes
118
119In the event that fragmentation is required, the incoming payload is split into
120N parts of size ieee->fts.  The first fragment contains the SNAP header and the
121remaining packets are just data.
122
123If encryption is enabled, each fragment payload size is reduced by enough space
124to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
125So if you have 1500 bytes of payload with ieee->fts set to 500 without
126encryption it will take 3 frames.  With WEP it will take 4 frames as the
127payload of each frame is reduced to 492 bytes.
128
129* SKB visualization
130*
131*  ,- skb->data
132* |
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)
149*
150*      SNAP HEADER
151*
152*/
153
154static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
155static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
156
157static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
158{
159	struct ieee80211_snap_hdr *snap;
160	u8 *oui;
161
162	snap = (struct ieee80211_snap_hdr *)data;
163	snap->dsap = 0xaa;
164	snap->ssap = 0xaa;
165	snap->ctrl = 0x03;
166
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];
174
175	*(u16 *)(data + SNAP_SIZE) = htons(h_proto);
176
177	return SNAP_SIZE + sizeof(u16);
178}
179
180int ieee80211_encrypt_fragment(
181	struct ieee80211_device *ieee,
182	struct sk_buff *frag,
183	int hdr_len)
184{
185	struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
186	int res;
187
188	if (!(crypt && crypt->ops))
189	{
190		printk("=========>%s(), crypt is null\n", __FUNCTION__);
191		return -1;
192	}
193#ifdef CONFIG_IEEE80211_CRYPT_TKIP
194	struct rtl_ieee80211_hdr *header;
195
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);
203		}
204		return -1;
205	}
206#endif
207	/* To encrypt, frame format is:
208	 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
209
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);
218
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;
225	}
226
227	return 0;
228}
229
230
231void ieee80211_txb_free(struct ieee80211_txb *txb) {
232	if (unlikely(!txb))
233		return;
234	kfree(txb);
235}
236
237struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
238					  int gfp_mask)
239{
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;
247
248	memset(txb, 0, sizeof(struct ieee80211_txb));
249	txb->nr_frags = nr_frags;
250	txb->frag_size = txb_size;
251
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;
257		}
258		memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
259	}
260	if (unlikely(i != nr_frags)) {
261		while (i >= 0)
262			dev_kfree_skb_any(txb->fragments[i--]);
263		kfree(txb);
264		return NULL;
265	}
266	return txb;
267}
268
269// Classify the to-be send data packet
270// Need to acquire the sent queue index.
271static int
272ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
273{
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;
279
280	ip = ip_hdr(skb);
281
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;
299	}
300}
301
302void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
303{
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;
307
308	if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
309		return;
310	if (!IsQoSDataFrame(skb->data))
311		return;
312
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
323
324	if(pHTInfo->IOTAction & HT_IOT_ACT_TX_NO_AGGREGATION)
325		return;
326
327	if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
328	{
329		return;
330	}
331	if(pHTInfo->bCurrentAMPDUEnable)
332	{
333		if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
334		{
335			printk("===>can't get TS\n");
336			return;
337		}
338		if (pTxTs->TxAdmittedBARecord.bValid == false)
339		{
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))
342			;
343			else
344			TsStartAddBaProcess(ieee, pTxTs);
345			goto FORCED_AGG_SETTING;
346		}
347		else if (pTxTs->bUsingBa == false)
348		{
349			if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
350				pTxTs->bUsingBa = true;
351			else
352				goto FORCED_AGG_SETTING;
353		}
354
355		if (ieee->iw_mode == IW_MODE_INFRA)
356		{
357			tcb_desc->bAMPDUEnable = true;
358			tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
359			tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
360		}
361	}
362FORCED_AGG_SETTING:
363	switch(pHTInfo->ForcedAMPDUMode )
364	{
365		case HT_AGG_AUTO:
366			break;
367
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;
373
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;
379
380	}
381		return;
382}
383
384extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
385{
386	tcb_desc->bUseShortPreamble = false;
387	if (tcb_desc->data_rate == 2)
388	{//// 1M can only use Long Preamble. 11B spec
389		return;
390	}
391	else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
392	{
393		tcb_desc->bUseShortPreamble = true;
394	}
395	return;
396}
397extern	void
398ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
399{
400	PRT_HIGH_THROUGHPUT		pHTInfo = ieee->pHTInfo;
401
402	tcb_desc->bUseShortGI 		= false;
403
404	if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
405		return;
406
407	if(pHTInfo->bForcedShortGI)
408	{
409		tcb_desc->bUseShortGI = true;
410		return;
411	}
412
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;
417}
418
419void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
420{
421	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
422
423	tcb_desc->bPacketBW = false;
424
425	if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
426		return;
427
428	if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
429		return;
430
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;
437}
438
439void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
440{
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
447
448	if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
449		return;
450
451	if (is_broadcast_ether_addr(skb->data+16))  //check addr3 as infrastructure add3 is DA.
452		return;
453
454	if (ieee->mode < IEEE_N_24G) //b, g mode
455	{
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)
461		{
462			tcb_desc->bRTSEnable = true;
463			tcb_desc->rts_rate = MGN_24M;
464		}
465		else if (ieee->current_network.buseprotection)
466		{
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;
471		}
472		//otherwise return;
473		return;
474	}
475	else
476	{// 11n High throughput case.
477		PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
478		while (true)
479		{
480			//check IOT action
481			if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
482			{
483				tcb_desc->bCTSEnable	= true;
484				tcb_desc->rts_rate  = 	MGN_24M;
485				tcb_desc->bRTSEnable = false;
486				break;
487			}
488			else if(pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_PURE_N_MODE))
489			{
490				tcb_desc->bRTSEnable = true;
491				tcb_desc->rts_rate  = 	MGN_24M;
492				break;
493			}
494			//check ERP protection
495			if (ieee->current_network.buseprotection)
496			{// CTS-to-SELF
497				tcb_desc->bRTSEnable = true;
498				tcb_desc->bCTSEnable = true;
499				tcb_desc->rts_rate = MGN_24M;
500				break;
501			}
502			//check HT op mode
503			if(pHTInfo->bCurrentHTSupport  && pHTInfo->bEnableHT)
504			{
505				u8 HTOpMode = pHTInfo->CurrentOpMode;
506				if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
507							(!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
508				{
509					tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
510					tcb_desc->bRTSEnable = true;
511					break;
512				}
513			}
514			//check rts
515			if (skb->len > ieee->rts)
516			{
517				tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
518				tcb_desc->bRTSEnable = true;
519				break;
520			}
521			//to do list: check MIMO power save condition.
522			//check AMPDU aggregation for TXOP
523			if(tcb_desc->bAMPDUEnable)
524			{
525				tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
526				// According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
527				// throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
528				tcb_desc->bRTSEnable = false;
529				break;
530			}
531			// Totally no protection case!!
532			goto NO_PROTECTION;
533		}
534		}
535	// For test , CTS replace with RTS
536	if( 0 )
537	{
538		tcb_desc->bCTSEnable	= true;
539		tcb_desc->rts_rate = MGN_24M;
540		tcb_desc->bRTSEnable 	= true;
541	}
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;
547NO_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;
553}
554
555
556void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
557{
558#ifdef TO_DO_LIST
559	if(!IsDataFrame(pFrame))
560	{
561		pTcb->bTxDisableRateFallBack = TRUE;
562		pTcb->bTxUseDriverAssingedRate = TRUE;
563		pTcb->RATRIndex = 7;
564		return;
565	}
566
567	if(pMgntInfo->ForcedDataRate!= 0)
568	{
569		pTcb->bTxDisableRateFallBack = TRUE;
570		pTcb->bTxUseDriverAssingedRate = TRUE;
571		return;
572	}
573#endif
574	if(ieee->bTxDisableRateFallBack)
575		tcb_desc->bTxDisableRateFallBack = true;
576
577	if(ieee->bTxUseDriverAssingedRate)
578		tcb_desc->bTxUseDriverAssingedRate = true;
579	if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
580	{
581		if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
582			tcb_desc->RATRIndex = 0;
583	}
584}
585
586void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst)
587{
588	if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
589		return;
590	if (IsQoSDataFrame(skb->data)) //we deal qos data only
591	{
592		PTX_TS_RECORD pTS = NULL;
593		if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true))
594		{
595			return;
596		}
597		pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
598	}
599}
600
601int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
602{
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
616	};
617	u8 dest[ETH_ALEN], src[ETH_ALEN];
618	int qos_actived = ieee->current_network.qos_data.active;
619
620	struct ieee80211_crypt_data* crypt;
621
622	cb_desc *tcb_desc;
623
624	spin_lock_irqsave(&ieee->lock, flags);
625
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;
633	}
634
635
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;
641		}
642
643		memset(skb->cb, 0, sizeof(skb->cb));
644		ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
645
646		crypt = ieee->crypt[ieee->tx_keyidx];
647
648		encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
649			ieee->host_encrypt && crypt && crypt->ops;
650
651		if (!encrypt && ieee->ieee802_1x &&
652		ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
653			stats->tx_dropped++;
654			goto success;
655		}
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));
662		}
663	#endif
664
665		/* Save source and destination addresses */
666		memcpy(&dest, skb->data, ETH_ALEN);
667		memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
668
669                /* Advance the SKB to the start of the payload */
670                skb_pull(skb, sizeof(struct ethhdr));
671
672                /* Determine total amount of storage required for TXB packets */
673                bytes = skb->len + SNAP_SIZE + sizeof(u16);
674
675		if (encrypt)
676			fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
677		else
678                        fc = IEEE80211_FTYPE_DATA;
679
680		if(qos_actived)
681			fc |= IEEE80211_STYPE_QOS_DATA;
682		else
683			fc |= IEEE80211_STYPE_DATA;
684
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);
698		}
699
700                header.frame_ctl = cpu_to_le16(fc);
701
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;
708		}
709		else {
710			frag_size = ieee->fts;//default:392
711			qos_ctl = 0;
712		}
713
714		//if (ieee->current_network.QoS_Enable)
715		if(qos_actived)
716		{
717			hdr_len = IEEE80211_3ADDR_LEN + 2;
718
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;
724		}
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;
733
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;
738
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;
747
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;
756		}
757		txb->encrypted = encrypt;
758		txb->payload_size = bytes;
759
760		if(qos_actived)
761		{
762			txb->queue_index = UP2AC(skb->priority);
763		} else {
764			txb->queue_index = WME_AC_BK;;
765		}
766
767
768
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;
778			}
779			skb_reserve(skb_frag, ieee->tx_headroom);
780
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);
787			}
788			else
789			{
790				tcb_desc->bHwSec = 0;
791			}
792			frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
793			memcpy(frag_hdr, &header, hdr_len);
794
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;
801
802			} else {
803				/* The last fragment takes the remaining length */
804				bytes = bytes_last_frag;
805			}
806			if(qos_actived)
807			{
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);
812			}
813
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);
820			}
821
822			memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
823
824			/* Advance the SKB... */
825			skb_pull(skb, bytes);
826
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);
834		}
835
836		if(qos_actived)
837		{
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]++;
847		}
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;
853		}
854
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;
860		}
861
862		txb->encrypted = 0;
863		txb->payload_size = skb->len;
864		memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
865	}
866
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)
870	{
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);
888	}
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;
899			}
900			ieee80211_txb_free(txb);
901		}
902	}
903
904	return 0;
905
906 failed:
907	spin_unlock_irqrestore(&ieee->lock, flags);
908	netif_stop_queue(dev);
909	stats->tx_errors++;
910	return 1;
911
912}
913