Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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  /*added to care about null crypt condition, to solve that system hangs when shared keys error*/
191         if (!crypt || !crypt->ops)
192         return -1;
193 
194 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
195         struct ieee80211_hdr *header;
196 
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));
204                 }
205                 return -1;
206         }
207 #endif
208         /* To encrypt, frame format is:
209          * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
210 
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);
220 
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;
227         }
228 
229         return 0;
230 }
231 
232 
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);
241 }
242 
243 struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
244                                           int gfp_mask)
245 {
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;
253 
254         memset(txb, 0, sizeof(struct ieee80211_txb));
255         txb->nr_frags = nr_frags;
256         txb->frag_size = txb_size;
257 
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;
263                 }
264         }
265         if (unlikely(i != nr_frags)) {
266                 while (i >= 0)
267                         dev_kfree_skb_any(txb->fragments[i--]);
268                 kfree(txb);
269                 return NULL;
270         }
271         return txb;
272 }
273 
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)
278 {
279   struct ether_header *eh = (struct ether_header*)skb->data;
280   unsigned int wme_UP = 0;
281 
282   if(!network->QoS_Enable) {
283      skb->priority = 0;
284      return(wme_UP);
285   }
286 
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;
301   }
302 
303   skb->priority = wme_UP;
304   return(wme_UP);
305 }
306 
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)
310 {
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;
322 
323         ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
324 
325         /* Advance the SKB to the start of the payload */
326         skb_pull(skb, sizeof(struct ethhdr));
327 
328         /* Determine total amount of storage required for TXB packets */
329         bytes = skb->len + SNAP_SIZE + sizeof(u16);
330 
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;
339         }
340         else {
341                 //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
342                 frag_size = ieee->fts;//default:392
343                 QOS_ctl = 0;
344         }
345 
346         if(isQoS) {
347                 QOS_ctl |= skb->priority; //set in the ieee80211_classify
348                 *pQOS_ctl = cpu_to_le16(QOS_ctl);
349         }
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;
360 
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;
365 
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;
374 
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;
383         }
384         txb->encrypted = isEncrypt;
385         txb->payload_size = bytes;
386 
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);
392 
393                 frag_hdr = (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
394                 memcpy(frag_hdr, (void *)header, hdr_len);
395 
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;
402 
403                 } else {
404                         /* The last fragment takes the remaining length */
405                         bytes = bytes_last_frag;
406                 }
407 
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);
410                 //
411 
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);
417                 }
418 
419                 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
420 
421                 /* Advance the SKB... */
422                 skb_pull(skb, bytes);
423 
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);
431         }
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
439 /*
440 {
441         int j=0;
442         for(j=0;j<nr_frags;j++)
443         {
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");
450         }
451 }
452 */
453 
454         return txb;
455 }
456 
457 
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)
461 {
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;
471 
472         ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
473 
474         /* Advance the SKB to the start of the payload */
475         skb_pull(skb, sizeof(struct ethhdr));
476 
477         /* Determine total amount of storage required for TXB packets */
478         bytes = skb->len + SNAP_SIZE + sizeof(u16);
479 
480         if (is_multicast_ether_addr(header->addr1) ||
481                         is_broadcast_ether_addr(header->addr1)) {
482                 QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
483         }
484         else {
485                 QOS_ctl = 0;
486         }
487 
488         if(isQoS) {
489                 QOS_ctl |= skb->priority; //set in the ieee80211_classify
490                 *pQOS_ctl = cpu_to_le16(QOS_ctl);
491         }
492 
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;
498         }
499 
500         txb->nr_frags = 1;
501         txb->frag_size = bytes;
502         txb->encrypted = isEncrypt;
503         txb->payload_size = bytes;
504 
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);
512 
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]++;
519 
520         return txb;
521 }
522 
523 #endif // _RTL8187_EXT_PATCH_
524 
525 /* SKBs are added to the ieee->tx_queue. */
526 int ieee80211_xmit(struct sk_buff *skb,
527                    struct net_device *dev)
528 {
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
546         };
547         u8 dest[ETH_ALEN], src[ETH_ALEN];
548 
549         struct ieee80211_crypt_data* crypt;
550 
551         //printk(KERN_WARNING "upper layer packet!\n");
552         spin_lock_irqsave(&ieee->lock, flags);
553 
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;
561         }
562 
563         ieee80211_classify(skb,&ieee->current_network);
564         if(likely(ieee->raw_tx == 0)){
565 
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;
570                 }
571 
572 
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))
576                 {
577                         txb = ieee->ext_patch_ieee80211_xmit(skb, dev);
578                         goto success;
579                 }
580 #endif
581 
582                 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
583 
584                 crypt = ieee->crypt[ieee->tx_keyidx];
585 
586                 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
587                         ieee->host_encrypt && crypt && crypt->ops;
588 
589                 if (!encrypt && ieee->ieee802_1x &&
590                 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
591                         stats->tx_dropped++;
592                         goto success;
593                 }
594 
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));
601                 }
602         #endif
603 
604                 /* Save source and destination addresses */
605                 memcpy(&dest, skb->data, ETH_ALEN);
606                 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
607 
608                 /* Advance the SKB to the start of the payload */
609                 skb_pull(skb, sizeof(struct ethhdr));
610 
611                 /* Determine total amount of storage required for TXB packets */
612                 bytes = skb->len + SNAP_SIZE + sizeof(u16);
613 
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;
620 
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;
627                 }
628 
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);
642                 }
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;
646 
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;
655                 }
656                 else {
657                         //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
658                         frag_size = ieee->fts;//default:392
659                         QOS_ctl = 0;
660                 }
661 
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;
668                 }
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;
679 
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;
684 
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;
693 
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;
702                 }
703                 txb->encrypted = encrypt;
704                 txb->payload_size = bytes;
705 
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);
711 
712                         frag_hdr = (struct ieee80211_hdr_3addr_QOS *)skb_put(skb_frag, hdr_len);
713                         memcpy(frag_hdr, &header, hdr_len);
714 
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;
721 
722                         } else {
723                                 /* The last fragment takes the remaining length */
724                                 bytes = bytes_last_frag;
725                         }
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);
733                         }
734                         //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
735                         //
736 
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);
743                         }
744 
745                         memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
746 
747                         /* Advance the SKB... */
748                         skb_pull(skb, bytes);
749 
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);
757                 }
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]++;
770                 }
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;
777                 }
778 
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;
784                 }
785 
786                 txb->encrypted = 0;
787                 txb->payload_size = skb->len;
788                 memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
789         }
790 
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;
806                         }
807                         ieee80211_txb_free(txb);
808                 }
809         }
810 
811         return 0;
812 
813  failed:
814         spin_unlock_irqrestore(&ieee->lock, flags);
815         netif_stop_queue(dev);
816         stats->tx_errors++;
817         return NETDEV_TX_BUSY;
818 
819 }
820 
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
829 
  This page was automatically generated by the LXR engine.