| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From: Avraham Stern <avraham.stern@intel.com> |
| 2 | Date: Sun, 6 Dec 2020 14:54:45 +0200 |
| 3 | Subject: [PATCH] mac80211: support Rx timestamp calculation for all preamble |
| 4 | types |
| 5 | |
| 6 | Add support for calculating the Rx timestamp for HE frames. |
| 7 | Since now all frame types are supported, allow setting the Rx |
| 8 | timestamp regardless of the frame type. |
| 9 | |
| 10 | Signed-off-by: Avraham Stern <avraham.stern@intel.com> |
| 11 | Signed-off-by: Luca Coelho <luciano.coelho@intel.com> |
| 12 | Link: https://lore.kernel.org/r/iwlwifi.20201206145305.4786559af475.Ia54486bb0a12e5351f9d5c60ef6fcda7c9e7141c@changeid |
| 13 | Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| 14 | --- |
| 15 | |
| 16 | --- a/net/mac80211/ieee80211_i.h |
| 17 | +++ b/net/mac80211/ieee80211_i.h |
| 18 | @@ -1592,13 +1592,8 @@ ieee80211_have_rx_timestamp(struct ieee8 |
| 19 | { |
| 20 | WARN_ON_ONCE(status->flag & RX_FLAG_MACTIME_START && |
| 21 | status->flag & RX_FLAG_MACTIME_END); |
| 22 | - if (status->flag & (RX_FLAG_MACTIME_START | RX_FLAG_MACTIME_END)) |
| 23 | - return true; |
| 24 | - /* can't handle non-legacy preamble yet */ |
| 25 | - if (status->flag & RX_FLAG_MACTIME_PLCP_START && |
| 26 | - status->encoding == RX_ENC_LEGACY) |
| 27 | - return true; |
| 28 | - return false; |
| 29 | + return !!(status->flag & (RX_FLAG_MACTIME_START | RX_FLAG_MACTIME_END | |
| 30 | + RX_FLAG_MACTIME_PLCP_START)); |
| 31 | } |
| 32 | |
| 33 | void ieee80211_vif_inc_num_mcast(struct ieee80211_sub_if_data *sdata); |
| 34 | --- a/net/mac80211/util.c |
| 35 | +++ b/net/mac80211/util.c |
| 36 | @@ -3673,6 +3673,7 @@ u64 ieee80211_calculate_rx_timestamp(str |
| 37 | u64 ts = status->mactime; |
| 38 | struct rate_info ri; |
| 39 | u16 rate; |
| 40 | + u8 n_ltf; |
| 41 | |
| 42 | if (WARN_ON(!ieee80211_have_rx_timestamp(status))) |
| 43 | return 0; |
| 44 | @@ -3683,11 +3684,58 @@ u64 ieee80211_calculate_rx_timestamp(str |
| 45 | |
| 46 | /* Fill cfg80211 rate info */ |
| 47 | switch (status->encoding) { |
| 48 | + case RX_ENC_HE: |
| 49 | + ri.flags |= RATE_INFO_FLAGS_HE_MCS; |
| 50 | + ri.mcs = status->rate_idx; |
| 51 | + ri.nss = status->nss; |
| 52 | + ri.he_ru_alloc = status->he_ru; |
| 53 | + if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) |
| 54 | + ri.flags |= RATE_INFO_FLAGS_SHORT_GI; |
| 55 | + |
| 56 | + /* |
| 57 | + * See P802.11ax_D6.0, section 27.3.4 for |
| 58 | + * VHT PPDU format. |
| 59 | + */ |
| 60 | + if (status->flag & RX_FLAG_MACTIME_PLCP_START) { |
| 61 | + mpdu_offset += 2; |
| 62 | + ts += 36; |
| 63 | + |
| 64 | + /* |
| 65 | + * TODO: |
| 66 | + * For HE MU PPDU, add the HE-SIG-B. |
| 67 | + * For HE ER PPDU, add 8us for the HE-SIG-A. |
| 68 | + * For HE TB PPDU, add 4us for the HE-STF. |
| 69 | + * Add the HE-LTF durations - variable. |
| 70 | + */ |
| 71 | + } |
| 72 | + |
| 73 | + break; |
| 74 | case RX_ENC_HT: |
| 75 | ri.mcs = status->rate_idx; |
| 76 | ri.flags |= RATE_INFO_FLAGS_MCS; |
| 77 | if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) |
| 78 | ri.flags |= RATE_INFO_FLAGS_SHORT_GI; |
| 79 | + |
| 80 | + /* |
| 81 | + * See P802.11REVmd_D3.0, section 19.3.2 for |
| 82 | + * HT PPDU format. |
| 83 | + */ |
| 84 | + if (status->flag & RX_FLAG_MACTIME_PLCP_START) { |
| 85 | + mpdu_offset += 2; |
| 86 | + if (status->enc_flags & RX_ENC_FLAG_HT_GF) |
| 87 | + ts += 24; |
| 88 | + else |
| 89 | + ts += 32; |
| 90 | + |
| 91 | + /* |
| 92 | + * Add Data HT-LTFs per streams |
| 93 | + * TODO: add Extension HT-LTFs, 4us per LTF |
| 94 | + */ |
| 95 | + n_ltf = ((ri.mcs >> 3) & 3) + 1; |
| 96 | + n_ltf = n_ltf == 3 ? 4 : n_ltf; |
| 97 | + ts += n_ltf * 4; |
| 98 | + } |
| 99 | + |
| 100 | break; |
| 101 | case RX_ENC_VHT: |
| 102 | ri.flags |= RATE_INFO_FLAGS_VHT_MCS; |
| 103 | @@ -3695,6 +3743,23 @@ u64 ieee80211_calculate_rx_timestamp(str |
| 104 | ri.nss = status->nss; |
| 105 | if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) |
| 106 | ri.flags |= RATE_INFO_FLAGS_SHORT_GI; |
| 107 | + |
| 108 | + /* |
| 109 | + * See P802.11REVmd_D3.0, section 21.3.2 for |
| 110 | + * VHT PPDU format. |
| 111 | + */ |
| 112 | + if (status->flag & RX_FLAG_MACTIME_PLCP_START) { |
| 113 | + mpdu_offset += 2; |
| 114 | + ts += 36; |
| 115 | + |
| 116 | + /* |
| 117 | + * Add VHT-LTFs per streams |
| 118 | + */ |
| 119 | + n_ltf = (ri.nss != 1) && (ri.nss % 2) ? |
| 120 | + ri.nss + 1 : ri.nss; |
| 121 | + ts += 4 * n_ltf; |
| 122 | + } |
| 123 | + |
| 124 | break; |
| 125 | default: |
| 126 | WARN_ON(1); |
| 127 | @@ -3718,7 +3783,6 @@ u64 ieee80211_calculate_rx_timestamp(str |
| 128 | ri.legacy = DIV_ROUND_UP(bitrate, (1 << shift)); |
| 129 | |
| 130 | if (status->flag & RX_FLAG_MACTIME_PLCP_START) { |
| 131 | - /* TODO: handle HT/VHT preambles */ |
| 132 | if (status->band == NL80211_BAND_5GHZ) { |
| 133 | ts += 20 << shift; |
| 134 | mpdu_offset += 2; |