mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 11:03:43 +02:00
wifi: iwlwifi: fixes - 2026-03-24
- Fix MLO scan timing (record the scan start in FW) - don't send a 6E related command when not supported - correctly set wifi generation data -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQQM3A3Pv7vbm9vtjWbacY7uyt+OfQUCacJ9dQAKCRDacY7uyt+O fUJjAQCq86IUYN2b3UuYnN2yD3wq/HgqL1BdiMnCnu7HdeUQjAD/RDMpK9CThJqI CsRZ3Uy6jEJTjg1o2eRBxmQhy2ouCAw= =q/o0 -----END PGP SIGNATURE----- Merge tag 'iwlwifi-fixes-2026-03-24' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next Miri Korenblit says: ==================== wifi: iwlwifi: fixes - 2026-03-24 - Fix MLO scan timing (record the scan start in FW) - don't send a 6E related command when not supported - correctly set wifi generation data ==================== Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
commit
249ddd5fe2
|
|
@ -296,6 +296,11 @@ enum iwl_legacy_cmds {
|
|||
*/
|
||||
SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E,
|
||||
|
||||
/**
|
||||
* @SCAN_START_NOTIFICATION_UMAC: uses &struct iwl_umac_scan_start
|
||||
*/
|
||||
SCAN_START_NOTIFICATION_UMAC = 0xb2,
|
||||
|
||||
/**
|
||||
* @MATCH_FOUND_NOTIFICATION: scan match found
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1156,6 +1156,16 @@ enum iwl_umac_scan_abort_status {
|
|||
IWL_UMAC_SCAN_ABORT_STATUS_NOT_FOUND,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_umac_scan_start - scan start notification
|
||||
* @uid: scan id, &enum iwl_umac_scan_uid_offsets
|
||||
* @reserved: for future use
|
||||
*/
|
||||
struct iwl_umac_scan_start {
|
||||
__le32 uid;
|
||||
__le32 reserved;
|
||||
} __packed; /* SCAN_START_UMAC_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_umac_scan_complete - scan complete notification
|
||||
* @uid: scan id, &enum iwl_umac_scan_uid_offsets
|
||||
|
|
|
|||
|
|
@ -111,14 +111,75 @@ static bool iwl_mld_is_nic_ack_enabled(struct iwl_mld *mld,
|
|||
IEEE80211_HE_MAC_CAP2_ACK_EN);
|
||||
}
|
||||
|
||||
static void iwl_mld_set_he_support(struct iwl_mld *mld,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_mac_config_cmd *cmd)
|
||||
struct iwl_mld_mac_wifi_gen_sta_iter_data {
|
||||
struct ieee80211_vif *vif;
|
||||
struct iwl_mac_wifi_gen_support *support;
|
||||
};
|
||||
|
||||
static void iwl_mld_mac_wifi_gen_sta_iter(void *_data,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
if (vif->type == NL80211_IFTYPE_AP)
|
||||
cmd->wifi_gen.he_ap_support = 1;
|
||||
else
|
||||
cmd->wifi_gen.he_support = 1;
|
||||
struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
|
||||
struct iwl_mld_mac_wifi_gen_sta_iter_data *data = _data;
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
unsigned int link_id;
|
||||
|
||||
if (mld_sta->vif != data->vif)
|
||||
return;
|
||||
|
||||
for_each_sta_active_link(data->vif, sta, link_sta, link_id) {
|
||||
if (link_sta->he_cap.has_he)
|
||||
data->support->he_support = 1;
|
||||
if (link_sta->eht_cap.has_eht)
|
||||
data->support->eht_support = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void iwl_mld_set_wifi_gen(struct iwl_mld *mld,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_mac_wifi_gen_support *support)
|
||||
{
|
||||
struct iwl_mld_mac_wifi_gen_sta_iter_data sta_iter_data = {
|
||||
.vif = vif,
|
||||
.support = support,
|
||||
};
|
||||
struct ieee80211_bss_conf *link_conf;
|
||||
unsigned int link_id;
|
||||
|
||||
switch (vif->type) {
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
/* for sniffer, set to HW capabilities */
|
||||
support->he_support = 1;
|
||||
support->eht_support = mld->trans->cfg->eht_supported;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
/* for AP set according to the link configs */
|
||||
for_each_vif_active_link(vif, link_conf, link_id) {
|
||||
support->he_ap_support |= link_conf->he_support;
|
||||
support->eht_support |= link_conf->eht_support;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* If we have MLO enabled, then the firmware needs to enable
|
||||
* address translation for the station(s) we add. That depends
|
||||
* on having EHT enabled in firmware, which in turn depends on
|
||||
* mac80211 in the iteration below.
|
||||
* However, mac80211 doesn't enable capabilities on the AP STA
|
||||
* until it has parsed the association response successfully,
|
||||
* so set EHT (and HE as a pre-requisite for EHT) when the vif
|
||||
* is an MLD.
|
||||
*/
|
||||
if (ieee80211_vif_is_mld(vif)) {
|
||||
support->he_support = 1;
|
||||
support->eht_support = 1;
|
||||
}
|
||||
|
||||
ieee80211_iterate_stations_mtx(mld->hw,
|
||||
iwl_mld_mac_wifi_gen_sta_iter,
|
||||
&sta_iter_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill the common part for all interface types */
|
||||
|
|
@ -128,8 +189,6 @@ static void iwl_mld_mac_cmd_fill_common(struct iwl_mld *mld,
|
|||
u32 action)
|
||||
{
|
||||
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
|
||||
struct ieee80211_bss_conf *link_conf;
|
||||
unsigned int link_id;
|
||||
|
||||
lockdep_assert_wiphy(mld->wiphy);
|
||||
|
||||
|
|
@ -147,29 +206,7 @@ static void iwl_mld_mac_cmd_fill_common(struct iwl_mld *mld,
|
|||
cmd->nic_not_ack_enabled =
|
||||
cpu_to_le32(!iwl_mld_is_nic_ack_enabled(mld, vif));
|
||||
|
||||
/* If we have MLO enabled, then the firmware needs to enable
|
||||
* address translation for the station(s) we add. That depends
|
||||
* on having EHT enabled in firmware, which in turn depends on
|
||||
* mac80211 in the code below.
|
||||
* However, mac80211 doesn't enable HE/EHT until it has parsed
|
||||
* the association response successfully, so just skip all that
|
||||
* and enable both when we have MLO.
|
||||
*/
|
||||
if (ieee80211_vif_is_mld(vif)) {
|
||||
iwl_mld_set_he_support(mld, vif, cmd);
|
||||
cmd->wifi_gen.eht_support = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
for_each_vif_active_link(vif, link_conf, link_id) {
|
||||
if (!link_conf->he_support)
|
||||
continue;
|
||||
|
||||
iwl_mld_set_he_support(mld, vif, cmd);
|
||||
|
||||
/* EHT, if supported, was already set above */
|
||||
break;
|
||||
}
|
||||
iwl_mld_set_wifi_gen(mld, vif, &cmd->wifi_gen);
|
||||
}
|
||||
|
||||
static void iwl_mld_fill_mac_cmd_sta(struct iwl_mld *mld,
|
||||
|
|
|
|||
|
|
@ -1761,6 +1761,16 @@ static int iwl_mld_move_sta_state_up(struct iwl_mld *mld,
|
|||
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
iwl_mld_link_set_2mhz_block(mld, vif, sta);
|
||||
|
||||
if (sta->tdls) {
|
||||
/*
|
||||
* update MAC since wifi generation flags may change,
|
||||
* we also update MAC on association to the AP via the
|
||||
* vif assoc change
|
||||
*/
|
||||
iwl_mld_mac_fw_action(mld, vif, FW_CTXT_ACTION_MODIFY);
|
||||
}
|
||||
|
||||
/* Now the link_sta's capabilities are set, update the FW */
|
||||
iwl_mld_config_tlc(mld, vif, sta);
|
||||
|
||||
|
|
@ -1873,6 +1883,15 @@ static int iwl_mld_move_sta_state_down(struct iwl_mld *mld,
|
|||
/* just removed last TDLS STA, so enable PM */
|
||||
iwl_mld_update_mac_power(mld, vif, false);
|
||||
}
|
||||
|
||||
if (sta->tdls) {
|
||||
/*
|
||||
* update MAC since wifi generation flags may change,
|
||||
* we also update MAC on disassociation to the AP via
|
||||
* the vif assoc change
|
||||
*/
|
||||
iwl_mld_mac_fw_action(mld, vif, FW_CTXT_ACTION_MODIFY);
|
||||
}
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ static const struct iwl_hcmd_names iwl_mld_legacy_names[] = {
|
|||
HCMD_NAME(MISSED_BEACONS_NOTIFICATION),
|
||||
HCMD_NAME(MAC_PM_POWER_TABLE),
|
||||
HCMD_NAME(MFUART_LOAD_NOTIFICATION),
|
||||
HCMD_NAME(SCAN_START_NOTIFICATION_UMAC),
|
||||
HCMD_NAME(RSS_CONFIG_CMD),
|
||||
HCMD_NAME(SCAN_ITERATION_COMPLETE_UMAC),
|
||||
HCMD_NAME(REPLY_RX_MPDU_CMD),
|
||||
|
|
|
|||
|
|
@ -739,7 +739,7 @@ iwl_mld_set_link_sel_data(struct iwl_mld *mld,
|
|||
|
||||
/* Ignore any BSS that was not seen in the last MLO scan */
|
||||
if (ktime_before(link_conf->bss->ts_boottime,
|
||||
mld->scan.last_mlo_scan_time))
|
||||
mld->scan.last_mlo_scan_start_time))
|
||||
continue;
|
||||
|
||||
data[n_data].link_id = link_id;
|
||||
|
|
@ -945,7 +945,7 @@ static void _iwl_mld_select_links(struct iwl_mld *mld,
|
|||
if (!mld_vif->authorized || hweight16(usable_links) <= 1)
|
||||
return;
|
||||
|
||||
if (WARN(ktime_before(mld->scan.last_mlo_scan_time,
|
||||
if (WARN(ktime_before(mld->scan.last_mlo_scan_start_time,
|
||||
ktime_sub_ns(ktime_get_boottime_ns(),
|
||||
5ULL * NSEC_PER_SEC)),
|
||||
"Last MLO scan was too long ago, can't select links\n"))
|
||||
|
|
|
|||
|
|
@ -287,6 +287,8 @@ static void iwl_mld_handle_beacon_notification(struct iwl_mld *mld,
|
|||
* at least enough bytes to cover the structure listed in the CMD_VER_ENTRY.
|
||||
*/
|
||||
|
||||
CMD_VERSIONS(scan_start_notif,
|
||||
CMD_VER_ENTRY(1, iwl_umac_scan_start))
|
||||
CMD_VERSIONS(scan_complete_notif,
|
||||
CMD_VER_ENTRY(1, iwl_umac_scan_complete))
|
||||
CMD_VERSIONS(scan_iter_complete_notif,
|
||||
|
|
@ -360,6 +362,7 @@ DEFINE_SIMPLE_CANCELLATION(datapath_monitor, iwl_datapath_monitor_notif,
|
|||
link_id)
|
||||
DEFINE_SIMPLE_CANCELLATION(roc, iwl_roc_notif, activity)
|
||||
DEFINE_SIMPLE_CANCELLATION(scan_complete, iwl_umac_scan_complete, uid)
|
||||
DEFINE_SIMPLE_CANCELLATION(scan_start, iwl_umac_scan_start, uid)
|
||||
DEFINE_SIMPLE_CANCELLATION(probe_resp_data, iwl_probe_resp_data_notif,
|
||||
mac_id)
|
||||
DEFINE_SIMPLE_CANCELLATION(uapsd_misbehaving_ap, iwl_uapsd_misbehaving_ap_notif,
|
||||
|
|
@ -402,6 +405,8 @@ const struct iwl_rx_handler iwl_mld_rx_handlers[] = {
|
|||
RX_HANDLER_SYNC)
|
||||
RX_HANDLER_NO_OBJECT(LEGACY_GROUP, BA_NOTIF, compressed_ba_notif,
|
||||
RX_HANDLER_SYNC)
|
||||
RX_HANDLER_OF_SCAN(LEGACY_GROUP, SCAN_START_NOTIFICATION_UMAC,
|
||||
scan_start_notif)
|
||||
RX_HANDLER_OF_SCAN(LEGACY_GROUP, SCAN_COMPLETE_UMAC,
|
||||
scan_complete_notif)
|
||||
RX_HANDLER_NO_OBJECT(LEGACY_GROUP, SCAN_ITERATION_COMPLETE_UMAC,
|
||||
|
|
|
|||
|
|
@ -473,6 +473,9 @@ iwl_mld_scan_get_cmd_gen_flags(struct iwl_mld *mld,
|
|||
params->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ)
|
||||
flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN;
|
||||
|
||||
if (scan_status == IWL_MLD_SCAN_INT_MLO)
|
||||
flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_NTF_START;
|
||||
|
||||
if (params->enable_6ghz_passive)
|
||||
flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN;
|
||||
|
||||
|
|
@ -1817,9 +1820,6 @@ static void iwl_mld_int_mlo_scan_start(struct iwl_mld *mld,
|
|||
ret = _iwl_mld_single_scan_start(mld, vif, req, &ies,
|
||||
IWL_MLD_SCAN_INT_MLO);
|
||||
|
||||
if (!ret)
|
||||
mld->scan.last_mlo_scan_time = ktime_get_boottime_ns();
|
||||
|
||||
IWL_DEBUG_SCAN(mld, "Internal MLO scan: ret=%d\n", ret);
|
||||
}
|
||||
|
||||
|
|
@ -1904,6 +1904,30 @@ void iwl_mld_handle_match_found_notif(struct iwl_mld *mld,
|
|||
ieee80211_sched_scan_results(mld->hw);
|
||||
}
|
||||
|
||||
void iwl_mld_handle_scan_start_notif(struct iwl_mld *mld,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
struct iwl_umac_scan_complete *notif = (void *)pkt->data;
|
||||
u32 uid = le32_to_cpu(notif->uid);
|
||||
|
||||
if (IWL_FW_CHECK(mld, uid >= ARRAY_SIZE(mld->scan.uid_status),
|
||||
"FW reports out-of-range scan UID %d\n", uid))
|
||||
return;
|
||||
|
||||
if (IWL_FW_CHECK(mld, !(mld->scan.uid_status[uid] & mld->scan.status),
|
||||
"FW reports scan UID %d we didn't trigger\n", uid))
|
||||
return;
|
||||
|
||||
IWL_DEBUG_SCAN(mld, "Scan started: uid=%u type=%u\n", uid,
|
||||
mld->scan.uid_status[uid]);
|
||||
if (IWL_FW_CHECK(mld, mld->scan.uid_status[uid] != IWL_MLD_SCAN_INT_MLO,
|
||||
"FW reports scan start notification %d we didn't trigger\n",
|
||||
mld->scan.uid_status[uid]))
|
||||
return;
|
||||
|
||||
mld->scan.last_mlo_scan_start_time = ktime_get_boottime_ns();
|
||||
}
|
||||
|
||||
void iwl_mld_handle_scan_complete_notif(struct iwl_mld *mld,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ int iwl_mld_sched_scan_start(struct iwl_mld *mld,
|
|||
void iwl_mld_handle_match_found_notif(struct iwl_mld *mld,
|
||||
struct iwl_rx_packet *pkt);
|
||||
|
||||
void iwl_mld_handle_scan_start_notif(struct iwl_mld *mld,
|
||||
struct iwl_rx_packet *pkt);
|
||||
|
||||
void iwl_mld_handle_scan_complete_notif(struct iwl_mld *mld,
|
||||
struct iwl_rx_packet *pkt);
|
||||
|
||||
|
|
@ -114,8 +117,8 @@ enum iwl_mld_traffic_load {
|
|||
* in jiffies.
|
||||
* @last_start_time_jiffies: stores the last start time in jiffies
|
||||
* (interface up/reset/resume).
|
||||
* @last_mlo_scan_time: start time of the last MLO scan in nanoseconds since
|
||||
* boot.
|
||||
* @last_mlo_scan_start_time: start time of the last MLO scan in nanoseconds
|
||||
* since boot.
|
||||
*/
|
||||
struct iwl_mld_scan {
|
||||
/* Add here fields that need clean up on restart */
|
||||
|
|
@ -136,7 +139,7 @@ struct iwl_mld_scan {
|
|||
void *cmd;
|
||||
unsigned long last_6ghz_passive_jiffies;
|
||||
unsigned long last_start_time_jiffies;
|
||||
u64 last_mlo_scan_time;
|
||||
u64 last_mlo_scan_start_time;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -470,7 +470,8 @@ static void iwl_mvm_uats_init(struct iwl_mvm *mvm)
|
|||
.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
|
||||
};
|
||||
|
||||
if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) {
|
||||
if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210 ||
|
||||
!mvm->trans->cfg->uhb_supported) {
|
||||
IWL_DEBUG_RADIO(mvm, "UATS feature is not supported\n");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user