/*
* Check for Cache availability.
*/
- if (unlikely(!rt2x00dev->csr_cache || buffer_length > CSR_CACHE_SIZE)) {
+ if (unlikely(!rt2x00dev->csr.cache || buffer_length > CSR_CACHE_SIZE)) {
ERROR(rt2x00dev, "CSR cache not available.\n");
return -ENOMEM;
}
if (requesttype == USB_VENDOR_REQUEST_OUT)
- memcpy(rt2x00dev->csr_cache, buffer, buffer_length);
+ memcpy(rt2x00dev->csr.cache, buffer, buffer_length);
status = rt2x00usb_vendor_request(rt2x00dev, request, requesttype,
- offset, 0, rt2x00dev->csr_cache,
+ offset, 0, rt2x00dev->csr.cache,
buffer_length, timeout);
if (!status && requesttype == USB_VENDOR_REQUEST_IN)
- memcpy(buffer, rt2x00dev->csr_cache, buffer_length);
+ memcpy(buffer, rt2x00dev->csr.cache, buffer_length);
return status;
}
}
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.
*/
* 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 = queue->data_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);
/*
* 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;
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))
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
{
struct queue_entry_priv_usb_rx *priv_rx;
struct queue_entry_priv_usb_tx *priv_tx;
+ struct queue_entry_priv_usb_bcn *priv_bcn;
struct data_queue *queue;
unsigned int i;
usb_kill_urb(priv_rx->urb);
}
- txall_queue_for_each(rt2x00dev, queue) {
+ tx_queue_for_each(rt2x00dev, queue) {
for (i = 0; i < queue->limit; i++) {
priv_tx = queue->entries[i].priv_data;
usb_kill_urb(priv_tx->urb);
}
}
+
+ /*
+ * 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);
+
+ if (priv_bcn->guardian_urb)
+ usb_kill_urb(priv_bcn->guardian_urb);
+ }
+
+ if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags))
+ return;
+
+ for (i = 0; i < rt2x00dev->bcn[1].limit; i++) {
+ priv_tx = rt2x00dev->bcn[1].entries[i].priv_data;
+ usb_kill_urb(priv_tx->urb);
+ }
}
EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
kfree(rt2x00dev->eeprom);
rt2x00dev->eeprom = NULL;
- kfree(rt2x00dev->csr_cache);
- rt2x00dev->csr_cache = NULL;
+ kfree(rt2x00dev->csr.cache);
+ rt2x00dev->csr.cache = NULL;
}
static int rt2x00usb_alloc_reg(struct rt2x00_dev *rt2x00dev)
{
- rt2x00dev->csr_cache = kzalloc(CSR_CACHE_SIZE, GFP_KERNEL);
- if (!rt2x00dev->csr_cache)
+ rt2x00dev->csr.cache = kzalloc(CSR_CACHE_SIZE, GFP_KERNEL);
+ if (!rt2x00dev->csr.cache)
goto exit;
rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);