aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-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}