wifi: ath12k: fill link station statistics for MLO

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>
This commit is contained in:
Sarika Sharma 2025-07-01 16:29:23 +05:30 committed by Jeff Johnson
parent a82ce08775
commit ebebe66ec2

View 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,