GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / rtl8187se / ieee80211 / ieee80211_tx.c
blobf43750a82a26a528ca8ed7e1956f60433805fb18
1 /******************************************************************************
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
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.
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.
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.
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
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
25 ******************************************************************************
27 Few modifications for Realtek's Wi-Fi drivers by
28 Andrea Merello <andreamrl@tiscali.it>
30 A special thanks goes to Realtek for their support !
32 ******************************************************************************/
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/wireless.h>
51 #include <linux/etherdevice.h>
52 #include <asm/uaccess.h>
53 #include <linux/if_vlan.h>
55 #include "ieee80211.h"
61 802.11 Data Frame
64 802.11 frame_contorl for data frames - 2 bytes
65 ,-----------------------------------------------------------------------------------------.
66 bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
67 |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
68 val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
69 |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
70 desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
71 | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
72 '-----------------------------------------------------------------------------------------'
75 802.11 Data Frame |
76 ,--------- 'ctrl' expands to >-----------'
78 ,--'---,-------------------------------------------------------------.
79 Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
80 |------|------|---------|---------|---------|------|---------|------|
81 Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
82 | | tion | (BSSID) | | | ence | data | |
83 `--------------------------------------------------| |------'
84 Total: 28 non-data bytes `----.----'
86 .- 'Frame data' expands to <---------------------------'
89 ,---------------------------------------------------.
90 Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
91 |------|------|---------|----------|------|---------|
92 Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
93 | DSAP | SSAP | | | | Packet |
94 | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
95 `-----------------------------------------| |
96 Total: 8 non-data bytes `----.----'
98 .- 'IP Packet' expands, if WEP enabled, to <--'
101 ,-----------------------.
102 Bytes | 4 | 0-2296 | 4 |
103 |-----|-----------|-----|
104 Desc. | IV | Encrypted | ICV |
105 | | IP Packet | |
106 `-----------------------'
107 Total: 8 non-data bytes
110 802.3 Ethernet Data Frame
112 ,-----------------------------------------.
113 Bytes | 6 | 6 | 2 | Variable | 4 |
114 |-------|-------|------|-----------|------|
115 Desc. | Dest. | Source| Type | IP Packet | fcs |
116 | MAC | MAC | | | |
117 `-----------------------------------------'
118 Total: 18 non-data bytes
120 In the event that fragmentation is required, the incoming payload is split into
121 N parts of size ieee->fts. The first fragment contains the SNAP header and the
122 remaining packets are just data.
124 If encryption is enabled, each fragment payload size is reduced by enough space
125 to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
126 So if you have 1500 bytes of payload with ieee->fts set to 500 without
127 encryption it will take 3 frames. With WEP it will take 4 frames as the
128 payload of each frame is reduced to 492 bytes.
130 * SKB visualization
132 * ,- skb->data
134 * | ETHERNET HEADER ,-<-- PAYLOAD
135 * | | 14 bytes from skb->data
136 * | 2 bytes for Type --> ,T. | (sizeof ethhdr)
137 * | | | |
138 * |,-Dest.--. ,--Src.---. | | |
139 * | 6 bytes| | 6 bytes | | | |
140 * v | | | | | |
141 * 0 | v 1 | v | v 2
142 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
143 * ^ | ^ | ^ |
144 * | | | | | |
145 * | | | | `T' <---- 2 bytes for Type
146 * | | | |
147 * | | '---SNAP--' <-------- 6 bytes for SNAP
148 * | |
149 * `-IV--' <-------------------- 4 bytes for IV (WEP)
151 * SNAP HEADER
155 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
156 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
158 static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
160 struct ieee80211_snap_hdr *snap;
161 u8 *oui;
163 snap = (struct ieee80211_snap_hdr *)data;
164 snap->dsap = 0xaa;
165 snap->ssap = 0xaa;
166 snap->ctrl = 0x03;
168 if (h_proto == 0x8137 || h_proto == 0x80f3)
169 oui = P802_1H_OUI;
170 else
171 oui = RFC1042_OUI;
172 snap->oui[0] = oui[0];
173 snap->oui[1] = oui[1];
174 snap->oui[2] = oui[2];
176 *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
178 return SNAP_SIZE + sizeof(u16);
181 int ieee80211_encrypt_fragment(
182 struct ieee80211_device *ieee,
183 struct sk_buff *frag,
184 int hdr_len)
186 struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
187 int res;
189 /*added to care about null crypt condition, to solve that system hangs when shared keys error*/
190 if (!crypt || !crypt->ops)
191 return -1;
193 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
194 struct ieee80211_hdr_4addr *header;
196 if (ieee->tkip_countermeasures &&
197 crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
198 header = (struct ieee80211_hdr_4addr *)frag->data;
199 if (net_ratelimit()) {
200 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
201 "TX packet to %pM\n",
202 ieee->dev->name, header->addr1);
204 return -1;
206 #endif
207 /* To encrypt, frame format is:
208 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
210 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
211 * call both MSDU and MPDU encryption functions from here. */
212 atomic_inc(&crypt->refcnt);
213 res = 0;
214 if (crypt->ops->encrypt_msdu)
215 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
216 if (res == 0 && crypt->ops->encrypt_mpdu)
217 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
219 atomic_dec(&crypt->refcnt);
220 if (res < 0) {
221 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
222 ieee->dev->name, frag->len);
223 ieee->ieee_stats.tx_discards++;
224 return -1;
227 return 0;
231 void ieee80211_txb_free(struct ieee80211_txb *txb) {
232 int i;
233 if (unlikely(!txb))
234 return;
235 for (i = 0; i < txb->nr_frags; i++)
236 if (txb->fragments[i])
237 dev_kfree_skb_any(txb->fragments[i]);
238 kfree(txb);
241 struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
242 int gfp_mask)
244 struct ieee80211_txb *txb;
245 int i;
246 txb = kmalloc(
247 sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
248 gfp_mask);
249 if (!txb)
250 return NULL;
252 memset(txb, 0, sizeof(struct ieee80211_txb));
253 txb->nr_frags = nr_frags;
254 txb->frag_size = txb_size;
256 for (i = 0; i < nr_frags; i++) {
257 txb->fragments[i] = dev_alloc_skb(txb_size);
258 if (unlikely(!txb->fragments[i])) {
259 i--;
260 break;
263 if (unlikely(i != nr_frags)) {
264 while (i >= 0)
265 dev_kfree_skb_any(txb->fragments[i--]);
266 kfree(txb);
267 return NULL;
269 return txb;
272 // Classify the to-be send data packet
273 // Need to acquire the sent queue index.
274 static int
275 ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
277 struct ether_header *eh = (struct ether_header*)skb->data;
278 unsigned int wme_UP = 0;
280 if(!network->QoS_Enable) {
281 skb->priority = 0;
282 return(wme_UP);
285 if(eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
286 const struct iphdr *ih = (struct iphdr*)(skb->data + \
287 sizeof(struct ether_header));
288 wme_UP = (ih->tos >> 5)&0x07;
289 } else if (vlan_tx_tag_present(skb)) {//vtag packet
290 #ifndef VLAN_PRI_SHIFT
291 #define VLAN_PRI_SHIFT 13 /* Shift to find VLAN user priority */
292 #define VLAN_PRI_MASK 7 /* Mask for user priority bits in VLAN */
293 #endif
294 u32 tag = vlan_tx_tag_get(skb);
295 wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
296 } else if(ETH_P_PAE == ntohs(((struct ethhdr *)skb->data)->h_proto)) {
297 //printk(KERN_WARNING "type = normal packet\n");
298 wme_UP = 7;
301 skb->priority = wme_UP;
302 return(wme_UP);
305 /* SKBs are added to the ieee->tx_queue. */
306 int ieee80211_rtl_xmit(struct sk_buff *skb,
307 struct net_device *dev)
309 struct ieee80211_device *ieee = netdev_priv(dev);
310 struct ieee80211_txb *txb = NULL;
311 struct ieee80211_hdr_3addrqos *frag_hdr;
312 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
313 unsigned long flags;
314 struct net_device_stats *stats = &ieee->stats;
315 int ether_type, encrypt;
316 int bytes, fc, qos_ctl, hdr_len;
317 struct sk_buff *skb_frag;
318 struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
319 .duration_id = 0,
320 .seq_ctl = 0,
321 .qos_ctl = 0
323 u8 dest[ETH_ALEN], src[ETH_ALEN];
325 struct ieee80211_crypt_data* crypt;
327 //printk(KERN_WARNING "upper layer packet!\n");
328 spin_lock_irqsave(&ieee->lock, flags);
330 /* If there is no driver handler to take the TXB, dont' bother
331 * creating it... */
332 if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
333 ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
334 printk(KERN_WARNING "%s: No xmit handler.\n",
335 ieee->dev->name);
336 goto success;
339 ieee80211_classify(skb,&ieee->current_network);
340 if(likely(ieee->raw_tx == 0)){
342 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
343 printk(KERN_WARNING "%s: skb too small (%d).\n",
344 ieee->dev->name, skb->len);
345 goto success;
348 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
350 crypt = ieee->crypt[ieee->tx_keyidx];
352 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
353 ieee->host_encrypt && crypt && crypt->ops;
355 if (!encrypt && ieee->ieee802_1x &&
356 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
357 stats->tx_dropped++;
358 goto success;
361 #ifdef CONFIG_IEEE80211_DEBUG
362 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
363 struct eapol *eap = (struct eapol *)(skb->data +
364 sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
365 IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
366 eap_get_type(eap->type));
368 #endif
370 /* Save source and destination addresses */
371 memcpy(&dest, skb->data, ETH_ALEN);
372 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
374 /* Advance the SKB to the start of the payload */
375 skb_pull(skb, sizeof(struct ethhdr));
377 /* Determine total amount of storage required for TXB packets */
378 bytes = skb->len + SNAP_SIZE + sizeof(u16);
380 if(ieee->current_network.QoS_Enable) {
381 if (encrypt)
382 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
383 IEEE80211_FCTL_WEP;
384 else
385 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
387 } else {
388 if (encrypt)
389 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
390 IEEE80211_FCTL_WEP;
391 else
392 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
395 if (ieee->iw_mode == IW_MODE_INFRA) {
396 fc |= IEEE80211_FCTL_TODS;
397 /* To DS: Addr1 = BSSID, Addr2 = SA,
398 Addr3 = DA */
399 memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
400 memcpy(&header.addr2, &src, ETH_ALEN);
401 memcpy(&header.addr3, &dest, ETH_ALEN);
402 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
403 /* not From/To DS: Addr1 = DA, Addr2 = SA,
404 Addr3 = BSSID */
405 memcpy(&header.addr1, dest, ETH_ALEN);
406 memcpy(&header.addr2, src, ETH_ALEN);
407 memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
409 // printk(KERN_WARNING "essid MAC address is %pM", &header.addr1);
410 header.frame_ctl = cpu_to_le16(fc);
411 //hdr_len = IEEE80211_3ADDR_LEN;
413 /* Determine fragmentation size based on destination (multicast
414 * and broadcast are not fragmented) */
415 // if (is_multicast_ether_addr(dest) ||
416 // is_broadcast_ether_addr(dest)) {
417 if (is_multicast_ether_addr(header.addr1) ||
418 is_broadcast_ether_addr(header.addr1)) {
419 frag_size = MAX_FRAG_THRESHOLD;
420 qos_ctl = QOS_CTL_NOTCONTAIN_ACK;
422 else {
423 //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
424 frag_size = ieee->fts;//default:392
425 qos_ctl = 0;
428 if (ieee->current_network.QoS_Enable) {
429 hdr_len = IEEE80211_3ADDR_LEN + 2;
430 /* skb->priority is set in the ieee80211_classify() */
431 qos_ctl |= skb->priority;
432 header.qos_ctl = cpu_to_le16(qos_ctl);
433 } else {
434 hdr_len = IEEE80211_3ADDR_LEN;
437 /* Determine amount of payload per fragment. Regardless of if
438 * this stack is providing the full 802.11 header, one will
439 * eventually be affixed to this fragment -- so we must account for
440 * it when determining the amount of payload space. */
441 //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
442 bytes_per_frag = frag_size - hdr_len;
443 if (ieee->config &
444 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
445 bytes_per_frag -= IEEE80211_FCS_LEN;
447 /* Each fragment may need to have room for encryptiong pre/postfix */
448 if (encrypt)
449 bytes_per_frag -= crypt->ops->extra_prefix_len +
450 crypt->ops->extra_postfix_len;
452 /* Number of fragments is the total bytes_per_frag /
453 * payload_per_fragment */
454 nr_frags = bytes / bytes_per_frag;
455 bytes_last_frag = bytes % bytes_per_frag;
456 if (bytes_last_frag)
457 nr_frags++;
458 else
459 bytes_last_frag = bytes_per_frag;
461 /* When we allocate the TXB we allocate enough space for the reserve
462 * and full fragment bytes (bytes_per_frag doesn't include prefix,
463 * postfix, header, FCS, etc.) */
464 txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
465 if (unlikely(!txb)) {
466 printk(KERN_WARNING "%s: Could not allocate TXB\n",
467 ieee->dev->name);
468 goto failed;
470 txb->encrypted = encrypt;
471 txb->payload_size = bytes;
473 for (i = 0; i < nr_frags; i++) {
474 skb_frag = txb->fragments[i];
475 skb_frag->priority = UP2AC(skb->priority);
476 if (encrypt)
477 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
479 frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
480 memcpy(frag_hdr, &header, hdr_len);
482 /* If this is not the last fragment, then add the MOREFRAGS
483 * bit to the frame control */
484 if (i != nr_frags - 1) {
485 frag_hdr->frame_ctl = cpu_to_le16(
486 fc | IEEE80211_FCTL_MOREFRAGS);
487 bytes = bytes_per_frag;
489 } else {
490 /* The last fragment takes the remaining length */
491 bytes = bytes_last_frag;
493 if(ieee->current_network.QoS_Enable) {
494 // add 1 only indicate to corresponding seq number control 2006/7/12
495 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
496 //printk(KERN_WARNING "skb->priority = %d,", skb->priority);
497 //printk(KERN_WARNING "type:%d: seq = %d\n",UP2AC(skb->priority),ieee->seq_ctrl[UP2AC(skb->priority)+1]);
498 } else {
499 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
501 //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
504 /* Put a SNAP header on the first fragment */
505 if (i == 0) {
506 ieee80211_put_snap(
507 skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
508 ether_type);
509 bytes -= SNAP_SIZE + sizeof(u16);
512 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
514 /* Advance the SKB... */
515 skb_pull(skb, bytes);
517 /* Encryption routine will move the header forward in order
518 * to insert the IV between the header and the payload */
519 if (encrypt)
520 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
521 if (ieee->config &
522 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
523 skb_put(skb_frag, 4);
525 // Advance sequence number in data frame.
526 //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
527 if (ieee->current_network.QoS_Enable) {
528 if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
529 ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
530 else
531 ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
532 } else {
533 if (ieee->seq_ctrl[0] == 0xFFF)
534 ieee->seq_ctrl[0] = 0;
535 else
536 ieee->seq_ctrl[0]++;
538 //---
539 }else{
540 if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
541 printk(KERN_WARNING "%s: skb too small (%d).\n",
542 ieee->dev->name, skb->len);
543 goto success;
546 txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
547 if(!txb){
548 printk(KERN_WARNING "%s: Could not allocate TXB\n",
549 ieee->dev->name);
550 goto failed;
553 txb->encrypted = 0;
554 txb->payload_size = skb->len;
555 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
558 success:
559 spin_unlock_irqrestore(&ieee->lock, flags);
560 dev_kfree_skb_any(skb);
561 if (txb) {
562 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
563 ieee80211_softmac_xmit(txb, ieee);
564 }else{
565 if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
566 stats->tx_packets++;
567 stats->tx_bytes += txb->payload_size;
568 return NETDEV_TX_OK;
570 ieee80211_txb_free(txb);
574 return NETDEV_TX_OK;
576 failed:
577 spin_unlock_irqrestore(&ieee->lock, flags);
578 netif_stop_queue(dev);
579 stats->tx_errors++;
580 return NETDEV_TX_BUSY;