aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath11k/wmi.c
diff options
context:
space:
mode:
authorWen Gong <[email protected]>2021-12-17 20:27:21 +0200
committerKalle Valo <[email protected]>2021-12-20 18:07:27 +0200
commitc3b39553fc7712a9621a19d9670d6f250943d50e (patch)
treea1acde7f065d92e6bbf83d247945d356a3742885 /drivers/net/wireless/ath/ath11k/wmi.c
parentb488c766442f7d9c07ea0708aa2a1a6bff1baef5 (diff)
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 <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
Diffstat (limited to 'drivers/net/wireless/ath/ath11k/wmi.c')
-rw-r--r--drivers/net/wireless/ath/ath11k/wmi.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index b7bdc37f24fd..6d92bb9483be 100644
--- 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_parse(struct ath11k_base *ab,
{
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_parse(struct ath11k_base *ab,
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_parse(struct ath11k_base *ab,
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_parse(struct ath11k_base *ab,
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_parse(struct ath11k_base *ab,
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,