wireless fixes for v6.12-rc6
Another set of fixes, mostly iwlwifi: * fix infinite loop in 6 GHz scan if more than 255 colocated APs were reported * revert removal of retry loops for now to work around issues with firmware initialization on some devices/platforms * fix SAR table issues with some BIOSes * fix race in suspend/debug collection * fix memory leak in fw recovery * fix link ID leak in AP mode for older devices * fix sending TX power constraints * fix link handling in FW restart And also the stack: * fix setting TX power from userspace with the new chanctx emulation code for old-style drivers * fix a memory corruption bug due to structure embedding * fix CQM configuration double-free when moving between net namespaces -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEpeA8sTs3M8SN2hR410qiO8sPaAAFAmcgnyMACgkQ10qiO8sP aAApKhAAgnQgnDXmtFYyP6qKr5tkHnY+4VcLOOUI13lGAuhIJwfMqct4204TUS+4 /3qBajSsr3n/pKjI/RQ9LtRdUHoZS+O6zVmSjAEFq8JU+Z8cZKo4teY8SfXY9pXm I/6X93o9hMCeL1+ebr4qgZVJFW9jdQnM9xJgR9lwNDViJUQT0Bn6Xfy2Crvkl2hn cnr1wU3lH261vf22X8ON+giWToyCvsQmKExGQzenSLJ1UK8bwcu9akWA7GZsjFYK Skp9q95EEFJ9V2qGAHWCivD3//rJlsXZPfwgT2QhHvvMawrb/l9pva9fk543y8Xk 9IpLa8WEiLivYk7lW4qzykrfWhNM+ubdOJVUIl23qbpI8aP/ZU3QHzIn9ZOGrBVJ yvu647OC0P/xNMHJ7jhOCAxmduqwsxKsRcnES1ZwWdQWAmHO97bSTh95+YfLsAwD 6l/PQVzeUcypeYG9rXnBkA/k8obFh8dJnIU4d96rxJdrtF7ixRiedfvx9V9tGEx4 dWu+4KVkh2W7iSXAWI/cammpU06ptzFNcjEYIGs/7xttu/riXH4fNcgm2wl+oPe7 SMaBwbGf2nTXtrqLPaVSkyM16MtSVHh9iqzYH//N357PCd1Kr9L+5xUKx1hfJ7X+ 7Z9+h9azBCQXeXz2AuWQWWynZPTSrdVLYuMNsdLJ17HAerDZJc8= =4M1T -----END PGP SIGNATURE----- Merge tag 'wireless-2024-10-29' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless Johannes Berg says: ==================== wireless fixes for v6.12-rc6 Another set of fixes, mostly iwlwifi: * fix infinite loop in 6 GHz scan if more than 255 colocated APs were reported * revert removal of retry loops for now to work around issues with firmware initialization on some devices/platforms * fix SAR table issues with some BIOSes * fix race in suspend/debug collection * fix memory leak in fw recovery * fix link ID leak in AP mode for older devices * fix sending TX power constraints * fix link handling in FW restart And also the stack: * fix setting TX power from userspace with the new chanctx emulation code for old-style drivers * fix a memory corruption bug due to structure embedding * fix CQM configuration double-free when moving between net namespaces * tag 'wireless-2024-10-29' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless: wifi: mac80211: ieee80211_i: Fix memory corruption bug in struct ieee80211_chanctx wifi: iwlwifi: mvm: fix 6 GHz scan construction wifi: cfg80211: clear wdev->cqm_config pointer on free mac80211: fix user-power when emulating chanctx Revert "wifi: iwlwifi: remove retry loops in start" wifi: iwlwifi: mvm: don't add default link in fw restart flow wifi: iwlwifi: mvm: Fix response handling in iwl_mvm_send_recovery_cmd() wifi: iwlwifi: mvm: SAR table alignment wifi: iwlwifi: mvm: Use the sync timepoint API in suspend wifi: iwlwifi: mvm: really send iwl_txpower_constraints_cmd wifi: iwlwifi: mvm: don't leak a link on AP removal ==================== Link: https://patch.msgid.link/20241029093926.13750-3-johannes@sipsolutions.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
c05c62850a
@ -429,38 +429,28 @@ out_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_acpi_sar_set_profile(union acpi_object *table,
|
||||
struct iwl_sar_profile *profile,
|
||||
bool enabled, u8 num_chains,
|
||||
u8 num_sub_bands)
|
||||
static int
|
||||
iwl_acpi_parse_chains_table(union acpi_object *table,
|
||||
struct iwl_sar_profile_chain *chains,
|
||||
u8 num_chains, u8 num_sub_bands)
|
||||
{
|
||||
int i, j, idx = 0;
|
||||
|
||||
/*
|
||||
* The table from ACPI is flat, but we store it in a
|
||||
* structured array.
|
||||
*/
|
||||
for (i = 0; i < BIOS_SAR_MAX_CHAINS_PER_PROFILE; i++) {
|
||||
for (j = 0; j < BIOS_SAR_MAX_SUB_BANDS_NUM; j++) {
|
||||
for (u8 chain = 0; chain < num_chains; chain++) {
|
||||
for (u8 subband = 0; subband < BIOS_SAR_MAX_SUB_BANDS_NUM;
|
||||
subband++) {
|
||||
/* if we don't have the values, use the default */
|
||||
if (i >= num_chains || j >= num_sub_bands) {
|
||||
profile->chains[i].subbands[j] = 0;
|
||||
if (subband >= num_sub_bands) {
|
||||
chains[chain].subbands[subband] = 0;
|
||||
} else if (table->type != ACPI_TYPE_INTEGER ||
|
||||
table->integer.value > U8_MAX) {
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (table[idx].type != ACPI_TYPE_INTEGER ||
|
||||
table[idx].integer.value > U8_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
profile->chains[i].subbands[j] =
|
||||
table[idx].integer.value;
|
||||
|
||||
idx++;
|
||||
chains[chain].subbands[subband] =
|
||||
table->integer.value;
|
||||
table++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Only if all values were valid can the profile be enabled */
|
||||
profile->enabled = enabled;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -543,9 +533,11 @@ read_table:
|
||||
/* The profile from WRDS is officially profile 1, but goes
|
||||
* into sar_profiles[0] (because we don't have a profile 0).
|
||||
*/
|
||||
ret = iwl_acpi_sar_set_profile(table, &fwrt->sar_profiles[0],
|
||||
flags & IWL_SAR_ENABLE_MSK,
|
||||
num_chains, num_sub_bands);
|
||||
ret = iwl_acpi_parse_chains_table(table, fwrt->sar_profiles[0].chains,
|
||||
num_chains, num_sub_bands);
|
||||
if (!ret && flags & IWL_SAR_ENABLE_MSK)
|
||||
fwrt->sar_profiles[0].enabled = true;
|
||||
|
||||
out_free:
|
||||
kfree(data);
|
||||
return ret;
|
||||
@ -557,7 +549,7 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
|
||||
bool enabled;
|
||||
int i, n_profiles, tbl_rev, pos;
|
||||
int ret = 0;
|
||||
u8 num_chains, num_sub_bands;
|
||||
u8 num_sub_bands;
|
||||
|
||||
data = iwl_acpi_get_object(fwrt->dev, ACPI_EWRD_METHOD);
|
||||
if (IS_ERR(data))
|
||||
@ -573,7 +565,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
num_chains = ACPI_SAR_NUM_CHAINS_REV2;
|
||||
num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV2;
|
||||
|
||||
goto read_table;
|
||||
@ -589,7 +580,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
num_chains = ACPI_SAR_NUM_CHAINS_REV1;
|
||||
num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV1;
|
||||
|
||||
goto read_table;
|
||||
@ -605,7 +595,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
num_chains = ACPI_SAR_NUM_CHAINS_REV0;
|
||||
num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV0;
|
||||
|
||||
goto read_table;
|
||||
@ -637,23 +626,54 @@ read_table:
|
||||
/* the tables start at element 3 */
|
||||
pos = 3;
|
||||
|
||||
BUILD_BUG_ON(ACPI_SAR_NUM_CHAINS_REV0 != ACPI_SAR_NUM_CHAINS_REV1);
|
||||
BUILD_BUG_ON(ACPI_SAR_NUM_CHAINS_REV2 != 2 * ACPI_SAR_NUM_CHAINS_REV0);
|
||||
|
||||
/* parse non-cdb chains for all profiles */
|
||||
for (i = 0; i < n_profiles; i++) {
|
||||
union acpi_object *table = &wifi_pkg->package.elements[pos];
|
||||
|
||||
/* The EWRD profiles officially go from 2 to 4, but we
|
||||
* save them in sar_profiles[1-3] (because we don't
|
||||
* have profile 0). So in the array we start from 1.
|
||||
*/
|
||||
ret = iwl_acpi_sar_set_profile(table,
|
||||
&fwrt->sar_profiles[i + 1],
|
||||
enabled, num_chains,
|
||||
num_sub_bands);
|
||||
ret = iwl_acpi_parse_chains_table(table,
|
||||
fwrt->sar_profiles[i + 1].chains,
|
||||
ACPI_SAR_NUM_CHAINS_REV0,
|
||||
num_sub_bands);
|
||||
if (ret < 0)
|
||||
break;
|
||||
goto out_free;
|
||||
|
||||
/* go to the next table */
|
||||
pos += num_chains * num_sub_bands;
|
||||
pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands;
|
||||
}
|
||||
|
||||
/* non-cdb table revisions */
|
||||
if (tbl_rev < 2)
|
||||
goto set_enabled;
|
||||
|
||||
/* parse cdb chains for all profiles */
|
||||
for (i = 0; i < n_profiles; i++) {
|
||||
struct iwl_sar_profile_chain *chains;
|
||||
union acpi_object *table;
|
||||
|
||||
table = &wifi_pkg->package.elements[pos];
|
||||
chains = &fwrt->sar_profiles[i + 1].chains[ACPI_SAR_NUM_CHAINS_REV0];
|
||||
ret = iwl_acpi_parse_chains_table(table,
|
||||
chains,
|
||||
ACPI_SAR_NUM_CHAINS_REV0,
|
||||
num_sub_bands);
|
||||
if (ret < 0)
|
||||
goto out_free;
|
||||
|
||||
/* go to the next table */
|
||||
pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands;
|
||||
}
|
||||
|
||||
set_enabled:
|
||||
for (i = 0; i < n_profiles; i++)
|
||||
fwrt->sar_profiles[i + 1].enabled = enabled;
|
||||
|
||||
out_free:
|
||||
kfree(data);
|
||||
return ret;
|
||||
|
@ -39,10 +39,12 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
|
||||
|
||||
/* Assumes the appropriate lock is held by the caller */
|
||||
void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
iwl_fw_suspend_timestamp(fwrt);
|
||||
iwl_dbg_tlv_time_point(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START, NULL);
|
||||
iwl_dbg_tlv_time_point_sync(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START,
|
||||
NULL);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend);
|
||||
|
||||
|
@ -1413,26 +1413,36 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op)
|
||||
const struct iwl_op_mode_ops *ops = op->ops;
|
||||
struct dentry *dbgfs_dir = NULL;
|
||||
struct iwl_op_mode *op_mode = NULL;
|
||||
int retry, max_retry = !!iwlwifi_mod_params.fw_restart * IWL_MAX_INIT_RETRY;
|
||||
|
||||
/* also protects start/stop from racing against each other */
|
||||
lockdep_assert_held(&iwlwifi_opmode_table_mtx);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
drv->dbgfs_op_mode = debugfs_create_dir(op->name,
|
||||
drv->dbgfs_drv);
|
||||
dbgfs_dir = drv->dbgfs_op_mode;
|
||||
#endif
|
||||
|
||||
op_mode = ops->start(drv->trans, drv->trans->cfg,
|
||||
&drv->fw, dbgfs_dir);
|
||||
if (op_mode)
|
||||
return op_mode;
|
||||
for (retry = 0; retry <= max_retry; retry++) {
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
debugfs_remove_recursive(drv->dbgfs_op_mode);
|
||||
drv->dbgfs_op_mode = NULL;
|
||||
drv->dbgfs_op_mode = debugfs_create_dir(op->name,
|
||||
drv->dbgfs_drv);
|
||||
dbgfs_dir = drv->dbgfs_op_mode;
|
||||
#endif
|
||||
|
||||
op_mode = ops->start(drv->trans, drv->trans->cfg,
|
||||
&drv->fw, dbgfs_dir);
|
||||
|
||||
if (op_mode)
|
||||
return op_mode;
|
||||
|
||||
if (test_bit(STATUS_TRANS_DEAD, &drv->trans->status))
|
||||
break;
|
||||
|
||||
IWL_ERR(drv, "retry init count %d\n", retry);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
debugfs_remove_recursive(drv->dbgfs_op_mode);
|
||||
drv->dbgfs_op_mode = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,9 @@ void iwl_drv_stop(struct iwl_drv *drv);
|
||||
#define VISIBLE_IF_IWLWIFI_KUNIT static
|
||||
#endif
|
||||
|
||||
/* max retry for init flow */
|
||||
#define IWL_MAX_INIT_RETRY 2
|
||||
|
||||
#define FW_NAME_PRE_BUFSIZE 64
|
||||
struct iwl_trans;
|
||||
const char *iwl_drv_get_fwname_pre(struct iwl_trans *trans, char *buf);
|
||||
|
@ -1398,7 +1398,9 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
||||
|
||||
iwl_mvm_pause_tcm(mvm, true);
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
iwl_fw_runtime_suspend(&mvm->fwrt);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return __iwl_mvm_suspend(hw, wowlan, false);
|
||||
}
|
||||
|
@ -1307,8 +1307,8 @@ static void iwl_mvm_disconnect_iterator(void *data, u8 *mac,
|
||||
void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
|
||||
{
|
||||
u32 error_log_size = mvm->fw->ucode_capa.error_log_size;
|
||||
u32 status = 0;
|
||||
int ret;
|
||||
u32 resp;
|
||||
|
||||
struct iwl_fw_error_recovery_cmd recovery_cmd = {
|
||||
.flags = cpu_to_le32(flags),
|
||||
@ -1316,7 +1316,6 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
|
||||
};
|
||||
struct iwl_host_cmd host_cmd = {
|
||||
.id = WIDE_ID(SYSTEM_GROUP, FW_ERROR_RECOVERY_CMD),
|
||||
.flags = CMD_WANT_SKB,
|
||||
.data = {&recovery_cmd, },
|
||||
.len = {sizeof(recovery_cmd), },
|
||||
};
|
||||
@ -1336,7 +1335,7 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
|
||||
recovery_cmd.buf_size = cpu_to_le32(error_log_size);
|
||||
}
|
||||
|
||||
ret = iwl_mvm_send_cmd(mvm, &host_cmd);
|
||||
ret = iwl_mvm_send_cmd_status(mvm, &host_cmd, &status);
|
||||
kfree(mvm->error_recovery_buf);
|
||||
mvm->error_recovery_buf = NULL;
|
||||
|
||||
@ -1347,11 +1346,10 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
|
||||
|
||||
/* skb respond is only relevant in ERROR_RECOVERY_UPDATE_DB */
|
||||
if (flags & ERROR_RECOVERY_UPDATE_DB) {
|
||||
resp = le32_to_cpu(*(__le32 *)host_cmd.resp_pkt->data);
|
||||
if (resp) {
|
||||
if (status) {
|
||||
IWL_ERR(mvm,
|
||||
"Failed to send recovery cmd blob was invalid %d\n",
|
||||
resp);
|
||||
status);
|
||||
|
||||
ieee80211_iterate_interfaces(mvm->hw, 0,
|
||||
iwl_mvm_disconnect_iterator,
|
||||
|
@ -1293,12 +1293,14 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
int ret;
|
||||
int retry, max_retry = 0;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
/* we are starting the mac not in error flow, and restart is enabled */
|
||||
if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) &&
|
||||
iwlwifi_mod_params.fw_restart) {
|
||||
max_retry = IWL_MAX_INIT_RETRY;
|
||||
/*
|
||||
* This will prevent mac80211 recovery flows to trigger during
|
||||
* init failures
|
||||
@ -1306,7 +1308,13 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw)
|
||||
set_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
|
||||
}
|
||||
|
||||
ret = __iwl_mvm_mac_start(mvm);
|
||||
for (retry = 0; retry <= max_retry; retry++) {
|
||||
ret = __iwl_mvm_mac_start(mvm);
|
||||
if (!ret)
|
||||
break;
|
||||
|
||||
IWL_ERR(mvm, "mac start retry %d\n", retry);
|
||||
}
|
||||
clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
@ -1970,7 +1978,6 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
|
||||
mvm->p2p_device_vif = NULL;
|
||||
}
|
||||
|
||||
iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf);
|
||||
iwl_mvm_mac_ctxt_remove(mvm, vif);
|
||||
|
||||
RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL);
|
||||
@ -1979,6 +1986,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
|
||||
mvm->monitor_on = false;
|
||||
|
||||
out:
|
||||
iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf);
|
||||
if (vif->type == NL80211_IFTYPE_AP ||
|
||||
vif->type == NL80211_IFTYPE_ADHOC) {
|
||||
iwl_mvm_dealloc_int_sta(mvm, &mvmvif->deflink.mcast_sta);
|
||||
|
@ -41,8 +41,6 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw,
|
||||
/* reset deflink MLO parameters */
|
||||
mvmvif->deflink.fw_link_id = IWL_MVM_FW_LINK_ID_INVALID;
|
||||
mvmvif->deflink.active = 0;
|
||||
/* the first link always points to the default one */
|
||||
mvmvif->link[0] = &mvmvif->deflink;
|
||||
|
||||
ret = iwl_mvm_mld_mac_ctxt_add(mvm, vif);
|
||||
if (ret)
|
||||
@ -60,9 +58,19 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw,
|
||||
IEEE80211_VIF_SUPPORTS_CQM_RSSI;
|
||||
}
|
||||
|
||||
ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf);
|
||||
if (ret)
|
||||
goto out_free_bf;
|
||||
/* We want link[0] to point to the default link, unless we have MLO and
|
||||
* in this case this will be modified later by .change_vif_links()
|
||||
* If we are in the restart flow with an MLD connection, we will wait
|
||||
* to .change_vif_links() to setup the links.
|
||||
*/
|
||||
if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) ||
|
||||
!ieee80211_vif_is_mld(vif)) {
|
||||
mvmvif->link[0] = &mvmvif->deflink;
|
||||
|
||||
ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf);
|
||||
if (ret)
|
||||
goto out_free_bf;
|
||||
}
|
||||
|
||||
/* Save a pointer to p2p device vif, so it can later be used to
|
||||
* update the p2p device MAC when a GO is started/stopped
|
||||
@ -350,11 +358,6 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif,
|
||||
link_conf,
|
||||
false);
|
||||
|
||||
/* then activate */
|
||||
ret = iwl_mvm_link_changed(mvm, vif, link_conf,
|
||||
LINK_CONTEXT_MODIFY_ACTIVE |
|
||||
@ -363,6 +366,11 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif,
|
||||
link_conf,
|
||||
false);
|
||||
|
||||
/*
|
||||
* Power state must be updated before quotas,
|
||||
* otherwise fw will complain.
|
||||
@ -1194,7 +1202,11 @@ iwl_mvm_mld_change_vif_links(struct ieee80211_hw *hw,
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
if (old_links == 0) {
|
||||
/* If we're in RESTART flow, the default link wasn't added in
|
||||
* drv_add_interface(), and link[0] doesn't point to it.
|
||||
*/
|
||||
if (old_links == 0 && !test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
|
||||
&mvm->status)) {
|
||||
err = iwl_mvm_disable_link(mvm, vif, &vif->bss_conf);
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
@ -1774,7 +1774,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
|
||||
&cp->channel_config[ch_cnt];
|
||||
|
||||
u32 s_ssid_bitmap = 0, bssid_bitmap = 0, flags = 0;
|
||||
u8 j, k, n_s_ssids = 0, n_bssids = 0;
|
||||
u8 k, n_s_ssids = 0, n_bssids = 0;
|
||||
u8 max_s_ssids, max_bssids;
|
||||
bool force_passive = false, found = false, allow_passive = true,
|
||||
unsolicited_probe_on_chan = false, psc_no_listen = false;
|
||||
@ -1799,7 +1799,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
|
||||
cfg->v5.iter_count = 1;
|
||||
cfg->v5.iter_interval = 0;
|
||||
|
||||
for (j = 0; j < params->n_6ghz_params; j++) {
|
||||
for (u32 j = 0; j < params->n_6ghz_params; j++) {
|
||||
s8 tmp_psd_20;
|
||||
|
||||
if (!(scan_6ghz_params[j].channel_idx == i))
|
||||
@ -1873,7 +1873,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
|
||||
* SSID.
|
||||
* TODO: improve this logic
|
||||
*/
|
||||
for (j = 0; j < params->n_6ghz_params; j++) {
|
||||
for (u32 j = 0; j < params->n_6ghz_params; j++) {
|
||||
if (!(scan_6ghz_params[j].channel_idx == i))
|
||||
continue;
|
||||
|
||||
|
@ -892,9 +892,10 @@ struct ieee80211_chanctx {
|
||||
/* temporary data for search algorithm etc. */
|
||||
struct ieee80211_chan_req req;
|
||||
|
||||
struct ieee80211_chanctx_conf conf;
|
||||
|
||||
bool radar_detected;
|
||||
|
||||
/* MUST be last - ends in a flexible-array member. */
|
||||
struct ieee80211_chanctx_conf conf;
|
||||
};
|
||||
|
||||
struct mac80211_qos_map {
|
||||
|
@ -167,6 +167,8 @@ static u32 ieee80211_calc_hw_conf_chan(struct ieee80211_local *local,
|
||||
}
|
||||
|
||||
power = ieee80211_chandef_max_power(&chandef);
|
||||
if (local->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
|
||||
power = min(local->user_power_level, power);
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
|
@ -1236,6 +1236,7 @@ static void _cfg80211_unregister_wdev(struct wireless_dev *wdev,
|
||||
/* deleted from the list, so can't be found from nl80211 any more */
|
||||
cqm_config = rcu_access_pointer(wdev->cqm_config);
|
||||
kfree_rcu(cqm_config, rcu_head);
|
||||
RCU_INIT_POINTER(wdev->cqm_config, NULL);
|
||||
|
||||
/*
|
||||
* Ensure that all events have been processed and
|
||||
|
Loading…
Reference in New Issue
Block a user