aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00.h
diff options
context:
space:
mode:
authorHelmut Schaa <helmut.schaa@googlemail.com>2010-10-02 05:27:35 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-05 13:35:26 -0400
commit96c3da7d7d7c37ee308ad6813947f48a71cca573 (patch)
tree525a6031138d4e4fbe8cd487f5fb3a42db50cb2f /drivers/net/wireless/rt2x00/rt2x00.h
parent144333313b156a9e99d80e39e034a3cba00adeaf (diff)
rt2x00: rework tx status handling in rt2800pci
This patch changes the way tx status reports are handled by rt2800pci. Previously rt2800pci would sometimes lose tx status reports as the TX_STA_FIFO register is a fifo of 16 entries that can overflow in case we don't read it often/fast enough. Since interrupts are disabled in the device during the execution of the interrupt thread it happend sometimes under high network and CPU load that processing took too long and a few tx status reports were dropped by the hw. To fix this issue the TX_STA_FIFO register is read directly in the interrupt handler and stored in a kfifo which is large enough to hold all status reports of all used tx queues. To process the status reports a new tasklet txstatus_tasklet is used. Using the already used interrupt thread is not possible since we don't want to disable the TX_FIFO_STATUS interrupt while processing them and it is not possible to schedule the interrupt thread multiple times for execution. A tasklet instead can be scheduled multiple times which allows to leave the TX_FIFO_STATUS interrupt enabled while a previously scheduled tasklet is still executing. In short: All other interrupts are handled in the interrupt thread as before. Only the TX_FIFO_STATUS interrupt is partly handled in the interrupt handler and finished in the according tasklet. One drawback of this patch is that it duplicates some code from rt2800lib. However, that can be cleaned up in the future once the rt2800usb and rt2800pci tx status handling converge more. Using this patch on a Ralink RT3052 embedded board gives me a reliable wireless connection even under high CPU and network load. I've transferred several gigabytes without any queue lockups. Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00.h')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 7832a5996a8c..bab10adae537 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -36,6 +36,7 @@
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/etherdevice.h> 37#include <linux/etherdevice.h>
38#include <linux/input-polldev.h> 38#include <linux/input-polldev.h>
39#include <linux/kfifo.h>
39 40
40#include <net/mac80211.h> 41#include <net/mac80211.h>
41 42
@@ -522,6 +523,11 @@ struct rt2x00lib_ops {
522 irq_handler_t irq_handler_thread; 523 irq_handler_t irq_handler_thread;
523 524
524 /* 525 /*
526 * TX status tasklet handler.
527 */
528 void (*txstatus_tasklet) (unsigned long data);
529
530 /*
525 * Device init handlers. 531 * Device init handlers.
526 */ 532 */
527 int (*probe_hw) (struct rt2x00_dev *rt2x00dev); 533 int (*probe_hw) (struct rt2x00_dev *rt2x00dev);
@@ -651,6 +657,7 @@ enum rt2x00_flags {
651 DRIVER_REQUIRE_DMA, 657 DRIVER_REQUIRE_DMA,
652 DRIVER_REQUIRE_COPY_IV, 658 DRIVER_REQUIRE_COPY_IV,
653 DRIVER_REQUIRE_L2PAD, 659 DRIVER_REQUIRE_L2PAD,
660 DRIVER_REQUIRE_TXSTATUS_FIFO,
654 661
655 /* 662 /*
656 * Driver features 663 * Driver features
@@ -884,6 +891,16 @@ struct rt2x00_dev {
884 * and interrupt thread routine. 891 * and interrupt thread routine.
885 */ 892 */
886 u32 irqvalue[2]; 893 u32 irqvalue[2];
894
895 /*
896 * FIFO for storing tx status reports between isr and tasklet.
897 */
898 struct kfifo txstatus_fifo;
899
900 /*
901 * Tasklet for processing tx status reports (rt2800pci).
902 */
903 struct tasklet_struct txstatus_tasklet;
887}; 904};
888 905
889/* 906/*