mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:44:45 +01:00
wifi: ath12k: fix station lookup failure when disconnecting from AP
In ath12k_wmi_tlv_fw_stats_data_parse() and ath12k_wmi_tlv_rssi_chain_parse(), the driver uses ieee80211_find_sta_by_ifaddr() to look up the station associated with the incoming firmware statistics. This works under normal conditions but fails during AP disconnection, resulting in log messages like: wlan0: deauthenticating from xxxxxx by local choice (Reason: 3=DEAUTH_LEAVING) wlan0: moving STA xxxxxx to state 3 wlan0: moving STA xxxxxx to state 2 wlan0: moving STA xxxxxx to state 1 ath12k_pci 0000:02:00.0: not found station bssid xxxxxx for vdev stat ath12k_pci 0000:02:00.0: not found station of bssid xxxxxx for rssi chain ath12k_pci 0000:02:00.0: failed to pull fw stats: -71 ath12k_pci 0000:02:00.0: time out while waiting for get fw stats wlan0: Removed STA xxxxxx wlan0: Destroyed STA xxxxxx The failure happens because the station has already been removed from ieee80211_local::sta_hash by the time firmware statistics are requested through drv_sta_statistics(). Switch the lookup to ath12k_link_sta_find_by_addr(), which searches the driver's link station hash table that still has the station recorded at that time. This also implicitly fixes another issue: the current code always uses deflink regardless of which link the statistics belong to, which is incorrect in MLO scenarios. The new helper returns the correct link station. Additionally, raise the log level on lookup failures. With the updated helper, such failures should no longer occur under normal conditions. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Fixes:79e7b04b53("wifi: ath12k: report station mode signal strength") Fixes:6af5bc381b("wifi: ath12k: report station mode per-chain signal strength") Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com> Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com> Link: https://patch.msgid.link/20260129-ath12k-fw-stats-fixes-v1-2-55d66064f4d5@oss.qualcomm.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
parent
8f153eb745
commit
7259b1a0e5
1 changed files with 13 additions and 23 deletions
|
|
@ -8241,8 +8241,6 @@ static int ath12k_wmi_tlv_fw_stats_data_parse(struct ath12k_base *ab,
|
|||
struct ath12k_fw_stats *stats = parse->stats;
|
||||
struct ath12k *ar;
|
||||
struct ath12k_link_vif *arvif;
|
||||
struct ieee80211_sta *sta;
|
||||
struct ath12k_sta *ahsta;
|
||||
struct ath12k_link_sta *arsta;
|
||||
int i, ret = 0;
|
||||
const void *data = ptr;
|
||||
|
|
@ -8278,21 +8276,19 @@ static int ath12k_wmi_tlv_fw_stats_data_parse(struct ath12k_base *ab,
|
|||
|
||||
arvif = ath12k_mac_get_arvif(ar, le32_to_cpu(src->vdev_id));
|
||||
if (arvif) {
|
||||
sta = ieee80211_find_sta_by_ifaddr(ath12k_ar_to_hw(ar),
|
||||
arvif->bssid,
|
||||
NULL);
|
||||
if (sta) {
|
||||
ahsta = ath12k_sta_to_ahsta(sta);
|
||||
arsta = &ahsta->deflink;
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
arsta = ath12k_link_sta_find_by_addr(ab, arvif->bssid);
|
||||
if (arsta) {
|
||||
arsta->rssi_beacon = le32_to_cpu(src->beacon_snr);
|
||||
ath12k_dbg(ab, ATH12K_DBG_WMI,
|
||||
"wmi stats vdev id %d snr %d\n",
|
||||
src->vdev_id, src->beacon_snr);
|
||||
} else {
|
||||
ath12k_dbg(ab, ATH12K_DBG_WMI,
|
||||
"not found station bssid %pM for vdev stat\n",
|
||||
arvif->bssid);
|
||||
ath12k_warn(ab,
|
||||
"not found link sta with bssid %pM for vdev stat\n",
|
||||
arvif->bssid);
|
||||
}
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
}
|
||||
|
||||
data += sizeof(*src);
|
||||
|
|
@ -8363,8 +8359,6 @@ static int ath12k_wmi_tlv_rssi_chain_parse(struct ath12k_base *ab,
|
|||
struct ath12k_fw_stats *stats = parse->stats;
|
||||
struct ath12k_link_vif *arvif;
|
||||
struct ath12k_link_sta *arsta;
|
||||
struct ieee80211_sta *sta;
|
||||
struct ath12k_sta *ahsta;
|
||||
struct ath12k *ar;
|
||||
int vdev_id;
|
||||
int j;
|
||||
|
|
@ -8400,19 +8394,15 @@ static int ath12k_wmi_tlv_rssi_chain_parse(struct ath12k_base *ab,
|
|||
"stats bssid %pM vif %p\n",
|
||||
arvif->bssid, arvif->ahvif->vif);
|
||||
|
||||
sta = ieee80211_find_sta_by_ifaddr(ath12k_ar_to_hw(ar),
|
||||
arvif->bssid,
|
||||
NULL);
|
||||
if (!sta) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_WMI,
|
||||
"not found station of bssid %pM for rssi chain\n",
|
||||
arvif->bssid);
|
||||
guard(spinlock_bh)(&ab->base_lock);
|
||||
arsta = ath12k_link_sta_find_by_addr(ab, arvif->bssid);
|
||||
if (!arsta) {
|
||||
ath12k_warn(ab,
|
||||
"not found link sta with bssid %pM for rssi chain\n",
|
||||
arvif->bssid);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
ahsta = ath12k_sta_to_ahsta(sta);
|
||||
arsta = &ahsta->deflink;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) >
|
||||
ARRAY_SIZE(stats_rssi->rssi_avg_beacon));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue