Skip to content

Commit

Permalink
ath11k: add signal report to mac80211 for QCA6390 and WCN6855
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Wen Gong authored and Kalle Valo committed Dec 20, 2021
1 parent b488c76 commit c3b3955
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 11 deletions.
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath11k/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,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;
Expand Down
22 changes: 19 additions & 3 deletions drivers/net/wireless/ath/ath11k/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -7811,6 +7811,9 @@ static void ath11k_mac_op_sta_statistics(struct ieee80211_hw *hw,
{
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);
Expand Down Expand Up @@ -7843,9 +7846,22 @@ static void ath11k_mac_op_sta_statistics(struct ieee80211_hw *hw,
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 = {
Expand Down
49 changes: 41 additions & 8 deletions drivers/net/wireless/ath/ath11k/wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;

Expand All @@ -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);

Expand All @@ -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;

Expand All @@ -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,
Expand Down

0 comments on commit c3b3955

Please sign in to comment.