linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] wil6210 bug fixes and performance enhancement
@ 2016-01-28 17:24 Maya Erez
  2016-01-28 17:24 ` [PATCH 1/4] wil6210: prevent access to vring_tx_data lock during its init Maya Erez
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Maya Erez @ 2016-01-28 17:24 UTC (permalink / raw)
  To: Kalle Valo; +Cc: Maya Erez, linux-wireless, wil6210

The below patches include:
- Bug fixes seen in stress connect/disconnect tests
- Increasing the TX vring size for performance boost

Hamad Kadmany (1):
  wil6210: TX vring optimization

Maya Erez (2):
  wil6210: prevent access to vring_tx_data lock during its init
  wil6210: protect synchronous wmi commands handling

Vladimir Kondratiev (1):
  wil6210: wait for disconnect completion

 drivers/net/wireless/ath/wil6210/cfg80211.c | 13 +++++++++++-
 drivers/net/wireless/ath/wil6210/debugfs.c  |  6 +++---
 drivers/net/wireless/ath/wil6210/main.c     | 31 +++++++++++------------------
 drivers/net/wireless/ath/wil6210/txrx.c     | 26 +++++++++++++++++++-----
 drivers/net/wireless/ath/wil6210/wil6210.h  |  3 ++-
 drivers/net/wireless/ath/wil6210/wmi.c      | 17 ++++++++++++----
 6 files changed, 63 insertions(+), 33 deletions(-)

-- 
1.8.5.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] wil6210: prevent access to vring_tx_data lock during its init
  2016-01-28 17:24 [PATCH 0/4] wil6210 bug fixes and performance enhancement Maya Erez
@ 2016-01-28 17:24 ` Maya Erez
  2016-01-28 17:24 ` [PATCH 2/4] wil6210: wait for disconnect completion Maya Erez
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Maya Erez @ 2016-01-28 17:24 UTC (permalink / raw)
  To: Kalle Valo; +Cc: Maya Erez, linux-wireless, wil6210

wil_tx_vring locks the vring_tx_data lock before accessing the TX
vring to check if it is enabled and valid for use.
In case of quick disconnect / connect events for the same station,
spin_lock(&txdata->lock) can be called during the lock initialization
in the vring init function.
To prevent such a race, the TX vrings spin lock should be initialized
once during wil6210 driver initialization.

Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
 drivers/net/wireless/ath/wil6210/main.c |  3 +++
 drivers/net/wireless/ath/wil6210/txrx.c | 26 +++++++++++++++++++++-----
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 0652efe..712ebbf 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -438,6 +438,9 @@ int wil_priv_init(struct wil6210_priv *wil)
 	for (i = 0; i < WIL6210_MAX_CID; i++)
 		spin_lock_init(&wil->sta[i].tid_rx_lock);
 
+	for (i = 0; i < WIL6210_MAX_TX_RINGS; i++)
+		spin_lock_init(&wil->vring_tx_data[i].lock);
+
 	mutex_init(&wil->mutex);
 	mutex_init(&wil->wmi_mutex);
 	mutex_init(&wil->back_rx_mutex);
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 9680b97..6af2090 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -717,6 +717,21 @@ void wil_rx_fini(struct wil6210_priv *wil)
 		wil_vring_free(wil, vring, 0);
 }
 
+static inline void wil_tx_data_init(struct vring_tx_data *txdata)
+{
+	spin_lock_bh(&txdata->lock);
+	txdata->dot1x_open = 0;
+	txdata->enabled = 0;
+	txdata->idle = 0;
+	txdata->last_idle = 0;
+	txdata->begin = 0;
+	txdata->agg_wsize = 0;
+	txdata->agg_timeout = 0;
+	txdata->agg_amsdu = 0;
+	txdata->addba_in_progress = false;
+	spin_unlock_bh(&txdata->lock);
+}
+
 int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
 		      int cid, int tid)
 {
@@ -758,8 +773,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
 		goto out;
 	}
 
-	memset(txdata, 0, sizeof(*txdata));
-	spin_lock_init(&txdata->lock);
+	wil_tx_data_init(txdata);
 	vring->size = size;
 	rc = wil_vring_alloc(wil, vring);
 	if (rc)
@@ -791,8 +805,10 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
 
 	return 0;
  out_free:
+	spin_lock_bh(&txdata->lock);
 	txdata->dot1x_open = false;
 	txdata->enabled = 0;
+	spin_unlock_bh(&txdata->lock);
 	wil_vring_free(wil, vring, 1);
 	wil->vring2cid_tid[id][0] = WIL6210_MAX_CID;
 	wil->vring2cid_tid[id][1] = 0;
@@ -834,8 +850,7 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
 		goto out;
 	}
 
-	memset(txdata, 0, sizeof(*txdata));
-	spin_lock_init(&txdata->lock);
+	wil_tx_data_init(txdata);
 	vring->size = size;
 	rc = wil_vring_alloc(wil, vring);
 	if (rc)
@@ -865,8 +880,10 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
 
 	return 0;
  out_free:
+	spin_lock_bh(&txdata->lock);
 	txdata->enabled = 0;
 	txdata->dot1x_open = false;
+	spin_unlock_bh(&txdata->lock);
 	wil_vring_free(wil, vring, 1);
  out:
 
@@ -894,7 +911,6 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
 		napi_synchronize(&wil->napi_tx);
 
 	wil_vring_free(wil, vring, 1);
-	memset(txdata, 0, sizeof(*txdata));
 }
 
 static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil,
-- 
1.8.5.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] wil6210: wait for disconnect completion
  2016-01-28 17:24 [PATCH 0/4] wil6210 bug fixes and performance enhancement Maya Erez
  2016-01-28 17:24 ` [PATCH 1/4] wil6210: prevent access to vring_tx_data lock during its init Maya Erez
