[wlan][ath10k] Change the peer->num_wlan_cfg logic.
The old code always advanced the peer->num_wlan_cfg. But new code
only advances it when the new key index is higher.
Also, if a key idx has been set in firmware, don't set it again.
BUG: WLAN-855
TEST: With go/fxr/233492.
In client role: "wlantools client connect 0 fx-tplink -p XXX"
Change-Id: I6f3b878926cf30ed7d131b6b954e033ac646624b
diff --git a/drivers/wlan/third_party/atheros/ath10k/mac.c b/drivers/wlan/third_party/atheros/ath10k/mac.c
index ad70008..888fb06 100644
--- a/drivers/wlan/third_party/atheros/ath10k/mac.c
+++ b/drivers/wlan/third_party/atheros/ath10k/mac.c
@@ -5574,15 +5574,6 @@
goto exit;
}
- if (peer->num_wlan_cfg >= WMI_MAX_KEY_INDEX) {
- char ethaddr_str[ETH_ALEN * 3];
- ethaddr_sprintf(ethaddr_str, peer_addr);
- ath10k_err("failed to install key for %s (key index too large: %zu >= %d)\n",
- ethaddr_str, peer->num_wlan_cfg, WMI_MAX_KEY_INDEX);
- ret = ZX_ERR_INVALID_ARGS;
- goto exit;
- }
-
switch (key_config->key_type) {
case WLAN_KEY_TYPE_PAIRWISE:
flags |= WMI_KEY_PAIRWISE;
@@ -5596,6 +5587,16 @@
ZX_ASSERT(0);
}
+ // If the key has been set, ignore the request. See WLAN-855.
+ mtx_lock(&ar->data_lock);
+ if (key_config->key_idx < peer->num_wlan_cfg &&
+ peer->wlan_cfg[key_config->key_idx].key_idx == key_config->key_idx) {
+ ath10k_warn("key idx %d has been created. ignore it.\n", key_config->key_idx);
+ mtx_unlock(&ar->data_lock);
+ goto exit;
+ }
+ mtx_unlock(&ar->data_lock);
+
ret = ath10k_install_key(arvif, key_config, peer_addr, flags);
if (ret != ZX_OK) {
char ethaddr_str[ETH_ALEN * 3];
@@ -5614,7 +5615,9 @@
ath10k_dbg(ar, ATH10K_DBG_MAC, "Added wlan_cfg[%zu] with key index: %hhu\n",
peer->num_wlan_cfg, key_config->key_idx);
mtx_lock(&ar->data_lock);
- peer->wlan_cfg[peer->num_wlan_cfg++] = *key_config;
+ peer->wlan_cfg[key_config->key_idx] = *key_config;
+ // peer->num_wlan_cfg is used to record the max key index in firmware for later deletion.
+ peer->num_wlan_cfg = MAX(peer->num_wlan_cfg, key_config->key_idx + 1);
mtx_unlock(&ar->data_lock);
ath10k_set_key_h_def_keyidx(ar, key_config);