]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
mac80211_hwsim: report survey data for scanned channels
authorJohannes Berg <johannes.berg@intel.com>
Wed, 6 Nov 2013 09:37:34 +0000 (10:37 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 6 Mar 2017 12:31:29 +0000 (13:31 +0100)
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: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/mac80211_hwsim.c

index 8b823c70ab69c3015e5e791f73d2a59b7c1653ea..67fc91dfcecdad58ce1924fea1ffd326bb46aa4e 100644 (file)
@@ -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);
 
-       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;
        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,
-       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);
 
-       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);