]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mac80211_hwsim: implement NAN schedule callbacks
authorDaniel Gabay <daniel.gabay@intel.com>
Wed, 6 May 2026 03:44:27 +0000 (06:44 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 6 May 2026 09:41:50 +0000 (11:41 +0200)
Implement mac80211 schedule callbacks for NAN Data Path support:

- Track local schedule via BSS_CHANGED_NAN_LOCAL_SCHED, caching
  the channel for each 16TU time slot.
- Copy peer schedule to driver-private storage in
  nan_peer_sched_changed callback for use in TX availability
  decisions.

Signed-off-by: Daniel Gabay <daniel.gabay@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260506064301.f3ad9e3dc9d4.I75cf3555b7506d5b8bb30e70a0f3721ab73477cb@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/virtual/mac80211_hwsim_i.h
drivers/net/wireless/virtual/mac80211_hwsim_main.c
drivers/net/wireless/virtual/mac80211_hwsim_nan.c
drivers/net/wireless/virtual/mac80211_hwsim_nan.h

index d182b5117bfb51b12ce46dabf683337ec13b127c..0f0f2ac6d80eb4ed0e9dbe7c9ccb7c91ac7fc08c 100644 (file)
 #include "mac80211_hwsim.h"
 #include "mac80211_hwsim_nan.h"
 
+struct hwsim_sta_nan_sched {
+       /* Later members are protected by this lock */
+       spinlock_t lock;
+       u16 committed_dw;
+       struct {
+               u8 map_id;
+               struct cfg80211_chan_def chans[CFG80211_NAN_SCHED_NUM_TIME_SLOTS];
+       } maps[CFG80211_NAN_MAX_PEER_MAPS];
+};
+
+struct hwsim_sta_priv {
+       u32 magic;
+       unsigned int last_link;
+       u16 active_links_rx;
+
+       /* NAN peer schedule - must be accessed under nan_sched.lock */
+       struct hwsim_sta_nan_sched nan_sched;
+};
+
+#define HWSIM_STA_MAGIC        0x6d537749
+
 struct mac80211_hwsim_link_data {
        u32 link_id;
        u64 beacon_int  /* beacon interval in us */;
index fc940b38c52cadc19bd0b79e52e5124e60d93eb8..1ea33ec577ddd110faf9933140295870da262be8 100644 (file)
@@ -252,14 +252,6 @@ static inline void hwsim_clear_magic(struct ieee80211_vif *vif)
        vp->magic = 0;
 }
 
-struct hwsim_sta_priv {
-       u32 magic;
-       unsigned int last_link;
-       u16 active_links_rx;
-};
-
-#define HWSIM_STA_MAGIC        0x6d537749
-
 static inline void hwsim_check_sta_magic(struct ieee80211_sta *sta)
 {
        struct hwsim_sta_priv *sp = (void *)sta->drv_priv;
@@ -2652,6 +2644,9 @@ static void mac80211_hwsim_vif_info_changed(struct ieee80211_hw *hw,
                vp->aid = vif->cfg.aid;
        }
 
+       if (changed & BSS_CHANGED_NAN_LOCAL_SCHED)
+               mac80211_hwsim_nan_local_sched_changed(hw, vif);
+
        if (vif->type == NL80211_IFTYPE_STATION &&
            changed & (BSS_CHANGED_MLD_VALID_LINKS | BSS_CHANGED_MLD_TTLM)) {
                u16 usable_links = ieee80211_vif_usable_links(vif);
@@ -2818,6 +2813,8 @@ static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw,
                sp->active_links_rx = sta->valid_links;
        }
 
+       spin_lock_init(&sp->nan_sched.lock);
+
        return 0;
 }
 
@@ -4245,6 +4242,7 @@ static int mac80211_hwsim_set_radar_background(struct ieee80211_hw *hw,
        .start_nan = mac80211_hwsim_nan_start,                  \
        .stop_nan = mac80211_hwsim_nan_stop,                    \
        .nan_change_conf = mac80211_hwsim_nan_change_config,    \
+       .nan_peer_sched_changed = mac80211_hwsim_nan_peer_sched_changed, \
        HWSIM_DEBUGFS_OPS
 
 #define HWSIM_NON_MLO_OPS                                      \
index 6053b6f8f91fc2f918eae21fdc8c2618b3ddf454..16883edd22158c15d9052a3fc4ae3a00ad2937c8 100644 (file)
@@ -1008,3 +1008,83 @@ bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,
 
        return false;
 }
+
+void mac80211_hwsim_nan_local_sched_changed(struct ieee80211_hw *hw,
+                                           struct ieee80211_vif *vif)
+{
+       struct mac80211_hwsim_data *data = hw->priv;
+       struct ieee80211_nan_channel **slots = vif->cfg.nan_sched.schedule;
+
+       if (WARN_ON(vif->type != NL80211_IFTYPE_NAN))
+               return;
+
+       spin_lock_bh(&data->nan.state_lock);
+
+       for (int i = 0; i < ARRAY_SIZE(data->nan.local_sched); i++) {
+               struct ieee80211_chanctx_conf *chanctx;
+
+               if (!slots[i] || IS_ERR(slots[i])) {
+                       memset(&data->nan.local_sched[i], 0,
+                              sizeof(data->nan.local_sched[i]));
+                       continue;
+               }
+
+               chanctx = slots[i]->chanctx_conf;
+               if (!chanctx) {
+                       memset(&data->nan.local_sched[i], 0,
+                              sizeof(data->nan.local_sched[i]));
+                       continue;
+               }
+
+               data->nan.local_sched[i] = chanctx->def;
+       }
+
+       spin_unlock_bh(&data->nan.state_lock);
+}
+
+int mac80211_hwsim_nan_peer_sched_changed(struct ieee80211_hw *hw,
+                                         struct ieee80211_sta *sta)
+{
+       struct hwsim_sta_priv *sp = (void *)sta->drv_priv;
+       struct ieee80211_nan_peer_sched *sched = sta->nan_sched;
+
+       spin_lock_bh(&sp->nan_sched.lock);
+
+       /* Clear existing schedule */
+       sp->nan_sched.committed_dw = 0;
+       for (int i = 0; i < CFG80211_NAN_MAX_PEER_MAPS; i++) {
+               sp->nan_sched.maps[i].map_id = CFG80211_NAN_INVALID_MAP_ID;
+               memset(sp->nan_sched.maps[i].chans, 0,
+                      sizeof(sp->nan_sched.maps[i].chans));
+       }
+
+       if (!sched)
+               goto out;
+
+       sp->nan_sched.committed_dw = sched->committed_dw;
+
+       for (int i = 0; i < CFG80211_NAN_MAX_PEER_MAPS; i++) {
+               struct ieee80211_nan_peer_map *map = &sched->maps[i];
+
+               if (map->map_id == CFG80211_NAN_INVALID_MAP_ID)
+                       continue;
+
+               sp->nan_sched.maps[i].map_id = map->map_id;
+
+               for (int j = 0; j < CFG80211_NAN_SCHED_NUM_TIME_SLOTS; j++) {
+                       struct ieee80211_nan_channel *peer_chan =
+                               map->slots[j];
+
+                       if (peer_chan && peer_chan->chanreq.oper.chan)
+                               sp->nan_sched.maps[i].chans[j] =
+                                       peer_chan->chanreq.oper;
+                       else
+                               memset(&sp->nan_sched.maps[i].chans[j], 0,
+                                      sizeof(sp->nan_sched.maps[i].chans[j]));
+               }
+       }
+
+out:
+       spin_unlock_bh(&sp->nan_sched.lock);
+       return 0;
+}
index 3199e5c5376bb76787574f5ba8b157ecc17122a3..eb53bacee206ccf25987c50d10ca7734e5b39747 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * mac80211_hwsim_nan - NAN software simulation for mac80211_hwsim
- * Copyright (C) 2025 Intel Corporation
+ * Copyright (C) 2025-2026 Intel Corporation
  */
 
 #ifndef __MAC80211_HWSIM_NAN_H
@@ -52,6 +52,13 @@ struct mac80211_hwsim_nan_data {
 
        bool tsf_adjusted;
        bool tsf_discontinuity;
+
+       /*
+        * Local schedule - stores channel definition for each 16TU slot.
+        * Derived from NMI vif->cfg.nan_schedule. chan == NULL means not
+        * available in that slot (except DW which is implicit).
+        */
+       struct cfg80211_chan_def local_sched[CFG80211_NAN_SCHED_NUM_TIME_SLOTS];
 };
 
 enum hrtimer_restart
@@ -73,6 +80,9 @@ int mac80211_hwsim_nan_change_config(struct ieee80211_hw *hw,
                                     struct cfg80211_nan_conf *conf,
                                     u32 changes);
 
+int mac80211_hwsim_nan_peer_sched_changed(struct ieee80211_hw *hw,
+                                         struct ieee80211_sta *sta);
+
 bool mac80211_hwsim_nan_txq_transmitting(struct ieee80211_hw *hw,
                                         struct ieee80211_txq *txq);
 
@@ -86,4 +96,7 @@ bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,
 void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,
                           struct sk_buff *skb);
 
+void mac80211_hwsim_nan_local_sched_changed(struct ieee80211_hw *hw,
+                                           struct ieee80211_vif *vif);
+
 #endif /* __MAC80211_HWSIM_NAN_H */