rt2x00: Decrease association time for USB devices
authorIvo van Doorn <IvDoorn@gmail.com>
Mon, 18 Apr 2011 13:31:02 +0000 (15:31 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 19 Apr 2011 19:39:37 +0000 (15:39 -0400)
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>
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00pci.h
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rt2x00/rt2x00usb.h
drivers/net/wireless/rt2x00/rt61pci.c

index 5d1654a8bda88cfb958e99fa69e1a567f52285e9..6b7206eddfa532139f4b41a053f6519297b56f5c 100644 (file)
@@ -1740,6 +1740,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
        .start_queue            = rt2400pci_start_queue,
        .kick_queue             = rt2400pci_kick_queue,
        .stop_queue             = rt2400pci_stop_queue,
+       .flush_queue            = rt2x00pci_flush_queue,
        .write_tx_desc          = rt2400pci_write_tx_desc,
        .write_beacon           = rt2400pci_write_beacon,
        .fill_rxdone            = rt2400pci_fill_rxdone,
index 3da954e1b4ab248c47bbf77926c0eecb2311434f..82e8012c7c27d3dbab59105ad881e47ef95bff36 100644 (file)
@@ -2033,6 +2033,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
        .start_queue            = rt2500pci_start_queue,
        .kick_queue             = rt2500pci_kick_queue,
        .stop_queue             = rt2500pci_stop_queue,
+       .flush_queue            = rt2x00pci_flush_queue,
        .write_tx_desc          = rt2500pci_write_tx_desc,
        .write_beacon           = rt2500pci_write_beacon,
        .fill_rxdone            = rt2500pci_fill_rxdone,
index 4241f194384206142ecf273412da71ade20d559a..d2fe5fd6f1eb864b2cb04ee8bccaafbc96903768 100644 (file)
@@ -1057,6 +1057,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
        .start_queue            = rt2800pci_start_queue,
        .kick_queue             = rt2800pci_kick_queue,
        .stop_queue             = rt2800pci_stop_queue,
+       .flush_queue            = rt2x00pci_flush_queue,
        .write_tx_desc          = rt2800pci_write_tx_desc,
        .write_tx_data          = rt2800_write_tx_data,
        .write_beacon           = rt2800_write_beacon,
index 8f37121bb83f1ccf2bae8b47e7fc25eb02ec4866..dcdc50d27ea0055858500148f5ab044e4b581ef0 100644 (file)
@@ -571,7 +571,7 @@ struct rt2x00lib_ops {
        void (*start_queue) (struct data_queue *queue);
        void (*kick_queue) (struct data_queue *queue);
        void (*stop_queue) (struct data_queue *queue);
-       void (*flush_queue) (struct data_queue *queue);
+       void (*flush_queue) (struct data_queue *queue, bool drop);
        void (*tx_dma_done) (struct queue_entry *entry);
 
        /*
index 9649bd0cd7188801ab80bb51d17cfdde7ee1a922..695aecf6bd031aaf906588035ca1ec278802ef95 100644 (file)
@@ -99,6 +99,15 @@ bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
 
+void rt2x00pci_flush_queue(struct data_queue *queue, bool drop)
+{
+       unsigned int i;
+
+       for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++)
+               msleep(10);
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue);
+
 /*
  * Device initialization handlers.
  */
index 07961b8b369a291497df773b64d681b4533a506a..5d5887426f7ad624684fc8dadab10bb5b3186485 100644 (file)
@@ -107,6 +107,16 @@ struct queue_entry_priv_pci {
  */
 bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
 
+/**
+ * rt2x00pci_flush_queue - Flush data queue
+ * @queue: Data queue to stop
+ * @drop: True to drop all pending frames.
+ *
+ * This will wait for a maximum of 100ms, waiting for the queues
+ * to become empty.
+ */
+void rt2x00pci_flush_queue(struct data_queue *queue, bool drop);
+
 /*
  * Device initialization handlers.
  */
index df8817fed09ec3b0e2c72fc884034aeafecda001..0d79278a0a190e8ee4368af3764024d82b8f6930 100644 (file)
@@ -849,7 +849,6 @@ EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue);
 
 void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
 {
-       unsigned int i;
        bool started;
        bool tx_queue =
                (queue->qid == QID_AC_VO) ||
@@ -884,20 +883,12 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
        }
 
        /*
-        * Check if driver supports flushing, we can only guarentee
-        * full support for flushing if the driver is able
-        * to cancel all pending frames (drop = true).
-        */
-       if (drop && queue->rt2x00dev->ops->lib->flush_queue)
-               queue->rt2x00dev->ops->lib->flush_queue(queue);
-
-       /*
-        * When we don't want to drop any frames, or when
-        * the driver doesn't fully flush the queue correcly,
-        * we must wait for the queue to become empty.
+        * Check if driver supports flushing, if that is the case we can
+        * defer the flushing to the driver. Otherwise we must use the
+        * alternative which just waits for the queue to become empty.
         */
-       for (i = 0; !rt2x00queue_empty(queue) && i < 100; i++)
-               msleep(10);
+       if (likely(queue->rt2x00dev->ops->lib->flush_queue))
+               queue->rt2x00dev->ops->lib->flush_queue(queue, drop);
 
        /*
         * The queue flush has failed...
index 34b8a887831bdd0d40ffa69dd82608394dc7ef55..9957579248c4779fb49f14088ec01f0359aa9e17 100644 (file)
@@ -458,13 +458,14 @@ static bool rt2x00usb_flush_entry(struct queue_entry *entry, void* data)
        return false;
 }
 
-void rt2x00usb_flush_queue(struct data_queue *queue)
+void rt2x00usb_flush_queue(struct data_queue *queue, bool drop)
 {
        struct work_struct *completion;
        unsigned int i;
 
-       rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL,
-                                  rt2x00usb_flush_entry);
+       if (drop)
+               rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL,
+                                          rt2x00usb_flush_entry);
 
        /*
         * Obtain the queue completion handler
@@ -483,7 +484,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue)
                return;
        }
 
-       for (i = 0; i < 20; i++) {
+       for (i = 0; i < 10; i++) {
                /*
                 * Check if the driver is already done, otherwise we
                 * have to sleep a little while to give the driver/hw
index e3faca6d2a4f9ab65b831fd1f85546508c4c601f..6aeba71b665b5c04d256963aaaf75cc301313bb0 100644 (file)
@@ -404,11 +404,13 @@ void rt2x00usb_kick_queue(struct data_queue *queue);
 /**
  * rt2x00usb_flush_queue - Flush data queue
  * @queue: Data queue to stop
+ * @drop: True to drop all pending frames.
  *
- * This will walk through all entries of the queue and kill all
- * URB's which were send to the device.
+ * This will walk through all entries of the queue and will optionally
+ * kill all URB's which were send to the device, or at least wait until
+ * they have been returned from the device..
  */
-void rt2x00usb_flush_queue(struct data_queue *queue);
+void rt2x00usb_flush_queue(struct data_queue *queue, bool drop);
 
 /**
  * rt2x00usb_watchdog - Watchdog for USB communication
index c16c1501df18f02c64fd65fb7e23b4494626b31d..35c5d20105a310bdc44e32a8a6ef1f0aa9007111 100644 (file)
@@ -3003,6 +3003,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
        .start_queue            = rt61pci_start_queue,
        .kick_queue             = rt61pci_kick_queue,
        .stop_queue             = rt61pci_stop_queue,
+       .flush_queue            = rt2x00pci_flush_queue,
        .write_tx_desc          = rt61pci_write_tx_desc,
        .write_beacon           = rt61pci_write_beacon,
        .clear_beacon           = rt61pci_clear_beacon,