]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mac80211_hwsim: Support Tx of multicast data on NAN
authorIlan Peer <ilan.peer@intel.com>
Wed, 6 May 2026 03:44:33 +0000 (06:44 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 6 May 2026 09:42:12 +0000 (11:42 +0200)
Add support for transmitting multicast data frames. These
frames can be transmitted when all the peer NDI stations
on the interface are available at the current slot.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Reviewed-by: Benjamin Berg <benjamin.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260506064301.0af7e24f0df3.I3c2de3e456ae092c939e6bfd3d30960fbf2fbeaa@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/virtual/mac80211_hwsim_nan.c

index 0397c43724fe68978b23c1fe97b806c112aee8f6..7be64c45babf949c23fa9aad7eb441d3cbe042f6 100644 (file)
@@ -41,6 +41,13 @@ struct hwsim_nan_sta_iter_ctx {
        bool can_tx;
 };
 
+struct hwsim_nan_mcast_data_iter_ctx {
+       struct ieee80211_hw *hw;
+       struct ieee80211_vif *vif;
+       size_t n_vif_sta;
+       size_t n_sta_can_tx;
+};
+
 static void mac80211_hwsim_nan_resume_txqs(struct mac80211_hwsim_data *data);
 
 static u64 hwsim_nan_get_timer_tsf(struct mac80211_hwsim_data *data)
@@ -1103,6 +1110,42 @@ mac80211_hwsim_nan_resume_txqs_timer(struct hrtimer *timer)
        return HRTIMER_NORESTART;
 }
 
+static void
+hwsim_nan_can_mcast_sta_transmit(void *_ctx, struct ieee80211_sta *sta)
+{
+       struct hwsim_nan_mcast_data_iter_ctx *ctx = _ctx;
+       struct ieee80211_txq *txq = sta->txq[0];
+
+       if (!txq || txq->vif != ctx->vif)
+               return;
+
+       ctx->n_vif_sta++;
+       if (mac80211_hwsim_nan_txq_transmitting(ctx->hw, txq))
+               ctx->n_sta_can_tx++;
+}
+
+static bool
+mac80211_hwsim_nan_mcast_data_transmitting(struct ieee80211_hw *hw,
+                                          struct ieee80211_txq *txq)
+{
+       struct mac80211_hwsim_data *data = hw->priv;
+       struct hwsim_nan_mcast_data_iter_ctx ctx = {
+               .hw = hw,
+               .vif = txq->vif,
+               .n_sta_can_tx = 0,
+               .n_vif_sta = 0,
+       };
+
+       /* Check if all the stations associated with the current
+        * interface are available.
+        */
+       ieee80211_iterate_stations_atomic(data->hw,
+                                         hwsim_nan_can_mcast_sta_transmit,
+                                         &ctx);
+
+       return ctx.n_vif_sta && ctx.n_sta_can_tx == ctx.n_vif_sta;
+}
+
 bool mac80211_hwsim_nan_txq_transmitting(struct ieee80211_hw *hw,
                                         struct ieee80211_txq *txq)
 {
@@ -1125,9 +1168,16 @@ bool mac80211_hwsim_nan_txq_transmitting(struct ieee80211_hw *hw,
 
        is_dw_slot = mac80211_hwsim_nan_is_dw_slot(data, slot);
 
-       /* Non-STA TXQ: allow management frames during DW */
-       if (!txq->sta)
-               return is_dw_slot;
+       if (!txq->sta) {
+               /* Non-STA TXQ: allow management frames during DW */
+               if (txq->vif->type == NL80211_IFTYPE_NAN)
+                       return is_dw_slot;
+
+               /* Allow multicast data when all the peers are available
+                * on this slot
+                */
+               return mac80211_hwsim_nan_mcast_data_transmitting(hw, txq);
+       }
 
        /* STA TXQ: need peer schedule for availability check */
        nmi_sta = rcu_dereference(txq->sta->nmi) ?: txq->sta;