mac80211: improve IBSS scanning

When IBSS is fixed to a frequency, it can still
scan to try to find the right BSSID. This makes
sense if the BSSID isn't also fixed, but it need
not scan all channels -- just one is sufficient.
Make it do that by moving the scan setup code to
ieee80211_request_internal_scan() and include
a channel variable setting.

Note that this can be further improved to start
the IBSS right away if both frequency and BSSID
are fixed.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Johannes Berg 2010-05-03 08:49:48 +02:00 committed by John W. Linville
parent a75b4363ea
commit be4a4b6a5d
4 changed files with 36 additions and 21 deletions

View file

@ -488,7 +488,9 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
"IBSS networks with same SSID (merge)\n", sdata->name);
ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len);
ieee80211_request_internal_scan(sdata,
ifibss->ssid, ifibss->ssid_len,
ifibss->fixed_channel ? ifibss->channel : NULL);
}
static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@ -595,8 +597,9 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
"join\n", sdata->name);
ieee80211_request_internal_scan(sdata, ifibss->ssid,
ifibss->ssid_len);
ieee80211_request_internal_scan(sdata,
ifibss->ssid, ifibss->ssid_len,
ifibss->fixed_channel ? ifibss->channel : NULL);
} else {
int interval = IEEE80211_SCAN_INTERVAL;

View file

@ -1020,7 +1020,8 @@ void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata);
/* scan/BSS handling */
void ieee80211_scan_work(struct work_struct *work);
int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
const u8 *ssid, u8 ssid_len);
const u8 *ssid, u8 ssid_len,
struct ieee80211_channel *chan);
int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
struct cfg80211_scan_request *req);
void ieee80211_scan_cancel(struct ieee80211_local *local);

View file

@ -439,7 +439,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
struct ieee80211_local *local = hw_to_local(hw);
int result;
enum ieee80211_band band;
int channels, i, j, max_bitrates;
int channels, max_bitrates;
bool supp_ht;
static const u32 cipher_suites[] = {
WLAN_CIPHER_SUITE_WEP40,
@ -605,21 +605,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
ieee80211_led_init(local);
/* alloc internal scan request */
i = 0;
local->int_scan_req->ssids = &local->scan_ssid;
local->int_scan_req->n_ssids = 1;
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (!hw->wiphy->bands[band])
continue;
for (j = 0; j < hw->wiphy->bands[band]->n_channels; j++) {
local->int_scan_req->channels[i] =
&hw->wiphy->bands[band]->channels[j];
i++;
}
}
local->int_scan_req->n_channels = i;
local->network_latency_notifier.notifier_call =
ieee80211_max_network_latency;
result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY,

View file

@ -728,10 +728,12 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
}
int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
const u8 *ssid, u8 ssid_len)
const u8 *ssid, u8 ssid_len,
struct ieee80211_channel *chan)
{
struct ieee80211_local *local = sdata->local;
int ret = -EBUSY;
enum nl80211_band band;
mutex_lock(&local->scan_mtx);
@ -739,6 +741,30 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
if (local->scan_req)
goto unlock;
/* fill internal scan request */
if (!chan) {
int i, nchan = 0;
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (!local->hw.wiphy->bands[band])
continue;
for (i = 0;
i < local->hw.wiphy->bands[band]->n_channels;
i++) {
local->int_scan_req->channels[nchan] =
&local->hw.wiphy->bands[band]->channels[i];
nchan++;
}
}
local->int_scan_req->n_channels = nchan;
} else {
local->int_scan_req->channels[0] = chan;
local->int_scan_req->n_channels = 1;
}
local->int_scan_req->ssids = &local->scan_ssid;
local->int_scan_req->n_ssids = 1;
memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
local->int_scan_req->ssids[0].ssid_len = ssid_len;