aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00usb.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c91
1 files changed, 82 insertions, 9 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 2fbf78ff6b18..83df312ac56f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -234,10 +234,10 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry)
234 * length of the data to usb_fill_bulk_urb. Pass the skb 234 * length of the data to usb_fill_bulk_urb. Pass the skb
235 * to the driver to determine what the length should be. 235 * to the driver to determine what the length should be.
236 */ 236 */
237 length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb); 237 length = rt2x00dev->ops->lib->get_tx_data_len(entry);
238 238
239 usb_fill_bulk_urb(entry_priv->urb, usb_dev, 239 usb_fill_bulk_urb(entry_priv->urb, usb_dev,
240 usb_sndbulkpipe(usb_dev, 1), 240 usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint),
241 entry->skb->data, length, 241 entry->skb->data, length,
242 rt2x00usb_interrupt_txdone, entry); 242 rt2x00usb_interrupt_txdone, entry);
243 243
@@ -378,10 +378,11 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
378 struct usb_device *usb_dev = 378 struct usb_device *usb_dev =
379 to_usb_device_intf(entry->queue->rt2x00dev->dev); 379 to_usb_device_intf(entry->queue->rt2x00dev->dev);
380 struct queue_entry_priv_usb *entry_priv = entry->priv_data; 380 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
381 int pipe;
381 382
382 if (entry->queue->qid == QID_RX) { 383 if (entry->queue->qid == QID_RX) {
383 usb_fill_bulk_urb(entry_priv->urb, usb_dev, 384 pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint);
384 usb_rcvbulkpipe(usb_dev, 1), 385 usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe,
385 entry->skb->data, entry->skb->len, 386 entry->skb->data, entry->skb->len,
386 rt2x00usb_interrupt_rxdone, entry); 387 rt2x00usb_interrupt_rxdone, entry);
387 388
@@ -393,6 +394,76 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
393} 394}
394EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); 395EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
395 396
397static void rt2x00usb_assign_endpoint(struct data_queue *queue,
398 struct usb_endpoint_descriptor *ep_desc)
399{
400 struct usb_device *usb_dev = to_usb_device_intf(queue->rt2x00dev->dev);
401 int pipe;
402
403 queue->usb_endpoint = usb_endpoint_num(ep_desc);
404
405 if (queue->qid == QID_RX) {
406 pipe = usb_rcvbulkpipe(usb_dev, queue->usb_endpoint);
407 queue->usb_maxpacket = usb_maxpacket(usb_dev, pipe, 0);
408 } else {
409 pipe = usb_sndbulkpipe(usb_dev, queue->usb_endpoint);
410 queue->usb_maxpacket = usb_maxpacket(usb_dev, pipe, 1);
411 }
412
413 if (!queue->usb_maxpacket)
414 queue->usb_maxpacket = 1;
415}
416
417static int rt2x00usb_find_endpoints(struct rt2x00_dev *rt2x00dev)
418{
419 struct usb_interface *intf = to_usb_interface(rt2x00dev->dev);
420 struct usb_host_interface *intf_desc = intf->cur_altsetting;
421 struct usb_endpoint_descriptor *ep_desc;
422 struct data_queue *queue = rt2x00dev->tx;
423 struct usb_endpoint_descriptor *tx_ep_desc = NULL;
424 unsigned int i;
425
426 /*
427 * Walk through all available endpoints to search for "bulk in"
428 * and "bulk out" endpoints. When we find such endpoints collect
429 * the information we need from the descriptor and assign it
430 * to the queue.
431 */
432 for (i = 0; i < intf_desc->desc.bNumEndpoints; i++) {
433 ep_desc = &intf_desc->endpoint[i].desc;
434
435 if (usb_endpoint_is_bulk_in(ep_desc)) {
436 rt2x00usb_assign_endpoint(rt2x00dev->rx, ep_desc);
437 } else if (usb_endpoint_is_bulk_out(ep_desc)) {
438 rt2x00usb_assign_endpoint(queue, ep_desc);
439
440 if (queue != queue_end(rt2x00dev))
441 queue = queue_next(queue);
442 tx_ep_desc = ep_desc;
443 }
444 }
445
446 /*
447 * At least 1 endpoint for RX and 1 endpoint for TX must be available.
448 */
449 if (!rt2x00dev->rx->usb_endpoint || !rt2x00dev->tx->usb_endpoint) {
450 ERROR(rt2x00dev, "Bulk-in/Bulk-out endpoints not found\n");
451 return -EPIPE;
452 }
453
454 /*
455 * It might be possible not all queues have a dedicated endpoint.
456 * Loop through all TX queues and copy the endpoint information
457 * which we have gathered from already assigned endpoints.
458 */
459 txall_queue_for_each(rt2x00dev, queue) {
460 if (!queue->usb_endpoint)
461 rt2x00usb_assign_endpoint(queue, tx_ep_desc);
462 }
463
464 return 0;
465}
466
396static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, 467static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
397 struct data_queue *queue) 468 struct data_queue *queue)
398{ 469{
@@ -464,6 +535,13 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
464 int status; 535 int status;
465 536
466 /* 537 /*
538 * Find endpoints for each queue
539 */
540 status = rt2x00usb_find_endpoints(rt2x00dev);
541 if (status)
542 goto exit;
543
544 /*
467 * Allocate DMA 545 * Allocate DMA
468 */ 546 */
469 queue_for_each(rt2x00dev, queue) { 547 queue_for_each(rt2x00dev, queue) {
@@ -554,11 +632,6 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
554 rt2x00dev->ops = ops; 632 rt2x00dev->ops = ops;
555 rt2x00dev->hw = hw; 633 rt2x00dev->hw = hw;
556 634
557 rt2x00dev->usb_maxpacket =
558 usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1);
559 if (!rt2x00dev->usb_maxpacket)
560 rt2x00dev->usb_maxpacket = 1;
561
562 retval = rt2x00usb_alloc_reg(rt2x00dev); 635 retval = rt2x00usb_alloc_reg(rt2x00dev);
563 if (retval) 636 if (retval)
564 goto exit_free_device; 637 goto exit_free_device;