From: Pagadala Yesu Anjaneyulu Date: Fri, 9 May 2025 10:44:52 +0000 (+0300) Subject: wifi: iwlwifi: mld: add support for ROC on BSS X-Git-Tag: v6.16-rc1~132^2~46^2~8^2~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=305e4e6b862c7995617ee98b7aaf07ea3b074009;p=thirdparty%2Flinux.git wifi: iwlwifi: mld: add support for ROC on BSS add support for remain on channel on BSS vif for iwlmld. Signed-off-by: Pagadala Yesu Anjaneyulu Link: https://patch.msgid.link/20250509104454.2582160-14-miriam.rachel.korenblit@intel.com Signed-off-by: Miri Korenblit --- diff --git a/drivers/net/wireless/intel/iwlwifi/mld/iface.h b/drivers/net/wireless/intel/iwlwifi/mld/iface.h index 15b4371103513..49e2ce65557d6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/iface.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/iface.h @@ -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 { diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.h b/drivers/net/wireless/intel/iwlwifi/mld/mld.h index 1a2c44f44eff3..74fcaad85a327 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.h @@ -127,6 +127,7 @@ * 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]; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/roc.c b/drivers/net/wireless/intel/iwlwifi/mld/roc.c index cfd010c1ca806..944d70901de55 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/roc.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/roc.c @@ -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; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/sta.c b/drivers/net/wireless/intel/iwlwifi/mld/sta.c index bc5313f44fdee..8fb51209b4a6f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/sta.c @@ -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, diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tx.c b/drivers/net/wireless/intel/iwlwifi/mld/tx.c index 96ea6320c084f..4d4d3308a90dd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c @@ -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;