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