All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] wl12xx: various bug fixes for 3.4
@ 2012-03-19 10:06 Eyal Shapira
  2012-03-19 10:06 ` [PATCH 1/4] wl12xx: fix race between suspend/resume and recovery Eyal Shapira
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Eyal Shapira @ 2012-03-19 10:06 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless

Some recent bug fixes fixing a panic and a memory leak
related to FW recovery as well as some scan issues.

Eyal Shapira (4):
  wl12xx: fix race between suspend/resume and recovery
  wl12xx: fix a memory leak of probereq template upon recovery
  wl12xx: adaptive sched scan dwell times
  wl12xx: increase scan timeout to 30s

 drivers/net/wireless/wl12xx/conf.h |   28 ++++++++++++++----
 drivers/net/wireless/wl12xx/main.c |   54 +++++++++++++++++++----------------
 drivers/net/wireless/wl12xx/scan.c |   29 ++++++++++++++++--
 drivers/net/wireless/wl12xx/scan.h |    2 +-
 4 files changed, 77 insertions(+), 36 deletions(-)

-- 
1.7.4.1


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

* [PATCH 1/4] wl12xx: fix race between suspend/resume and recovery
  2012-03-19 10:06 [PATCH 0/4] wl12xx: various bug fixes for 3.4 Eyal Shapira
@ 2012-03-19 10:06 ` Eyal Shapira
  2012-03-19 10:06 ` [PATCH 2/4] wl12xx: fix a memory leak of probereq template upon recovery Eyal Shapira
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Eyal Shapira @ 2012-03-19 10:06 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless

The iteration on the wlvif list in wl1271_op_resume/suspend was
perfomed before locking wl->mutex which would lead to a kernel
panic in case a recovery was queued at the same time
and would delete the wlvifs from the list.

Signed-off-by: Eyal Shapira <eyal@wizery.com>
---
 drivers/net/wireless/wl12xx/main.c |   29 ++++++++++++-----------------
 1 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 3900236..791cdcc 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -1652,14 +1652,12 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl,
 {
 	int ret = 0;
 
-	mutex_lock(&wl->mutex);
-
 	if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
-		goto out_unlock;
+		goto out;
 
 	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
-		goto out_unlock;
+		goto out;
 
 	ret = wl1271_acx_wake_up_conditions(wl, wlvif,
 				    wl->conf.conn.suspend_wake_up_event,
@@ -1668,11 +1666,9 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl,
 	if (ret < 0)
 		wl1271_error("suspend: set wake up conditions failed: %d", ret);
 
-
 	wl1271_ps_elp_sleep(wl);
 
-out_unlock:
-	mutex_unlock(&wl->mutex);
+out:
 	return ret;
 
 }
@@ -1682,20 +1678,17 @@ static int wl1271_configure_suspend_ap(struct wl1271 *wl,
 {
 	int ret = 0;
 
-	mutex_lock(&wl->mutex);
-
 	if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
-		goto out_unlock;
+		goto out;
 
 	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
-		goto out_unlock;
+		goto out;
 
 	ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true);
 
 	wl1271_ps_elp_sleep(wl);
-out_unlock:
-	mutex_unlock(&wl->mutex);
+out:
 	return ret;
 
 }
@@ -1720,10 +1713,9 @@ static void wl1271_configure_resume(struct wl1271 *wl,
 	if ((!is_ap) && (!is_sta))
 		return;
 
-	mutex_lock(&wl->mutex);
 	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
-		goto out;
+		return;
 
 	if (is_sta) {
 		ret = wl1271_acx_wake_up_conditions(wl, wlvif,
@@ -1739,8 +1731,6 @@ static void wl1271_configure_resume(struct wl1271 *wl,
 	}
 
 	wl1271_ps_elp_sleep(wl);
-out:
-	mutex_unlock(&wl->mutex);
 }
 
 static int wl1271_op_suspend(struct ieee80211_hw *hw,
@@ -1755,6 +1745,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
 
 	wl1271_tx_flush(wl);
 
+	mutex_lock(&wl->mutex);
 	wl->wow_enabled = true;
 	wl12xx_for_each_wlvif(wl, wlvif) {
 		ret = wl1271_configure_suspend(wl, wlvif);
@@ -1763,6 +1754,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
 			return ret;
 		}
 	}
+	mutex_unlock(&wl->mutex);
 	/* flush any remaining work */
 	wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
 
@@ -1812,10 +1804,13 @@ static int wl1271_op_resume(struct ieee80211_hw *hw)
 		wl1271_irq(0, wl);
 		wl1271_enable_interrupts(wl);
 	}
+
+	mutex_lock(&wl->mutex);
 	wl12xx_for_each_wlvif(wl, wlvif) {
 		wl1271_configure_resume(wl, wlvif);
 	}
 	wl->wow_enabled = false;
+	mutex_unlock(&wl->mutex);
 
 	return 0;
 }
-- 
1.7.4.1


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

* [PATCH 2/4] wl12xx: fix a memory leak of probereq template upon recovery
  2012-03-19 10:06 [PATCH 0/4] wl12xx: various bug fixes for 3.4 Eyal Shapira
  2012-03-19 10:06 ` [PATCH 1/4] wl12xx: fix race between suspend/resume and recovery Eyal Shapira
