diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_main.c b/drivers/net/wireless/virtual/mac80211_hwsim_main.c index f0f6cb7fa894..76f1028bc42e 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim_main.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim_main.c @@ -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, diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_nan.c b/drivers/net/wireless/virtual/mac80211_hwsim_nan.c index 10bbac9a4b55..805848172605 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim_nan.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim_nan.c @@ -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; +} diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_nan.h b/drivers/net/wireless/virtual/mac80211_hwsim_nan.h index 796cc17d194e..af8dd7ff00cc 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim_nan.h +++ b/drivers/net/wireless/virtual/mac80211_hwsim_nan.h @@ -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 */