@ 2016-01-28 17:24 ` Maya Erez
  2016-01-28 17:24 ` [PATCH 3/4] wil6210: protect synchronous wmi commands handling Maya Erez
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Maya Erez @ 2016-01-28 17:24 UTC (permalink / raw)
  To: Kalle Valo; +Cc: Vladimir Kondratiev, linux-wireless, wil6210, Maya Erez

From: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>

cfg80211_ops.disconnect() should wait for disconnect flow to
complete. If it does not, internal state becomes out of sync with
one in cfg80211. If one does stress test connect/disconnect
sequence, cfg80211 will issue next connect before disconnect
completed internally.

Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
 drivers/net/wireless/ath/wil6210/cfg80211.c | 13 ++++++++++++-
 drivers/net/wireless/ath/wil6210/main.c     | 28 +++++++++-------------------
 drivers/net/wireless/ath/wil6210/wil6210.h  |  1 +
 3 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 774352f..97ad91e 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -535,7 +535,18 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
 
 	wil_dbg_misc(wil, "%s(reason=%d)\n", __func__, reason_code);
 
-	rc = wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0);
+	if (!(test_bit(wil_status_fwconnecting, wil->status) ||
+	      test_bit(wil_status_fwconnected, wil->status))) {
+		wil_err(wil, "%s: Disconnect was called while disconnected\n",
+			__func__);
+		return 0;
+	}
+
+	rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0,
+		      WMI_DISCONNECT_EVENTID, NULL, 0,
+		      WIL6210_DISCONNECT_TO_MS);
+	if (rc)
+		wil_err(wil, "%s: disconnect error %d\n", __func__, rc);
 
 	return rc;
 }
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 712ebbf..78ba6e0 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -23,9 +23,6 @@
 #include "wmi.h"
 #include "boot_loader.h"
 
-#define WAIT_FOR_DISCONNECT_TIMEOUT_MS 2000
-#define WAIT_FOR_DISCONNECT_INTERVAL_MS 10
-
 bool debug_fw; /* = false; */
 module_param(debug_fw, bool, S_IRUGO);
 MODULE_PARM_DESC(debug_fw, " do not perform card reset. For FW debug");
@@ -942,8 +939,7 @@ int wil_up(struct wil6210_priv *wil)
 
 int __wil_down(struct wil6210_priv *wil)
 {
-	int iter = WAIT_FOR_DISCONNECT_TIMEOUT_MS /
-			WAIT_FOR_DISCONNECT_INTERVAL_MS;
+	int rc;
 
 	WARN_ON(!mutex_is_locked(&wil->mutex));
 
@@ -967,22 +963,16 @@ int __wil_down(struct wil6210_priv *wil)
 	}
 
 	if (test_bit(wil_status_fwconnected, wil->status) ||
-	    test_bit(wil_status_fwconnecting, wil->status))
-		wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0);
+	    test_bit(wil_status_fwconnecting, wil->status)) {
 
-	/* make sure wil is idle (not connected) */
-	mutex_unlock(&wil->mutex);
-	while (iter--) {
-		int idle = !test_bit(wil_status_fwconnected, wil->status) &&
-			   !test_bit(wil_status_fwconnecting, wil->status);
-		if (idle)
-			break;
-		msleep(WAIT_FOR_DISCONNECT_INTERVAL_MS);
+		mutex_unlock(&wil->mutex);
+		rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0,
+			      WMI_DISCONNECT_EVENTID, NULL, 0,
+			      WIL6210_DISCONNECT_TO_MS);
+		mutex_lock(&wil->mutex);
+		if (rc)
+			wil_err(wil, "timeout waiting for disconnect\n");
 	}
