Message ID | 20241212044522.922351-1-greearb@candelatech.com (mailing list archive) |
---|---|
State | New |
Delegated to: | Miri Korenblit |
Headers | show |
Series | wifi: iwlwifi: Fix survey dump for be200 radios. | expand |
On 12/11/24 20:45, greearb@candelatech.com wrote: > From: Ben Greear <greearb@candelatech.com> > > 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@candelatech.com> > --- > .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 19 +++++++++++++++++++ > drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 4 ++++ > drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 18 ++++++++++++++++++ > 3 files changed, 41 insertions(+) > > diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c > index fb341d8e8cdb..ec01350bbb34 100644 > --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c > +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c > @@ -6080,6 +6080,25 @@ 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. > + */ I later realized that I need to skip contexts that have zero 'ref', so at the least that needs changing. However, I'd like to know if there are other comments before I send a v2... Thanks, Ben
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index fb341d8e8cdb..ec01350bbb34 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -6080,6 +6080,25 @@ 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. + */ + + survey->filled = SURVEY_INFO_TIME | SURVEY_INFO_TIME_BUSY; + if (idx > 2) + return -ENOENT; + + 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 42545b611b97..a4e789290dd6 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 8230a9576428..3ac62ad0144b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -865,6 +865,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) @@ -875,6 +877,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; } }