]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: iwlwifi: mld: add support for ROC on BSS
authorPagadala Yesu Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
Fri, 9 May 2025 10:44:52 +0000 (13:44 +0300)
committerMiri Korenblit <miriam.rachel.korenblit@intel.com>
Sat, 10 May 2025 18:43:12 +0000 (21:43 +0300)
add support for remain on channel on BSS vif for iwlmld.

Signed-off-by: Pagadala Yesu Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
Link: https://patch.msgid.link/20250509104454.2582160-14-miriam.rachel.korenblit@intel.com
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
drivers/net/wireless/intel/iwlwifi/mld/iface.h
drivers/net/wireless/intel/iwlwifi/mld/mld.h
drivers/net/wireless/intel/iwlwifi/mld/roc.c
drivers/net/wireless/intel/iwlwifi/mld/sta.c
drivers/net/wireless/intel/iwlwifi/mld/tx.c

index 15b43711035131cacb1a3fa4274d8798339b6071..49e2ce65557d6e5dde2df82ae0ca7b7ede09820f 100644 (file)
@@ -141,8 +141,8 @@ struct iwl_mld_emlsr {
  * @use_ps_poll: use ps_poll frames
  * @disable_bf: disable beacon filter
  * @dbgfs_slink: debugfs symlink for this interface
- * @roc_activity: the id of the roc_activity running. Relevant for p2p device
- *     only. Set to %ROC_NUM_ACTIVITIES when not in use.
+ * @roc_activity: the id of the roc_activity running. Relevant for STA and
+ *     p2p device only. Set to %ROC_NUM_ACTIVITIES when not in use.
  * @aux_sta: station used for remain on channel. Used in P2P device.
  */
 struct iwl_mld_vif {
index 1a2c44f44eff324468ef1037c6b2b926b1c4e04a..74fcaad85a32743ce175bebdf5b345c75f16a705 100644 (file)
  *     cleanup using iwl_mld_free_internal_sta
  * @netdetect: indicates the FW is in suspend mode with netdetect configured
  * @p2p_device_vif: points to the p2p device vif if exists
+ * @bss_roc_vif: points to the BSS vif that has an active ROC.
  * @dev: pointer to device struct. For printing purposes
  * @trans: pointer to the transport layer
  * @cfg: pointer to the device configuration
@@ -212,6 +213,7 @@ struct iwl_mld {
                bool netdetect;
 #endif /* CONFIG_PM_SLEEP */
                struct ieee80211_vif *p2p_device_vif;
+               struct ieee80211_vif *bss_roc_vif;
                struct iwl_bt_coex_profile_notif last_bt_notif;
        );
        struct ieee80211_link_sta __rcu *fw_id_to_link_sta[IWL_STATION_COUNT_MAX];
index cfd010c1ca8067020269bd23f5ff80ee941e0d2f..944d70901de5554e77ef29a69566ff7176ae7da7 100644 (file)
@@ -49,29 +49,36 @@ int iwl_mld_start_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
        lockdep_assert_wiphy(mld->wiphy);
 
-       /* TODO: task=Hotspot 2.0 */
-       if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
+       if (vif->type != NL80211_IFTYPE_P2P_DEVICE &&
+           vif->type != NL80211_IFTYPE_STATION) {
                IWL_ERR(mld, "NOT SUPPORTED: ROC on vif->type %d\n",
                        vif->type);
 
                return -EOPNOTSUPP;
        }
 
-       switch (type) {
-       case IEEE80211_ROC_TYPE_NORMAL:
-               activity = ROC_ACTIVITY_P2P_DISC;
-               break;
-       case IEEE80211_ROC_TYPE_MGMT_TX:
-               activity = ROC_ACTIVITY_P2P_NEG;
-               break;
-       default:
-               WARN_ONCE(1, "Got an invalid P2P ROC type\n");
-               return -EINVAL;
+       if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
+               switch (type) {
+               case IEEE80211_ROC_TYPE_NORMAL:
+                       activity = ROC_ACTIVITY_P2P_DISC;
+                       break;
+               case IEEE80211_ROC_TYPE_MGMT_TX:
+                       activity = ROC_ACTIVITY_P2P_NEG;
+                       break;
+               default:
+                       WARN_ONCE(1, "Got an invalid P2P ROC type\n");
+                       return -EINVAL;
+               }
+       } else {
+               activity = ROC_ACTIVITY_HOTSPOT;
        }
 
        if (WARN_ON(mld_vif->roc_activity != ROC_NUM_ACTIVITIES))
                return -EBUSY;
 
+       if (vif->type == NL80211_IFTYPE_STATION && mld->bss_roc_vif)
+               return -EBUSY;
+
        ieee80211_iterate_active_interfaces_mtx(mld->hw,
                                                IEEE80211_IFACE_ITER_NORMAL,
                                                iwl_mld_vif_iter_emlsr_block_roc,
@@ -88,9 +95,6 @@ int iwl_mld_start_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        cmd.channel_info.channel = cpu_to_le32(channel->hw_value);
        cmd.channel_info.band = iwl_mld_nl80211_band_to_fw(channel->band);
        cmd.channel_info.width = IWL_PHY_CHANNEL_MODE20;
-       /* TODO: task=Hotspot 2.0, revisit those parameters when we add an ROC
-        * on the BSS vif
-        */
        cmd.max_delay = cpu_to_le32(AUX_ROC_MAX_DELAY);
        cmd.duration = cpu_to_le32(MSEC_TO_TU(duration));
 
@@ -102,8 +106,12 @@ int iwl_mld_start_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                IWL_ERR(mld, "Couldn't send the ROC_CMD\n");
                return ret;
        }
+
        mld_vif->roc_activity = activity;
 
+       if (vif->type == NL80211_IFTYPE_STATION)
+               mld->bss_roc_vif = vif;
+
        return 0;
 }
 
@@ -122,6 +130,9 @@ static void iwl_mld_destroy_roc(struct iwl_mld *mld,
 {
        mld_vif->roc_activity = ROC_NUM_ACTIVITIES;
 
+       if (vif->type == NL80211_IFTYPE_STATION)
+               mld->bss_roc_vif = NULL;
+
        ieee80211_iterate_active_interfaces_mtx(mld->hw,
                                                IEEE80211_IFACE_ITER_NORMAL,
                                                iwl_mld_vif_iter_emlsr_unblock_roc,
@@ -153,8 +164,8 @@ int iwl_mld_cancel_roc(struct ieee80211_hw *hw,
 
        lockdep_assert_wiphy(mld->wiphy);
 
-       /* TODO: task=Hotspot 2.0 */
-       if (WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE))
+       if (WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE &&
+                   vif->type != NL80211_IFTYPE_STATION))
                return -EOPNOTSUPP;
 
        /* No roc activity running it's probably already done */
@@ -189,9 +200,13 @@ void iwl_mld_handle_roc_notif(struct iwl_mld *mld,
 {
        const struct iwl_roc_notif *notif = (void *)pkt->data;
        u32 activity = le32_to_cpu(notif->activity);
-       /* TODO: task=Hotspot 2.0 - roc can run on BSS */
-       struct ieee80211_vif *vif = mld->p2p_device_vif;
        struct iwl_mld_vif *mld_vif;
+       struct ieee80211_vif *vif;
+
+       if (activity == ROC_ACTIVITY_HOTSPOT)
+               vif = mld->bss_roc_vif;
+       else
+               vif = mld->p2p_device_vif;
 
        if (WARN_ON(!vif))
                return;
index bc5313f44fdee300c1319ebc50e334998dc79015..8fb51209b4a6f7a7e3b109f1f7296423dcf21b19 100644 (file)
@@ -1164,8 +1164,8 @@ void iwl_mld_remove_aux_sta(struct iwl_mld *mld,
 {
        struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
 
-       /* TODO: Hotspot 2.0 */
-       if (WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE))
+       if (WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE &&
+                   vif->type != NL80211_IFTYPE_STATION))
                return;
 
        iwl_mld_remove_internal_sta(mld, &mld_vif->aux_sta, false,
index 96ea6320c084f6c7f5936fd02db6d84e8bf5d966..4d4d3308a90ddba0b11d417868bb5d40165fe24d 100644 (file)
@@ -638,8 +638,11 @@ iwl_mld_get_tx_queue_id(struct iwl_mld *mld, struct ieee80211_txq *txq,
        case NL80211_IFTYPE_P2P_DEVICE:
                mld_vif = iwl_mld_vif_from_mac80211(info->control.vif);
 
-               if (mld_vif->roc_activity == ROC_NUM_ACTIVITIES) {
-                       IWL_DEBUG_DROP(mld, "Drop tx outside ROC\n");
+               if (mld_vif->roc_activity != ROC_ACTIVITY_P2P_DISC &&
+                   mld_vif->roc_activity != ROC_ACTIVITY_P2P_NEG) {
+                       IWL_DEBUG_DROP(mld,
+                                      "Drop tx outside ROC with activity %d\n",
+                                      mld_vif->roc_activity);
                        return IWL_MLD_INVALID_DROP_TX;
                }
 
@@ -649,6 +652,21 @@ iwl_mld_get_tx_queue_id(struct iwl_mld *mld, struct ieee80211_txq *txq,
        case NL80211_IFTYPE_MONITOR:
                mld_vif = iwl_mld_vif_from_mac80211(info->control.vif);
                return mld_vif->deflink.mon_sta.queue_id;
+       case NL80211_IFTYPE_STATION:
+               mld_vif = iwl_mld_vif_from_mac80211(info->control.vif);
+
+               if (!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)) {
+                       IWL_DEBUG_DROP(mld, "Drop tx not off-channel\n");
+                       return IWL_MLD_INVALID_DROP_TX;
+               }
+
+               if (mld_vif->roc_activity != ROC_ACTIVITY_HOTSPOT) {
+                       IWL_DEBUG_DROP(mld, "Drop tx outside ROC\n");
+                       return IWL_MLD_INVALID_DROP_TX;
+               }
+
+               WARN_ON(!ieee80211_is_mgmt(fc));
+               return mld_vif->aux_sta.queue_id;
        default:
                WARN_ONCE(1, "Unsupported vif type\n");
                break;