mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-07-01 16:27:08 +08:00
171 lines
5.1 KiB
Diff
171 lines
5.1 KiB
Diff
From c3b39553fc7712a9621a19d9670d6f250943d50e Mon Sep 17 00:00:00 2001
|
|
From: Wen Gong <quic_wgong@quicinc.com>
|
|
Date: Fri, 17 Dec 2021 20:27:21 +0200
|
|
Subject: [PATCH] ath11k: add signal report to mac80211 for QCA6390 and WCN6855
|
|
|
|
IEEE80211_HW_USES_RSS is set in ath11k, then the device uses RSS and
|
|
thus requires parallel RX which implies using per-CPU station statistics
|
|
in sta_get_last_rx_stats() of mac80211. Currently signal is only set in
|
|
ath11k_mgmt_rx_event(), and not set for RX data packet, then it show
|
|
signal as 0 for iw command easily.
|
|
|
|
Change to get signal from firmware and report to mac80211.
|
|
|
|
For QCA6390 and WCN6855, the rssi value is already in dbm unit, so
|
|
don't need to convert it again.
|
|
|
|
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
|
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
|
|
|
Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
|
|
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
|
|
Link: https://lore.kernel.org/r/20211216070535.31732-1-quic_wgong@quicinc.com
|
|
---
|
|
drivers/net/wireless/ath/ath11k/core.h | 1 +
|
|
drivers/net/wireless/ath/ath11k/mac.c | 22 ++++++++++--
|
|
drivers/net/wireless/ath/ath11k/wmi.c | 49 +++++++++++++++++++++-----
|
|
3 files changed, 61 insertions(+), 11 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/core.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
|
@@ -387,6 +387,7 @@ struct ath11k_sta {
|
|
u64 rx_duration;
|
|
u64 tx_duration;
|
|
u8 rssi_comb;
|
|
+ s8 rssi_beacon;
|
|
s8 chain_signal[IEEE80211_MAX_CHAINS];
|
|
struct ath11k_htt_tx_stats *tx_stats;
|
|
struct ath11k_rx_peer_stats *rx_stats;
|
|
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
|
@@ -7811,6 +7811,9 @@ static void ath11k_mac_op_sta_statistics
|
|
{
|
|
struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
|
|
struct ath11k *ar = arsta->arvif->ar;
|
|
+ s8 signal;
|
|
+ bool db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,
|
|
+ ar->ab->wmi_ab.svc_map);
|
|
|
|
sinfo->rx_duration = arsta->rx_duration;
|
|
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION);
|
|
@@ -7843,9 +7846,22 @@ static void ath11k_mac_op_sta_statistics
|
|
ath11k_mac_put_chain_rssi(sinfo, arsta, "fw stats", true);
|
|
}
|
|
|
|
- /* TODO: Use real NF instead of default one. */
|
|
- sinfo->signal = arsta->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR;
|
|
- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
|
|
+ signal = arsta->rssi_comb;
|
|
+ if (!signal &&
|
|
+ arsta->arvif->vdev_type == WMI_VDEV_TYPE_STA &&
|
|
+ ar->ab->hw_params.supports_rssi_stats &&
|
|
+ !(ath11k_debugfs_get_fw_stats(ar, ar->pdev->pdev_id, 0,
|
|
+ WMI_REQUEST_VDEV_STAT)))
|
|
+ signal = arsta->rssi_beacon;
|
|
+
|
|
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
|
+ "mac sta statistics db2dbm %u rssi comb %d rssi beacon %d\n",
|
|
+ db2dbm, arsta->rssi_comb, arsta->rssi_beacon);
|
|
+
|
|
+ if (signal) {
|
|
+ sinfo->signal = db2dbm ? signal : signal + ATH11K_DEFAULT_NOISE_FLOOR;
|
|
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
|
|
+ }
|
|
}
|
|
|
|
static const struct ieee80211_ops ath11k_ops = {
|
|
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
|
@@ -5639,7 +5639,11 @@ static int ath11k_wmi_tlv_fw_stats_data_
|
|
{
|
|
struct ath11k_fw_stats *stats = parse->stats;
|
|
const struct wmi_stats_event *ev = parse->ev;
|
|
- int i;
|
|
+ struct ath11k *ar;
|
|
+ struct ath11k_vif *arvif;
|
|
+ struct ieee80211_sta *sta;
|
|
+ struct ath11k_sta *arsta;
|
|
+ int i, ret = 0;
|
|
const void *data = ptr;
|
|
|
|
if (!ev) {
|
|
@@ -5649,13 +5653,19 @@ static int ath11k_wmi_tlv_fw_stats_data_
|
|
|
|
stats->stats_id = 0;
|
|
|
|
+ rcu_read_lock();
|
|
+
|
|
+ ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id);
|
|
+
|
|
for (i = 0; i < ev->num_pdev_stats; i++) {
|
|
const struct wmi_pdev_stats *src;
|
|
struct ath11k_fw_stats_pdev *dst;
|
|
|
|
src = data;
|
|
- if (len < sizeof(*src))
|
|
- return -EPROTO;
|
|
+ if (len < sizeof(*src)) {
|
|
+ ret = -EPROTO;
|
|
+ goto exit;
|
|
+ }
|
|
|
|
stats->stats_id = WMI_REQUEST_PDEV_STAT;
|
|
|
|
@@ -5677,11 +5687,30 @@ static int ath11k_wmi_tlv_fw_stats_data_
|
|
struct ath11k_fw_stats_vdev *dst;
|
|
|
|
src = data;
|
|
- if (len < sizeof(*src))
|
|
- return -EPROTO;
|
|
+ if (len < sizeof(*src)) {
|
|
+ ret = -EPROTO;
|
|
+ goto exit;
|
|
+ }
|
|
|
|
stats->stats_id = WMI_REQUEST_VDEV_STAT;
|
|
|
|
+ arvif = ath11k_mac_get_arvif(ar, src->vdev_id);
|
|
+ if (arvif) {
|
|
+ sta = ieee80211_find_sta_by_ifaddr(ar->hw,
|
|
+ arvif->bssid,
|
|
+ NULL);
|
|
+ if (sta) {
|
|
+ arsta = (struct ath11k_sta *)sta->drv_priv;
|
|
+ arsta->rssi_beacon = src->beacon_snr;
|
|
+ ath11k_dbg(ab, ATH11K_DBG_WMI,
|
|
+ "wmi stats vdev id %d snr %d\n",
|
|
+ src->vdev_id, src->beacon_snr);
|
|
+ } else {
|
|
+ ath11k_warn(ab, "not found station for bssid %pM\n",
|
|
+ arvif->bssid);
|
|
+ }
|
|
+ }
|
|
+
|
|
data += sizeof(*src);
|
|
len -= sizeof(*src);
|
|
|
|
@@ -5698,8 +5727,10 @@ static int ath11k_wmi_tlv_fw_stats_data_
|
|
struct ath11k_fw_stats_bcn *dst;
|
|
|
|
src = data;
|
|
- if (len < sizeof(*src))
|
|
- return -EPROTO;
|
|
+ if (len < sizeof(*src)) {
|
|
+ ret = -EPROTO;
|
|
+ goto exit;
|
|
+ }
|
|
|
|
stats->stats_id = WMI_REQUEST_BCN_STAT;
|
|
|
|
@@ -5714,7 +5745,9 @@ static int ath11k_wmi_tlv_fw_stats_data_
|
|
list_add_tail(&dst->list, &stats->bcn);
|
|
}
|
|
|
|
- return 0;
|
|
+exit:
|
|
+ rcu_read_unlock();
|
|
+ return ret;
|
|
}
|
|
|
|
static int ath11k_wmi_tlv_fw_stats_parse(struct ath11k_base *ab,
|