[PATCH 3/7] ath10k: drain wmi quickly upon hw restart

Michal Kazior michal.kazior at tieto.com
Fri May 9 05:35:53 PDT 2014


Once restart is started it doesn't make much sense
to process pending requests. Just drop all WMI
commands that are in progress.

This speeds up hw restart because conf_mutex can
be held in some cases while a crash happens. In
that case WMI tx credits are no replenished and 3
second timeout for each WMI command happens. This
could add up to quite a lot.

Signed-off-by: Michal Kazior <michal.kazior at tieto.com>
---
 drivers/net/wireless/ath/ath10k/core.c |  5 +++++
 drivers/net/wireless/ath/ath10k/core.h |  3 +++
 drivers/net/wireless/ath/ath10k/wmi.c  | 12 +++++++++++-
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index acc22cc..3f4d28f 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -706,6 +706,11 @@ static void ath10k_core_restart_work(struct work_struct *work)
 
 void ath10k_core_restart(struct ath10k *ar)
 {
+	spin_lock_bh(&ar->data_lock);
+	ar->wmi.drop = true;
+	wake_up(&ar->wmi.tx_credits_wq);
+	spin_unlock_bh(&ar->data_lock);
+
 	queue_work(ar->workqueue, &ar->restart_work);
 }
 EXPORT_SYMBOL(ath10k_core_restart);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 170094d..074cb41 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -113,6 +113,9 @@ struct ath10k_wmi {
 
 	u32 num_mem_chunks;
 	struct ath10k_mem_chunk mem_chunks[ATH10K_MAX_MEM_REQS];
+
+	/* protected by ar->data_lock. used to speed up hw restart */
+	bool drop;
 };
 
 struct ath10k_peer_stat {
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 72cc4f2..159d744 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -621,7 +621,13 @@ static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb,
 		/* try to send pending beacons first. they take priority */
 		ath10k_wmi_tx_beacons_nowait(ar);
 
-		ret = ath10k_wmi_cmd_send_nowait(ar, skb, cmd_id);
+		spin_lock_bh(&ar->data_lock);
+		if (ar->wmi.drop)
+			ret = -EPERM;
+		else
+			ret = ath10k_wmi_cmd_send_nowait(ar, skb, cmd_id);
+		spin_unlock_bh(&ar->data_lock);
+
 		(ret != -EAGAIN);
 	}), 3*HZ);
 
@@ -2341,6 +2347,10 @@ int ath10k_wmi_attach(struct ath10k *ar)
 	init_completion(&ar->wmi.unified_ready);
 	init_waitqueue_head(&ar->wmi.tx_credits_wq);
 
+	spin_lock_bh(&ar->data_lock);
+	ar->wmi.drop = false;
+	spin_unlock_bh(&ar->data_lock);
+
 	return 0;
 }
 
-- 
1.8.5.3




More information about the ath10k mailing list