mac80211: improve IBSS scanning
authorJohannes Berg <johannes@sipsolutions.net>
Mon, 3 May 2010 06:49:48 +0000 (08:49 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 3 May 2010 18:53:10 +0000 (14:53 -0400)
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>
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/scan.c

index c585fced8584eecf83b78c766760b9298005ba40..ba752362b2b2627a123f204e6dc7ce304c2f6a56 100644 (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;
 
index 4e73660ebe99ab92a3d46e0c4fc629c4cd319919..c8077a3647c68b45a28ad3f93e845b92ee4c7551 100644 (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);
index ebcca0eaf1dc5854c7bb41fcdf4832d8a1204467..353b6b42d9c5036b0fd0d2e165adc71b58dc86b0 100644 (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,
index a9d40584e383ef8348579de3830666bdf01d189f..414651217b497c8d1614e00202a0a053e0bda72e 100644 (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;