@ 2012-03-19 10:06 ` Eyal Shapira
  2012-03-19 10:06 ` [PATCH 3/4] wl12xx: adaptive sched scan dwell times Eyal Shapira
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Eyal Shapira @ 2012-03-19 10:06 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless

wlvif->probereq is zeroed when adding an interface but
the skb pointed to isn't freed when the interface is removed.
This would lead to a mem leak on every recovery.
Fix it by freeing the skb when removing the interface.

Signed-off-by: Eyal Shapira <eyal@wizery.com>
---
 drivers/net/wireless/wl12xx/main.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 791cdcc..55a0191 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -2357,6 +2357,8 @@ deinit:
 						&wlvif->ap.ucast_rate_idx[i]);
 	}
 
+	dev_kfree_skb(wlvif->probereq);
+	wlvif->probereq = NULL;
 	wl12xx_tx_reset_wlvif(wl, wlvif);
 	wl1271_free_ap_keys(wl, wlvif);
 	if (wl->last_wlvif == wlvif)
-- 
1.7.4.1


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

* [PATCH 3/4] wl12xx: adaptive sched scan dwell times
  2012-03-19 10:06 [PATCH 0/4] wl12xx: various bug fixes for 3.4 Eyal Shapira
  2012-03-19 10:06 ` [PATCH 1/4] wl12xx: fix race between suspend/resume and recovery Eyal Shapira
  2012-03-19 10:06 ` [PATCH 2/4] wl12xx: fix a memory leak of probereq template upon recovery Eyal Shapira
