Skip to content

Commit d5705af

Browse files
committed
Johannes Berg says: ==================== Another quick round of updates: - revert mwifiex HT40 that was causing issues - many ath10k/ath11k/ath12k fixes - re-add some iwlwifi code I lost in a merge - use kfree_sensitive() on an error path in cfg80211 * tag 'wireless-2025-06-12' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless: wifi: cfg80211: use kfree_sensitive() for connkeys cleanup wifi: iwlwifi: fix merge damage related to iwl_pci_resume Revert "wifi: mwifiex: Fix HT40 bandwidth issue." wifi: ath12k: fix uaf in ath12k_core_init() wifi: ath12k: Fix hal_reo_cmd_status kernel-doc wifi: ath12k: fix GCC_GCC_PCIE_HOT_RST definition for WCN7850 wifi: ath11k: validate ath11k_crypto_mode on top of ath11k_core_qmi_firmware_ready wifi: ath11k: consistently use ath11k_mac_get_fw_stats() wifi: ath11k: move locking outside of ath11k_mac_get_fw_stats() wifi: ath11k: adjust unlock sequence in ath11k_update_stats_event() wifi: ath11k: move some firmware stats related functions outside of debugfs wifi: ath11k: don't wait when there is no vdev started wifi: ath11k: don't use static variables in ath11k_debugfs_fw_stats_process() wifi: ath11k: avoid burning CPU in ath11k_debugfs_fw_stats_request() wil6210: fix support for sparrow chipsets wifi: ath10k: Avoid vdev delete timeout when firmware is already down ath10k: snoc: fix unbalanced IRQ enable in crash recovery ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 613fd52 + f875865 commit d5705af

File tree

19 files changed

+251
-246
lines changed

19 files changed

+251
-246
lines changed

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

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
55
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
66
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
7+
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
78
*/
89

910
#include "mac.h"
@@ -1022,6 +1023,26 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
10221023
return ar->last_wmi_vdev_start_status;
10231024
}
10241025

1026+
static inline int ath10k_vdev_delete_sync(struct ath10k *ar)
1027+
{
1028+
unsigned long time_left;
1029+
1030+
lockdep_assert_held(&ar->conf_mutex);
1031+
1032+
if (!test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map))
1033+
return 0;
1034+
1035+
if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
1036+
return -ESHUTDOWN;
1037+
1038+
time_left = wait_for_completion_timeout(&ar->vdev_delete_done,
1039+
ATH10K_VDEV_DELETE_TIMEOUT_HZ);
1040+
if (time_left == 0)
1041+
return -ETIMEDOUT;
1042+
1043+
return 0;
1044+
}
1045+
10251046
static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
10261047
{
10271048
struct cfg80211_chan_def *chandef = NULL;
@@ -5900,7 +5921,6 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
59005921
struct ath10k *ar = hw->priv;
59015922
struct ath10k_vif *arvif = (void *)vif->drv_priv;
59025923
struct ath10k_peer *peer;
5903-
unsigned long time_left;
59045924
int ret;
59055925
int i;
59065926

@@ -5940,13 +5960,10 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
59405960
ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
59415961
arvif->vdev_id, ret);
59425962

5943-
if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) {
5944-
time_left = wait_for_completion_timeout(&ar->vdev_delete_done,
5945-
ATH10K_VDEV_DELETE_TIMEOUT_HZ);
5946-
if (time_left == 0) {
5947-
ath10k_warn(ar, "Timeout in receiving vdev delete response\n");
5948-
goto out;
5949-
}
5963+
ret = ath10k_vdev_delete_sync(ar);
5964+
if (ret) {
5965+
ath10k_warn(ar, "Error in receiving vdev delete response: %d\n", ret);
5966+
goto out;
59505967
}
59515968

59525969
/* Some firmware revisions don't notify host about self-peer removal

drivers/net/wireless/ath/ath10k/snoc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,9 @@ static int ath10k_snoc_hif_start(struct ath10k *ar)
937937

938938
dev_set_threaded(ar->napi_dev, true);
939939
ath10k_core_napi_enable(ar);
940-
ath10k_snoc_irq_enable(ar);
940+
/* IRQs are left enabled when we restart due to a firmware crash */
941+
if (!test_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags))
942+
ath10k_snoc_irq_enable(ar);
941943
ath10k_snoc_rx_post(ar);
942944

943945
clear_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags);

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

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,7 @@ void ath11k_fw_stats_init(struct ath11k *ar)
990990
INIT_LIST_HEAD(&ar->fw_stats.bcn);
991991

992992
init_completion(&ar->fw_stats_complete);
993+
init_completion(&ar->fw_stats_done);
993994
}
994995

