xref: /linux/drivers/net/wireless/virtual/mac80211_hwsim_nan.c (revision 0b87d2ab030fd969ea626b2da95594949a2c0508)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * mac80211_hwsim_nan - NAN software simulation for mac80211_hwsim
4  * Copyright (C) 2025-2026 Intel Corporation
5  */
6 
7 #include <net/cfg80211.h>
8 #include "mac80211_hwsim_i.h"
9 
10 /* Defined as the lower 23 bits being zero */
11 #define DW0_TSF_MASK		GENMASK(22, 0)
12 
13 /* DWs are repeated every 512 TUs */
14 #define DWST_TU			512
15 #define DWST_TSF_MASK		(ieee80211_tu_to_usec(DWST_TU) - 1)
16 
17 #define SLOT_TU			16
18 #define SLOT_TSF_MASK		(ieee80211_tu_to_usec(DWST_TU) - 1)
19 
20 /* The 2.4 GHz DW is at the start, the 5 GHz is in slot 8 (after 128 TUs) */
21 #define DW_5G_OFFSET_TU		128
22 
23 #define SLOT_24GHZ_DW		0
24 #define SLOT_5GHZ_DW		(DW_5G_OFFSET_TU / SLOT_TU)
25 
26 /* The special DW0 happens every 16 DWSTs (8192 TUs) */
27 static_assert(16 * DWST_TU * 1024 == 8192 * 1024);
28 static_assert(DW0_TSF_MASK + 1 == 8192 * 1024);
29 
30 /* warmup phase should be 120 seconds, which is approximately 225 DWSTs */
31 #define NAN_WARMUP_DWST		225
32 
33 #define NAN_RSSI_CLOSE (-60)
34 #define NAN_RSSI_MIDDLE (-75)
35 
36 /* Quiet time at the end of each slot where TX is suppressed */
37 #define NAN_CHAN_SWITCH_TIME_US		256
38 
39 struct hwsim_nan_sta_iter_ctx {
40 	struct ieee80211_hw *hw;
41 	bool can_tx;
42 };
43 
44 struct hwsim_nan_mcast_data_iter_ctx {
45 	struct ieee80211_hw *hw;
46 	struct ieee80211_vif *vif;
47 	size_t n_vif_sta;
48 	size_t n_sta_can_tx;
49 };
50 
51 static void mac80211_hwsim_nan_resume_txqs(struct mac80211_hwsim_data *data);
52 
53 static u64 hwsim_nan_get_timer_tsf(struct mac80211_hwsim_data *data)
54 {
55 	ktime_t expires = hrtimer_get_expires(&data->nan.slot_timer);
56 
57 	return mac80211_hwsim_boottime_to_tsf(data, expires);
58 }
59 
60 static u8 hwsim_nan_slot_from_tsf(u64 tsf)
61 {
62 	return (tsf & DWST_TSF_MASK) / ieee80211_tu_to_usec(SLOT_TU);
63 }
64 
65 static u64 hwsim_nan_encode_master_rank(u8 master_pref, u8 random_factor,
66 					const u8 *addr)
67 {
68 	return ((u64)master_pref << 56) +
69 		((u64)random_factor << 48) +
70 		((u64)addr[5] << 40) +
71 		((u64)addr[4] << 32) +
72 		((u64)addr[3] << 24) +
73 		((u64)addr[2] << 16) +
74 		((u64)addr[1] << 8) +
75 		((u64)addr[0] << 0);
76 }
77 
78 static u64 hwsim_nan_get_master_rank(struct mac80211_hwsim_data *data)
79 {
80 	u8 master_pref = 0;
81 	u8 random_factor = 0;
82 
83 	if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_UP) {
84 		master_pref = data->nan.master_pref;
85 		random_factor = data->nan.random_factor;
86 	}
87 
88 	return hwsim_nan_encode_master_rank(master_pref, random_factor,
89 					    data->nan.device_vif->addr);
90 }
91 
92 static bool mac80211_hwsim_nan_is_dw_slot(struct mac80211_hwsim_data *data,
93 					  u8 slot)
94 {
95 	return slot == SLOT_24GHZ_DW ||
96 		(slot == SLOT_5GHZ_DW &&
97 		 (data->nan.bands & BIT(NL80211_BAND_5GHZ)));
98 }
99 
100 static bool
101 hwsim_nan_rx_chandef_compatible(struct mac80211_hwsim_data *data, u8 slot,
102 				struct ieee80211_channel *rx_chan, u8 rx_bw)
103 {
104 	static const int bw_to_mhz[] = {
105 		[RATE_INFO_BW_20] = 20, [RATE_INFO_BW_40] = 40,
106 		[RATE_INFO_BW_80] = 80, [RATE_INFO_BW_160] = 160,
107 	};
108 	struct cfg80211_chan_def sched_chandef;
109 	int rx_mhz, sched_mhz;
110 
111 	scoped_guard(spinlock_bh, &data->nan.state_lock)
112 		sched_chandef = data->nan.local_sched[slot];
113 
114 	if (!sched_chandef.chan ||
115 	    sched_chandef.chan->center_freq != rx_chan->center_freq)
116 		return false;
117 
118 	if (rx_bw >= ARRAY_SIZE(bw_to_mhz) || !bw_to_mhz[rx_bw])
119 		return false;
120 
121 	rx_mhz = bw_to_mhz[rx_bw];
122 	sched_mhz = cfg80211_chandef_get_width(&sched_chandef);
123 
124 	/* Accept RX at narrower or equal bandwidth */
125 	return rx_mhz <= sched_mhz;
126 }
127 
128 static bool hwsim_nan_peer_present_in_dw(struct hwsim_sta_priv *sp, u64 tsf)
129 {
130 	u8 slot = hwsim_nan_slot_from_tsf(tsf);
131 	u8 cdw = 0;
132 	u8 dw_index, wake_interval;
133 	u16 committed_dw;
134 
135 	scoped_guard(spinlock_bh, &sp->nan_sched.lock)
136 		committed_dw = sp->nan_sched.committed_dw;
137 
138 	/* If peer doesn't advertise committed DW, assume presence in
139 	 * all 2.4 GHz DW slots
140 	 */
141 	if (!committed_dw)
142 		return slot == SLOT_24GHZ_DW;
143 
144 	/* Get DW index (0-15) within the 16-DWST DW0 cycle */
145 	dw_index = (tsf / ieee80211_tu_to_usec(DWST_TU)) & 0xf;
146 
147 	/* Extract CDW for the appropriate band (spec Table 80) */
148 	if (slot == SLOT_24GHZ_DW)
149 		cdw = committed_dw & 0x7;
150 	else if (slot == SLOT_5GHZ_DW)
151 		cdw = (committed_dw >> 3) & 0x7;
152 
153 	if (cdw == 0)
154 		return false;
155 
156 	/* Peer wakes every 2^(cdw-1) DWs: 1, 2, 4, 8, or 16 */
157 	wake_interval = 1 << (cdw - 1);
158 
159 	return (dw_index % wake_interval) == 0;
160 }
161 
162 static bool
163 hwsim_nan_peer_present_in_faw(struct hwsim_sta_priv *sp,
164 			      struct mac80211_hwsim_data *data, u8 slot)
165 {
166 	struct cfg80211_chan_def local_chandef;
167 
168 	scoped_guard(spinlock_bh, &data->nan.state_lock)
169 		local_chandef = data->nan.local_sched[slot];
170 
171 	if (!local_chandef.chan)
172 		return false;
173 
174 	scoped_guard(spinlock_bh, &sp->nan_sched.lock) {
175 		for (int i = 0; i < CFG80211_NAN_MAX_PEER_MAPS; i++) {
176 			struct cfg80211_chan_def *peer_chandef;
177 
178 			if (sp->nan_sched.maps[i].map_id ==
179 			    CFG80211_NAN_INVALID_MAP_ID)
180 				continue;
181 
182 			peer_chandef = &sp->nan_sched.maps[i].chans[slot];
183 			if (!peer_chandef->chan)
184 				continue;
185 
186 			if (cfg80211_chandef_compatible(&local_chandef,
187 							peer_chandef))
188 				return true;
189 		}
190 	}
191 
192 	return false;
193 }
194 
195 static void
196 mac80211_hwsim_nan_schedule_slot(struct mac80211_hwsim_data *data, u8 slot,
197 				 bool discontinuity)
198 {
199 	u64 tsf;
200 
201 	if (!discontinuity)
202 		tsf = hwsim_nan_get_timer_tsf(data);
203 	else
204 		tsf = mac80211_hwsim_get_tsf(data->hw, data->nan.device_vif);
205 
206 	/* Only called by mac80211_hwsim_nan_dw_timer from softirq context */
207 	lockdep_assert_in_softirq();
208 
209 	tsf &= ~DWST_TSF_MASK;
210 	tsf += ieee80211_tu_to_usec(slot * SLOT_TU);
211 
212 	hrtimer_set_expires(&data->nan.slot_timer,
213 			    mac80211_hwsim_tsf_to_boottime(data, tsf));
214 }
215 
216 void mac80211_hwsim_nan_rx(struct ieee80211_hw *hw,
217 			   struct sk_buff *skb)
218 {
219 	struct mac80211_hwsim_data *data = hw->priv;
220 	const struct ieee80211_mgmt *mgmt = (void *)skb->data;
221 	struct element *nan_elem = (void *)mgmt->u.beacon.variable;
222 	struct ieee80211_nan_anchor_master_info *ami = NULL;
223 	const struct ieee80211_nan_attr *nan_attr;
224 	struct ieee80211_rx_status rx_status;
225 	bool joined_cluster = false;
226 	bool adopt_tsf = false;
227 	bool is_sync_beacon;
228 	bool is_same_cluster;
229 	u64 master_rank = 0;
230 	ssize_t data_len;
231 	u8 slot;
232 
233 	/* Need a NAN vendor element at the start */
234 	if (skb->len < (offsetofend(struct ieee80211_mgmt, u.beacon) + 6) ||
235 	    !ieee80211_is_beacon(mgmt->frame_control))
236 		return;
237 
238 	data_len = skb->len - offsetofend(struct ieee80211_mgmt, u.beacon);
239 
240 	/* Copy the RX status to add a MAC timestamp if needed */
241 	memcpy(&rx_status, IEEE80211_SKB_RXCB(skb),
242 	       sizeof(struct ieee80211_rx_status));
243 
244 	/* And deal with the lack of mac time stamp */
245 	if ((rx_status.flag & RX_FLAG_MACTIME) != RX_FLAG_MACTIME_START) {
246 		u64 tsf = mac80211_hwsim_get_tsf(hw, data->nan.device_vif);;
247 
248 		/* In that case there should be no timestamp */
249 		WARN_ON_ONCE(rx_status.flag & RX_FLAG_MACTIME);
250 
251 		/* No mac timestamp, set current TSF for the frame end */
252 		rx_status.flag |= RX_FLAG_MACTIME_END;
253 		rx_status.mactime = tsf;
254 
255 		/* And translate to the start for the rest of the code */
256 		rx_status.mactime =
257 			ieee80211_calculate_rx_timestamp(hw, &rx_status,
258 							 skb->len, 0);
259 		rx_status.flag &= ~RX_FLAG_MACTIME;
260 		rx_status.flag |= RX_FLAG_MACTIME_START;
261 
262 		/* Match mac80211_hwsim_nan_receive, see comment there */
263 		slot = hwsim_nan_slot_from_tsf(tsf + 128);
264 	} else {
265 		slot = hwsim_nan_slot_from_tsf(rx_status.mactime);
266 	}
267 
268 	/*
269 	 * (overly) simplify things, only track 2.4 GHz here. Also, ignore
270 	 * frames outside of the 2.4 GHz DW slot, unless in the initial SCAN
271 	 * phase.
272 	 */
273 	if ((slot != SLOT_24GHZ_DW &&
274 	     data->nan.phase != MAC80211_HWSIM_NAN_PHASE_SCAN) ||
275 	    rx_status.freq != 2437)
276 		return;
277 
278 	/* Just ignore low RSSI beacons that we cannot sync to */
279 	if (rx_status.signal < NAN_RSSI_MIDDLE)
280 		return;
281 
282 	/* Needs to be a valid NAN cluster ID in A3 */
283 	if (get_unaligned_be32(mgmt->bssid) != ((WLAN_OUI_WFA << 8) | 0x01))
284 		return;
285 
286 	/* We are only interested in NAN beacons */
287 	if (nan_elem->id != WLAN_EID_VENDOR_SPECIFIC ||
288 	    nan_elem->datalen < 4 ||
289 	    get_unaligned_be32(nan_elem->data) !=
290 	    (WLAN_OUI_WFA << 8 | WLAN_OUI_TYPE_WFA_NAN))
291 		return;
292 
293 	u8 *nan_defragmented __free(kfree) = kzalloc(data_len, GFP_ATOMIC);
294 	if (!nan_defragmented)
295 		return;
296 
297 	data_len = cfg80211_defragment_element(nan_elem,
298 					       mgmt->u.beacon.variable,
299 					       data_len,
300 					       nan_defragmented, data_len,
301 					       WLAN_EID_FRAGMENT);
302 
303 	if (data_len < 0)
304 		return;
305 
306 	/* Assume it is a synchronization beacon if beacon_int is 512 TUs */
307 	is_sync_beacon = le16_to_cpu(mgmt->u.beacon.beacon_int) == DWST_TU;
308 	is_same_cluster = ether_addr_equal(mgmt->bssid, data->nan.cluster_id);
309 
310 	for_each_nan_attr(nan_attr, nan_defragmented + 4, data_len - 4) {
311 		if (nan_attr->attr == NAN_ATTR_MASTER_INDICATION &&
312 		    le16_to_cpu(nan_attr->length) >=
313 		    sizeof(struct ieee80211_nan_master_indication)) {
314 			struct ieee80211_nan_master_indication *mi =
315 				(void *)nan_attr->data;
316 
317 			master_rank =
318 				hwsim_nan_encode_master_rank(mi->master_pref,
319 							     mi->random_factor,
320 							     mgmt->sa);
321 		}
322 
323 		if (nan_attr->attr == NAN_ATTR_CLUSTER_INFO &&
324 		    le16_to_cpu(nan_attr->length) >=
325 		    sizeof(struct ieee80211_nan_anchor_master_info)) {
326 			ami = (void *)nan_attr->data;
327 
328 			/*
329 			 * The AMBTT should be set to the beacon timestamp when
330 			 * the sender is the anchor master. We can simply
331 			 * modify the structure because we created a copy when
332 			 * defragmenting the NAN element.
333 			 */
334 			if (ami->hop_count == 0)
335 				ami->ambtt = cpu_to_le32(
336 					le64_to_cpu(mgmt->u.beacon.timestamp));
337 		}
338 	}
339 
340 	/* Do the rest of the processing under lock */
341 	spin_lock_bh(&data->nan.state_lock);
342 
343 	/*
344 	 * sync beacon should be discarded if the master rank is the same
345 	 * and the AMBTT is older than 16 * 512 TUs compared to our own TSF.
346 	 *
347 	 * Subtract the AMBTT from the lowered TSF. If the AMBTT is older
348 	 * (smaller) then the calculation will not underflow.
349 	 */
350 	if (is_sync_beacon && ami &&
351 	    ami->master_rank == data->nan.current_ami.master_rank &&
352 	    (((u32)rx_status.mactime -
353 	      ieee80211_tu_to_usec(16 * 512)) -
354 	     le32_to_cpu(ami->ambtt)) < 0x8000000) {
355 		wiphy_dbg(hw->wiphy,
356 			  "NAN: ignoring sync beacon with old AMBTT\n");
357 		is_sync_beacon = false;
358 	}
359 
360 	if (is_same_cluster && is_sync_beacon &&
361 	    master_rank > hwsim_nan_get_master_rank(data)) {
362 		if (rx_status.signal > NAN_RSSI_CLOSE)
363 			data->nan.master_transition_score += 3;
364 		else
365 			data->nan.master_transition_score += 1;
366 	}
367 
368 	if (is_same_cluster && is_sync_beacon && ami &&
369 	    ((ami->master_rank == data->nan.current_ami.master_rank &&
370 	      ami->hop_count < data->nan.current_ami.hop_count) ||
371 	     (master_rank > hwsim_nan_get_master_rank(data) &&
372 	      ami->hop_count == data->nan.current_ami.hop_count))) {
373 		if (rx_status.signal > NAN_RSSI_CLOSE)
374 			data->nan.sync_transition_score += 3;
375 		else
376 			data->nan.sync_transition_score += 1;
377 	}
378 
379 	/*
380 	 * Decide on TSF adjustments before updating any other state
381 	 */
382 	if (is_same_cluster && is_sync_beacon && ami &&
383 	    data->nan.current_ami.hop_count != 0) {
384 		if (le64_to_cpu(ami->master_rank) >
385 		    le64_to_cpu(data->nan.current_ami.master_rank) &&
386 		    ami->master_rank != data->nan.last_ami.master_rank)
387 			adopt_tsf = true;
388 
389 		if (le64_to_cpu(ami->master_rank) >
390 		    le64_to_cpu(data->nan.current_ami.master_rank) &&
391 		    ami->master_rank == data->nan.last_ami.master_rank &&
392 		    le32_to_cpu(ami->ambtt) >
393 		    le32_to_cpu(data->nan.last_ami.ambtt))
394 			adopt_tsf = true;
395 
396 		if (le64_to_cpu(ami->master_rank) <
397 		    le64_to_cpu(data->nan.current_ami.master_rank) &&
398 		    le64_to_cpu(ami->master_rank) >
399 		    hwsim_nan_get_master_rank(data) &&
400 		    ether_addr_equal(ami->master_addr,
401 				     data->nan.current_ami.master_addr))
402 			adopt_tsf = true;
403 
404 		if (ami->master_rank == data->nan.current_ami.master_rank &&
405 		    le32_to_cpu(ami->ambtt) >
406 		    le32_to_cpu(data->nan.current_ami.ambtt))
407 			adopt_tsf = true;
408 
409 		/* Anchor Master case is handled below */
410 	}
411 
412 	/*
413 	 * NAN Cluster merging
414 	 */
415 	if (!is_same_cluster && ami) {
416 		u64 curr_amr;
417 		u64 own_cg;
418 		u64 frame_amr;
419 		u64 cg;
420 
421 		/* Shifted down by 19 bits compared to spec */
422 		frame_amr = le64_to_cpu(ami->master_rank);
423 		cg = (u64)ami->master_pref << (64 - 19);
424 		cg += le64_to_cpu(mgmt->u.beacon.timestamp) >> 19;
425 
426 		curr_amr = le64_to_cpu(data->nan.current_ami.master_rank);
427 		own_cg = (u64)data->nan.current_ami.master_pref << (64 - 19);
428 		own_cg += rx_status.mactime >> 19;
429 
430 		/*
431 		 * Check if the cluster shall be joined
432 		 *
433 		 * When in the "scan" phase, just join immediately.
434 		 */
435 		if (cg > own_cg ||
436 		    (cg == own_cg && frame_amr > curr_amr) ||
437 		    data->nan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN) {
438 			/* Avoid a state transition */
439 			data->nan.master_transition_score = 0;
440 			data->nan.sync_transition_score = 0;
441 
442 			/*
443 			 * NOTE: The spec says we should TX sync beacons on the
444 			 * old schedule after joining. We do not implement this.
445 			 */
446 
447 			wiphy_dbg(hw->wiphy, "NAN: joining cluster %pM\n",
448 				  mgmt->bssid);
449 
450 			joined_cluster = true;
451 			adopt_tsf = true;
452 
453 			memcpy(&data->nan.last_ami, &data->nan.current_ami,
454 			       sizeof(data->nan.last_ami));
455 			memcpy(&data->nan.current_ami, ami,
456 			       sizeof(data->nan.last_ami));
457 			data->nan.current_ami.hop_count += 1;
458 
459 			memcpy(data->nan.cluster_id, mgmt->bssid, ETH_ALEN);
460 
461 			/*
462 			 * Assume we are UP if we joined a cluster.
463 			 *
464 			 * If the other anchor master is still in the warmup
465 			 * phase, then we may temporarily become the anchor
466 			 * master until it sets its own master preference to
467 			 * be non-zero.
468 			 */
469 			data->nan.phase = MAC80211_HWSIM_NAN_PHASE_UP;
470 			data->nan.random_factor_valid_dwst = 0;
471 		}
472 	}
473 
474 	/*
475 	 * Anchor master selection
476 	 */
477 	/* We are not anchor master */
478 	if (is_same_cluster && is_sync_beacon && ami &&
479 	    data->nan.current_ami.hop_count != 0) {
480 		if (le64_to_cpu(data->nan.current_ami.master_rank) <
481 		    le64_to_cpu(ami->master_rank)) {
482 			if (ami->master_rank == data->nan.last_ami.master_rank &&
483 			    le32_to_cpu(ami->ambtt) <=
484 			    le32_to_cpu(data->nan.last_ami.ambtt)) {
485 				/* disregard frame */
486 			} else {
487 				memcpy(&data->nan.last_ami,
488 				       &data->nan.current_ami,
489 				       sizeof(data->nan.last_ami));
490 				memcpy(&data->nan.current_ami, ami,
491 				       sizeof(data->nan.last_ami));
492 				data->nan.current_ami.hop_count += 1;
493 			}
494 		}
495 
496 		if (le64_to_cpu(data->nan.current_ami.master_rank) >
497 		    le64_to_cpu(ami->master_rank)) {
498 			if (!ether_addr_equal(data->nan.current_ami.master_addr,
499 					      ami->master_addr)) {
500 				/* disregard frame */
501 			} else {
502 				u64 amr = hwsim_nan_get_master_rank(data);
503 
504 				if (amr > le64_to_cpu(ami->master_rank)) {
505 					/* assume ourselves as anchor master */
506 					wiphy_dbg(hw->wiphy,
507 						  "NAN: assume anchor master role\n");
508 					data->nan.current_ami.master_rank =
509 						cpu_to_le64(amr);
510 					data->nan.current_ami.hop_count = 0;
511 					memset(&data->nan.last_ami, 0,
512 					       sizeof(data->nan.last_ami));
513 					data->nan.last_ami.ambtt =
514 						data->nan.current_ami.ambtt;
515 					data->nan.current_ami.ambtt = 0;
516 				} else {
517 					memcpy(&data->nan.last_ami,
518 					       &data->nan.current_ami,
519 					       sizeof(data->nan.last_ami));
520 					memcpy(&data->nan.current_ami, ami,
521 					       sizeof(data->nan.last_ami));
522 					data->nan.current_ami.hop_count += 1;
523 				}
524 			}
525 		}
526 
527 		if (data->nan.current_ami.master_rank == ami->master_rank) {
528 			if (le32_to_cpu(data->nan.current_ami.ambtt) <
529 			    le32_to_cpu(ami->ambtt)) {
530 				data->nan.current_ami.ambtt = ami->ambtt;
531 			}
532 
533 			if (data->nan.current_ami.hop_count >
534 			    ami->hop_count + 1) {
535 				data->nan.current_ami.hop_count =
536 					ami->hop_count + 1;
537 			}
538 		}
539 	}
540 
541 	/* We are anchor master */
542 	if (is_same_cluster && is_sync_beacon && ami &&
543 	    data->nan.current_ami.hop_count == 0) {
544 		WARN_ON_ONCE(!ether_addr_equal(data->nan.current_ami.master_addr,
545 					       data->nan.device_vif->addr));
546 
547 		if (le64_to_cpu(ami->master_rank) <
548 		    le64_to_cpu(data->nan.current_ami.master_rank) ||
549 		    ether_addr_equal(ami->master_addr,
550 				     data->nan.current_ami.master_addr)) {
551 			/* disregard */
552 		} else {
553 			wiphy_dbg(hw->wiphy, "NAN: lost anchor master role\n");
554 			adopt_tsf = true;
555 			memcpy(&data->nan.last_ami, &data->nan.current_ami,
556 			       sizeof(data->nan.last_ami));
557 			memcpy(&data->nan.current_ami, ami,
558 			       sizeof(data->nan.last_ami));
559 			data->nan.current_ami.hop_count += 1;
560 		}
561 	}
562 
563 	if (adopt_tsf && !data->nan.tsf_adjusted) {
564 		int threshold = 5;
565 		s64 adjustment;
566 
567 		/* Timestamp is likely inaccurate (and late) in this case */
568 		if (!(IEEE80211_SKB_RXCB(skb)->flag & RX_FLAG_MACTIME))
569 			threshold = 128;
570 
571 		adjustment =
572 			le64_to_cpu(mgmt->u.beacon.timestamp) -
573 			ieee80211_calculate_rx_timestamp(hw, &rx_status,
574 							 skb->len, 24);
575 
576 		scoped_guard(spinlock_bh, &data->tsf_offset_lock) {
577 			if (adjustment < -threshold || adjustment > threshold) {
578 				if (adjustment < -(s64)ieee80211_tu_to_usec(4) ||
579 				    adjustment > (s64)ieee80211_tu_to_usec(4))
580 					data->nan.tsf_discontinuity = true;
581 
582 				wiphy_debug(hw->wiphy,
583 					    "NAN: Adjusting TSF by +/- %d us or more: %lld us (discontinuity: %d, from: %pM, old offset: %lld)\n",
584 					    threshold, adjustment,
585 					    data->nan.tsf_discontinuity, mgmt->sa,
586 					    data->tsf_offset);
587 			} else {
588 				/* smooth things out a little bit */
589 				adjustment /= 2;
590 			}
591 
592 			/*
593 			 * Do the TSF adjustment
594 			 * The flag prevents further adjustments until the next
595 			 * 2.4 GHz DW starts to avoid race conditions for
596 			 * in-flight packets.
597 			 */
598 			data->nan.tsf_adjusted = true;
599 			data->tsf_offset += adjustment;
600 		}
601 	}
602 
603 	spin_unlock_bh(&data->nan.state_lock);
604 
605 	if (joined_cluster)
606 		ieee80211_nan_cluster_joined(data->nan.device_vif,
607 					     data->nan.cluster_id, false,
608 					     GFP_ATOMIC);
609 }
610 
611 static void
612 mac80211_hwsim_nan_exec_state_transitions(struct mac80211_hwsim_data *data)
613 {
614 	bool notify_join = false;
615 
616 	/*
617 	 * Handle NAN role and state transitions at the end of the DW period
618 	 * in accordance to Wi-Fi Aware version 4.0 section 3.3.7 point 2, i.e.
619 	 * end of 5 GHz DW if enabled else at the end of the 2.4 GHz DW.
620 	 */
621 
622 	spin_lock(&data->nan.state_lock);
623 
624 	/* Handle role transitions, Wi-Fi Aware version 4.0 section 3.3.6  */
625 	if (data->nan.master_transition_score < 3)
626 		data->nan.role = MAC80211_HWSIM_NAN_ROLE_MASTER;
627 	else if (data->nan.role == MAC80211_HWSIM_NAN_ROLE_MASTER &&
628 		 data->nan.master_transition_score >= 3)
629 		data->nan.role = MAC80211_HWSIM_NAN_ROLE_SYNC;
630 	else if (data->nan.role == MAC80211_HWSIM_NAN_ROLE_SYNC &&
631 		 data->nan.sync_transition_score >= 3)
632 		data->nan.role = MAC80211_HWSIM_NAN_ROLE_NON_SYNC;
633 	else if (data->nan.role == MAC80211_HWSIM_NAN_ROLE_NON_SYNC &&
634 		 data->nan.sync_transition_score < 3)
635 		data->nan.role = MAC80211_HWSIM_NAN_ROLE_SYNC;
636 
637 	/*
638 	 * The discovery beacon timer will stop automatically. Make sure it is
639 	 * running if we are master. Do not bother with a proper alignment it
640 	 * will sync itself to the TSF after the first TX.
641 	 */
642 	if (data->nan.role == MAC80211_HWSIM_NAN_ROLE_MASTER &&
643 	    !hrtimer_active(&data->nan.discovery_beacon_timer))
644 		hrtimer_start(&data->nan.discovery_beacon_timer,
645 			      ns_to_ktime(10 * NSEC_PER_USEC),
646 			      HRTIMER_MODE_REL_SOFT);
647 
648 	data->nan.master_transition_score = 0;
649 	data->nan.sync_transition_score = 0;
650 
651 	if (data->nan.random_factor_valid_dwst == 0) {
652 		u64 amr;
653 
654 		if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN) {
655 			data->nan.phase = MAC80211_HWSIM_NAN_PHASE_WARMUP;
656 			data->nan.random_factor_valid_dwst = NAN_WARMUP_DWST;
657 
658 			notify_join = true;
659 		} else {
660 			data->nan.phase = MAC80211_HWSIM_NAN_PHASE_UP;
661 			data->nan.random_factor_valid_dwst =
662 				get_random_u32_inclusive(120, 240);
663 			data->nan.random_factor = get_random_u8();
664 		}
665 
666 		amr = hwsim_nan_get_master_rank(data);
667 
668 		if (data->nan.current_ami.hop_count == 0) {
669 			/* Update if we are already anchor master */
670 			data->nan.current_ami.master_rank = cpu_to_le64(amr);
671 		} else if (le64_to_cpu(data->nan.current_ami.master_rank) < amr) {
672 			/* assume role if we have a higher rank */
673 			wiphy_dbg(data->hw->wiphy,
674 				  "NAN: assume anchor master role\n");
675 			data->nan.current_ami.master_rank = cpu_to_le64(amr);
676 			data->nan.current_ami.hop_count = 0;
677 			memset(&data->nan.last_ami, 0,
678 			       sizeof(data->nan.last_ami));
679 			data->nan.last_ami.ambtt = data->nan.current_ami.ambtt;
680 			data->nan.current_ami.ambtt = 0;
681 		}
682 	} else {
683 		data->nan.random_factor_valid_dwst--;
684 	}
685 
686 	spin_unlock(&data->nan.state_lock);
687 
688 	if (notify_join)
689 		ieee80211_nan_cluster_joined(data->nan.device_vif,
690 					     data->nan.cluster_id, true,
691 					     GFP_ATOMIC);
692 }
693 
694 static void
695 mac80211_hwsim_nan_tx_beacon(struct mac80211_hwsim_data *data,
696 			     bool is_discovery,
697 			     struct ieee80211_channel *channel)
698 {
699 	struct ieee80211_vendor_ie nan_ie = {
700 		.element_id = WLAN_EID_VENDOR_SPECIFIC,
701 		.len = 27 - 2,
702 		.oui = { u32_get_bits(WLAN_OUI_WFA, 0xff0000),
703 			 u32_get_bits(WLAN_OUI_WFA, 0xff00),
704 			 u32_get_bits(WLAN_OUI_WFA, 0xff) },
705 		.oui_type = WLAN_OUI_TYPE_WFA_NAN,
706 	};
707 	size_t alloc_size =
708 		IEEE80211_TX_STATUS_HEADROOM +
709 		offsetofend(struct ieee80211_mgmt, u.beacon) +
710 		27 /* size of NAN vendor element */;
711 	struct ieee80211_nan_master_indication master_indication;
712 	struct ieee80211_nan_attr nan_attr;
713 	struct ieee80211_mgmt *mgmt;
714 	struct sk_buff *skb;
715 
716 	/*
717 	 * TODO: Should the configured vendor elements or NAN attributes be
718 	 * included in some of these beacons?
719 	 */
720 
721 	skb = alloc_skb(alloc_size, GFP_ATOMIC);
722 	if (!skb)
723 		return;
724 
725 	spin_lock(&data->nan.state_lock);
726 
727 	skb_reserve(skb, IEEE80211_TX_STATUS_HEADROOM);
728 	mgmt = skb_put(skb, offsetofend(struct ieee80211_mgmt, u.beacon));
729 
730 	memset(mgmt, 0, offsetofend(struct ieee80211_mgmt, u.beacon));
731 	memcpy(mgmt->sa, data->nan.device_vif->addr, ETH_ALEN);
732 	memset(mgmt->da, 0xff, ETH_ALEN);
733 	memcpy(mgmt->bssid, data->nan.cluster_id, ETH_ALEN);
734 
735 	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
736 					  IEEE80211_STYPE_BEACON);
737 	mgmt->u.beacon.beacon_int = cpu_to_le16(is_discovery ? 100 : DWST_TU);
738 	mgmt->u.beacon.capab_info =
739 		cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME |
740 			    WLAN_CAPABILITY_SHORT_PREAMBLE);
741 
742 	/* FIXME: set these to saner values? */
743 	mgmt->duration = 0;
744 	mgmt->seq_ctrl = 0;
745 
746 	/* Put the NAN element */
747 	skb_put_data(skb, &nan_ie, sizeof(nan_ie));
748 
749 	nan_attr.attr = NAN_ATTR_MASTER_INDICATION;
750 	nan_attr.length = cpu_to_le16(sizeof(master_indication));
751 	if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_UP) {
752 		master_indication.master_pref = data->nan.master_pref;
753 		master_indication.random_factor = data->nan.random_factor;
754 	} else {
755 		master_indication.master_pref = 0;
756 		master_indication.random_factor = 0;
757 	}
758 
759 	skb_put_data(skb, &nan_attr, sizeof(nan_attr));
760 	skb_put_data(skb, &master_indication, sizeof(master_indication));
761 
762 	nan_attr.attr = NAN_ATTR_CLUSTER_INFO;
763 	nan_attr.length = cpu_to_le16(sizeof(data->nan.current_ami));
764 	skb_put_data(skb, &nan_attr, sizeof(nan_attr));
765 	skb_put_data(skb, &data->nan.current_ami,
766 		     sizeof(data->nan.current_ami));
767 
768 	spin_unlock(&data->nan.state_lock);
769 
770 	mac80211_hwsim_tx_frame(data->hw, skb, channel);
771 }
772 
773 enum hrtimer_restart
774 mac80211_hwsim_nan_slot_timer(struct hrtimer *timer)
775 {
776 	struct mac80211_hwsim_data *data =
777 		container_of(timer, struct mac80211_hwsim_data,
778 			     nan.slot_timer);
779 	struct ieee80211_hw *hw = data->hw;
780 	struct ieee80211_channel *notify_dw_chan = NULL;
781 	struct ieee80211_channel *beacon_sync_chan = NULL;
782 	u64 tsf = hwsim_nan_get_timer_tsf(data);
783 	u8 slot = hwsim_nan_slot_from_tsf(tsf);
784 	bool dwst_of_dw0 = false;
785 	bool dw_end = false;
786 	bool tx_sync_beacon;
787 
788 	if (!data->nan.device_vif)
789 		return HRTIMER_NORESTART;
790 
791 	if ((tsf & DW0_TSF_MASK & ~DWST_TSF_MASK) == 0)
792 		dwst_of_dw0 = true;
793 
794 
795 	scoped_guard(spinlock, &data->nan.state_lock) {
796 		if (data->nan.tsf_discontinuity) {
797 			data->nan.tsf_discontinuity = false;
798 
799 			mac80211_hwsim_nan_schedule_slot(data, 32, true);
800 
801 			return HRTIMER_RESTART;
802 		}
803 
804 		if (slot == SLOT_24GHZ_DW)
805 			data->nan.tsf_adjusted = false;
806 
807 		tx_sync_beacon =
808 			data->nan.phase != MAC80211_HWSIM_NAN_PHASE_SCAN &&
809 			data->nan.role != MAC80211_HWSIM_NAN_ROLE_NON_SYNC;
810 	}
811 
812 	switch (slot) {
813 	case SLOT_24GHZ_DW:
814 		wiphy_dbg(data->hw->wiphy, "Start of 2.4 GHz DW, is DW0=%d\n",
815 			  dwst_of_dw0);
816 		beacon_sync_chan = ieee80211_get_channel(hw->wiphy, 2437);
817 		break;
818 
819 	case SLOT_24GHZ_DW + 1:
820 		if (!(data->nan.bands & BIT(NL80211_BAND_5GHZ))) {
821 			notify_dw_chan = ieee80211_get_channel(hw->wiphy, 2437);
822 			dw_end = true;
823 		} else {
824 			notify_dw_chan = ieee80211_get_channel(hw->wiphy, 5745);
825 		}
826 		break;
827 
828 	case SLOT_5GHZ_DW:
829 		if (data->nan.bands & BIT(NL80211_BAND_5GHZ)) {
830 			wiphy_dbg(data->hw->wiphy, "Start of 5 GHz DW\n");
831 			beacon_sync_chan =
832 				ieee80211_get_channel(hw->wiphy, 5745);
833 		}
834 		break;
835 
836 	case SLOT_5GHZ_DW + 1:
837 		if (data->nan.bands & BIT(NL80211_BAND_5GHZ)) {
838 			notify_dw_chan =
839 				ieee80211_get_channel(hw->wiphy, 2437);
840 			dw_end = true;
841 		}
842 		break;
843 	}
844 
845 	/* TODO: This does not implement DW contention mitigation */
846 	if (beacon_sync_chan && tx_sync_beacon)
847 		mac80211_hwsim_nan_tx_beacon(data, false, beacon_sync_chan);
848 
849 	if (dw_end)
850 		mac80211_hwsim_nan_exec_state_transitions(data);
851 
852 	if (data->nan.notify_dw && notify_dw_chan) {
853 		struct wireless_dev *wdev =
854 			ieee80211_vif_to_wdev(data->nan.device_vif);
855 
856 		cfg80211_next_nan_dw_notif(wdev, notify_dw_chan, GFP_ATOMIC);
857 	}
858 
859 	mac80211_hwsim_nan_resume_txqs(data);
860 
861 	mac80211_hwsim_nan_schedule_slot(data, slot + 1, false);
862 
863 	return HRTIMER_RESTART;
864 }
865 
866 enum hrtimer_restart
867 mac80211_hwsim_nan_discovery_beacon_timer(struct hrtimer *timer)
868 {
869 	struct mac80211_hwsim_data *data =
870 		container_of(timer, struct mac80211_hwsim_data,
871 			     nan.discovery_beacon_timer);
872 	u32 remainder;
873 	u64 tsf_now;
874 	u64 tbtt;
875 
876 	if (!data->nan.device_vif)
877 		return HRTIMER_NORESTART;
878 
879 	scoped_guard(spinlock, &data->nan.state_lock) {
880 		if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN ||
881 		    data->nan.role != MAC80211_HWSIM_NAN_ROLE_MASTER)
882 			return HRTIMER_NORESTART;
883 	}
884 
885 	mac80211_hwsim_nan_tx_beacon(
886 		data, true, ieee80211_get_channel(data->hw->wiphy, 2437));
887 
888 	if (data->nan.bands & BIT(NL80211_BAND_5GHZ))
889 		mac80211_hwsim_nan_tx_beacon(
890 			data, true,
891 			ieee80211_get_channel(data->hw->wiphy, 5745));
892 
893 	/* Read the TSF from the current time in case of adjustments */
894 	tsf_now = mac80211_hwsim_get_tsf(data->hw, data->nan.device_vif);
895 
896 	/* Wrap value to be after the next TBTT */
897 	tbtt = tsf_now + ieee80211_tu_to_usec(100);
898 
899 	/* Round TBTT down to the correct time */
900 	div_u64_rem(tbtt, ieee80211_tu_to_usec(100), &remainder);
901 	tbtt = tbtt - remainder;
902 
903 	hrtimer_set_expires(&data->nan.discovery_beacon_timer,
904 			    mac80211_hwsim_tsf_to_boottime(data, tbtt));
905 
906 	return HRTIMER_RESTART;
907 }
908 
909 int mac80211_hwsim_nan_start(struct ieee80211_hw *hw,
910 			     struct ieee80211_vif *vif,
911 			     struct cfg80211_nan_conf *conf)
912 {
913 	struct mac80211_hwsim_data *data = hw->priv;
914 
915 	if (vif->type != NL80211_IFTYPE_NAN)
916 		return -EINVAL;
917 
918 	if (data->nan.device_vif)
919 		return -EALREADY;
920 
921 	/* set this before starting the timer, as preemption might occur */
922 	data->nan.device_vif = vif;
923 	data->nan.bands = conf->bands;
924 
925 	scoped_guard(spinlock_bh, &data->nan.state_lock) {
926 		/* Start in the "scan" phase and stay there for a little bit */
927 		data->nan.phase = MAC80211_HWSIM_NAN_PHASE_SCAN;
928 		data->nan.random_factor_valid_dwst = 1;
929 		data->nan.random_factor = 0;
930 		data->nan.master_pref = conf->master_pref;
931 		data->nan.role = MAC80211_HWSIM_NAN_ROLE_MASTER;
932 		memset(&data->nan.current_ami, 0,
933 		       sizeof(data->nan.current_ami));
934 		memset(&data->nan.last_ami, 0, sizeof(data->nan.last_ami));
935 		data->nan.current_ami.master_rank =
936 			cpu_to_le64(hwsim_nan_get_master_rank(data));
937 	}
938 
939 	/* Just run this "soon" and start in a random schedule position */
940 	hrtimer_start(&data->nan.slot_timer,
941 		      ns_to_ktime(10 * NSEC_PER_USEC),
942 		      HRTIMER_MODE_REL_SOFT);
943 
944 	ether_addr_copy(data->nan.cluster_id, conf->cluster_id);
945 
946 	data->nan.notify_dw = conf->enable_dw_notification;
947 
948 	return 0;
949 }
950 
951 int mac80211_hwsim_nan_stop(struct ieee80211_hw *hw,
952 			    struct ieee80211_vif *vif)
953 {
954 	struct mac80211_hwsim_data *data = hw->priv;
955 
956 	if (vif->type != NL80211_IFTYPE_NAN || !data->nan.device_vif ||
957 	    data->nan.device_vif != vif)
958 		return -EINVAL;
959 
960 	hrtimer_cancel(&data->nan.slot_timer);
961 	hrtimer_cancel(&data->nan.resume_txqs_timer);
962 	hrtimer_cancel(&data->nan.discovery_beacon_timer);
963 	data->nan.device_vif = NULL;
964 
965 	return 0;
966 }
967 
968 int mac80211_hwsim_nan_change_config(struct ieee80211_hw *hw,
969 				     struct ieee80211_vif *vif,
970 				     struct cfg80211_nan_conf *conf,
971 				     u32 changes)
972 {
973 	struct mac80211_hwsim_data *data = hw->priv;
974 
975 	if (vif->type != NL80211_IFTYPE_NAN)
976 		return -EINVAL;
977 
978 	if (!data->nan.device_vif)
979 		return -EINVAL;
980 
981 	wiphy_debug(hw->wiphy, "nan_config_changed: changes=0x%x\n", changes);
982 
983 	/* Handle only the changes we care about for simulation purposes */
984 	if (changes & CFG80211_NAN_CONF_CHANGED_BANDS)
985 		data->nan.bands = conf->bands;
986 
987 	if (changes & CFG80211_NAN_CONF_CHANGED_CONFIG)
988 		data->nan.notify_dw = conf->enable_dw_notification;
989 
990 	if (changes & CFG80211_NAN_CONF_CHANGED_PREF) {
991 		scoped_guard(spinlock_bh, &data->nan.state_lock)
992 			data->nan.master_pref = conf->master_pref;
993 	}
994 
995 	return 0;
996 }
997 
998 static void hwsim_nan_can_sta_transmit(void *_ctx, struct ieee80211_sta *sta)
999 {
1000 	struct hwsim_nan_sta_iter_ctx *ctx = _ctx;
1001 
1002 	if (ctx->can_tx)
1003 		return;
1004 
1005 	for (int i = 0; i < ARRAY_SIZE(sta->txq); i++) {
1006 		struct ieee80211_txq *txq = sta->txq[i];
1007 
1008 		if (!txq)
1009 			continue;
1010 
1011 		if (txq->vif->type != NL80211_IFTYPE_NAN &&
1012 		    txq->vif->type != NL80211_IFTYPE_NAN_DATA)
1013 			return;
1014 
1015 		if (mac80211_hwsim_nan_txq_transmitting(ctx->hw, txq)) {
1016 			ctx->can_tx = true;
1017 			return;
1018 		}
1019 	}
1020 }
1021 
1022 static void mac80211_hwsim_nan_resume_txqs(struct mac80211_hwsim_data *data)
1023 {
1024 	u64 tsf = mac80211_hwsim_get_tsf(data->hw, data->nan.device_vif);
1025 	u8 slot = hwsim_nan_slot_from_tsf(tsf);
1026 	bool is_dw_slot = mac80211_hwsim_nan_is_dw_slot(data, slot);
1027 	struct hwsim_nan_sta_iter_ctx ctx = {
1028 		.hw = data->hw,
1029 		.can_tx = false,
1030 	};
1031 	u32 timeout_ns;
1032 
1033 	/* Outside DW, require local FAW schedule to proceed */
1034 	if (!is_dw_slot) {
1035 		scoped_guard(spinlock_bh, &data->nan.state_lock) {
1036 			if (!data->nan.local_sched[slot].chan)
1037 				return;
1038 		}
1039 	}
1040 
1041 	guard(rcu)();
1042 
1043 	/* Check if management queue can transmit */
1044 	if (mac80211_hwsim_nan_txq_transmitting(data->hw,
1045 						data->nan.device_vif->txq_mgmt))
1046 		goto resume_txqs_timer;
1047 
1048 	/* Check if any STA queue can transmit */
1049 	ieee80211_iterate_stations_atomic(data->hw,
1050 					  hwsim_nan_can_sta_transmit,
1051 					  &ctx);
1052 
1053 	if (!ctx.can_tx)
1054 		return;
1055 
1056 resume_txqs_timer:
1057 	/*
1058 	 * Wait a bit and also randomize things so that not everyone is TXing
1059 	 * at the same time. Each slot is 16 TU long, this waits between 100 us
1060 	 * and 5 ms before starting to TX (unless a new frame arrives).
1061 	 */
1062 	timeout_ns = get_random_u32_inclusive(100 * NSEC_PER_USEC,
1063 					      5 * NSEC_PER_MSEC);
1064 
1065 	hrtimer_start(&data->nan.resume_txqs_timer,
1066 		      ns_to_ktime(timeout_ns),
1067 		      HRTIMER_MODE_REL_SOFT);
1068 }
1069 
1070 static void hwsim_nan_wake_sta_iter(void *_data, struct ieee80211_sta *sta)
1071 {
1072 	struct ieee80211_hw *hw = _data;
1073 
1074 	for (int i = 0; i < ARRAY_SIZE(sta->txq); i++) {
1075 		struct ieee80211_txq *txq = sta->txq[i];
1076 
1077 		if (!txq)
1078 			continue;
1079 
1080 		/* exit early if non-NAN */
1081 		if (txq->vif->type != NL80211_IFTYPE_NAN &&
1082 		    txq->vif->type != NL80211_IFTYPE_NAN_DATA)
1083 			return;
1084 
1085 		if (mac80211_hwsim_nan_txq_transmitting(hw, txq))
1086 			ieee80211_hwsim_wake_tx_queue(hw, txq);
1087 	}
1088 }
1089 
1090 enum hrtimer_restart
1091 mac80211_hwsim_nan_resume_txqs_timer(struct hrtimer *timer)
1092 {
1093 	struct mac80211_hwsim_data *data =
1094 		container_of(timer, struct mac80211_hwsim_data,
1095 			     nan.resume_txqs_timer);
1096 
1097 	guard(rcu)();
1098 
1099 	/* Wake TX queue for management frames on the NAN device interface */
1100 	if (mac80211_hwsim_nan_txq_transmitting(data->hw,
1101 						data->nan.device_vif->txq_mgmt))
1102 		ieee80211_hwsim_wake_tx_queue(data->hw,
1103 					      data->nan.device_vif->txq_mgmt);
1104 
1105 	/* Wake TX queues for all stations */
1106 	ieee80211_iterate_stations_atomic(data->hw,
1107 					  hwsim_nan_wake_sta_iter,
1108 					  data->hw);
1109 
1110 	return HRTIMER_NORESTART;
1111 }
1112 
1113 static void
1114 hwsim_nan_can_mcast_sta_transmit(void *_ctx, struct ieee80211_sta *sta)
1115 {
1116 	struct hwsim_nan_mcast_data_iter_ctx *ctx = _ctx;
1117 	struct ieee80211_txq *txq = sta->txq[0];
1118 
1119 	if (!txq || txq->vif != ctx->vif)
1120 		return;
1121 
1122 	ctx->n_vif_sta++;
1123 	if (mac80211_hwsim_nan_txq_transmitting(ctx->hw, txq))
1124 		ctx->n_sta_can_tx++;
1125 }
1126 
1127 static bool
1128 mac80211_hwsim_nan_mcast_data_transmitting(struct ieee80211_hw *hw,
1129 					   struct ieee80211_txq *txq)
1130 {
1131 	struct mac80211_hwsim_data *data = hw->priv;
1132 	struct hwsim_nan_mcast_data_iter_ctx ctx = {
1133 		.hw = hw,
1134 		.vif = txq->vif,
1135 		.n_sta_can_tx = 0,
1136 		.n_vif_sta = 0,
1137 	};
1138 
1139 	/* Check if all the stations associated with the current
1140 	 * interface are available.
1141 	 */
1142 	ieee80211_iterate_stations_atomic(data->hw,
1143 					  hwsim_nan_can_mcast_sta_transmit,
1144 					  &ctx);
1145 
1146 	return ctx.n_vif_sta && ctx.n_sta_can_tx == ctx.n_vif_sta;
1147 }
1148 
1149 bool mac80211_hwsim_nan_txq_transmitting(struct ieee80211_hw *hw,
1150 					 struct ieee80211_txq *txq)
1151 {
1152 	struct mac80211_hwsim_data *data = hw->priv;
1153 	struct ieee80211_sta *nmi_sta;
1154 	struct hwsim_sta_priv *sp;
1155 	bool is_dw_slot;
1156 	u64 tsf;
1157 	u8 slot;
1158 
1159 	if (WARN_ON_ONCE(!data->nan.device_vif))
1160 		return true;
1161 
1162 	tsf = mac80211_hwsim_get_tsf(hw, data->nan.device_vif);
1163 	slot = hwsim_nan_slot_from_tsf(tsf);
1164 
1165 	/* Enforce a maximum channel switch time and guard against TX delays */
1166 	if (slot != hwsim_nan_slot_from_tsf(tsf + NAN_CHAN_SWITCH_TIME_US))
1167 		return false;
1168 
1169 	is_dw_slot = mac80211_hwsim_nan_is_dw_slot(data, slot);
1170 
1171 	if (!txq->sta) {
1172 		/* Non-STA TXQ: allow management frames during DW */
1173 		if (txq->vif->type == NL80211_IFTYPE_NAN)
1174 			return is_dw_slot;
1175 
1176 		/* Allow multicast data when all the peers are available
1177 		 * on this slot
1178 		 */
1179 		return mac80211_hwsim_nan_mcast_data_transmitting(hw, txq);
1180 	}
1181 
1182 	/* STA TXQ: need peer schedule for availability check */
1183 	nmi_sta = rcu_dereference(txq->sta->nmi) ?: txq->sta;
1184 	sp = (void *)nmi_sta->drv_priv;
1185 
1186 	/* DW slot: NDI can TX only mgmt but not worth checking,
1187 	 * NMI checks peer's committed DW
1188 	 */
1189 	if (is_dw_slot) {
1190 		if (txq->vif->type == NL80211_IFTYPE_NAN_DATA)
1191 			return false;
1192 		return hwsim_nan_peer_present_in_dw(sp, tsf);
1193 	}
1194 
1195 	/* FAW slot: verify local schedule and peer availability */
1196 	return hwsim_nan_peer_present_in_faw(sp, data, slot);
1197 }
1198 
1199 void mac80211_hwsim_nan_get_tx_chandef(struct ieee80211_hw *hw,
1200 				       struct cfg80211_chan_def *chandef)
1201 {
1202 	struct mac80211_hwsim_data *data = hw->priv;
1203 	u64 tsf = mac80211_hwsim_get_tsf(data->hw, data->nan.device_vif);
1204 	u8 slot = hwsim_nan_slot_from_tsf(tsf);
1205 
1206 	/* DW slots are always 20 MHz */
1207 	if (slot == SLOT_24GHZ_DW) {
1208 		cfg80211_chandef_create(chandef,
1209 					ieee80211_get_channel(hw->wiphy, 2437),
1210 					NL80211_CHAN_NO_HT);
1211 		return;
1212 	}
1213 
1214 	if (slot == SLOT_5GHZ_DW && data->nan.bands & BIT(NL80211_BAND_5GHZ)) {
1215 		cfg80211_chandef_create(chandef,
1216 					ieee80211_get_channel(hw->wiphy, 5745),
1217 					NL80211_CHAN_NO_HT);
1218 		return;
1219 	}
1220 
1221 	/* FAW slot: copy local schedule for this slot */
1222 	scoped_guard(spinlock_bh, &data->nan.state_lock)
1223 		*chandef = data->nan.local_sched[slot];
1224 }
1225 
1226 bool mac80211_hwsim_nan_receive(struct ieee80211_hw *hw,
1227 				struct ieee80211_channel *channel,
1228 				struct ieee80211_rx_status *rx_status)
1229 {
1230 	struct mac80211_hwsim_data *data = hw->priv;
1231 	u8 slot;
1232 
1233 	if (WARN_ON_ONCE(!data->nan.device_vif))
1234 		return false;
1235 
1236 	if (data->nan.phase == MAC80211_HWSIM_NAN_PHASE_SCAN)
1237 		return channel->center_freq == 2437;
1238 
1239 	if (rx_status->flag & RX_FLAG_MACTIME) {
1240 		slot = hwsim_nan_slot_from_tsf(rx_status->mactime);
1241 	} else {
1242 		u64 tsf;
1243 
1244 		/*
1245 		 * This is not perfect, but that should be fine.
1246 		 *
1247 		 * Assume the frame might be a bit early in relation to our
1248 		 * own TSF. This is largely because the TSF sync is going to be
1249 		 * pretty bad when the frame was RXed via NL and the beacon as
1250 		 * well as RX timestamps are not accurate.
1251 		 */
1252 		tsf = mac80211_hwsim_get_tsf(data->hw, data->nan.device_vif);
1253 		slot = hwsim_nan_slot_from_tsf(tsf + 128);
1254 	}
1255 
1256 	if (slot == SLOT_24GHZ_DW && channel->center_freq == 2437)
1257 		return true;
1258 
1259 	if (slot == SLOT_5GHZ_DW && data->nan.bands & BIT(NL80211_BAND_5GHZ) &&
1260 	    channel->center_freq == 5745)
1261 		return true;
1262 
1263 	/* Accept frames during FAW slots if chandef is compatible */
1264 	return hwsim_nan_rx_chandef_compatible(data, slot, channel,
1265 					       rx_status->bw);
1266 }
1267 
1268 void mac80211_hwsim_nan_local_sched_changed(struct ieee80211_hw *hw,
1269 					    struct ieee80211_vif *vif)
1270 {
1271 	struct mac80211_hwsim_data *data = hw->priv;
1272 	struct ieee80211_nan_channel **slots = vif->cfg.nan_sched.schedule;
1273 
1274 	if (WARN_ON(vif->type != NL80211_IFTYPE_NAN))
1275 		return;
1276 
1277 	spin_lock_bh(&data->nan.state_lock);
1278 
1279 	for (int i = 0; i < ARRAY_SIZE(data->nan.local_sched); i++) {
1280 		struct ieee80211_chanctx_conf *chanctx;
1281 
1282 		if (!slots[i] || IS_ERR(slots[i])) {
1283 			memset(&data->nan.local_sched[i], 0,
1284 			       sizeof(data->nan.local_sched[i]));
1285 			continue;
1286 		}
1287 
1288 		chanctx = slots[i]->chanctx_conf;
1289 		if (!chanctx) {
1290 			memset(&data->nan.local_sched[i], 0,
1291 			       sizeof(data->nan.local_sched[i]));
1292 			continue;
1293 		}
1294 
1295 		data->nan.local_sched[i] = chanctx->def;
1296 	}
1297 
1298 	spin_unlock_bh(&data->nan.state_lock);
1299 }
1300 
1301 int mac80211_hwsim_nan_peer_sched_changed(struct ieee80211_hw *hw,
1302 					  struct ieee80211_sta *sta)
1303 {
1304 	struct hwsim_sta_priv *sp = (void *)sta->drv_priv;
1305 	struct ieee80211_nan_peer_sched *sched = sta->nan_sched;
1306 
1307 	spin_lock_bh(&sp->nan_sched.lock);
1308 
1309 	/* Clear existing schedule */
1310 	sp->nan_sched.committed_dw = 0;
1311 	for (int i = 0; i < CFG80211_NAN_MAX_PEER_MAPS; i++) {
1312 		sp->nan_sched.maps[i].map_id = CFG80211_NAN_INVALID_MAP_ID;
1313 		memset(sp->nan_sched.maps[i].chans, 0,
1314 		       sizeof(sp->nan_sched.maps[i].chans));
1315 	}
1316 
1317 	if (!sched)
1318 		goto out;
1319 
1320 	sp->nan_sched.committed_dw = sched->committed_dw;
1321 
1322 	for (int i = 0; i < CFG80211_NAN_MAX_PEER_MAPS; i++) {
1323 		struct ieee80211_nan_peer_map *map = &sched->maps[i];
1324 
1325 		if (map->map_id == CFG80211_NAN_INVALID_MAP_ID)
1326 			continue;
1327 
1328 		sp->nan_sched.maps[i].map_id = map->map_id;
1329 
1330 		for (int j = 0; j < CFG80211_NAN_SCHED_NUM_TIME_SLOTS; j++) {
1331 			struct ieee80211_nan_channel *peer_chan =
1332 				map->slots[j];
1333 
1334 			if (peer_chan && peer_chan->chanreq.oper.chan)
1335 				sp->nan_sched.maps[i].chans[j] =
1336 					peer_chan->chanreq.oper;
1337 			else
1338 				memset(&sp->nan_sched.maps[i].chans[j], 0,
1339 				       sizeof(sp->nan_sched.maps[i].chans[j]));
1340 		}
1341 	}
1342 
1343 out:
1344 	spin_unlock_bh(&sp->nan_sched.lock);
1345 	return 0;
1346 }
1347