Skip to content

Commit 27893dd

Browse files
committed
Merge tag 'ath-current-20250902' of git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath
Jeff Johnson says: ================== ath.git update for v6.17-rc5 Fix a long-standing issue with ath11k dropping group data packets during GTK rekey, and fix an omission in the ath12k multi-link EMLSR support introduced in v6.16. ================== Signed-off-by: Johannes Berg <[email protected]>
2 parents fe9e4d0 + 97acb02 commit 27893dd

File tree

3 files changed

+105
-9
lines changed

3 files changed

+105
-9
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,8 @@ struct ath11k_vif {
411411
bool do_not_send_tmpl;
412412
struct ath11k_arp_ns_offload arp_ns_offload;
413413
struct ath11k_rekey_data rekey_data;
414+
u32 num_stations;
415+
bool reinstall_group_keys;
414416

415417
struct ath11k_reg_tpc_power_info reg_tpc_info;
416418

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

Lines changed: 102 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4317,6 +4317,40 @@ static int ath11k_clear_peer_keys(struct ath11k_vif *arvif,
43174317
return first_errno;
43184318
}
43194319

4320+
static int ath11k_set_group_keys(struct ath11k_vif *arvif)
4321+
{
4322+
struct ath11k *ar = arvif->ar;
4323+
struct ath11k_base *ab = ar->ab;
4324+
const u8 *addr = arvif->bssid;
4325+
int i, ret, first_errno = 0;
4326+
struct ath11k_peer *peer;
4327+
4328+
spin_lock_bh(&ab->base_lock);
4329+
peer = ath11k_peer_find(ab, arvif->vdev_id, addr);
4330+
spin_unlock_bh(&ab->base_lock);
4331+
4332+
if (!peer)
4333+
return -ENOENT;
4334+
4335+
for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
4336+
struct ieee80211_key_conf *key = peer->keys[i];
4337+
4338+
if (!key || (key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
4339+
continue;
4340+
4341+
ret = ath11k_install_key(arvif, key, SET_KEY, addr,
4342+
WMI_KEY_GROUP);
4343+
if (ret < 0 && first_errno == 0)
4344+
first_errno = ret;
4345+
4346+
if (ret < 0)
4347+
ath11k_warn(ab, "failed to set group key of idx %d for vdev %d: %d\n",
4348+
i, arvif->vdev_id, ret);
4349+
}
4350+
4351+
return first_errno;
4352+
}
4353+
43204354
static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
43214355
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
43224356
struct ieee80211_key_conf *key)
@@ -4326,6 +4360,7 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
43264360
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
43274361
struct ath11k_peer *peer;
43284362
struct ath11k_sta *arsta;
4363+
bool is_ap_with_no_sta;
43294364
const u8 *peer_addr;
43304365
int ret = 0;
43314366
u32 flags = 0;
@@ -4386,16 +4421,57 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
43864421
else
43874422
flags |= WMI_KEY_GROUP;
43884423

4389-
ret = ath11k_install_key(arvif, key, cmd, peer_addr, flags);
4390-
if (ret) {
4391-
ath11k_warn(ab, "ath11k_install_key failed (%d)\n", ret);
4392-
goto exit;
4393-
}
4424+
ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
4425+
"%s for peer %pM on vdev %d flags 0x%X, type = %d, num_sta %d\n",
4426+
cmd == SET_KEY ? "SET_KEY" : "DEL_KEY", peer_addr, arvif->vdev_id,
4427+
flags, arvif->vdev_type, arvif->num_stations);
4428+
4429+
/* Allow group key clearing only in AP mode when no stations are
4430+
* associated. There is a known race condition in firmware where
4431+
* group addressed packets may be dropped if the key is cleared
4432+
* and immediately set again during rekey.
4433+
*
4434+
* During GTK rekey, mac80211 issues a clear key (if the old key
4435+
* exists) followed by an install key operation for same key
4436+
* index. This causes ath11k to send two WMI commands in quick
4437+
* succession: one to clear the old key and another to install the
4438+
* new key in the same slot.
4439+
*
4440+
* Under certain conditions—especially under high load or time
4441+
* sensitive scenarios, firmware may process these commands
4442+
* asynchronously in a way that firmware assumes the key is
4443+
* cleared whereas hardware has a valid key. This inconsistency
4444+
* between hardware and firmware leads to group addressed packet
4445+
* drops after rekey.
4446+
* Only setting the same key again can restore a valid key in
4447+
* firmware and allow packets to be transmitted.
4448+
*
4449+
* There is a use case where an AP can transition from Secure mode
4450+
* to open mode without a vdev restart by just deleting all
4451+
* associated peers and clearing key, Hence allow clear key for
4452+
* that case alone. Mark arvif->reinstall_group_keys in such cases
4453+
* and reinstall the same key when the first peer is added,
4454+
* allowing firmware to recover from the race if it had occurred.
4455+
*/
43944456

