Skip to content

Commit 3faa76b

Browse files
Baochen Qianggregkh
authored andcommitted
wifi: ath12k: install pairwise key first
commit 66e865f upstream. As station, WCN7850 firmware requires pairwise key to be installed before group key. Currently host does not care about this, so it is up to kernel or userspace to decide which one will be installed first. In case above requirement is not met, WCN7850 firmware's EAPOL station machine is messed up, and finally connection fails [1]. Reorder key install for station interface in that case: this is done by caching group key first; Later when pairwise key arrives, both can be installed in required order. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4 Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00217-QCAHKSWPL_SILICONZ-1 Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218733 Link: https://lore.kernel.org/all/AS8P190MB12051DDBD84CD88E71C40AD7873F2@AS8P190MB1205.EURP190.PROD.OUTLOOK.COM # [1] 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]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e1be1f3 commit 3faa76b

3 files changed

Lines changed: 74 additions & 7 deletions

File tree

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ struct ath12k_link_vif {
345345
bool is_sta_assoc_link;
346346

347347
struct ath12k_reg_tpc_power_info reg_tpc_info;
348+
349+
bool group_key_valid;
350+
struct wmi_vdev_install_key_arg group_key;
351+
bool pairwise_key_done;
348352
};
349353

350354
struct ath12k_vif {

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

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4723,14 +4723,13 @@ static int ath12k_install_key(struct ath12k_link_vif *arvif,
47234723
.key_len = key->keylen,
47244724
.key_data = key->key,
47254725
.key_flags = flags,
4726+
.ieee80211_key_cipher = key->cipher,
47264727
.macaddr = macaddr,
47274728
};
47284729
struct ath12k_vif *ahvif = arvif->ahvif;
47294730

47304731
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
47314732

4732-
reinit_completion(&ar->install_key_done);
4733-
47344733
if (test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags))
47354734
return 0;
47364735

@@ -4739,7 +4738,7 @@ static int ath12k_install_key(struct ath12k_link_vif *arvif,
47394738
/* arg.key_cipher = WMI_CIPHER_NONE; */
47404739
arg.key_len = 0;
47414740
arg.key_data = NULL;
4742-
goto install;
4741+
goto check_order;
47434742
}
47444743

47454744
switch (key->cipher) {
@@ -4767,19 +4766,82 @@ static int ath12k_install_key(struct ath12k_link_vif *arvif,
47674766
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV |
47684767
IEEE80211_KEY_FLAG_RESERVE_TAILROOM;
47694768

4769+
check_order:
4770+
if (ahvif->vdev_type == WMI_VDEV_TYPE_STA &&
4771+
arg.key_flags == WMI_KEY_GROUP) {
4772+
if (cmd == SET_KEY) {
4773+
if (arvif->pairwise_key_done) {
4774+
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
4775+
"vdev %u pairwise key done, go install group key\n",
4776+
arg.vdev_id);
4777+
goto install;
4778+
} else {
4779+
/* WCN7850 firmware requires pairwise key to be installed
4780+
* before group key. In case group key comes first, cache
4781+
* it and return. Will revisit it once pairwise key gets
4782+
* installed.
4783+
*/
4784+
arvif->group_key = arg;
4785+
arvif->group_key_valid = true;
4786+
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
4787+
"vdev %u group key before pairwise key, cache and skip\n",
4788+
arg.vdev_id);
4789+
4790+
ret = 0;
4791+
goto out;
4792+
}
4793+
} else {
4794+
arvif->group_key_valid = false;
4795+
}
4796+
}
4797+
47704798
install:
4771-
ret = ath12k_wmi_vdev_install_key(arvif->ar, &arg);
4799+
reinit_completion(&ar->install_key_done);
47724800

4801+
ret = ath12k_wmi_vdev_install_key(arvif->ar, &arg);
47734802
if (ret)
47744803
return ret;
47754804

47764805
if (!wait_for_completion_timeout(&ar->install_key_done, 1 * HZ))
47774806
return -ETIMEDOUT;
47784807

4779-
if (ether_addr_equal(macaddr, arvif->bssid))
4780-
ahvif->key_cipher = key->cipher;
4808+
if (ether_addr_equal(arg.macaddr, arvif->bssid))
4809+
ahvif->key_cipher = arg.ieee80211_key_cipher;
4810+
4811+
if (ar->install_key_status) {
4812+
ret = -EINVAL;
4813+
goto out;
4814+
}
4815+
4816+
if (ahvif->vdev_type == WMI_VDEV_TYPE_STA &&
4817+
arg.key_flags == WMI_KEY_PAIRWISE) {
4818+
if (cmd == SET_KEY) {
4819+
arvif->pairwise_key_done = true;
4820+
if (arvif->group_key_valid) {
4821+
/* Install cached GTK */
4822+
arvif->group_key_valid = false;
4823+
arg = arvif->group_key;
4824+
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
4825+
"vdev %u pairwise key done, group key ready, go install\n",
4826+
arg.vdev_id);
4827+
goto install;
4828+
}
4829+
} else {
4830+
arvif->pairwise_key_done = false;
4831+
}
4832+
}
4833+
4834+
out:
4835+
if (ret) {
4836+
/* In case of failure userspace may not do DISABLE_KEY
4837+
* but triggers re-connection directly, so manually reset
4838+
* status here.
4839+
*/
4840+
arvif->group_key_valid = false;
4841+
arvif->pairwise_key_done = false;
4842+
}
47814843

4782-
return ar->install_key_status ? -EINVAL : 0;
4844+
return ret;
47834845
}
47844846

47854847
static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif,

drivers/net/wireless/ath/ath12k/wmi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3760,6 +3760,7 @@ struct wmi_vdev_install_key_arg {
37603760
u32 key_idx;
37613761
u32 key_flags;
37623762
u32 key_cipher;
3763+
u32 ieee80211_key_cipher;
37633764
u32 key_len;
37643765
u32 key_txmic_len;
37653766
u32 key_rxmic_len;

0 commit comments

Comments
 (0)