aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvo van Doorn <IvDoorn@gmail.com>2011-04-18 09:31:02 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-19 15:39:37 -0400
commit152a599274b15028604e24ae2d9c9d7f49853977 (patch)
tree79beecad25449bac7b6f39b6134a267388ad7878
parentf0187a1987ed6524518ff2a533eaf8394ac1a500 (diff)
rt2x00: Decrease association time for USB devices
When powersaving is enabled, assocaition times are very high (for WPA2 networks, the time can easily be around the 3 seconds). This is caused, because the flushing of the queues takes too much time. Without the flushing callback mac80211 assumes a timeout of 100ms while scanning. Limit all flush waiting loops to the same maximum. We can apply this maximum by passing the drop status to the driver, which makes sure the driver performs extra actions during the waiting for the queue to become empty. After these changes, association times fall within the healthy range of ~0.6 seconds with powersaving enabled. The difference between association time between powersaving enabled and disabled is now only ~0.1 second (which can also be due to the measuring method). Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Acked-by: Gertjan van Wingerde <gwingerde@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c9
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c19
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c9
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h8
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c1
10 files changed, 39 insertions, 22 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 5d1654a8bda8..6b7206eddfa5 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1740,6 +1740,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
1740 .start_queue = rt2400pci_start_queue, 1740 .start_queue = rt2400pci_start_queue,
1741 .kick_queue = rt2400pci_kick_queue, 1741 .kick_queue = rt2400pci_kick_queue,
1742 .stop_queue = rt2400pci_stop_queue, 1742 .stop_queue = rt2400pci_stop_queue,
1743 .flush_queue = rt2x00pci_flush_queue,
1743 .write_tx_desc = rt2400pci_write_tx_desc, 1744 .write_tx_desc = rt2400pci_write_tx_desc,
1744 .write_beacon = rt2400pci_write_beacon, 1745 .write_beacon = rt2400pci_write_beacon,
1745 .fill_rxdone = rt2400pci_fill_rxdone, 1746 .fill_rxdone = rt2400pci_fill_rxdone,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 3da954e1b4ab..82e8012c7c27 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -2033,6 +2033,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
2033 .start_queue = rt2500pci_start_queue, 2033 .start_queue = rt2500pci_start_queue,
2034 .kick_queue = rt2500pci_kick_queue, 2034 .kick_queue = rt2500pci_kick_queue,
2035 .stop_queue = rt2500pci_stop_queue, 2035 .stop_queue = rt2500pci_stop_queue,
2036 .flush_queue = rt2x00pci_flush_queue,
2036 .write_tx_desc = rt2500pci_write_tx_desc, 2037 .write_tx_desc = rt2500pci_write_tx_desc,
2037 .write_beacon = rt2500pci_write_beacon, 2038 .write_beacon = rt2500pci_write_beacon,
2038 .fill_rxdone = rt2500pci_fill_rxdone, 2039 .fill_rxdone = rt2500pci_fill_rxdone,
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 4241f1943842..d2fe5fd6f1eb 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -1057,6 +1057,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
1057 .start_queue = rt2800pci_start_queue, 1057 .start_queue = rt2800pci_start_queue,
1058 .kick_queue = rt2800pci_kick_queue, 1058 .kick_queue = rt2800pci_kick_queue,
1059 .stop_queue = rt2800pci_stop_queue, 1059 .stop_queue = rt2800pci_stop_queue,
1060 .flush_queue = rt2x00pci_flush_queue,
1060 .write_tx_desc = rt2800pci_write_tx_desc, 1061 .write_tx_desc = rt2800pci_write_tx_desc,
1061 .write_tx_data = rt2800_write_tx_data, 1062 .write_tx_data = rt2800_write_tx_data,
1062 .write_beacon = rt2800_write_beacon, 1063 .write_beacon = rt2800_write_beacon,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 8f37121bb83f..dcdc50d27ea0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -571,7 +571,7 @@ struct rt2x00lib_ops {
571 void (*start_queue) (struct data_queue *queue); 571 void (*start_queue) (struct data_queue *queue);
572 void (*kick_queue) (struct data_queue *queue); 572 void (*kick_queue) (struct data_queue *queue);
573 void (*stop_queue) (struct data_queue *queue); 573 void (*stop_queue) (struct data_queue *queue);
574 void (*flush_queue) (struct data_queue *queue); 574 void (*flush_queue) (struct data_queue *queue, bool drop);
575 void (*tx_dma_done) (struct queue_entry *entry); 575 void (*tx_dma_done) (struct queue_entry *entry);
576 576
577 /* 577 /*
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 9649bd0cd718..695aecf6bd03 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -99,6 +99,15 @@ bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
99} 99}
100EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); 100EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
101 101
102void rt2x00pci_flush_queue(struct data_queue *queue, bool drop)
103{
104 unsigned int i;
105
106 for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++)
107 msleep(10);
108}
109EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue);
110
102/* 111/*
103 * Device initialization handlers. 112 * Device initialization handlers.
104 */ 113 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 07961b8b369a..5d5887426f7a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -107,6 +107,16 @@ struct queue_entry_priv_pci {
107 */ 107 */
108bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); 108bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
109 109
110/**
111 * rt2x00pci_flush_queue - Flush data queue
112 * @queue: Data queue to stop
113 * @drop: True to drop all pending frames.
114 *
115 * This will wait for a maximum of 100ms, waiting for the queues
116 * to become empty.
117 */
118void rt2x00pci_flush_queue(struct data_queue *queue, bool drop);
119
110/* 120/*
111 * Device initialization handlers. 121 * Device initialization handlers.
112 */ 122 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index df8817fed09e..0d79278a0a19 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -849,7 +849,6 @@ EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue);
849 849
850void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) 850void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
851{ 851{
852 unsigned int i;
853 bool started; 852 bool started;
854 bool tx_queue = 853 bool tx_queue =
855 (queue->qid == QID_AC_VO) || 854 (queue->qid == QID_AC_VO) ||
@@ -884,20 +883,12 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
884 } 883 }
885 884
886 /* 885 /*
887 * Check if driver supports flushing, we can only guarentee 886 * Check if driver supports flushing, if that is the case we can
888 * full support for flushing if the driver is able 887 * defer the flushing to the driver. Otherwise we must use the
889 * to cancel all pending frames (drop = true). 888 * alternative which just waits for the queue to become empty.
890 */
891 if (drop && queue->rt2x00dev->ops->lib->flush_queue)
892 queue->rt2x00dev->ops->lib->flush_queue(queue);
893
894 /*
895 * When we don't want to drop any frames, or when
896 * the driver doesn't fully flush the queue correcly,
897 * we must wait for the queue to become empty.
898 */ 889 */
899 for (i = 0; !rt2x00queue_empty(queue) && i < 100; i++) 890 if (likely(queue->rt2x00dev->ops->lib->flush_queue))
900 msleep(10); 891 queue->rt2x00dev->ops->lib->flush_queue(queue, drop);
901 892
902 /* 893 /*
903 * The queue flush has failed... 894 * The queue flush has failed...
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 34b8a887831b..9957579248c4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -458,13 +458,14 @@ static bool rt2x00usb_flush_entry(struct queue_entry *entry, void* data)
458 return false; 458 return false;
459} 459}
460 460
461void rt2x00usb_flush_queue(struct data_queue *queue) 461void rt2x00usb_flush_queue(struct data_queue *queue, bool drop)
462{ 462{
463 struct work_struct *completion; 463 struct work_struct *completion;
464 unsigned int i; 464 unsigned int i;
465 465
466 rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL, 466 if (drop)
467 rt2x00usb_flush_entry); 467 rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL,
468 rt2x00usb_flush_entry);
468 469
469 /* 470 /*
470 * Obtain the queue completion handler 471 * Obtain the queue completion handler
@@ -483,7 +484,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue)
483 return; 484 return;
484 } 485 }
485 486
486 for (i = 0; i < 20; i++) { 487 for (i = 0; i < 10; i++) {
487 /* 488 /*
488 * Check if the driver is already done, otherwise we 489 * Check if the driver is already done, otherwise we
489 * have to sleep a little while to give the driver/hw 490 * have to sleep a little while to give the driver/hw
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index e3faca6d2a4f..6aeba71b665b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -404,11 +404,13 @@ void rt2x00usb_kick_queue(struct data_queue *queue);
404/** 404/**
405 * rt2x00usb_flush_queue - Flush data queue 405 * rt2x00usb_flush_queue - Flush data queue
406 * @queue: Data queue to stop 406 * @queue: Data queue to stop
407 * @drop: True to drop all pending frames.
407 * 408 *
408 * This will walk through all entries of the queue and kill all 409 * This will walk through all entries of the queue and will optionally
409 * URB's which were send to the device. 410 * kill all URB's which were send to the device, or at least wait until
411 * they have been returned from the device..
410 */ 412 */
411void rt2x00usb_flush_queue(struct data_queue *queue); 413void rt2x00usb_flush_queue(struct data_queue *queue, bool drop);
412 414
413/** 415/**
414 * rt2x00usb_watchdog - Watchdog for USB communication 416 * rt2x00usb_watchdog - Watchdog for USB communication
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index c16c1501df18..35c5d20105a3 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -3003,6 +3003,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
3003 .start_queue = rt61pci_start_queue, 3003 .start_queue = rt61pci_start_queue,
3004 .kick_queue = rt61pci_kick_queue, 3004 .kick_queue = rt61pci_kick_queue,
3005 .stop_queue = rt61pci_stop_queue, 3005 .stop_queue = rt61pci_stop_queue,
3006 .flush_queue = rt2x00pci_flush_queue,
3006 .write_tx_desc = rt61pci_write_tx_desc, 3007 .write_tx_desc = rt61pci_write_tx_desc,
3007 .write_beacon = rt61pci_write_beacon, 3008 .write_beacon = rt61pci_write_beacon,
3008 .clear_beacon = rt61pci_clear_beacon, 3009 .clear_beacon = rt61pci_clear_beacon,