]> err.no Git - linux-2.6/commitdiff
rt2x00: Add skb descriptor
authorIvo van Doorn <IvDoorn@gmail.com>
Thu, 24 Jan 2008 09:56:25 +0000 (01:56 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 Jan 2008 23:05:07 +0000 (15:05 -0800)
Use the skb->cb field to add a frame description that can be used
to transfer information passed each rt2x00 layer. This reduces the
required arguments for rt2x00lib_write_tx_desc().

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00ring.h
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c

index 15ab4b20d067e7bc3f67358f508c0faeb5a7a913..2a38388a79e146433535af533b3c65b844d4d6d9 100644 (file)
@@ -1686,8 +1686,8 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
        struct rt2x00_dev *rt2x00dev = hw->priv;
        struct usb_device *usb_dev =
            interface_to_usbdev(rt2x00dev_usb(rt2x00dev));
-       struct data_ring *ring =
-           rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
+       struct skb_desc *desc;
+       struct data_ring *ring;
        struct data_entry *beacon;
        struct data_entry *guardian;
        int pipe = usb_sndbulkpipe(usb_dev, 1);
@@ -1699,6 +1699,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
         * initialization.
         */
        control->queue = IEEE80211_TX_QUEUE_BEACON;
+       ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
 
        /*
         * Obtain 2 entries, one for the guardian byte,
@@ -1709,23 +1710,34 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
        beacon = rt2x00_get_data_entry(ring);
 
        /*
-        * First we create the beacon.
+        * Add the descriptor in front of the skb.
         */
        skb_push(skb, ring->desc_size);
        memset(skb->data, 0, ring->desc_size);
 
-       rt2x00lib_write_tx_desc(rt2x00dev, (__le32 *)skb->data,
-                               (struct ieee80211_hdr *)(skb->data +
-                                                        ring->desc_size),
-                               skb->len - ring->desc_size, control);
+       /*
+        * Fill in skb descriptor
+        */
+       desc = get_skb_desc(skb);
+       desc->desc_len = ring->desc_size;
+       desc->data_len = skb->len - ring->desc_size;
+       desc->desc = skb->data;
+       desc->data = skb->data + ring->desc_size;
+       desc->ring = ring;
+       desc->entry = beacon;
+
+       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
+       /*
+        * USB devices cannot blindly pass the skb->len as the
+        * length of the data to usb_fill_bulk_urb. Pass the skb
+        * to the driver to determine what the length should be.
+        */
        length = rt2500usb_get_tx_data_len(rt2x00dev, skb);
 
        usb_fill_bulk_urb(beacon->priv, usb_dev, pipe,
                          skb->data, length, rt2500usb_beacondone, beacon);
 
-       beacon->skb = skb;
-
        /*
         * Second we need to create the guardian byte.
         * We only need a single byte, so lets recycle
index b2283cebfab9258ede7388709e6f4d6eda22f0a0..31e48c25a692f4ebeae44bf703c1b042d07672e0 100644 (file)
@@ -901,9 +901,7 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
  * TX descriptor initializer
  */
 void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                            __le32 *txd,
-                            struct ieee80211_hdr *ieee80211hdr,
-                            unsigned int length,
+                            struct sk_buff *skb,
                             struct ieee80211_tx_control *control);
 
 /*
index e8949785c662981a4032d2c735737080a0f7f20b..4f32ee8f4cb7aa40fbb2eedf8335b9a5ce83406d 100644 (file)
@@ -573,36 +573,26 @@ EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
  * TX descriptor initializer
  */
 void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                            __le32 *txd,