995996
void ath11k_fw_stats_free(struct ath11k_fw_stats *stats)
@@ -2134,6 +2135,20 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
21342135
{
21352136
int ret;
21362137

2138+
switch (ath11k_crypto_mode) {
2139+
case ATH11K_CRYPT_MODE_SW:
2140+
set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
2141+
set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
2142+
break;
2143+
case ATH11K_CRYPT_MODE_HW:
2144+
clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
2145+
clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
2146+
break;
2147+
default:
2148+
ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
2149+
return -EINVAL;
2150+
}
2151+
21372152
ret = ath11k_core_start_firmware(ab, ab->fw_mode);
21382153
if (ret) {
21392154
ath11k_err(ab, "failed to start firmware: %d\n", ret);
@@ -2152,20 +2167,6 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
21522167
goto err_firmware_stop;
21532168
}
21542169

2155-
switch (ath11k_crypto_mode) {
2156-
case ATH11K_CRYPT_MODE_SW:
2157-
set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
2158-
set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
2159-
break;
2160-
case ATH11K_CRYPT_MODE_HW:
2161-
clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
2162-
clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
2163-
break;
2164-
default:
2165-
ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
2166-
return -EINVAL;
2167-
}
2168-
21692170
if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW)
21702171
set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
21712172

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,8 @@ struct ath11k_fw_stats {
600600
struct list_head pdevs;
601601
struct list_head vdevs;
602602
struct list_head bcn;
603+
u32 num_vdev_recvd;
604+
u32 num_bcn_recvd;
603605
};
604606

605607
struct ath11k_dbg_htt_stats {
@@ -784,7 +786,7 @@ struct ath11k {
784786
u8 alpha2[REG_ALPHA2_LEN + 1];
785787
struct ath11k_fw_stats fw_stats;
786788
struct completion fw_stats_complete;
787-
bool fw_stats_done;
789+
struct completion fw_stats_done;
788790

789791
/* protected by conf_mutex */
790792
bool ps_state_enable;

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

Lines changed: 13 additions & 135 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-2020 The Linux Foundation. All rights reserved.
4-
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4+
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
55
*/
66

77
#include <linux/vmalloc.h>
@@ -93,57 +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-
ar->fw_stats_done = false;
100-
ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
101-
ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
102-
spin_unlock_bh(&ar->data_lock);
103-
}
104-
10596
void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats)
10697
{
10798
struct ath11k_base *ab = ar->ab;
108-
struct ath11k_pdev *pdev;
109-
bool is_end;
110-
static unsigned int num_vdev, num_bcn;
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-
ar->fw_stats_done = true;
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-
is_end = ((++num_vdev) == total_vdevs_started);
136-
137-
list_splice_tail_init(&stats->vdevs,
138-
&ar->fw_stats.vdevs);
139-
140-
if (is_end) {
141-
ar->fw_stats_done = true;
142-
num_vdev = 0;
143-
}
144-
return;
145-
}
99+
bool is_end = true;
146100

101+
/* WMI_REQUEST_PDEV_STAT, WMI_REQUEST_RSSI_PER_CHAIN_STAT and
102+
* WMI_REQUEST_VDEV_STAT requests have been already processed.
103+
*/
147104
if (stats->stats_id == WMI_REQUEST_BCN_STAT) {
148105
if (list_empty(&stats->bcn)) {
149106
ath11k_warn(ab, "empty bcn stats");
@@ -152,97 +109,18 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *
152109
/* Mark end until we reached the count of all started VDEVs
153110
* within the PDEV
154111
*/
155-
is_end = ((++num_bcn) == ar->num_started_vdevs);
112+
if (ar->num_started_vdevs)
113+
is_end = ((++ar->fw_stats.num_bcn_recvd) ==
114+
ar->num_started_vdevs);
156115

157116
list_splice_tail_init(&stats->bcn,
158117
&ar->fw_stats.bcn);
159118

160-
if (is_end) {
161-
ar->fw_stats_done = true;
162-
num_bcn = 0;
163-
}
119+
if (is_end)
120+
complete(&ar->fw_stats_done);
164121
}
165122
}
166123

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

271-
ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
149+
ret = ath11k_mac_fw_stats_request(ar, &req_param);
272150
if (ret) {
273151
ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
274152
goto err_free;
@@ -339,7 +217,7 @@ static int ath11k_open_vdev_stats(struct inode *inode, struct file *file)
339217
req_param.vdev_id = 0;
340218
req_param.stats_id = WMI_REQUEST_VDEV_STAT;
341219

342-
ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
220+
ret = ath11k_mac_fw_stats_request(ar, &req_param);
343221
if (ret) {
344222
ath11k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
345223
goto err_free;
@@ -415,7 +293,7 @@ static int ath11k_open_bcn_stats(struct inode *inode, struct file *file)
415293
continue;
416294

417295
req_param.vdev_id = arvif->vdev_id;
418-
ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
296+
ret = ath11k_mac_fw_stats_request(ar, &req_param);
419297
if (ret) {
420298
ath11k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
421299
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,

0 commit comments

Comments
 (0)