diff mbox series

[v2,2/2] wifi: iwlwifi: Fix survey dump for be200 radios.

Message ID 20241218232849.3156720-2-greearb@candelatech.com (mailing list archive)
State New
Delegated to: Johannes Berg
Headers show
Series [v2,1/2] wifi: iwlwifi: Use phy-ctx channel load if no ies. | expand

Commit Message

Ben Greear Dec. 18, 2024, 11:28 p.m. UTC
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 | 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 mbox series

Patch

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