mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
wifi: iwlwifi: fixes - 2026-05-31
This contains a few fixes: - Don't grab nic access in non-fast-resume - Don't send a large hcmd than transport supports - In AP mode, don't send tx power constraints command before activating the link - Don't do sw reset handshake on older firmwares. -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQQM3A3Pv7vbm9vtjWbacY7uyt+OfQUCahxB+wAKCRDacY7uyt+O fbPvAQDUKxERZJuf0FezGx4Z17XyibqhCPlPLrxuCOiWR5OObAD8DZ7do7sSJx/P r0r7rUfLW0eKkbQ/UthAhHx0jD7imgQ= =J9uk -----END PGP SIGNATURE----- Merge tag 'iwlwifi-fixes-2026-05-31' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next wifi: iwlwifi: fixes - 2026-05-31 Miri Korenblit says: ==================== This contains a few fixes: - Don't grab nic access in non-fast-resume - Don't send a large hcmd than transport supports - In AP mode, don't send tx power constraints command before activating the link - Don't do sw reset handshake on older firmwares. ==================== Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
commit
7752c54353
|
|
@ -9,7 +9,6 @@
|
|||
#include "ap.h"
|
||||
#include "hcmd.h"
|
||||
#include "tx.h"
|
||||
#include "power.h"
|
||||
#include "key.h"
|
||||
#include "phy.h"
|
||||
#include "iwl-utils.h"
|
||||
|
|
@ -273,9 +272,6 @@ int iwl_mld_start_ap_ibss(struct ieee80211_hw *hw,
|
|||
struct ieee80211_chanctx_conf *ctx;
|
||||
int ret;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_AP)
|
||||
iwl_mld_send_ap_tx_power_constraint_cmd(mld, vif, link);
|
||||
|
||||
ret = iwl_mld_update_beacon_template(mld, vif, link);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -1150,6 +1150,13 @@ int iwl_mld_assign_vif_chanctx(struct ieee80211_hw *hw,
|
|||
if (iwl_mld_can_activate_link(mld, vif, link)) {
|
||||
iwl_mld_tlc_update_phy(mld, vif, link);
|
||||
|
||||
/* FW requires AP_TX_POWER_CONSTRAINTS_CMD before link
|
||||
* activation for AP and after link activation for STA,
|
||||
* for an unknown reason.
|
||||
*/
|
||||
if (vif->type == NL80211_IFTYPE_AP)
|
||||
iwl_mld_send_ap_tx_power_constraint_cmd(mld, vif, link);
|
||||
|
||||
ret = iwl_mld_activate_link(mld, link);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ iwl_mld_send_ap_tx_power_constraint_cmd(struct iwl_mld *mld,
|
|||
|
||||
lockdep_assert_wiphy(mld->wiphy);
|
||||
|
||||
if (!mld_link->active)
|
||||
if (!mld_link->active && vif->type != NL80211_IFTYPE_AP)
|
||||
return;
|
||||
|
||||
if (link->chanreq.oper.chan->band != NL80211_BAND_6GHZ)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018-2025 Intel Corporation
|
||||
* Copyright (C) 2012-2014, 2018-2026 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
|
@ -459,9 +459,14 @@ static void iwl_mvm_phy_filter_init(struct iwl_mvm *mvm,
|
|||
|
||||
static void iwl_mvm_uats_init(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_mcc_allowed_ap_type_cmd_v1 *cmd __free(kfree) = NULL;
|
||||
int cmd_id = WIDE_ID(REGULATORY_AND_NVM_GROUP,
|
||||
MCC_ALLOWED_AP_TYPE_CMD);
|
||||
struct iwl_mcc_allowed_ap_type_cmd_v1 cmd = {};
|
||||
struct iwl_host_cmd hcmd = {
|
||||
.id = cmd_id,
|
||||
.len[0] = sizeof(*cmd),
|
||||
.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
|
||||
};
|
||||
u8 cmd_ver;
|
||||
int ret;
|
||||
|
||||
|
|
@ -485,14 +490,25 @@ static void iwl_mvm_uats_init(struct iwl_mvm *mvm)
|
|||
if (!mvm->fwrt.ap_type_cmd_valid)
|
||||
return;
|
||||
|
||||
BUILD_BUG_ON(sizeof(mvm->fwrt.ap_type_cmd.mcc_to_ap_type_map) !=
|
||||
sizeof(cmd.mcc_to_ap_type_map));
|
||||
/* Since we free the command immediately after iwl_mvm_send_cmd, we
|
||||
* must send this command in SYNC mode.
|
||||
*/
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
memcpy(cmd.mcc_to_ap_type_map,
|
||||
cmd = kzalloc_obj(*cmd);
|
||||
if (!cmd)
|
||||
return;
|
||||
|
||||
BUILD_BUG_ON(sizeof(mvm->fwrt.ap_type_cmd.mcc_to_ap_type_map) !=
|
||||
sizeof(cmd->mcc_to_ap_type_map));
|
||||
|
||||
memcpy(cmd->mcc_to_ap_type_map,
|
||||
mvm->fwrt.ap_type_cmd.mcc_to_ap_type_map,
|
||||
sizeof(mvm->fwrt.ap_type_cmd.mcc_to_ap_type_map));
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cmd), &cmd);
|
||||
hcmd.data[0] = cmd;
|
||||
|
||||
ret = iwl_mvm_send_cmd(mvm, &hcmd);
|
||||
if (ret < 0)
|
||||
IWL_ERR(mvm, "failed to send MCC_ALLOWED_AP_TYPE_CMD (%d)\n",
|
||||
ret);
|
||||
|
|
|
|||
|
|
@ -1416,6 +1416,12 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
|
|||
fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_FW_RESET_HANDSHAKE);
|
||||
|
||||
/* Those firmware versions claim to support the fw_reset_handshake
|
||||
* but they are buggy.
|
||||
*/
|
||||
if (IWL_UCODE_MAJOR(mvm->fw->ucode_ver) <= 77)
|
||||
trans->conf.fw_reset_handshake = false;
|
||||
|
||||
trans->conf.queue_alloc_cmd_ver =
|
||||
iwl_fw_lookup_cmd_ver(mvm->fw,
|
||||
WIDE_ID(DATA_PATH_GROUP,
|
||||
|
|
|
|||
|
|
@ -1225,33 +1225,41 @@ static int _iwl_pci_resume(struct device *device, bool restore)
|
|||
if (!trans->op_mode)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Scratch value was altered, this means the device was powered off, we
|
||||
* need to reset it completely.
|
||||
* Note: MAC (bits 0:7) will be cleared upon suspend even with wowlan,
|
||||
* but not bits [15:8]. So if we have bits set in lower word, assume
|
||||
* the device is alive.
|
||||
* Alternatively, if the scratch value is 0xFFFFFFFF, then we no longer
|
||||
* have access to the device and consider it powered off.
|
||||
* For older devices, just try silently to grab the NIC.
|
||||
*/
|
||||
if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
|
||||
u32 scratch = iwl_read32(trans, CSR_FUNC_SCRATCH);
|
||||
|
||||
if (!(scratch & CSR_FUNC_SCRATCH_POWER_OFF_MASK) ||
|
||||
scratch == ~0U)
|
||||
device_was_powered_off = true;
|
||||
} else {
|
||||
if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
|
||||
/*
|
||||
* bh are re-enabled by iwl_trans_pcie_release_nic_access,
|
||||
* so re-enable them if _iwl_trans_pcie_grab_nic_access fails.
|
||||
* Scratch value was altered, this means the device was powered
|
||||
* off, we need to reset it completely.
|
||||
* Note: MAC (bits 0:7) will be cleared upon suspend even with
|
||||
* wowlan, but not bits [15:8]. So if we have bits set in lower
|
||||
* word, assume the device is alive.
|
||||
* Alternatively, if the scratch value is 0xFFFFFFFF, then we
|
||||
* no longer have access to the device and consider it powered
|
||||
* off.
|
||||
* For older devices, just try silently to grab the NIC.
|
||||
*/
|
||||
local_bh_disable();
|
||||
if (_iwl_trans_pcie_grab_nic_access(trans, true)) {
|
||||
iwl_trans_pcie_release_nic_access(trans);
|
||||
if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
|
||||
u32 scratch = iwl_read32(trans, CSR_FUNC_SCRATCH);
|
||||
|
||||
if (!(scratch & CSR_FUNC_SCRATCH_POWER_OFF_MASK) ||
|
||||
scratch == ~0U) {
|
||||
IWL_DEBUG_WOWLAN(trans,
|
||||
"Scratch 0x%08x indicates device was powered off\n",
|
||||
scratch);
|
||||
device_was_powered_off = true;
|
||||
}
|
||||
} else {
|
||||
device_was_powered_off = true;
|
||||
local_bh_enable();
|
||||
/*
|
||||
* bh are re-enabled by iwl_trans_pcie_release_nic_access,
|
||||
* so re-enable them if _iwl_trans_pcie_grab_nic_access
|
||||
* fails.
|
||||
*/
|
||||
local_bh_disable();
|
||||
if (_iwl_trans_pcie_grab_nic_access(trans, true)) {
|
||||
iwl_trans_pcie_release_nic_access(trans);
|
||||
} else {
|
||||
device_was_powered_off = true;
|
||||
local_bh_enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user