-	mutex_lock(&wil->mutex);
-
-	if (iter < 0)
-		wil_err(wil, "timeout waiting for idle FW/HW\n");
 
 	wil_reset(wil, false);
 
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 1b8fa1d..9502965 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -92,6 +92,7 @@ static inline u32 wil_mtu2macbuf(u32 mtu)
 #define WIL6210_FW_RECOVERY_RETRIES	(5) /* try to recover this many times */
 #define WIL6210_FW_RECOVERY_TO	msecs_to_jiffies(5000)
 #define WIL6210_SCAN_TO		msecs_to_jiffies(10000)
+#define WIL6210_DISCONNECT_TO_MS (2000)
 #define WIL6210_RX_HIGH_TRSH_INIT		(0)
 #define WIL6210_RX_HIGH_TRSH_DEFAULT \
 				(1 << (WIL_RX_RING_SIZE_ORDER_DEFAULT - 3))
-- 
1.8.5.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] wil6210: protect synchronous wmi commands handling
  2016-01-28 17:24 [PATCH 0/4] wil6210 bug fixes and performance enhancement Maya Erez
  2016-01-28 17:24 ` [PATCH 1/4] wil6210: prevent access to vring_tx_data lock during its init Maya Erez
  2016-01-28 17:24 ` [PATCH 2/4] wil6210: wait for disconnect completion Maya Erez