@ 2012-03-19 10:06 ` Eyal Shapira
  2012-03-19 10:06 ` [PATCH 4/4] wl12xx: increase scan timeout to 30s Eyal Shapira
  2012-04-10 10:20 ` [PATCH 0/4] wl12xx: various bug fixes for 3.4 Luciano Coelho
  4 siblings, 0 replies; 6+ messages in thread
From: Eyal Shapira @ 2012-03-19 10:06 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless

Set the dwell times for sched scan according to the number
of probe requests which are going to be transmitted.
This should fix the too short dwell time problem which
prevented some of the probe requests from being transmitted
in cases of high number of SSIDs (10+) to be actively sched scanned.
However, in the common case of having up to 1-2 SSIDs that
require active scan, the dwell time would be kept to a minimum
which should conserve power. This is important as sched scan
also runs periodically while the host is suspended and there's
great importance to keep power consumption as low as possible.

Signed-off-by: Eyal Shapira <eyal@wizery.com>
---
 drivers/net/wireless/wl12xx/conf.h |   28 ++++++++++++++++++++++------
 drivers/net/wireless/wl12xx/main.c |   23 +++++++++++++++--------
 drivers/net/wireless/wl12xx/scan.c |   29 +++++++++++++++++++++++++----
 3 files changed, 62 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
index 3e581e1..7028f10 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -1096,16 +1096,32 @@ struct conf_scan_settings {
 };
 
 struct conf_sched_scan_settings {
-	/* minimum time to wait on the channel for active scans (in TUs) */
-	u16 min_dwell_time_active;
+	/*
+	 * The base time to wait on the channel for active scans (in TU/1000).
+	 * The minimum dwell time is calculated according to this:
+	 * min_dwell_time = base + num_of_probes_to_be_sent * delta_per_probe
+	 * The maximum dwell time is calculated according to this:
+	 * max_dwell_time = min_dwell_time + max_dwell_time_delta
+	 */
+	u32 base_dwell_time;
+
+	/*
+	 * The delta between the min dwell time and max dwell time for
+	 * active scans (in TU/1000s). The max dwell time is used by the FW once
+	 * traffic is detected on the channel.
+	 */
+	u32 max_dwell_time_delta;
+
+	/* Delta added to min dwell time per each probe in 2.4 GHz (TU/1000) */
+	u32 dwell_time_delta_per_probe;
 
-	/* maximum time to wait on the channel for active scans (in TUs) */
-	u16 max_dwell_time_active;
+	/* Delta added to min dwell time per each probe in 5 GHz (TU/1000) */
+	u32 dwell_time_delta_per_probe_5;
 
-	/* time to wait on the channel for passive scans (in TUs) */
+	/* time to wait on the channel for passive scans (in TU/1000) */
 	u32 dwell_time_passive;
 
-	/* time to wait on the channel for DFS scans (in TUs) */
+	/* time to wait on the channel for DFS scans (in TU/1000) */
 	u32 dwell_time_dfs;
 
 	/* number of probe requests to send on each channel in active scans */
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 55a0191..6db7796 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -276,14 +276,21 @@ static struct conf_drv_settings default_conf = {
 		.split_scan_timeout           = 50000,
 	},
 	.sched_scan = {
-		/* sched_scan requires dwell times in TU instead of TU/1000 */
-		.min_dwell_time_active = 30,
-		.max_dwell_time_active = 60,
-		.dwell_time_passive    = 100,
-		.dwell_time_dfs        = 150,
-		.num_probe_reqs        = 2,
-		.rssi_threshold        = -90,
-		.snr_threshold         = 0,
+		/*
+		 * Values are in TU/1000 but since sched scan FW command
+		 * params are in TUs rounding up may occur.
+		 */
+		.base_dwell_time              = 7500,
+		.max_dwell_time_delta         = 22500,
+		/* based on 250bits per probe @1Mbps */
+		.dwell_time_delta_per_probe   = 2000,
+		/* based on 250bits per probe @6Mbps (plus a bit more) */
+		.dwell_time_delta_per_probe_5 = 350,
+		.dwell_time_passive           = 100000,
+		.dwell_time_dfs               = 150000,
+		.num_probe_reqs               = 2,
+		.rssi_threshold               = -90,
+		.snr_threshold                = 0,
 	},
 	.rf = {
 		.tx_per_channel_power_compensation_2 = {
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c
index fcba055..801ea53 100644
--- a/drivers/net/wireless/wl12xx/scan.c
+++ b/drivers/net/wireless/wl12xx/scan.c
@@ -417,6 +417,23 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
 	int i, j;
 	u32 flags;
 	bool force_passive = !req->n_ssids;
+	u32 min_dwell_time_active, max_dwell_time_active, delta_per_probe;
+	u32 dwell_time_passive, dwell_time_dfs;
+
+	if (band == IEEE80211_BAND_5GHZ)
+		delta_per_probe = c->dwell_time_delta_per_probe_5;
+	else
+		delta_per_probe = c->dwell_time_delta_per_probe;
+
+	min_dwell_time_active = c->base_dwell_time +
+		 req->n_ssids * c->num_probe_reqs * delta_per_probe;
+
+	max_dwell_time_active = min_dwell_time_active + c->max_dwell_time_delta;
+
+	min_dwell_time_active = DIV_ROUND_UP(min_dwell_time_active, 1000);
+	max_dwell_time_active = DIV_ROUND_UP(max_dwell_time_active, 1000);
+	dwell_time_passive = DIV_ROUND_UP(c->dwell_time_passive, 1000);
+	dwell_time_dfs = DIV_ROUND_UP(c->dwell_time_dfs, 1000);
 
 	for (i = 0, j = start;
 	     i < req->n_channels && j < max_channels;
@@ -440,21 +457,25 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
 				     req->channels[i]->flags);
 			wl1271_debug(DEBUG_SCAN, "max_power %d",
 				     req->channels[i]->max_power);
+			wl1271_debug(DEBUG_SCAN, "min_dwell_time %d"
+				     "max dwell time %d",
+				     min_dwell_time_active,
+				     max_dwell_time_active);
 
 			if (flags & IEEE80211_CHAN_RADAR) {
 				channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS;
 
 				channels[j].passive_duration =
-					cpu_to_le16(c->dwell_time_dfs);
+					cpu_to_le16(dwell_time_dfs);
 			} else {
 				channels[j].passive_duration =
-					cpu_to_le16(c->dwell_time_passive);
+					cpu_to_le16(dwell_time_passive);
 			}
 
 			channels[j].min_duration =
-				cpu_to_le16(c->min_dwell_time_active);
+				cpu_to_le16(min_dwell_time_active);
 			channels[j].max_duration =
-				cpu_to_le16(c->max_dwell_time_active);
+				cpu_to_le16(max_dwell_time_active);
 
 			channels[j].tx_power_att = req->channels[i]->max_power;
 			channels[j].channel = req->channels[i]->hw_value;
-- 
1.7.4.1


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

* [PATCH 4/4] wl12xx: increase scan timeout to 30s
  2012-03-19 10:06 [PATCH 0/4] wl12xx: various bug fixes for 3.4 Eyal Shapira
                   ` (2 preceding siblings ...)
  2012-03-19 10:06 ` [PATCH 3/4] wl12xx: adaptive sched scan dwell times Eyal Shapira
@ 2012-03-19 10:06 ` Eyal Shapira
  2012-04-10 10:20 ` [PATCH 0/4] wl12xx: various bug fixes for 3.4 Luciano Coelho
  4 siblings, 0 replies; 6+ messages in thread
From: Eyal Shapira @ 2012-03-19 10:06 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless

In certain scenarios involving sched scan + normal scan + COEX
scan could take longer than 10s and this triggers a recovery
where it shouldn't. Increase the timeout to avoid that.

Signed-off-by: Eyal Shapira <eyal@wizery.com>
---
 drivers/net/wireless/wl12xx/scan.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/scan.h b/drivers/net/wireless/wl12xx/scan.h
index 96ff457..2b300f4 100644
--- a/drivers/net/wireless/wl12xx/scan.h
+++ b/drivers/net/wireless/wl12xx/scan.h
@@ -55,7 +55,7 @@ void wl1271_scan_sched_scan_results(struct wl1271 *wl);
 #define WL1271_SCAN_BAND_2_4_GHZ 0
 #define WL1271_SCAN_BAND_5_GHZ 1
 
-#define WL1271_SCAN_TIMEOUT    10000 /* msec */
+#define WL1271_SCAN_TIMEOUT    30000 /* msec */
 
 enum {
 	WL1271_SCAN_STATE_IDLE,
-- 
1.7.4.1


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

* Re: [PATCH 0/4] wl12xx: various bug fixes for 3.4
  2012-03-19 10:06 [PATCH 0/4] wl12xx: various bug fixes for 3.4 Eyal Shapira
                   ` (3 preceding siblings ...)
  2012-03-19 10:06 ` [PATCH 4/4] wl12xx: increase scan timeout to 30s Eyal Shapira
@ 2012-04-10 10:20 ` Luciano Coelho
  4 siblings, 0 replies; 6+ messages in thread
