Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7f813ce1 authored by Johannes Berg's avatar Johannes Berg
Browse files

mac80211_hwsim: report survey data for scanned channels



Currently, hwsim is reporting survey data (only a fake noise floor)
for the current channel. This breaks when the multi-channel support
is enabled since then there's no current channel.

Make the dummy implementation closer to a real one and only report
data while scanning, for all the scanned channels. At other times,
no survey data might be available (in real hardware) due to power-
save for example.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent f8f118ce
Loading
Loading
Loading
Loading
+60 −13
Original line number Diff line number Diff line
@@ -526,6 +526,11 @@ struct mac80211_hwsim_data {
	struct ieee80211_vif *hw_scan_vif;
	int scan_chan_idx;
	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;
	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_DYNAMIC] = "dynamic",
	};
	int idx;

	if (conf->chandef.chan)
		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);

	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;
			}
		}

		data->channel = conf->chandef.chan;

	WARN_ON(data->channel && data->use_chanctx);
		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;
	if (!data->started || !data->beacon_int)
@@ -1788,28 +1818,39 @@ static int mac80211_hwsim_conf_tx(
	return 0;
}

static int mac80211_hwsim_get_survey(
	struct ieee80211_hw *hw, int idx,
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);

	if (idx != 0)
	if (idx < 0 || idx >= ARRAY_SIZE(hwsim->survey_data))
		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->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;
}
@@ -1987,6 +2028,10 @@ static void hw_scan_work(struct work_struct *work)
	}
	ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan,
				     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++;
	mutex_unlock(&hwsim->mutex);
}
@@ -2012,6 +2057,7 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
				     hw_req->req.mac_addr_mask);
	else
		memcpy(hwsim->scan_addr, vif->addr, ETH_ALEN);
	memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
	mutex_unlock(&hwsim->mutex);

	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);
	hwsim->scanning = true;
	memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));

out:
	mutex_unlock(&hwsim->mutex);