struct tx_iter_data {
struct ieee80211_channel *channel;
+ struct ieee80211_rx_status *rx_status;
+ struct ieee80211_hw *hw;
bool receive;
};
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;
}
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)
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(
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);
/* 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,
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:
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;
/* 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,
/* 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;
+}
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;
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 */