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 <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>
This commit is contained in:
Pagadala Yesu Anjaneyulu 2025-05-09 13:44:52 +03:00 committed by Miri Korenblit
parent 2903fe335e
commit 305e4e6b86
5 changed files with 60 additions and 25 deletions

View 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 {

View File

@ -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];

View 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;

View 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,

View 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;