aboutsummaryrefslogtreecommitdiff
path: root/sys/net80211/ieee80211_wds.c
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2011-05-04 02:23:59 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2011-05-04 02:23:59 +0000
commitcd0b8f2d4ab91aa079aefb8d6020919579abe061 (patch)
tree2c10c692ad321ba67c135201cbef081aa5b6043d /sys/net80211/ieee80211_wds.c
parent274b0bd51dc5a3ee92b9156f90c4c63afbde32eb (diff)
downloadsrc-cd0b8f2d4ab91aa079aefb8d6020919579abe061.tar.gz
src-cd0b8f2d4ab91aa079aefb8d6020919579abe061.zip
Fix some corner cases in the net80211 sequence number retransmission
handling. The current sequence number code does a few things incorrectly: * It didn't try eliminating duplications from HT nodes. I guess it's assumed that out of order / retransmission handling would be handled by the AMPDU RX routines. If a HT node isn't doing AMPDU RX, then retransmissions need to be eliminated. Since most of my debugging is based on this (as AMPDU TX software packet aggregation isn't yet handled), handle this corner case. * When a sequence number of 4095 was received, any subsequent sequence number is going to be (by definition) less than 4095. So if the following sequence number (0) doesn't initially occur and the retransmit is received, it's incorrectly eliminated by the IEEE80211_FC1_RETRY && SEQ_LEQ() check. Try to handle this better. This almost completely eliminates out of order TCP statistics showing up during iperf testing for the 11a, 11g and non-aggregate 11n AMPDU RX case. The only other packet loss conditions leading to this are due to baseband resets or heavy interference.
Notes
Notes: svn path=/head/; revision=221418
Diffstat (limited to 'sys/net80211/ieee80211_wds.c')
-rw-r--r--sys/net80211/ieee80211_wds.c6
1 files changed, 1 insertions, 5 deletions
diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c
index 926ef578bd19..ed82fac1c086 100644
--- a/sys/net80211/ieee80211_wds.c
+++ b/sys/net80211/ieee80211_wds.c
@@ -406,7 +406,6 @@ wds_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
static int
wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
{
-#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
#define HAS_SEQ(type) ((type & 0x4) == 0)
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -495,9 +494,7 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
TID_TO_WME_AC(tid) >= WME_AC_VI)
ic->ic_wme.wme_hipri_traffic++;
rxseq = le16toh(*(uint16_t *)wh->i_seq);
- if ((ni->ni_flags & IEEE80211_NODE_HT) == 0 &&
- (wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
- SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) {
+ if (! ieee80211_check_rxseq(ni, wh)) {
/* duplicate, discard */
IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
wh->i_addr1, "duplicate",
@@ -741,7 +738,6 @@ out:
m_freem(m);
}
return type;
-#undef SEQ_LEQ
}
static void