diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2010-12-13 06:35:40 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-12-13 15:23:35 -0500 |
commit | 5be65609fec2e331c7d804471be3d59089a30d98 (patch) | |
tree | 6c6967c7835d6ec3a8ce79c2c9b84bf95aefca31 /drivers/net | |
parent | 0b7fde54f94979edc67bbf86b5adba702ebfefe8 (diff) |
rt2x00: Add "flush" queue command
Add a new command to the queue handlers: "flush",
this moves the flush() callback from mac80211
into rt2x00queue and adds support for flushing
the RX queue as well.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Acked-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 21 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 32 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 85 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 70 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 3 |
9 files changed, 161 insertions, 61 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index a56b38f9bf29..6b3b1de46792 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -785,8 +785,6 @@ static void rt2500usb_stop_queue(struct data_queue *queue) | |||
785 | default: | 785 | default: |
786 | break; | 786 | break; |
787 | } | 787 | } |
788 | |||
789 | rt2x00usb_stop_queue(queue); | ||
790 | } | 788 | } |
791 | 789 | ||
792 | /* | 790 | /* |
@@ -1842,6 +1840,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1842 | .start_queue = rt2500usb_start_queue, | 1840 | .start_queue = rt2500usb_start_queue, |
1843 | .kick_queue = rt2x00usb_kick_queue, | 1841 | .kick_queue = rt2x00usb_kick_queue, |
1844 | .stop_queue = rt2500usb_stop_queue, | 1842 | .stop_queue = rt2500usb_stop_queue, |
1843 | .flush_queue = rt2x00usb_flush_queue, | ||
1845 | .write_tx_desc = rt2500usb_write_tx_desc, | 1844 | .write_tx_desc = rt2500usb_write_tx_desc, |
1846 | .write_beacon = rt2500usb_write_beacon, | 1845 | .write_beacon = rt2500usb_write_beacon, |
1847 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1846 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 60b550313688..3e0205ddf7b4 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -96,8 +96,6 @@ static void rt2800usb_stop_queue(struct data_queue *queue) | |||
96 | default: | 96 | default: |
97 | break; | 97 | break; |
98 | } | 98 | } |
99 | |||
100 | rt2x00usb_stop_queue(queue); | ||
101 | } | 99 | } |
102 | 100 | ||
103 | /* | 101 | /* |
@@ -623,6 +621,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | |||
623 | .start_queue = rt2800usb_start_queue, | 621 | .start_queue = rt2800usb_start_queue, |
624 | .kick_queue = rt2x00usb_kick_queue, | 622 | .kick_queue = rt2x00usb_kick_queue, |
625 | .stop_queue = rt2800usb_stop_queue, | 623 | .stop_queue = rt2800usb_stop_queue, |
624 | .flush_queue = rt2x00usb_flush_queue, | ||
626 | .write_tx_desc = rt2800usb_write_tx_desc, | 625 | .write_tx_desc = rt2800usb_write_tx_desc, |
627 | .write_tx_data = rt2800usb_write_tx_data, | 626 | .write_tx_data = rt2800usb_write_tx_data, |
628 | .write_beacon = rt2800_write_beacon, | 627 | .write_beacon = rt2800_write_beacon, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index ac7c3d80300e..1d7b481ec357 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -575,6 +575,7 @@ struct rt2x00lib_ops { | |||
575 | void (*start_queue) (struct data_queue *queue); | 575 | void (*start_queue) (struct data_queue *queue); |
576 | void (*kick_queue) (struct data_queue *queue); | 576 | void (*kick_queue) (struct data_queue *queue); |
577 | void (*stop_queue) (struct data_queue *queue); | 577 | void (*stop_queue) (struct data_queue *queue); |
578 | void (*flush_queue) (struct data_queue *queue); | ||
578 | 579 | ||
579 | /* | 580 | /* |
580 | * TX control handlers | 581 | * TX control handlers |
@@ -1109,6 +1110,16 @@ void rt2x00queue_start_queue(struct data_queue *queue); | |||
1109 | void rt2x00queue_stop_queue(struct data_queue *queue); | 1110 | void rt2x00queue_stop_queue(struct data_queue *queue); |
1110 | 1111 | ||
1111 | /** | 1112 | /** |
1113 | * rt2x00queue_flush_queue - Flush a data queue | ||
1114 | * @queue: Pointer to &struct data_queue. | ||
1115 | * @drop: True to drop all pending frames. | ||
1116 | * | ||
1117 | * This function will flush the queue. After this call | ||
1118 | * the queue is guarenteed to be empty. | ||
1119 | */ | ||
1120 | void rt2x00queue_flush_queue(struct data_queue *queue, bool drop); | ||
1121 | |||
1122 | /** | ||
1112 | * rt2x00queue_start_queues - Start all data queues | 1123 | * rt2x00queue_start_queues - Start all data queues |
1113 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | 1124 | * @rt2x00dev: Pointer to &struct rt2x00_dev. |
1114 | * | 1125 | * |
@@ -1125,6 +1136,16 @@ void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev); | |||
1125 | */ | 1136 | */ |
1126 | void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev); | 1137 | void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev); |
1127 | 1138 | ||
1139 | /** | ||
1140 | * rt2x00queue_flush_queues - Flush all data queues | ||
1141 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
1142 | * @drop: True to drop all pending frames. | ||
1143 | * | ||
1144 | * This function will loop through all available queues to flush | ||
1145 | * any pending frames. | ||
1146 | */ | ||
1147 | void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop); | ||
1148 | |||
1128 | /* | 1149 | /* |
1129 | * Debugfs handlers. | 1150 | * Debugfs handlers. |
1130 | */ | 1151 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e42816286ffc..9ef5a2468216 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -94,6 +94,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
94 | */ | 94 | */ |
95 | rt2x00link_stop_tuner(rt2x00dev); | 95 | rt2x00link_stop_tuner(rt2x00dev); |
96 | rt2x00queue_stop_queues(rt2x00dev); | 96 | rt2x00queue_stop_queues(rt2x00dev); |
97 | rt2x00queue_flush_queues(rt2x00dev, true); | ||
97 | 98 | ||
98 | /* | 99 | /* |
99 | * Disable radio. | 100 | * Disable radio. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c4abb204aeda..4cac7ad60f47 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -718,36 +718,8 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop) | |||
718 | { | 718 | { |
719 | struct rt2x00_dev *rt2x00dev = hw->priv; | 719 | struct rt2x00_dev *rt2x00dev = hw->priv; |
720 | struct data_queue *queue; | 720 | struct data_queue *queue; |
721 | unsigned int i = 0; | ||
722 | 721 | ||
723 | ieee80211_stop_queues(hw); | 722 | tx_queue_for_each(rt2x00dev, queue) |
724 | 723 | rt2x00queue_flush_queue(queue, drop); | |
725 | /* | ||
726 | * Run over all queues to kick them, this will force | ||
727 | * any pending frames to be transmitted. | ||
728 | */ | ||
729 | tx_queue_for_each(rt2x00dev, queue) { | ||
730 | rt2x00dev->ops->lib->kick_queue(queue); | ||
731 | } | ||
732 | |||
733 | /** | ||
734 | * All queues have been kicked, now wait for each queue | ||
735 | * to become empty. With a bit of luck, we only have to wait | ||
736 | * for the first queue to become empty, because while waiting | ||
737 | * for the that queue, the other queues will have transmitted | ||
738 | * all their frames as well (since they were already kicked). | ||
739 | */ | ||
740 | tx_queue_for_each(rt2x00dev, queue) { | ||
741 | for (i = 0; i < 10; i++) { | ||
742 | if (rt2x00queue_empty(queue)) | ||
743 | break; | ||
744 | msleep(100); | ||
745 | } | ||
746 | |||
747 | if (!rt2x00queue_empty(queue)) | ||
748 | WARNING(rt2x00dev, "Failed to flush queue %d\n", queue->qid); | ||
749 | } | ||
750 | |||
751 | ieee80211_wake_queues(hw); | ||
752 | } | 724 | } |
753 | EXPORT_SYMBOL_GPL(rt2x00mac_flush); | 725 | EXPORT_SYMBOL_GPL(rt2x00mac_flush); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 558965fb41b3..313a8faa5fa4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -780,6 +780,12 @@ void rt2x00queue_unpause_queue(struct data_queue *queue) | |||
780 | */ | 780 | */ |
781 | ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid); | 781 | ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid); |
782 | break; | 782 | break; |
783 | case QID_RX: | ||
784 | /* | ||
785 | * For RX we need to kick the queue now in order to | ||
786 | * receive frames. | ||
787 | */ | ||
788 | queue->rt2x00dev->ops->lib->kick_queue(queue); | ||
783 | default: | 789 | default: |
784 | break; | 790 | break; |
785 | } | 791 | } |
@@ -823,6 +829,74 @@ void rt2x00queue_stop_queue(struct data_queue *queue) | |||
823 | } | 829 | } |
824 | EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue); | 830 | EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue); |
825 | 831 | ||
832 | void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) | ||
833 | { | ||
834 | unsigned int i; | ||
835 | bool started; | ||
836 | bool tx_queue = | ||
837 | (queue->qid == QID_AC_BE) || | ||
838 | (queue->qid == QID_AC_BK) || | ||
839 | (queue->qid == QID_AC_VI) || | ||
840 | (queue->qid == QID_AC_VO); | ||
841 | |||
842 | mutex_lock(&queue->status_lock); | ||
843 | |||
844 | /* | ||
845 | * If the queue has been started, we must stop it temporarily | ||
846 | * to prevent any new frames to be queued on the device. If | ||
847 | * we are not dropping the pending frames, the queue must | ||
848 | * only be stopped in the software and not the hardware, | ||
849 | * otherwise the queue will never become empty on its own. | ||
850 | */ | ||
851 | started = test_bit(QUEUE_STARTED, &queue->flags); | ||
852 | if (started) { | ||
853 | /* | ||
854 | * Pause the queue | ||
855 | */ | ||
856 | rt2x00queue_pause_queue(queue); | ||
857 | |||
858 | /* | ||
859 | * If we are not supposed to drop any pending | ||
860 | * frames, this means we must force a start (=kick) | ||
861 | * to the queue to make sure the hardware will | ||
862 | * start transmitting. | ||
863 | */ | ||
864 | if (!drop && tx_queue) | ||
865 | queue->rt2x00dev->ops->lib->kick_queue(queue); | ||
866 | } | ||
867 | |||
868 | /* | ||
869 | * Check if driver supports flushing, we can only guarentee | ||
870 | * full support for flushing if the driver is able | ||
871 | * to cancel all pending frames (drop = true). | ||
872 | */ | ||
873 | if (drop && queue->rt2x00dev->ops->lib->flush_queue) | ||
874 | queue->rt2x00dev->ops->lib->flush_queue(queue); | ||
875 | |||
876 | /* | ||
877 | * When we don't want to drop any frames, or when | ||
878 | * the driver doesn't fully flush the queue correcly, | ||
879 | * we must wait for the queue to become empty. | ||
880 | */ | ||
881 | for (i = 0; !rt2x00queue_empty(queue) && i < 100; i++) | ||
882 | msleep(10); | ||
883 | |||
884 | /* | ||
885 | * The queue flush has failed... | ||
886 | */ | ||
887 | if (unlikely(!rt2x00queue_empty(queue))) | ||
888 | WARNING(queue->rt2x00dev, "Queue %d failed to flush", queue->qid); | ||
889 | |||
890 | /* | ||
891 | * Restore the queue to the previous status | ||
892 | */ | ||
893 | if (started) | ||
894 | rt2x00queue_unpause_queue(queue); | ||
895 | |||
896 | mutex_unlock(&queue->status_lock); | ||
897 | } | ||
898 | EXPORT_SYMBOL_GPL(rt2x00queue_flush_queue); | ||
899 | |||
826 | void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev) | 900 | void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev) |
827 | { | 901 | { |
828 | struct data_queue *queue; | 902 | struct data_queue *queue; |
@@ -857,6 +931,17 @@ void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) | |||
857 | } | 931 | } |
858 | EXPORT_SYMBOL_GPL(rt2x00queue_stop_queues); | 932 | EXPORT_SYMBOL_GPL(rt2x00queue_stop_queues); |
859 | 933 | ||
934 | void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop) | ||
935 | { | ||
936 | struct data_queue *queue; | ||
937 | |||
938 | tx_queue_for_each(rt2x00dev, queue) | ||
939 | rt2x00queue_flush_queue(queue, drop); | ||
940 | |||
941 | rt2x00queue_flush_queue(rt2x00dev->rx, drop); | ||
942 | } | ||
943 | EXPORT_SYMBOL_GPL(rt2x00queue_flush_queues); | ||
944 | |||
860 | static void rt2x00queue_reset(struct data_queue *queue) | 945 | static void rt2x00queue_reset(struct data_queue *queue) |
861 | { | 946 | { |
862 | unsigned long irqflags; | 947 | unsigned long irqflags; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index fca29ae57e71..cd80eec5ff51 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -366,7 +366,7 @@ void rt2x00usb_kick_queue(struct data_queue *queue) | |||
366 | } | 366 | } |
367 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); | 367 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); |
368 | 368 | ||
369 | static void rt2x00usb_kill_entry(struct queue_entry *entry) | 369 | static void rt2x00usb_flush_entry(struct queue_entry *entry) |
370 | { | 370 | { |
371 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 371 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
372 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 372 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
@@ -385,37 +385,61 @@ static void rt2x00usb_kill_entry(struct queue_entry *entry) | |||
385 | usb_kill_urb(bcn_priv->guardian_urb); | 385 | usb_kill_urb(bcn_priv->guardian_urb); |
386 | } | 386 | } |
387 | 387 | ||
388 | void rt2x00usb_stop_queue(struct data_queue *queue) | 388 | void rt2x00usb_flush_queue(struct data_queue *queue) |
389 | { | 389 | { |
390 | struct work_struct *completion; | ||
391 | unsigned int i; | ||
392 | |||
390 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, | 393 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, |
391 | rt2x00usb_kill_entry); | 394 | rt2x00usb_flush_entry); |
395 | |||
396 | /* | ||
397 | * Obtain the queue completion handler | ||
398 | */ | ||
399 | switch (queue->qid) { | ||
400 | case QID_AC_BE: | ||
401 | case QID_AC_BK: | ||
402 | case QID_AC_VI: | ||
403 | case QID_AC_VO: | ||
404 | completion = &queue->rt2x00dev->txdone_work; | ||
405 | break; | ||
406 | case QID_RX: | ||
407 | completion = &queue->rt2x00dev->rxdone_work; | ||
408 | break; | ||
409 | default: | ||
410 | return; | ||
411 | } | ||
412 | |||
413 | for (i = 0; i < 20; i++) { | ||
414 | /* | ||
415 | * Check if the driver is already done, otherwise we | ||
416 | * have to sleep a little while to give the driver/hw | ||
417 | * the oppurtunity to complete interrupt process itself. | ||
418 | */ | ||
419 | if (rt2x00queue_empty(queue)) | ||
420 | break; | ||
421 | |||
422 | /* | ||
423 | * Schedule the completion handler manually, when this | ||
424 | * worker function runs, it should cleanup the queue. | ||
425 | */ | ||
426 | ieee80211_queue_work(queue->rt2x00dev->hw, completion); | ||
427 | |||
428 | /* | ||
429 | * Wait for a little while to give the driver | ||
430 | * the oppurtunity to recover itself. | ||
431 | */ | ||
432 | msleep(10); | ||
433 | } | ||
392 | } | 434 | } |
393 | EXPORT_SYMBOL_GPL(rt2x00usb_stop_queue); | 435 | EXPORT_SYMBOL_GPL(rt2x00usb_flush_queue); |
394 | 436 | ||
395 | static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) | 437 | static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) |
396 | { | 438 | { |
397 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
398 | |||
399 | WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," | 439 | WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," |
400 | " invoke forced forced reset\n", queue->qid); | 440 | " invoke forced forced reset\n", queue->qid); |
401 | 441 | ||
402 | /* | 442 | rt2x00queue_flush_queue(queue, true); |
403 | * Temporarily disable the TX queue, this will force mac80211 | ||
404 | * to use the other queues until this queue has been restored. | ||
405 | */ | ||
406 | rt2x00queue_stop_queue(queue); | ||
407 | |||
408 | /* | ||
409 | * In case that a driver has overriden the txdone_work | ||
410 | * function, we invoke the TX done through there. | ||
411 | */ | ||
412 | rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work); | ||
413 | |||
414 | /* | ||
415 | * The queue has been reset, and mac80211 is allowed to use the | ||
416 | * queue again. | ||
417 | */ | ||
418 | rt2x00queue_start_queue(queue); | ||
419 | } | 443 | } |
420 | 444 | ||
421 | static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) | 445 | static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 05a5424d9b76..6aaf51fc7ad8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -387,13 +387,13 @@ struct queue_entry_priv_usb_bcn { | |||
387 | void rt2x00usb_kick_queue(struct data_queue *queue); | 387 | void rt2x00usb_kick_queue(struct data_queue *queue); |
388 | 388 | ||
389 | /** | 389 | /** |
390 | * rt2x00usb_stop_queue - Stop data queue | 390 | * rt2x00usb_flush_queue - Flush data queue |
391 | * @queue: Data queue to stop | 391 | * @queue: Data queue to stop |
392 | * | 392 | * |
393 | * This will walk through all entries of the queue and kill all | 393 | * This will walk through all entries of the queue and kill all |
394 | * URB's which were send to the device. | 394 | * URB's which were send to the device. |
395 | */ | 395 | */ |
396 | void rt2x00usb_stop_queue(struct data_queue *queue); | 396 | void rt2x00usb_flush_queue(struct data_queue *queue); |
397 | 397 | ||
398 | /** | 398 | /** |
399 | * rt2x00usb_watchdog - Watchdog for USB communication | 399 | * rt2x00usb_watchdog - Watchdog for USB communication |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index f55e74ef02e0..0b3959bdd3eb 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1077,8 +1077,6 @@ static void rt73usb_stop_queue(struct data_queue *queue) | |||
1077 | default: | 1077 | default: |
1078 | break; | 1078 | break; |
1079 | } | 1079 | } |
1080 | |||
1081 | rt2x00usb_stop_queue(queue); | ||
1082 | } | 1080 | } |
1083 | 1081 | ||
1084 | /* | 1082 | /* |
@@ -2309,6 +2307,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2309 | .start_queue = rt73usb_start_queue, | 2307 | .start_queue = rt73usb_start_queue, |
2310 | .kick_queue = rt2x00usb_kick_queue, | 2308 | .kick_queue = rt2x00usb_kick_queue, |
2311 | .stop_queue = rt73usb_stop_queue, | 2309 | .stop_queue = rt73usb_stop_queue, |
2310 | .flush_queue = rt2x00usb_flush_queue, | ||
2312 | .write_tx_desc = rt73usb_write_tx_desc, | 2311 | .write_tx_desc = rt73usb_write_tx_desc, |
2313 | .write_beacon = rt73usb_write_beacon, | 2312 | .write_beacon = rt73usb_write_beacon, |
2314 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2313 | .get_tx_data_len = rt73usb_get_tx_data_len, |