Skip to content

Commit 2248db6

Browse files
committed
Miri Korenblit says: ==================== wifi: iwlwifi: fixes - 2026-05-16 Contains: wifi: iwlwifi: mld: fix TSO segmentation explosion when AMSDU is disabled wifi: iwlwifi: mld: stop TX during firmware restart wifi: iwlwifi: mld: don't WARN on WoWLAN suspend w/o BSS vif wifi: iwlwifi: mvm: fix driver-set TX rates on old devices wifi: iwlwifi: mld: disconnect only after 6 beacons without Rx wifi: iwlwifi: mld: don't dereference a pointer before NULL checking it wifi: iwlwifi: use correct function to read STEP_URM register ==================== Signed-off-by: Johannes Berg <johannes.berg@intel.com>
2 parents a6e6ccd + 734a4e0 commit 2248db6

7 files changed

Lines changed: 50 additions & 35 deletions

File tree

drivers/net/wireless/intel/iwlwifi/mld/constants.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
22
/*
3-
* Copyright (C) 2024-2025 Intel Corporation
3+
* Copyright (C) 2024-2026 Intel Corporation
44
*/
55
#ifndef __iwl_mld_constants_h__
66
#define __iwl_mld_constants_h__
77

8-
#define IWL_MLD_MISSED_BEACONS_SINCE_RX_THOLD 4
8+
#define IWL_MLD_MISSED_BEACONS_SINCE_RX_THOLD 6
99
#define IWL_MLD_MISSED_BEACONS_THRESHOLD 8
1010
#define IWL_MLD_MISSED_BEACONS_THRESHOLD_LONG 19
1111
#define IWL_MLD_BCN_LOSS_EXIT_ESR_THRESH_2_LINKS 5

drivers/net/wireless/intel/iwlwifi/mld/d3.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,12 +1930,12 @@ int iwl_mld_wowlan_suspend(struct iwl_mld *mld, struct cfg80211_wowlan *wowlan)
19301930
if (WARN_ON(!wowlan))
19311931
return 1;
19321932

1933-
IWL_DEBUG_WOWLAN(mld, "Starting the wowlan suspend flow\n");
1934-
19351933
bss_vif = iwl_mld_get_bss_vif(mld);
1936-
if (WARN_ON(!bss_vif))
1934+
if (!bss_vif)
19371935
return 1;
19381936

1937+
IWL_DEBUG_WOWLAN(mld, "Starting the wowlan suspend flow\n");
1938+
19391939
if (!bss_vif->cfg.assoc) {
19401940
int ret;
19411941
/* If we're not associated, this must be netdetect */

drivers/net/wireless/intel/iwlwifi/mld/link.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
22
/*
3-
* Copyright (C) 2024-2025 Intel Corporation
3+
* Copyright (C) 2024-2026 Intel Corporation
44
*/
55

66
#include "constants.h"
@@ -504,23 +504,22 @@ void iwl_mld_remove_link(struct iwl_mld *mld,
504504
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(bss_conf->vif);
505505
struct iwl_mld_link *link = iwl_mld_link_from_mac80211(bss_conf);
506506
bool is_deflink = link == &mld_vif->deflink;
507-
u8 fw_id = link->fw_id;
508507

509508
if (WARN_ON(!link || link->active))
510509
return;
511510

512511
iwl_mld_rm_link_from_fw(mld, bss_conf);
513512
/* Continue cleanup on failure */
514513

515-
if (!is_deflink)
516-
kfree_rcu(link, rcu_head);
517-
518514
RCU_INIT_POINTER(mld_vif->link[bss_conf->link_id], NULL);
519515

520-
if (WARN_ON(fw_id >= mld->fw->ucode_capa.num_links))
516+
if (WARN_ON(link->fw_id >= mld->fw->ucode_capa.num_links))
521517
return;
522518

523-
RCU_INIT_POINTER(mld->fw_id_to_bss_conf[fw_id], NULL);
519+
RCU_INIT_POINTER(mld->fw_id_to_bss_conf[link->fw_id], NULL);
520+
521+
if (!is_deflink)
522+
kfree_rcu(link, rcu_head);
524523
}
525524

526525
void iwl_mld_handle_missed_beacon_notif(struct iwl_mld *mld,

drivers/net/wireless/intel/iwlwifi/mld/tx.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,7 @@ static int iwl_mld_tx_tso_segment(struct iwl_mld *mld, struct sk_buff *skb,
834834
return -EINVAL;
835835

836836
max_tid_amsdu_len = sta->cur->max_tid_amsdu_len[tid];
837-
if (!max_tid_amsdu_len)
837+
if (!max_tid_amsdu_len || max_tid_amsdu_len == 1)
838838
return iwl_tx_tso_segment(skb, 1, netdev_flags, mpdus_skbs);
839839

840840
/* Sub frame header + SNAP + IP header + TCP header + MSS */
@@ -846,6 +846,9 @@ static int iwl_mld_tx_tso_segment(struct iwl_mld *mld, struct sk_buff *skb,
846846
*/
847847
num_subframes = (max_tid_amsdu_len + pad) / (subf_len + pad);
848848

849+
if (WARN_ON_ONCE(!num_subframes))
850+
return iwl_tx_tso_segment(skb, 1, netdev_flags, mpdus_skbs);
851+
849852
if (sta->max_amsdu_subframes &&
850853
num_subframes > sta->max_amsdu_subframes)
851854
num_subframes = sta->max_amsdu_subframes;
@@ -970,6 +973,16 @@ void iwl_mld_tx_from_txq(struct iwl_mld *mld, struct ieee80211_txq *txq)
970973
struct sk_buff *skb = NULL;
971974
u8 zero_addr[ETH_ALEN] = {};
972975

976+
/*
977+
* Don't transmit during firmware restart. The firmware is dead,
978+
* so iwl_trans_tx() would return -EIO for each frame. Avoid the
979+
* overhead of dequeuing from mac80211 only to immediately free
980+
* the skbs, and the potential memory pressure from rapid skb
981+
* allocation churn during high-throughput restart scenarios.
982+
*/
983+
if (unlikely(mld->fw_status.in_hw_restart))
984+
return;
985+
973986
/*
974987
* No need for threads to be pending here, they can leave the first
975988
* taker all the work.

drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
22
/*
3-
* Copyright (C) 2012-2014, 2018-2025 Intel Corporation
3+
* Copyright (C) 2012-2014, 2018-2026 Intel Corporation
44
* Copyright (C) 2013-2014 Intel Mobile Communications GmbH
55
* Copyright (C) 2015-2017 Intel Deutschland GmbH
66
*/
@@ -927,13 +927,18 @@ u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct iwl_mvm *mvm,
927927

928928
u16 iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw *fw, u8 rate_idx)
929929
{
930-
u16 flags = iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx);
931930
bool is_new_rate = iwl_fw_lookup_cmd_ver(fw, BEACON_TEMPLATE_CMD, 0) > 10;
931+
u16 flags = 0;
932932

933933
if (rate_idx <= IWL_LAST_CCK_RATE)
934934
flags |= is_new_rate ? IWL_MAC_BEACON_CCK
935935
: IWL_MAC_BEACON_CCK_V1;
936936

937+
if (iwl_fw_lookup_cmd_ver(fw, TX_CMD, 0) > 8)
938+
flags |= iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx);
939+
else
940+
flags |= iwl_fw_rate_idx_to_plcp(rate_idx);
941+
937942
return flags;
938943
}
939944

@@ -962,6 +967,7 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
962967
{
963968
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
964969
struct ieee80211_tx_info *info;
970+
u32 rate_n_flags = 0;
965971
u8 rate;
966972
u32 tx_flags;
967973

@@ -981,18 +987,21 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
981987
IWL_UCODE_TLV_CAPA_BEACON_ANT_SELECTION)) {
982988
iwl_mvm_toggle_tx_ant(mvm, &mvm->mgmt_last_antenna_idx);
983989

984-
tx_params->rate_n_flags =
985-
cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) <<
986-
RATE_MCS_ANT_POS);
990+
rate_n_flags |= BIT(mvm->mgmt_last_antenna_idx) <<
991+
RATE_MCS_ANT_POS;
987992
}
988993