-                            struct ieee80211_hdr *ieee80211hdr,
-                            unsigned int length,
+                            struct sk_buff *skb,
                             struct ieee80211_tx_control *control)
 {
        struct txdata_entry_desc desc;
-       struct data_ring *ring;
+       struct skb_desc *skbdesc = get_skb_desc(skb);
+       struct ieee80211_hdr *ieee80211hdr = skbdesc->data;
+       __le32 *txd = skbdesc->desc;
        int tx_rate;
        int bitrate;
+       int length;
        int duration;
        int residual;
        u16 frame_control;
        u16 seq_ctrl;
 
-       /*
-        * Make sure the descriptor is properly cleared.
-        */
-       memset(&desc, 0x00, sizeof(desc));
+       memset(&desc, 0, sizeof(desc));
 
-       /*
-        * Get ring pointer, if we fail to obtain the
-        * correct ring, then use the first TX ring.
-        */
-       ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
-       if (!ring)
-               ring = rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0);
-
-       desc.cw_min = ring->tx_params.cw_min;
-       desc.cw_max = ring->tx_params.cw_max;
-       desc.aifs = ring->tx_params.aifs;
+       desc.cw_min = skbdesc->ring->tx_params.cw_min;
+       desc.cw_max = skbdesc->ring->tx_params.cw_max;
+       desc.aifs = skbdesc->ring->tx_params.aifs;
 
        /*
         * Identify queue
@@ -683,17 +673,18 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        desc.signal = DEVICE_GET_RATE_FIELD(tx_rate, PLCP);
        desc.service = 0x04;
 
+       length = skbdesc->data_len + FCS_LEN;
        if (test_bit(ENTRY_TXD_OFDM_RATE, &desc.flags)) {
-               desc.length_high = ((length + FCS_LEN) >> 6) & 0x3f;
-               desc.length_low = ((length + FCS_LEN) & 0x3f);
+               desc.length_high = (length >> 6) & 0x3f;
+               desc.length_low = length & 0x3f;
        } else {
                bitrate = DEVICE_GET_RATE_FIELD(tx_rate, RATE);
 
                /*
                 * Convert length to microseconds.
                 */
-               residual = get_duration_res(length + FCS_LEN, bitrate);
-               duration = get_duration(length + FCS_LEN, bitrate);
+               residual = get_duration_res(length, bitrate);
+               duration = get_duration(length, bitrate);
 
                if (residual != 0) {
                        duration++;
@@ -716,8 +707,14 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
                        desc.signal |= 0x08;
        }
 
-       rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, txd, &desc,
-                                          ieee80211hdr, length, control);
+       rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, txd, &desc, ieee80211hdr,
+                                          skbdesc->data_len, control);
+
+       /*
+        * Update ring entry.
+        */
+       skbdesc->entry->skb = skb;
+       memcpy(&skbdesc->entry->tx_status.control, control, sizeof(*control));
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc);
 
index cf0bb5d9d847cc18e2aac9e431f7fc925ec3c939..c1d7c10e58fecc2413d9c1977a1019d1b5c11b62 100644 (file)
@@ -38,9 +38,9 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
                            struct ieee80211_tx_control *control)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct data_ring *ring =
-           rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
-       struct data_entry *entry = rt2x00_get_data_entry(ring);
+       struct skb_desc *desc;
+       struct data_ring *ring;
+       struct data_entry *entry;
 
        /*
         * Just in case mac80211 doesn't set this correctly,
@@ -48,14 +48,22 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * initialization.
         */
        control->queue = IEEE80211_TX_QUEUE_BEACON;
+       ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
+       entry = rt2x00_get_data_entry(ring);
 
        /*
-        * Update the beacon entry.
+        * Fill in skb descriptor
         */
+       desc = get_skb_desc(skb);
+       desc->desc_len = ring->desc_size;
+       desc->data_len = skb->len;
+       desc->desc = entry->priv;
+       desc->data = skb->data;
+       desc->ring = ring;
+       desc->entry = entry;
+
        memcpy(entry->data_addr, skb->data, skb->len);
-       rt2x00lib_write_tx_desc(rt2x00dev, entry->priv,
-                               (struct ieee80211_hdr *)skb->data,
-                               skb->len, control);
+       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
        /*
         * Enable beacon generation.
@@ -73,9 +81,9 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
                            struct data_ring *ring, struct sk_buff *skb,
                            struct ieee80211_tx_control *control)
 {
-       struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
        struct data_entry *entry = rt2x00_get_data_entry(ring);
        __le32 *txd = entry->priv;
+       struct skb_desc *desc;
        u32 word;
 
        if (rt2x00_ring_full(ring)) {
@@ -95,11 +103,19 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
                return -EINVAL;
        }
 
-       entry->skb = skb;
-       memcpy(&entry->tx_status.control, control, sizeof(*control));
+       /*
+        * Fill in skb descriptor
+        */
+       desc = get_skb_desc(skb);
+       desc->desc_len = ring->desc_size;
+       desc->data_len = skb->len;
+       desc->desc = entry->priv;
+       desc->data = skb->data;
+       desc->ring = ring;
+       desc->entry = entry;
+
        memcpy(entry->data_addr, skb->data, skb->len);
