From: Ben Greear <greearb@xxxxxxxxxxxxxxx> The old code did not assign channel, so survey dump was always empty. Instead, return the info from the phy ctxts since we can at least fake out the channel busy time with that. Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx> --- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 21 +++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 4 ++++ drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 18 ++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 07778d55878b..038bb41594fc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -6063,6 +6063,27 @@ int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx, memset(survey, 0, sizeof(*survey)); + if (mvm->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_BZ) { + /* None of the code below this if clause appears to work + * on be200 radios, primarily because 'channel' is not assigned. + * So special case this to do something useful on be200 + * radio: Return channel and busy-time for the first 3 + * phy contexts. + */ + if (idx > 2) + return -ENOENT; + + if (!mvm->phy_ctxts[idx].ref) + return 0; + + survey->filled = SURVEY_INFO_TIME | SURVEY_INFO_TIME_BUSY; + survey->channel = mvm->phy_ctxts[idx].channel; + + survey->time = jiffies64_to_msecs(mvm->phy_ctxts[idx].channel_time_accum); + survey->time_busy = jiffies64_to_msecs(mvm->phy_ctxts[idx].channel_busy_accum); + return 0; + } + if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS)) return -ENOENT; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 751d2c2bf541..a79263e9e5bf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -105,6 +105,10 @@ struct iwl_mvm_phy_ctxt { u32 channel_load; u32 channel_load_by_us; u32 channel_load_not_by_us; + + u64 channel_time_accum; /* in jiffies */ + u64 channel_busy_accum; /* in jiffies */ + u64 last_jiffies; /* last time we accumulated the above */ }; struct iwl_mvm_time_event_data { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 7f285ee49097..ebb13df60a0f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -783,6 +783,8 @@ static void iwl_mvm_handle_per_phy_stats(struct iwl_mvm *mvm, struct iwl_stats_ntfy_per_phy *per_phy) { int i; + unsigned long jdiff; + u64 j = jiffies_64; for (i = 0; i < NUM_PHY_CTX; i++) { if (!mvm->phy_ctxts[i].ref) @@ -793,6 +795,22 @@ static void iwl_mvm_handle_per_phy_stats(struct iwl_mvm *mvm, le32_to_cpu(per_phy[i].channel_load_by_us); mvm->phy_ctxts[i].channel_load_not_by_us = le32_to_cpu(per_phy[i].channel_load_not_by_us); + + if (mvm->phy_ctxts[i].last_jiffies) { + if (j > mvm->phy_ctxts[i].last_jiffies) + jdiff = j - mvm->phy_ctxts[i].last_jiffies; + else + /* jiffies wrapped, just count from zero, close enough. */ + jdiff = j; + + /* We know busy percentage, back convert this to total + * time and total busy time. + */ + mvm->phy_ctxts[i].channel_time_accum += jdiff; + mvm->phy_ctxts[i].channel_busy_accum += + (jdiff * mvm->phy_ctxts[i].channel_load) / 100; + } + mvm->phy_ctxts[i].last_jiffies = j; } } -- 2.42.0