Commit d515fdca authored by Felix Fietkau's avatar Felix Fietkau

mt76: report rx a-mpdu subframe status

This can be used in monitor mode to figure out which subframes were sent as
part of which A-MPDU
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 055da6cf
...@@ -502,6 +502,7 @@ static struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb) ...@@ -502,6 +502,7 @@ static struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb)
status->band = mstat.band; status->band = mstat.band;
status->signal = mstat.signal; status->signal = mstat.signal;
status->chains = mstat.chains; status->chains = mstat.chains;
status->ampdu_reference = mstat.ampdu_ref;
BUILD_BUG_ON(sizeof(mstat) > sizeof(skb->cb)); BUILD_BUG_ON(sizeof(mstat) > sizeof(skb->cb));
BUILD_BUG_ON(sizeof(status->chain_signal) != BUILD_BUG_ON(sizeof(status->chain_signal) !=
......
...@@ -438,6 +438,7 @@ struct mt76_dev { ...@@ -438,6 +438,7 @@ struct mt76_dev {
spinlock_t rx_lock; spinlock_t rx_lock;
struct napi_struct napi[__MT_RXQ_MAX]; struct napi_struct napi[__MT_RXQ_MAX];
struct sk_buff_head rx_skb[__MT_RXQ_MAX]; struct sk_buff_head rx_skb[__MT_RXQ_MAX];
u32 ampdu_ref;
struct list_head txwi_cache; struct list_head txwi_cache;
struct mt76_sw_queue q_tx[__MT_TXQ_MAX]; struct mt76_sw_queue q_tx[__MT_TXQ_MAX];
...@@ -514,6 +515,8 @@ struct mt76_rx_status { ...@@ -514,6 +515,8 @@ struct mt76_rx_status {
unsigned long reorder_time; unsigned long reorder_time;
u32 ampdu_ref;
u8 iv[6]; u8 iv[6];
u8 aggr:1; u8 aggr:1;
......
...@@ -445,6 +445,20 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb) ...@@ -445,6 +445,20 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
status->flag |= RX_FLAG_MMIC_STRIPPED | RX_FLAG_MIC_STRIPPED; 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->mt76.ampdu_ref)
dev->mt76.ampdu_ref++;
}
dev->rx_ampdu_ts = rxd[12];
status->ampdu_ref = dev->mt76.ampdu_ref;
}
remove_pad = rxd1 & MT_RXD1_NORMAL_HDR_OFFSET; remove_pad = rxd1 & MT_RXD1_NORMAL_HDR_OFFSET;
if (rxd2 & MT_RXD2_NORMAL_MAX_LEN_ERROR) if (rxd2 & MT_RXD2_NORMAL_MAX_LEN_ERROR)
......
...@@ -109,6 +109,7 @@ struct mt7603_dev { ...@@ -109,6 +109,7 @@ struct mt7603_dev {
u32 false_cca_ofdm, false_cca_cck; u32 false_cca_ofdm, false_cca_cck;
unsigned long last_cca_adj; unsigned long last_cca_adj;
__le32 rx_ampdu_ts;
u8 rssi_offset[3]; u8 rssi_offset[3];
u8 slottime; u8 slottime;
......
...@@ -93,6 +93,20 @@ int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb) ...@@ -93,6 +93,20 @@ int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
status->flag |= RX_FLAG_MMIC_STRIPPED | RX_FLAG_MIC_STRIPPED; 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->mt76.ampdu_ref)
dev->mt76.ampdu_ref++;
}
dev->rx_ampdu_ts = rxd[12];
status->ampdu_ref = dev->mt76.ampdu_ref;
}
remove_pad = rxd1 & MT_RXD1_NORMAL_HDR_OFFSET; remove_pad = rxd1 & MT_RXD1_NORMAL_HDR_OFFSET;
if (rxd2 & MT_RXD2_NORMAL_MAX_LEN_ERROR) if (rxd2 & MT_RXD2_NORMAL_MAX_LEN_ERROR)
......
...@@ -81,6 +81,8 @@ struct mt7615_dev { ...@@ -81,6 +81,8 @@ struct mt7615_dev {
u32 vif_mask; u32 vif_mask;
u32 omac_mask; u32 omac_mask;
__le32 rx_ampdu_ts;
struct { struct {
u8 n_pulses; u8 n_pulses;
u32 period; u32 period;
......
...@@ -789,6 +789,21 @@ int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb, ...@@ -789,6 +789,21 @@ int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
if ((rxinfo & MT_RXINFO_BA) && !(rxinfo & MT_RXINFO_NULL)) if ((rxinfo & MT_RXINFO_BA) && !(rxinfo & MT_RXINFO_NULL))
status->aggr = true; status->aggr = true;
if (rxinfo & MT_RXINFO_AMPDU) {
status->flag |= RX_FLAG_AMPDU_DETAILS;
status->ampdu_ref = dev->mt76.ampdu_ref;
/*
* When receiving an A-MPDU subframe and RSSI info is not valid,
* we can assume that more subframes belonging to the same A-MPDU
* are coming. The last one will have valid RSSI info
*/
if (!(rxinfo & MT_RXINFO_RSSI)) {
if (!++dev->mt76.ampdu_ref)
dev->mt76.ampdu_ref++;
}
}
if (WARN_ON_ONCE(len > skb->len)) if (WARN_ON_ONCE(len > skb->len))
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment