Skip to content

Commit 72610ed

Browse files
Baochen Qiangjeff-t-johnson
authored andcommitted
wifi: ath11k: move some firmware stats related functions outside of debugfs
Commit b488c76 ("ath11k: report rssi of each chain to mac80211 for QCA6390/WCN6855") and commit c3b3955 ("ath11k: add signal report to mac80211 for QCA6390 and WCN6855") call debugfs functions in mac ops. Those functions are no-ops if CONFIG_ATH11K_DEBUGFS is not enabled, thus cause wrong status reported. Move them to mac.c. Besides, since WMI_REQUEST_RSSI_PER_CHAIN_STAT and WMI_REQUEST_VDEV_STAT stats could also be requested via mac ops, process them directly in ath11k_update_stats_event(). Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.37 Fixes: b488c76 ("ath11k: report rssi of each chain to mac80211 for QCA6390/WCN6855") Fixes: c3b3955 ("ath11k: add signal report to mac80211 for QCA6390 and WCN6855") Signed-off-by: Baochen Qiang <[email protected]> Reviewed-by: Vasanthakumar Thiagarajan <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jeff Johnson <[email protected]>
1 parent 3b6d00f commit 72610ed

File tree

5 files changed

+135
-138
lines changed

5 files changed

+135
-138
lines changed

drivers/net/wireless/ath/ath11k/debugfs.c

Lines changed: 6 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -93,58 +93,14 @@ void ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
9393
spin_unlock_bh(&dbr_data->lock);
9494
}
9595

96-
static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar)
97-
{
98-
spin_lock_bh(&ar->data_lock);
99-
ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
100-
ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
101-
ar->fw_stats.num_vdev_recvd = 0;
102-
ar->fw_stats.num_bcn_recvd = 0;
103-
spin_unlock_bh(&ar->data_lock);
104-
}
105-
10696
void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats)
10797
{
10898
struct ath11k_base *ab = ar->ab;
109-
struct ath11k_pdev *pdev;
11099
bool is_end = true;
111-
size_t total_vdevs_started = 0;
112-
int i;
113-
114-
/* WMI_REQUEST_PDEV_STAT request has been already processed */
115-
116-
if (stats->stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
117-
complete(&ar->fw_stats_done);
118-
return;
119-
}
120-
121-
if (stats->stats_id == WMI_REQUEST_VDEV_STAT) {
122-
if (list_empty(&stats->vdevs)) {
123-
ath11k_warn(ab, "empty vdev stats");
124-
return;
125-
}
126-
/* FW sends all the active VDEV stats irrespective of PDEV,
127-
* hence limit until the count of all VDEVs started
128-
*/
129-
for (i = 0; i < ab->num_radios; i++) {
130-
pdev = rcu_dereference(ab->pdevs_active[i]);
131-
if (pdev && pdev->ar)
132-
total_vdevs_started += ar->num_started_vdevs;
133-
}
134-
135-
if (total_vdevs_started)
136-
is_end = ((++ar->fw_stats.num_vdev_recvd) ==
137-
total_vdevs_started);
138-
139-
list_splice_tail_init(&stats->vdevs,
140-
&ar->fw_stats.vdevs);
141-
142-
if (is_end)
143-
complete(&ar->fw_stats_done);
144-
145-
return;
146-
}
147100

101+
/* WMI_REQUEST_PDEV_STAT, WMI_REQUEST_RSSI_PER_CHAIN_STAT and
102+
* WMI_REQUEST_VDEV_STAT requests have been already processed.
103+
*/
148104
if (stats->stats_id == WMI_REQUEST_BCN_STAT) {
149105
if (list_empty(&stats->bcn)) {
150106
ath11k_warn(ab, "empty bcn stats");
@@ -165,76 +121,6 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *
165121
}
166122
}
167123

168-
static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
169-
struct stats_request_params *req_param)
170-
{
171-
struct ath11k_base *ab = ar->ab;
172-
unsigned long time_left;
173-
int ret;
174-
175-
lockdep_assert_held(&ar->conf_mutex);
176-
177-
ath11k_debugfs_fw_stats_reset(ar);
178-
179-
reinit_completion(&ar->fw_stats_complete);
180-
reinit_completion(&ar->fw_stats_done);
181-
182-
ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
183-
184-
if (ret) {
185-
ath11k_warn(ab, "could not request fw stats (%d)\n",
186-
ret);
187-
return ret;
188-
}
189-
190-
time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
191-
if (!time_left)
192-
return -ETIMEDOUT;
193-
194-
/* FW stats can get split when exceeding the stats data buffer limit.
195-
* In that case, since there is no end marking for the back-to-back
196-
* received 'update stats' event, we keep a 3 seconds timeout in case,
197-
* fw_stats_done is not marked yet
198-
*/
199-
time_left = wait_for_completion_timeout(&ar->fw_stats_done, 3 * HZ);
200-
if (!time_left)
201-
return -ETIMEDOUT;
202-
203-
return 0;
204-
}
205-
206-
int ath11k_debugfs_get_fw_stats(struct ath11k *ar, u32 pdev_id,
207-
u32 vdev_id, u32 stats_id)
208-
{
209-
struct ath11k_base *ab = ar->ab;
210-
struct stats_request_params req_param;
211-
int ret;
212-
213-
mutex_lock(&ar->conf_mutex);
214-
215-
if (ar->state != ATH11K_STATE_ON) {
216-
ret = -ENETDOWN;
217-
goto err_unlock;
218-
}
219-
220-
req_param.pdev_id = pdev_id;
221-
req_param.vdev_id = vdev_id;
222-
req_param.stats_id = stats_id;
223-
224-
ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
225-
if (ret)
226-
ath11k_warn(ab, "failed to request fw stats: %d\n", ret);
227-
228-
ath11k_dbg(ab, ATH11K_DBG_WMI,
229-
"debug get fw stat pdev id %d vdev id %d stats id 0x%x\n",
230-
pdev_id, vdev_id, stats_id);
231-
232-
err_unlock:
233-
mutex_unlock(&ar->conf_mutex);
234-
235-
return ret;
236-
}
237-
238124
static int ath11k_open_pdev_stats(struct inode *inode, struct file *file)
239125
{
240126
struct ath11k *ar = inode->i_private;
@@ -260,7 +146,7 @@ static int ath11k_open_pdev_stats(struct inode *inode, struct file *file)
260146
req_param.vdev_id = 0;
261147
req_param.stats_id = WMI_REQUEST_PDEV_STAT;
262148

263-
ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
149+
ret = ath11k_mac_fw_stats_request(ar, &req_param);
264150
if (ret) {
265151
ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
266152
goto err_free;
@@ -331,7 +217,7 @@ static int ath11k_open_vdev_stats(struct inode *inode, struct file *file)
331217
req_param.vdev_id = 0;
332218
req_param.stats_id = WMI_REQUEST_VDEV_STAT;
333219

334-
ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
220+
ret = ath11k_mac_fw_stats_request(ar, &req_param);
335221
if (ret) {
336222
ath11k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
337223
goto err_free;
@@ -407,7 +293,7 @@ static int ath11k_open_bcn_stats(struct inode *inode, struct file *file)
407293
continue;
408294

409295
req_param.vdev_id = arvif->vdev_id;
410-
ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
296+
ret = ath11k_mac_fw_stats_request(ar, &req_param);
411297
if (ret) {
412298
ath11k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
413299
goto err_free;

drivers/net/wireless/ath/ath11k/debugfs.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
22
/*
33
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4-
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
4+
* Copyright (c) 2021-2022, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
55
*/
66

77
#ifndef _ATH11K_DEBUGFS_H_
@@ -273,8 +273,6 @@ void ath11k_debugfs_unregister(struct ath11k *ar);
273273
void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats);
274274

275275
void ath11k_debugfs_fw_stats_init(struct ath11k *ar);
276-
int ath11k_debugfs_get_fw_stats(struct ath11k *ar, u32 pdev_id,
277-
u32 vdev_id, u32 stats_id);
278276

279277
static inline bool ath11k_debugfs_is_pktlog_lite_mode_enabled(struct ath11k *ar)
280278
{
@@ -381,12 +379,6 @@ static inline int ath11k_debugfs_rx_filter(struct ath11k *ar)
381379
return 0;
382380
}
383381

384-
static inline int ath11k_debugfs_get_fw_stats(struct ath11k *ar,
385-
u32 pdev_id, u32 vdev_id, u32 stats_id)
386-
{
387-
return 0;
388-
}
389-
390382
static inline void
391383
ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
392384
enum wmi_direct_buffer_module id,

drivers/net/wireless/ath/ath11k/mac.c

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8997,6 +8997,86 @@ static void ath11k_mac_put_chain_rssi(struct station_info *sinfo,
89978997
}
89988998
}
89998999

9000+
static void ath11k_mac_fw_stats_reset(struct ath11k *ar)
9001+
{
9002+
spin_lock_bh(&ar->data_lock);
9003+
ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
9004+
ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
9005+
ar->fw_stats.num_vdev_recvd = 0;
9006+
ar->fw_stats.num_bcn_recvd = 0;
9007+
spin_unlock_bh(&ar->data_lock);
9008+
}
9009+
9010+
int ath11k_mac_fw_stats_request(struct ath11k *ar,
9011+
struct stats_request_params *req_param)
9012+
{
9013+
struct ath11k_base *ab = ar->ab;
9014+
unsigned long time_left;
9015+
int ret;
9016+
9017+
lockdep_assert_held(&ar->conf_mutex);
9018+
9019+
ath11k_mac_fw_stats_reset(ar);
9020+
9021+
reinit_completion(&ar->fw_stats_complete);
9022+
reinit_completion(&ar->fw_stats_done);
9023+
9024+
ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
9025+
9026+
if (ret) {
9027+
ath11k_warn(ab, "could not request fw stats (%d)\n",
9028+
ret);
9029+
return ret;
9030+
}
9031+
9032+
time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
9033+
if (!time_left)
9034+
return -ETIMEDOUT;
9035+
9036+
/* FW stats can get split when exceeding the stats data buffer limit.
9037+
* In that case, since there is no end marking for the back-to-back
9038+
* received 'update stats' event, we keep a 3 seconds timeout in case,
9039+
* fw_stats_done is not marked yet
9040+
*/
9041+
time_left = wait_for_completion_timeout(&ar->fw_stats_done, 3 * HZ);
9042+
if (!time_left)
9043+
return -ETIMEDOUT;
9044+
9045+
return 0;
9046+
}
9047+
9048+
static int ath11k_mac_get_fw_stats(struct ath11k *ar, u32 pdev_id,
9049+
u32 vdev_id, u32 stats_id)
9050+
{
9051+
struct ath11k_base *ab = ar->ab;
9052+
struct stats_request_params req_param;
9053+
int ret;
9054+
9055+
mutex_lock(&ar->conf_mutex);
9056+
9057+
if (ar->state != ATH11K_STATE_ON) {
9058+
ret = -ENETDOWN;
9059+
goto err_unlock;
9060+
}
9061+
9062+
req_param.pdev_id = pdev_id;
9063+
req_param.vdev_id = vdev_id;
9064+
req_param.stats_id = stats_id;
9065+
9066+
ret = ath11k_mac_fw_stats_request(ar, &req_param);
9067+
if (ret)
9068+
ath11k_warn(ab, "failed to request fw stats: %d\n", ret);
9069+
9070+
ath11k_dbg(ab, ATH11K_DBG_WMI,
9071+
"debug get fw stat pdev id %d vdev id %d stats id 0x%x\n",
9072+
pdev_id, vdev_id, stats_id);
9073+
9074+
err_unlock:
9075+
mutex_unlock(&ar->conf_mutex);
9076+
9077+
return ret;
9078+
}
9079+
90009080
static void ath11k_mac_op_sta_statistics(struct ieee80211_hw *hw,
90019081
struct ieee80211_vif *vif,
90029082
struct ieee80211_sta *sta,
@@ -9034,17 +9114,17 @@ static void ath11k_mac_op_sta_statistics(struct ieee80211_hw *hw,
90349114
if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) &&
90359115
arsta->arvif->vdev_type == WMI_VDEV_TYPE_STA &&
90369116
ar->ab->hw_params.supports_rssi_stats &&
9037-
!ath11k_debugfs_get_fw_stats(ar, ar->pdev->pdev_id, 0,
9038-
WMI_REQUEST_RSSI_PER_CHAIN_STAT)) {
9117+
!ath11k_mac_get_fw_stats(ar, ar->pdev->pdev_id, 0,
9118+
WMI_REQUEST_RSSI_PER_CHAIN_STAT)) {
90399119
ath11k_mac_put_chain_rssi(sinfo, arsta, "fw stats", true);
90409120
}
90419121

90429122
signal = arsta->rssi_comb;
90439123
if (!signal &&
90449124
arsta->arvif->vdev_type == WMI_VDEV_TYPE_STA &&
90459125
ar->ab->hw_params.supports_rssi_stats &&
9046-
!(ath11k_debugfs_get_fw_stats(ar, ar->pdev->pdev_id, 0,
9047-
WMI_REQUEST_VDEV_STAT)))
9126+
!(ath11k_mac_get_fw_stats(ar, ar->pdev->pdev_id, 0,
9127+
WMI_REQUEST_VDEV_STAT)))
90489128
signal = arsta->rssi_beacon;
90499129

90509130
ath11k_dbg(ar->ab, ATH11K_DBG_MAC,

drivers/net/wireless/ath/ath11k/mac.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
22
/*
33
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4-
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4+
* Copyright (c) 2021-2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
55
*/
66

77
#ifndef ATH11K_MAC_H
@@ -179,4 +179,6 @@ int ath11k_mac_vif_set_keepalive(struct ath11k_vif *arvif,
179179
void ath11k_mac_fill_reg_tpc_info(struct ath11k *ar,
180180
struct ieee80211_vif *vif,
181181
struct ieee80211_chanctx_conf *ctx);
182+
int ath11k_mac_fw_stats_request(struct ath11k *ar,
183+
struct stats_request_params *req_param);
182184
#endif

drivers/net/wireless/ath/ath11k/wmi.c

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8158,6 +8158,11 @@ static void ath11k_peer_assoc_conf_event(struct ath11k_base *ab, struct sk_buff
81588158
static void ath11k_update_stats_event(struct ath11k_base *ab, struct sk_buff *skb)
81598159
{
81608160
struct ath11k_fw_stats stats = {};
8161+
size_t total_vdevs_started = 0;
8162+
struct ath11k_pdev *pdev;
8163+
bool is_end = true;
8164+
int i;
8165+
81618166
struct ath11k *ar;
81628167
int ret;
81638168

@@ -8184,7 +8189,8 @@ static void ath11k_update_stats_event(struct ath11k_base *ab, struct sk_buff *sk
81848189

81858190
spin_lock_bh(&ar->data_lock);
81868191

8187-
/* WMI_REQUEST_PDEV_STAT can be requested via .get_txpower mac ops or via
8192+
/* WMI_REQUEST_PDEV_STAT, WMI_REQUEST_VDEV_STAT and
8193+
* WMI_REQUEST_RSSI_PER_CHAIN_STAT can be requested via mac ops or via
81888194
* debugfs fw stats. Therefore, processing it separately.
81898195
*/
81908196
if (stats.stats_id == WMI_REQUEST_PDEV_STAT) {
@@ -8193,9 +8199,40 @@ static void ath11k_update_stats_event(struct ath11k_base *ab, struct sk_buff *sk
81938199
goto complete;
81948200
}
81958201

8196-
/* WMI_REQUEST_VDEV_STAT, WMI_REQUEST_BCN_STAT and WMI_REQUEST_RSSI_PER_CHAIN_STAT
8197-
* are currently requested only via debugfs fw stats. Hence, processing these
8198-
* in debugfs context
8202+
if (stats.stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
8203+
complete(&ar->fw_stats_done);
8204+
goto complete;
8205+
}
8206+
8207+
if (stats.stats_id == WMI_REQUEST_VDEV_STAT) {
8208+
if (list_empty(&stats.vdevs)) {
8209+
ath11k_warn(ab, "empty vdev stats");
8210+
goto complete;
8211+
}
8212+
/* FW sends all the active VDEV stats irrespective of PDEV,
8213+
* hence limit until the count of all VDEVs started
8214+
*/
8215+
for (i = 0; i < ab->num_radios; i++) {
8216+
pdev = rcu_dereference(ab->pdevs_active[i]);
8217+
if (pdev && pdev->ar)
8218+
total_vdevs_started += ar->num_started_vdevs;
8219+
}
8220+
8221+
if (total_vdevs_started)
8222+
is_end = ((++ar->fw_stats.num_vdev_recvd) ==
8223+
total_vdevs_started);
8224+
8225+
list_splice_tail_init(&stats.vdevs,
8226+
&ar->fw_stats.vdevs);
8227+
8228+
if (is_end)
8229+
complete(&ar->fw_stats_done);
8230+
8231+
goto complete;
8232+
}
8233+
8234+
/* WMI_REQUEST_BCN_STAT is currently requested only via debugfs fw stats.
8235+
* Hence, processing it in debugfs context
81998236
*/
82008237
ath11k_debugfs_fw_stats_process(ar, &stats);
82018238

0 commit comments

Comments
 (0)