#ifdef PROP_TXSTATUS_VSDB
extern int disable_proptx;
#endif /* PROP_TXSTATUS_VSDB */
+static int wl_cfg80211_check_in4way(struct bcm_cfg80211 *cfg,
+ struct net_device *dev, uint action, enum wl_ext_status status, void *context);
extern int passive_channel_skip;
return err;
}
-void
-wl_cfg80211_4way_start(struct bcm_cfg80211 *cfg, struct net_device *dev)
-{
- dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
- struct wl_security *sec;
- s32 bssidx = -1;
-
- bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr);
-
- sec = wl_read_prof(cfg, dev, WL_PROF_SEC);
- if ((sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) &&
- bssidx == 0 && dhdp->conf->in4way) {
- WL_DBG(("Enter in4way=0x%x\n", dhdp->conf->in4way));
- cfg->handshaking = 1;
- if (dhdp->conf->in4way & NO_BTC_IN4WAY)
- wldev_iovar_setint(dev, "btc_mode", 0);
- }
-}
-
-void
-wl_cfg80211_4way_exit(struct bcm_cfg80211 *cfg, struct net_device *dev)
-{
- dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
-
- if (cfg->handshaking) {
- WL_DBG(("Enter in4way=0x%x\n", dhdp->conf->in4way));
- if (dhdp->conf->in4way & NO_BTC_IN4WAY)
- wldev_iovar_setint(dev, "btc_mode", 1);
- cfg->handshaking = 0;
- }
-}
-
-s32
-wl_cfg80211_4way_check(struct bcm_cfg80211 *cfg, uint mode)
-{
- dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
-
- if (cfg->handshaking && (dhdp->conf->in4way & mode)) {
- if (mode & NO_SCAN_IN4WAY && cfg->handshaking <= 3) {
- WL_ERR(("%s: return -EBUSY cnt %d\n", __FUNCTION__, cfg->handshaking));
- cfg->handshaking++;
- return -EBUSY;
- }
- }
- return 0;
-}
-
static s32
#if defined(WL_CFG80211_P2P_DEV_IF)
wl_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
return -ENODEV;
}
}
- err = wl_cfg80211_4way_check(cfg, NO_SCAN_IN4WAY);
+ err = wl_cfg80211_check_in4way(cfg, ndev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY,
+ WL_EXT_STATUS_SCAN, NULL);
if (err)
return err;
wl_clr_drv_status(cfg, CONNECTING, dev);
}
if (!err)
- wl_cfg80211_4way_start(cfg, dev);
+ wl_cfg80211_check_in4way(cfg, dev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY,
+ WL_EXT_STATUS_CONNECTING, NULL);
#ifdef WLTDLS
/* disable TDLS if number of connected interfaces is >= 1 */
WL_ERR(("Find p2p index from dev(%p) failed\n", dev->ieee80211_ptr));
return BCME_ERROR;
}
- wl_cfg80211_4way_exit(cfg, dev);
+ wl_cfg80211_check_in4way(cfg, dev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY,
+ WL_EXT_STATUS_4WAY_DONE, NULL);
if (mac_addr &&
((params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
u16 rc = params->reason_code;
#endif /* CUSTOM_BLOCK_DEAUTH_AT_EAP_FAILURE */
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) */
+
WL_DBG(("Entry\n"));
if (mac_addr == NULL) {
WL_DBG(("mac_addr is NULL ignore it\n"));
return -EFAULT;
}
}
+ err = wl_cfg80211_check_in4way(cfg, ndev, DONT_DELETE_GC_AFTER_WPS,
+ WL_EXT_STATUS_DELETE_GC, (void *)mac_addr);
+ if (err) {
+ return 0;
+ }
assoc_maclist->count = MAX_NUM_OF_ASSOCIATED_DEV;
err = wldev_ioctl_get(ndev, WLC_GET_ASSOCLIST,
sinfo.assoc_req_ies = data;
sinfo.assoc_req_ies_len = len;
printf("%s: connected device "MACDBG"\n", __FUNCTION__, MAC2STRDBG(e->addr.octet));
+ wl_cfg80211_check_in4way(cfg, ndev, DONT_DELETE_GC_AFTER_WPS,
+ WL_EXT_STATUS_GC_CONNECTED, NULL);
cfg80211_new_sta(ndev, e->addr.octet, &sinfo, GFP_ATOMIC);
} else if (event == WLC_E_DISASSOC_IND) {
printf("%s: disassociated device "MACDBG"\n", __FUNCTION__, MAC2STRDBG(e->addr.octet));
+ wl_cfg80211_check_in4way(cfg, ndev, DONT_DELETE_GC_AFTER_WPS,
+ WL_EXT_STATUS_GC_DISCONNECTED, NULL);
cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
} else if ((event == WLC_E_DEAUTH_IND) ||
((event == WLC_E_DEAUTH) && (reason != DOT11_RC_RESERVED))) {
printf("%s: deauthenticated device "MACDBG"\n", __FUNCTION__, MAC2STRDBG(e->addr.octet));
+ wl_cfg80211_check_in4way(cfg, ndev, DONT_DELETE_GC_AFTER_WPS,
+ WL_EXT_STATUS_GC_DISCONNECTED, NULL);
cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
}
#endif
"event : %d, reason=%d from " MACDBG "\n",
ndev->name, event, ntoh32(e->reason),
MAC2STRDBG((const u8*)(&e->addr)));
- wl_cfg80211_4way_exit(cfg, ndev);
+ wl_cfg80211_check_in4way(cfg, ndev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY,
+ WL_EXT_STATUS_DISCONNECTED, NULL);
/* roam offload does not sync BSSID always, get it from dongle */
if (cfg->roam_offload) {
}
else if (wl_get_drv_status(cfg, CONNECTING, ndev)) {
printf("link down, during connecting\n");
- wl_cfg80211_4way_exit(cfg, ndev);
+ wl_cfg80211_check_in4way(cfg, ndev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY,
+ WL_EXT_STATUS_DISCONNECTED, NULL);
/* Issue WLC_DISASSOC to prevent FW roam attempts */
err = wldev_ioctl_set(ndev, WLC_DISASSOC, NULL, 0);
if (err < 0) {
} else if (wl_is_nonetwork(cfg, e)) {
printf("connect failed event=%d e->status %d e->reason %d \n",
event, (int)ntoh32(e->status), (int)ntoh32(e->reason));
- wl_cfg80211_4way_exit(cfg, ndev);
+ wl_cfg80211_check_in4way(cfg, ndev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY,
+ WL_EXT_STATUS_DISCONNECTED, NULL);
#if defined(DHD_ENABLE_BIGDATA_LOGGING)
if (event == WLC_E_SET_SSID) {
wl_get_connect_failed_status(cfg, e);
dhd_conf_set_wme(cfg->pub, 0);
} else {
WL_ERR(("Report connect result - connection failed\n"));
- wl_cfg80211_4way_exit(cfg, ndev);
+ wl_cfg80211_check_in4way(cfg, ndev, NO_SCAN_IN4WAY|NO_BTC_IN4WAY,
+ WL_EXT_STATUS_DISCONNECTED, NULL);
}
}
#ifdef CONFIG_TCPACK_FASTTX
}
#endif /* WL_DRV_AVOID_SCANCACHE */
+
static s32 wl_escan_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
const wl_event_msg_t *e, void *data)
{
goto exit;
}
#ifdef ESCAN_BUF_OVERFLOW_MGMT
- WL_TRACE(("%s("MACDBG"), i=%d bss: RSSI %d list->count %d\n",
+ WL_SCAN(("%s("MACDBG"), i=%d bss: RSSI %d list->count %d\n",
bss->SSID, MAC2STRDBG(bss->BSSID.octet),
i, bss->RSSI, list->count));
DBG_EVENT_LOG((dhd_pub_t *)cfg->pub, WIFI_EVENT_DRIVER_SCAN_COMPLETE);
cfg->bss_list = wl_escan_get_buf(cfg, FALSE);
if (!scan_req_match(cfg)) {
- WL_TRACE_HW4(("SCAN COMPLETED: scanned AP count=%d\n",
+ WL_SCAN(("SCAN COMPLETED: scanned AP count=%d\n",
cfg->bss_list->count));
}
wl_inform_bss(cfg);
spin_lock_init(&cfg->cfgdrv_lock);
mutex_init(&cfg->ioctl_buf_sync);
init_waitqueue_head(&cfg->netif_change_event);
+ init_waitqueue_head(&cfg->wps_done_event);
init_completion(&cfg->send_af_done);
init_completion(&cfg->iface_disable);
mutex_init(&cfg->usr_sync);
mutex_init(&cfg->scan_complete);
mutex_init(&cfg->if_sync);
mutex_init(&cfg->pm_sync);
+ mutex_init(&cfg->in4way_sync);
#ifdef WLTDLS
mutex_init(&cfg->tdls_sync);
#endif /* WLTDLS */
return BCME_VERSION;
}
ioctl_version = val;
- wl_cfg80211_4way_exit(cfg, net);
+ wl_cfg80211_check_in4way(cfg, net, NO_SCAN_IN4WAY|NO_BTC_IN4WAY,
+ WL_EXT_STATUS_DISCONNECTED, NULL);
WL_TRACE(("WLC_GET_VERSION=%d\n", ioctl_version));
mutex_lock(&cfg->usr_sync);
}
#endif /* SUPPORT_RSSI_LOGGING */
-s32 wl_cfg80211_autochannel(struct net_device *dev, char* command, int total_len)
+s32
+wl_cfg80211_autochannel(struct net_device *dev, char* command, int total_len)
{
struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
int ret = 0;
return ret;
}
+
+static int
+wl_cfg80211_check_in4way(struct bcm_cfg80211 *cfg,
+ struct net_device *dev, uint action, enum wl_ext_status status, void *context)
+{
+ dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
+ struct wl_security *sec;
+ s32 bssidx = -1;
+ int ret = 0;
+ int max_wait_gc_time = dhdp->conf->max_wait_gc_time;
+
+ if (!(dhdp->conf->in4way & action))
+ return 0;
+
+ mutex_lock(&cfg->in4way_sync);
+ WL_DBG(("status=%d, action=0x%x\n", status, action));
+
+ switch (status) {
+ case WL_EXT_STATUS_SCAN:
+ if (action & (NO_SCAN_IN4WAY|NO_BTC_IN4WAY)) {
+ if (cfg->handshaking > 0 && cfg->handshaking <= 3) {
+ WL_ERR(("%s: return -EBUSY cnt %d\n",
+ __FUNCTION__, cfg->handshaking));
+ cfg->handshaking++;
+ ret = -EBUSY;
+ break;
+ }
+ }
+ break;
+ case WL_EXT_STATUS_CONNECTING:
+ if (action & (NO_SCAN_IN4WAY|NO_BTC_IN4WAY)) {
+ bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr);
+ sec = wl_read_prof(cfg, dev, WL_PROF_SEC);
+ if ((sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) &&
+ bssidx == 0) {
+ cfg->handshaking = 1;
+ if (action & NO_BTC_IN4WAY)
+ wldev_iovar_setint(dev, "btc_mode", 0);
+ }
+ }
+ break;
+ case WL_EXT_STATUS_DELETE_GC:
+ if ((action & DONT_DELETE_GC_AFTER_WPS) &&
+ (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO)) {
+ u8* mac_addr = context;
+ if (memcmp(ðer_bcast, mac_addr, ETHER_ADDR_LEN) &&
+ dhdp->conf->eapol_status == EAPOL_STATUS_WPS_DONE) {
+ u32 timeout;
+ WL_TRACE(("status=%d, wps_done=%d, waiting %dms ...\n",
+ status, cfg->wps_done, max_wait_gc_time));
+ mutex_unlock(&cfg->in4way_sync);
+ timeout = wait_event_interruptible_timeout(cfg->wps_done_event,
+ cfg->wps_done, msecs_to_jiffies(max_wait_gc_time));
+ mutex_lock(&cfg->in4way_sync);
+ WL_TRACE(("status=%d, wps_done=%d, timeout=%d\n",
+ status, cfg->wps_done, timeout));
+ if (timeout > 0) {
+ ret = -1;
+ break;
+ }
+ } else {
+ WL_TRACE(("status=%d, wps_done=%d => 0\n", status, cfg->wps_done));
+ cfg->wps_done = FALSE;
+ dhdp->conf->eapol_status = EAPOL_STATUS_NONE;
+ }
+ }
+ break;
+ case WL_EXT_STATUS_GC_DISCONNECTED:
+ if ((action & DONT_DELETE_GC_AFTER_WPS) &&
+ (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO) &&
+ dhdp->conf->eapol_status == EAPOL_STATUS_WPS_DONE) {
+ WL_TRACE(("status=%d, wps_done=%d => 0\n", status, cfg->wps_done));
+ cfg->wps_done = FALSE;
+ }
+ break;
+ case WL_EXT_STATUS_GC_CONNECTED:
+ if ((action & DONT_DELETE_GC_AFTER_WPS) &&
+ (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO) &&
+ dhdp->conf->eapol_status == EAPOL_STATUS_WPS_DONE) {
+ WL_TRACE(("status=%d, wps_done=%d => 1\n", status, cfg->wps_done));
+ cfg->wps_done = TRUE;
+ wake_up_interruptible(&cfg->wps_done_event);
+ }
+ break;
+ case WL_EXT_STATUS_DISCONNECTED:
+ case WL_EXT_STATUS_4WAY_DONE:
+ if (action & (NO_SCAN_IN4WAY|NO_BTC_IN4WAY)) {
+ if (cfg->handshaking) {
+ if (action & NO_BTC_IN4WAY)
+ wldev_iovar_setint(dev, "btc_mode", 1);
+ cfg->handshaking = 0;
+ }
+ }
+ break;
+ default:
+ WL_ERR(("Unknown action=0x%x, status=%d\n", action, status));
+ }
+
+ mutex_unlock(&cfg->in4way_sync);
+
+ return ret;
+}
\ No newline at end of file