]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: iwlwifi: mld: support get/set_antenna
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 15 Sep 2025 08:34:31 +0000 (11:34 +0300)
committerMiri Korenblit <miriam.rachel.korenblit@intel.com>
Tue, 28 Oct 2025 14:17:26 +0000 (16:17 +0200)
This allows to set the antennas from user space.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250915113137.5a45baf9513c.I5912e6b6d9a9ae6530d0ac45e9517d07f98b8d05@changeid
drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
drivers/net/wireless/intel/iwlwifi/mld/mld.h

index 5725104a53bf0376eddf4f44e2e8ce35dcdad7ae..98d47fed84215787be71cbd2a1c6347befd8fdfd 100644 (file)
@@ -23,6 +23,7 @@
 #include "roc.h"
 #include "mlo.h"
 #include "stats.h"
+#include "iwl-nvm-parse.h"
 #include "ftm-initiator.h"
 #include "low_latency.h"
 #include "fw/api/scan.h"
@@ -2591,11 +2592,44 @@ iwl_mld_can_neg_ttlm(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        return NEG_TTLM_RES_ACCEPT;
 }
 
+static int iwl_mld_get_antenna(struct ieee80211_hw *hw, int radio_idx,
+                              u32 *tx_ant, u32 *rx_ant)
+{
+       struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
+
+       *tx_ant = iwl_mld_get_valid_tx_ant(mld);
+       *rx_ant = iwl_mld_get_valid_rx_ant(mld);
+
+       return 0;
+}
+
+static int iwl_mld_set_antenna(struct ieee80211_hw *hw, int radio_idx,
+                              u32 tx_ant, u32 rx_ant)
+{
+       struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
+
+       if (WARN_ON(!mld->nvm_data))
+               return -EBUSY;
+
+       /* mac80211 ensures the device is not started,
+        * so the firmware cannot be running
+        */
+
+       mld->set_tx_ant = tx_ant;
+       mld->set_rx_ant = rx_ant;
+
+       iwl_reinit_cab(mld->trans, mld->nvm_data, tx_ant, rx_ant, mld->fw);
+
+       return 0;
+}
+
 const struct ieee80211_ops iwl_mld_hw_ops = {
        .tx = iwl_mld_mac80211_tx,
        .start = iwl_mld_mac80211_start,
        .stop = iwl_mld_mac80211_stop,
        .config = iwl_mld_mac80211_config,
+       .get_antenna = iwl_mld_get_antenna,
+       .set_antenna = iwl_mld_set_antenna,
        .add_interface = iwl_mld_mac80211_add_interface,
        .remove_interface = iwl_mld_mac80211_remove_interface,
        .conf_tx = iwl_mld_mac80211_conf_tx,
index 94dc9da6360dc6040aab1211e0037ade24853f7a..b1d44fdaa61b0a922ec1c53c63c32aeec7ad4893 100644 (file)
  * @mcast_filter_cmd: pointer to the multicast filter command.
  * @mgmt_tx_ant: stores the last TX antenna index; used for setting
  *     TX rate_n_flags for non-STA mgmt frames (toggles on every TX failure).
+ * @set_tx_ant: stores the last TX antenna bitmask set by user space (if any)
+ * @set_rx_ant: stores the last RX antenna bitmask set by user space (if any)
  * @fw_rates_ver_3: FW rates are in version 3
  * @low_latency: low-latency manager.
  * @tzone: thermal zone device's data
@@ -279,6 +281,9 @@ struct iwl_mld {
 
        u8 mgmt_tx_ant;
 
+       u8 set_tx_ant;
+       u8 set_rx_ant;
+
        bool fw_rates_ver_3;
 
        struct iwl_mld_low_latency low_latency;
@@ -374,6 +379,9 @@ static inline u8 iwl_mld_get_valid_tx_ant(const struct iwl_mld *mld)
        if (mld->nvm_data && mld->nvm_data->valid_tx_ant)
                tx_ant &= mld->nvm_data->valid_tx_ant;
 
+       if (mld->set_tx_ant)
+               tx_ant &= mld->set_tx_ant;
+
        return tx_ant;
 }
 
@@ -384,6 +392,9 @@ static inline u8 iwl_mld_get_valid_rx_ant(const struct iwl_mld *mld)
        if (mld->nvm_data && mld->nvm_data->valid_rx_ant)
                rx_ant &= mld->nvm_data->valid_rx_ant;
 
+       if (mld->set_rx_ant)
+               rx_ant &= mld->set_rx_ant;
+
        return rx_ant;
 }