|
@@ -1270,7 +1270,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
|
|
|
|
|
|
scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
|
|
scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
|
|
ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len,
|
|
ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len,
|
|
- NULL, scan_width);
|
|
|
|
|
|
+ NULL, 0, scan_width);
|
|
}
|
|
}
|
|
|
|
|
|
static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
|
|
static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
|
|
@@ -1307,6 +1307,76 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
|
|
capability, 0, true);
|
|
capability, 0, true);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static unsigned ibss_setup_channels(struct wiphy *wiphy,
|
|
|
|
+ struct ieee80211_channel **channels,
|
|
|
|
+ unsigned int channels_max,
|
|
|
|
+ u32 center_freq, u32 width)
|
|
|
|
+{
|
|
|
|
+ struct ieee80211_channel *chan = NULL;
|
|
|
|
+ unsigned int n_chan = 0;
|
|
|
|
+ u32 start_freq, end_freq, freq;
|
|
|
|
+
|
|
|
|
+ if (width <= 20) {
|
|
|
|
+ start_freq = center_freq;
|
|
|
|
+ end_freq = center_freq;
|
|
|
|
+ } else {
|
|
|
|
+ start_freq = center_freq - width / 2 + 10;
|
|
|
|
+ end_freq = center_freq + width / 2 - 10;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (freq = start_freq; freq <= end_freq; freq += 20) {
|
|
|
|
+ chan = ieee80211_get_channel(wiphy, freq);
|
|
|
|
+ if (!chan)
|
|
|
|
+ continue;
|
|
|
|
+ if (n_chan >= channels_max)
|
|
|
|
+ return n_chan;
|
|
|
|
+
|
|
|
|
+ channels[n_chan] = chan;
|
|
|
|
+ n_chan++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return n_chan;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static unsigned int
|
|
|
|
+ieee80211_ibss_setup_scan_channels(struct wiphy *wiphy,
|
|
|
|
+ const struct cfg80211_chan_def *chandef,
|
|
|
|
+ struct ieee80211_channel **channels,
|
|
|
|
+ unsigned int channels_max)
|
|
|
|
+{
|
|
|
|
+ unsigned int n_chan = 0;
|
|
|
|
+ u32 width, cf1, cf2 = 0;
|
|
|
|
+
|
|
|
|
+ switch (chandef->width) {
|
|
|
|
+ case NL80211_CHAN_WIDTH_40:
|
|
|
|
+ width = 40;
|
|
|
|
+ break;
|
|
|
|
+ case NL80211_CHAN_WIDTH_80P80:
|
|
|
|
+ cf2 = chandef->center_freq2;
|
|
|
|
+ /* fall through */
|
|
|
|
+ case NL80211_CHAN_WIDTH_80:
|
|
|
|
+ width = 80;
|
|
|
|
+ break;
|
|
|
|
+ case NL80211_CHAN_WIDTH_160:
|
|
|
|
+ width = 160;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ width = 20;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cf1 = chandef->center_freq1;
|
|
|
|
+
|
|
|
|
+ n_chan = ibss_setup_channels(wiphy, channels, channels_max, cf1, width);
|
|
|
|
+
|
|
|
|
+ if (cf2)
|
|
|
|
+ n_chan += ibss_setup_channels(wiphy, &channels[n_chan],
|
|
|
|
+ channels_max - n_chan, cf2,
|
|
|
|
+ width);
|
|
|
|
+
|
|
|
|
+ return n_chan;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* This function is called with state == IEEE80211_IBSS_MLME_SEARCH
|
|
* This function is called with state == IEEE80211_IBSS_MLME_SEARCH
|
|
*/
|
|
*/
|
|
@@ -1372,11 +1442,18 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
|
|
/* Selected IBSS not found in current scan results - try to scan */
|
|
/* Selected IBSS not found in current scan results - try to scan */
|
|
if (time_after(jiffies, ifibss->last_scan_completed +
|
|
if (time_after(jiffies, ifibss->last_scan_completed +
|
|
IEEE80211_SCAN_INTERVAL)) {
|
|
IEEE80211_SCAN_INTERVAL)) {
|
|
|
|
+ struct ieee80211_channel *channels[8];
|
|
|
|
+ unsigned int num;
|
|
|
|
+
|
|
sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
|
|
sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
|
|
|
|
|
|
|
|
+ num = ieee80211_ibss_setup_scan_channels(local->hw.wiphy,
|
|
|
|
+ &ifibss->chandef,
|
|
|
|
+ channels,
|
|
|
|
+ ARRAY_SIZE(channels));
|
|
scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
|
|
scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
|
|
ieee80211_request_ibss_scan(sdata, ifibss->ssid,
|
|
ieee80211_request_ibss_scan(sdata, ifibss->ssid,
|
|
- ifibss->ssid_len, chan,
|
|
|
|
|
|
+ ifibss->ssid_len, channels, num,
|
|
scan_width);
|
|
scan_width);
|
|
} else {
|
|
} else {
|
|
int interval = IEEE80211_SCAN_INTERVAL;
|
|
int interval = IEEE80211_SCAN_INTERVAL;
|