From bde2f9b420f69297455df7fb68792e486c04a9b4 Mon Sep 17 00:00:00 2001 From: Mukesh Sisodiya Date: Tue, 16 Apr 2024 13:53:57 +0300 Subject: wifi: iwlwifi: mvm: send ap_tx_power_constraints cmd to FW in AP mode Send AP_TX_POWER_CONSTRAINTS_CMD with no local maximum transmit power constraint to FW and FW will update the TPE element with required tx power limits. Signed-off-by: Mukesh Sisodiya Signed-off-by: Miri Korenblit Link: https://msgid.link/20240416134215.b6af4ecfcfe8.I07e8db349190e0c58c468c18477d8551288ac069@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ops.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index a93981cb9714..5cdad4dfa699 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -586,6 +586,7 @@ static const struct iwl_hcmd_names iwl_mvm_phy_names[] = { HCMD_NAME(CTDP_CONFIG_CMD), HCMD_NAME(TEMP_REPORTING_THRESHOLDS_CMD), HCMD_NAME(PER_CHAIN_LIMIT_OFFSET_CMD), + HCMD_NAME(AP_TX_POWER_CONSTRAINTS_CMD), HCMD_NAME(CT_KILL_NOTIFICATION), HCMD_NAME(DTS_MEASUREMENT_NOTIF_WIDE), }; -- cgit v1.2.3 From 07bf5297d392069021055800ef48a1106a5c85b5 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Tue, 16 Apr 2024 13:54:03 +0300 Subject: wifi: iwlwifi: mvm: Implement new link selection algorithm Replaces the current logic with a new algorithm based on the link grading introduced in a previous patch. The new selection algorithm will be invoked upon successful scan to ensure it has the necessary updated data it needs. This update delegates the selection logic as the primary link determiner in EMLSR mode, storing it in mvmvif to avoid repeated calculations, as the result may vary. Additionally, includes tests for iwl_mvm_valid_link_pair to validate link pairs for EMLSR. Signed-off-by: Miri Korenblit Reviewed-by: Johannes Berg Link: https://msgid.link/20240416134215.309fb1b3fe44.I5baf0c293c89a5a28bd1a6386bf9ca6d2bf61ab8@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ops.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 5cdad4dfa699..7b70248c6090 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -365,7 +365,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { iwl_mvm_rx_scan_match_found, RX_HANDLER_SYNC), RX_HANDLER(SCAN_COMPLETE_UMAC, iwl_mvm_rx_umac_scan_complete_notif, - RX_HANDLER_ASYNC_LOCKED, struct iwl_umac_scan_complete), + RX_HANDLER_ASYNC_LOCKED_WIPHY, + struct iwl_umac_scan_complete), RX_HANDLER(SCAN_ITERATION_COMPLETE_UMAC, iwl_mvm_rx_umac_scan_iter_complete_notif, RX_HANDLER_SYNC, struct iwl_umac_scan_iter_complete_notif), -- cgit v1.2.3 From 48ac6c8ed719478ab8b3035406319c7c98a8f134 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Tue, 16 Apr 2024 13:54:06 +0300 Subject: wifi: iwlwifi: mvm: exit EMLSR upon missed beacon In case of more than 6 missed beacons on one of the links, exit EMLSR by deactivating that link. Signed-off-by: Miri Korenblit Link: https://msgid.link/20240416134215.f9111c79cb53.Ie95ea60149a9bc4367f6b338b37c8635051351ba@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ops.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 7b70248c6090..c4528a979add 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -372,7 +372,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { struct iwl_umac_scan_iter_complete_notif), RX_HANDLER(MISSED_BEACONS_NOTIFICATION, iwl_mvm_rx_missed_beacons_notif, - RX_HANDLER_SYNC, struct iwl_missed_beacons_notif), + RX_HANDLER_ASYNC_LOCKED_WIPHY, + struct iwl_missed_beacons_notif), RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, RX_HANDLER_SYNC, struct iwl_error_resp), -- cgit v1.2.3 From e619ad55b9fd535b266a9fbcdc48cc3a3e08d746 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Sun, 5 May 2024 09:19:51 +0300 Subject: wifi: iwlwifi: mvm: consider FWs recommendation for EMLSR FW sends a notification indicating whether activating EMLSR mode is recommended or not. Support the notification and enter EMLSR only if recommended. Signed-off-by: Miri Korenblit Link: https://msgid.link/20240505091420.2fd3387882eb.I7a8a5b24658744ed732bfc03b1872c9298483d62@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ops.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index c4528a979add..55ac5552b2f8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -145,6 +145,24 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode) ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); } +static void iwl_mvm_rx_esr_mode_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_mvm_esr_mode_notif *notif = (void *)pkt->data; + struct ieee80211_vif *vif = iwl_mvm_get_bss_vif(mvm); + + /* FW recommendations is only for entering EMLSR */ + if (!vif || iwl_mvm_vif_from_mac80211(vif)->esr_active) + return; + + if (le32_to_cpu(notif->action) == ESR_RECOMMEND_ENTER) + iwl_mvm_unblock_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_FW); + else + iwl_mvm_block_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_FW, + iwl_mvm_get_primary_link(vif)); +} + static void iwl_mvm_rx_monitor_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) { @@ -425,6 +443,11 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { iwl_mvm_channel_switch_error_notif, RX_HANDLER_ASYNC_UNLOCKED, struct iwl_channel_switch_error_notif), + + RX_HANDLER_GRP(DATA_PATH_GROUP, ESR_MODE_NOTIF, + iwl_mvm_rx_esr_mode_notif, RX_HANDLER_ASYNC_LOCKED, + struct iwl_mvm_esr_mode_notif), + RX_HANDLER_GRP(DATA_PATH_GROUP, MONITOR_NOTIF, iwl_mvm_rx_monitor_notif, RX_HANDLER_ASYNC_LOCKED, struct iwl_datapath_monitor_notif), @@ -607,6 +630,7 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = { HCMD_NAME(CHEST_COLLECTOR_FILTER_CONFIG_CMD), HCMD_NAME(SCD_QUEUE_CONFIG_CMD), HCMD_NAME(SEC_KEY_CMD), + HCMD_NAME(ESR_MODE_NOTIF), HCMD_NAME(MONITOR_NOTIF), HCMD_NAME(THERMAL_DUAL_CHAIN_REQUEST), HCMD_NAME(STA_PM_NOTIF), -- cgit v1.2.3 From a1efeb823084020c31412cc8f2b5d110ad3e58a3 Mon Sep 17 00:00:00 2001 From: Yedidya Benshimol Date: Sun, 5 May 2024 09:19:57 +0300 Subject: wifi: iwlwifi: mvm: Block EMLSR when a p2p/softAP vif is active When there's an active link in a non-station vif, the station vif is not allowed to enter EMLSR Note that blocking EMLSR by calling iwl_mvm_block_esr() we will schedule an exit from EMLSR worker, but the worker cannot run before the activation of the non-BSS link, as ieee80211_remain_on_channel already holds the wiphy mutex. Handle that by explicitly calling ieee80211_set_active_links() to leave EMLSR, and then doing iwl_mvm_block_esr() only for consistency and to avoid re-entering it before ready. Note that a call to ieee80211_set_active_links requires to release the mvm mutex, but that's ok since we still hold the wiphy lock. The only thing that might race here is the ESR_MODE_NOTIF, so this changes its handler to run under the wiphy lock. Signed-off-by: Yedidya Benshimol Co-developed-by: Miri Korenblit Signed-off-by: Miri Korenblit Link: https://msgid.link/20240505091420.916193759f8a.Idf3a3caf5cdc3e69c81710b7ceb57e87f2de87e4@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ops.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 55ac5552b2f8..155a44e8ab07 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -445,7 +445,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { struct iwl_channel_switch_error_notif), RX_HANDLER_GRP(DATA_PATH_GROUP, ESR_MODE_NOTIF, - iwl_mvm_rx_esr_mode_notif, RX_HANDLER_ASYNC_LOCKED, + iwl_mvm_rx_esr_mode_notif, + RX_HANDLER_ASYNC_LOCKED_WIPHY, struct iwl_mvm_esr_mode_notif), RX_HANDLER_GRP(DATA_PATH_GROUP, MONITOR_NOTIF, -- cgit v1.2.3 From 2e194efa38093f5f216802f08afc5b4b0a615ccf Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Mon, 6 May 2024 10:04:11 +0300 Subject: wifi: iwlwifi: mvm: Fix race in scan completion The move of the scan complete notification handling to the wiphy worker introduced a race between scan complete notification and scan abort: - The wiphy lock is held, e.g., for rfkill handling etc. - Scan complete notification is received but not handled yet. - Scan abort is triggered, and scan abort is sent to the FW. Once the scan abort command is sent successfully, the flow synchronously waits for the scan complete notification. However, as the scan complete notification was already received but not processed yet, this hangs for a second and continues leaving the scan status in an inconsistent state. - Once scan complete handling is started (when the wiphy lock is not held) since the scan status is not an inconsistent state, a warning is issued and the scan complete notification is not handled. To fix this issue, switch back the scan complete notification to be asynchronously handling, and only move the link selection logic to a worker (which was the original reason for the move to use wiphy lock). While at it, refactor some prints to improve debug data. Fixes: 07bf5297d392 ("wifi: iwlwifi: mvm: Implement new link selection algorithm") Signed-off-by: Ilan Peer Signed-off-by: Miri Korenblit Link: https://msgid.link/20240506095953.1f484a86324b.I63ed445a47f144546948c74ae6df85587fdb4ce3@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ops.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 155a44e8ab07..b27a03207938 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -383,7 +383,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { iwl_mvm_rx_scan_match_found, RX_HANDLER_SYNC), RX_HANDLER(SCAN_COMPLETE_UMAC, iwl_mvm_rx_umac_scan_complete_notif, - RX_HANDLER_ASYNC_LOCKED_WIPHY, + RX_HANDLER_ASYNC_LOCKED, struct iwl_umac_scan_complete), RX_HANDLER(SCAN_ITERATION_COMPLETE_UMAC, iwl_mvm_rx_umac_scan_iter_complete_notif, RX_HANDLER_SYNC, @@ -1171,6 +1171,27 @@ static const struct iwl_mei_ops mei_ops = { .nic_stolen = iwl_mvm_mei_nic_stolen, }; +static void iwl_mvm_find_link_selection_vif(void *_data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + + if (ieee80211_vif_is_mld(vif) && mvmvif->authorized) + iwl_mvm_select_links(mvmvif->mvm, vif); +} + +static void iwl_mvm_trig_link_selection(struct wiphy *wiphy, + struct wiphy_work *wk) +{ + struct iwl_mvm *mvm = + container_of(wk, struct iwl_mvm, trig_link_selection_wk); + + ieee80211_iterate_active_interfaces(mvm->hw, + IEEE80211_IFACE_ITER_NORMAL, + iwl_mvm_find_link_selection_vif, + NULL); +} + static struct iwl_op_mode * iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, const struct iwl_fw *fw, struct dentry *dbgfs_dir) @@ -1302,6 +1323,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, wiphy_work_init(&mvm->async_handlers_wiphy_wk, iwl_mvm_async_handlers_wiphy_wk); + + wiphy_work_init(&mvm->trig_link_selection_wk, + iwl_mvm_trig_link_selection); + init_waitqueue_head(&mvm->rx_sync_waitq); mvm->queue_sync_state = 0; -- cgit v1.2.3 From 97320888cb1582312bb171f4d8b5adc96e630333 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 6 May 2024 10:04:12 +0300 Subject: wifi: iwlwifi: mvm: add the firmware API for channel survey When requested, the firmware can return per-channel survey information generally used for ACS (automatic channel selection). Add the API for this, which consists of a flag and a new channel survey notification. Signed-off-by: Benjamin Berg Signed-off-by: Miri Korenblit Link: https://msgid.link/20240506095953.1facde532676.I3864ac4bc0fecb7fd5136e85c07585ab7100234b@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ops.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index b27a03207938..c52e69743c80 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -651,6 +651,7 @@ static const struct iwl_hcmd_names iwl_mvm_statistics_names[] = { * Access is done through binary search */ static const struct iwl_hcmd_names iwl_mvm_scan_names[] = { + HCMD_NAME(CHANNEL_SURVEY_NOTIF), HCMD_NAME(OFFLOAD_MATCH_INFO_NOTIF), }; -- cgit v1.2.3 From fc612222416ce206e01d7509b013bad41a051d83 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Mon, 6 May 2024 10:04:13 +0300 Subject: wifi: iwlwifi: mvm: record and return channel survey information While doing a passive scan, the firmware will report per-channel survey information. This information is primarily useful for hostapd when doing an ACS (Automatic Channel Selection). Collect this information and add it to the result set when getting the survey information. Signed-off-by: Benjamin Berg Signed-off-by: Miri Korenblit Link: https://msgid.link/20240506095953.9287591a5999.I54a3f9f6480d3694e67eea1cb4f5853beace2780@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ops.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index c52e69743c80..53283d052e18 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -473,6 +473,9 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { RX_HANDLER_GRP(MAC_CONF_GROUP, ROC_NOTIF, iwl_mvm_rx_roc_notif, RX_HANDLER_SYNC, struct iwl_roc_notif), + RX_HANDLER_GRP(SCAN_GROUP, CHANNEL_SURVEY_NOTIF, + iwl_mvm_rx_channel_survey_notif, RX_HANDLER_ASYNC_LOCKED, + struct iwl_umac_scan_channel_survey_notif), }; #undef RX_HANDLER #undef RX_HANDLER_GRP @@ -1582,6 +1585,7 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) kfree(mvm->temp_nvm_data); for (i = 0; i < NVM_MAX_NUM_SECTIONS; i++) kfree(mvm->nvm_sections[i].data); + kfree(mvm->acs_survey); cancel_delayed_work_sync(&mvm->tcm.work); -- cgit v1.2.3