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