diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-12-09 23:54:27 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 15:06:30 -0800 |
commit | 2eb188a1c57ae79283cee951c317bd191cf1ca56 (patch) | |
tree | 6fa459e2d171f035c97af88bfa5957dd544b4413 /drivers/net/wireless/libertas/main.c | |
parent | b8d40bc9c9099943cbcf18d285bf241f1f080a44 (diff) |
libertas: Move actual transmission to main thread
The locking issues with TX, especially TX from multiple netdevs, get
_so_ much easier if you do it like this.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/main.c')
-rw-r--r-- | drivers/net/wireless/libertas/main.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 42b64b5ad08..f16c93ba6ef 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -739,6 +739,8 @@ static int lbs_thread(void *data) shouldsleep = 0; /* Interrupt pending. Deal with it now */ else if (priv->dnld_sent) shouldsleep = 1; /* Something is en route to the device already */ + else if (priv->tx_pending_len > 0) + shouldsleep = 0; /* We've a packet to send */ else if (priv->cur_cmd) shouldsleep = 1; /* Can't send a command; one already running */ else if (!list_empty(&priv->cmdpendingq)) @@ -852,6 +854,28 @@ static int lbs_thread(void *data) */ if (!list_empty(&priv->cmdpendingq)) wake_up_all(&priv->cmd_pending); + + spin_lock_irq(&priv->driver_lock); + if (!priv->dnld_sent && priv->tx_pending_len > 0) { + int ret = priv->hw_host_to_card(priv, MVMS_DAT, + priv->tx_pending_buf, + priv->tx_pending_len); + if (ret) { + lbs_deb_tx("host_to_card failed %d\n", ret); + priv->dnld_sent = DNLD_RES_RECEIVED; + } + priv->tx_pending_len = 0; + if (!priv->currenttxskb) { + /* We can wake the queues immediately if we aren't + waiting for TX feedback */ + if (priv->connect_status == LBS_CONNECTED) + netif_wake_queue(priv->dev); + if (priv->mesh_dev && + priv->mesh_connect_status == LBS_CONNECTED) + netif_wake_queue(priv->mesh_dev); + } + } + spin_unlock_irq(&priv->driver_lock); } del_timer(&priv->command_timer); |