diff options
author | Avraham Stern <avraham.stern@intel.com> | 2022-01-26 12:15:31 +0300 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2022-07-22 15:28:29 +0300 |
commit | f9202638df34474f862109731203e71d8e71f85e (patch) | |
tree | e43fac0e56e1d25d9bb24ea52ba0f2a560592349 /net/mac80211/rx.c | |
parent | 1ff715ffa0ec1b5af9093c43185e686f575f15cc (diff) | |
download | linux-f9202638df34474f862109731203e71d8e71f85e.tar.xz |
wifi: mac80211: add hardware timestamps for RX and TX
When the low level driver reports hardware timestamps for frame
TX status or frame RX, pass the timestamps to cfg80211.
Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 9054a1e0b0d8..ef9c2fcd68f5 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -3644,7 +3644,11 @@ static ieee80211_rx_result debug_noinline ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); - int sig = 0; + struct cfg80211_rx_info info = { + .freq = ieee80211_rx_status_to_khz(status), + .buf = rx->skb->data, + .len = rx->skb->len + }; /* skip known-bad action frames and return them in the next handler */ if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) @@ -3659,11 +3663,15 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) if (ieee80211_hw_check(&rx->local->hw, SIGNAL_DBM) && !(status->flag & RX_FLAG_NO_SIGNAL_VAL)) - sig = status->signal; + info.sig_dbm = status->signal; + + if (ieee80211_is_timing_measurement(rx->skb) || + ieee80211_is_ftm(rx->skb)) { + info.rx_tstamp = ktime_to_ns(skb_hwtstamps(rx->skb)->hwtstamp); + info.ack_tstamp = ktime_to_ns(status->ack_tx_hwtstamp); + } - if (cfg80211_rx_mgmt_khz(&rx->sdata->wdev, - ieee80211_rx_status_to_khz(status), sig, - rx->skb->data, rx->skb->len, 0)) { + if (cfg80211_rx_mgmt_ext(&rx->sdata->wdev, &info)) { if (rx->sta) rx->sta->deflink.rx_stats.packets++; dev_kfree_skb(rx->skb); @@ -4758,8 +4766,10 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, } if (!consume) { - skb = skb_copy(skb, GFP_ATOMIC); - if (!skb) { + struct skb_shared_hwtstamps *shwt; + + rx->skb = skb_copy(skb, GFP_ATOMIC); + if (!rx->skb) { if (net_ratelimit()) wiphy_debug(local->hw.wiphy, "failed to copy skb for %s\n", @@ -4767,7 +4777,11 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, return true; } - rx->skb = skb; + /* skb_copy() does not copy the hw timestamps, so copy it + * explicitly + */ + shwt = skb_hwtstamps(rx->skb); + shwt->hwtstamp = skb_hwtstamps(skb)->hwtstamp; } if (unlikely(link_sta)) { |