|
@@ -526,6 +526,11 @@ struct mac80211_hwsim_data {
|
|
struct ieee80211_vif *hw_scan_vif;
|
|
struct ieee80211_vif *hw_scan_vif;
|
|
int scan_chan_idx;
|
|
int scan_chan_idx;
|
|
u8 scan_addr[ETH_ALEN];
|
|
u8 scan_addr[ETH_ALEN];
|
|
|
|
+ struct {
|
|
|
|
+ struct ieee80211_channel *channel;
|
|
|
|
+ unsigned long next_start, start, end;
|
|
|
|
+ } survey_data[ARRAY_SIZE(hwsim_channels_2ghz) +
|
|
|
|
+ ARRAY_SIZE(hwsim_channels_5ghz)];
|
|
|
|
|
|
struct ieee80211_channel *channel;
|
|
struct ieee80211_channel *channel;
|
|
u64 beacon_int /* beacon interval in us */;
|
|
u64 beacon_int /* beacon interval in us */;
|
|
@@ -1577,6 +1582,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
|
|
[IEEE80211_SMPS_STATIC] = "static",
|
|
[IEEE80211_SMPS_STATIC] = "static",
|
|
[IEEE80211_SMPS_DYNAMIC] = "dynamic",
|
|
[IEEE80211_SMPS_DYNAMIC] = "dynamic",
|
|
};
|
|
};
|
|
|
|
+ int idx;
|
|
|
|
|
|
if (conf->chandef.chan)
|
|
if (conf->chandef.chan)
|
|
wiphy_debug(hw->wiphy,
|
|
wiphy_debug(hw->wiphy,
|
|
@@ -1599,9 +1605,33 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
|
|
|
|
|
|
data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
|
|
data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
|
|
|
|
|
|
- data->channel = conf->chandef.chan;
|
|
|
|
|
|
+ WARN_ON(conf->chandef.chan && data->use_chanctx);
|
|
|
|
+
|
|
|
|
+ mutex_lock(&data->mutex);
|
|
|
|
+ if (data->scanning && conf->chandef.chan) {
|
|
|
|
+ for (idx = 0; idx < ARRAY_SIZE(data->survey_data); idx++) {
|
|
|
|
+ if (data->survey_data[idx].channel == data->channel) {
|
|
|
|
+ data->survey_data[idx].start =
|
|
|
|
+ data->survey_data[idx].next_start;
|
|
|
|
+ data->survey_data[idx].end = jiffies;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- WARN_ON(data->channel && data->use_chanctx);
|
|
|
|
|
|
+ data->channel = conf->chandef.chan;
|
|
|
|
+
|
|
|
|
+ for (idx = 0; idx < ARRAY_SIZE(data->survey_data); idx++) {
|
|
|
|
+ if (data->survey_data[idx].channel &&
|
|
|
|
+ data->survey_data[idx].channel != data->channel)
|
|
|
|
+ continue;
|
|
|
|
+ data->survey_data[idx].channel = data->channel;
|
|
|
|
+ data->survey_data[idx].next_start = jiffies;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ data->channel = conf->chandef.chan;
|
|
|
|
+ }
|
|
|
|
+ mutex_unlock(&data->mutex);
|
|
|
|
|
|
data->power_level = conf->power_level;
|
|
data->power_level = conf->power_level;
|
|
if (!data->started || !data->beacon_int)
|
|
if (!data->started || !data->beacon_int)
|
|
@@ -1788,28 +1818,39 @@ static int mac80211_hwsim_conf_tx(
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int mac80211_hwsim_get_survey(
|
|
|
|
- struct ieee80211_hw *hw, int idx,
|
|
|
|
- struct survey_info *survey)
|
|
|
|
|
|
+static int mac80211_hwsim_get_survey(struct ieee80211_hw *hw, int idx,
|
|
|
|
+ struct survey_info *survey)
|
|
{
|
|
{
|
|
- struct ieee80211_conf *conf = &hw->conf;
|
|
|
|
|
|
+ struct mac80211_hwsim_data *hwsim = hw->priv;
|
|
|
|
|
|
wiphy_debug(hw->wiphy, "%s (idx=%d)\n", __func__, idx);
|
|
wiphy_debug(hw->wiphy, "%s (idx=%d)\n", __func__, idx);
|
|
|
|
|
|
- if (idx != 0)
|
|
|
|
|
|
+ if (idx < 0 || idx >= ARRAY_SIZE(hwsim->survey_data))
|
|
return -ENOENT;
|
|
return -ENOENT;
|
|
|
|
|
|
- /* Current channel */
|
|
|
|
- survey->channel = conf->chandef.chan;
|
|
|
|
|
|
+ mutex_lock(&hwsim->mutex);
|
|
|
|
+ survey->channel = hwsim->survey_data[idx].channel;
|
|
|
|
+ if (!survey->channel) {
|
|
|
|
+ mutex_unlock(&hwsim->mutex);
|
|
|
|
+ return -ENOENT;
|
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
/*
|
|
- * Magically conjured noise level --- this is only ok for simulated hardware.
|
|
|
|
|
|
+ * Magically conjured dummy values --- this is only ok for simulated hardware.
|
|
*
|
|
*
|
|
- * A real driver which cannot determine the real channel noise MUST NOT
|
|
|
|
- * report any noise, especially not a magically conjured one :-)
|
|
|
|
|
|
+ * A real driver which cannot determine real values noise MUST NOT
|
|
|
|
+ * report any, especially not a magically conjured ones :-)
|
|
*/
|
|
*/
|
|
- survey->filled = SURVEY_INFO_NOISE_DBM;
|
|
|
|
|
|
+ survey->filled = SURVEY_INFO_NOISE_DBM |
|
|
|
|
+ SURVEY_INFO_TIME |
|
|
|
|
+ SURVEY_INFO_TIME_BUSY;
|
|
survey->noise = -92;
|
|
survey->noise = -92;
|
|
|
|
+ survey->time =
|
|
|
|
+ jiffies_to_msecs(hwsim->survey_data[idx].end -
|
|
|
|
+ hwsim->survey_data[idx].start);
|
|
|
|
+ /* report 12.5% of channel time is used */
|
|
|
|
+ survey->time_busy = survey->time/8;
|
|
|
|
+ mutex_unlock(&hwsim->mutex);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -1987,6 +2028,10 @@ static void hw_scan_work(struct work_struct *work)
|
|
}
|
|
}
|
|
ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan,
|
|
ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan,
|
|
msecs_to_jiffies(dwell));
|
|
msecs_to_jiffies(dwell));
|
|
|
|
+ hwsim->survey_data[hwsim->scan_chan_idx].channel = hwsim->tmp_chan;
|
|
|
|
+ hwsim->survey_data[hwsim->scan_chan_idx].start = jiffies;
|
|
|
|
+ hwsim->survey_data[hwsim->scan_chan_idx].end =
|
|
|
|
+ jiffies + msecs_to_jiffies(dwell);
|
|
hwsim->scan_chan_idx++;
|
|
hwsim->scan_chan_idx++;
|
|
mutex_unlock(&hwsim->mutex);
|
|
mutex_unlock(&hwsim->mutex);
|
|
}
|
|
}
|
|
@@ -2012,6 +2057,7 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
|
|
hw_req->req.mac_addr_mask);
|
|
hw_req->req.mac_addr_mask);
|
|
else
|
|
else
|
|
memcpy(hwsim->scan_addr, vif->addr, ETH_ALEN);
|
|
memcpy(hwsim->scan_addr, vif->addr, ETH_ALEN);
|
|
|
|
+ memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
|
|
mutex_unlock(&hwsim->mutex);
|
|
mutex_unlock(&hwsim->mutex);
|
|
|
|
|
|
wiphy_debug(hw->wiphy, "hwsim hw_scan request\n");
|
|
wiphy_debug(hw->wiphy, "hwsim hw_scan request\n");
|
|
@@ -2058,6 +2104,7 @@ static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw,
|
|
|
|
|
|
memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN);
|
|
memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN);
|
|
hwsim->scanning = true;
|
|
hwsim->scanning = true;
|
|
|
|
+ memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
|
|
|
|
|
|
out:
|
|
out:
|
|
mutex_unlock(&hwsim->mutex);
|
|
mutex_unlock(&hwsim->mutex);
|