aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-11-13 17:07:33 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-11-25 16:41:34 -0500
commitf1ca2167d89d991eed519c789d3902f9682c06b8 (patch)
treee170d7fe637f7a9ff552e694af6f409529865daa /drivers/net/wireless
parentc8f96974eebbc8f078ad64f2d8041e6dce741d67 (diff)
rt2x00: Detect USB BULK in/out endpoints
Instead of hardcoding the used in/out endpoints we should detect them by walking through all available endpoints. rt2800usb will gain the most out of this, because the legacy drivers indicate that there are multiple endpoints available. However this code might benefit at least rt73usb as well for the MIMO queues, and if we are really lucky rt2500usb will benefit because for the TX and PRIO queues. Even if rt2500usb and rt73usb do not get better performance after this patch, the endpoint detection still belongs to rt2x00usb, and it shouldn't hurt to always try to detect the available endpoints. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h22
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c91
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c7
5 files changed, 111 insertions, 28 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 40eb64358821..0447e93306ad 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1108,7 +1108,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry)
1108 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); 1108 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
1109 struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; 1109 struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
1110 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 1110 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1111 int pipe = usb_sndbulkpipe(usb_dev, 1); 1111 int pipe = usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint);
1112 int length; 1112 int length;
1113 u16 reg; 1113 u16 reg;
1114 1114
@@ -1134,7 +1134,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry)
1134 * length of the data to usb_fill_bulk_urb. Pass the skb 1134 * length of the data to usb_fill_bulk_urb. Pass the skb
1135 * to the driver to determine what the length should be. 1135 * to the driver to determine what the length should be.
1136 */ 1136 */
1137 length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb); 1137 length = rt2x00dev->ops->lib->get_tx_data_len(entry);
1138 1138
1139 usb_fill_bulk_urb(bcn_priv->urb, usb_dev, pipe, 1139 usb_fill_bulk_urb(bcn_priv->urb, usb_dev, pipe,
1140 entry->skb->data, length, rt2500usb_beacondone, 1140 entry->skb->data, length, rt2500usb_beacondone,
@@ -1156,8 +1156,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry)
1156 usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC); 1156 usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC);
1157} 1157}
1158 1158
1159static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, 1159static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
1160 struct sk_buff *skb)
1161{ 1160{
1162 int length; 1161 int length;
1163 1162
@@ -1165,8 +1164,8 @@ static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev,
1165 * The length _must_ be a multiple of 2, 1164 * The length _must_ be a multiple of 2,
1166 * but it must _not_ be a multiple of the USB packet size. 1165 * but it must _not_ be a multiple of the USB packet size.
1167 */ 1166 */
1168 length = roundup(skb->len, 2); 1167 length = roundup(entry->skb->len, 2);
1169 length += (2 * !(length % rt2x00dev->usb_maxpacket)); 1168 length += (2 * !(length % entry->queue->usb_maxpacket));
1170 1169
1171 return length; 1170 return length;
1172} 1171}
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index fee61bee1e7e..780ba7365810 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -555,8 +555,7 @@ struct rt2x00lib_ops {
555 struct txentry_desc *txdesc); 555 struct txentry_desc *txdesc);
556 int (*write_tx_data) (struct queue_entry *entry); 556 int (*write_tx_data) (struct queue_entry *entry);
557 void (*write_beacon) (struct queue_entry *entry); 557 void (*write_beacon) (struct queue_entry *entry);
558 int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, 558 int (*get_tx_data_len) (struct queue_entry *entry);
559 struct sk_buff *skb);
560 void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, 559 void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
561 const enum data_queue_qid queue); 560 const enum data_queue_qid queue);
562 561
@@ -799,11 +798,6 @@ struct rt2x00_dev {
799 short lna_gain; 798 short lna_gain;
800 799
801 /* 800 /*
802 * USB Max frame size (for rt2500usb & rt73usb).
803 */
804 u16 usb_maxpacket;
805
806 /*
807 * Current TX power value. 801 * Current TX power value.
808 */ 802 */
809 u16 tx_power; 803 u16 tx_power;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 4d3c7246f9ae..2e99ab53ec65 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -380,6 +380,8 @@ enum queue_index {
380 * @cw_max: The cw max value for outgoing frames (field ignored in RX queue). 380 * @cw_max: The cw max value for outgoing frames (field ignored in RX queue).
381 * @data_size: Maximum data size for the frames in this queue. 381 * @data_size: Maximum data size for the frames in this queue.
382 * @desc_size: Hardware descriptor size for the data in this queue. 382 * @desc_size: Hardware descriptor size for the data in this queue.
383 * @usb_endpoint: Device endpoint used for communication (USB only)
384 * @usb_maxpacket: Max packet size for given endpoint (USB only)
383 */ 385 */
384struct data_queue { 386struct data_queue {
385 struct rt2x00_dev *rt2x00dev; 387 struct rt2x00_dev *rt2x00dev;
@@ -401,6 +403,9 @@ struct data_queue {
401 403
402 unsigned short data_size; 404 unsigned short data_size;
403 unsigned short desc_size; 405 unsigned short desc_size;
406
407 unsigned short usb_endpoint;
408 unsigned short usb_maxpacket;
404}; 409};
405 410
406/** 411/**
@@ -444,6 +449,19 @@ struct data_queue_desc {
444 &(__dev)->tx[(__dev)->ops->tx_queues] 449 &(__dev)->tx[(__dev)->ops->tx_queues]
445 450
446/** 451/**
452 * queue_next - Return pointer to next queue in list (HELPER MACRO).
453 * @__queue: Current queue for which we need the next queue
454 *
455 * Using the current queue address we take the address directly
456 * after the queue to take the next queue. Note that this macro
457 * should be used carefully since it does not protect against
458 * moving past the end of the list. (See macros &queue_end and
459 * &tx_queue_end for determining the end of the queue).
460 */
461#define queue_next(__queue) \
462 &(__queue)[1]
463
464/**
447 * queue_loop - Loop through the queues within a specific range (HELPER MACRO). 465 * queue_loop - Loop through the queues within a specific range (HELPER MACRO).
448 * @__entry: Pointer where the current queue entry will be stored in. 466 * @__entry: Pointer where the current queue entry will be stored in.
449 * @__start: Start queue pointer. 467 * @__start: Start queue pointer.
@@ -453,8 +471,8 @@ struct data_queue_desc {
453 */ 471 */
454#define queue_loop(__entry, __start, __end) \ 472#define queue_loop(__entry, __start, __end) \
455 for ((__entry) = (__start); \ 473 for ((__entry) = (__start); \
456 prefetch(&(__entry)[1]), (__entry) != (__end); \ 474 prefetch(queue_next(__entry)), (__entry) != (__end);\
457 (__entry) = &(__entry)[1]) 475 (__entry) = queue_next(__entry))
458 476
459/** 477/**
460 * queue_for_each - Loop through all queues 478 * queue_for_each - Loop through all queues
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;
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index ee59b4e35cdc..37a782dc8080 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1508,8 +1508,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
1508 entry->skb = NULL; 1508 entry->skb = NULL;
1509} 1509}
1510 1510
1511static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, 1511static int rt73usb_get_tx_data_len(struct queue_entry *entry)
1512 struct sk_buff *skb)
1513{ 1512{
1514 int length; 1513 int length;
1515 1514
@@ -1517,8 +1516,8 @@ static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev,
1517 * The length _must_ be a multiple of 4, 1516 * The length _must_ be a multiple of 4,
1518 * but it must _not_ be a multiple of the USB packet size. 1517 * but it must _not_ be a multiple of the USB packet size.
1519 */ 1518 */
1520 length = roundup(skb->len, 4); 1519 length = roundup(entry->skb->len, 4);
1521 length += (4 * !(length % rt2x00dev->usb_maxpacket)); 1520 length += (4 * !(length % entry->queue->usb_maxpacket));
1522 1521
1523 return length; 1522 return length;
1524} 1523}