mt76: report Rx timestamp

Frame reception timestamp (low 32-bits) that indicates the value of the
local TSF timer value at the time the first bit of the MAC header in the
received frame (PPDU unit) arriving at the MAC.

Signed-off-by: Ryder Lee <[email protected]>
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Ryder Lee
2021-04-11 12:49:17 +02:00
committed by Felix Fietkau
parent 028b7152b1
commit 7714dc914d
15 changed files with 89 additions and 63 deletions
+1 -1
View File
@@ -76,7 +76,7 @@ mt76_rx_aggr_check_release(struct mt76_rx_tid *tid, struct sk_buff_head *frames)
nframes--;
status = (struct mt76_rx_status *)skb->cb;
if (!time_after(jiffies,
if (!time_after32(jiffies,
status->reorder_time +
mt76_aggr_tid_to_timeo(tid->num)))
continue;
+2
View File
@@ -754,6 +754,8 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
status->signal = mstat.signal;
status->chains = mstat.chains;
status->ampdu_reference = mstat.ampdu_ref;
status->device_timestamp = mstat.timestamp;
status->mactime = mstat.timestamp;
BUILD_BUG_ON(sizeof(mstat) > sizeof(skb->cb));
BUILD_BUG_ON(sizeof(status->chain_signal) !=
+2 -1
View File
@@ -499,9 +499,10 @@ struct mt76_rx_status {
u16 wcid_idx;
};
unsigned long reorder_time;
u32 reorder_time;
u32 ampdu_ref;
u32 timestamp;
u8 iv[6];
+3
View File
@@ -548,6 +548,9 @@ int mt7603_register_device(struct mt7603_dev *dev)
hw->max_report_rates = 7;
hw->max_rate_tries = 11;
hw->radiotap_timestamp.units_pos =
IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
hw->sta_data_size = sizeof(struct mt7603_sta);
hw->vif_data_size = sizeof(struct mt7603_vif);
+17 -14
View File
@@ -532,20 +532,6 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
status->flag |= RX_FLAG_MMIC_STRIPPED | RX_FLAG_MIC_STRIPPED;
}
if (!(rxd2 & (MT_RXD2_NORMAL_NON_AMPDU_SUB |
MT_RXD2_NORMAL_NON_AMPDU))) {
status->flag |= RX_FLAG_AMPDU_DETAILS;
/* all subframes of an A-MPDU have the same timestamp */
if (dev->rx_ampdu_ts != rxd[12]) {
if (!++dev->ampdu_ref)
dev->ampdu_ref++;
}
dev->rx_ampdu_ts = rxd[12];
status->ampdu_ref = dev->ampdu_ref;
}
remove_pad = rxd1 & MT_RXD1_NORMAL_HDR_OFFSET;
if (rxd2 & MT_RXD2_NORMAL_MAX_LEN_ERROR)
@@ -579,6 +565,23 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
return -EINVAL;
}
if (rxd0 & MT_RXD0_NORMAL_GROUP_2) {
status->timestamp = le32_to_cpu(rxd[0]);
status->flag |= RX_FLAG_MACTIME_START;
if (!(rxd2 & (MT_RXD2_NORMAL_NON_AMPDU_SUB |
MT_RXD2_NORMAL_NON_AMPDU))) {
status->flag |= RX_FLAG_AMPDU_DETAILS;
/* all subframes of an A-MPDU have the same timestamp */
if (dev->rx_ampdu_ts != status->timestamp) {
if (!++dev->ampdu_ref)
dev->ampdu_ref++;
}
dev->rx_ampdu_ts = status->timestamp;
status->ampdu_ref = dev->ampdu_ref;
}
rxd += 2;
if ((u8 *)rxd - skb->data >= skb->len)
return -EINVAL;
+1 -1
View File
@@ -120,7 +120,7 @@ struct mt7603_dev {
unsigned long last_cca_adj;
u32 ampdu_ref;
__le32 rx_ampdu_ts;
u32 rx_ampdu_ts;
u8 rssi_offset[3];
u8 slottime;
+3
View File
@@ -341,6 +341,9 @@ mt7615_init_wiphy(struct ieee80211_hw *hw)
hw->max_rate_tries = 11;
hw->netdev_features = NETIF_F_RXCSUM;
hw->radiotap_timestamp.units_pos =
IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
phy->slottime = 9;
hw->sta_data_size = sizeof(struct mt7615_sta);
+17 -15
View File
@@ -235,7 +235,6 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
u32 rxd1 = le32_to_cpu(rxd[1]);
u32 rxd2 = le32_to_cpu(rxd[2]);
u32 csum_mask = MT_RXD0_NORMAL_IP_SUM | MT_RXD0_NORMAL_UDP_TCP_SUM;
__le32 rxd12 = rxd[12];
bool unicast, hdr_trans, remove_pad, insert_ccmp_hdr = false;
int phy_idx;
int i, idx;
@@ -329,6 +328,23 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
}
if (rxd0 & MT_RXD0_NORMAL_GROUP_2) {
status->timestamp = le32_to_cpu(rxd[0]);
status->flag |= RX_FLAG_MACTIME_START;
if (!(rxd2 & (MT_RXD2_NORMAL_NON_AMPDU_SUB |
MT_RXD2_NORMAL_NON_AMPDU))) {
status->flag |= RX_FLAG_AMPDU_DETAILS;
/* all subframes of an A-MPDU have the same timestamp */
if (phy->rx_ampdu_ts != status->timestamp) {
if (!++phy->ampdu_ref)
phy->ampdu_ref++;
}
phy->rx_ampdu_ts = status->timestamp;
status->ampdu_ref = phy->ampdu_ref;
}
rxd += 2;
if ((u8 *)rxd - skb->data >= skb->len)
return -EINVAL;
@@ -372,20 +388,6 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
if (!sband->channels)
return -EINVAL;
if (!(rxd2 & (MT_RXD2_NORMAL_NON_AMPDU_SUB |
MT_RXD2_NORMAL_NON_AMPDU))) {
status->flag |= RX_FLAG_AMPDU_DETAILS;
/* all subframes of an A-MPDU have the same timestamp */
if (phy->rx_ampdu_ts != rxd12) {
if (!++phy->ampdu_ref)
phy->ampdu_ref++;
}
phy->rx_ampdu_ts = rxd12;
status->ampdu_ref = phy->ampdu_ref;
}
if (rxd0 & MT_RXD0_NORMAL_GROUP_3) {
u32 rxdg0 = le32_to_cpu(rxd[0]);
u32 rxdg1 = le32_to_cpu(rxd[1]);
+1 -1
View File
@@ -168,7 +168,7 @@ struct mt7615_phy {
u8 rdd_state;
int dfs_state;
__le32 rx_ampdu_ts;
u32 rx_ampdu_ts;
u32 ampdu_ref;
struct mib_stats mib;
+3
View File
@@ -133,6 +133,9 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
hw->netdev_features = NETIF_F_RXCSUM;
hw->radiotap_timestamp.units_pos =
IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
phy->slottime = 9;
hw->sta_data_size = sizeof(struct mt7915_sta);
+16 -13
View File
@@ -389,19 +389,6 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
status->flag |= RX_FLAG_MMIC_STRIPPED | RX_FLAG_MIC_STRIPPED;
}
if (!(rxd2 & MT_RXD2_NORMAL_NON_AMPDU)) {
status->flag |= RX_FLAG_AMPDU_DETAILS;
/* all subframes of an A-MPDU have the same timestamp */
if (phy->rx_ampdu_ts != rxd[14]) {
if (!++phy->ampdu_ref)
phy->ampdu_ref++;
}
phy->rx_ampdu_ts = rxd[14];
status->ampdu_ref = phy->ampdu_ref;
}
remove_pad = FIELD_GET(MT_RXD2_NORMAL_HDR_OFFSET, rxd2);
if (rxd2 & MT_RXD2_NORMAL_MAX_LEN_ERROR)
@@ -440,6 +427,22 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
}
if (rxd1 & MT_RXD1_NORMAL_GROUP_2) {
status->timestamp = le32_to_cpu(rxd[0]);
status->flag |= RX_FLAG_MACTIME_START;
if (!(rxd2 & MT_RXD2_NORMAL_NON_AMPDU)) {
status->flag |= RX_FLAG_AMPDU_DETAILS;
/* all subframes of an A-MPDU have the same timestamp */
if (phy->rx_ampdu_ts != status->timestamp) {
if (!++phy->ampdu_ref)
phy->ampdu_ref++;
}
phy->rx_ampdu_ts = status->timestamp;
status->ampdu_ref = phy->ampdu_ref;
}
rxd += 2;
if ((u8 *)rxd - skb->data >= skb->len)
return -EINVAL;
+1 -1
View File
@@ -138,7 +138,7 @@ struct mt7915_phy {
u8 rdd_state;
int dfs_state;
__le32 rx_ampdu_ts;
u32 rx_ampdu_ts;
u32 ampdu_ref;
struct mib_stats mib;
+3
View File
@@ -77,6 +77,9 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
hw->radiotap_timestamp.units_pos =
IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
phy->slottime = 9;
hw->sta_data_size = sizeof(struct mt7921_sta);
+16 -13
View File
@@ -370,19 +370,6 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
status->flag |= RX_FLAG_MMIC_STRIPPED | RX_FLAG_MIC_STRIPPED;
}
if (!(rxd2 & MT_RXD2_NORMAL_NON_AMPDU)) {
status->flag |= RX_FLAG_AMPDU_DETAILS;
/* all subframes of an A-MPDU have the same timestamp */
if (phy->rx_ampdu_ts != rxd[14]) {
if (!++phy->ampdu_ref)
phy->ampdu_ref++;
}
phy->rx_ampdu_ts = rxd[14];
status->ampdu_ref = phy->ampdu_ref;
}
remove_pad = FIELD_GET(MT_RXD2_NORMAL_HDR_OFFSET, rxd2);
if (rxd2 & MT_RXD2_NORMAL_MAX_LEN_ERROR)
@@ -414,6 +401,22 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
}
if (rxd1 & MT_RXD1_NORMAL_GROUP_2) {
status->timestamp = le32_to_cpu(rxd[0]);
status->flag |= RX_FLAG_MACTIME_START;
if (!(rxd2 & MT_RXD2_NORMAL_NON_AMPDU)) {
status->flag |= RX_FLAG_AMPDU_DETAILS;
/* all subframes of an A-MPDU have the same timestamp */
if (phy->rx_ampdu_ts != status->timestamp) {
if (!++phy->ampdu_ref)
phy->ampdu_ref++;
}
phy->rx_ampdu_ts = status->timestamp;
status->ampdu_ref = phy->ampdu_ref;
}
rxd += 2;
if ((u8 *)rxd - skb->data >= skb->len)
return -EINVAL;
+1 -1
View File
@@ -132,7 +132,7 @@ struct mt7921_phy {
s16 coverage_class;
u8 slottime;
__le32 rx_ampdu_ts;
u32 rx_ampdu_ts;
u32 ampdu_ref;
struct mib_stats mib;