struct net_device *_ndev;
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
int (*net_attach)(dhd_pub_t *dhdp, int ifidx);
+ bool rollback_lock = false;
+
WL_DBG(("if name: %s, type: %d\n", name, type));
switch (type) {
case NL80211_IFTYPE_ADHOC:
/* wait till IF_DEL is complete
* release the lock for the unregister to proceed
*/
- rtnl_unlock();
+ /* put back the rtnl_lock again */
+ if (rtnl_is_locked()) {
+ rtnl_unlock();
+ rollback_lock = true;
+ }
WL_INFO(("%s: Released the lock and wait till IF_DEL is complete\n",
__func__));
timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
msecs_to_jiffies(MAX_WAIT_TIME));
/* put back the rtnl_lock again */
- rtnl_lock();
+ if (rollback_lock) {
+ rtnl_lock();
+ rollback_lock = false;
+ }
if (timeout > 0) {
WL_ERR(("IF DEL is Success\n"));
wl->p2p->vif_created = true;
set_mode_by_netdev(wl, _ndev, mode);
net_attach = wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION);
- rtnl_unlock();
+ /* put back the rtnl_lock again */
+ if (rtnl_is_locked()) {
+ rtnl_unlock();
+ rollback_lock = true;
+ }
if (net_attach && !net_attach(dhd, _ndev->ifindex))
WL_DBG((" virtual interface(%s) is "
"created net attach done\n", wl->p2p->vir_ifname));
else {
- rtnl_lock();
+ /* put back the rtnl_lock again */
+ if (rollback_lock)
+ rtnl_lock();
goto fail;
}
- rtnl_lock();
+ /* put back the rtnl_lock again */
+ if (rollback_lock)
+ rtnl_lock();
return _ndev;
} else {
struct cfg80211_ssid ssid;
s32 scan_retry = 0;
s32 err = 0;
+ bool rollback_lock = false;
WL_TRACE(("In\n"));
CHECK_SYS_UP(wl);
}
} while (++scan_retry < WL_SCAN_RETRY_MAX);
/* to allow scan_inform to propagate to cfg80211 plane */
- rtnl_unlock();
+ if (rtnl_is_locked()) {
+ rtnl_unlock();
+ rollback_lock = true;
+ }
/* wait 4 secons till scan done.... */
schedule_timeout_interruptible(4 * HZ);
- rtnl_lock();
+ if (rollback_lock)
+ rtnl_lock();
bss = cfg80211_get_ibss(wiphy, NULL,
params->ssid, params->ssid_len);
}
ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
WLAN_CAPABILITY_ESS);
- rtnl_lock();
+ mutex_lock(&wl->usr_sync);
if (unlikely(!bss)) {
WL_DBG(("Could not find the AP\n"));
*(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
update_bss_info_out:
- rtnl_unlock();
+ mutex_unlock(&wl->usr_sync);
return err;
}
u16 flags = ntoh16(e->flags);
enum nl80211_key_type key_type;
- rtnl_lock();
+ mutex_lock(&wl->usr_sync);
if (flags & WLC_EVENT_MSG_GROUP)
key_type = NL80211_KEYTYPE_GROUP;
else
cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
NULL, GFP_KERNEL);
- rtnl_unlock();
+ mutex_unlock(&wl->usr_sync);
return 0;
}
if (wl->iscan_on && wl->iscan_kickstart)
return wl_wakeup_iscan(wl_to_iscan(wl));
+ mutex_lock(&wl->usr_sync);
wl_clr_drv_status(wl, SCANNING);
- rtnl_lock();
err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
sizeof(channel_inform), false);
if (unlikely(err)) {
wl->scan_request = NULL;
}
dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
- rtnl_unlock();
+ mutex_unlock(&wl->usr_sync);
return err;
}
static s32
s32 err = 0;
iscan->state = WL_ISCAN_STATE_IDLE;
- rtnl_lock();
+ mutex_lock(&wl->usr_sync);
wl_inform_bss(wl);
wl_notify_iscan_complete(iscan, false);
- rtnl_unlock();
+ mutex_unlock(&wl->usr_sync);
return err;
}
struct wl_iscan_ctrl *iscan = wl->iscan;
s32 err = 0;
- rtnl_lock();
+ mutex_lock(&wl->usr_sync);
wl_inform_bss(wl);
wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
- rtnl_unlock();
+ mutex_unlock(&wl->usr_sync);
/* Reschedule the timer */
mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
iscan->timer_on = 1;
s32 err = 0;
iscan->state = WL_ISCAN_STATE_IDLE;
- rtnl_lock();
+ mutex_lock(&wl->usr_sync);
wl_notify_iscan_complete(iscan, true);
- rtnl_unlock();
+ mutex_unlock(&wl->usr_sync);
return err;
}
del_timer_sync(&iscan->timer);
iscan->timer_on = 0;
}
- rtnl_lock();
+ mutex_lock(&wl->usr_sync);
err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
if (unlikely(err)) {
status = WL_SCAN_RESULTS_ABORTED;
WL_ERR(("Abort iscan\n"));
}
- rtnl_unlock();
+ mutex_unlock(&wl->usr_sync);
iscan->iscan_handler[status] (wl);
}
if (iscan->timer_on) {
else if (status == WLC_E_STATUS_SUCCESS) {
wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
if (likely(wl->scan_request)) {
- rtnl_lock();
+ mutex_lock(&wl->usr_sync);
del_timer_sync(&wl->scan_timeout);
WL_INFO(("ESCAN COMPLETED\n"));
wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
wl_inform_bss(wl);
wl_notify_escan_complete(wl, false);
- rtnl_unlock();
+ mutex_unlock(&wl->usr_sync);
}
}
else if (status == WLC_E_STATUS_ABORT) {
wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
if (likely(wl->scan_request)) {
- rtnl_lock();
+ mutex_lock(&wl->usr_sync);
del_timer_sync(&wl->scan_timeout);
WL_INFO(("ESCAN ABORTED\n"));
wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
wl_inform_bss(wl);
wl_notify_escan_complete(wl, true);
- rtnl_unlock();
+ mutex_unlock(&wl->usr_sync);
}
}
else {
WL_ERR(("unexpected Escan Event %d : abort\n", status));
wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
if (likely(wl->scan_request)) {
- rtnl_lock();
+ mutex_lock(&wl->usr_sync);
del_timer_sync(&wl->scan_timeout);
wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
wl_inform_bss(wl);
wl_notify_escan_complete(wl, true);
- rtnl_unlock();
+ mutex_unlock(&wl->usr_sync);
}
}
exit:
char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00};
#endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
- rtnl_lock();
-#endif
-
#if defined(BT_DHCP_eSCO_FIX)
/* set = 1, save & turn on 0 - off & restore prev settings */
set_btc_esco_params(dev, set);
(char *)&buf_flag7_default[0],
sizeof(buf_flag7_default));
#endif
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
- rtnl_unlock();
-#endif
}
static void wl_cfg80211_bt_timerfunc(ulong data)