989994
rate = iwl_mvm_mac_ctxt_get_beacon_rate(mvm, info, vif);
990995

991-
tx_params->rate_n_flags |=
992-
cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate));
993-
if (rate == IWL_FIRST_CCK_RATE)
994-
tx_params->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK_V1);
996+
if (rate < IWL_FIRST_OFDM_RATE)
997+
rate_n_flags |= RATE_MCS_MOD_TYPE_CCK;
998+
else
999+
rate_n_flags |= RATE_MCS_MOD_TYPE_LEGACY_OFDM;
1000+
1001+
rate_n_flags |= iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate);
9951002

1003+
tx_params->rate_n_flags = iwl_mvm_v3_rate_to_fw(rate_n_flags,
1004+
mvm->fw_rates_ver);
9961005
}
9971006

9981007
int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm,

drivers/net/wireless/intel/iwlwifi/mvm/utils.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
22
/*
3-
* Copyright (C) 2012-2014, 2018-2025 Intel Corporation
3+
* Copyright (C) 2012-2014, 2018-2026 Intel Corporation
44
* Copyright (C) 2013-2014 Intel Mobile Communications GmbH
55
* Copyright (C) 2015-2017 Intel Deutschland GmbH
66
*/
@@ -159,15 +159,9 @@ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
159159

160160
u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx)
161161
{
162-
if (iwl_fw_lookup_cmd_ver(fw, TX_CMD, 0) > 8)
163-
/* In the new rate legacy rates are indexed:
164-
* 0 - 3 for CCK and 0 - 7 for OFDM.
165-
*/
166-
return (rate_idx >= IWL_FIRST_OFDM_RATE ?
167-
rate_idx - IWL_FIRST_OFDM_RATE :
168-
rate_idx);
169-
170-
return iwl_fw_rate_idx_to_plcp(rate_idx);
162+
return rate_idx >= IWL_FIRST_OFDM_RATE ?
163+
rate_idx - IWL_FIRST_OFDM_RATE :
164+
rate_idx;
171165
}
172166

173167
u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac)

drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans-gen2.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,9 @@ void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans)
398398
mutex_unlock(&trans_pcie->mutex);
399399

400400
if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
401-
trans->step_urm = !!(iwl_read_umac_prph(trans,
402-
CNVI_PMU_STEP_FLOW) &
403-
CNVI_PMU_STEP_FLOW_FORCE_URM);
401+
trans->step_urm = !!(iwl_read_prph(trans,
402+
CNVI_PMU_STEP_FLOW) &
403+
CNVI_PMU_STEP_FLOW_FORCE_URM);
404404
}
405405

406406
static bool iwl_pcie_set_ltr(struct iwl_trans *trans)

0 commit comments

Comments
 (0)