mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 12:35:52 +02:00
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. -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQ/mtSHzPUi16IfDEksFbugiYzLewUCaLeIKwAKCRAsFbugiYzL e4fPAP9JDoYJG5G/2/8dEvyQyCYzqkhzaqwCxV4wfUA+igwUugD8C8El/qu2TOxY /0ZPJ9AR86csDmEjQ38oG8elQzSOQQA= =scAW -----END PGP SIGNATURE----- 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 <johannes.berg@intel.com>
This commit is contained in:
commit
27893dd634
|
|
@ -411,6 +411,8 @@ struct ath11k_vif {
|
|||
bool do_not_send_tmpl;
|
||||
struct ath11k_arp_ns_offload arp_ns_offload;
|
||||
struct ath11k_rekey_data rekey_data;
|
||||
u32 num_stations;
|
||||
bool reinstall_group_keys;
|
||||
|
||||
struct ath11k_reg_tpc_power_info reg_tpc_info;
|
||||
|
||||
|
|
|
|||
|
|
@ -4317,6 +4317,40 @@ static int ath11k_clear_peer_keys(struct ath11k_vif *arvif,
|
|||
return first_errno;
|
||||
}
|
||||
|
||||
static int ath11k_set_group_keys(struct ath11k_vif *arvif)
|
||||
{
|
||||
struct ath11k *ar = arvif->ar;
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
const u8 *addr = arvif->bssid;
|
||||
int i, ret, first_errno = 0;
|
||||
struct ath11k_peer *peer;
|
||||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
peer = ath11k_peer_find(ab, arvif->vdev_id, addr);
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
|
||||
if (!peer)
|
||||
return -ENOENT;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
|
||||
struct ieee80211_key_conf *key = peer->keys[i];
|
||||
|
||||
if (!key || (key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
|
||||
continue;
|
||||
|
||||
ret = ath11k_install_key(arvif, key, SET_KEY, addr,
|
||||
WMI_KEY_GROUP);
|
||||
if (ret < 0 && first_errno == 0)
|
||||
first_errno = ret;
|
||||
|
||||
if (ret < 0)
|
||||
ath11k_warn(ab, "failed to set group key of idx %d for vdev %d: %d\n",
|
||||
i, arvif->vdev_id, ret);
|
||||
}
|
||||
|
||||
return first_errno;
|
||||
}
|
||||
|
||||
static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
|
||||
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,
|
|||
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
|
||||
struct ath11k_peer *peer;
|
||||
struct ath11k_sta *arsta;
|
||||
bool is_ap_with_no_sta;
|
||||
const u8 *peer_addr;
|
||||
int ret = 0;
|
||||
u32 flags = 0;
|
||||
|
|
@ -4386,16 +4421,57 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
else
|
||||
flags |= WMI_KEY_GROUP;
|
||||
|
||||
ret = ath11k_install_key(arvif, key, cmd, peer_addr, flags);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "ath11k_install_key failed (%d)\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
||||
"%s for peer %pM on vdev %d flags 0x%X, type = %d, num_sta %d\n",
|
||||
cmd == SET_KEY ? "SET_KEY" : "DEL_KEY", peer_addr, arvif->vdev_id,
|
||||
flags, arvif->vdev_type, arvif->num_stations);
|
||||
|
||||
ret = ath11k_dp_peer_rx_pn_replay_config(arvif, peer_addr, cmd, key);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to offload PN replay detection %d\n", ret);
|
||||
goto exit;
|
||||
/* Allow group key clearing only in AP mode when no stations are
|
||||
* associated. There is a known race condition in firmware where
|
||||
* group addressed packets may be dropped if the key is cleared
|
||||
* and immediately set again during rekey.
|
||||
*
|
||||
* During GTK rekey, mac80211 issues a clear key (if the old key
|
||||
* exists) followed by an install key operation for same key
|
||||
* index. This causes ath11k to send two WMI commands in quick
|
||||
* succession: one to clear the old key and another to install the
|
||||
* new key in the same slot.
|
||||
*
|
||||
* Under certain conditions—especially under high load or time
|
||||
* sensitive scenarios, firmware may process these commands
|
||||
* asynchronously in a way that firmware assumes the key is
|
||||
* cleared whereas hardware has a valid key. This inconsistency
|
||||
* between hardware and firmware leads to group addressed packet
|
||||
* drops after rekey.
|
||||
* Only setting the same key again can restore a valid key in
|
||||
* firmware and allow packets to be transmitted.
|
||||
*
|
||||
* There is a use case where an AP can transition from Secure mode
|
||||
* to open mode without a vdev restart by just deleting all
|
||||
* associated peers and clearing key, Hence allow clear key for
|
||||
* that case alone. Mark arvif->reinstall_group_keys in such cases
|
||||
* and reinstall the same key when the first peer is added,
|
||||
* allowing firmware to recover from the race if it had occurred.
|
||||
*/
|
||||
|
||||
is_ap_with_no_sta = (vif->type == NL80211_IFTYPE_AP &&
|
||||
!arvif->num_stations);
|
||||
if ((flags & WMI_KEY_PAIRWISE) || cmd == SET_KEY || is_ap_with_no_sta) {
|
||||
ret = ath11k_install_key(arvif, key, cmd, peer_addr, flags);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "ath11k_install_key failed (%d)\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = ath11k_dp_peer_rx_pn_replay_config(arvif, peer_addr, cmd, key);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to offload PN replay detection %d\n",
|
||||
ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((flags & WMI_KEY_GROUP) && cmd == SET_KEY && is_ap_with_no_sta)
|
||||
arvif->reinstall_group_keys = true;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
|
|
@ -4994,6 +5070,7 @@ static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif,
|
|||
return -ENOBUFS;
|
||||
|
||||
ar->num_stations++;
|
||||
arvif->num_stations++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -5009,6 +5086,7 @@ static void ath11k_mac_dec_num_stations(struct ath11k_vif *arvif,
|
|||
return;
|
||||
|
||||
ar->num_stations--;
|
||||
arvif->num_stations--;
|
||||
}
|
||||
|
||||
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,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
/* Driver allows the DEL KEY followed by SET KEY sequence for
|
||||
* group keys for only when there is no clients associated, if at
|
||||
* all firmware has entered the race during that window,
|
||||
* reinstalling the same key when the first sta connects will allow
|
||||
* firmware to recover from the race.
|
||||
*/
|
||||
if (arvif->num_stations == 1 && arvif->reinstall_group_keys) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_MAC, "set group keys on 1st station add for vdev %d\n",
|
||||
arvif->vdev_id);
|
||||
ret = ath11k_set_group_keys(arvif);
|
||||
if (ret)
|
||||
goto dec_num_station;
|
||||
arvif->reinstall_group_keys = false;
|
||||
}
|
||||
|
||||
arsta->rx_stats = kzalloc(sizeof(*arsta->rx_stats), GFP_KERNEL);
|
||||
if (!arsta->rx_stats) {
|
||||
ret = -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -2423,6 +2423,7 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
|
|||
|
||||
eml_cap = arg->ml.eml_cap;
|
||||
if (u16_get_bits(eml_cap, IEEE80211_EML_CAP_EMLSR_SUPP)) {
|
||||
ml_params->flags |= cpu_to_le32(ATH12K_WMI_FLAG_MLO_EMLSR_SUPPORT);
|
||||
/* Padding delay */
|
||||
eml_pad_delay = ieee80211_emlsr_pad_delay_in_us(eml_cap);
|
||||
ml_params->emlsr_padding_delay_us = cpu_to_le32(eml_pad_delay);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user