wifi: iwlwifi: mvm: consider FWs recommendation for EMLSR
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Sun, 5 May 2024 06:19:51 +0000 (09:19 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 6 May 2024 14:33:24 +0000 (16:33 +0200)
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 <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240505091420.2fd3387882eb.I7a8a5b24658744ed732bfc03b1872c9298483d62@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/ops.c

index 0f7903c5a4dfea4022916f95cee8111550bfc774..f272b6a4e72ee7c252ce01e601449d4ace6bb19b 100644 (file)
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
+ * Copyright (C) 2024 Intel Corporation
  * Copyright (C) 2012-2014, 2018-2022 Intel Corporation
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
@@ -89,6 +90,12 @@ enum iwl_data_path_subcmd_ids {
         */
        SEC_KEY_CMD = 0x18,
 
+       /**
+        * @ESR_MODE_NOTIF: notification to recommend/force a wanted esr mode,
+        *      uses &struct iwl_mvm_esr_mode_notif
+        */
+       ESR_MODE_NOTIF = 0xF3,
+
        /**
         * @MONITOR_NOTIF: Datapath monitoring notification, using
         *      &struct iwl_datapath_monitor_notif
index c6d1f56446382732ecc449805c95e4b3cfd31229..754c5d655ad02fbc6915d6f3a68504d4b742487f 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2012-2014, 2018-2019, 2021-2023 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2019, 2021-2024 Intel Corporation
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
  */
@@ -642,4 +642,25 @@ struct iwl_mvm_sta_disable_tx_cmd {
        __le32 disable;
 } __packed; /* STA_DISABLE_TX_API_S_VER_1 */
 
+/**
+ * enum iwl_mvm_fw_esr_recommendation - FW recommendation code
+ * @ESR_RECOMMEND_LEAVE: recommendation to leave esr
+ * @ESR_FORCE_LEAVE: force exiting esr
+ * @ESR_RECOMMEND_ENTER: recommendation to enter esr
+ */
+enum iwl_mvm_fw_esr_recommendation {
+       ESR_RECOMMEND_LEAVE,
+       ESR_FORCE_LEAVE,
+       ESR_RECOMMEND_ENTER,
+}; /* ESR_MODE_RECOMMENDATION_CODE_API_E_VER_1 */
+
+/**
+ * struct iwl_mvm_esr_mode_notif - FWs recommendation/force for esr mode
+ *
+ * @action: the action to apply on esr state. See &iwl_mvm_fw_esr_recommendation
+ */
+struct iwl_mvm_esr_mode_notif {
+       __le32 action;
+} __packed; /* ESR_MODE_RECOMMENDATION_NTFY_API_S_VER_1 */
+
 #endif /* __iwl_fw_api_mac_cfg_h__ */
index 4c94f753c9513bad449ebdf0615f36a5bbafa9dd..61b3c45e3f0c764dcea2b29e0e5e9197833d6ba4 100644 (file)
@@ -3949,6 +3949,9 @@ iwl_mvm_sta_state_assoc_to_authorized(struct iwl_mvm *mvm,
 
                iwl_mvm_block_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_TPT, 0);
 
+               /* Block until FW notif will arrive */
+               iwl_mvm_block_esr(mvm, vif, IWL_MVM_ESR_BLOCKED_FW, 0);
+
                /* when client is authorized (AP station marked as such),
                 * try to enable the best link(s).
                 */
index 7f1a4ac563974e77a25ce7373ed0372beda0b215..bc182645004892c3b6065f383934ad423deb00ba 100644 (file)
@@ -357,6 +357,7 @@ struct iwl_mvm_vif_link_info {
  *     in a loop.
  * @IWL_MVM_ESR_BLOCKED_WOWLAN: WOWLAN is preventing the enablement of EMLSR
  * @IWL_MVM_ESR_BLOCKED_TPT: block EMLSR when there is not enough traffic
+ * @IWL_MVM_ESR_BLOCKED_FW: FW didn't recommended/forced exit from EMLSR
  * @IWL_MVM_ESR_EXIT_MISSED_BEACON: exited EMLSR due to missed beacons
  * @IWL_MVM_ESR_EXIT_LOW_RSSI: link is deactivated/not allowed for EMLSR
  *     due to low RSSI.
@@ -367,6 +368,7 @@ enum iwl_mvm_esr_state {
        IWL_MVM_ESR_BLOCKED_PREVENTION  = 0x1,
        IWL_MVM_ESR_BLOCKED_WOWLAN      = 0x2,
        IWL_MVM_ESR_BLOCKED_TPT         = 0x4,
+       IWL_MVM_ESR_BLOCKED_FW          = 0x8,
        IWL_MVM_ESR_EXIT_MISSED_BEACON  = 0x10000,
        IWL_MVM_ESR_EXIT_LOW_RSSI       = 0x20000,
        IWL_MVM_ESR_EXIT_COEX           = 0x40000,
index c4528a979add62e35bfeea9c696d1d685a89e178..55ac5552b2f8b6a57ed31af4e44d41920a3ab698 100644 (file)
@@ -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),