|
@@ -66,6 +66,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
|
|
|
struct cfg80211_bss *cbss;
|
|
|
struct ieee80211_bss *bss;
|
|
|
int clen, srlen;
|
|
|
+ enum nl80211_bss_scan_width scan_width;
|
|
|
s32 signal = 0;
|
|
|
|
|
|
if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
|
|
@@ -73,8 +74,15 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
|
|
|
else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
|
|
|
signal = (rx_status->signal * 100) / local->hw.max_signal;
|
|
|
|
|
|
- cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel,
|
|
|
- mgmt, len, signal, GFP_ATOMIC);
|
|
|
+ scan_width = NL80211_BSS_CHAN_WIDTH_20;
|
|
|
+ if (rx_status->flag & RX_FLAG_5MHZ)
|
|
|
+ scan_width = NL80211_BSS_CHAN_WIDTH_5;
|
|
|
+ if (rx_status->flag & RX_FLAG_10MHZ)
|
|
|
+ scan_width = NL80211_BSS_CHAN_WIDTH_10;
|
|
|
+
|
|
|
+ cbss = cfg80211_inform_bss_width_frame(local->hw.wiphy, channel,
|
|
|
+ scan_width, mgmt, len, signal,
|
|
|
+ GFP_ATOMIC);
|
|
|
if (!cbss)
|
|
|
return NULL;
|
|
|
|
|
@@ -300,7 +308,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
|
|
|
rcu_assign_pointer(local->scan_sdata, NULL);
|
|
|
|
|
|
local->scanning = 0;
|
|
|
- local->scan_channel = NULL;
|
|
|
+ local->scan_chandef.chan = NULL;
|
|
|
|
|
|
/* Set power back to normal operating levels. */
|
|
|
ieee80211_hw_config(local, 0);
|
|
@@ -635,11 +643,34 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
|
|
|
{
|
|
|
int skip;
|
|
|
struct ieee80211_channel *chan;
|
|
|
+ enum nl80211_bss_scan_width oper_scan_width;
|
|
|
|
|
|
skip = 0;
|
|
|
chan = local->scan_req->channels[local->scan_channel_idx];
|
|
|
|
|
|
- local->scan_channel = chan;
|
|
|
+ local->scan_chandef.chan = chan;
|
|
|
+ local->scan_chandef.center_freq1 = chan->center_freq;
|
|
|
+ local->scan_chandef.center_freq2 = 0;
|
|
|
+ switch (local->scan_req->scan_width) {
|
|
|
+ case NL80211_BSS_CHAN_WIDTH_5:
|
|
|
+ local->scan_chandef.width = NL80211_CHAN_WIDTH_5;
|
|
|
+ break;
|
|
|
+ case NL80211_BSS_CHAN_WIDTH_10:
|
|
|
+ local->scan_chandef.width = NL80211_CHAN_WIDTH_10;
|
|
|
+ break;
|
|
|
+ case NL80211_BSS_CHAN_WIDTH_20:
|
|
|
+ /* If scanning on oper channel, use whatever channel-type
|
|
|
+ * is currently in use.
|
|
|
+ */
|
|
|
+ oper_scan_width = cfg80211_chandef_to_scan_width(
|
|
|
+ &local->_oper_chandef);
|
|
|
+ if (chan == local->_oper_chandef.chan &&
|
|
|
+ oper_scan_width == local->scan_req->scan_width)
|
|
|
+ local->scan_chandef = local->_oper_chandef;
|
|
|
+ else
|
|
|
+ local->scan_chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL))
|
|
|
skip = 1;
|
|
@@ -679,7 +710,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
|
|
|
unsigned long *next_delay)
|
|
|
{
|
|
|
/* switch back to the operating channel */
|
|
|
- local->scan_channel = NULL;
|
|
|
+ local->scan_chandef.chan = NULL;
|
|
|
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
|
|
|
|
|
|
/* disable PS */
|
|
@@ -821,7 +852,8 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
|
|
|
|
|
|
int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
|
|
|
const u8 *ssid, u8 ssid_len,
|
|
|
- struct ieee80211_channel *chan)
|
|
|
+ struct ieee80211_channel *chan,
|
|
|
+ enum nl80211_bss_scan_width scan_width)
|
|
|
{
|
|
|
struct ieee80211_local *local = sdata->local;
|
|
|
int ret = -EBUSY;
|
|
@@ -871,6 +903,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
|
|
|
|
|
|
local->int_scan_req->ssids = &local->scan_ssid;
|
|
|
local->int_scan_req->n_ssids = 1;
|
|
|
+ local->int_scan_req->scan_width = scan_width;
|
|
|
memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
|
|
|
local->int_scan_req->ssids[0].ssid_len = ssid_len;
|
|
|
|