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