summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2008-08-05 23:20:56 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2008-08-20 11:05:10 -0700
commitc8579c82a2404274193ac75fe27d68bf112b908c (patch)
tree209321f38056124d09a1643de3ca94dc006e6988 /drivers
parentf733cd4d7fdbac8af0c711b4932e57909cab7883 (diff)
rtl8187: Fix lockups due to concurrent access to config routine
With the rtl8187 driver, the config routine is not protected against access before a previous call has completed. When this happens, the TX loopback that is needed to change channels may cause the chip to be locked with a reset needed to restore communications. This patch entered mainline as commit 7dcdd073bf78bb6958bbc12a1a47754a0f3c4721. The problem was found by Herton Ronaldo Krzesinski <herton@mandriva.com.br>, who also suggested this type of fix. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Acked-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br> Acked-by: Hin-Tak Leung <htl10@users.sourceforge.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/rtl8187.h4
-rw-r--r--drivers/net/wireless/rtl8187_dev.c3
2 files changed, 7 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h
index 076d88b6db0e..aefd4f67307c 100644
--- a/drivers/net/wireless/rtl8187.h
+++ b/drivers/net/wireless/rtl8187.h
@@ -67,6 +67,10 @@ struct rtl8187_priv {
const struct rtl818x_rf_ops *rf;
struct ieee80211_vif *vif;
int mode;
+ /* The mutex protects the TX loopback state.
+ * Any attempt to set channels concurrently locks the device.
+ */
+ struct mutex conf_mutex;
/* rtl8187 specific */
struct ieee80211_channel channels[14];
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 9223ada5f00e..d49d1c6960a2 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -580,6 +580,7 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
struct rtl8187_priv *priv = dev->priv;
u32 reg;
+ mutex_lock(&priv->conf_mutex);
reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
/* Enable TX loopback on MAC level to avoid TX during channel
* changes, as this has be seen to causes problems and the
@@ -610,6 +611,7 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100);
rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100);
+ mutex_unlock(&priv->conf_mutex);
return 0;
}
@@ -814,6 +816,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
printk(KERN_ERR "rtl8187: Cannot register device\n");
goto err_free_dev;
}
+ mutex_init(&priv->conf_mutex);
printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n",
wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),