]> Pileus Git - ~andy/linux/blobdiff - drivers/net/wireless/rt2x00/rt2x00usb.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
[~andy/linux] / drivers / net / wireless / rt2x00 / rt2x00usb.c
index 6cb4432e1ee0e040ae69cda57e183842e856bef6..e5ceae805b579805909f72fe7a98f43247775f9e 100644 (file)
@@ -122,58 +122,6 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
 
-static void rt2x00usb_vendor_request_async_complete(struct urb *urb)
-{
-       /*
-        * We're done with it, descrease usage count and let the
-        * usb layer delete it as soon as it is done with it.
-        */
-       usb_put_urb(urb);
-}
-
-int rt2x00usb_vendor_request_async(struct rt2x00_dev *rt2x00dev,
-                                  const u8 request, const u16 offset,
-                                  const u16 value)
-{
-       struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev);
-       struct usb_ctrlrequest *ctrl;
-       struct urb *urb;
-       int status;
-
-       urb = usb_alloc_urb(0, GFP_NOIO);
-       if (!urb)
-               return -ENOMEM;
-
-       ctrl = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
-       if (!ctrl) {
-               status = -ENOMEM;
-               goto exit;
-       }
-
-       ctrl->bRequestType= USB_VENDOR_REQUEST_OUT;
-       ctrl->bRequest = request;
-       ctrl->wValue = cpu_to_le16p(&value);
-       ctrl->wIndex = cpu_to_le16p(&offset);
-       ctrl->wLength = 0;
-
-       usb_fill_control_urb(urb, usb_dev, usb_sndctrlpipe(usb_dev, 0),
-                            (unsigned char *)ctrl, NULL, 0,
-                            rt2x00usb_vendor_request_async_complete, NULL);
-
-       status = usb_submit_urb(urb, GFP_ATOMIC);
-       if (!status)
-               goto exit;
-
-       return 0;
-
-exit:
-       usb_put_urb(urb);
-       kfree(ctrl);
-
-       return status;
-}
-EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_async);
-
 /*
  * TX data handlers.
  */
@@ -252,13 +200,13 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
         * Fill in skb descriptor
         */
        skbdesc = get_skb_frame_desc(skb);
-       memset(skbdesc, 0, sizeof(*skbdesc));
        skbdesc->data = skb->data + queue->desc_size;
        skbdesc->data_len = skb->len - queue->desc_size;
        skbdesc->desc = skb->data;
        skbdesc->desc_len = queue->desc_size;
        skbdesc->entry = entry;
 
+       memcpy(&priv_tx->control, control, sizeof(priv_tx->control));
        rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
        /*
@@ -300,11 +248,11 @@ static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue)
         * advance.
         */
        frame_size = queue->data_size + queue->desc_size;
-       skb = dev_alloc_skb(frame_size + 2);
+       skb = dev_alloc_skb(queue->desc_size + frame_size + 2);
        if (!skb)
                return NULL;
 
-       skb_reserve(skb, 2);
+       skb_reserve(skb, queue->desc_size + 2);
        skb_put(skb, frame_size);
 
        return skb;
@@ -317,6 +265,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
        struct sk_buff *skb;
        struct skb_frame_desc *skbdesc;
        struct rxdone_entry_desc rxdesc;
+       int header_size;
 
        if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
            !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
@@ -340,6 +289,19 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
        memset(&rxdesc, 0, sizeof(rxdesc));
        rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
 
+       /*
+        * The data behind the ieee80211 header must be
+        * aligned on a 4 byte boundary.
+        */
+       header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
+       if (header_size % 4 == 0) {
+               skb_push(entry->skb, 2);
+               memmove(entry->skb->data, entry->skb->data + 2,
+                       entry->skb->len - 2);
+               skbdesc->data = entry->skb->data;
+               skb_trim(entry->skb,entry->skb->len - 2);
+       }
+
        /*
         * Allocate a new sk buffer to replace the current one.
         * If allocation fails, we should drop the current frame
@@ -400,6 +362,12 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
                }
        }
 
+       /*
+        * Kill guardian urb (if required by driver).
+        */
+       if (!test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
+               return;
+
        for (i = 0; i < rt2x00dev->bcn->limit; i++) {
                priv_bcn = rt2x00dev->bcn->entries[i].priv_data;
                usb_kill_urb(priv_bcn->urb);