X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Frt2x00%2Frt2x00usb.c;h=8d76bb2e031289b027ec810a9bbbc6b75754dfbd;hb=82f97b8d3cb3982ec97e081598c671fab2c321b0;hp=fdf505beb79c5ab9a73403fad102cb5e9fbef501;hpb=6db3786aee36b32e5ed072ed67fad6d5341b0991;p=linux-2.6 diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index fdf505beb7..8d76bb2e03 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -40,7 +40,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, void *buffer, const u16 buffer_length, const int timeout) { - struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); + struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); int status; unsigned int i; unsigned int pipe = @@ -122,6 +122,38 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, } EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); +int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev, + const u8 request, const u8 requesttype, + const u16 offset, const void *buffer, + const u16 buffer_length, + const int timeout) +{ + int status = 0; + unsigned char *tb; + u16 off, len, bsize; + + mutex_lock(&rt2x00dev->usb_cache_mutex); + + tb = (char *)buffer; + off = offset; + len = buffer_length; + while (len && !status) { + bsize = min_t(u16, CSR_CACHE_SIZE, len); + status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request, + requesttype, off, tb, + bsize, timeout); + + tb += bsize; + len -= bsize; + off += bsize; + } + + mutex_unlock(&rt2x00dev->usb_cache_mutex); + + return status; +} +EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_large_buff); + /* * TX data handlers. */ @@ -130,10 +162,9 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct txdone_entry_desc txdesc; - enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || - !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; /* @@ -157,26 +188,12 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) txdesc.retry = 0; rt2x00lib_txdone(entry, &txdesc); - - /* - * Make this entry available for reuse. - */ - entry->flags = 0; - rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); - - /* - * If the data queue was full before the txdone handler - * we must make sure the packet queue in the mac80211 stack - * is reenabled when the txdone handler has finished. - */ - if (!rt2x00queue_full(entry->queue)) - ieee80211_wake_queue(rt2x00dev->hw, qid); } int rt2x00usb_write_tx_data(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); + struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); struct queue_entry_priv_usb *entry_priv = entry->priv_data; struct skb_frame_desc *skbdesc; u32 length; @@ -191,12 +208,8 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry) * Fill in skb descriptor */ skbdesc = get_skb_frame_desc(entry->skb); - memset(skbdesc, 0, sizeof(*skbdesc)); - skbdesc->data = entry->skb->data + entry->queue->desc_size; - skbdesc->data_len = entry->skb->len - entry->queue->desc_size; skbdesc->desc = entry->skb->data; skbdesc->desc_len = entry->queue->desc_size; - skbdesc->entry = entry; /* * USB devices cannot blindly pass the skb->len as the @@ -262,56 +275,15 @@ 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; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct sk_buff *skb; - struct skb_frame_desc *skbdesc; - struct rxdone_entry_desc rxdesc; - unsigned int header_size; - unsigned int align; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + u8 rxd[32]; if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || - !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; /* @@ -319,71 +291,22 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) * to be actually valid, or if the urb is signaling * a problem. */ - if (urb->actual_length < entry->queue->desc_size || urb->status) - goto skip_entry; - - /* - * Fill in skb descriptor - */ - skbdesc = get_skb_frame_desc(entry->skb); - memset(skbdesc, 0, sizeof(*skbdesc)); - skbdesc->entry = entry; - - 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. - */ - 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); + if (urb->actual_length < entry->queue->desc_size || urb->status) { + __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); + usb_submit_urb(urb, GFP_ATOMIC); + return; } - /* Update data pointers, trim buffer to correct size */ - skbdesc->data = entry->skb->data; - skb_trim(entry->skb, rxdesc.size); - /* - * Allocate a new sk buffer to replace the current one. - * If allocation fails, we should drop the current frame - * so we can recycle the existing sk buffer for the new frame. + * Fill in desc fields of the skb descriptor */ - skb = rt2x00usb_alloc_rxskb(entry->queue); - if (!skb) - goto skip_entry; + skbdesc->desc = rxd; + skbdesc->desc_len = entry->queue->desc_size; /* * Send the frame to rt2x00lib for further processing. */ - rt2x00lib_rxdone(entry, &rxdesc); - - /* - * Replace current entry's skb with the newly allocated one, - * and reinitialize the urb. - */ - entry->skb = skb; - urb->transfer_buffer = entry->skb->data; - urb->transfer_buffer_length = entry->skb->len; - -skip_entry: - if (test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) { - __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); - usb_submit_urb(urb, GFP_ATOMIC); - } - - rt2x00queue_index_inc(entry->queue, Q_INDEX); + rt2x00lib_rxdone(rt2x00dev, entry); } /* @@ -393,6 +316,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) { struct queue_entry_priv_usb *entry_priv; struct queue_entry_priv_usb_bcn *bcn_priv; + struct data_queue *queue; unsigned int i; rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0, @@ -401,14 +325,19 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) /* * Cancel all queues. */ - for (i = 0; i < rt2x00dev->rx->limit; i++) { - entry_priv = rt2x00dev->rx->entries[i].priv_data; - usb_kill_urb(entry_priv->urb); + queue_for_each(rt2x00dev, queue) { + for (i = 0; i < queue->limit; i++) { + entry_priv = queue->entries[i].priv_data; + usb_kill_urb(entry_priv->urb); + } } /* - * Kill guardian 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++) { bcn_priv = rt2x00dev->bcn->entries[i].priv_data; if (bcn_priv->guardian_urb) @@ -423,7 +352,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry) { - struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); + struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); struct queue_entry_priv_usb *entry_priv = entry->priv_data; usb_fill_bulk_urb(entry_priv->urb, usb_dev, @@ -490,8 +419,6 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, entry_priv = queue->entries[i].priv_data; usb_kill_urb(entry_priv->urb); usb_free_urb(entry_priv->urb); - if (queue->entries[i].skb) - kfree_skb(queue->entries[i].skb); } /* @@ -513,10 +440,7 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; - struct sk_buff *skb; - unsigned int entry_size; - unsigned int i; - int uninitialized_var(status); + int status; /* * Allocate DMA @@ -527,18 +451,6 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) goto exit; } - /* - * For the RX queue, skb's should be allocated. - */ - entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; - for (i = 0; i < rt2x00dev->rx->limit; i++) { - skb = rt2x00usb_alloc_rxskb(rt2x00dev->rx); - if (!skb) - goto exit; - - rt2x00dev->rx->entries[i].skb = skb; - } - return 0; exit: @@ -617,7 +529,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, usb_set_intfdata(usb_intf, hw); rt2x00dev = hw->priv; - rt2x00dev->dev = usb_intf; + rt2x00dev->dev = &usb_intf->dev; rt2x00dev->ops = ops; rt2x00dev->hw = hw; mutex_init(&rt2x00dev->usb_cache_mutex);