Search Linux Wireless

[PATCH 4/5] mwl8k: Handle watchdog event with highest prioriry

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently, command path waits till all the tx host queues
are empty. Whenever watchdog event is raised, firmware
expects driver to destroy ampdu queues immediately.

This requires corresponding commands i.e.
mwl8k_cmd_get_watchdog_bitmap and mwl8k_destroy_ba to be
sent without waiting for the tx queues to be completely
empty.

Use "watchdog_event_pending" to ensure the above mentioned
two commands are sent down immediately.

Signed-off-by: Nishant Sarmukadam <nishants@xxxxxxxxxxx>
Signed-off-by: Yogesh Ashok Powar <yogeshp@xxxxxxxxxxx>
---
 drivers/net/wireless/mwl8k.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 07b7546..51ae9e9 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -213,6 +213,8 @@ struct mwl8k_priv {
 	int fw_mutex_depth;
 	struct completion *hostcmd_wait;
 
+	atomic_t watchdog_event_pending;
+
 	/* lock held over TX and TX reap */
 	spinlock_t tx_lock;
 
@@ -1527,6 +1529,9 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
 			return -EBUSY;
 	}
 
+	if (atomic_read(&priv->watchdog_event_pending))
+		return 0;
+
 	/*
 	 * The TX queues are stopped at this point, so this test
 	 * doesn't need to take ->tx_lock.
@@ -1548,6 +1553,14 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
 		spin_unlock_bh(&priv->tx_lock);
 		timeout = wait_for_completion_timeout(&tx_wait,
 			    msecs_to_jiffies(MWL8K_TX_WAIT_TIMEOUT_MS));
+
+		if (atomic_read(&priv->watchdog_event_pending)) {
+			spin_lock_bh(&priv->tx_lock);
+			priv->tx_wait = NULL;
+			spin_unlock_bh(&priv->tx_lock);
+			return 0;
+		}
+
 		spin_lock_bh(&priv->tx_lock);
 
 		if (timeout) {
@@ -3645,6 +3658,7 @@ static void mwl8k_watchdog_ba_events(struct work_struct *work)
 
 	spin_unlock(&priv->stream_lock);
 done:
+	atomic_dec(&priv->watchdog_event_pending);
 	status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
 	iowrite32((status | MWL8K_A2H_INT_BA_WATCHDOG),
 		  priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
@@ -4346,6 +4360,10 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
 	}
 
 	if (status & MWL8K_A2H_INT_BA_WATCHDOG) {
+		iowrite32(~MWL8K_A2H_INT_BA_WATCHDOG,
+			  priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
+
+		atomic_inc(&priv->watchdog_event_pending);
 		status &= ~MWL8K_A2H_INT_BA_WATCHDOG;
 		ieee80211_queue_work(hw, &priv->watchdog_ba_handle);
 	}
@@ -5518,6 +5536,7 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
 	priv->sniffer_enabled = false;
 	priv->wmm_enabled = false;
 	priv->pending_tx_pkts = 0;
+	atomic_set(&priv->watchdog_event_pending, 0);
 
 	rc = mwl8k_rxq_init(hw, 0);
 	if (rc)
-- 
1.8.0.3

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux