Skip to content

Commit 25e18b9

Browse files
Rameshkumar SundaramJeff Johnson
authored andcommitted
wifi: ath12k: modify ath12k_mac_op_set_key() for MLO
Currently ath12k_mac_op_set_key() uses ahvif's deflink to set/cache keys depending upon the availability of corresponding vdev. But with MLO the incoming vif could have multiple links affiliated to it, hence use the link id provided in the key info argument and apply/cache the key to the corresponding link arvif. When the set key is a pairwise key intended for an ML station then set the same key on all the affiliated link stations. Also there could be multiple keys associates to a single link: group keys, mgmt/beacon protection keys and so on. Current key caching design lacks support for caching multiple keys for a given link cache. Add support to store a list of all link keys in the ahvifs link cache as well as update, flush and free the same whenever required. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Rameshkumar Sundaram <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jeff Johnson <[email protected]>
1 parent afbab6e commit 25e18b9

File tree

2 files changed

+141
-35
lines changed

2 files changed

+141
-35
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,9 @@ struct ath12k_tx_conf {
221221
};
222222

223223
struct ath12k_key_conf {
224-
bool changed;
225224
enum set_key_cmd cmd;
225+
struct list_head list;
226+
struct ieee80211_sta *sta;
226227
struct ieee80211_key_conf *key;
227228
};
228229

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

Lines changed: 139 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3519,14 +3519,30 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar,
35193519
static struct ath12k_vif_cache *ath12k_ahvif_get_link_cache(struct ath12k_vif *ahvif,
35203520
u8 link_id)
35213521
{
3522-
if (!ahvif->cache[link_id])
3522+
if (!ahvif->cache[link_id]) {
35233523
ahvif->cache[link_id] = kzalloc(sizeof(*ahvif->cache[0]), GFP_KERNEL);
3524+
if (ahvif->cache[link_id])
3525+
INIT_LIST_HEAD(&ahvif->cache[link_id]->key_conf.list);
3526+
}
35243527

35253528
return ahvif->cache[link_id];
35263529
}
35273530

3531+
static void ath12k_ahvif_put_link_key_cache(struct ath12k_vif_cache *cache)
3532+
{
3533+
struct ath12k_key_conf *key_conf, *tmp;
3534+
3535+
if (!cache || list_empty(&cache->key_conf.list))
3536+
return;
3537+
list_for_each_entry_safe(key_conf, tmp, &cache->key_conf.list, list) {
3538+
list_del(&key_conf->list);
3539+
kfree(key_conf);
3540+
}
3541+
}
3542+
35283543
static void ath12k_ahvif_put_link_cache(struct ath12k_vif *ahvif, u8 link_id)
35293544
{
3545+
ath12k_ahvif_put_link_key_cache(ahvif->cache[link_id]);
35303546
kfree(ahvif->cache[link_id]);
35313547
ahvif->cache[link_id] = NULL;
35323548
}
@@ -4170,6 +4186,39 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd,
41704186
return 0;
41714187
}
41724188

4189+
static int ath12k_mac_update_key_cache(struct ath12k_vif_cache *cache,
4190+
enum set_key_cmd cmd,
4191+
struct ieee80211_sta *sta,
4192+
struct ieee80211_key_conf *key)
4193+
{
4194+
struct ath12k_key_conf *key_conf = NULL, *tmp;
4195+
4196+
if (cmd == SET_KEY) {
4197+
key_conf = kzalloc(sizeof(*key_conf), GFP_KERNEL);
4198+
4199+
if (!key_conf)
4200+
return -ENOMEM;
4201+
4202+
key_conf->cmd = cmd;
4203+
key_conf->sta = sta;
4204+
key_conf->key = key;
4205+
list_add_tail(&key_conf->list,
4206+
&cache->key_conf.list);
4207+
}
4208+
if (list_empty(&cache->key_conf.list))
4209+
return 0;
4210+
list_for_each_entry_safe(key_conf, tmp, &cache->key_conf.list, list) {
4211+
if (key_conf->key == key) {
4212+
/* DEL key for an old SET key which driver hasn't flushed yet.
4213+
*/
4214+
list_del(&key_conf->list);
4215+
kfree(key_conf);
4216+
break;
4217+
}
4218+
}
4219+
return 0;
4220+
}
4221+
41734222
static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
41744223
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
41754224
struct ieee80211_key_conf *key)
@@ -4179,13 +4228,12 @@ static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
41794228
struct ath12k_link_sta *arsta = NULL;
41804229
struct ath12k_vif_cache *cache;
41814230
struct ath12k_sta *ahsta;
4182-
struct ath12k *ar;
4231+
unsigned long links;
4232+
u8 link_id;
41834233
int ret;
41844234

41854235
lockdep_assert_wiphy(hw->wiphy);
41864236

4187-
arvif = &ahvif->deflink;
4188-
41894237
/* BIP needs to be done in software */
41904238
if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
41914239
key->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
@@ -4197,36 +4245,63 @@ static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
41974245
if (key->keyidx > WMI_MAX_KEY_INDEX)
41984246
return -ENOSPC;
41994247

