|
|
|
@@ -527,7 +527,8 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
|
|
|
|
|
|
|
|
|
|
if (ch->flags & IEEE80211_CHAN_NO_IR)
|
|
|
|
|
scan_chan_list[chan_idx].chan_scan_mode_bitmap
|
|
|
|
|
|= MWIFIEX_PASSIVE_SCAN;
|
|
|
|
|
|= (MWIFIEX_PASSIVE_SCAN |
|
|
|
|
|
MWIFIEX_HIDDEN_SSID_REPORT);
|
|
|
|
|
else
|
|
|
|
|
scan_chan_list[chan_idx].chan_scan_mode_bitmap
|
|
|
|
|
&= ~MWIFIEX_PASSIVE_SCAN;
|
|
|
|
@@ -1049,7 +1050,8 @@ mwifiex_config_scan(struct mwifiex_private *priv,
|
|
|
|
|
if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
|
|
|
|
|
(scan_chan_list +
|
|
|
|
|
chan_idx)->chan_scan_mode_bitmap
|
|
|
|
|
|= MWIFIEX_PASSIVE_SCAN;
|
|
|
|
|
|= (MWIFIEX_PASSIVE_SCAN |
|
|
|
|
|
MWIFIEX_HIDDEN_SSID_REPORT);
|
|
|
|
|
else
|
|
|
|
|
(scan_chan_list +
|
|
|
|
|
chan_idx)->chan_scan_mode_bitmap
|
|
|
|
@@ -1600,6 +1602,62 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This function checks if SSID string contains all zeroes or length is zero */
|
|
|
|
|
static bool mwifiex_is_hidden_ssid(struct cfg80211_ssid *ssid)
|
|
|
|
|
{
|
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
|
|
for (idx = 0; idx < ssid->ssid_len; idx++) {
|
|
|
|
|
if (ssid->ssid[idx])
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This function checks if any hidden SSID found in passive scan channels
|
|
|
|
|
* and save those channels for specific SSID active scan
|
|
|
|
|
*/
|
|
|
|
|
static int mwifiex_save_hidden_ssid_channels(struct mwifiex_private *priv,
|
|
|
|
|
struct cfg80211_bss *bss)
|
|
|
|
|
{
|
|
|
|
|
struct mwifiex_bssdescriptor *bss_desc;
|
|
|
|
|
int ret;
|
|
|
|
|
int chid;
|
|
|
|
|
|
|
|
|
|
/* Allocate and fill new bss descriptor */
|
|
|
|
|
bss_desc = kzalloc(sizeof(*bss_desc), GFP_KERNEL);
|
|
|
|
|
if (!bss_desc)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
|
|
ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
|
|
if (mwifiex_is_hidden_ssid(&bss_desc->ssid)) {
|
|
|
|
|
mwifiex_dbg(priv->adapter, INFO, "found hidden SSID\n");
|
|
|
|
|
for (chid = 0 ; chid < MWIFIEX_USER_SCAN_CHAN_MAX; chid++) {
|
|
|
|
|
if (priv->hidden_chan[chid].chan_number ==
|
|
|
|
|
bss->channel->hw_value)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (!priv->hidden_chan[chid].chan_number) {
|
|
|
|
|
priv->hidden_chan[chid].chan_number =
|
|
|
|
|
bss->channel->hw_value;
|
|
|
|
|
priv->hidden_chan[chid].radio_type =
|
|
|
|
|
bss->channel->band;
|
|
|
|
|
priv->hidden_chan[chid].scan_type =
|
|
|
|
|
MWIFIEX_SCAN_TYPE_ACTIVE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
kfree(bss_desc);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
|
|
|
|
|
struct cfg80211_bss *bss)
|
|
|
|
|
{
|
|
|
|
@@ -1789,6 +1847,14 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
|
|
|
|
|
.mac_address, ETH_ALEN))
|
|
|
|
|
mwifiex_update_curr_bss_params(priv, bss);
|
|
|
|
|
cfg80211_put_bss(priv->wdev.wiphy, bss);
|
|
|
|
|
|
|
|
|
|
if ((chan->flags & IEEE80211_CHAN_RADAR) ||
|
|
|
|
|
(chan->flags & IEEE80211_CHAN_NO_IR)) {
|
|
|
|
|
mwifiex_dbg(adapter, INFO,
|
|
|
|
|
"radar or passive channel %d\n",
|
|
|
|
|
channel);
|
|
|
|
|
mwifiex_save_hidden_ssid_channels(priv, bss);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
mwifiex_dbg(adapter, WARN, "missing BSS channel IE\n");
|
|
|
|
@@ -1812,6 +1878,57 @@ static void mwifiex_complete_scan(struct mwifiex_private *priv)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This function checks if any hidden SSID found in passive scan channels
|
|
|
|
|
* and do specific SSID active scan for those channels
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
struct mwifiex_adapter *adapter = priv->adapter;
|
|
|
|
|
u8 id = 0;
|
|
|
|
|
struct mwifiex_user_scan_cfg *user_scan_cfg;
|
|
|
|
|
|
|
|
|
|
if (adapter->active_scan_triggered) {
|
|
|
|
|
adapter->active_scan_triggered = false;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!priv->hidden_chan[0].chan_number) {
|
|
|
|
|
mwifiex_dbg(adapter, INFO, "No BSS with hidden SSID found on DFS channels\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
user_scan_cfg = kzalloc(sizeof(*user_scan_cfg), GFP_KERNEL);
|
|
|
|
|
|
|
|
|
|
if (!user_scan_cfg)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
|
|
memset(user_scan_cfg, 0, sizeof(*user_scan_cfg));
|
|
|
|
|
|
|
|
|
|
for (id = 0; id < MWIFIEX_USER_SCAN_CHAN_MAX; id++) {
|
|
|
|
|
if (!priv->hidden_chan[id].chan_number)
|
|
|
|
|
break;
|
|
|
|
|
memcpy(&user_scan_cfg->chan_list[id],
|
|
|
|
|
&priv->hidden_chan[id],
|
|
|
|
|
sizeof(struct mwifiex_user_scan_chan));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
adapter->active_scan_triggered = true;
|
|
|
|
|
user_scan_cfg->num_ssids = priv->scan_request->n_ssids;
|
|
|
|
|
user_scan_cfg->ssid_list = priv->scan_request->ssids;
|
|
|
|
|
|
|
|
|
|
ret = mwifiex_scan_networks(priv, user_scan_cfg);
|
|
|
|
|
kfree(user_scan_cfg);
|
|
|
|
|
|
|
|
|
|
memset(&priv->hidden_chan, 0, sizeof(priv->hidden_chan));
|
|
|
|
|
|
|
|
|
|
if (ret) {
|
|
|
|
|
dev_err(priv->adapter->dev, "scan failed: %d\n", ret);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
|
|
|
|
|
{
|
|
|
|
|
struct mwifiex_adapter *adapter = priv->adapter;
|
|
|
|
@@ -1825,6 +1942,8 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
|
|
|
|
|
adapter->scan_processing = false;
|
|
|
|
|
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
|
|
|
|
|
|
|
|
|
|
mwifiex_active_scan_req_for_passive_chan(priv);
|
|
|
|
|
|
|
|
|
|
if (!adapter->ext_scan)
|
|
|
|
|
mwifiex_complete_scan(priv);
|
|
|
|
|
|
|
|
|
@@ -1851,6 +1970,7 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
|
|
|
|
|
adapter->scan_processing = false;
|
|
|
|
|
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
|
|
|
|
|
|
|
|
|
|
if (!adapter->active_scan_triggered) {
|
|
|
|
|
if (priv->scan_request) {
|
|
|
|
|
mwifiex_dbg(adapter, INFO,
|
|
|
|
|
"info: aborting scan\n");
|
|
|
|
@@ -1861,6 +1981,7 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
|
|
|
|
|
mwifiex_dbg(adapter, INFO,
|
|
|
|
|
"info: scan already aborted\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* Get scan command from scan_pending_q and put to
|
|
|
|
|
* cmd_pending_q
|
|
|
|
|