-       rt2x00lib_write_tx_desc(rt2x00dev, txd, ieee80211hdr,
-                               skb->len, control);
+       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
        rt2x00_ring_index_inc(ring);
 
@@ -119,6 +135,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
        struct data_entry *entry;
        struct sk_buff *skb;
        struct ieee80211_hdr *hdr;
+       struct skb_desc *skbdesc;
        struct rxdata_entry_desc desc;
        int header_size;
        __le32 *rxd;
@@ -133,7 +150,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
                if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC))
                        break;
 
-               memset(&desc, 0x00, sizeof(desc));
+               memset(&desc, 0, sizeof(desc));
                rt2x00dev->ops->lib->fill_rxdone(entry, &desc);
 
                hdr = (struct ieee80211_hdr *)entry->data_addr;
@@ -157,6 +174,17 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
                skb_reserve(skb, align);
                memcpy(skb_put(skb, desc.size), entry->data_addr, desc.size);
 
+               /*
+                * Fill in skb descriptor
+                */
+               skbdesc = get_skb_desc(skb);
+               skbdesc->desc_len = desc.size;
+               skbdesc->data_len = entry->ring->desc_size;
+               skbdesc->desc = entry->priv;
+               skbdesc->data = skb->data;
+               skbdesc->ring = ring;
+               skbdesc->entry = entry;
+
                /*
                 * Send the frame to rt2x00lib for further processing.
                 */
index 5b871adfa22a53a4e1059f09075f65b70198d2f0..5b32f3ef2a7356c0ccc7616bdfec72c979b85e22 100644 (file)
 #ifndef RT2X00RING_H
 #define RT2X00RING_H
 
+/*
+ * skb_desc
+ * Descriptor information for the skb buffer
+ */
+struct skb_desc {
+       unsigned int frame_type;
+
+       unsigned int desc_len;
+       unsigned int data_len;
+
+       void *desc;
+       void *data;
+
+       struct data_ring *ring;
+       struct data_entry *entry;
+};
+
+static inline struct skb_desc* get_skb_desc(struct sk_buff *skb)
+{
+       return (struct skb_desc*)&skb->cb[0];
+}
+
 /*
  * rxdata_entry_desc
  * Summary of information that has been read from the
index 9b55f7997ca211ede7e482dda8e74306581449c7..fd6b61c9761910664e76b5ecacfa42871e11f630 100644 (file)
@@ -176,7 +176,7 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
        struct usb_device *usb_dev =
            interface_to_usbdev(rt2x00dev_usb(rt2x00dev));
        struct data_entry *entry = rt2x00_get_data_entry(ring);
-       int pipe = usb_sndbulkpipe(usb_dev, 1);
+       struct skb_desc *desc;
        u32 length;
 
        if (rt2x00_ring_full(ring)) {
@@ -199,12 +199,18 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
        skb_push(skb, ring->desc_size);
        memset(skb->data, 0, ring->desc_size);
 
-       rt2x00lib_write_tx_desc(rt2x00dev, (__le32 *)skb->data,
-                               (struct ieee80211_hdr *)(skb->data +
-                                                        ring->desc_size),
-                               skb->len - ring->desc_size, control);
-       memcpy(&entry->tx_status.control, control, sizeof(*control));
-       entry->skb = skb;
+       /*
+        * Fill in skb descriptor
+        */
+       desc = get_skb_desc(skb);
+       desc->desc_len = ring->desc_size;
+       desc->data_len = skb->len - ring->desc_size;
+       desc->desc = skb->data;
+       desc->data = skb->data + ring->desc_size;
+       desc->ring = ring;
+       desc->entry = entry;
+
+       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
        /*
         * USB devices cannot blindly pass the skb->len as the
@@ -217,7 +223,7 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
         * Initialize URB and send the frame to the device.
         */
        __set_bit(ENTRY_OWNER_NIC, &entry->flags);