4200-
ar = ath12k_get_ar_by_vif(hw, vif);
4201-
if (!ar) {
4202-
/* ar is expected to be valid when sta ptr is available */
4203-
if (sta) {
4204-
WARN_ON_ONCE(1);
4205-
return -EINVAL;
4248+
if (sta) {
4249+
ahsta = ath12k_sta_to_ahsta(sta);
4250+
/* For an ML STA Pairwise key is same for all associated link Stations,
4251+
* hence do set key for all link STAs which are active.
4252+
*/
4253+
if (sta->mlo) {
4254+
links = ahsta->links_map;
4255+
for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) {
4256+
arvif = wiphy_dereference(hw->wiphy,
4257+
ahvif->link[link_id]);
4258+
arsta = wiphy_dereference(hw->wiphy,
4259+
ahsta->link[link_id]);
4260+
4261+
if (WARN_ON(!arvif || !arsta))
4262+
/* arvif and arsta are expected to be valid when
4263+
* STA is present.
4264+
*/
4265+
continue;
4266+
4267+
ret = ath12k_mac_set_key(arvif->ar, cmd, arvif,
4268+
arsta, key);
4269+
if (ret)
4270+
break;
4271+
}
4272+
} else {
4273+
arsta = &ahsta->deflink;
4274+
arvif = arsta->arvif;
4275+
if (WARN_ON(!arvif)) {
4276+
ret = -EINVAL;
4277+
goto out;
4278+
}
4279+
4280+
ret = ath12k_mac_set_key(arvif->ar, cmd, arvif, arsta, key);
4281+
}
4282+
} else {
4283+
if (key->link_id >= 0 && key->link_id < IEEE80211_MLD_MAX_NUM_LINKS) {
4284+
link_id = key->link_id;
4285+
arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]);
4286+
} else {
4287+
link_id = 0;
4288+
arvif = &ahvif->deflink;
42064289
}
42074290

4208-
cache = ath12k_ahvif_get_link_cache(ahvif, ATH12K_DEFAULT_LINK_ID);
4209-
if (!cache)
4210-
return -ENOSPC;
4291+
if (!arvif || !arvif->is_created) {
4292+
cache = ath12k_ahvif_get_link_cache(ahvif, link_id);
4293+
if (!cache)
4294+
return -ENOSPC;
42114295

4212-
cache->key_conf.cmd = cmd;
4213-
cache->key_conf.key = key;
4214-
cache->key_conf.changed = true;
4296+
ret = ath12k_mac_update_key_cache(cache, cmd, sta, key);
42154297

4216-
return 0;
4217-
}
4298+
return ret;
4299+
}
42184300

4219-
if (sta) {
4220-
ahsta = ath12k_sta_to_ahsta(sta);
4221-
arsta = &ahsta->deflink;
4301+
ret = ath12k_mac_set_key(arvif->ar, cmd, arvif, NULL, key);
42224302
}
42234303

4224-
/* Note: Currently only deflink of ahvif and ahsta are used here,
4225-
* once MLO support is added the allocated links (i.e ahvif->links[])
4226-
* should be use based on link id passed from mac80211 and such link
4227-
* access needs to be protected with ah->conf_mutex.
4228-
*/
4229-
ret = ath12k_mac_set_key(ar, cmd, arvif, arsta, key);
4304+
out:
42304305

42314306
return ret;
42324307
}
@@ -6838,6 +6913,40 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
68386913
return ret;
68396914
}
68406915

6916+
static void ath12k_mac_vif_flush_key_cache(struct ath12k_link_vif *arvif)
6917+
{
6918+
struct ath12k_key_conf *key_conf, *tmp;
6919+
struct ath12k_vif *ahvif = arvif->ahvif;
6920+
struct ath12k_hw *ah = ahvif->ah;
6921+
struct ath12k_sta *ahsta;
6922+
struct ath12k_link_sta *arsta;
6923+
struct ath12k_vif_cache *cache = ahvif->cache[arvif->link_id];
6924+
int ret;
6925+
6926+
lockdep_assert_wiphy(ah->hw->wiphy);
6927+
6928+
list_for_each_entry_safe(key_conf, tmp, &cache->key_conf.list, list) {
6929+
arsta = NULL;
6930+
if (key_conf->sta) {
6931+
ahsta = ath12k_sta_to_ahsta(key_conf->sta);
6932+
arsta = wiphy_dereference(ah->hw->wiphy,
6933+
ahsta->link[arvif->link_id]);
6934+
if (!arsta)
6935+
goto free_cache;
6936+
}
6937+
6938+
ret = ath12k_mac_set_key(arvif->ar, key_conf->cmd,
6939+
arvif, arsta,
6940+
key_conf->key);
6941+
if (ret)
6942+
ath12k_warn(arvif->ar->ab, "unable to apply set key param to vdev %d ret %d\n",
6943+
arvif->vdev_id, ret);
6944+
free_cache:
6945+
list_del(&key_conf->list);
6946+
kfree(key_conf);
6947+
}
6948+
}
6949+
68416950
static void ath12k_mac_vif_cache_flush(struct ath12k *ar, struct ath12k_link_vif *arvif)
68426951
{
68436952
struct ath12k_vif *ahvif = arvif->ahvif;
@@ -6866,13 +6975,9 @@ static void ath12k_mac_vif_cache_flush(struct ath12k *ar, struct ath12k_link_vif
68666975
cache->bss_conf_changed);
68676976
}
68686977

6869-
if (cache->key_conf.changed) {
6870-
ret = ath12k_mac_set_key(ar, cache->key_conf.cmd, arvif, NULL,
6871-
cache->key_conf.key);
6872-
if (ret)
6873-
ath12k_warn(ab, "unable to apply set key param to vdev %d ret %d\n",
6874-
arvif->vdev_id, ret);
6875-
}
6978+
if (!list_empty(&cache->key_conf.list))
6979+
ath12k_mac_vif_flush_key_cache(arvif);
6980+
68766981
ath12k_ahvif_put_link_cache(ahvif, arvif->link_id);
68776982
}
68786983

0 commit comments

Comments
 (0)