From: Luciano Coelho @ 2012-04-10 10:20 UTC (permalink / raw)
  To: Eyal Shapira; +Cc: linux-wireless

On Mon, 2012-03-19 at 12:06 +0200, Eyal Shapira wrote: 
> Some recent bug fixes fixing a panic and a memory leak
> related to FW recovery as well as some scan issues.
> 
> Eyal Shapira (4):
>   wl12xx: fix race between suspend/resume and recovery
>   wl12xx: fix a memory leak of probereq template upon recovery
>   wl12xx: adaptive sched scan dwell times
>   wl12xx: increase scan timeout to 30s
> 
>  drivers/net/wireless/wl12xx/conf.h |   28 ++++++++++++++----
>  drivers/net/wireless/wl12xx/main.c |   54 +++++++++++++++++++----------------
>  drivers/net/wireless/wl12xx/scan.c |   29 ++++++++++++++++--
>  drivers/net/wireless/wl12xx/scan.h |    2 +-
>  4 files changed, 77 insertions(+), 36 deletions(-)

Pushed the series, except for 1/4 because it was duplicate.

-- 
Cheers,
Luca.


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

end of thread, other threads:[~2012-04-10 10:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-19 10:06 [PATCH 0/4] wl12xx: various bug fixes for 3.4 Eyal Shapira
2012-03-19 10:06 ` [PATCH 1/4] wl12xx: fix race between suspend/resume and recovery Eyal Shapira
2012-03-19 10:06 ` [PATCH 2/4] wl12xx: fix a memory leak of probereq template upon recovery Eyal Shapira
2012-03-19 10:06 ` [PATCH 3/4] wl12xx: adaptive sched scan dwell times Eyal Shapira
2012-03-19 10:06 ` [PATCH 4/4] wl12xx: increase scan timeout to 30s Eyal Shapira
2012-04-10 10:20 ` [PATCH 0/4] wl12xx: various bug fixes for 3.4 Luciano Coelho

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.