-       usb_fill_bulk_urb(entry->priv, usb_dev, pipe,
+       usb_fill_bulk_urb(entry->priv, usb_dev, usb_sndbulkpipe(usb_dev, 1),
                          skb->data, length, rt2x00usb_interrupt_txdone, entry);
        usb_submit_urb(entry->priv, GFP_ATOMIC);
 
@@ -240,6 +246,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
        struct rt2x00_dev *rt2x00dev = ring->rt2x00dev;
        struct sk_buff *skb;
        struct ieee80211_hdr *hdr;
+       struct skb_desc *skbdesc;
        struct rxdata_entry_desc desc;
        int header_size;
        int frame_size;
@@ -256,7 +263,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
        if (urb->actual_length < entry->ring->desc_size || urb->status)
                goto skip_entry;
 
-       memset(&desc, 0x00, sizeof(desc));
+       memset(&desc, 0, sizeof(desc));
        rt2x00dev->ops->lib->fill_rxdone(entry, &desc);
 
        /*
@@ -296,6 +303,17 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
        }
        skb_trim(entry->skb, desc.size);
 
+       /*
+        * Fill in skb descriptor
+        */
+       skbdesc = get_skb_desc(entry->skb);
+       skbdesc->desc_len = desc.size;
+       skbdesc->data_len = entry->ring->desc_size;
+       skbdesc->desc = entry->skb->data + desc.size;
+       skbdesc->data = entry->skb->data;
+       skbdesc->ring = ring;
+       skbdesc->entry = entry;
+
        /*
         * Send the frame to rt2x00lib for further processing.
         */
index 52622d32ea4c53799bf8f9b7373166b26b373712..0693b3920e688e0a691dfe065298912e1b591581 100644 (file)
@@ -2408,6 +2408,9 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
                          struct ieee80211_tx_control *control)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
+       struct skb_desc *desc;
+       struct data_ring *ring;
+       struct data_entry *entry;
 
        /*
         * Just in case the ieee80211 doesn't set this,
@@ -2415,6 +2418,8 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * initialization.
         */
        control->queue = IEEE80211_TX_QUEUE_BEACON;
+       ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
+       entry = rt2x00_get_data_entry(ring);
 
        /*
         * We need to append the descriptor in front of the
@@ -2428,15 +2433,23 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
        }
 
        /*
-        * First we create the beacon.
+        * Add the descriptor in front of the skb.
+        */
+       skb_push(skb, ring->desc_size);
+       memset(skb->data, 0, ring->desc_size);
+
+       /*
+        * Fill in skb descriptor
         */
-       skb_push(skb, TXD_DESC_SIZE);
-       memset(skb->data, 0, TXD_DESC_SIZE);
+       desc = get_skb_desc(skb);
+       desc->desc_len = ring->desc_size;
+       desc->data_len = skb->len - ring->desc_size;
+       desc->desc = skb->data;
+       desc->data = skb->data + ring->desc_size;
+       desc->ring = ring;
+       desc->entry = entry;
 
-       rt2x00lib_write_tx_desc(rt2x00dev, (__le32 *)skb->data,
-                               (struct ieee80211_hdr *)(skb->data +
-                                                        TXD_DESC_SIZE),
-                               skb->len - TXD_DESC_SIZE, control);
+       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
        /*
         * Write entire beacon with descriptor to register,
index 49180de321e473d4dcaeef4f6a4f8f0d9a9a8669..8093a4d49335ccdbbc263b714e9d64538f00ea7a 100644 (file)
@@ -1965,6 +1965,9 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
                          struct ieee80211_tx_control *control)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
+       struct skb_desc *desc;
+       struct data_ring *ring;
+       struct data_entry *entry;
        int timeout;
 
        /*
@@ -1973,17 +1976,27 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * initialization.
         */
        control->queue = IEEE80211_TX_QUEUE_BEACON;
+       ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
+       entry = rt2x00_get_data_entry(ring);
 
        /*
-        * First we create the beacon.
+        * Add the descriptor in front of the skb.
         */
-       skb_push(skb, TXD_DESC_SIZE);
-       memset(skb->data, 0, TXD_DESC_SIZE);
+       skb_push(skb, ring->desc_size);
+       memset(skb->data, 0, ring->desc_size);
 
-       rt2x00lib_write_tx_desc(rt2x00dev, (__le32 *)skb->data,
-                               (struct ieee80211_hdr *)(skb->data +
-                                                        TXD_DESC_SIZE),
-                               skb->len - TXD_DESC_SIZE, control);
+       /*
+        * Fill in skb descriptor
+        */
+       desc = get_skb_desc(skb);
+       desc->desc_len = ring->desc_size;
+       desc->data_len = skb->len - ring->desc_size;
+       desc->desc = skb->data;
+       desc->data = skb->data + ring->desc_size;
+       desc->ring = ring;
+       desc->entry = entry;
+
+       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
        /*
         * Write entire beacon with descriptor to register,