]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: ath12k: fill link station statistics for MLO
authorSarika Sharma <quic_sarishar@quicinc.com>
Tue, 1 Jul 2025 10:59:23 +0000 (16:29 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Mon, 7 Jul 2025 22:34:48 +0000 (15:34 -0700)
Introduce ath12k_mac_op_link_sta_statistics(), to report link level
station statistics for MLO. The link_station_info structure is filled
from arsta and arsta is fetch from corresponding ahsta->link[link_id].

Therefore, this will be helpful to check the link related statistics.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1

Signed-off-by: Sarika Sharma <quic_sarishar@quicinc.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250701105927.803342-2-quic_sarishar@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/mac.c

index 6dd4441ce9a0b72018e4e79711deef59e2727a2f..8fcfb374fc868ba57bb494c371e6bfc4418b0ca4 100644 (file)
@@ -12444,6 +12444,83 @@ static void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw,
        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
 }
 
+static void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw,
+                                             struct ieee80211_vif *vif,
+                                             struct ieee80211_link_sta *link_sta,
+                                             struct link_station_info *link_sinfo)
+{
+       struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(link_sta->sta);
+       struct ath12k_fw_stats_req_params params = {};
+       struct ath12k_link_sta *arsta;
+       struct ath12k *ar;
+       s8 signal;
+       bool db2dbm;
+
+       lockdep_assert_wiphy(hw->wiphy);
+
+       arsta = wiphy_dereference(hw->wiphy, ahsta->link[link_sta->link_id]);
+
+       if (!arsta)
+               return;
+
+       ar = ath12k_get_ar_by_vif(hw, vif, arsta->link_id);
+       if (!ar)
+               return;
+
+       db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,
+                         ar->ab->wmi_ab.svc_map);
+
+       link_sinfo->rx_duration = arsta->rx_duration;
+       link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION);
+
+       link_sinfo->tx_duration = arsta->tx_duration;
+       link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION);
+
+       if (arsta->txrate.legacy || arsta->txrate.nss) {
+               if (arsta->txrate.legacy) {
+                       link_sinfo->txrate.legacy = arsta->txrate.legacy;
+               } else {
+                       link_sinfo->txrate.mcs = arsta->txrate.mcs;
+                       link_sinfo->txrate.nss = arsta->txrate.nss;
+                       link_sinfo->txrate.bw = arsta->txrate.bw;
+                       link_sinfo->txrate.he_gi = arsta->txrate.he_gi;
+                       link_sinfo->txrate.he_dcm = arsta->txrate.he_dcm;
+                       link_sinfo->txrate.he_ru_alloc =
+                               arsta->txrate.he_ru_alloc;
+                       link_sinfo->txrate.eht_gi = arsta->txrate.eht_gi;
+                       link_sinfo->txrate.eht_ru_alloc =
+                               arsta->txrate.eht_ru_alloc;
+               }
+               link_sinfo->txrate.flags = arsta->txrate.flags;
+               link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
+       }
+
+       /* TODO: Use real NF instead of default one. */
+       signal = arsta->rssi_comb;
+
+       params.pdev_id = ar->pdev->pdev_id;
+       params.vdev_id = 0;
+       params.stats_id = WMI_REQUEST_VDEV_STAT;
+
+       if (!signal &&
+           ahsta->ahvif->vdev_type == WMI_VDEV_TYPE_STA &&
+           !(ath12k_mac_get_fw_stats(ar, &params)))
+               signal = arsta->rssi_beacon;
+
+       if (signal) {
+               link_sinfo->signal =
+                       db2dbm ? signal : signal + ATH12K_DEFAULT_NOISE_FLOOR;
+               link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
+       }
+
+       link_sinfo->signal_avg = ewma_avg_rssi_read(&arsta->avg_rssi);
+
+       if (!db2dbm)
+               link_sinfo->signal_avg += ATH12K_DEFAULT_NOISE_FLOOR;
+
+       link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
+}
+
 static int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw,
                                                  struct ieee80211_vif *vif)
 {
@@ -12679,6 +12756,7 @@ static const struct ieee80211_ops ath12k_ops = {
        .get_survey                     = ath12k_mac_op_get_survey,
        .flush                          = ath12k_mac_op_flush,
        .sta_statistics                 = ath12k_mac_op_sta_statistics,
+       .link_sta_statistics            = ath12k_mac_op_link_sta_statistics,
        .remain_on_channel              = ath12k_mac_op_remain_on_channel,
        .cancel_remain_on_channel       = ath12k_mac_op_cancel_remain_on_channel,
        .change_sta_links               = ath12k_mac_op_change_sta_links,