rt2x00: Centralize RX packet alignment handling in rt2x00lib.
authorGertjan van Wingerde <gwingerde@kpnplanet.nl>
Fri, 6 Jun 2008 20:54:12 +0000 (22:54 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Sat, 14 Jun 2008 16:17:57 +0000 (12:17 -0400)
When rt2x00pci will be switched over to dynamically mapped skb's
instead of statically allocated DMA buffers, it no longer can handle
alignment of RX packets in a copy step, and needs to implement the
same scheme as rt2x00usb does.

In order to make the patch on dynamically mapped skb's smaller,
already centralize the alignment handling into rt2x00lib. This allows
us to move more code in rt2x00lib, and thus remove code duplication
between rt2x00usb and rt2x00pci.

Signed-off-by: Gertjan van Wingerde <gwingerde@kpnplanet.nl>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rt2x00/rt2x00usb.c

index 938d375027be760715b74260e6d98d30d28013c4..0da8f972a1b22582b7faacb256d014afd4acef11 100644 (file)
@@ -929,6 +929,12 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate)
        return ((size * 8 * 10) % rate);
 }
 
+/**
+ * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes.
+ * @queue: The queue for which the skb will be applicable.
+ */
+struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue);
+
 /**
  * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input
  * @entry: The entry which will be used to transfer the TX frame.
index 48f4aec1a4d98c33da7675714f228a0cc12a1db5..ce1f7bbd3d7a4644bee999d361f0a2e844887075 100644 (file)
@@ -554,13 +554,35 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
+       unsigned int header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
        struct ieee80211_supported_band *sband;
        struct ieee80211_hdr *hdr;
        const struct rt2x00_rate *rate;
+       unsigned int align;
        unsigned int i;
        int idx = -1;
        u16 fc;
 
+       /*
+        * The data behind the ieee80211 header must be
+        * aligned on a 4 byte boundary. We already reserved
+        * 2 bytes for header_size % 4 == 2 optimization.
+        * To determine the number of bytes which the data
+        * should be moved to the left, we must add these
+        * 2 bytes to the header_size.
+        */
+       align = (header_size + 2) % 4;
+
+       if (align) {
+               skb_push(entry->skb, align);
+               /* Move entire frame in 1 command */
+               memmove(entry->skb->data, entry->skb->data + align,
+                       rxdesc->size);
+       }
+
+       /* Update data pointers, trim buffer to correct size */
+       skb_trim(entry->skb, rxdesc->size);
+
        /*
         * Update RX statistics.
         */
index a9819aad5e7dd24c2cad58e6e9d97f43a843b9c0..82e80b69d0be0606b97c993a8fdd5b4579dd0f08 100644 (file)
@@ -79,11 +79,8 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
        struct data_queue *queue = rt2x00dev->rx;
        struct queue_entry *entry;
        struct queue_entry_priv_pci *entry_priv;
-       struct ieee80211_hdr *hdr;
        struct skb_frame_desc *skbdesc;
        struct rxdone_entry_desc rxdesc;
