blob: 7ccad8601821a241f60b7492342d870758270b7e [file] [log] [blame]
Larry Finger94a79942011-08-23 19:00:42 -05001/******************************************************************************
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/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 "rtllib.h"
56
Larry Finger94a79942011-08-23 19:00:42 -050057/*
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
157inline int rtllib_put_snap(u8 *data, u16 h_proto)
158{
159 struct rtllib_snap_hdr *snap;
160 u8 *oui;
161
162 snap = (struct rtllib_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 rtllib_encrypt_fragment(
181 struct rtllib_device *ieee,
182 struct sk_buff *frag,
183 int hdr_len)
184{
185 struct rtllib_crypt_data* crypt = NULL;
186 int res;
187
188 crypt = ieee->crypt[ieee->tx_keyidx];
189
190 if (!(crypt && crypt->ops))
191 {
192 printk("=========>%s(), crypt is null\n", __func__);
193 return -1;
194 }
Larry Finger94a79942011-08-23 19:00:42 -0500195 /* To encrypt, frame format is:
196 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
197
198 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
199 * call both MSDU and MPDU encryption functions from here. */
200 atomic_inc(&crypt->refcnt);
201 res = 0;
202 if (crypt->ops->encrypt_msdu)
203 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
204 if (res == 0 && crypt->ops->encrypt_mpdu)
205 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
206
207 atomic_dec(&crypt->refcnt);
208 if (res < 0) {
209 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
210 ieee->dev->name, frag->len);
211 ieee->ieee_stats.tx_discards++;
212 return -1;
213 }
214
215 return 0;
216}
217
218
219void rtllib_txb_free(struct rtllib_txb *txb) {
220 if (unlikely(!txb))
221 return;
222 kfree(txb);
223}
224
225struct rtllib_txb *rtllib_alloc_txb(int nr_frags, int txb_size,
226 int gfp_mask)
227{
Larry Finger94a79942011-08-23 19:00:42 -0500228 struct rtllib_txb *txb;
229 int i;
230 txb = kmalloc(
231 sizeof(struct rtllib_txb) + (sizeof(u8*) * nr_frags),
232 gfp_mask);
233 if (!txb)
234 return NULL;
235
236 memset(txb, 0, sizeof(struct rtllib_txb));
237 txb->nr_frags = nr_frags;
238 txb->frag_size = txb_size;
239
240 for (i = 0; i < nr_frags; i++) {
Larry Finger94a79942011-08-23 19:00:42 -0500241 txb->fragments[i] = dev_alloc_skb(txb_size);
Larry Finger94a79942011-08-23 19:00:42 -0500242 if (unlikely(!txb->fragments[i])) {
243 i--;
244 break;
245 }
Larry Finger94a79942011-08-23 19:00:42 -0500246 memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
247 }
248 if (unlikely(i != nr_frags)) {
249 while (i >= 0)
250 dev_kfree_skb_any(txb->fragments[i--]);
251 kfree(txb);
252 return NULL;
253 }
254 return txb;
255}
256
257int
258rtllib_classify(struct sk_buff *skb, u8 bIsAmsdu)
259{
260 struct ethhdr *eth;
261 struct iphdr *ip;
262
263 eth = (struct ethhdr *)skb->data;
264 if (eth->h_proto != htons(ETH_P_IP))
265 return 0;
266
267 RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA, skb->data, skb->len);
268 ip = ip_hdr(skb);
269 switch (ip->tos & 0xfc) {
270 case 0x20:
271 return 2;
272 case 0x40:
273 return 1;
274 case 0x60:
275 return 3;
276 case 0x80:
277 return 4;
278 case 0xa0:
279 return 5;
280 case 0xc0:
281 return 6;
282 case 0xe0:
283 return 7;
284 default:
285 return 0;
286 }
287}
288
289#define SN_LESS(a, b) (((a-b)&0x800)!=0)
Larry Finger3b83db42011-07-19 00:01:29 -0500290void rtllib_tx_query_agg_cap(struct rtllib_device* ieee, struct sk_buff* skb, struct cb_desc * tcb_desc)
Larry Finger94a79942011-08-23 19:00:42 -0500291{
Larry Finger7796d932011-07-18 20:22:19 -0500292 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
Larry Finger60554f22011-07-18 20:10:03 -0500293 struct tx_ts_record *pTxTs = NULL;
Larry Finger94a79942011-08-23 19:00:42 -0500294 struct rtllib_hdr_1addr* hdr = (struct rtllib_hdr_1addr*)skb->data;
295
296 if (rtllib_act_scanning(ieee,false))
297 return;
298
299 if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
300 return;
301 if (!IsQoSDataFrame(skb->data))
302 return;
303 if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1))
304 return;
Larry Finger94a79942011-08-23 19:00:42 -0500305
306 if (tcb_desc->bdhcp || ieee->CntAfterLink<2)
307 return;
308
309 if (pHTInfo->IOTAction & HT_IOT_ACT_TX_NO_AGGREGATION)
310 return;
311
312 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
313 return;
314 if (pHTInfo->bCurrentAMPDUEnable){
Larry Finger74724de2011-07-18 20:19:19 -0500315 if (!GetTs(ieee, (struct ts_common_info **)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true)){
Larry Finger94a79942011-08-23 19:00:42 -0500316 printk("%s: can't get TS\n", __func__);
317 return;
318 }
319 if (pTxTs->TxAdmittedBARecord.bValid == false){
320 if (ieee->wpa_ie_len && (ieee->pairwise_key_type == KEY_TYPE_NA)) {
321 ;
322 } else if (tcb_desc->bdhcp == 1){
323 ;
324 } else if (!pTxTs->bDisable_AddBa){
325 TsStartAddBaProcess(ieee, pTxTs);
326 }
327 goto FORCED_AGG_SETTING;
328 } else if (pTxTs->bUsingBa == false) {
329 if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
330 pTxTs->bUsingBa = true;
331 else
332 goto FORCED_AGG_SETTING;
333 }
334 if (ieee->iw_mode == IW_MODE_INFRA) {
335 tcb_desc->bAMPDUEnable = true;
336 tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
337 tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
338 }
339 }
340FORCED_AGG_SETTING:
341 switch (pHTInfo->ForcedAMPDUMode) {
342 case HT_AGG_AUTO:
343 break;
344
345 case HT_AGG_FORCE_ENABLE:
346 tcb_desc->bAMPDUEnable = true;
347 tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
348 tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
349 break;
350
351 case HT_AGG_FORCE_DISABLE:
352 tcb_desc->bAMPDUEnable = false;
353 tcb_desc->ampdu_density = 0;
354 tcb_desc->ampdu_factor = 0;
355 break;
356
357 }
358 return;
359}
360
Larry Finger3b83db42011-07-19 00:01:29 -0500361extern void rtllib_qurey_ShortPreambleMode(struct rtllib_device* ieee, struct cb_desc * tcb_desc)
Larry Finger94a79942011-08-23 19:00:42 -0500362{
363 tcb_desc->bUseShortPreamble = false;
364 if (tcb_desc->data_rate == 2)
365 {
366 return;
367 }
368 else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
369 {
370 tcb_desc->bUseShortPreamble = true;
371 }
372 return;
373}
374
375extern void
Larry Finger3b83db42011-07-19 00:01:29 -0500376rtllib_query_HTCapShortGI(struct rtllib_device *ieee, struct cb_desc *tcb_desc)
Larry Finger94a79942011-08-23 19:00:42 -0500377{
Larry Finger7796d932011-07-18 20:22:19 -0500378 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
Larry Finger94a79942011-08-23 19:00:42 -0500379
380 tcb_desc->bUseShortGI = false;
381
382 if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
383 return;
384
385 if (pHTInfo->bForcedShortGI)
386 {
387 tcb_desc->bUseShortGI = true;
388 return;
389 }
390
391 if ((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz)
392 tcb_desc->bUseShortGI = true;
393 else if ((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz)
394 tcb_desc->bUseShortGI = true;
395}
396
Larry Finger3b83db42011-07-19 00:01:29 -0500397void rtllib_query_BandwidthMode(struct rtllib_device* ieee, struct cb_desc *tcb_desc)
Larry Finger94a79942011-08-23 19:00:42 -0500398{
Larry Finger7796d932011-07-18 20:22:19 -0500399 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
Larry Finger94a79942011-08-23 19:00:42 -0500400
401 tcb_desc->bPacketBW = false;
402
403 if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
404 return;
405
406 if (tcb_desc->bMulticast || tcb_desc->bBroadcast)
407 return;
408
409 if ((tcb_desc->data_rate & 0x80)==0)
410 return;
411 if (pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
412 tcb_desc->bPacketBW = true;
413 return;
414}
Larry Finger94a79942011-08-23 19:00:42 -0500415
Larry Finger3b83db42011-07-19 00:01:29 -0500416void rtllib_query_protectionmode(struct rtllib_device* ieee, struct cb_desc * tcb_desc, struct sk_buff* skb)
Larry Finger94a79942011-08-23 19:00:42 -0500417{
418 tcb_desc->bRTSSTBC = false;
419 tcb_desc->bRTSUseShortGI = false;
420 tcb_desc->bCTSEnable = false;
421 tcb_desc->RTSSC = 0;
422 tcb_desc->bRTSBW = false;
423
424 if (tcb_desc->bBroadcast || tcb_desc->bMulticast)
425 return;
426
427 if (is_broadcast_ether_addr(skb->data+16))
428 return;
429
430 if (ieee->mode < IEEE_N_24G)
431 {
432 if (skb->len > ieee->rts)
433 {
434 tcb_desc->bRTSEnable = true;
435 tcb_desc->rts_rate = MGN_24M;
436 }
437 else if (ieee->current_network.buseprotection)
438 {
439 tcb_desc->bRTSEnable = true;
440 tcb_desc->bCTSEnable = true;
441 tcb_desc->rts_rate = MGN_24M;
442 }
443 return;
444 }
445 else
446 {
Larry Finger7796d932011-07-18 20:22:19 -0500447 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
Larry Finger94a79942011-08-23 19:00:42 -0500448 while (true)
449 {
450 if (pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
451 {
452 tcb_desc->bCTSEnable = true;
453 tcb_desc->rts_rate = MGN_24M;
454 tcb_desc->bRTSEnable = true;
455 break;
456 }
457 else if (pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_PURE_N_MODE))
458 {
459 tcb_desc->bRTSEnable = true;
460 tcb_desc->rts_rate = MGN_24M;
461 break;
462 }
463 if (ieee->current_network.buseprotection)
464 {
465 tcb_desc->bRTSEnable = true;
466 tcb_desc->bCTSEnable = true;
467 tcb_desc->rts_rate = MGN_24M;
468 break;
469 }
470 if (pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT)
471 {
472 u8 HTOpMode = pHTInfo->CurrentOpMode;
473 if ((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
474 (!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
475 {
476 tcb_desc->rts_rate = MGN_24M;
477 tcb_desc->bRTSEnable = true;
478 break;
479 }
480 }
481 if (skb->len > ieee->rts)
482 {
483 tcb_desc->rts_rate = MGN_24M;
484 tcb_desc->bRTSEnable = true;
485 break;
486 }
487 if (tcb_desc->bAMPDUEnable)
488 {
489 tcb_desc->rts_rate = MGN_24M;
490 tcb_desc->bRTSEnable = false;
491 break;
492 }
493 goto NO_PROTECTION;
494 }
495 }
496 if ( 0 )
497 {
498 tcb_desc->bCTSEnable = true;
499 tcb_desc->rts_rate = MGN_24M;
500 tcb_desc->bRTSEnable = true;
501 }
502 if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
503 tcb_desc->bUseShortPreamble = true;
504 if (ieee->iw_mode == IW_MODE_MASTER)
505 goto NO_PROTECTION;
506 return;
507NO_PROTECTION:
508 tcb_desc->bRTSEnable = false;
509 tcb_desc->bCTSEnable = false;
510 tcb_desc->rts_rate = 0;
511 tcb_desc->RTSSC = 0;
512 tcb_desc->bRTSBW = false;
513}
514
515
Larry Finger3b83db42011-07-19 00:01:29 -0500516void rtllib_txrate_selectmode(struct rtllib_device* ieee, struct cb_desc * tcb_desc)
Larry Finger94a79942011-08-23 19:00:42 -0500517{
Larry Finger94a79942011-08-23 19:00:42 -0500518 if (ieee->bTxDisableRateFallBack)
519 tcb_desc->bTxDisableRateFallBack = true;
520
521 if (ieee->bTxUseDriverAssingedRate)
522 tcb_desc->bTxUseDriverAssingedRate = true;
523 if (!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
524 {
525 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
526 tcb_desc->RATRIndex = 0;
527 }
528}
529
530u16 rtllib_query_seqnum(struct rtllib_device*ieee, struct sk_buff* skb, u8* dst)
531{
532 u16 seqnum = 0;
533
534 if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
535 return 0;
536 if (IsQoSDataFrame(skb->data))
537 {
Larry Finger60554f22011-07-18 20:10:03 -0500538 struct tx_ts_record *pTS = NULL;
Larry Finger74724de2011-07-18 20:19:19 -0500539 if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, skb->priority, TX_DIR, true))
Larry Finger94a79942011-08-23 19:00:42 -0500540 {
541 return 0;
542 }
543 seqnum = pTS->TxCurSeq;
544 pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
545 return seqnum;
546 }
547 return 0;
548}
549
550static int wme_downgrade_ac(struct sk_buff *skb)
551{
552 switch (skb->priority) {
553 case 6:
554 case 7:
555 skb->priority = 5; /* VO -> VI */
556 return 0;
557 case 4:
558 case 5:
559 skb->priority = 3; /* VI -> BE */
560 return 0;
561 case 0:
562 case 3:
563 skb->priority = 1; /* BE -> BK */
564 return 0;
565 default:
566 return -1;
567 }
568}
569
570int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
571{
572 struct rtllib_device *ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
573 struct rtllib_txb *txb = NULL;
574 struct rtllib_hdr_3addrqos *frag_hdr;
575 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
576 unsigned long flags;
577 struct net_device_stats *stats = &ieee->stats;
578 int ether_type = 0, encrypt;
579 int bytes, fc, qos_ctl = 0, hdr_len;
580 struct sk_buff *skb_frag;
581 struct rtllib_hdr_3addrqos header = { /* Ensure zero initialized */
582 .duration_id = 0,
583 .seq_ctl = 0,
584 .qos_ctl = 0
585 };
586 u8 dest[ETH_ALEN], src[ETH_ALEN];
587 int qos_actived = ieee->current_network.qos_data.active;
588 struct rtllib_crypt_data* crypt = NULL;
Larry Finger3b83db42011-07-19 00:01:29 -0500589 struct cb_desc *tcb_desc;
Larry Finger94a79942011-08-23 19:00:42 -0500590 u8 bIsMulticast = false;
591 u8 IsAmsdu = false;
592
593 bool bdhcp =false;
594 spin_lock_irqsave(&ieee->lock, flags);
595
596 /* If there is no driver handler to take the TXB, dont' bother
597 * creating it... */
598 if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
599 ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
600 printk(KERN_WARNING "%s: No xmit handler.\n",
601 ieee->dev->name);
602 goto success;
603 }
604
605
606 if (likely(ieee->raw_tx == 0)){
607 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
608 printk(KERN_WARNING "%s: skb too small (%d).\n",
609 ieee->dev->name, skb->len);
610 goto success;
611 }
612 /* Save source and destination addresses */
613 memcpy(dest, skb->data, ETH_ALEN);
614 memcpy(src, skb->data+ETH_ALEN, ETH_ALEN);
615
616 memset(skb->cb, 0, sizeof(skb->cb));
617 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
618
619 if (ieee->iw_mode == IW_MODE_MONITOR)
620 {
621 txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC);
622 if (unlikely(!txb)) {
623 printk(KERN_WARNING "%s: Could not allocate TXB\n",
624 ieee->dev->name);
625 goto failed;
626 }
627
628 txb->encrypted = 0;
629 txb->payload_size = skb->len;
630 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
631
632 goto success;
633 }
634
Larry Finger55dc4eb2011-08-25 11:48:13 -0500635 if (skb->len > 282) {
Larry Finger94a79942011-08-23 19:00:42 -0500636 if (ETH_P_IP == ether_type) {
637 const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14);
638 if (IPPROTO_UDP == ip->protocol) {
639 struct udphdr *udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
640 if (((((u8 *)udp)[1] == 68) && (((u8 *)udp)[3] == 67)) ||
641 ((((u8 *)udp)[1] == 67) && (((u8 *)udp)[3] == 68))) {
Larry Finger94a79942011-08-23 19:00:42 -0500642 bdhcp = true;
643 ieee->LPSDelayCnt = 200;
644 }
645 }
646 }else if (ETH_P_ARP == ether_type){
647 printk("=================>DHCP Protocol start tx ARP pkt!!\n");
648 bdhcp = true;
649 ieee->LPSDelayCnt = ieee->current_network.tim.tim_count;
650
651
652 }
653 }
654
655 skb->priority = rtllib_classify(skb, IsAmsdu);
656 crypt = ieee->crypt[ieee->tx_keyidx];
657 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
658 ieee->host_encrypt && crypt && crypt->ops;
659 if (!encrypt && ieee->ieee802_1x &&
660 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
661 stats->tx_dropped++;
662 goto success;
663 }
Larry Finger94a79942011-08-23 19:00:42 -0500664 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
665 struct eapol *eap = (struct eapol *)(skb->data +
666 sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
667 RTLLIB_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
668 eap_get_type(eap->type));
669 }
Larry Finger94a79942011-08-23 19:00:42 -0500670
671 /* Advance the SKB to the start of the payload */
672 skb_pull(skb, sizeof(struct ethhdr));
673
674 /* Determine total amount of storage required for TXB packets */
675 bytes = skb->len + SNAP_SIZE + sizeof(u16);
676
677 if (encrypt)
678 fc = RTLLIB_FTYPE_DATA | RTLLIB_FCTL_WEP;
679 else
680 fc = RTLLIB_FTYPE_DATA;
681
682 if (qos_actived)
683 fc |= RTLLIB_STYPE_QOS_DATA;
684 else
685 fc |= RTLLIB_STYPE_DATA;
686
687 if (ieee->iw_mode == IW_MODE_INFRA) {
688 fc |= RTLLIB_FCTL_TODS;
689 /* To DS: Addr1 = BSSID, Addr2 = SA,
690 Addr3 = DA */
691 memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
692 memcpy(&header.addr2, &src, ETH_ALEN);
693 if (IsAmsdu)
694 memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
695 else
696 memcpy(&header.addr3, &dest, ETH_ALEN);
697 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
698 /* not From/To DS: Addr1 = DA, Addr2 = SA,
699 Addr3 = BSSID */
700 memcpy(&header.addr1, dest, ETH_ALEN);
701 memcpy(&header.addr2, src, ETH_ALEN);
702 memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
703 }
704
705 bIsMulticast = is_broadcast_ether_addr(header.addr1) ||is_multicast_ether_addr(header.addr1);
706
707 header.frame_ctl = cpu_to_le16(fc);
708
709 /* Determine fragmentation size based on destination (multicast
710 * and broadcast are not fragmented) */
711 if (bIsMulticast) {
712 frag_size = MAX_FRAG_THRESHOLD;
713 qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
714 } else {
715 frag_size = ieee->fts;
716 qos_ctl = 0;
717 }
718
719 if (qos_actived) {
720 hdr_len = RTLLIB_3ADDR_LEN + 2;
721
722 /* in case we are a client verify acm is not set for this ac */
723 while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) {
724 printk("skb->priority = %x\n", skb->priority);
725 if (wme_downgrade_ac(skb)) {
726 break;
727 }
728 printk("converted skb->priority = %x\n", skb->priority);
729 }
730 qos_ctl |= skb->priority;
731 header.qos_ctl = cpu_to_le16(qos_ctl & RTLLIB_QOS_TID);
732 } else {
733 hdr_len = RTLLIB_3ADDR_LEN;
734 }
735 /* Determine amount of payload per fragment. Regardless of if
736 * this stack is providing the full 802.11 header, one will
737 * eventually be affixed to this fragment -- so we must account for
738 * it when determining the amount of payload space. */
739 bytes_per_frag = frag_size - hdr_len;
740 if (ieee->config &
741 (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS))
742 bytes_per_frag -= RTLLIB_FCS_LEN;
743
744 /* Each fragment may need to have room for encryptiong pre/postfix */
745 if (encrypt) {
746 bytes_per_frag -= crypt->ops->extra_prefix_len +
747 crypt->ops->extra_postfix_len;
748 }
749 /* Number of fragments is the total bytes_per_frag /
750 * payload_per_fragment */
751 nr_frags = bytes / bytes_per_frag;
752 bytes_last_frag = bytes % bytes_per_frag;
753 if (bytes_last_frag)
754 nr_frags++;
755 else
756 bytes_last_frag = bytes_per_frag;
757
758 /* When we allocate the TXB we allocate enough space for the reserve
759 * and full fragment bytes (bytes_per_frag doesn't include prefix,
760 * postfix, header, FCS, etc.) */
761 txb = rtllib_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
762 if (unlikely(!txb)) {
763 printk(KERN_WARNING "%s: Could not allocate TXB\n",
764 ieee->dev->name);
765 goto failed;
766 }
767 txb->encrypted = encrypt;
768 txb->payload_size = bytes;
769
770 if (qos_actived)
771 {
772 txb->queue_index = UP2AC(skb->priority);
773 } else {
774 txb->queue_index = WME_AC_BE;;
775 }
776
777 for (i = 0; i < nr_frags; i++) {
778 skb_frag = txb->fragments[i];
Larry Finger3b83db42011-07-19 00:01:29 -0500779 tcb_desc = (struct cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
Larry Finger94a79942011-08-23 19:00:42 -0500780 if (qos_actived){
781 skb_frag->priority = skb->priority;
782 tcb_desc->queue_index = UP2AC(skb->priority);
783 } else {
784 skb_frag->priority = WME_AC_BE;
785 tcb_desc->queue_index = WME_AC_BE;
786 }
787 skb_reserve(skb_frag, ieee->tx_headroom);
788
789 if (encrypt){
790 if (ieee->hwsec_active)
791 tcb_desc->bHwSec = 1;
792 else
793 tcb_desc->bHwSec = 0;
794 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
795 } else {
796 tcb_desc->bHwSec = 0;
797 }
798 frag_hdr = (struct rtllib_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
799 memcpy(frag_hdr, &header, hdr_len);
800
801 /* If this is not the last fragment, then add the MOREFRAGS
802 * bit to the frame control */
803 if (i != nr_frags - 1) {
804 frag_hdr->frame_ctl = cpu_to_le16(
805 fc | RTLLIB_FCTL_MOREFRAGS);
806 bytes = bytes_per_frag;
807
808 } else {
809 /* The last fragment takes the remaining length */
810 bytes = bytes_last_frag;
811 }
812 if ((qos_actived) && (!bIsMulticast))
813 {
814 frag_hdr->seq_ctl = rtllib_query_seqnum(ieee, skb_frag, header.addr1);
815 frag_hdr->seq_ctl = cpu_to_le16(frag_hdr->seq_ctl<<4 | i);
816 } else {
817 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
818 }
819 /* Put a SNAP header on the first fragment */
820 if (i == 0) {
821 rtllib_put_snap(
822 skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
823 ether_type);
824 bytes -= SNAP_SIZE + sizeof(u16);
825 }
826
827 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
828
829 /* Advance the SKB... */
830 skb_pull(skb, bytes);
831
832 /* Encryption routine will move the header forward in order
833 * to insert the IV between the header and the payload */
834 if (encrypt)
835 rtllib_encrypt_fragment(ieee, skb_frag, hdr_len);
836 if (ieee->config &
837 (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS))
838 skb_put(skb_frag, 4);
839 }
840
841 if ((qos_actived) && (!bIsMulticast)) {
842 if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
843 ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
844 else
845 ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
846 } else {
847 if (ieee->seq_ctrl[0] == 0xFFF)
848 ieee->seq_ctrl[0] = 0;
849 else
850 ieee->seq_ctrl[0]++;
851 }
852 }else{
853 if (unlikely(skb->len < sizeof(struct rtllib_hdr_3addr))) {
854 printk(KERN_WARNING "%s: skb too small (%d).\n",
855 ieee->dev->name, skb->len);
856 goto success;
857 }
858
859 txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC);
860 if (!txb){
861 printk(KERN_WARNING "%s: Could not allocate TXB\n",
862 ieee->dev->name);
863 goto failed;
864 }
865
866 txb->encrypted = 0;
867 txb->payload_size = skb->len;
868 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
869 }
870
871 success:
872 if (txb)
873 {
Larry Finger3b83db42011-07-19 00:01:29 -0500874 struct cb_desc *tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
Larry Finger94a79942011-08-23 19:00:42 -0500875 tcb_desc->bTxEnableFwCalcDur = 1;
876 tcb_desc->priority = skb->priority;
877
878 if (ether_type == ETH_P_PAE) {
879 if (ieee->pHTInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom)
880 {
881 tcb_desc->data_rate = MgntQuery_TxRateExcludeCCKRates(ieee);
882 tcb_desc->bTxDisableRateFallBack = false;
883 }else{
884 tcb_desc->data_rate = ieee->basic_rate;
885 tcb_desc->bTxDisableRateFallBack = 1;
886 }
887
888
889 tcb_desc->RATRIndex = 7;
890 tcb_desc->bTxUseDriverAssingedRate = 1;
891 } else {
892 if (is_multicast_ether_addr(header.addr1))
893 tcb_desc->bMulticast = 1;
894 if (is_broadcast_ether_addr(header.addr1))
895 tcb_desc->bBroadcast = 1;
Larry Finger94a79942011-08-23 19:00:42 -0500896 rtllib_txrate_selectmode(ieee, tcb_desc);
897 if ( tcb_desc->bMulticast || tcb_desc->bBroadcast)
898 tcb_desc->data_rate = ieee->basic_rate;
899 else
900 tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
901
902 if (bdhcp == true){
903 if (ieee->pHTInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom)
904 {
905 tcb_desc->data_rate = MgntQuery_TxRateExcludeCCKRates(ieee);
906 tcb_desc->bTxDisableRateFallBack = false;
907 }else{
908 tcb_desc->data_rate = MGN_1M;
909 tcb_desc->bTxDisableRateFallBack = 1;
910 }
911
912
913 tcb_desc->RATRIndex = 7;
914 tcb_desc->bTxUseDriverAssingedRate = 1;
915 tcb_desc->bdhcp = 1;
916 }
917
918 rtllib_qurey_ShortPreambleMode(ieee, tcb_desc);
919 rtllib_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
920 rtllib_query_HTCapShortGI(ieee, tcb_desc);
921 rtllib_query_BandwidthMode(ieee, tcb_desc);
922 rtllib_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
Larry Finger94a79942011-08-23 19:00:42 -0500923 }
Larry Finger94a79942011-08-23 19:00:42 -0500924 }
925 spin_unlock_irqrestore(&ieee->lock, flags);
926 dev_kfree_skb_any(skb);
927 if (txb) {
928 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
929 dev->stats.tx_packets++;
930 dev->stats.tx_bytes += txb->payload_size;
931 rtllib_softmac_xmit(txb, ieee);
932 }else{
933 if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
934 stats->tx_packets++;
935 stats->tx_bytes += txb->payload_size;
936 return 0;
937 }
938 rtllib_txb_free(txb);
939 }
940 }
941
942 return 0;
943
944 failed:
945 spin_unlock_irqrestore(&ieee->lock, flags);
946 netif_stop_queue(dev);
947 stats->tx_errors++;
948 return 1;
949
950}
951int rtllib_xmit(struct sk_buff *skb, struct net_device *dev)
952{
953 memset(skb->cb, 0, sizeof(skb->cb));
954 return rtllib_xmit_inter(skb, dev);
955}