aboutsummaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2010-11-02 16:35:22 -0700
committerJonas ABERG <jonas.aberg@stericsson.com>2011-04-01 13:23:44 +0200
commit5e5a2fd34de09353f5337a9de5e42743490b1b9a (patch)
treeaa1ff696bee2e371470287dc3ea4c0a6effa08ce /drivers/net
parent51df0e4d1eed30a131116d2812b8ec0ca947c444 (diff)
net: wireless: bcm4329: Fix race conditions for sysioc_thread
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com> Change-Id: I6a651b0267946e54762f2df33909c9dc5a41a7c0 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/19491 Tested-by: Piotr TOMASZEWSKI <piotr.tomaszewski@stericsson.com> Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/bcm4329/dhd.h3
-rw-r--r--drivers/net/wireless/bcm4329/dhd_linux.c24
-rw-r--r--drivers/net/wireless/bcm4329/wl_iw.c19
3 files changed, 38 insertions, 8 deletions
diff --git a/drivers/net/wireless/bcm4329/dhd.h b/drivers/net/wireless/bcm4329/dhd.h
index cc7e8cb286b..5d8dc32fd30 100644
--- a/drivers/net/wireless/bcm4329/dhd.h
+++ b/drivers/net/wireless/bcm4329/dhd.h
@@ -218,6 +218,9 @@ extern int dhd_os_wake_unlock(dhd_pub_t *pub);
extern int dhd_os_wake_lock_timeout(dhd_pub_t *pub);
extern int dhd_os_wake_lock_timeout_enable(dhd_pub_t *pub);
+extern void dhd_os_start_lock(dhd_pub_t *pub);
+extern void dhd_os_start_unlock(dhd_pub_t *pub);
+
typedef struct dhd_if_event {
uint8 ifidx;
uint8 action;
diff --git a/drivers/net/wireless/bcm4329/dhd_linux.c b/drivers/net/wireless/bcm4329/dhd_linux.c
index f687b31e333..ba185752e78 100644
--- a/drivers/net/wireless/bcm4329/dhd_linux.c
+++ b/drivers/net/wireless/bcm4329/dhd_linux.c
@@ -281,6 +281,8 @@ typedef struct dhd_info {
int hang_was_sent;
+ struct mutex wl_start_lock;
+
/* Thread to issue ioctl for multicast */
long sysioc_pid;
struct semaphore sysioc_sem;
@@ -992,9 +994,11 @@ _dhd_sysioc_thread(void *data)
DAEMONIZE("dhd_sysioc");
while (down_interruptible(&dhd->sysioc_sem) == 0) {
+ dhd_os_start_lock(&dhd->pub);
dhd_os_wake_lock(&dhd->pub);
for (i = 0; i < DHD_MAX_IFS; i++) {
if (dhd->iflist[i]) {
+ DHD_TRACE(("%s: interface %d\n",__FUNCTION__, i));
#ifdef SOFTAP
in_ap = (ap_net_dev != NULL);
#endif /* SOFTAP */
@@ -1029,6 +1033,7 @@ _dhd_sysioc_thread(void *data)
}
}
dhd_os_wake_unlock(&dhd->pub);
+ dhd_os_start_unlock(&dhd->pub);
}
complete_and_exit(&dhd->sysioc_exited, 0);
}
@@ -1042,6 +1047,7 @@ dhd_set_mac_address(struct net_device *dev, void *addr)
struct sockaddr *sa = (struct sockaddr *)addr;
int ifidx;
+ DHD_TRACE(("%s: Enter\n",__FUNCTION__));
ifidx = dhd_net2idx(dhd, dev);
if (ifidx == DHD_BAD_IF)
return -1;
@@ -1060,6 +1066,7 @@ dhd_set_multicast_list(struct net_device *dev)
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
int ifidx;
+ DHD_TRACE(("%s: Enter\n",__FUNCTION__));
ifidx = dhd_net2idx(dhd, dev);
if (ifidx == DHD_BAD_IF)
return;
@@ -2046,6 +2053,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
wake_lock_init(&dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake");
wake_lock_init(&dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake");
#endif
+ mutex_init(&dhd->wl_start_lock);
/* Link to info module */
dhd->pub.info = dhd;
@@ -3216,3 +3224,19 @@ int net_os_send_hang_message(struct net_device *dev)
}
return ret;
}
+
+void dhd_os_start_lock(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+ if (dhd)
+ mutex_lock(&dhd->wl_start_lock);
+}
+
+void dhd_os_start_unlock(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+ if (dhd)
+ mutex_unlock(&dhd->wl_start_lock);
+}
diff --git a/drivers/net/wireless/bcm4329/wl_iw.c b/drivers/net/wireless/bcm4329/wl_iw.c
index 070c3e32531..14477ee6edc 100644
--- a/drivers/net/wireless/bcm4329/wl_iw.c
+++ b/drivers/net/wireless/bcm4329/wl_iw.c
@@ -109,8 +109,7 @@ static int wl_iw_softap_deassoc_stations(struct net_device *dev);
} while (0)
static int g_onoff = G_WLAN_SET_ON;
-wl_iw_extra_params_t g_wl_iw_params;
-static struct mutex wl_start_lock;
+wl_iw_extra_params_t g_wl_iw_params;
static struct mutex wl_cache_lock;
extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status,
@@ -1347,6 +1346,7 @@ wl_iw_send_priv_event(
int
wl_control_wl_start(struct net_device *dev)
{
+ wl_iw_t *iw;
int ret = 0;
WL_TRACE(("Enter %s \n", __FUNCTION__));
@@ -1356,7 +1356,8 @@ wl_control_wl_start(struct net_device *dev)
return -1;
}
- mutex_lock(&wl_start_lock);
+ iw = *(wl_iw_t **)netdev_priv(dev);
+ dhd_os_start_lock(iw->pub);
if (g_onoff == G_WLAN_SET_OFF) {
dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON);
@@ -1377,7 +1378,7 @@ wl_control_wl_start(struct net_device *dev)
}
WL_TRACE(("Exited %s \n", __FUNCTION__));
- mutex_unlock(&wl_start_lock);
+ dhd_os_start_unlock(iw->pub);
return ret;
}
@@ -1388,7 +1389,9 @@ wl_iw_control_wl_off(
struct iw_request_info *info
)
{
+ wl_iw_t *iw;
int ret = 0;
+
WL_TRACE(("Enter %s\n", __FUNCTION__));
if (!dev) {
@@ -1396,7 +1399,8 @@ wl_iw_control_wl_off(
return -1;
}
- mutex_lock(&wl_start_lock);
+ iw = *(wl_iw_t **)netdev_priv(dev);
+ dhd_os_start_lock(iw->pub);
#ifdef SOFTAP
ap_cfg_running = FALSE;
@@ -1435,7 +1439,7 @@ wl_iw_control_wl_off(
wl_iw_send_priv_event(dev, "STOP");
}
- mutex_unlock(&wl_start_lock);
+ dhd_os_start_unlock(iw->pub);
WL_TRACE(("Exited %s\n", __FUNCTION__));
@@ -7753,7 +7757,7 @@ wl_iw_bt_init(struct net_device *dev)
return 0;
}
-int wl_iw_attach(struct net_device *dev, void * dhdp)
+int wl_iw_attach(struct net_device *dev, void *dhdp)
{
int params_size;
wl_iw_t *iw;
@@ -7762,7 +7766,6 @@ int wl_iw_attach(struct net_device *dev, void * dhdp)
#endif
mutex_init(&wl_cache_lock);
- mutex_init(&wl_start_lock);
#if defined(WL_IW_USE_ISCAN)
if (!dev)