4395-
ret = ath11k_dp_peer_rx_pn_replay_config(arvif, peer_addr, cmd, key);
4396-
if (ret) {
4397-
ath11k_warn(ab, "failed to offload PN replay detection %d\n", ret);
4398-
goto exit;
4457+
is_ap_with_no_sta = (vif->type == NL80211_IFTYPE_AP &&
4458+
!arvif->num_stations);
4459+
if ((flags & WMI_KEY_PAIRWISE) || cmd == SET_KEY || is_ap_with_no_sta) {
4460+
ret = ath11k_install_key(arvif, key, cmd, peer_addr, flags);
4461+
if (ret) {
4462+
ath11k_warn(ab, "ath11k_install_key failed (%d)\n", ret);
4463+
goto exit;
4464+
}
4465+
4466+
ret = ath11k_dp_peer_rx_pn_replay_config(arvif, peer_addr, cmd, key);
4467+
if (ret) {
4468+
ath11k_warn(ab, "failed to offload PN replay detection %d\n",
4469+
ret);
4470+
goto exit;
4471+
}
4472+
4473+
if ((flags & WMI_KEY_GROUP) && cmd == SET_KEY && is_ap_with_no_sta)
4474+
arvif->reinstall_group_keys = true;
43994475
}
44004476

44014477
spin_lock_bh(&ab->base_lock);
@@ -4994,6 +5070,7 @@ static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif,
49945070
return -ENOBUFS;
49955071

49965072
ar->num_stations++;
5073+
arvif->num_stations++;
49975074

49985075
return 0;
49995076
}
@@ -5009,6 +5086,7 @@ static void ath11k_mac_dec_num_stations(struct ath11k_vif *arvif,
50095086
return;
50105087

50115088
ar->num_stations--;
5089+
arvif->num_stations--;
50125090
}
50135091

50145092
static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar,
@@ -9540,6 +9618,21 @@ static int ath11k_mac_station_add(struct ath11k *ar,
95409618
goto exit;
95419619
}
95429620

9621+
/* Driver allows the DEL KEY followed by SET KEY sequence for
9622+
* group keys for only when there is no clients associated, if at
9623+
* all firmware has entered the race during that window,
9624+
* reinstalling the same key when the first sta connects will allow
9625+
* firmware to recover from the race.
9626+
*/
9627+
if (arvif->num_stations == 1 && arvif->reinstall_group_keys) {
9628+
ath11k_dbg(ab, ATH11K_DBG_MAC, "set group keys on 1st station add for vdev %d\n",
9629+
arvif->vdev_id);
9630+
ret = ath11k_set_group_keys(arvif);
9631+
if (ret)
9632+
goto dec_num_station;
9633+
arvif->reinstall_group_keys = false;
9634+
}
9635+
95439636
arsta->rx_stats = kzalloc(sizeof(*arsta->rx_stats), GFP_KERNEL);
95449637
if (!arsta->rx_stats) {
95459638
ret = -ENOMEM;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2423,6 +2423,7 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
24232423

24242424
eml_cap = arg->ml.eml_cap;
24252425
if (u16_get_bits(eml_cap, IEEE80211_EML_CAP_EMLSR_SUPP)) {
2426+
ml_params->flags |= cpu_to_le32(ATH12K_WMI_FLAG_MLO_EMLSR_SUPPORT);
24262427
/* Padding delay */
24272428
eml_pad_delay = ieee80211_emlsr_pad_delay_in_us(eml_cap);
24282429
ml_params->emlsr_padding_delay_us = cpu_to_le32(eml_pad_delay);

0 commit comments

Comments
 (0)