svn commit: r330233 - stable/11/sys/net80211
Eitan Adler
eadler at FreeBSD.org
Thu Mar 1 08:05:54 UTC 2018
Author: eadler
Date: Thu Mar 1 08:05:52 2018
New Revision: 330233
URL: https://svnweb.freebsd.org/changeset/base/330233
Log:
MFC r324570,r324580:
[net80211] begin handling multiple hardware decap'ed A-MSDU in the RX path.
The duplicate detection code currently expects A-MSDU frames to be encaped -
they're decap'ed /after/ duplicate detection.
However for ath10k (and iwm hardware later on) the firmware supports
doing A-MSDU decap in hardware - which shows up as multiple frames with
the same sequence number and IV.
This is the first part of decap handling - if we see a stretch of A-MSDU
frames from the driver with the MORE bit set, then don't treat them
as duplicates.
This isn't 100% complete as crypto sequence number handling and "A-MSDU in
A-MPDU" needs handling, but it's a start.
This should be a glorified no-op for everyone. Please tell me if it isn't.
Modified:
stable/11/sys/net80211/ieee80211_input.h
stable/11/sys/net80211/ieee80211_ioctl.h
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/net80211/ieee80211_input.h
==============================================================================
--- stable/11/sys/net80211/ieee80211_input.h Thu Mar 1 07:59:14 2018 (r330232)
+++ stable/11/sys/net80211/ieee80211_input.h Thu Mar 1 08:05:52 2018 (r330233)
@@ -131,7 +131,39 @@ ishtinfooui(const uint8_t *frm)
return frm[1] > 3 && le32dec(frm+2) == ((BCM_OUI_HTINFO<<24)|BCM_OUI);
}
+static __inline int
+ieee80211_check_rxseq_amsdu(const struct ieee80211_rx_stats *rxs)
+{
+
+ return (!! (rxs->c_pktflags & IEEE80211_RX_F_AMSDU));
+}
+
/*
+ * Return 1 if the rxseq check should increment the sequence
+ * number. Return 0 if it's part of an AMSDU batch and it isn't
+ * the final frame in the decap'ed burst.
+ */
+static __inline int
+ieee80211_check_rxseq_amsdu_more(const struct ieee80211_rx_stats *rxs)
+{
+ /* No state? ok */
+ if (rxs == NULL)
+ return (1);
+
+ /* State but no AMSDU set? ok */
+ if ((rxs->c_pktflags & IEEE80211_RX_F_AMSDU) == 0)
+ return (1);
+
+ /* State, AMSDU set, then _MORE means "don't inc yet" */
+ if (rxs->c_pktflags & IEEE80211_RX_F_AMSDU_MORE) {
+ return (0);
+ }
+
+ /* Both are set, so return ok */
+ return (1);
+}
+
+/*
* Check the current frame sequence number against the current TID
* state and return whether it's in sequence or should be dropped.
*
@@ -225,7 +257,20 @@ ieee80211_check_rxseq(struct ieee80211_node *ni, struc
goto fail;
ok:
- ni->ni_rxseqs[tid] = rxseq;
+ /*
+ * Only bump the sequence number if it's the last frame
+ * in a batch. That way frames in the rest of the batch
+ * get included, and the last frame in the batch kicks
+ * it next.
+ */
+ if (ieee80211_check_rxseq_amsdu_more(rxs)) {
+ ni->ni_rxseqs[tid] = rxseq;
+ if ((rxs != NULL) && ieee80211_check_rxseq_amsdu(rxs))
+ IEEE80211_NODE_STAT(ni, rx_amsdu_more_end);
+ } else {
+ /* .. still waiting */
+ IEEE80211_NODE_STAT(ni, rx_amsdu_more);
+ }
return 1;
Modified: stable/11/sys/net80211/ieee80211_ioctl.h
==============================================================================
--- stable/11/sys/net80211/ieee80211_ioctl.h Thu Mar 1 07:59:14 2018 (r330232)
+++ stable/11/sys/net80211/ieee80211_ioctl.h Thu Mar 1 08:05:52 2018 (r330233)
@@ -84,7 +84,11 @@ struct ieee80211_nodestats {
uint32_t ns_tx_deauth_code; /* last deauth reason */
uint32_t ns_tx_disassoc; /* disassociations */
uint32_t ns_tx_disassoc_code; /* last disassociation reason */
- uint32_t ns_spare[8];
+
+ /* Hardware A-MSDU decode */
+ uint32_t ns_rx_amsdu_more; /* RX decap A-MSDU, more coming from A-MSDU */
+ uint32_t ns_rx_amsdu_more_end; /* RX decap A-MSDU (or any other frame), no more coming */
+ uint32_t ns_spare[6];
};
/*
More information about the svn-src-stable-11
mailing list