staging: rtl8192e: remove eqMacAddr macro
[deliverable/linux.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
559a4c31 28 Andrea Merello <andrea.merello@gmail.com>
ecdfa446
GKH
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>
ecdfa446
GKH
49#include <linux/wireless.h>
50#include <linux/etherdevice.h>
f38d223b 51#include <linux/uaccess.h>
ecdfa446
GKH
52#include <linux/if_vlan.h>
53
94a79942 54#include "rtllib.h"
ecdfa446 55
ecdfa446
GKH
56/*
57
58
59802.11 Data Frame
60
61
cd017123 62802.11 frame_control for data frames - 2 bytes
ecdfa446
GKH
63 ,-----------------------------------------------------------------------------------------.
64bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
65 |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
66val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
67 |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
68desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
f38d223b 69 | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
ecdfa446 70 '-----------------------------------------------------------------------------------------'
f38d223b
LF
71 /\
72 |
73802.11 Data Frame |
74 ,--------- 'ctrl' expands to >-----------'
75 |
ecdfa446
GKH
76 ,--'---,-------------------------------------------------------------.
77Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
78 |------|------|---------|---------|---------|------|---------|------|
79Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
f38d223b
LF
80 | | tion | (BSSID) | | | ence | data | |
81 `--------------------------------------------------| |------'
82Total: 28 non-data bytes `----.----'
83 |
ecdfa446
GKH
84 .- 'Frame data' expands to <---------------------------'
85 |
86 V
87 ,---------------------------------------------------.
88Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
89 |------|------|---------|----------|------|---------|
90Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
f38d223b
LF
91 | DSAP | SSAP | | | | Packet |
92 | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
93 `-----------------------------------------| |
94Total: 8 non-data bytes `----.----'
95 |
ecdfa446
GKH
96 .- 'IP Packet' expands, if WEP enabled, to <--'
97 |
98 V
99 ,-----------------------.
100Bytes | 4 | 0-2296 | 4 |
101 |-----|-----------|-----|
102Desc. | IV | Encrypted | ICV |
103 | | IP Packet | |
104 `-----------------------'
105Total: 8 non-data bytes
106
107
108802.3 Ethernet Data Frame
109
110 ,-----------------------------------------.
111Bytes | 6 | 6 | 2 | Variable | 4 |
112 |-------|-------|------|-----------|------|
113Desc. | Dest. | Source| Type | IP Packet | fcs |
f38d223b 114 | MAC | MAC | | | |
ecdfa446
GKH
115 `-----------------------------------------'
116Total: 18 non-data bytes
117
118In the event that fragmentation is required, the incoming payload is split into
119N parts of size ieee->fts. The first fragment contains the SNAP header and the
120remaining packets are just data.
121
122If encryption is enabled, each fragment payload size is reduced by enough space
123to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
124So if you have 1500 bytes of payload with ieee->fts set to 500 without
125encryption it will take 3 frames. With WEP it will take 4 frames as the
126payload of each frame is reduced to 492 bytes.
127
128* SKB visualization
129*
130* ,- skb->data
131* |
f38d223b
LF
132* | ETHERNET HEADER ,-<-- PAYLOAD
133* | | 14 bytes from skb->data
ecdfa446 134* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
f38d223b 135* | | | |
ecdfa446
GKH
136* |,-Dest.--. ,--Src.---. | | |
137* | 6 bytes| | 6 bytes | | | |
f38d223b
LF
138* v | | | | | |
139* 0 | v 1 | v | v 2
ecdfa446 140* 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
f38d223b
LF
141* ^ | ^ | ^ |
142* | | | | | |
143* | | | | `T' <---- 2 bytes for Type
144* | | | |
ecdfa446
GKH
145* | | '---SNAP--' <-------- 6 bytes for SNAP
146* | |
147* `-IV--' <-------------------- 4 bytes for IV (WEP)
148*
149* SNAP HEADER
150*
151*/
152
153static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
154static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
155
94a79942 156inline int rtllib_put_snap(u8 *data, u16 h_proto)
ecdfa446 157{
94a79942 158 struct rtllib_snap_hdr *snap;
ecdfa446
GKH
159 u8 *oui;
160
94a79942 161 snap = (struct rtllib_snap_hdr *)data;
ecdfa446
GKH
162 snap->dsap = 0xaa;
163 snap->ssap = 0xaa;
164 snap->ctrl = 0x03;
165
166 if (h_proto == 0x8137 || h_proto == 0x80f3)
167 oui = P802_1H_OUI;
168 else
169 oui = RFC1042_OUI;
170 snap->oui[0] = oui[0];
171 snap->oui[1] = oui[1];
172 snap->oui[2] = oui[2];
173
9326c5ca 174 *(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
ecdfa446
GKH
175
176 return SNAP_SIZE + sizeof(u16);
177}
178
f38d223b
LF
179int rtllib_encrypt_fragment(struct rtllib_device *ieee, struct sk_buff *frag,
180 int hdr_len)
ecdfa446 181{
32c44cb5 182 struct lib80211_crypt_data *crypt = NULL;
ecdfa446
GKH
183 int res;
184
0ddcf5fd 185 crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
94a79942 186
f38d223b 187 if (!(crypt && crypt->ops)) {
d69d2054
MK
188 netdev_info(ieee->dev, "=========>%s(), crypt is null\n",
189 __func__);
ecdfa446
GKH
190 return -1;
191 }
ecdfa446
GKH
192 /* To encrypt, frame format is:
193 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
194
ecdfa446
GKH
195 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
196 * call both MSDU and MPDU encryption functions from here. */
197 atomic_inc(&crypt->refcnt);
198 res = 0;
199 if (crypt->ops->encrypt_msdu)
200 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
201 if (res == 0 && crypt->ops->encrypt_mpdu)
202 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
203
204 atomic_dec(&crypt->refcnt);
205 if (res < 0) {
d69d2054
MK
206 netdev_info(ieee->dev, "%s: Encryption failed: len=%d.\n",
207 ieee->dev->name, frag->len);
ecdfa446
GKH
208 ieee->ieee_stats.tx_discards++;
209 return -1;
210 }
211
212 return 0;
213}
214
215
f38d223b
LF
216void rtllib_txb_free(struct rtllib_txb *txb)
217{
ecdfa446
GKH
218 if (unlikely(!txb))
219 return;
ecdfa446
GKH
220 kfree(txb);
221}
222
ec0dc6be
LF
223static struct rtllib_txb *rtllib_alloc_txb(int nr_frags, int txb_size,
224 gfp_t gfp_mask)
ecdfa446 225{
94a79942 226 struct rtllib_txb *txb;
ecdfa446 227 int i;
3a6b70c3 228
f38d223b
LF
229 txb = kmalloc(sizeof(struct rtllib_txb) + (sizeof(u8 *) * nr_frags),
230 gfp_mask);
ecdfa446
GKH
231 if (!txb)
232 return NULL;
233
94a79942 234 memset(txb, 0, sizeof(struct rtllib_txb));
ecdfa446 235 txb->nr_frags = nr_frags;
198e0d17 236 txb->frag_size = cpu_to_le16(txb_size);
ecdfa446
GKH
237
238 for (i = 0; i < nr_frags; i++) {
239 txb->fragments[i] = dev_alloc_skb(txb_size);
240 if (unlikely(!txb->fragments[i])) {
241 i--;
242 break;
243 }
244 memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
245 }
246 if (unlikely(i != nr_frags)) {
247 while (i >= 0)
248 dev_kfree_skb_any(txb->fragments[i--]);
249 kfree(txb);
250 return NULL;
251 }
252 return txb;
253}
254
ec0dc6be 255static int rtllib_classify(struct sk_buff *skb, u8 bIsAmsdu)
ecdfa446
GKH
256{
257 struct ethhdr *eth;
258 struct iphdr *ip;
94a79942 259
ecdfa446
GKH
260 eth = (struct ethhdr *)skb->data;
261 if (eth->h_proto != htons(ETH_P_IP))
262 return 0;
263
94a79942 264 RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA, skb->data, skb->len);
ecdfa446 265 ip = ip_hdr(skb);
ecdfa446 266 switch (ip->tos & 0xfc) {
94a79942
LF
267 case 0x20:
268 return 2;
269 case 0x40:
270 return 1;
271 case 0x60:
272 return 3;
273 case 0x80:
274 return 4;
275 case 0xa0:
276 return 5;
277 case 0xc0:
278 return 6;
279 case 0xe0:
280 return 7;
281 default:
282 return 0;
ecdfa446
GKH
283 }
284}
285
ec0dc6be
LF
286static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee,
287 struct sk_buff *skb,
288 struct cb_desc *tcb_desc)
ecdfa446 289{
7796d93e 290 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
60554f2b 291 struct tx_ts_record *pTxTs = NULL;
4d0c8ee8 292 struct rtllib_hdr_1addr *hdr = (struct rtllib_hdr_1addr *)skb->data;
94a79942 293
f38d223b 294 if (rtllib_act_scanning(ieee, false))
94a79942 295 return;
ecdfa446 296
f38d223b 297 if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT)
ecdfa446
GKH
298 return;
299 if (!IsQoSDataFrame(skb->data))
300 return;
14fc4235 301 if (is_multicast_ether_addr(hdr->addr1))
ecdfa446 302 return;
65a43784 303
f38d223b 304 if (tcb_desc->bdhcp || ieee->CntAfterLink < 2)
94a79942 305 return;
65a43784 306
94a79942
LF
307 if (pHTInfo->IOTAction & HT_IOT_ACT_TX_NO_AGGREGATION)
308 return;
65a43784 309
94a79942 310 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
ecdfa446 311 return;
f38d223b
LF
312 if (pHTInfo->bCurrentAMPDUEnable) {
313 if (!GetTs(ieee, (struct ts_common_info **)(&pTxTs), hdr->addr1,
314 skb->priority, TX_DIR, true)) {
d69d2054 315 netdev_info(ieee->dev, "%s: can't get TS\n", __func__);
ecdfa446
GKH
316 return;
317 }
f38d223b
LF
318 if (pTxTs->TxAdmittedBARecord.bValid == false) {
319 if (ieee->wpa_ie_len && (ieee->pairwise_key_type ==
320 KEY_TYPE_NA)) {
94a79942 321 ;
f38d223b 322 } else if (tcb_desc->bdhcp == 1) {
94a79942 323 ;
f38d223b 324 } else if (!pTxTs->bDisable_AddBa) {
94a79942
LF
325 TsStartAddBaProcess(ieee, pTxTs);
326 }
ecdfa446 327 goto FORCED_AGG_SETTING;
94a79942 328 } else if (pTxTs->bUsingBa == false) {
f38d223b
LF
329 if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum,
330 (pTxTs->TxCurSeq+1)%4096))
ecdfa446
GKH
331 pTxTs->bUsingBa = true;
332 else
333 goto FORCED_AGG_SETTING;
334 }
94a79942 335 if (ieee->iw_mode == IW_MODE_INFRA) {
ecdfa446
GKH
336 tcb_desc->bAMPDUEnable = true;
337 tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
338 tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
339 }
340 }
341FORCED_AGG_SETTING:
94a79942 342 switch (pHTInfo->ForcedAMPDUMode) {
f38d223b
LF
343 case HT_AGG_AUTO:
344 break;
345
346 case HT_AGG_FORCE_ENABLE:
347 tcb_desc->bAMPDUEnable = true;
348 tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
349 tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
350 break;
351
352 case HT_AGG_FORCE_DISABLE:
353 tcb_desc->bAMPDUEnable = false;
354 tcb_desc->ampdu_density = 0;
355 tcb_desc->ampdu_factor = 0;
356 break;
ecdfa446 357 }
ecdfa446
GKH
358}
359
ec0dc6be 360static void rtllib_qurey_ShortPreambleMode(struct rtllib_device *ieee,
f38d223b 361 struct cb_desc *tcb_desc)
ecdfa446
GKH
362{
363 tcb_desc->bUseShortPreamble = false;
364 if (tcb_desc->data_rate == 2)
ecdfa446 365 return;
f38d223b
LF
366 else if (ieee->current_network.capability &
367 WLAN_CAPABILITY_SHORT_PREAMBLE)
ecdfa446 368 tcb_desc->bUseShortPreamble = true;
ecdfa446 369}
94a79942 370
ec0dc6be 371static void rtllib_query_HTCapShortGI(struct rtllib_device *ieee,
f38d223b 372 struct cb_desc *tcb_desc)
ecdfa446 373{
7796d93e 374 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
ecdfa446 375
94a79942 376 tcb_desc->bUseShortGI = false;
ecdfa446 377
f38d223b 378 if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT)
ecdfa446
GKH
379 return;
380
f38d223b 381 if (pHTInfo->bForcedShortGI) {
ecdfa446
GKH
382 tcb_desc->bUseShortGI = true;
383 return;
384 }
385
f38d223b 386 if ((pHTInfo->bCurBW40MHz == true) && pHTInfo->bCurShortGI40MHz)
ecdfa446 387 tcb_desc->bUseShortGI = true;
f38d223b 388 else if ((pHTInfo->bCurBW40MHz == false) && pHTInfo->bCurShortGI20MHz)
ecdfa446
GKH
389 tcb_desc->bUseShortGI = true;
390}
391
ec0dc6be
LF
392static void rtllib_query_BandwidthMode(struct rtllib_device *ieee,
393 struct cb_desc *tcb_desc)
ecdfa446 394{
7796d93e 395 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
ecdfa446
GKH
396
397 tcb_desc->bPacketBW = false;
398
f38d223b 399 if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT)
ecdfa446
GKH
400 return;
401
94a79942 402 if (tcb_desc->bMulticast || tcb_desc->bBroadcast)
ecdfa446
GKH
403 return;
404
f38d223b 405 if ((tcb_desc->data_rate & 0x80) == 0)
ecdfa446 406 return;
f38d223b
LF
407 if (pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz &&
408 !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
ecdfa446 409 tcb_desc->bPacketBW = true;
ecdfa446 410}
94a79942 411
ec0dc6be
LF
412static void rtllib_query_protectionmode(struct rtllib_device *ieee,
413 struct cb_desc *tcb_desc,
414 struct sk_buff *skb)
ecdfa446 415{
ecdfa446 416 tcb_desc->bRTSSTBC = false;
94a79942
LF
417 tcb_desc->bRTSUseShortGI = false;
418 tcb_desc->bCTSEnable = false;
419 tcb_desc->RTSSC = 0;
420 tcb_desc->bRTSBW = false;
ecdfa446 421
94a79942 422 if (tcb_desc->bBroadcast || tcb_desc->bMulticast)
ecdfa446
GKH
423 return;
424
94a79942 425 if (is_broadcast_ether_addr(skb->data+16))
ecdfa446
GKH
426 return;
427
f38d223b
LF
428 if (ieee->mode < IEEE_N_24G) {
429 if (skb->len > ieee->rts) {
ecdfa446
GKH
430 tcb_desc->bRTSEnable = true;
431 tcb_desc->rts_rate = MGN_24M;
f38d223b 432 } else if (ieee->current_network.buseprotection) {
ecdfa446
GKH
433 tcb_desc->bRTSEnable = true;
434 tcb_desc->bCTSEnable = true;
435 tcb_desc->rts_rate = MGN_24M;
436 }
ecdfa446 437 return;
f38d223b 438 } else {
7796d93e 439 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
3a6b70c3 440
f38d223b
LF
441 while (true) {
442 if (pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) {
94a79942
LF
443 tcb_desc->bCTSEnable = true;
444 tcb_desc->rts_rate = MGN_24M;
445 tcb_desc->bRTSEnable = true;
446 break;
f38d223b
LF
447 } else if (pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS |
448 HT_IOT_ACT_PURE_N_MODE)) {
94a79942
LF
449 tcb_desc->bRTSEnable = true;
450 tcb_desc->rts_rate = MGN_24M;
451 break;
452 }
f38d223b 453 if (ieee->current_network.buseprotection) {
ecdfa446
GKH
454 tcb_desc->bRTSEnable = true;
455 tcb_desc->bCTSEnable = true;
456 tcb_desc->rts_rate = MGN_24M;
457 break;
458 }
f38d223b 459 if (pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT) {
ecdfa446 460 u8 HTOpMode = pHTInfo->CurrentOpMode;
3a6b70c3 461
f38d223b
LF
462 if ((pHTInfo->bCurBW40MHz && (HTOpMode == 2 ||
463 HTOpMode == 3)) ||
464 (!pHTInfo->bCurBW40MHz && HTOpMode == 3)) {
94a79942 465 tcb_desc->rts_rate = MGN_24M;
ecdfa446
GKH
466 tcb_desc->bRTSEnable = true;
467 break;
468 }
469 }
f38d223b 470 if (skb->len > ieee->rts) {
94a79942 471 tcb_desc->rts_rate = MGN_24M;
ecdfa446
GKH
472 tcb_desc->bRTSEnable = true;
473 break;
474 }
f38d223b 475 if (tcb_desc->bAMPDUEnable) {
94a79942 476 tcb_desc->rts_rate = MGN_24M;
ecdfa446
GKH
477 tcb_desc->bRTSEnable = false;
478 break;
479 }
ecdfa446
GKH
480 goto NO_PROTECTION;
481 }
ecdfa446
GKH
482 }
483 if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
484 tcb_desc->bUseShortPreamble = true;
94a79942 485 if (ieee->iw_mode == IW_MODE_MASTER)
ecdfa446
GKH
486 goto NO_PROTECTION;
487 return;
488NO_PROTECTION:
489 tcb_desc->bRTSEnable = false;
490 tcb_desc->bCTSEnable = false;
f38d223b 491 tcb_desc->rts_rate = 0;
ecdfa446 492 tcb_desc->RTSSC = 0;
f38d223b 493 tcb_desc->bRTSBW = false;
ecdfa446
GKH
494}
495
496
ec0dc6be
LF
497static void rtllib_txrate_selectmode(struct rtllib_device *ieee,
498 struct cb_desc *tcb_desc)
ecdfa446 499{
94a79942 500 if (ieee->bTxDisableRateFallBack)
ecdfa446
GKH
501 tcb_desc->bTxDisableRateFallBack = true;
502
94a79942 503 if (ieee->bTxUseDriverAssingedRate)
ecdfa446 504 tcb_desc->bTxUseDriverAssingedRate = true;
f38d223b
LF
505 if (!tcb_desc->bTxDisableRateFallBack ||
506 !tcb_desc->bTxUseDriverAssingedRate) {
507 if (ieee->iw_mode == IW_MODE_INFRA ||
508 ieee->iw_mode == IW_MODE_ADHOC)
ecdfa446
GKH
509 tcb_desc->RATRIndex = 0;
510 }
511}
512
f38d223b
LF
513u16 rtllib_query_seqnum(struct rtllib_device *ieee, struct sk_buff *skb,
514 u8 *dst)
ecdfa446 515{
94a79942
LF
516 u16 seqnum = 0;
517
14fc4235 518 if (is_multicast_ether_addr(dst))
94a79942 519 return 0;
f38d223b 520 if (IsQoSDataFrame(skb->data)) {
60554f2b 521 struct tx_ts_record *pTS = NULL;
3a6b70c3 522
f38d223b
LF
523 if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst,
524 skb->priority, TX_DIR, true))
94a79942 525 return 0;
94a79942 526 seqnum = pTS->TxCurSeq;
ecdfa446 527 pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
94a79942
LF
528 return seqnum;
529 }
530 return 0;
531}
532
533static int wme_downgrade_ac(struct sk_buff *skb)
534{
535 switch (skb->priority) {
f38d223b
LF
536 case 6:
537 case 7:
538 skb->priority = 5; /* VO -> VI */
539 return 0;
540 case 4:
541 case 5:
542 skb->priority = 3; /* VI -> BE */
543 return 0;
544 case 0:
545 case 3:
546 skb->priority = 1; /* BE -> BK */
547 return 0;
548 default:
549 return -1;
ecdfa446
GKH
550 }
551}
552
94a79942 553int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
ecdfa446 554{
f38d223b
LF
555 struct rtllib_device *ieee = (struct rtllib_device *)
556 netdev_priv_rsl(dev);
94a79942
LF
557 struct rtllib_txb *txb = NULL;
558 struct rtllib_hdr_3addrqos *frag_hdr;
ecdfa446
GKH
559 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
560 unsigned long flags;
561 struct net_device_stats *stats = &ieee->stats;
562 int ether_type = 0, encrypt;
563 int bytes, fc, qos_ctl = 0, hdr_len;
564 struct sk_buff *skb_frag;
94a79942 565 struct rtllib_hdr_3addrqos header = { /* Ensure zero initialized */
ecdfa446
GKH
566 .duration_id = 0,
567 .seq_ctl = 0,
568 .qos_ctl = 0
569 };
570 u8 dest[ETH_ALEN], src[ETH_ALEN];
571 int qos_actived = ieee->current_network.qos_data.active;
32c44cb5 572 struct lib80211_crypt_data *crypt = NULL;
3b83db43 573 struct cb_desc *tcb_desc;
94a79942
LF
574 u8 bIsMulticast = false;
575 u8 IsAmsdu = false;
f38d223b 576 bool bdhcp = false;
ecdfa446
GKH
577
578 spin_lock_irqsave(&ieee->lock, flags);
579
cd017123 580 /* If there is no driver handler to take the TXB, don't bother
ecdfa446 581 * creating it... */
f38d223b
LF
582 if ((!ieee->hard_start_xmit && !(ieee->softmac_features &
583 IEEE_SOFTMAC_TX_QUEUE)) ||
584 ((!ieee->softmac_data_hard_start_xmit &&
585 (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
d69d2054 586 netdev_warn(ieee->dev, "No xmit handler.\n");
ecdfa446
GKH
587 goto success;
588 }
589
590
f38d223b 591 if (likely(ieee->raw_tx == 0)) {
ecdfa446 592 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
d69d2054
MK
593 netdev_warn(ieee->dev, "skb too small (%d).\n",
594 skb->len);
ecdfa446
GKH
595 goto success;
596 }
94a79942
LF
597 /* Save source and destination addresses */
598 memcpy(dest, skb->data, ETH_ALEN);
599 memcpy(src, skb->data+ETH_ALEN, ETH_ALEN);
ecdfa446
GKH
600
601 memset(skb->cb, 0, sizeof(skb->cb));
602 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
603
f38d223b 604 if (ieee->iw_mode == IW_MODE_MONITOR) {
94a79942
LF
605 txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC);
606 if (unlikely(!txb)) {
d69d2054
MK
607 netdev_warn(ieee->dev,
608 "Could not allocate TXB\n");
94a79942
LF
609 goto failed;
610 }
ecdfa446 611
94a79942 612 txb->encrypted = 0;
198e0d17 613 txb->payload_size = cpu_to_le16(skb->len);
f38d223b
LF
614 memcpy(skb_put(txb->fragments[0], skb->len), skb->data,
615 skb->len);
ecdfa446 616
ecdfa446
GKH
617 goto success;
618 }
ecdfa446 619
55dc4eb3 620 if (skb->len > 282) {
94a79942 621 if (ETH_P_IP == ether_type) {
f38d223b
LF
622 const struct iphdr *ip = (struct iphdr *)
623 ((u8 *)skb->data+14);
94a79942 624 if (IPPROTO_UDP == ip->protocol) {
f38d223b
LF
625 struct udphdr *udp;
626
627 udp = (struct udphdr *)((u8 *)ip +
628 (ip->ihl << 2));
629 if (((((u8 *)udp)[1] == 68) &&
630 (((u8 *)udp)[3] == 67)) ||
631 ((((u8 *)udp)[1] == 67) &&
632 (((u8 *)udp)[3] == 68))) {
65a43784 633 bdhcp = true;
94a79942 634 ieee->LPSDelayCnt = 200;
65a43784 635 }
636 }
f38d223b 637 } else if (ETH_P_ARP == ether_type) {
d69d2054
MK
638 netdev_info(ieee->dev,
639 "=================>DHCP Protocol start tx ARP pkt!!\n");
94a79942 640 bdhcp = true;
f38d223b
LF
641 ieee->LPSDelayCnt =
642 ieee->current_network.tim.tim_count;
65a43784 643 }
94a79942 644 }
65a43784 645
94a79942 646 skb->priority = rtllib_classify(skb, IsAmsdu);
0ddcf5fd 647 crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
94a79942
LF
648 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
649 ieee->host_encrypt && crypt && crypt->ops;
650 if (!encrypt && ieee->ieee802_1x &&
f38d223b 651 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
94a79942
LF
652 stats->tx_dropped++;
653 goto success;
654 }
94a79942
LF
655 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
656 struct eapol *eap = (struct eapol *)(skb->data +
f38d223b
LF
657 sizeof(struct ethhdr) - SNAP_SIZE -
658 sizeof(u16));
94a79942
LF
659 RTLLIB_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
660 eap_get_type(eap->type));
661 }
ecdfa446 662
94a79942
LF
663 /* Advance the SKB to the start of the payload */
664 skb_pull(skb, sizeof(struct ethhdr));
ecdfa446 665
f38d223b 666 /* Determine total amount of storage required for TXB packets */
94a79942 667 bytes = skb->len + SNAP_SIZE + sizeof(u16);
ecdfa446
GKH
668
669 if (encrypt)
94a79942 670 fc = RTLLIB_FTYPE_DATA | RTLLIB_FCTL_WEP;
ecdfa446 671 else
94a79942 672 fc = RTLLIB_FTYPE_DATA;
ecdfa446 673
94a79942
LF
674 if (qos_actived)
675 fc |= RTLLIB_STYPE_QOS_DATA;
ecdfa446 676 else
94a79942 677 fc |= RTLLIB_STYPE_DATA;
ecdfa446
GKH
678
679 if (ieee->iw_mode == IW_MODE_INFRA) {
94a79942 680 fc |= RTLLIB_FCTL_TODS;
ecdfa446
GKH
681 /* To DS: Addr1 = BSSID, Addr2 = SA,
682 Addr3 = DA */
f38d223b
LF
683 memcpy(&header.addr1, ieee->current_network.bssid,
684 ETH_ALEN);
ecdfa446 685 memcpy(&header.addr2, &src, ETH_ALEN);
94a79942 686 if (IsAmsdu)
f38d223b
LF
687 memcpy(&header.addr3,
688 ieee->current_network.bssid, ETH_ALEN);
94a79942
LF
689 else
690 memcpy(&header.addr3, &dest, ETH_ALEN);
ecdfa446
GKH
691 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
692 /* not From/To DS: Addr1 = DA, Addr2 = SA,
693 Addr3 = BSSID */
694 memcpy(&header.addr1, dest, ETH_ALEN);
695 memcpy(&header.addr2, src, ETH_ALEN);
f38d223b
LF
696 memcpy(&header.addr3, ieee->current_network.bssid,
697 ETH_ALEN);
ecdfa446
GKH
698 }
699
14fc4235 700 bIsMulticast = is_multicast_ether_addr(header.addr1);
94a79942 701
f38d223b 702 header.frame_ctl = cpu_to_le16(fc);
ecdfa446
GKH
703
704 /* Determine fragmentation size based on destination (multicast
705 * and broadcast are not fragmented) */
94a79942 706 if (bIsMulticast) {
ecdfa446
GKH
707 frag_size = MAX_FRAG_THRESHOLD;
708 qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
94a79942
LF
709 } else {
710 frag_size = ieee->fts;
ecdfa446
GKH
711 qos_ctl = 0;
712 }
713
94a79942
LF
714 if (qos_actived) {
715 hdr_len = RTLLIB_3ADDR_LEN + 2;
716
f38d223b
LF
717 /* in case we are a client verify acm is not set for this ac */
718 while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) {
d69d2054
MK
719 netdev_info(ieee->dev, "skb->priority = %x\n",
720 skb->priority);
f38d223b
LF
721 if (wme_downgrade_ac(skb))
722 break;
d69d2054 723 netdev_info(ieee->dev, "converted skb->priority = %x\n",
f38d223b
LF
724 skb->priority);
725 }
726 qos_ctl |= skb->priority;
727 header.qos_ctl = cpu_to_le16(qos_ctl & RTLLIB_QOS_TID);
ecdfa446 728 } else {
94a79942 729 hdr_len = RTLLIB_3ADDR_LEN;
ecdfa446
GKH
730 }
731 /* Determine amount of payload per fragment. Regardless of if
f38d223b
LF
732 * this stack is providing the full 802.11 header, one will
733 * eventually be affixed to this fragment -- so we must account
734 * for it when determining the amount of payload space. */
ecdfa446
GKH
735 bytes_per_frag = frag_size - hdr_len;
736 if (ieee->config &
f38d223b 737 (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS))
94a79942 738 bytes_per_frag -= RTLLIB_FCS_LEN;
ecdfa446 739
cd017123 740 /* Each fragment may need to have room for encrypting
f38d223b 741 * pre/postfix */
94a79942 742 if (encrypt) {
32c44cb5
SM
743 bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len +
744 crypt->ops->extra_mpdu_postfix_len +
745 crypt->ops->extra_msdu_prefix_len +
746 crypt->ops->extra_msdu_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
f38d223b
LF
757 /* When we allocate the TXB we allocate enough space for the
758 * reserve and full fragment bytes (bytes_per_frag doesn't
759 * include prefix, postfix, header, FCS, etc.) */
760 txb = rtllib_alloc_txb(nr_frags, frag_size +
761 ieee->tx_headroom, GFP_ATOMIC);
ecdfa446 762 if (unlikely(!txb)) {
d69d2054 763 netdev_warn(ieee->dev, "Could not allocate TXB\n");
ecdfa446
GKH
764 goto failed;
765 }
766 txb->encrypted = encrypt;
198e0d17 767 txb->payload_size = cpu_to_le16(bytes);
ecdfa446 768
94a79942 769 if (qos_actived)
ecdfa446 770 txb->queue_index = UP2AC(skb->priority);
f38d223b
LF
771 else
772 txb->queue_index = WME_AC_BE;
ecdfa446 773
ecdfa446
GKH
774 for (i = 0; i < nr_frags; i++) {
775 skb_frag = txb->fragments[i];
f38d223b
LF
776 tcb_desc = (struct cb_desc *)(skb_frag->cb +
777 MAX_DEV_ADDR_SIZE);
778 if (qos_actived) {
94a79942 779 skb_frag->priority = skb->priority;
ecdfa446
GKH
780 tcb_desc->queue_index = UP2AC(skb->priority);
781 } else {
94a79942
LF
782 skb_frag->priority = WME_AC_BE;
783 tcb_desc->queue_index = WME_AC_BE;
ecdfa446
GKH
784 }
785 skb_reserve(skb_frag, ieee->tx_headroom);
786
f38d223b 787 if (encrypt) {
ecdfa446
GKH
788 if (ieee->hwsec_active)
789 tcb_desc->bHwSec = 1;
790 else
791 tcb_desc->bHwSec = 0;
f38d223b 792 skb_reserve(skb_frag,
32c44cb5
SM
793 crypt->ops->extra_mpdu_prefix_len +
794 crypt->ops->extra_msdu_prefix_len);
94a79942 795 } else {
ecdfa446
GKH
796 tcb_desc->bHwSec = 0;
797 }
f38d223b
LF
798 frag_hdr = (struct rtllib_hdr_3addrqos *)
799 skb_put(skb_frag, hdr_len);
ecdfa446
GKH
800 memcpy(frag_hdr, &header, hdr_len);
801
f38d223b
LF
802 /* If this is not the last fragment, then add the
803 * MOREFRAGS bit to the frame control */
ecdfa446
GKH
804 if (i != nr_frags - 1) {
805 frag_hdr->frame_ctl = cpu_to_le16(
94a79942 806 fc | RTLLIB_FCTL_MOREFRAGS);
ecdfa446
GKH
807 bytes = bytes_per_frag;
808
809 } else {
f38d223b 810 /* The last fragment has the remaining length */
ecdfa446
GKH
811 bytes = bytes_last_frag;
812 }
f38d223b
LF
813 if ((qos_actived) && (!bIsMulticast)) {
814 frag_hdr->seq_ctl =
198e0d17
RK
815 cpu_to_le16(rtllib_query_seqnum(ieee, skb_frag,
816 header.addr1));
f38d223b 817 frag_hdr->seq_ctl =
86005e16 818 cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctl)<<4 | i);
ecdfa446 819 } else {
f38d223b
LF
820 frag_hdr->seq_ctl =
821 cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
ecdfa446 822 }
ecdfa446
GKH
823 /* Put a SNAP header on the first fragment */
824 if (i == 0) {
94a79942 825 rtllib_put_snap(
f38d223b
LF
826 skb_put(skb_frag, SNAP_SIZE +
827 sizeof(u16)), ether_type);
ecdfa446
GKH
828 bytes -= SNAP_SIZE + sizeof(u16);
829 }
830
831 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
832
833 /* Advance the SKB... */
834 skb_pull(skb, bytes);
835
f38d223b
LF
836 /* Encryption routine will move the header forward in
837 * order to insert the IV between the header and the
838 * payload */
ecdfa446 839 if (encrypt)
f38d223b
LF
840 rtllib_encrypt_fragment(ieee, skb_frag,
841 hdr_len);
ecdfa446 842 if (ieee->config &
f38d223b 843 (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS))
ecdfa446
GKH
844 skb_put(skb_frag, 4);
845 }
846
94a79942 847 if ((qos_actived) && (!bIsMulticast)) {
f38d223b
LF
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]++;
ecdfa446 852 } else {
f38d223b
LF
853 if (ieee->seq_ctrl[0] == 0xFFF)
854 ieee->seq_ctrl[0] = 0;
855 else
856 ieee->seq_ctrl[0]++;
ecdfa446 857 }
f38d223b 858 } else {
94a79942 859 if (unlikely(skb->len < sizeof(struct rtllib_hdr_3addr))) {
d69d2054
MK
860 netdev_warn(ieee->dev, "skb too small (%d).\n",
861 skb->len);
ecdfa446
GKH
862 goto success;
863 }
864
94a79942 865 txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC);
f38d223b 866 if (!txb) {
d69d2054 867 netdev_warn(ieee->dev, "Could not allocate TXB\n");
ecdfa446
GKH
868 goto failed;
869 }
870
871 txb->encrypted = 0;
198e0d17 872 txb->payload_size = cpu_to_le16(skb->len);
f38d223b
LF
873 memcpy(skb_put(txb->fragments[0], skb->len), skb->data,
874 skb->len);
ecdfa446
GKH
875 }
876
877 success:
f38d223b
LF
878 if (txb) {
879 struct cb_desc *tcb_desc = (struct cb_desc *)
880 (txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
ecdfa446 881 tcb_desc->bTxEnableFwCalcDur = 1;
94a79942 882 tcb_desc->priority = skb->priority;
65a43784 883
94a79942 884 if (ether_type == ETH_P_PAE) {
f38d223b
LF
885 if (ieee->pHTInfo->IOTAction &
886 HT_IOT_ACT_WA_IOT_Broadcom) {
887 tcb_desc->data_rate =
888 MgntQuery_TxRateExcludeCCKRates(ieee);
94a79942 889 tcb_desc->bTxDisableRateFallBack = false;
f38d223b 890 } else {
94a79942 891 tcb_desc->data_rate = ieee->basic_rate;
65a43784 892 tcb_desc->bTxDisableRateFallBack = 1;
94a79942
LF
893 }
894
65a43784 895
896 tcb_desc->RATRIndex = 7;
897 tcb_desc->bTxUseDriverAssingedRate = 1;
94a79942
LF
898 } else {
899 if (is_multicast_ether_addr(header.addr1))
900 tcb_desc->bMulticast = 1;
901 if (is_broadcast_ether_addr(header.addr1))
902 tcb_desc->bBroadcast = 1;
94a79942 903 rtllib_txrate_selectmode(ieee, tcb_desc);
f38d223b 904 if (tcb_desc->bMulticast || tcb_desc->bBroadcast)
94a79942
LF
905 tcb_desc->data_rate = ieee->basic_rate;
906 else
f38d223b
LF
907 tcb_desc->data_rate = CURRENT_RATE(ieee->mode,
908 ieee->rate, ieee->HTCurrentOperaRate);
909
4bb01423 910 if (bdhcp) {
f38d223b
LF
911 if (ieee->pHTInfo->IOTAction &
912 HT_IOT_ACT_WA_IOT_Broadcom) {
913 tcb_desc->data_rate =
914 MgntQuery_TxRateExcludeCCKRates(ieee);
94a79942 915 tcb_desc->bTxDisableRateFallBack = false;
f38d223b 916 } else {
94a79942
LF
917 tcb_desc->data_rate = MGN_1M;
918 tcb_desc->bTxDisableRateFallBack = 1;
919 }
65a43784 920
921
94a79942
LF
922 tcb_desc->RATRIndex = 7;
923 tcb_desc->bTxUseDriverAssingedRate = 1;
924 tcb_desc->bdhcp = 1;
925 }
926
927 rtllib_qurey_ShortPreambleMode(ieee, tcb_desc);
f38d223b
LF
928 rtllib_tx_query_agg_cap(ieee, txb->fragments[0],
929 tcb_desc);
94a79942
LF
930 rtllib_query_HTCapShortGI(ieee, tcb_desc);
931 rtllib_query_BandwidthMode(ieee, tcb_desc);
f38d223b
LF
932 rtllib_query_protectionmode(ieee, tcb_desc,
933 txb->fragments[0]);
94a79942 934 }
ecdfa446
GKH
935 }
936 spin_unlock_irqrestore(&ieee->lock, flags);
937 dev_kfree_skb_any(skb);
938 if (txb) {
f38d223b 939 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) {
94a79942 940 dev->stats.tx_packets++;
83efd529 941 dev->stats.tx_bytes += le16_to_cpu(txb->payload_size);
94a79942 942 rtllib_softmac_xmit(txb, ieee);
f38d223b 943 } else {
94a79942 944 if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
ecdfa446 945 stats->tx_packets++;
83efd529 946 stats->tx_bytes += le16_to_cpu(txb->payload_size);
ecdfa446
GKH
947 return 0;
948 }
94a79942 949 rtllib_txb_free(txb);
ecdfa446
GKH
950 }
951 }
952
953 return 0;
954
955 failed:
956 spin_unlock_irqrestore(&ieee->lock, flags);
957 netif_stop_queue(dev);
958 stats->tx_errors++;
959 return 1;
960
961}
94a79942
LF
962int rtllib_xmit(struct sk_buff *skb, struct net_device *dev)
963{
964 memset(skb->cb, 0, sizeof(skb->cb));
965 return rtllib_xmit_inter(skb, dev);
966}
3b28499c 967EXPORT_SYMBOL(rtllib_xmit);
This page took 1.011454 seconds and 5 git commands to generate.