]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
Staging: rtl8187su: remove unused #include <linux/version.h>
[net-next-2.6.git] / drivers / staging / rtl8192su / ieee80211 / ieee80211_tx.c
CommitLineData
5f53d8ca
JC
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>
5f53d8ca
JC
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
b4fcc8a2 195 struct rtl_ieee80211_hdr *header;
5f53d8ca
JC
196
197 if (ieee->tkip_countermeasures &&
198 crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
b4fcc8a2 199 header = (struct rtl_ieee80211_hdr *)frag->data;
5f53d8ca
JC
200 if (net_ratelimit()) {
201 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
202 "TX packet to " MAC_FMT "\n",
203 ieee->dev->name, MAC_ARG(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 // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
212 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
213 * call both MSDU and MPDU encryption functions from here. */
214 atomic_inc(&crypt->refcnt);
215 res = 0;
216 if (crypt->ops->encrypt_msdu)
217 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
218 if (res == 0 && crypt->ops->encrypt_mpdu)
219 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
220
221 atomic_dec(&crypt->refcnt);
222 if (res < 0) {
223 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
224 ieee->dev->name, frag->len);
225 ieee->ieee_stats.tx_discards++;
226 return -1;
227 }
228
229 return 0;
230}
231
232
233void ieee80211_txb_free(struct ieee80211_txb *txb) {
234 //int i;
235 if (unlikely(!txb))
236 return;
5f53d8ca
JC
237 kfree(txb);
238}
239
240struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
241 int gfp_mask)
242{
243 struct ieee80211_txb *txb;
244 int i;
245 txb = kmalloc(
246 sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
247 gfp_mask);
248 if (!txb)
249 return NULL;
250
251 memset(txb, 0, sizeof(struct ieee80211_txb));
252 txb->nr_frags = nr_frags;
253 txb->frag_size = txb_size;
254
255 for (i = 0; i < nr_frags; i++) {
256 txb->fragments[i] = dev_alloc_skb(txb_size);
257 if (unlikely(!txb->fragments[i])) {
258 i--;
259 break;
260 }
261 memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
262 }
263 if (unlikely(i != nr_frags)) {
264 while (i >= 0)
265 dev_kfree_skb_any(txb->fragments[i--]);
266 kfree(txb);
267 return NULL;
268 }
269 return txb;
270}
271
272// Classify the to-be send data packet
273// Need to acquire the sent queue index.
274static int
275ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
276{
277 struct ethhdr *eth;
278 struct iphdr *ip;
279 eth = (struct ethhdr *)skb->data;
280 if (eth->h_proto != htons(ETH_P_IP))
281 return 0;
282
283// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
5f53d8ca 284 ip = ip_hdr(skb);
1ec9e48d 285
5f53d8ca
JC
286 switch (ip->tos & 0xfc) {
287 case 0x20:
288 return 2;
289 case 0x40:
290 return 1;
291 case 0x60:
292 return 3;
293 case 0x80:
294 return 4;
295 case 0xa0:
296 return 5;
297 case 0xc0:
298 return 6;
299 case 0xe0:
300 return 7;
301 default:
302 return 0;
303 }
304}
305
5f53d8ca
JC
306void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
307{
308 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
309 PTX_TS_RECORD pTxTs = NULL;
310 struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data;
311
312 if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
313 return;
314 if (!IsQoSDataFrame(skb->data))
315 return;
316
317 if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1))
318 return;
319 //check packet and mode later
320#ifdef TO_DO_LIST
321 if(pTcb->PacketLength >= 4096)
322 return;
323 // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
324 if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
325 return;
326#endif
327
328 if(pHTInfo->IOTAction & HT_IOT_ACT_TX_NO_AGGREGATION)
329 return;
330
331#if 1
332 if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
333 {
334 return;
335 }
336#endif
337 if(pHTInfo->bCurrentAMPDUEnable)
338 {
339 if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
340 {
341 printk("===>can't get TS\n");
342 return;
343 }
344 if (pTxTs->TxAdmittedBARecord.bValid == false)
345 {
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))
348 ;
349 else
350 TsStartAddBaProcess(ieee, pTxTs);
351 goto FORCED_AGG_SETTING;
352 }
353 else if (pTxTs->bUsingBa == false)
354 {
355 if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
356 pTxTs->bUsingBa = true;
357 else
358 goto FORCED_AGG_SETTING;
359 }
360
361 if (ieee->iw_mode == IW_MODE_INFRA)
362 {
363 tcb_desc->bAMPDUEnable = true;
364 tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
365 tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
366 }
367 }
368FORCED_AGG_SETTING:
369 switch(pHTInfo->ForcedAMPDUMode )
370 {
371 case HT_AGG_AUTO:
372 break;
373
374 case HT_AGG_FORCE_ENABLE:
375 tcb_desc->bAMPDUEnable = true;
376 tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
377 tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
378 break;
379
380 case HT_AGG_FORCE_DISABLE:
381 tcb_desc->bAMPDUEnable = false;
382 tcb_desc->ampdu_density = 0;
383 tcb_desc->ampdu_factor = 0;
384 break;
385
386 }
387 return;
388}
389
390extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
391{
392 tcb_desc->bUseShortPreamble = false;
393 if (tcb_desc->data_rate == 2)
394 {//// 1M can only use Long Preamble. 11B spec
395 return;
396 }
397 else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
398 {
399 tcb_desc->bUseShortPreamble = true;
400 }
401 return;
402}
403extern void
404ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
405{
406 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
407
408 tcb_desc->bUseShortGI = false;
409
410 if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
411 return;
412
413 if(pHTInfo->bForcedShortGI)
414 {
415 tcb_desc->bUseShortGI = true;
416 return;
417 }
418
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;
423}
424
425void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
426{
427 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
428
429 tcb_desc->bPacketBW = false;
430
431 if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
432 return;
433
434 if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
435 return;
436
437 if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
438 return;
439 //BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
440 if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
441 tcb_desc->bPacketBW = true;
442 return;
443}
444
445void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
446{
447 // Common Settings
448 tcb_desc->bRTSSTBC = false;
449 tcb_desc->bRTSUseShortGI = false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
450 tcb_desc->bCTSEnable = false; // Most of protection using RTS/CTS
451 tcb_desc->RTSSC = 0; // 20MHz: Don't care; 40MHz: Duplicate.
452 tcb_desc->bRTSBW = false; // RTS frame bandwidth is always 20MHz
453
454 if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
455 return;
456
457 if (is_broadcast_ether_addr(skb->data+16)) //check addr3 as infrastructure add3 is DA.
458 return;
459
460 if (ieee->mode < IEEE_N_24G) //b, g mode
461 {
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)
467 {
468 tcb_desc->bRTSEnable = true;
469 tcb_desc->rts_rate = MGN_24M;
470 }
471 else if (ieee->current_network.buseprotection)
472 {
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;
477 }
478 //otherwise return;
479 return;
480 }
481 else
482 {// 11n High throughput case.
483 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
484 while (true)
485 {
486 //check IOT action
487 if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
488 {
489 tcb_desc->bCTSEnable = true;
490 tcb_desc->rts_rate = MGN_24M;
5f53d8ca 491 tcb_desc->bRTSEnable = false;
5f53d8ca
JC
492 break;
493 }
494 else if(pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_PURE_N_MODE))
495 {
496 tcb_desc->bRTSEnable = true;
497 tcb_desc->rts_rate = MGN_24M;
498 break;
499 }
500 //check ERP protection
501 if (ieee->current_network.buseprotection)
502 {// CTS-to-SELF
503 tcb_desc->bRTSEnable = true;
504 tcb_desc->bCTSEnable = true;
505 tcb_desc->rts_rate = MGN_24M;
506 break;
507 }
508 //check HT op mode
509 if(pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT)
510 {
511 u8 HTOpMode = pHTInfo->CurrentOpMode;
512 if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
513 (!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
514 {
515 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
516 tcb_desc->bRTSEnable = true;
517 break;
518 }
519 }
520 //check rts
521 if (skb->len > ieee->rts)
522 {
523 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
524 tcb_desc->bRTSEnable = true;
525 break;
526 }
527 //to do list: check MIMO power save condition.
528 //check AMPDU aggregation for TXOP
529 if(tcb_desc->bAMPDUEnable)
530 {
531 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
532 // According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
533 // throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
534 tcb_desc->bRTSEnable = false;
535 break;
536 }
537 // Totally no protection case!!
538 goto NO_PROTECTION;
539 }
540 }
541 // For test , CTS replace with RTS
542 if( 0 )
543 {
544 tcb_desc->bCTSEnable = true;
545 tcb_desc->rts_rate = MGN_24M;
546 tcb_desc->bRTSEnable = true;
547 }
548 if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
549 tcb_desc->bUseShortPreamble = true;
550 if (ieee->mode == IW_MODE_MASTER)
551 goto NO_PROTECTION;
552 return;
553NO_PROTECTION:
554 tcb_desc->bRTSEnable = false;
555 tcb_desc->bCTSEnable = false;
556 tcb_desc->rts_rate = 0;
557 tcb_desc->RTSSC = 0;
558 tcb_desc->bRTSBW = false;
559}
560
561
562void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
563{
564#ifdef TO_DO_LIST
565 if(!IsDataFrame(pFrame))
566 {
567 pTcb->bTxDisableRateFallBack = TRUE;
568 pTcb->bTxUseDriverAssingedRate = TRUE;
569 pTcb->RATRIndex = 7;
570 return;
571 }
572
573 if(pMgntInfo->ForcedDataRate!= 0)
574 {
575 pTcb->bTxDisableRateFallBack = TRUE;
576 pTcb->bTxUseDriverAssingedRate = TRUE;
577 return;
578 }
579#endif
580 if(ieee->bTxDisableRateFallBack)
581 tcb_desc->bTxDisableRateFallBack = true;
582
583 if(ieee->bTxUseDriverAssingedRate)
584 tcb_desc->bTxUseDriverAssingedRate = true;
585 if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
586 {
587 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
588 tcb_desc->RATRIndex = 0;
589 }
590}
591
592void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst)
593{
594 if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
595 return;
596 if (IsQoSDataFrame(skb->data)) //we deal qos data only
597 {
598 PTX_TS_RECORD pTS = NULL;
599 if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true))
600 {
601 return;
602 }
603 pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
604 }
605}
606
ce9c010c 607int rtl8192_ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
5f53d8ca 608{
5f53d8ca 609 struct ieee80211_device *ieee = netdev_priv(dev);
5f53d8ca
JC
610 struct ieee80211_txb *txb = NULL;
611 struct ieee80211_hdr_3addrqos *frag_hdr;
612 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
613 unsigned long flags;
614 struct net_device_stats *stats = &ieee->stats;
615 int ether_type = 0, encrypt;
616 int bytes, fc, qos_ctl = 0, hdr_len;
617 struct sk_buff *skb_frag;
618 struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
619 .duration_id = 0,
620 .seq_ctl = 0,
621 .qos_ctl = 0
622 };
623 u8 dest[ETH_ALEN], src[ETH_ALEN];
624 int qos_actived = ieee->current_network.qos_data.active;
625
626 struct ieee80211_crypt_data* crypt;
627
628 cb_desc *tcb_desc;
629
630 spin_lock_irqsave(&ieee->lock, flags);
631
632 /* If there is no driver handler to take the TXB, dont' bother
633 * creating it... */
634 if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
635 ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
636 printk(KERN_WARNING "%s: No xmit handler.\n",
637 ieee->dev->name);
638 goto success;
639 }
640
641
642 if(likely(ieee->raw_tx == 0)){
643 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
644 printk(KERN_WARNING "%s: skb too small (%d).\n",
645 ieee->dev->name, skb->len);
646 goto success;
647 }
648
649 memset(skb->cb, 0, sizeof(skb->cb));
650 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
651
652 crypt = ieee->crypt[ieee->tx_keyidx];
653
654 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
655 ieee->host_encrypt && crypt && crypt->ops;
656
657 if (!encrypt && ieee->ieee802_1x &&
658 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
659 stats->tx_dropped++;
660 goto success;
661 }
662 #ifdef CONFIG_IEEE80211_DEBUG
663 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
664 struct eapol *eap = (struct eapol *)(skb->data +
665 sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
666 IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
667 eap_get_type(eap->type));
668 }
669 #endif
670
671 /* Save source and destination addresses */
672 memcpy(&dest, skb->data, ETH_ALEN);
673 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
674
675 /* Advance the SKB to the start of the payload */
676 skb_pull(skb, sizeof(struct ethhdr));
677
678 /* Determine total amount of storage required for TXB packets */
679 bytes = skb->len + SNAP_SIZE + sizeof(u16);
680
681 if (encrypt)
682 fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
683 else
684
685 fc = IEEE80211_FTYPE_DATA;
686
687 //if(ieee->current_network.QoS_Enable)
688 if(qos_actived)
689 fc |= IEEE80211_STYPE_QOS_DATA;
690 else
691 fc |= IEEE80211_STYPE_DATA;
692
693 if (ieee->iw_mode == IW_MODE_INFRA) {
694 fc |= IEEE80211_FCTL_TODS;
695 /* To DS: Addr1 = BSSID, Addr2 = SA,
696 Addr3 = DA */
697 memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
698 memcpy(&header.addr2, &src, ETH_ALEN);
699 memcpy(&header.addr3, &dest, ETH_ALEN);
700 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
701 /* not From/To DS: Addr1 = DA, Addr2 = SA,
702 Addr3 = BSSID */
703 memcpy(&header.addr1, dest, ETH_ALEN);
704 memcpy(&header.addr2, src, ETH_ALEN);
705 memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
706 }
707
708 header.frame_ctl = cpu_to_le16(fc);
709
710 /* Determine fragmentation size based on destination (multicast
711 * and broadcast are not fragmented) */
712 if (is_multicast_ether_addr(header.addr1) ||
713 is_broadcast_ether_addr(header.addr1)) {
714 frag_size = MAX_FRAG_THRESHOLD;
715 qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
716 }
717 else {
718 frag_size = ieee->fts;//default:392
719 qos_ctl = 0;
720 }
721
722 //if (ieee->current_network.QoS_Enable)
723 if(qos_actived)
724 {
725 hdr_len = IEEE80211_3ADDR_LEN + 2;
726
727 skb->priority = ieee80211_classify(skb, &ieee->current_network);
728 qos_ctl |= skb->priority; //set in the ieee80211_classify
729 header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
730 } else {
731 hdr_len = IEEE80211_3ADDR_LEN;
732 }
733 /* Determine amount of payload per fragment. Regardless of if
734 * this stack is providing the full 802.11 header, one will
735 * eventually be affixed to this fragment -- so we must account for
736 * it when determining the amount of payload space. */
737 bytes_per_frag = frag_size - hdr_len;
738 if (ieee->config &
739 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
740 bytes_per_frag -= IEEE80211_FCS_LEN;
741
742 /* Each fragment may need to have room for encryptiong pre/postfix */
743 if (encrypt)
744 bytes_per_frag -= crypt->ops->extra_prefix_len +
745 crypt->ops->extra_postfix_len;
746
747 /* Number of fragments is the total bytes_per_frag /
748 * payload_per_fragment */
749 nr_frags = bytes / bytes_per_frag;
750 bytes_last_frag = bytes % bytes_per_frag;
751 if (bytes_last_frag)
752 nr_frags++;
753 else
754 bytes_last_frag = bytes_per_frag;
755
756 /* When we allocate the TXB we allocate enough space for the reserve
757 * and full fragment bytes (bytes_per_frag doesn't include prefix,
758 * postfix, header, FCS, etc.) */
759 txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
760 if (unlikely(!txb)) {
761 printk(KERN_WARNING "%s: Could not allocate TXB\n",
762 ieee->dev->name);
763 goto failed;
764 }
765 txb->encrypted = encrypt;
766 txb->payload_size = bytes;
767
768 //if (ieee->current_network.QoS_Enable)
769 if(qos_actived)
770 {
771 txb->queue_index = UP2AC(skb->priority);
772 } else {
773 txb->queue_index = WME_AC_BK;;
774 }
775
776
777
778 for (i = 0; i < nr_frags; i++) {
779 skb_frag = txb->fragments[i];
780 tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
781 if(qos_actived){
782 skb_frag->priority = skb->priority;//UP2AC(skb->priority);
783 tcb_desc->queue_index = UP2AC(skb->priority);
784 } else {
785 skb_frag->priority = WME_AC_BK;
786 tcb_desc->queue_index = WME_AC_BK;
787 }
788 skb_reserve(skb_frag, ieee->tx_headroom);
789
790 if (encrypt){
791 if (ieee->hwsec_active)
792 tcb_desc->bHwSec = 1;
793 else
794 tcb_desc->bHwSec = 0;
795 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
796 }
797 else
798 {
799 tcb_desc->bHwSec = 0;
800 }
801 frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
802 memcpy(frag_hdr, &header, hdr_len);
803
804 /* If this is not the last fragment, then add the MOREFRAGS
805 * bit to the frame control */
806 if (i != nr_frags - 1) {
807 frag_hdr->frame_ctl = cpu_to_le16(
808 fc | IEEE80211_FCTL_MOREFRAGS);
809 bytes = bytes_per_frag;
810
811 } else {
812 /* The last fragment takes the remaining length */
813 bytes = bytes_last_frag;
814 }
815 //if(ieee->current_network.QoS_Enable)
816 if(qos_actived)
817 {
818 // add 1 only indicate to corresponding seq number control 2006/7/12
819 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
820 } else {
821 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
822 }
823
824 /* Put a SNAP header on the first fragment */
825 if (i == 0) {
826 ieee80211_put_snap(
827 skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
828 ether_type);
829 bytes -= SNAP_SIZE + sizeof(u16);
830 }
831
832 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
833
834 /* Advance the SKB... */
835 skb_pull(skb, bytes);
836
837 /* Encryption routine will move the header forward in order
838 * to insert the IV between the header and the payload */
839 if (encrypt)
840 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
841 if (ieee->config &
842 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
843 skb_put(skb_frag, 4);
844 }
845
846 if(qos_actived)
847 {
848 if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
849 ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
850 else
851 ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
852 } else {
853 if (ieee->seq_ctrl[0] == 0xFFF)
854 ieee->seq_ctrl[0] = 0;
855 else
856 ieee->seq_ctrl[0]++;
857 }
858 }else{
859 if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
860 printk(KERN_WARNING "%s: skb too small (%d).\n",
861 ieee->dev->name, skb->len);
862 goto success;
863 }
864
865 txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
866 if(!txb){
867 printk(KERN_WARNING "%s: Could not allocate TXB\n",
868 ieee->dev->name);
869 goto failed;
870 }
871
872 txb->encrypted = 0;
873 txb->payload_size = skb->len;
874 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
875 }
876
877 success:
878//WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
879 if (txb)
880 {
881#if 1
882 cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
883 tcb_desc->bTxEnableFwCalcDur = 1;
884 if (is_multicast_ether_addr(header.addr1))
885 tcb_desc->bMulticast = 1;
886 if (is_broadcast_ether_addr(header.addr1))
887 tcb_desc->bBroadcast = 1;
888 ieee80211_txrate_selectmode(ieee, tcb_desc);
889 if ( tcb_desc->bMulticast || tcb_desc->bBroadcast)
890 tcb_desc->data_rate = ieee->basic_rate;
891 else
892 //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
893 tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
894 ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
895 ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
896 ieee80211_query_HTCapShortGI(ieee, tcb_desc);
897 ieee80211_query_BandwidthMode(ieee, tcb_desc);
898 ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
899 ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
900// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len);
901 //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc));
902#endif
903 }
904 spin_unlock_irqrestore(&ieee->lock, flags);
905 dev_kfree_skb_any(skb);
906 if (txb) {
907 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
908 ieee80211_softmac_xmit(txb, ieee);
909 }else{
910 if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
911 stats->tx_packets++;
912 stats->tx_bytes += txb->payload_size;
913 return 0;
914 }
915 ieee80211_txb_free(txb);
916 }
917 }
918
919 return 0;
920
921 failed:
922 spin_unlock_irqrestore(&ieee->lock, flags);
923 netif_stop_queue(dev);
924 stats->tx_errors++;
925 return 1;
926
927}