]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: iwlwifi: mld: expose beacon avg signal
authorShahar Tzarfati <shahar.tzarfati@intel.com>
Fri, 15 May 2026 12:09:47 +0000 (15:09 +0300)
committerMiri Korenblit <miriam.rachel.korenblit@intel.com>
Tue, 26 May 2026 12:17:12 +0000 (15:17 +0300)
Store beacon_average_energy from per-link FW statistics and expose it
via station_info as rx_beacon_signal_avg in sta statistics.

This fixes missing beacon average signal reporting to upper layers.

Signed-off-by: Shahar Tzarfati <shahar.tzarfati@intel.com>
Link: https://patch.msgid.link/20260515150751.a74a22d90890.I74d596359c5b69364fb977fdf31396eb57ca0927@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
drivers/net/wireless/intel/iwlwifi/mld/link.h
drivers/net/wireless/intel/iwlwifi/mld/stats.c

index 4527f054ce921da44531b6fb55a85bd0b72f93d3..0b3974d86531aef80d4a13de39dd6c2a1bb9e9d8 100644 (file)
@@ -36,6 +36,8 @@ struct iwl_probe_resp_data {
  * @rcu_head: RCU head for freeing this data.
  * @fw_id: the fw id of the link.
  * @active: if the link is active or not.
+ * @avg_signal: The current average signal of beacons [dBm] retrieved from
+ *     firmware per-link periodic stats (STATISTICS_OPER_NOTIF).
  * @queue_params: QoS data from mac80211. This is updated with a call to
  *     drv_conf_tx per each AC, and then notified once with BSS_CHANGED_QOS.
  *     So we store it here and then send one link cmd for all the ACs.
@@ -68,6 +70,7 @@ struct iwl_mld_link {
        struct_group(zeroed_on_hw_restart,
                u8 fw_id;
                bool active;
+               s8 avg_signal;
                struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
                struct ieee80211_chanctx_conf __rcu *chan_ctx;
                bool he_ru_2mhz_block;
index b93e0f8ab5fbcd0573d5213a91cae48f1f70d8a0..e7b283cbe19913752df573bfbb08e88644b06787 100644 (file)
@@ -311,6 +311,40 @@ static void iwl_mld_sta_stats_fill_txrate(struct iwl_mld_sta *mld_sta,
        }
 }
 
+static void iwl_mld_sta_stats_fill_beacon_signal_avg(struct ieee80211_vif *vif,
+                                                    struct station_info *sinfo)
+{
+       struct ieee80211_bss_conf *link_conf;
+       struct iwl_mld_link *link;
+       u8 link_id;
+
+       if (iwl_mld_emlsr_active(vif))
+               return;
+
+       /* TODO: support statistics for NAN */
+       if (vif->type == NL80211_IFTYPE_NAN ||
+           vif->type == NL80211_IFTYPE_NAN_DATA)
+               return;
+
+       link_id = iwl_mld_get_primary_link(vif);
+       link_conf = link_conf_dereference_protected(vif, link_id);
+
+       if (WARN_ONCE(!link_conf,
+                     "link_conf is NULL for link_id=%u\n", link_id))
+               return;
+
+       link = iwl_mld_link_from_mac80211(link_conf);
+       if (WARN_ONCE(!link,
+                     "iwl_mld_link is NULL for link_id=%u\n", link_id))
+               return;
+
+       if (!link->avg_signal)
+               return;
+
+       sinfo->rx_beacon_signal_avg = link->avg_signal;
+       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG);
+}
+
 void iwl_mld_mac80211_sta_statistics(struct ieee80211_hw *hw,
                                     struct ieee80211_vif *vif,
                                     struct ieee80211_sta *sta,
@@ -329,9 +363,9 @@ void iwl_mld_mac80211_sta_statistics(struct ieee80211_hw *hw,
 
        iwl_mld_sta_stats_fill_txrate(mld_sta, sinfo);
 
-       /* TODO: NL80211_STA_INFO_BEACON_RX */
+       iwl_mld_sta_stats_fill_beacon_signal_avg(vif, sinfo);
 
-       /* TODO: NL80211_STA_INFO_BEACON_SIGNAL_AVG */
+       /* TODO: NL80211_STA_INFO_BEACON_RX */
 }
 
 #define IWL_MLD_TRAFFIC_LOAD_MEDIUM_THRESH     10 /* percentage */
@@ -443,6 +477,8 @@ iwl_mld_process_per_link_stats(struct iwl_mld *mld,
             fw_id++) {
                const struct iwl_stats_ntfy_per_link *link_stats;
                struct ieee80211_bss_conf *bss_conf;
+               struct iwl_mld_link *link;
+               u32 avg_raw;
                int sig;
 
                bss_conf = iwl_mld_fw_id_to_link_conf(mld, fw_id);
@@ -456,6 +492,13 @@ iwl_mld_process_per_link_stats(struct iwl_mld *mld,
                sig = -le32_to_cpu(link_stats->beacon_filter_average_energy);
                iwl_mld_update_link_sig(bss_conf->vif, sig, bss_conf);
 
+               link = iwl_mld_link_from_mac80211(bss_conf);
+               if (WARN_ON_ONCE(!link))
+                       continue;
+
+               avg_raw = le32_to_cpu(link_stats->beacon_average_energy);
+               link->avg_signal = clamp_t(int, -(int)avg_raw, S8_MIN, 0);
+
                /* TODO: parse more fields here (task=statistics)*/
        }