lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 04 Mar 2011 16:55:18 -0800
From:	Greg KH <gregkh@...e.de>
To:	linux-kernel@...r.kernel.org, stable@...nel.org
Cc:	stable-review@...nel.org, torvalds@...ux-foundation.org,
	akpm@...ux-foundation.org, alan@...rguk.ukuu.org.uk,
	rvossen@...adcom.com
Subject: [13/73] staging: brcm80211: bugfix for softmac crash on multi cpu configurations

2.6.37-stable review patch.  If anyone has any objections, please let us know.

------------------


From: Roland Vossen <rvossen@...adcom.com>

commit 6a3be6e6e7feb4cb35275475d6a863b748d59cc3 upstream

Solved a locking issue that resulted in driver crashes with the 43224 and 43225
chips. The problem has been reported on several fora. Root cause was two fold:
hardware was being manipulated by two unsynchronized threads, and a scan
operation could interfere with an ongoing dynamic calibration process. Fix was
to invoke a lock on wl_ops_config() operation and to set internal flags when a
scan operation is started and stopped.

Please add this to the staging-linus branch.

Reviewed-by: Arend van Spriel <arend@...adcom.com>
Signed-off-by: Roland Vossen <rvossen@...adcom.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...e.de>
---
 drivers/staging/brcm80211/sys/wl_mac80211.c  |   14 ++++++++++----
 drivers/staging/brcm80211/sys/wlc_mac80211.c |   13 +++++++++++++
 drivers/staging/brcm80211/sys/wlc_pub.h      |    2 ++
 3 files changed, 25 insertions(+), 4 deletions(-)

--- a/drivers/staging/brcm80211/sys/wl_mac80211.c
+++ b/drivers/staging/brcm80211/sys/wl_mac80211.c
@@ -353,9 +353,7 @@ ieee_set_channel(struct ieee80211_hw *hw
 	switch (type) {
 	case NL80211_CHAN_HT20:
 	case NL80211_CHAN_NO_HT:
-		WL_LOCK(wl);
 		err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value);
-		WL_UNLOCK(wl);
 		break;
 	case NL80211_CHAN_HT40MINUS:
 	case NL80211_CHAN_HT40PLUS:
@@ -376,6 +374,7 @@ static int wl_ops_config(struct ieee8021
 	int err = 0;
 	int new_int;
 
+	WL_LOCK(wl);
 	if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
 		WL_NONE(("%s: Setting listen interval to %d\n",
 			 __func__, conf->listen_interval));
@@ -431,6 +430,7 @@ static int wl_ops_config(struct ieee8021
 	}
 
  config_out:
+	WL_UNLOCK(wl);
 	return err;
 }
 
@@ -559,14 +559,20 @@ wl_ops_set_tim(struct ieee80211_hw *hw,
 
 static void wl_ops_sw_scan_start(struct ieee80211_hw *hw)
 {
+	struct wl_info *wl = hw->priv;
 	WL_NONE(("Scan Start\n"));
-	return;
+	WL_LOCK(wl);
+	wlc_scan_start(wl->wlc);
+	WL_UNLOCK(wl);
 }
 
 static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw)
 {
+	struct wl_info *wl = hw->priv;
 	WL_NONE(("Scan Complete\n"));
-	return;
+	WL_LOCK(wl);
+	wlc_scan_stop(wl->wlc);
+	WL_UNLOCK(wl);
 }
 
 static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf)
--- a/drivers/staging/brcm80211/sys/wlc_mac80211.c
+++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c
@@ -8672,3 +8672,16 @@ static void wlc_txq_free(wlc_info_t *wlc
 
 	kfree(qi);
 }
+
+/*
+ * Flag 'scan in progress' to withold dynamic phy calibration
+ */
+void wlc_scan_start(struct wlc_info *wlc)
+{
+	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
+}
+
+void wlc_scan_stop(struct wlc_info *wlc)
+{
+	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
+}
--- a/drivers/staging/brcm80211/sys/wlc_pub.h
+++ b/drivers/staging/brcm80211/sys/wlc_pub.h
@@ -568,6 +568,8 @@ extern void wlc_enable_mac(struct wlc_in
 extern u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate);
 extern u32 wlc_get_rspec_history(struct wlc_bsscfg *cfg);
 extern u32 wlc_get_current_highest_rate(struct wlc_bsscfg *cfg);
+extern void wlc_scan_start(struct wlc_info *wlc);
+extern void wlc_scan_stop(struct wlc_info *wlc);
 
 static inline int wlc_iovar_getuint(struct wlc_info *wlc, const char *name,
 				    uint *arg)


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