All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.