From: David Heidelberg <[email protected]>
When removing a pairwise key, ath10k_send_key() sends a
WMI_VDEV_INSTALL_KEY with WMI_CIPHER_NONE and no key data. On WCN3990
the firmware never answers that with an HTT security indication, so
ath10k_install_key() always sleeps for the full 3 s and then fails:
[ 117.285854] wlan0: deauthenticating from XX:XX:XX:XX:XX:XX by local
choice (Reason: 3=DEAUTH_LEAVING)
[ 120.302934] ath10k_snoc 18800000.wifi: failed to install key for vdev 0
peer XX:XX:XX:XX:XX:XX: -110
[ 120.302996] wlan0: failed to remove key (0, XX:XX:XX:XX:XX:XX) from
hardware (-110)
The indication is missing, not late. Tracing mac80211:drv_set_key and
the ath10k "sec ind" debug message on WCN3990 with firmware
WLAN.HL.2.0.c8-00050-QCAHLSWMTPLZ-1.435283.1.441421.1 across a
disconnect/reconnect shows no indication at all for the pairwise
removal, while both installs on reconnect are acknowledged within 2 ms:
866.899253: drv_set_key: sta:AP cmd: 1 flags=0x9, keyidx=0
866.899270: ath10k_log_dbg: wmi tlv vdev install key
869.920623: ath10k_log_warn: failed to install key ... peer AP: -110
880.701296: drv_set_key: sta:AP cmd: 0 flags=0x8, keyidx=0
880.701318: ath10k_log_dbg: wmi tlv vdev install key
880.701584: ath10k_log_dbg: sec ind peer_id 86 unicast 1 type 6
880.716075: drv_set_key: sta:GROUP cmd: 0 flags=0x0, keyidx=2
880.716088: ath10k_log_dbg: wmi tlv vdev install key
880.718250: ath10k_log_dbg: sec ind peer_id 86 unicast 0 type 6
Shortening the timeout would still stall every disconnect and still log
a failure for a key the firmware has already dropped. Add a
no_pairwise_key_del_ind hw_params flag, set it for WCN3990 only, and
skip the wait for pairwise removal when it is set. Other firmware
families have been observed to acknowledge the cipher-none deletion;
skipping the wait there would leave a stale indication that completes
the next installation's wait early, so they keep the unconditional wait.
Group-key removal is left alone on all targets: ath10k_send_key()
implements it as an installation of a random key with the original
cipher, which the firmware does acknowledge, and ieee80211_key_replace()
issues the following SET_KEY right after the DISABLE_KEY.
Tested on WCN3990 (SDM845): the pairwise removal returns immediately and
the reconnect installs are acknowledged as before.
>From previous mailing list discussion assumed it's relevant for QCA6174 HW3.0.
Assisted-by: LLM
Signed-off-by: David Heidelberg <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.c | 2 ++
drivers/net/wireless/ath/ath10k/hw.h | 6 ++++++
drivers/net/wireless/ath/ath10k/mac.c | 5 +++++
3 files changed, 13 insertions(+)
diff --git a/drivers/net/wireless/ath/ath10k/core.c
b/drivers/net/wireless/ath/ath10k/core.c
index 7c2939cbde5f0..3177fa415ea06 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -342,16 +342,17 @@ static const struct ath10k_hw_params
ath10k_hw_params_list[] = {
.fw_diag_ce_download = false,
.credit_size_workaround = false,
.tx_stats_over_pktlog = false,
.dynamic_sar_support = false,
.hw_restart_disconnect = false,
.use_fw_tx_credits = true,
.delay_unmap_buffer = false,
.mcast_frame_registration = false,
+ .no_pairwise_key_del_ind = true,
},
{
.id = QCA6174_HW_3_2_VERSION,
.dev_id = QCA6174_2_1_DEVICE_ID,
.bus = ATH10K_BUS_PCI,
.name = "qca6174 hw3.2",
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
.uart_pin = 6,
@@ -741,16 +742,17 @@ static const struct ath10k_hw_params
ath10k_hw_params_list[] = {
.fw_diag_ce_download = false,
.credit_size_workaround = false,
.tx_stats_over_pktlog = false,
.dynamic_sar_support = true,
.hw_restart_disconnect = true,
.use_fw_tx_credits = false,
.delay_unmap_buffer = true,
.mcast_frame_registration = false,
+ .no_pairwise_key_del_ind = true,
},
};
static const char *const ath10k_core_fw_feature_str[] = {
[ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX] = "wmi-mgmt-rx",
[ATH10K_FW_FEATURE_WMI_10X] = "wmi-10.x",
[ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX] = "has-wmi-mgmt-tx",
[ATH10K_FW_FEATURE_NO_P2P] = "no-p2p",
diff --git a/drivers/net/wireless/ath/ath10k/hw.h
b/drivers/net/wireless/ath/ath10k/hw.h
index cd468b24bd333..a6abab83df7df 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -633,16 +633,22 @@ struct ath10k_hw_params {
bool hw_restart_disconnect;
bool use_fw_tx_credits;
bool delay_unmap_buffer;
/* The hardware support multicast frame registrations */
bool mcast_frame_registration;
+
+ /* Firmware sends no HTT security indication for a pairwise key
+ * removal (WMI_CIPHER_NONE install), so waiting for one would only
+ * time out.
+ */
+ bool no_pairwise_key_del_ind;
};
struct htt_resp;
struct htt_data_tx_completion_ext;
struct htt_rx_ring_rx_desc_offsets;
/* Defines needed for Rx descriptor abstraction */
struct ath10k_hw_ops {
diff --git a/drivers/net/wireless/ath/ath10k/mac.c
b/drivers/net/wireless/ath/ath10k/mac.c
index 8e604697d6c20..653bc70a9e6af 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -319,16 +319,21 @@ static int ath10k_install_key(struct ath10k_vif *arvif,
if (arvif->nohwcrypt)
return 1;
ret = ath10k_send_key(arvif, key, cmd, macaddr, flags);
if (ret)
return ret;
+ /* Group-key removal installs a replacement key and is acknowledged. */
+ if (cmd == DISABLE_KEY && !(flags & WMI_KEY_GROUP) &&
+ ar->hw_params.no_pairwise_key_del_ind)
+ return 0;
+
time_left = wait_for_completion_timeout(&ar->install_key_done, 3 * HZ);
if (time_left == 0)
return -ETIMEDOUT;
return 0;
}
static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
---
base-commit: 7079a12d7506b07fb53b54a664bfad5fa9b16d70
change-id: 20260917-ath10k-del-d9f956ee1167
Best regards,
--
David Heidelberg <[email protected]>