From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
To: linux-wireless@vger.kernel.org
Cc: Daniel Drake <dsd@gentoo.org>,
"John W. Linville" <linville@tuxdriver.com>,
Ulrich Kunitz <kune@deine-taler.de>
Subject: [PATCH 20/22] zd1211rw: reset rx urbs after idle period of 30 seconds
Date: Mon, 31 Jan 2011 20:50:12 +0200 [thread overview]
Message-ID: <20110131185012.10044.21341.stgit@fate.lan> (raw)
In-Reply-To: <20110131184657.10044.98610.stgit@fate.lan>
RX appears to freeze while idle. Resetting rx-urbs appears to be enough to fix
this. Do reset 30 seconds after last rx.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/zd1211rw/zd_usb.c | 79 +++++++++++++++++++++++++++++++-
drivers/net/wireless/zd1211rw/zd_usb.h | 7 ++-
2 files changed, 83 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 00c333f..5cedfea 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -638,6 +638,8 @@ static void rx_urb_complete(struct urb *urb)
usb = urb->context;
rx = &usb->rx;
+ zd_usb_reset_rx_idle_timer(usb);
+
if (length%rx->usb_packet_size > rx->usb_packet_size-4) {
/* If there is an old first fragment, we don't care. */
dev_dbg_f(urb_dev(urb), "*** first fragment ***\n");
@@ -702,7 +704,7 @@ static void free_rx_urb(struct urb *urb)
usb_free_urb(urb);
}
-int zd_usb_enable_rx(struct zd_usb *usb)
+static int __zd_usb_enable_rx(struct zd_usb *usb)
{
int i, r;
struct zd_usb_rx *rx = &usb->rx;
@@ -754,7 +756,21 @@ error:
return r;
}
-void zd_usb_disable_rx(struct zd_usb *usb)
+int zd_usb_enable_rx(struct zd_usb *usb)
+{
+ int r;
+ struct zd_usb_rx *rx = &usb->rx;
+
+ mutex_lock(&rx->setup_mutex);
+ r = __zd_usb_enable_rx(usb);
+ mutex_unlock(&rx->setup_mutex);
+
+ zd_usb_reset_rx_idle_timer(usb);
+
+ return r;
+}
+
+static void __zd_usb_disable_rx(struct zd_usb *usb)
{
int i;
unsigned long flags;
@@ -781,6 +797,40 @@ void zd_usb_disable_rx(struct zd_usb *usb)
spin_unlock_irqrestore(&rx->lock, flags);
}
+void zd_usb_disable_rx(struct zd_usb *usb)
+{
+ struct zd_usb_rx *rx = &usb->rx;
+
+ mutex_lock(&rx->setup_mutex);
+ __zd_usb_disable_rx(usb);
+ mutex_unlock(&rx->setup_mutex);
+
+ cancel_delayed_work_sync(&rx->idle_work);
+}
+
+static void zd_usb_reset_rx(struct zd_usb *usb)
+{
+ bool do_reset;
+ struct zd_usb_rx *rx = &usb->rx;
+ unsigned long flags;
+
+ mutex_lock(&rx->setup_mutex);
+
+ spin_lock_irqsave(&rx->lock, flags);
+ do_reset = rx->urbs != NULL;
+ spin_unlock_irqrestore(&rx->lock, flags);
+
+ if (do_reset) {
+ __zd_usb_disable_rx(usb);
+ __zd_usb_enable_rx(usb);
+ }
+
+ mutex_unlock(&rx->setup_mutex);
+
+ if (do_reset)
+ zd_usb_reset_rx_idle_timer(usb);
+}
+
/**
* zd_usb_disable_tx - disable transmission
* @usb: the zd1211rw-private USB structure
@@ -1033,6 +1083,29 @@ void zd_tx_watchdog_disable(struct zd_usb *usb)
}
}
+static void zd_rx_idle_timer_handler(struct work_struct *work)
+{
+ struct zd_usb *usb =
+ container_of(work, struct zd_usb, rx.idle_work.work);
+ struct zd_mac *mac = zd_usb_to_mac(usb);
+
+ if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags))
+ return;
+
+ dev_dbg_f(zd_usb_dev(usb), "\n");
+
+ /* 30 seconds since last rx, reset rx */
+ zd_usb_reset_rx(usb);
+}
+
+void zd_usb_reset_rx_idle_timer(struct zd_usb *usb)
+{
+ struct zd_usb_rx *rx = &usb->rx;
+
+ cancel_delayed_work(&rx->idle_work);
+ queue_delayed_work(zd_workqueue, &rx->idle_work, ZD_RX_IDLE_INTERVAL);
+}
+
static inline void init_usb_interrupt(struct zd_usb *usb)
{
struct zd_usb_interrupt *intr = &usb->intr;
@@ -1047,12 +1120,14 @@ static inline void init_usb_rx(struct zd_usb *usb)
{
struct zd_usb_rx *rx = &usb->rx;
spin_lock_init(&rx->lock);
+ mutex_init(&rx->setup_mutex);
if (interface_to_usbdev(usb->intf)->speed == USB_SPEED_HIGH) {
rx->usb_packet_size = 512;
} else {
rx->usb_packet_size = 64;
}
ZD_ASSERT(rx->fragment_length == 0);
+ INIT_DELAYED_WORK(&rx->idle_work, zd_rx_idle_timer_handler);
}
static inline void init_usb_tx(struct zd_usb *usb)
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
index 98f09c2..2d688f4 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.h
+++ b/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -34,6 +34,7 @@
#define ZD_TX_TIMEOUT (HZ * 5)
#define ZD_TX_WATCHDOG_INTERVAL round_jiffies_relative(HZ)
+#define ZD_RX_IDLE_INTERVAL round_jiffies_relative(30 * HZ)
enum devicetype {
DEVICE_ZD1211 = 0,
@@ -180,7 +181,9 @@ static inline struct usb_int_regs *get_read_regs(struct zd_usb_interrupt *intr)
struct zd_usb_rx {
spinlock_t lock;
- u8 fragment[2*USB_MAX_RX_SIZE];
+ struct mutex setup_mutex;
+ struct delayed_work idle_work;
+ u8 fragment[2 * USB_MAX_RX_SIZE];
unsigned int fragment_length;
unsigned int usb_packet_size;
struct urb **urbs;
@@ -251,6 +254,8 @@ void zd_usb_disable_int(struct zd_usb *usb);
int zd_usb_enable_rx(struct zd_usb *usb);
void zd_usb_disable_rx(struct zd_usb *usb);
+void zd_usb_reset_rx_idle_timer(struct zd_usb *usb);
+
void zd_usb_enable_tx(struct zd_usb *usb);
void zd_usb_disable_tx(struct zd_usb *usb);
next prev parent reply other threads:[~2011-01-31 18:50 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-31 18:46 [PATCH 00/22] zd1211rw: add support for AP-mode Jussi Kivilinna
2011-01-31 18:47 ` [PATCH 01/22] zd1211rw: use urb anchors for tx and fix tx-queue disabling Jussi Kivilinna
2011-01-31 18:47 ` [PATCH 02/22] zd1211rw: cancel process_intr work on zd_chip_disable_int() Jussi Kivilinna
2011-01-31 18:47 ` [PATCH 03/22] zd1211rw: add locking for mac->process_intr Jussi Kivilinna
2011-01-31 18:47 ` [PATCH 04/22] zd1211rw: fix beacon interval setup Jussi Kivilinna
2011-01-31 18:47 ` [PATCH 05/22] zd1211rw: move set_multicast_hash and set_rx_filter from workers to configure_filter Jussi Kivilinna
2011-01-31 18:47 ` [PATCH 06/22] zd1211rw: move set_rts_cts_work to bss_info_changed Jussi Kivilinna
2011-01-31 18:48 ` [PATCH 07/22] zd1211rw: support setting BSSID for AP mode Jussi Kivilinna
2011-01-31 18:48 ` [PATCH 08/22] zd1211rw: fix ack_pending in filter_ack causing tx-packet ordering problem on monitor Jussi Kivilinna
2011-01-31 18:48 ` [PATCH 09/22] zd1211rw: let zd_set_beacon_interval() set dtim_period and add AP-beacon flag Jussi Kivilinna
2011-01-31 18:48 ` [PATCH 10/22] zd1211rw: implement beacon fetching and handling ieee80211_get_buffered_bc() Jussi Kivilinna
2011-01-31 18:48 ` [PATCH 11/22] mac80211: fix race between next beacon dtim and ieee80211_get_buffered_bc Jussi Kivilinna
2011-01-31 18:48 ` [PATCH 12/22] zd1211rw: add beacon watchdog and setting HW beacon more failsafe Jussi Kivilinna
2011-01-31 18:49 ` [PATCH 13/22] zd1211rw: batch beacon config commands together Jussi Kivilinna
2011-01-31 18:49 ` [PATCH 14/22] [v2] zd1211rw: use stack and preallocated memory for small cmd-buffers Jussi Kivilinna
2011-01-31 18:49 ` [PATCH 15/22] zd1211rw: change interrupt URB buffer to DMA buffer Jussi Kivilinna
2011-01-31 18:49 ` [PATCH 16/22] zd1211rw: lower hw command timeouts Jussi Kivilinna
2011-01-31 18:49 ` [PATCH 17/22] zd1211rw: collect driver settings and add function to restore theim Jussi Kivilinna
2011-01-31 18:49 ` [PATCH 18/22] zd1211rw: add TX watchdog and device resetting Jussi Kivilinna
2011-01-31 18:50 ` [PATCH 19/22] zd1211rw: reset device when CR_BCN_FIFO_SEMAPHORE freezes in beacon setup Jussi Kivilinna
2011-01-31 18:50 ` Jussi Kivilinna [this message]
2011-01-31 18:50 ` [PATCH 21/22] zd1211rw: enable NL80211_IFTYPE_AP Jussi Kivilinna
2011-01-31 18:50 ` [PATCH 22/22] zd1211rw: add useful debug output Jussi Kivilinna
2011-02-04 14:06 ` [PATCH 00/22] zd1211rw: add support for AP-mode Jussi Kivilinna
2011-02-04 21:25 ` John W. Linville
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110131185012.10044.21341.stgit@fate.lan \
--to=jussi.kivilinna@mbnet.fi \
--cc=dsd@gentoo.org \
--cc=kune@deine-taler.de \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).