diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_i.h b/drivers/net/wireless/virtual/mac80211_hwsim_i.h index 741eb08f8a85..b4d0a3869619 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim_i.h +++ b/drivers/net/wireless/virtual/mac80211_hwsim_i.h @@ -104,8 +104,6 @@ struct mac80211_hwsim_data { /* difference between this hw's clock and the real clock, in usecs */ s64 tsf_offset; s64 bcn_delta; - /* absolute beacon transmission time. Used to cover up "tx" delay. */ - u64 abs_bcn_ts; /* Stats */ u64 tx_pkts; diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_main.c b/drivers/net/wireless/virtual/mac80211_hwsim_main.c index 3bda5532ab62..5bf6541498ec 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim_main.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim_main.c @@ -1523,6 +1523,43 @@ static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate) return result; } +static void mac80211_hwsim_write_tsf(struct mac80211_hwsim_data *data, + struct sk_buff *skb, u64 sim_time) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + struct ieee80211_rate *txrate; + /* TODO: get MCS */ + int bitrate = 100; + + txrate = ieee80211_get_tx_rate(data->hw, info); + if (txrate) + bitrate = txrate->bitrate; + + if (skb->len >= offsetofend(typeof(*mgmt), u.probe_resp.timestamp) && + ieee80211_is_probe_resp(hdr->frame_control)) { + mgmt->u.probe_resp.timestamp = + cpu_to_le64(sim_time + data->tsf_offset + + 24 * 8 * 10 / bitrate); + } else if (skb->len >= offsetofend(typeof(*mgmt), u.beacon.timestamp) && + ieee80211_is_beacon(mgmt->frame_control)) { + mgmt->u.beacon.timestamp = cpu_to_le64(sim_time + + data->tsf_offset + + 24 * 8 * 10 / + bitrate); + } else if (skb->len >= offsetofend(struct ieee80211_ext, + u.s1g_beacon.timestamp) && + ieee80211_is_s1g_beacon(mgmt->frame_control)) { + struct ieee80211_ext *ext = (void *)mgmt; + + ext->u.s1g_beacon.timestamp = cpu_to_le32(sim_time + + data->tsf_offset + + 10 * 8 * 10 / + bitrate); + } +} + static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, struct sk_buff *my_skb, int dst_portid, @@ -1538,6 +1575,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES]; struct hwsim_tx_rate_flag tx_attempts_flags[IEEE80211_TX_MAX_RATES]; uintptr_t cookie; + u64 sim_tsf; if (data->ps != PS_DISABLED) hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); @@ -1550,6 +1588,9 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, } } + sim_tsf = mac80211_hwsim_get_sim_tsf(); + mac80211_hwsim_write_tsf(data, my_skb, sim_tsf); + skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC); if (skb == NULL) goto nla_put_failure; @@ -1781,7 +1822,11 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_rx_status rx_status; - u64 sim_tsf; + u64 sim_tsf = mac80211_hwsim_get_sim_tsf(); + + mac80211_hwsim_write_tsf(data, skb, sim_tsf); + + mac80211_hwsim_monitor_rx(hw, skb, chan); memset(&rx_status, 0, sizeof(rx_status)); rx_status.flag |= RX_FLAG_MACTIME_START; @@ -1824,20 +1869,9 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, skb_ext_reset(skb); nf_reset_ct(skb); - /* - * Get absolute mactime here so all HWs RX at the "same time", and - * absolute TX time for beacon mactime so the timestamp matches. - * Giving beacons a different mactime than non-beacons looks messy, but - * it helps the Toffset be exact and a ~10us mactime discrepancy - * probably doesn't really matter. - */ if (ieee80211_is_beacon(hdr->frame_control) || - ieee80211_is_probe_resp(hdr->frame_control)) { + ieee80211_is_probe_resp(hdr->frame_control)) rx_status.boottime_ns = ktime_get_boottime_ns(); - sim_tsf = data->abs_bcn_ts; - } else { - sim_tsf = mac80211_hwsim_get_sim_tsf(); - } /* Copy skb to all enabled radios that are on the current frequency */ spin_lock(&hwsim_radio_lock); @@ -2137,27 +2171,6 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, return; } - if (skb->len >= 24 + 8 && - ieee80211_is_probe_resp(hdr->frame_control)) { - /* fake header transmission time */ - struct ieee80211_mgmt *mgmt; - struct ieee80211_rate *txrate; - /* TODO: get MCS */ - int bitrate = 100; - u64 ts; - - mgmt = (struct ieee80211_mgmt *)skb->data; - txrate = ieee80211_get_tx_rate(hw, txi); - if (txrate) - bitrate = txrate->bitrate; - ts = mac80211_hwsim_get_sim_tsf(); - mgmt->u.probe_resp.timestamp = - cpu_to_le64(ts + data->tsf_offset + - 24 * 8 * 10 / bitrate); - } - - mac80211_hwsim_monitor_rx(hw, skb, channel); - /* wmediumd mode check */ _portid = READ_ONCE(data->wmediumd); @@ -2291,8 +2304,6 @@ static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, ARRAY_SIZE(txi->control.rates)); } - mac80211_hwsim_monitor_rx(hw, skb, chan); - if (_portid || hwsim_virtio_enabled) return mac80211_hwsim_tx_frame_nl(hw, skb, _portid, chan); @@ -2310,10 +2321,6 @@ static void __mac80211_hwsim_beacon_tx(struct ieee80211_bss_conf *link_conf, { struct hwsim_vif_priv *vp = (void *)vif->drv_priv; struct ieee80211_tx_info *info; - struct ieee80211_rate *txrate; - struct ieee80211_mgmt *mgmt; - /* TODO: get MCS */ - int bitrate = 100; if (vp->skip_beacons[link_conf->link_id]) { vp->skip_beacons[link_conf->link_id]--; @@ -2327,27 +2334,6 @@ static void __mac80211_hwsim_beacon_tx(struct ieee80211_bss_conf *link_conf, info->control.rates, ARRAY_SIZE(info->control.rates)); - txrate = ieee80211_get_tx_rate(hw, info); - if (txrate) - bitrate = txrate->bitrate; - - mgmt = (struct ieee80211_mgmt *) skb->data; - /* fake header transmission time */ - data->abs_bcn_ts = mac80211_hwsim_get_sim_tsf(); - if (ieee80211_is_s1g_beacon(mgmt->frame_control)) { - struct ieee80211_ext *ext = (void *) mgmt; - - ext->u.s1g_beacon.timestamp = cpu_to_le32(data->abs_bcn_ts + - data->tsf_offset + - 10 * 8 * 10 / - bitrate); - } else { - mgmt->u.beacon.timestamp = cpu_to_le64(data->abs_bcn_ts + - data->tsf_offset + - 24 * 8 * 10 / - bitrate); - } - mac80211_hwsim_tx_frame(hw, skb, rcu_dereference(link_conf->chanctx_conf)->def.chan); } @@ -6033,6 +6019,8 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, if (!found) goto out; + mac80211_hwsim_monitor_rx(data2->hw, skb, data2->channel); + /* Tx info received because the frame was broadcasted on user space, so we get all the necessary info: tx attempts and skb control buff */