@ 2016-01-28 17:24 ` Maya Erez
  2016-01-28 17:24 ` [PATCH 4/4] wil6210: TX vring optimization Maya Erez
  2016-02-24 13:50 ` [PATCH 0/4] wil6210 bug fixes and performance enhancement Kalle Valo
  4 siblings, 0 replies; 6+ messages in thread
From: Maya Erez @ 2016-01-28 17:24 UTC (permalink / raw)
  To: Kalle Valo; +Cc: Maya Erez, linux-wireless, wil6210

In case there are multiple WMI commands with the same reply_id,
the following scenario can occur:
- Driver sends the first command to the device
- The reply didn’t get on time and there is timeout
- Reply_id, reply_buf and reply_size are set to 0
- Driver sends second wmi command with the same reply_id as the first
- Driver sets wil->reply_id
- Reply for the first wmi command arrives and handled by wmi_recv_cmd
- As its ID fits the reply_id but the reply_buf is not set yet it is
handled as a reply with event handler, and WARN_ON is printed

This patch guarantee atomic setting of all the reply variables and
prevents the above scenario.

Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
 drivers/net/wireless/ath/wil6210/wmi.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index e1a6cb8..493e721 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -838,6 +838,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
 			struct wil6210_mbox_hdr_wmi *wmi = &evt->event.wmi;
 			u16 id = le16_to_cpu(wmi->id);
 			u32 tstamp = le32_to_cpu(wmi->timestamp);
+			spin_lock_irqsave(&wil->wmi_ev_lock, flags);
 			if (wil->reply_id && wil->reply_id == id) {
 				if (wil->reply_buf) {
 					memcpy(wil->reply_buf, wmi,
@@ -845,6 +846,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
 					immed_reply = true;
 				}
 			}
+			spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
 
 			wil_dbg_wmi(wil, "WMI event 0x%04x MID %d @%d msec\n",
 				    id, wmi->mid, tstamp);
@@ -888,13 +890,16 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
 
 	mutex_lock(&wil->wmi_mutex);
 
+	spin_lock(&wil->wmi_ev_lock);
+	wil->reply_id = reply_id;
+	wil->reply_buf = reply;
+	wil->reply_size = reply_size;
+	spin_unlock(&wil->wmi_ev_lock);
+
 	rc = __wmi_send(wil, cmdid, buf, len);
 	if (rc)
 		goto out;
 
-	wil->reply_id = reply_id;
-	wil->reply_buf = reply;
-	wil->reply_size = reply_size;
 	remain = wait_for_completion_timeout(&wil->wmi_call,
 					     msecs_to_jiffies(to_msec));
 	if (0 == remain) {
@@ -907,10 +912,14 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
 			    cmdid, reply_id,
 			    to_msec - jiffies_to_msecs(remain));
 	}
+
+out:
+	spin_lock(&wil->wmi_ev_lock);
 	wil->reply_id = 0;
 	wil->reply_buf = NULL;
 	wil->reply_size = 0;
- out:
+	spin_unlock(&wil->wmi_ev_lock);
+
 	mutex_unlock(&wil->wmi_mutex);
 
 	return rc;
-- 
1.8.5.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] wil6210: TX vring optimization
  2016-01-28 17:24 [PATCH 0/4] wil6210 bug fixes and performance enhancement Maya Erez
                   ` (2 preceding siblings ...)
  2016-01-28 17:24 ` [PATCH 3/4] wil6210: protect synchronous wmi commands handling Maya Erez
@ 2016-01-28 17:24 ` Maya Erez
  2016-02-24 13:50 ` [PATCH 0/4] wil6210 bug fixes and performance enhancement Kalle Valo
  4 siblings, 0 replies; 6+ messages in thread
From: Maya Erez @ 2016-01-28 17:24 UTC (permalink / raw)
  To: Kalle Valo; +Cc: Hamad Kadmany, linux-wireless, wil6210, Maya Erez

From: Hamad Kadmany <qca_hkadmany@qca.qualcomm.com>

Tx vring needs to be enlarged to get better
performance for traffic over 2Gbps.

Signed-off-by: Hamad Kadmany <qca_hkadmany@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
 drivers/net/wireless/ath/wil6210/debugfs.c | 6 +++---
 drivers/net/wireless/ath/wil6210/wil6210.h | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index a1d10b8..3bbe73b 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -68,13 +68,13 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil,
 		seq_puts(s, "???\n");
 	}
 
-	if (vring->va && (vring->size < 1025)) {
+	if (vring->va && (vring->size <= (1 << WIL_RING_SIZE_ORDER_MAX))) {
 		uint i;
 
 		for (i = 0; i < vring->size; i++) {
 			volatile struct vring_tx_desc *d = &vring->va[i].tx;
 
-			if ((i % 64) == 0 && (i != 0))
+			if ((i % 128) == 0 && (i != 0))
 				seq_puts(s, "\n");
 			seq_printf(s, "%c", (d->dma.status & BIT(0)) ?
 					_s : (vring->ctx[i].skb ? _h : 'h'));
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 9502965..8427d68 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -51,7 +51,7 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
 
 #define WIL_TX_Q_LEN_DEFAULT		(4000)
 #define WIL_RX_RING_SIZE_ORDER_DEFAULT	(10)
-#define WIL_TX_RING_SIZE_ORDER_DEFAULT	(10)
+#define WIL_TX_RING_SIZE_ORDER_DEFAULT	(12)
 #define WIL_BCAST_RING_SIZE_ORDER_DEFAULT	(7)
 #define WIL_BCAST_MCS0_LIMIT		(1024) /* limit for MCS0 frame size */
 /* limit ring size in range [32..32k] */
-- 
1.8.5.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] wil6210 bug fixes and performance enhancement
  2016-01-28 17:24 [PATCH 0/4] wil6210 bug fixes and performance enhancement Maya Erez
                   ` (3 preceding siblings ...)
  2016-01-28 17:24 ` [PATCH 4/4] wil6210: TX vring optimization Maya Erez
@ 2016-02-24 13:50 ` Kalle Valo
  4 siblings, 0 replies; 6+ messages in thread
From: Kalle Valo @ 2016-02-24 13:50 UTC (permalink / raw)
  To: Maya Erez; +Cc: linux-wireless, wil6210

Maya Erez <qca_merez@qca.qualcomm.com> writes:

> The below patches include:
> - Bug fixes seen in stress connect/disconnect tests
> - Increasing the TX vring size for performance boost
>
> Hamad Kadmany (1):
>   wil6210: TX vring optimization
>
> Maya Erez (2):
>   wil6210: prevent access to vring_tx_data lock during its init
>   wil6210: protect synchronous wmi commands handling
>
> Vladimir Kondratiev (1):
>   wil6210: wait for disconnect completion

Applied to ath.git, thanks.

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-02-24 13:50 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-28 17:24 [PATCH 0/4] wil6210 bug fixes and performance enhancement Maya Erez
2016-01-28 17:24 ` [PATCH 1/4] wil6210: prevent access to vring_tx_data lock during its init Maya Erez
2016-01-28 17:24 ` [PATCH 2/4] wil6210: wait for disconnect completion Maya Erez
2016-01-28 17:24 ` [PATCH 3/4] wil6210: protect synchronous wmi commands handling Maya Erez
2016-01-28 17:24 ` [PATCH 4/4] wil6210: TX vring optimization Maya Erez
2016-02-24 13:50 ` [PATCH 0/4] wil6210 bug fixes and performance enhancement Kalle Valo

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).