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