@@ -3519,14 +3519,30 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar,
3519
3519
static struct ath12k_vif_cache *ath12k_ahvif_get_link_cache(struct ath12k_vif *ahvif,
3520
3520
u8 link_id)
3521
3521
{
3522
- if (!ahvif->cache[link_id])
3522
+ if (!ahvif->cache[link_id]) {
3523
3523
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
+ }
3524
3527
3525
3528
return ahvif->cache[link_id];
3526
3529
}
3527
3530
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
+
3528
3543
static void ath12k_ahvif_put_link_cache(struct ath12k_vif *ahvif, u8 link_id)
3529
3544
{
3545
+ ath12k_ahvif_put_link_key_cache(ahvif->cache[link_id]);
3530
3546
kfree(ahvif->cache[link_id]);
3531
3547
ahvif->cache[link_id] = NULL;
3532
3548
}
@@ -4170,6 +4186,39 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd,
4170
4186
return 0;
4171
4187
}
4172
4188
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
+
4173
4222
static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
4174
4223
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
4175
4224
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,
4179
4228
struct ath12k_link_sta *arsta = NULL;
4180
4229
struct ath12k_vif_cache *cache;
4181
4230
struct ath12k_sta *ahsta;
4182
- struct ath12k *ar;
4231
+ unsigned long links;
4232
+ u8 link_id;
4183
4233
int ret;
4184
4234
4185
4235
lockdep_assert_wiphy(hw->wiphy);
4186
4236
4187
- arvif = &ahvif->deflink;
4188
-
4189
4237
/* BIP needs to be done in software */
4190
4238
if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
4191
4239
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,
4197
4245
if (key->keyidx > WMI_MAX_KEY_INDEX)
4198
4246
return -ENOSPC;
4199
4247
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;
4206
4289
}
4207
4290
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;
4211
4295
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);
4215
4297
4216
- return 0 ;
4217
- }
4298
+ return ret ;
4299
+ }
4218
4300
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);
4222
4302
}
4223
4303
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:
4230
4305
4231
4306
return ret;
4232
4307
}
@@ -6838,6 +6913,40 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
6838
6913
return ret;
6839
6914
}
6840
6915
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
+
6841
6950
static void ath12k_mac_vif_cache_flush(struct ath12k *ar, struct ath12k_link_vif *arvif)
6842
6951
{
6843
6952
struct ath12k_vif *ahvif = arvif->ahvif;
@@ -6866,13 +6975,9 @@ static void ath12k_mac_vif_cache_flush(struct ath12k *ar, struct ath12k_link_vif
6866
6975
cache->bss_conf_changed);
6867
6976
}
6868
6977
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
+
6876
6981
ath12k_ahvif_put_link_cache(ahvif, arvif->link_id);
6877
6982
}
6878
6983
0 commit comments