aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-10-11 15:35:42 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-10-11 15:35:42 -0400
commit094daf7db7c47861009899ce23f9177d761e20b0 (patch)
treea107065393720b80664157a035b206576e834793 /drivers/net/wireless/libertas
parent3ed6f6958c0ac21958285d8648f14d34da4bbcb3 (diff)
parent5f68a2b0a890d086e40fc7b55f4a0c32c28bc0d2 (diff)
Merge branch 'master' of git://git.infradead.org/users/linville/wireless-next into for-davem
Conflicts: Documentation/feature-removal-schedule.txt
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/main.c35
2 files changed, 36 insertions, 0 deletions
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index fb3e40bf5902..f3fd447131c2 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -158,6 +158,7 @@ struct lbs_private {
158 /* protected by hard_start_xmit serialization */ 158 /* protected by hard_start_xmit serialization */
159 u8 txretrycount; 159 u8 txretrycount;
160 struct sk_buff *currenttxskb; 160 struct sk_buff *currenttxskb;
161 struct timer_list tx_lockup_timer;
161 162
162 /* Locks */ 163 /* Locks */
163 struct mutex lock; 164 struct mutex lock;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index d1c1d52931f1..c50ae07e2e89 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -188,6 +188,7 @@ int lbs_stop_iface(struct lbs_private *priv)
188 spin_unlock_irqrestore(&priv->driver_lock, flags); 188 spin_unlock_irqrestore(&priv->driver_lock, flags);
189 189
190 cancel_work_sync(&priv->mcast_work); 190 cancel_work_sync(&priv->mcast_work);
191 del_timer_sync(&priv->tx_lockup_timer);
191 192
192 /* Disable command processing, and wait for all commands to complete */ 193 /* Disable command processing, and wait for all commands to complete */
193 lbs_deb_main("waiting for commands to complete\n"); 194 lbs_deb_main("waiting for commands to complete\n");
@@ -243,6 +244,7 @@ void lbs_host_to_card_done(struct lbs_private *priv)
243 lbs_deb_enter(LBS_DEB_THREAD); 244 lbs_deb_enter(LBS_DEB_THREAD);
244 245
245 spin_lock_irqsave(&priv->driver_lock, flags); 246 spin_lock_irqsave(&priv->driver_lock, flags);
247 del_timer(&priv->tx_lockup_timer);
246 248
247 priv->dnld_sent = DNLD_RES_RECEIVED; 249 priv->dnld_sent = DNLD_RES_RECEIVED;
248 250
@@ -585,6 +587,9 @@ static int lbs_thread(void *data)
585 if (ret) { 587 if (ret) {
586 lbs_deb_tx("host_to_card failed %d\n", ret); 588 lbs_deb_tx("host_to_card failed %d\n", ret);
587 priv->dnld_sent = DNLD_RES_RECEIVED; 589 priv->dnld_sent = DNLD_RES_RECEIVED;
590 } else {
591 mod_timer(&priv->tx_lockup_timer,
592 jiffies + (HZ * 5));
588 } 593 }
589 priv->tx_pending_len = 0; 594 priv->tx_pending_len = 0;
590 if (!priv->currenttxskb) { 595 if (!priv->currenttxskb) {
@@ -601,6 +606,7 @@ static int lbs_thread(void *data)
601 } 606 }
602 607
603 del_timer(&priv->command_timer); 608 del_timer(&priv->command_timer);
609 del_timer(&priv->tx_lockup_timer);
604 del_timer(&priv->auto_deepsleep_timer); 610 del_timer(&priv->auto_deepsleep_timer);
605 611
606 lbs_deb_leave(LBS_DEB_THREAD); 612 lbs_deb_leave(LBS_DEB_THREAD);
@@ -735,6 +741,32 @@ out:
735} 741}
736 742
737/** 743/**
744 * lbs_tx_lockup_handler - handles the timeout of the passing of TX frames
745 * to the hardware. This is known to frequently happen with SD8686 when
746 * waking up after a Wake-on-WLAN-triggered resume.
747 *
748 * @data: &struct lbs_private pointer
749 */
750static void lbs_tx_lockup_handler(unsigned long data)
751{
752 struct lbs_private *priv = (struct lbs_private *)data;
753 unsigned long flags;
754
755 lbs_deb_enter(LBS_DEB_TX);
756 spin_lock_irqsave(&priv->driver_lock, flags);
757
758 netdev_info(priv->dev, "TX lockup detected\n");
759 if (priv->reset_card)
760 priv->reset_card(priv);
761
762 priv->dnld_sent = DNLD_RES_RECEIVED;
763 wake_up_interruptible(&priv->waitq);
764
765 spin_unlock_irqrestore(&priv->driver_lock, flags);
766 lbs_deb_leave(LBS_DEB_TX);
767}
768
769/**
738 * auto_deepsleep_timer_fn - put the device back to deep sleep mode when 770 * auto_deepsleep_timer_fn - put the device back to deep sleep mode when
739 * timer expires and no activity (command, event, data etc.) is detected. 771 * timer expires and no activity (command, event, data etc.) is detected.
740 * @data: &struct lbs_private pointer 772 * @data: &struct lbs_private pointer
@@ -820,6 +852,8 @@ static int lbs_init_adapter(struct lbs_private *priv)
820 852
821 setup_timer(&priv->command_timer, lbs_cmd_timeout_handler, 853 setup_timer(&priv->command_timer, lbs_cmd_timeout_handler,
822 (unsigned long)priv); 854 (unsigned long)priv);
855 setup_timer(&priv->tx_lockup_timer, lbs_tx_lockup_handler,
856 (unsigned long)priv);
823 setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn, 857 setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn,
824 (unsigned long)priv); 858 (unsigned long)priv);
825 859
@@ -857,6 +891,7 @@ static void lbs_free_adapter(struct lbs_private *priv)
857 lbs_free_cmd_buffer(priv); 891 lbs_free_cmd_buffer(priv);
858 kfifo_free(&priv->event_fifo); 892 kfifo_free(&priv->event_fifo);
859 del_timer(&priv->command_timer); 893 del_timer(&priv->command_timer);
894 del_timer(&priv->tx_lockup_timer);
860 del_timer(&priv->auto_deepsleep_timer); 895 del_timer(&priv->auto_deepsleep_timer);
861 896
862 lbs_deb_leave(LBS_DEB_MAIN); 897 lbs_deb_leave(LBS_DEB_MAIN);