x86, pat: Sanity check remap_pfn_range for RAM region
[deliverable/linux.git] / drivers / staging / rtl8192su / ieee80211 / ieee80211_tx.c
1 /******************************************************************************
2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Contact Information:
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25 ******************************************************************************
26
27 Few modifications for Realtek's Wi-Fi drivers by
28 Andrea Merello <andreamrl@tiscali.it>
29
30 A special thanks goes to Realtek for their support !
31
32 ******************************************************************************/
33
34 #include <linux/compiler.h>
35 //#include <linux/config.h>
36 #include <linux/errno.h>
37 #include <linux/if_arp.h>
38 #include <linux/in6.h>
39 #include <linux/in.h>
40 #include <linux/ip.h>
41 #include <linux/kernel.h>
42 #include <linux/module.h>
43 #include <linux/netdevice.h>
44 #include <linux/pci.h>
45 #include <linux/proc_fs.h>
46 #include <linux/skbuff.h>
47 #include <linux/slab.h>
48 #include <linux/tcp.h>
49 #include <linux/types.h>
50 #include <linux/version.h>
51 #include <linux/wireless.h>
52 #include <linux/etherdevice.h>
53 #include <asm/uaccess.h>
54 #include <linux/if_vlan.h>
55
56 #include "ieee80211.h"
57
58
59 /*
60
61
62 802.11 Data Frame
63
64
65 802.11 frame_contorl for data frames - 2 bytes
66 ,-----------------------------------------------------------------------------------------.
67 bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
68 |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
69 val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
70 |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
71 desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
72 | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
73 '-----------------------------------------------------------------------------------------'
74 /\
75 |
76 802.11 Data Frame |
77 ,--------- 'ctrl' expands to >-----------'
78 |
79 ,--'---,-------------------------------------------------------------.
80 Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
81 |------|------|---------|---------|---------|------|---------|------|
82 Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
83 | | tion | (BSSID) | | | ence | data | |
84 `--------------------------------------------------| |------'
85 Total: 28 non-data bytes `----.----'
86 |
87 .- 'Frame data' expands to <---------------------------'
88 |
89 V
90 ,---------------------------------------------------.
91 Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
92 |------|------|---------|----------|------|---------|
93 Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
94 | DSAP | SSAP | | | | Packet |
95 | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
96 `-----------------------------------------| |
97 Total: 8 non-data bytes `----.----'
98 |
99 .- 'IP Packet' expands, if WEP enabled, to <--'
100 |
101 V
102 ,-----------------------.
103 Bytes | 4 | 0-2296 | 4 |
104 |-----|-----------|-----|
105 Desc. | IV | Encrypted | ICV |
106 | | IP Packet | |
107 `-----------------------'
108 Total: 8 non-data bytes
109
110
111 802.3 Ethernet Data Frame
112
113 ,-----------------------------------------.
114 Bytes | 6 | 6 | 2 | Variable | 4 |
115 |-------|-------|------|-----------|------|
116 Desc. | Dest. | Source| Type | IP Packet | fcs |
117 | MAC | MAC | | | |
118 `-----------------------------------------'
119 Total: 18 non-data bytes
120
121 In the event that fragmentation is required, the incoming payload is split into
122 N parts of size ieee->fts. The first fragment contains the SNAP header and the
123 remaining packets are just data.
124
125 If encryption is enabled, each fragment payload size is reduced by enough space
126 to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
127 So if you have 1500 bytes of payload with ieee->fts set to 500 without
128 encryption it will take 3 frames. With WEP it will take 4 frames as the
129 payload of each frame is reduced to 492 bytes.
130
131 * SKB visualization
132 *
133 * ,- skb->data
134 * |
135 * | ETHERNET HEADER ,-<-- PAYLOAD
136 * | | 14 bytes from skb->data
137 * | 2 bytes for Type --> ,T. | (sizeof ethhdr)
138 * | | | |
139 * |,-Dest.--. ,--Src.---. | | |
140 * | 6 bytes| | 6 bytes | | | |
141 * v | | | | | |
142 * 0 | v 1 | v | v 2
143 * 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
144 * ^ | ^ | ^ |
145 * | | | | | |
146 * | | | | `T' <---- 2 bytes for Type
147 * | | | |
148 * | | '---SNAP--' <-------- 6 bytes for SNAP
149 * | |
150 * `-IV--' <-------------------- 4 bytes for IV (WEP)
151 *
152 * SNAP HEADER
153 *
154 */
155
156 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
157 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
158
159 static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
160 {
161 struct ieee80211_snap_hdr *snap;
162 u8 *oui;
163
164 snap = (struct ieee80211_snap_hdr *)data;
165 snap->dsap = 0xaa;
166 snap->ssap = 0xaa;
167 snap->ctrl = 0x03;
168
169 if (h_proto == 0x8137 || h_proto == 0x80f3)
170 oui = P802_1H_OUI;
171 else
172 oui = RFC1042_OUI;
173 snap->oui[0] = oui[0];
174 snap->oui[1] = oui[1];
175 snap->oui[2] = oui[2];
176
177 *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
178
179 return SNAP_SIZE + sizeof(u16);
180 }
181
182 int ieee80211_encrypt_fragment(
183 struct ieee80211_device *ieee,
184 struct sk_buff *frag,
185 int hdr_len)
186 {
187 struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
188 int res;
189
190 if (!(crypt && crypt->ops))
191 {
192 printk("=========>%s(), crypt is null\n", __FUNCTION__);
193 return -1;
194 }
195 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
196 struct ieee80211_hdr *header;
197
198 if (ieee->tkip_countermeasures &&
199 crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
200 header = (struct ieee80211_hdr *) frag->data;
201 if (net_ratelimit()) {
202 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
203 "TX packet to " MAC_FMT "\n",
204 ieee->dev->name, MAC_ARG(header->addr1));
205 }
206 return -1;
207 }
208 #endif
209 /* To encrypt, frame format is:
210 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
211
212 // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
213 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
214 * call both MSDU and MPDU encryption functions from here. */
215 atomic_inc(&crypt->refcnt);
216 res = 0;
217 if (crypt->ops->encrypt_msdu)
218 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
219 if (res == 0 && crypt->ops->encrypt_mpdu)
220 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
221
222 atomic_dec(&crypt->refcnt);
223 if (res < 0) {
224 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
225 ieee->dev->name, frag->len);
226 ieee->ieee_stats.tx_discards++;
227 return -1;
228 }
229
230 return 0;
231 }
232
233
234 void ieee80211_txb_free(struct ieee80211_txb *txb) {
235 //int i;
236 if (unlikely(!txb))
237 return;
238 #if 0
239 for (i = 0; i < txb->nr_frags; i++)
240 if (txb->fragments[i])
241 dev_kfree_skb_any(txb->fragments[i]);
242 #endif
243 kfree(txb);
244 }
245
246 struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
247 int gfp_mask)
248 {
249 struct ieee80211_txb *txb;
250 int i;
251 txb = kmalloc(
252 sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
253 gfp_mask);
254 if (!txb)
255 return NULL;
256
257 memset(txb, 0, sizeof(struct ieee80211_txb));
258 txb->nr_frags = nr_frags;
259 txb->frag_size = txb_size;
260
261 for (i = 0; i < nr_frags; i++) {
262 txb->fragments[i] = dev_alloc_skb(txb_size);
263 if (unlikely(!txb->fragments[i])) {
264 i--;
265 break;
266 }
267 memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
268 }
269 if (unlikely(i != nr_frags)) {
270 while (i >= 0)
271 dev_kfree_skb_any(txb->fragments[i--]);
272 kfree(txb);
273 return NULL;
274 }
275 return txb;
276 }
277
278 // Classify the to-be send data packet
279 // Need to acquire the sent queue index.
280 static int
281 ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
282 {
283 struct ethhdr *eth;
284 struct iphdr *ip;
285 eth = (struct ethhdr *)skb->data;
286 if (eth->h_proto != htons(ETH_P_IP))
287 return 0;
288
289 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
290 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
291 ip = ip_hdr(skb);
292 #else
293 ip = (struct iphdr*)(skb->data + sizeof(struct ether_header));
294 #endif
295 switch (ip->tos & 0xfc) {
296 case 0x20:
297 return 2;
298 case 0x40:
299 return 1;
300 case 0x60:
301 return 3;
302 case 0x80:
303 return 4;
304 case 0xa0:
305 return 5;
306 case 0xc0:
307 return 6;
308 case 0xe0:
309 return 7;
310 default:
311 return 0;
312 }
313 }
314
315 #define SN_LESS(a, b) (((a-b)&0x800)!=0)
316 void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
317 {
318 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
319 PTX_TS_RECORD pTxTs = NULL;
320 struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data;
321
322 if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
323 return;
324 if (!IsQoSDataFrame(skb->data))
325 return;
326
327 if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1))
328 return;
329 //check packet and mode later
330 #ifdef TO_DO_LIST
331 if(pTcb->PacketLength >= 4096)
332 return;
333 // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
334 if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
335 return;
336 #endif
337
338 if(pHTInfo->IOTAction & HT_IOT_ACT_TX_NO_AGGREGATION)
339 return;
340
341 #if 1
342 if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
343 {
344 return;
345 }
346 #endif
347 if(pHTInfo->bCurrentAMPDUEnable)
348 {
349 if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
350 {
351 printk("===>can't get TS\n");
352 return;
353 }
354 if (pTxTs->TxAdmittedBARecord.bValid == false)
355 {
356 //as some AP will refuse our action frame until key handshake has been finished. WB
357 if (ieee->wpa_ie_len && (ieee->pairwise_key_type == KEY_TYPE_NA))
358 ;
359 else
360 TsStartAddBaProcess(ieee, pTxTs);
361 goto FORCED_AGG_SETTING;
362 }
363 else if (pTxTs->bUsingBa == false)
364 {
365 if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
366 pTxTs->bUsingBa = true;
367 else
368 goto FORCED_AGG_SETTING;
369 }
370
371 if (ieee->iw_mode == IW_MODE_INFRA)
372 {
373 tcb_desc->bAMPDUEnable = true;
374 tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
375 tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
376 }
377 }
378 FORCED_AGG_SETTING:
379 switch(pHTInfo->ForcedAMPDUMode )
380 {
381 case HT_AGG_AUTO:
382 break;
383
384 case HT_AGG_FORCE_ENABLE:
385 tcb_desc->bAMPDUEnable = true;
386 tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
387 tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
388 break;
389
390 case HT_AGG_FORCE_DISABLE:
391 tcb_desc->bAMPDUEnable = false;
392 tcb_desc->ampdu_density = 0;
393 tcb_desc->ampdu_factor = 0;
394 break;
395
396 }
397 return;
398 }
399
400 extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
401 {
402 tcb_desc->bUseShortPreamble = false;
403 if (tcb_desc->data_rate == 2)
404 {//// 1M can only use Long Preamble. 11B spec
405 return;
406 }
407 else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
408 {
409 tcb_desc->bUseShortPreamble = true;
410 }
411 return;
412 }
413 extern void
414 ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
415 {
416 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
417
418 tcb_desc->bUseShortGI = false;
419
420 if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
421 return;
422
423 if(pHTInfo->bForcedShortGI)
424 {
425 tcb_desc->bUseShortGI = true;
426 return;
427 }
428
429 if((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz)
430 tcb_desc->bUseShortGI = true;
431 else if((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz)
432 tcb_desc->bUseShortGI = true;
433 }
434
435 void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
436 {
437 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
438
439 tcb_desc->bPacketBW = false;
440
441 if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
442 return;
443
444 if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
445 return;
446
447 if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
448 return;
449 //BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
450 if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
451 tcb_desc->bPacketBW = true;
452 return;
453 }
454
455 void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
456 {
457 // Common Settings
458 tcb_desc->bRTSSTBC = false;
459 tcb_desc->bRTSUseShortGI = false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
460 tcb_desc->bCTSEnable = false; // Most of protection using RTS/CTS
461 tcb_desc->RTSSC = 0; // 20MHz: Don't care; 40MHz: Duplicate.
462 tcb_desc->bRTSBW = false; // RTS frame bandwidth is always 20MHz
463
464 if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
465 return;
466
467 if (is_broadcast_ether_addr(skb->data+16)) //check addr3 as infrastructure add3 is DA.
468 return;
469
470 if (ieee->mode < IEEE_N_24G) //b, g mode
471 {
472 // (1) RTS_Threshold is compared to the MPDU, not MSDU.
473 // (2) If there are more than one frag in this MSDU, only the first frag uses protection frame.
474 // Other fragments are protected by previous fragment.
475 // So we only need to check the length of first fragment.
476 if (skb->len > ieee->rts)
477 {
478 tcb_desc->bRTSEnable = true;
479 tcb_desc->rts_rate = MGN_24M;
480 }
481 else if (ieee->current_network.buseprotection)
482 {
483 // Use CTS-to-SELF in protection mode.
484 tcb_desc->bRTSEnable = true;
485 tcb_desc->bCTSEnable = true;
486 tcb_desc->rts_rate = MGN_24M;
487 }
488 //otherwise return;
489 return;
490 }
491 else
492 {// 11n High throughput case.
493 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
494 while (true)
495 {
496 //check IOT action
497 if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
498 {
499 tcb_desc->bCTSEnable = true;
500 tcb_desc->rts_rate = MGN_24M;
501 #if defined(RTL8192SE) || defined(RTL8192SU)
502 tcb_desc->bRTSEnable = false;
503 #else
504 tcb_desc->bRTSEnable = true;
505 #endif
506 break;
507 }
508 else if(pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_PURE_N_MODE))
509 {
510 tcb_desc->bRTSEnable = true;
511 tcb_desc->rts_rate = MGN_24M;
512 break;
513 }
514 //check ERP protection
515 if (ieee->current_network.buseprotection)
516 {// CTS-to-SELF
517 tcb_desc->bRTSEnable = true;
518 tcb_desc->bCTSEnable = true;
519 tcb_desc->rts_rate = MGN_24M;
520 break;
521 }
522 //check HT op mode
523 if(pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT)
524 {
525 u8 HTOpMode = pHTInfo->CurrentOpMode;
526 if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
527 (!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
528 {
529 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
530 tcb_desc->bRTSEnable = true;
531 break;
532 }
533 }
534 //check rts
535 if (skb->len > ieee->rts)
536 {
537 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
538 tcb_desc->bRTSEnable = true;
539 break;
540 }
541 //to do list: check MIMO power save condition.
542 //check AMPDU aggregation for TXOP
543 if(tcb_desc->bAMPDUEnable)
544 {
545 tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
546 // According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
547 // throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
548 tcb_desc->bRTSEnable = false;
549 break;
550 }
551 // Totally no protection case!!
552 goto NO_PROTECTION;
553 }
554 }
555 // For test , CTS replace with RTS
556 if( 0 )
557 {
558 tcb_desc->bCTSEnable = true;
559 tcb_desc->rts_rate = MGN_24M;
560 tcb_desc->bRTSEnable = true;
561 }
562 if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
563 tcb_desc->bUseShortPreamble = true;
564 if (ieee->mode == IW_MODE_MASTER)
565 goto NO_PROTECTION;
566 return;
567 NO_PROTECTION:
568 tcb_desc->bRTSEnable = false;
569 tcb_desc->bCTSEnable = false;
570 tcb_desc->rts_rate = 0;
571 tcb_desc->RTSSC = 0;
572 tcb_desc->bRTSBW = false;
573 }
574
575
576 void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
577 {
578 #ifdef TO_DO_LIST
579 if(!IsDataFrame(pFrame))
580 {
581 pTcb->bTxDisableRateFallBack = TRUE;
582 pTcb->bTxUseDriverAssingedRate = TRUE;
583 pTcb->RATRIndex = 7;
584 return;
585 }
586
587 if(pMgntInfo->ForcedDataRate!= 0)
588 {
589 pTcb->bTxDisableRateFallBack = TRUE;
590 pTcb->bTxUseDriverAssingedRate = TRUE;
591 return;
592 }
593 #endif
594 if(ieee->bTxDisableRateFallBack)
595 tcb_desc->bTxDisableRateFallBack = true;
596
597 if(ieee->bTxUseDriverAssingedRate)
598 tcb_desc->bTxUseDriverAssingedRate = true;
599 if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
600 {
601 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
602 tcb_desc->RATRIndex = 0;
603 }
604 }
605
606 void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst)
607 {
608 if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
609 return;
610 if (IsQoSDataFrame(skb->data)) //we deal qos data only
611 {
612 PTX_TS_RECORD pTS = NULL;
613 if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true))
614 {
615 return;
616 }
617 pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
618 }
619 }
620
621 int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
622 {
623 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
624 struct ieee80211_device *ieee = netdev_priv(dev);
625 #else
626 struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
627 #endif
628 struct ieee80211_txb *txb = NULL;
629 struct ieee80211_hdr_3addrqos *frag_hdr;
630 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
631 unsigned long flags;
632 struct net_device_stats *stats = &ieee->stats;
633 int ether_type = 0, encrypt;
634 int bytes, fc, qos_ctl = 0, hdr_len;
635 struct sk_buff *skb_frag;
636 struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
637 .duration_id = 0,
638 .seq_ctl = 0,
639 .qos_ctl = 0
640 };
641 u8 dest[ETH_ALEN], src[ETH_ALEN];
642 int qos_actived = ieee->current_network.qos_data.active;
643
644 struct ieee80211_crypt_data* crypt;
645
646 cb_desc *tcb_desc;
647
648 spin_lock_irqsave(&ieee->lock, flags);
649
650 /* If there is no driver handler to take the TXB, dont' bother
651 * creating it... */
652 if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
653 ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
654 printk(KERN_WARNING "%s: No xmit handler.\n",
655 ieee->dev->name);
656 goto success;
657 }
658
659
660 if(likely(ieee->raw_tx == 0)){
661 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
662 printk(KERN_WARNING "%s: skb too small (%d).\n",
663 ieee->dev->name, skb->len);
664 goto success;
665 }
666
667 memset(skb->cb, 0, sizeof(skb->cb));
668 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
669
670 crypt = ieee->crypt[ieee->tx_keyidx];
671
672 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
673 ieee->host_encrypt && crypt && crypt->ops;
674
675 if (!encrypt && ieee->ieee802_1x &&
676 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
677 stats->tx_dropped++;
678 goto success;
679 }
680 #ifdef CONFIG_IEEE80211_DEBUG
681 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
682 struct eapol *eap = (struct eapol *)(skb->data +
683 sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
684 IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
685 eap_get_type(eap->type));
686 }
687 #endif
688
689 /* Save source and destination addresses */
690 memcpy(&dest, skb->data, ETH_ALEN);
691 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
692
693 /* Advance the SKB to the start of the payload */
694 skb_pull(skb, sizeof(struct ethhdr));
695
696 /* Determine total amount of storage required for TXB packets */
697 bytes = skb->len + SNAP_SIZE + sizeof(u16);
698
699 if (encrypt)
700 fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
701 else
702
703 fc = IEEE80211_FTYPE_DATA;
704
705 //if(ieee->current_network.QoS_Enable)
706 if(qos_actived)
707 fc |= IEEE80211_STYPE_QOS_DATA;
708 else
709 fc |= IEEE80211_STYPE_DATA;
710
711 if (ieee->iw_mode == IW_MODE_INFRA) {
712 fc |= IEEE80211_FCTL_TODS;
713 /* To DS: Addr1 = BSSID, Addr2 = SA,
714 Addr3 = DA */
715 memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
716 memcpy(&header.addr2, &src, ETH_ALEN);
717 memcpy(&header.addr3, &dest, ETH_ALEN);
718 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
719 /* not From/To DS: Addr1 = DA, Addr2 = SA,
720 Addr3 = BSSID */
721 memcpy(&header.addr1, dest, ETH_ALEN);
722 memcpy(&header.addr2, src, ETH_ALEN);
723 memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
724 }
725
726 header.frame_ctl = cpu_to_le16(fc);
727
728 /* Determine fragmentation size based on destination (multicast
729 * and broadcast are not fragmented) */
730 if (is_multicast_ether_addr(header.addr1) ||
731 is_broadcast_ether_addr(header.addr1)) {
732 frag_size = MAX_FRAG_THRESHOLD;
733 qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
734 }
735 else {
736 frag_size = ieee->fts;//default:392
737 qos_ctl = 0;
738 }
739
740 //if (ieee->current_network.QoS_Enable)
741 if(qos_actived)
742 {
743 hdr_len = IEEE80211_3ADDR_LEN + 2;
744
745 skb->priority = ieee80211_classify(skb, &ieee->current_network);
746 qos_ctl |= skb->priority; //set in the ieee80211_classify
747 header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
748 } else {
749 hdr_len = IEEE80211_3ADDR_LEN;
750 }
751 /* Determine amount of payload per fragment. Regardless of if
752 * this stack is providing the full 802.11 header, one will
753 * eventually be affixed to this fragment -- so we must account for
754 * it when determining the amount of payload space. */
755 bytes_per_frag = frag_size - hdr_len;
756 if (ieee->config &
757 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
758 bytes_per_frag -= IEEE80211_FCS_LEN;
759
760 /* Each fragment may need to have room for encryptiong pre/postfix */
761 if (encrypt)
762 bytes_per_frag -= crypt->ops->extra_prefix_len +
763 crypt->ops->extra_postfix_len;
764
765 /* Number of fragments is the total bytes_per_frag /
766 * payload_per_fragment */
767 nr_frags = bytes / bytes_per_frag;
768 bytes_last_frag = bytes % bytes_per_frag;
769 if (bytes_last_frag)
770 nr_frags++;
771 else
772 bytes_last_frag = bytes_per_frag;
773
774 /* When we allocate the TXB we allocate enough space for the reserve
775 * and full fragment bytes (bytes_per_frag doesn't include prefix,
776 * postfix, header, FCS, etc.) */
777 txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
778 if (unlikely(!txb)) {
779 printk(KERN_WARNING "%s: Could not allocate TXB\n",
780 ieee->dev->name);
781 goto failed;
782 }
783 txb->encrypted = encrypt;
784 txb->payload_size = bytes;
785
786 //if (ieee->current_network.QoS_Enable)
787 if(qos_actived)
788 {
789 txb->queue_index = UP2AC(skb->priority);
790 } else {
791 txb->queue_index = WME_AC_BK;;
792 }
793
794
795
796 for (i = 0; i < nr_frags; i++) {
797 skb_frag = txb->fragments[i];
798 tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
799 if(qos_actived){
800 skb_frag->priority = skb->priority;//UP2AC(skb->priority);
801 tcb_desc->queue_index = UP2AC(skb->priority);
802 } else {
803 skb_frag->priority = WME_AC_BK;
804 tcb_desc->queue_index = WME_AC_BK;
805 }
806 skb_reserve(skb_frag, ieee->tx_headroom);
807
808 if (encrypt){
809 if (ieee->hwsec_active)
810 tcb_desc->bHwSec = 1;
811 else
812 tcb_desc->bHwSec = 0;
813 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
814 }
815 else
816 {
817 tcb_desc->bHwSec = 0;
818 }
819 frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
820 memcpy(frag_hdr, &header, hdr_len);
821
822 /* If this is not the last fragment, then add the MOREFRAGS
823 * bit to the frame control */
824 if (i != nr_frags - 1) {
825 frag_hdr->frame_ctl = cpu_to_le16(
826 fc | IEEE80211_FCTL_MOREFRAGS);
827 bytes = bytes_per_frag;
828
829 } else {
830 /* The last fragment takes the remaining length */
831 bytes = bytes_last_frag;
832 }
833 //if(ieee->current_network.QoS_Enable)
834 if(qos_actived)
835 {
836 // add 1 only indicate to corresponding seq number control 2006/7/12
837 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
838 } else {
839 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
840 }
841
842 /* Put a SNAP header on the first fragment */
843 if (i == 0) {
844 ieee80211_put_snap(
845 skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
846 ether_type);
847 bytes -= SNAP_SIZE + sizeof(u16);
848 }
849
850 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
851
852 /* Advance the SKB... */
853 skb_pull(skb, bytes);
854
855 /* Encryption routine will move the header forward in order
856 * to insert the IV between the header and the payload */
857 if (encrypt)
858 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
859 if (ieee->config &
860 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
861 skb_put(skb_frag, 4);
862 }
863
864 if(qos_actived)
865 {
866 if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
867 ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
868 else
869 ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
870 } else {
871 if (ieee->seq_ctrl[0] == 0xFFF)
872 ieee->seq_ctrl[0] = 0;
873 else
874 ieee->seq_ctrl[0]++;
875 }
876 }else{
877 if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
878 printk(KERN_WARNING "%s: skb too small (%d).\n",
879 ieee->dev->name, skb->len);
880 goto success;
881 }
882
883 txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
884 if(!txb){
885 printk(KERN_WARNING "%s: Could not allocate TXB\n",
886 ieee->dev->name);
887 goto failed;
888 }
889
890 txb->encrypted = 0;
891 txb->payload_size = skb->len;
892 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
893 }
894
895 success:
896 //WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
897 if (txb)
898 {
899 #if 1
900 cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
901 tcb_desc->bTxEnableFwCalcDur = 1;
902 if (is_multicast_ether_addr(header.addr1))
903 tcb_desc->bMulticast = 1;
904 if (is_broadcast_ether_addr(header.addr1))
905 tcb_desc->bBroadcast = 1;
906 ieee80211_txrate_selectmode(ieee, tcb_desc);
907 if ( tcb_desc->bMulticast || tcb_desc->bBroadcast)
908 tcb_desc->data_rate = ieee->basic_rate;
909 else
910 //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
911 tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
912 ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
913 ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
914 ieee80211_query_HTCapShortGI(ieee, tcb_desc);
915 ieee80211_query_BandwidthMode(ieee, tcb_desc);
916 ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
917 ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
918 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len);
919 //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc));
920 #endif
921 }
922 spin_unlock_irqrestore(&ieee->lock, flags);
923 dev_kfree_skb_any(skb);
924 if (txb) {
925 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
926 ieee80211_softmac_xmit(txb, ieee);
927 }else{
928 if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
929 stats->tx_packets++;
930 stats->tx_bytes += txb->payload_size;
931 return 0;
932 }
933 ieee80211_txb_free(txb);
934 }
935 }
936
937 return 0;
938
939 failed:
940 spin_unlock_irqrestore(&ieee->lock, flags);
941 netif_stop_queue(dev);
942 stats->tx_errors++;
943 return 1;
944
945 }
946
947 EXPORT_SYMBOL(ieee80211_txb_free);
This page took 0.051912 seconds and 5 git commands to generate.