-       int header_size;
-       int align;
        u32 word;
 
        while (1) {
@@ -97,27 +94,15 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
                memset(&rxdesc, 0, sizeof(rxdesc));
                rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
 
-               hdr = (struct ieee80211_hdr *)entry_priv->data;
-               header_size =
-                   ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
-
-               /*
-                * The data behind the ieee80211 header must be
-                * aligned on a 4 byte boundary.
-                */
-               align = header_size % 4;
-
                /*
-                * Allocate the sk_buffer, initialize it and copy
-                * all data into it.
+                * Allocate the sk_buffer and copy all data into it.
                 */
-               entry->skb = dev_alloc_skb(rxdesc.size + align);
+               entry->skb = rt2x00queue_alloc_rxskb(queue);
                if (!entry->skb)
                        return;
 
-               skb_reserve(entry->skb, align);
-               memcpy(skb_put(entry->skb, rxdesc.size),
-                      entry_priv->data, rxdesc.size);
+               memcpy(entry->skb->data, entry_priv->data, rxdesc.size);
+               skb_trim(entry->skb, rxdesc.size);
 
                /*
                 * Fill in skb descriptor
index 493066519ef3096bec59412656190df66cdfa269..2f3dd1d91a129684df2193d65a84f8a71df77af6 100644 (file)
 #include "rt2x00.h"
 #include "rt2x00lib.h"
 
+struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue)
+{
+       struct sk_buff *skb;
+       unsigned int frame_size;
+       unsigned int reserved_size;
+
+       /*
+        * The frame size includes descriptor size, because the
+        * hardware directly receive the frame into the skbuffer.
+        */
+       frame_size = queue->data_size + queue->desc_size;
+
+       /*
+        * For the allocation we should keep a few things in mind:
+        * 1) 4byte alignment of 802.11 payload
+        *
+        * For (1) we need at most 4 bytes to guarentee the correct
+        * alignment. We are going to optimize the fact that the chance
+        * that the 802.11 header_size % 4 == 2 is much bigger then
+        * anything else. However since we need to move the frame up
+        * to 3 bytes to the front, which means we need to preallocate
+        * 6 bytes.
+        */
+       reserved_size = 6;
+
+       /*
+        * Allocate skbuffer.
+        */
+       skb = dev_alloc_skb(frame_size + reserved_size);
+       if (!skb)
+               return NULL;
+
+       skb_reserve(skb, reserved_size);
+       skb_put(skb, frame_size);
+
+       return skb;
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb);
+
 void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
                                      struct txentry_desc *txdesc)
 {
index 797023cad947df6caea8bc270288fa0c4870dcef..33833bc6d6659a54d9eb01c91765067aff96f6a4 100644 (file)
@@ -260,44 +260,6 @@ EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
 /*
  * RX data handlers.
  */
-static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue)
-{
-       struct sk_buff *skb;
-       unsigned int frame_size;
-       unsigned int reserved_size;
-
-       /*
-        * The frame size includes descriptor size, because the
-        * hardware directly receive the frame into the skbuffer.
-        */
-       frame_size = queue->data_size + queue->desc_size;
-
-       /*
-        * For the allocation we should keep a few things in mind:
-        * 1) 4byte alignment of 802.11 payload
-        *
-        * For (1) we need at most 4 bytes to guarentee the correct
-        * alignment. We are going to optimize the fact that the chance
-        * that the 802.11 header_size % 4 == 2 is much bigger then
-        * anything else. However since we need to move the frame up
-        * to 3 bytes to the front, which means we need to preallocate
-        * 6 bytes.
-        */
-       reserved_size = 6;
-
-       /*
-        * Allocate skbuffer.
-        */
-       skb = dev_alloc_skb(frame_size + reserved_size);
-       if (!skb)
-               return NULL;
-
-       skb_reserve(skb, reserved_size);
-       skb_put(skb, frame_size);
-
-       return skb;
-}
-
 static void rt2x00usb_interrupt_rxdone(struct urb *urb)
 {
        struct queue_entry *entry = (struct queue_entry *)urb->context;
@@ -305,8 +267,6 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
        struct sk_buff *skb;
        struct skb_frame_desc *skbdesc;
        struct rxdone_entry_desc rxdesc;
-       unsigned int header_size;
-       unsigned int align;
 
        if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
            !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
@@ -330,26 +290,9 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
        memset(&rxdesc, 0, sizeof(rxdesc));
        rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
 
-       header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
-
        /*
-        * The data behind the ieee80211 header must be
-        * aligned on a 4 byte boundary. We already reserved
-        * 2 bytes for header_size % 4 == 2 optimization.
-        * To determine the number of bytes which the data
-        * should be moved to the left, we must add these
-        * 2 bytes to the header_size.
+        * Trim the skb to the correct size.
         */
-       align = (header_size + 2) % 4;
-
-       if (align) {
-               skb_push(entry->skb, align);
-               /* Move entire frame in 1 command */
-               memmove(entry->skb->data, entry->skb->data + align,
-                       rxdesc.size);
-       }
-
-       /* Update data pointers, trim buffer to correct size */
        skb_trim(entry->skb, rxdesc.size);
 
        /*
@@ -357,7 +300,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
         * If allocation fails, we should drop the current frame
         * so we can recycle the existing sk buffer for the new frame.
         */
-       skb = rt2x00usb_alloc_rxskb(entry->queue);
+       skb = rt2x00queue_alloc_rxskb(entry->queue);
        if (!skb)
                goto skip_entry;
 
@@ -529,7 +472,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
         */
        entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size;
        for (i = 0; i < rt2x00dev->rx->limit; i++) {
-               skb = rt2x00usb_alloc_rxskb(rt2x00dev->rx);
+               skb = rt2x00queue_alloc_rxskb(rt2x00dev->rx);
                if (!skb)
                        goto exit;