added 2.6.29.6 aldebaran kernel
[nao-ulib.git] / kernel / 2.6.29.6-aldebaran-rt / drivers / staging / rtl8187se / ieee80211 / ieee80211_tx.c
blob33a0687252afa4973000226f388bff2b3d179e55
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/version.h>
51 #include <linux/wireless.h>
52 #include <linux/etherdevice.h>
53 #include <asm/uaccess.h>
54 #include <linux/if_vlan.h>
56 #include "ieee80211.h"
62 802.11 Data Frame
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 '-----------------------------------------------------------------------------------------'
76 802.11 Data Frame |
77 ,--------- 'ctrl' expands to >-----------'
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 `----.----'
87 .- 'Frame data' expands to <---------------------------'
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 `----.----'
99 .- 'IP Packet' expands, if WEP enabled, to <--'
102 ,-----------------------.
103 Bytes | 4 | 0-2296 | 4 |
104 |-----|-----------|-----|
105 Desc. | IV | Encrypted | ICV |
106 | | IP Packet | |
107 `-----------------------'
108 Total: 8 non-data bytes
111 802.3 Ethernet Data Frame
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
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.
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.
131 * SKB visualization
133 * ,- skb->data
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)
152 * SNAP HEADER
156 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
157 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
159 static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
161 struct ieee80211_snap_hdr *snap;
162 u8 *oui;
164 snap = (struct ieee80211_snap_hdr *)data;
165 snap->dsap = 0xaa;
166 snap->ssap = 0xaa;
167 snap->ctrl = 0x03;
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];
177 *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
179 return SNAP_SIZE + sizeof(u16);
182 int ieee80211_encrypt_fragment(
183 struct ieee80211_device *ieee,
184 struct sk_buff *frag,
185 int hdr_len)
187 struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
188 int res;
190 /*added to care about null crypt condition, to solve that system hangs when shared keys error*/
191 if (!crypt || !crypt->ops)
192 return -1;
194 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
195 struct ieee80211_hdr *header;
197 if (ieee->tkip_countermeasures &&
198 crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
199 header = (struct ieee80211_hdr *) frag->data;
200 if (net_ratelimit()) {
201 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
202 "TX packet to " MAC_FMT "\n",
203 ieee->dev->name, MAC_ARG(header->addr1));
205 return -1;
207 #endif
208 /* To encrypt, frame format is:
209 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
211 // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
212 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
213 * call both MSDU and MPDU encryption functions from here. */
214 atomic_inc(&crypt->refcnt);
215 res = 0;
216 if (crypt->ops->encrypt_msdu)
217 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
218 if (res == 0 && crypt->ops->encrypt_mpdu)
219 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
221 atomic_dec(&crypt->refcnt);
222 if (res < 0) {
223 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
224 ieee->dev->name, frag->len);
225 ieee->ieee_stats.tx_discards++;
226 return -1;
229 return 0;
233 void ieee80211_txb_free(struct ieee80211_txb *txb) {
234 int i;
235 if (unlikely(!txb))
236 return;
237 for (i = 0; i < txb->nr_frags; i++)
238 if (txb->fragments[i])
239 dev_kfree_skb_any(txb->fragments[i]);
240 kfree(txb);
243 struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
244 int gfp_mask)
246 struct ieee80211_txb *txb;
247 int i;
248 txb = kmalloc(
249 sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
250 gfp_mask);
251 if (!txb)
252 return NULL;
254 memset(txb, 0, sizeof(struct ieee80211_txb));
255 txb->nr_frags = nr_frags;
256 txb->frag_size = txb_size;
258 for (i = 0; i < nr_frags; i++) {
259 txb->fragments[i] = dev_alloc_skb(txb_size);
260 if (unlikely(!txb->fragments[i])) {
261 i--;
262 break;
265 if (unlikely(i != nr_frags)) {
266 while (i >= 0)
267 dev_kfree_skb_any(txb->fragments[i--]);
268 kfree(txb);
269 return NULL;
271 return txb;
274 // Classify the to-be send data packet
275 // Need to acquire the sent queue index.
276 static int
277 ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
279 struct ether_header *eh = (struct ether_header*)skb->data;
280 unsigned int wme_UP = 0;
282 if(!network->QoS_Enable) {
283 skb->priority = 0;
284 return(wme_UP);
287 if(eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
288 const struct iphdr *ih = (struct iphdr*)(skb->data + \
289 sizeof(struct ether_header));
290 wme_UP = (ih->tos >> 5)&0x07;
291 } else if (vlan_tx_tag_present(skb)) {//vtag packet
292 #ifndef VLAN_PRI_SHIFT
293 #define VLAN_PRI_SHIFT 13 /* Shift to find VLAN user priority */
294 #define VLAN_PRI_MASK 7 /* Mask for user priority bits in VLAN */
295 #endif
296 u32 tag = vlan_tx_tag_get(skb);
297 wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
298 } else if(ETH_P_PAE == ntohs(((struct ethhdr *)skb->data)->h_proto)) {
299 //printk(KERN_WARNING "type = normal packet\n");
300 wme_UP = 7;
303 skb->priority = wme_UP;
304 return(wme_UP);
307 #ifdef _RTL8187_EXT_PATCH_
308 // based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
309 struct ieee80211_txb *ieee80211_ext_alloc_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt)
311 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
312 struct ieee80211_device *ieee = netdev_priv(dev);
313 #else
314 struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
315 #endif
316 struct ieee80211_txb *txb = NULL;
317 struct ieee80211_hdr_3addr *frag_hdr;
318 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
319 int ether_type;
320 int bytes, QOS_ctl;
321 struct sk_buff *skb_frag;
323 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
325 /* Advance the SKB to the start of the payload */
326 skb_pull(skb, sizeof(struct ethhdr));
328 /* Determine total amount of storage required for TXB packets */
329 bytes = skb->len + SNAP_SIZE + sizeof(u16);
331 /* Determine fragmentation size based on destination (multicast
332 * and broadcast are not fragmented) */
333 // if (is_multicast_ether_addr(dest) ||
334 // is_broadcast_ether_addr(dest)) {
335 if (is_multicast_ether_addr(header->addr1) ||
336 is_broadcast_ether_addr(header->addr1)) {
337 frag_size = MAX_FRAG_THRESHOLD;
338 QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
340 else {
341 //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
342 frag_size = ieee->fts;//default:392
343 QOS_ctl = 0;
346 if(isQoS) {
347 QOS_ctl |= skb->priority; //set in the ieee80211_classify
348 *pQOS_ctl = cpu_to_le16(QOS_ctl);
350 //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
351 /* Determine amount of payload per fragment. Regardless of if
352 * this stack is providing the full 802.11 header, one will
353 * eventually be affixed to this fragment -- so we must account for
354 * it when determining the amount of payload space. */
355 //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
356 bytes_per_frag = frag_size - hdr_len;
357 if (ieee->config &
358 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
359 bytes_per_frag -= IEEE80211_FCS_LEN;
361 /* Each fragment may need to have room for encryptiong pre/postfix */
362 if (isEncrypt)
363 bytes_per_frag -= crypt->ops->extra_prefix_len +
364 crypt->ops->extra_postfix_len;
366 /* Number of fragments is the total bytes_per_frag /
367 * payload_per_fragment */
368 nr_frags = bytes / bytes_per_frag;
369 bytes_last_frag = bytes % bytes_per_frag;
370 if (bytes_last_frag)
371 nr_frags++;
372 else
373 bytes_last_frag = bytes_per_frag;
375 /* When we allocate the TXB we allocate enough space for the reserve
376 * and full fragment bytes (bytes_per_frag doesn't include prefix,
377 * postfix, header, FCS, etc.) */
378 txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
379 if (unlikely(!txb)) {
380 printk(KERN_WARNING "%s: Could not allocate TXB\n",
381 ieee->dev->name);
382 return NULL;
384 txb->encrypted = isEncrypt;
385 txb->payload_size = bytes;
387 for (i = 0; i < nr_frags; i++) {
388 skb_frag = txb->fragments[i];
389 skb_frag->priority = UP2AC(skb->priority);
390 if (isEncrypt)
391 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
393 frag_hdr = (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
394 memcpy(frag_hdr, (void *)header, hdr_len);
396 /* If this is not the last fragment, then add the MOREFRAGS
397 * bit to the frame control */
398 if (i != nr_frags - 1) {
399 frag_hdr->frame_ctl = cpu_to_le16(
400 header->frame_ctl | IEEE80211_FCTL_MOREFRAGS);
401 bytes = bytes_per_frag;
403 } else {
404 /* The last fragment takes the remaining length */
405 bytes = bytes_last_frag;
408 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
409 //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
412 /* Put a SNAP header on the first fragment */
413 if (i == 0) {
414 ieee80211_put_snap(
415 skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), ether_type);
416 bytes -= SNAP_SIZE + sizeof(u16);
419 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
421 /* Advance the SKB... */
422 skb_pull(skb, bytes);
424 /* Encryption routine will move the header forward in order
425 * to insert the IV between the header and the payload */
426 if (isEncrypt)
427 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
428 if (ieee->config &
429 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
430 skb_put(skb_frag, 4);
432 // Advance sequence number in data frame.
433 //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
434 if (ieee->seq_ctrl[0] == 0xFFF)
435 ieee->seq_ctrl[0] = 0;
436 else
437 ieee->seq_ctrl[0]++;
438 // stanley, just for debug
441 int j=0;
442 for(j=0;j<nr_frags;j++)
444 int i;
445 struct sk_buff *skb = txb->fragments[j];
446 printk("send(%d): ", j);
447 for (i=0;i<skb->len;i++)
448 printk("%02X ", skb->data[i]&0xff);
449 printk("\n");
454 return txb;
458 // based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
459 // Assume no encryption, no FCS computing
460 struct ieee80211_txb *ieee80211_ext_reuse_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt)
462 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
463 struct ieee80211_device *ieee = netdev_priv(dev);
464 #else
465 struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
466 #endif
467 struct ieee80211_txb *txb = NULL;
468 struct ieee80211_hdr_3addr *frag_hdr;
469 int ether_type;
470 int bytes, QOS_ctl;
472 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
474 /* Advance the SKB to the start of the payload */
475 skb_pull(skb, sizeof(struct ethhdr));
477 /* Determine total amount of storage required for TXB packets */
478 bytes = skb->len + SNAP_SIZE + sizeof(u16);
480 if (is_multicast_ether_addr(header->addr1) ||
481 is_broadcast_ether_addr(header->addr1)) {
482 QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
484 else {
485 QOS_ctl = 0;
488 if(isQoS) {
489 QOS_ctl |= skb->priority; //set in the ieee80211_classify
490 *pQOS_ctl = cpu_to_le16(QOS_ctl);
493 txb = kmalloc( sizeof(struct ieee80211_txb) + sizeof(u8*), GFP_ATOMIC );
494 if (unlikely(!txb)) {
495 printk(KERN_WARNING "%s: Could not allocate TXB\n",
496 ieee->dev->name);
497 return NULL;
500 txb->nr_frags = 1;
501 txb->frag_size = bytes;
502 txb->encrypted = isEncrypt;
503 txb->payload_size = bytes;
505 txb->fragments[0] = skb;
506 ieee80211_put_snap(
507 skb_push(skb, SNAP_SIZE + sizeof(u16)), ether_type);
508 frag_hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, hdr_len);
509 memcpy(frag_hdr, (void *)header, hdr_len);
510 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | 0);
511 skb->priority = UP2AC(skb->priority);
513 // Advance sequence number in data frame.
514 //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
515 if (ieee->seq_ctrl[0] == 0xFFF)
516 ieee->seq_ctrl[0] = 0;
517 else
518 ieee->seq_ctrl[0]++;
520 return txb;
523 #endif // _RTL8187_EXT_PATCH_
525 /* SKBs are added to the ieee->tx_queue. */
526 int ieee80211_xmit(struct sk_buff *skb,
527 struct net_device *dev)
529 struct ieee80211_device *ieee = netdev_priv(dev);
530 struct ieee80211_txb *txb = NULL;
531 struct ieee80211_hdr_3addr_QOS *frag_hdr;
532 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
533 unsigned long flags;
534 struct net_device_stats *stats = &ieee->stats;
535 int ether_type, encrypt;
536 int bytes, fc, QOS_ctl, hdr_len;
537 struct sk_buff *skb_frag;
538 //struct ieee80211_hdr header = { /* Ensure zero initialized */
539 // .duration_id = 0,
540 // .seq_ctl = 0
541 //};
542 struct ieee80211_hdr_3addr_QOS header = { /* Ensure zero initialized */
543 .duration_id = 0,
544 .seq_ctl = 0,
545 .QOS_ctl = 0
547 u8 dest[ETH_ALEN], src[ETH_ALEN];
549 struct ieee80211_crypt_data* crypt;
551 //printk(KERN_WARNING "upper layer packet!\n");
552 spin_lock_irqsave(&ieee->lock, flags);
554 /* If there is no driver handler to take the TXB, dont' bother
555 * creating it... */
556 if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
557 ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
558 printk(KERN_WARNING "%s: No xmit handler.\n",
559 ieee->dev->name);
560 goto success;
563 ieee80211_classify(skb,&ieee->current_network);
564 if(likely(ieee->raw_tx == 0)){
566 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
567 printk(KERN_WARNING "%s: skb too small (%d).\n",
568 ieee->dev->name, skb->len);
569 goto success;
573 #ifdef _RTL8187_EXT_PATCH_
574 // note, skb->priority which was set by ieee80211_classify, and used by physical tx
575 if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_xmit))
577 txb = ieee->ext_patch_ieee80211_xmit(skb, dev);
578 goto success;
580 #endif
582 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
584 crypt = ieee->crypt[ieee->tx_keyidx];
586 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
587 ieee->host_encrypt && crypt && crypt->ops;
589 if (!encrypt && ieee->ieee802_1x &&
590 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
591 stats->tx_dropped++;
592 goto success;
595 #ifdef CONFIG_IEEE80211_DEBUG
596 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
597 struct eapol *eap = (struct eapol *)(skb->data +
598 sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
599 IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
600 eap_get_type(eap->type));
602 #endif
604 /* Save source and destination addresses */
605 memcpy(&dest, skb->data, ETH_ALEN);
606 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
608 /* Advance the SKB to the start of the payload */
609 skb_pull(skb, sizeof(struct ethhdr));
611 /* Determine total amount of storage required for TXB packets */
612 bytes = skb->len + SNAP_SIZE + sizeof(u16);
614 if(ieee->current_network.QoS_Enable) {
615 if (encrypt)
616 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
617 IEEE80211_FCTL_WEP;
618 else
619 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
621 } else {
622 if (encrypt)
623 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
624 IEEE80211_FCTL_WEP;
625 else
626 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
629 if (ieee->iw_mode == IW_MODE_INFRA) {
630 fc |= IEEE80211_FCTL_TODS;
631 /* To DS: Addr1 = BSSID, Addr2 = SA,
632 Addr3 = DA */
633 memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
634 memcpy(&header.addr2, &src, ETH_ALEN);
635 memcpy(&header.addr3, &dest, ETH_ALEN);
636 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
637 /* not From/To DS: Addr1 = DA, Addr2 = SA,
638 Addr3 = BSSID */
639 memcpy(&header.addr1, dest, ETH_ALEN);
640 memcpy(&header.addr2, src, ETH_ALEN);
641 memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
643 // printk(KERN_WARNING "essid MAC address is "MAC_FMT, MAC_ARG(&header.addr1));
644 header.frame_ctl = cpu_to_le16(fc);
645 //hdr_len = IEEE80211_3ADDR_LEN;
647 /* Determine fragmentation size based on destination (multicast
648 * and broadcast are not fragmented) */
649 // if (is_multicast_ether_addr(dest) ||
650 // is_broadcast_ether_addr(dest)) {
651 if (is_multicast_ether_addr(header.addr1) ||
652 is_broadcast_ether_addr(header.addr1)) {
653 frag_size = MAX_FRAG_THRESHOLD;
654 QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
656 else {
657 //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
658 frag_size = ieee->fts;//default:392
659 QOS_ctl = 0;
662 if (ieee->current_network.QoS_Enable) {
663 hdr_len = IEEE80211_3ADDR_LEN + 2;
664 QOS_ctl |= skb->priority; //set in the ieee80211_classify
665 header.QOS_ctl = cpu_to_le16(QOS_ctl);
666 } else {
667 hdr_len = IEEE80211_3ADDR_LEN;
669 //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
670 /* Determine amount of payload per fragment. Regardless of if
671 * this stack is providing the full 802.11 header, one will
672 * eventually be affixed to this fragment -- so we must account for
673 * it when determining the amount of payload space. */
674 //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
675 bytes_per_frag = frag_size - hdr_len;
676 if (ieee->config &
677 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
678 bytes_per_frag -= IEEE80211_FCS_LEN;
680 /* Each fragment may need to have room for encryptiong pre/postfix */
681 if (encrypt)
682 bytes_per_frag -= crypt->ops->extra_prefix_len +
683 crypt->ops->extra_postfix_len;
685 /* Number of fragments is the total bytes_per_frag /
686 * payload_per_fragment */
687 nr_frags = bytes / bytes_per_frag;
688 bytes_last_frag = bytes % bytes_per_frag;
689 if (bytes_last_frag)
690 nr_frags++;
691 else
692 bytes_last_frag = bytes_per_frag;
694 /* When we allocate the TXB we allocate enough space for the reserve
695 * and full fragment bytes (bytes_per_frag doesn't include prefix,
696 * postfix, header, FCS, etc.) */
697 txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
698 if (unlikely(!txb)) {
699 printk(KERN_WARNING "%s: Could not allocate TXB\n",
700 ieee->dev->name);
701 goto failed;
703 txb->encrypted = encrypt;
704 txb->payload_size = bytes;
706 for (i = 0; i < nr_frags; i++) {
707 skb_frag = txb->fragments[i];
708 skb_frag->priority = UP2AC(skb->priority);
709 if (encrypt)
710 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
712 frag_hdr = (struct ieee80211_hdr_3addr_QOS *)skb_put(skb_frag, hdr_len);
713 memcpy(frag_hdr, &header, hdr_len);
715 /* If this is not the last fragment, then add the MOREFRAGS
716 * bit to the frame control */
717 if (i != nr_frags - 1) {
718 frag_hdr->frame_ctl = cpu_to_le16(
719 fc | IEEE80211_FCTL_MOREFRAGS);
720 bytes = bytes_per_frag;
722 } else {
723 /* The last fragment takes the remaining length */
724 bytes = bytes_last_frag;
726 if(ieee->current_network.QoS_Enable) {
727 // add 1 only indicate to corresponding seq number control 2006/7/12
728 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
729 //printk(KERN_WARNING "skb->priority = %d,", skb->priority);
730 //printk(KERN_WARNING "type:%d: seq = %d\n",UP2AC(skb->priority),ieee->seq_ctrl[UP2AC(skb->priority)+1]);
731 } else {
732 frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
734 //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
737 /* Put a SNAP header on the first fragment */
738 if (i == 0) {
739 ieee80211_put_snap(
740 skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
741 ether_type);
742 bytes -= SNAP_SIZE + sizeof(u16);
745 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
747 /* Advance the SKB... */
748 skb_pull(skb, bytes);
750 /* Encryption routine will move the header forward in order
751 * to insert the IV between the header and the payload */
752 if (encrypt)
753 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
754 if (ieee->config &
755 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
756 skb_put(skb_frag, 4);
758 // Advance sequence number in data frame.
759 //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
760 if (ieee->current_network.QoS_Enable) {
761 if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
762 ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
763 else
764 ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
765 } else {
766 if (ieee->seq_ctrl[0] == 0xFFF)
767 ieee->seq_ctrl[0] = 0;
768 else
769 ieee->seq_ctrl[0]++;
771 //---
772 }else{
773 if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
774 printk(KERN_WARNING "%s: skb too small (%d).\n",
775 ieee->dev->name, skb->len);
776 goto success;
779 txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
780 if(!txb){
781 printk(KERN_WARNING "%s: Could not allocate TXB\n",
782 ieee->dev->name);
783 goto failed;
786 txb->encrypted = 0;
787 txb->payload_size = skb->len;
788 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
791 success:
792 spin_unlock_irqrestore(&ieee->lock, flags);
793 #ifdef _RTL8187_EXT_PATCH_
794 // Sometimes, extension mode can reuse skb (by txb->fragments[0])
795 if( ! ((ieee->iw_mode == ieee->iw_ext_mode) && txb && (txb->fragments[0] == skb)) )
796 #endif
797 dev_kfree_skb_any(skb);
798 if (txb) {
799 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
800 ieee80211_softmac_xmit(txb, ieee);
801 }else{
802 if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
803 stats->tx_packets++;
804 stats->tx_bytes += txb->payload_size;
805 return 0;
807 ieee80211_txb_free(txb);
811 return 0;
813 failed:
814 spin_unlock_irqrestore(&ieee->lock, flags);
815 netif_stop_queue(dev);
816 stats->tx_errors++;
817 return 1;
821 #if 0
822 EXPORT_SYMBOL(ieee80211_txb_free);
823 #ifdef _RTL8187_EXT_PATCH_
824 EXPORT_SYMBOL(ieee80211_alloc_txb);
825 EXPORT_SYMBOL(ieee80211_ext_alloc_txb);
826 EXPORT_SYMBOL(ieee80211_ext_reuse_txb);
827 #endif // _RTL8187_EXT_PATCH_
828 #endif