]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mac80211_hwsim: only RX on NAN when active on a slot
authorBenjamin Berg <benjamin.berg@intel.com>
Wed, 6 May 2026 03:44:22 +0000 (06:44 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 6 May 2026 09:41:49 +0000 (11:41 +0200)
This moves the NAN receive into the main code and changes it so that
frame RX only happens when the device is active on the channel. This
limits RX to the DW slots as there is currently no datapath.

With this the globally stored channel is obsolete, remove it.

Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260506064301.8cf4a67d3436.Ife07cf4ae8a2d59766356398163f7ee8d734bd6a@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
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 f0f6cb7fa8949738ceff6449e95807a4d3c8a827..76f1028bc42e0d28bab791db54721e850ed03712 100644 (file)
@@ -1731,6 +1731,8 @@ static bool hwsim_chans_compat(struct ieee80211_channel *c1,
 
 struct tx_iter_data {
        struct ieee80211_channel *channel;
+       struct ieee80211_rx_status *rx_status;
+       struct ieee80211_hw *hw;
        bool receive;
 };
 
@@ -1740,13 +1742,10 @@ static void mac80211_hwsim_tx_iter(void *_data, u8 *addr,
        struct tx_iter_data *data = _data;
        int i;
 
-       /* For NAN Device simulation purposes, assume that NAN is always
-        * on channel 6 or channel 149.
-        */
        if (vif->type == NL80211_IFTYPE_NAN) {
-               data->receive = (data->channel &&
-                                (data->channel->center_freq == 2437 ||
-                                 data->channel->center_freq == 5745));
+               data->receive = mac80211_hwsim_nan_receive(data->hw,
+                                                          data->channel,
+                                                          data->rx_status);
                return;
        }
 
@@ -1923,7 +1922,9 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
                struct sk_buff *nskb;
                struct tx_iter_data tx_iter_data = {
                        .receive = false,
+                       .hw = data2->hw,
                        .channel = chan,
+                       .rx_status = &rx_status,
                };
 
                if (data == data2)
@@ -1939,6 +1940,12 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
                if (data->netgroup != data2->netgroup)
                        continue;
 
+               /*
+                * Set mactime early since NAN RX filtering relies on it
+                * for slot calculation
+                */
+               rx_status.mactime = sim_tsf + data2->tsf_offset;
+
                if (!hwsim_chans_compat(chan, data2->tmp_chan) &&
                    !hwsim_chans_compat(chan, data2->channel)) {
                        ieee80211_iterate_active_interfaces_atomic(
@@ -1975,8 +1982,6 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
                if (mac80211_hwsim_addr_match(data2, hdr->addr1))
                        ack = true;
 
-               rx_status.mactime = sim_tsf + data2->tsf_offset;
-
                mac80211_hwsim_rx(data2, &rx_status, nskb);
        }
        spin_unlock(&hwsim_radio_lock);
@@ -6286,7 +6291,10 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
        /* A frame is received from user space */
        memset(&rx_status, 0, sizeof(rx_status));
        if (info->attrs[HWSIM_ATTR_FREQ]) {
-               struct tx_iter_data iter_data = {};
+               struct tx_iter_data iter_data = {
+                       .hw = data2->hw,
+                       .rx_status = &rx_status,
+               };
 
                /* throw away off-channel packets, but allow both the temporary
                 * ("hw" scan/remain-on-channel), regular channels and links,
index 10bbac9a4b5546d82835abfa27e18778a0bd5df3..8058481726056abdaacb3eb513389fb9ad5af239 100644 (file)
@@ -96,7 +96,6 @@ mac80211_hwsim_nan_slot_timer(struct hrtimer *timer)
        case SLOT_24GHZ_DW:
                wiphy_dbg(data->hw->wiphy, "Start of 2.4 GHz DW, is DW0=%d\n",
                          dwst_of_dw0);
-               data->nan.channel = ieee80211_get_channel(hw->wiphy, 2437);
                break;
 
        case SLOT_24GHZ_DW + 1:
@@ -111,8 +110,6 @@ mac80211_hwsim_nan_slot_timer(struct hrtimer *timer)
        case SLOT_5GHZ_DW:
                if (data->nan.bands & BIT(NL80211_BAND_5GHZ)) {
                        wiphy_dbg(data->hw->wiphy, "Start of 5 GHz DW\n");
-                       data->nan.channel =
-                               ieee80211_get_channel(hw->wiphy, 5745);
                }
                break;
 
@@ -158,7 +155,6 @@ int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,
        /* set this before starting the timer, as preemption might occur */
        data->nan.device_vif = vif;
        data->nan.bands = conf->bands;
-       data->nan.channel = ieee80211_get_channel(hw->wiphy, 2437);
 
        /* Just run this "soon" and start in a random schedule position */
        hrtimer_start(&data->nan.slot_timer,
@@ -328,3 +324,40 @@ mac80211_hwsim_nan_get_tx_channel(struct ieee80211_hw *hw)
        /* drop frame and warn, NAN_CHAN_SWITCH_TIME_US should avoid races */
        return NULL;
 }
+
+bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,
+                               struct ieee80211_channel *channel,
+                               struct ieee80211_rx_status *rx_status)
+{
+       struct mac80211_hwsim_data *data = hw->priv;
+       u8 slot;
+
+       if (WARN_ON_ONCE(!data->nan.device_vif))
+               return false;
+
+       if (rx_status->rx_flags & RX_FLAG_MACTIME) {
+               slot = hwsim_nan_slot_from_tsf(rx_status->mactime);
+       } else {
+               u64 tsf;
+
+               /*
+                * This is not perfect, but that should be fine.
+                *
+                * Assume the frame might be a bit early in relation to our
+                * own TSF. This is largely because the TSF sync is going to be
+                * pretty bad when the frame was RXed via NL and the beacon as
+                * well as RX timestamps are not accurate.
+                */
+               tsf = mac80211_hwsim_get_tsf(data->hw, data->nan.device_vif);
+               slot = hwsim_nan_slot_from_tsf(tsf + 128);
+       }
+
+       if (slot == SLOT_24GHZ_DW && channel->center_freq == 2437)
+               return true;
+
+       if (slot == SLOT_5GHZ_DW && data->nan.bands & BIT(NL80211_BAND_5GHZ) &&
+           channel->center_freq == 5745)
+               return true;
+
+       return false;
+}
index 796cc17d194e2e3c45324c55d21f85b2544e1121..af8dd7ff00cc1c37205fafbeb0f7daa16b24b543 100644 (file)
@@ -11,9 +11,6 @@ struct mac80211_hwsim_nan_data {
        struct ieee80211_vif *device_vif;
        u8 bands;
 
-       /* Current channel of the NAN device */
-       struct ieee80211_channel *channel;
-
        struct hrtimer slot_timer;
        struct hrtimer resume_txqs_timer;
        bool notify_dw;
@@ -42,4 +39,8 @@ bool mac80211_hwsim_nan_txq_transmitting(struct ieee80211_hw *hw,
 struct ieee80211_channel *
 mac80211_hwsim_nan_get_tx_channel(struct ieee80211_hw *hw);
 
+bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,
+                               struct ieee80211_channel *channel,
+                               struct ieee80211_rx_status *rx_status);
+
 #endif /* __MAC80211_HWSIM_NAN_H */