Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Nov 2016 18:36:40 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r308485 - head/sys/net80211
Message-ID:  <201611101836.uAAIaeUE082291@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Thu Nov 10 18:36:40 2016
New Revision: 308485
URL: https://svnweb.freebsd.org/changeset/base/308485

Log:
  [net80211] implement "first RX defines the BAW" hack.
  
  Unfortunately (sigh) some firmware doesn't provide the RX BA starting point,
  so we need to cope and set a "close enough" sequence number so we (hopefully!)
  don't discard frames as duplicates.
  
  Tested:
  
  * QCA9880v2, athp driver (under development), STA mode

Modified:
  head/sys/net80211/ieee80211_ht.c
  head/sys/net80211/ieee80211_ht.h

Modified: head/sys/net80211/ieee80211_ht.c
==============================================================================
--- head/sys/net80211/ieee80211_ht.c	Thu Nov 10 16:27:34 2016	(r308484)
+++ head/sys/net80211/ieee80211_ht.c	Thu Nov 10 18:36:40 2016	(r308485)
@@ -582,7 +582,13 @@ ieee80211_ampdu_rx_start_ext(struct ieee
 	memset(rap, 0, sizeof(*rap));
 	rap->rxa_wnd = (baw== 0) ?
 	    IEEE80211_AGGR_BAWMAX : min(baw, IEEE80211_AGGR_BAWMAX);
-	rap->rxa_start = seq;
+	if (seq == -1) {
+		/* Wait for the first RX frame, use that as BAW */
+		rap->rxa_start = 0;
+		rap->rxa_flags |= IEEE80211_AGGR_WAITRX;
+	} else {
+		rap->rxa_start = seq;
+	}
 	rap->rxa_flags |=  IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_XCHGPEND;
 
 	IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni,
@@ -617,7 +623,9 @@ ampdu_rx_stop(struct ieee80211_node *ni,
 {
 
 	ampdu_rx_purge(rap);
-	rap->rxa_flags &= ~(IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_XCHGPEND);
+	rap->rxa_flags &= ~(IEEE80211_AGGR_RUNNING
+	    | IEEE80211_AGGR_XCHGPEND
+	    | IEEE80211_AGGR_WAITRX);
 }
 
 /*
@@ -842,6 +850,16 @@ ieee80211_ampdu_reorder(struct ieee80211
 	}
 	rxseq >>= IEEE80211_SEQ_SEQ_SHIFT;
 	rap->rxa_nframes++;
+
+	/*
+	 * Handle waiting for the first frame to define the BAW.
+	 * Some firmware doesn't provide the RX of the starting point
+	 * of the BAW and we have to cope.
+	 */
+	if (rap->rxa_flags & IEEE80211_AGGR_WAITRX) {
+		rap->rxa_flags &= ~IEEE80211_AGGR_WAITRX;
+		rap->rxa_start = rxseq;
+	}
 again:
 	if (rxseq == rap->rxa_start) {
 		/*

Modified: head/sys/net80211/ieee80211_ht.h
==============================================================================
--- head/sys/net80211/ieee80211_ht.h	Thu Nov 10 16:27:34 2016	(r308484)
+++ head/sys/net80211/ieee80211_ht.h	Thu Nov 10 18:36:40 2016	(r308485)
@@ -44,6 +44,7 @@ struct ieee80211_tx_ampdu {
 #define	IEEE80211_AGGR_SETUP		0x0008	/* deferred state setup */
 #define	IEEE80211_AGGR_NAK		0x0010	/* peer NAK'd ADDBA request */
 #define	IEEE80211_AGGR_BARPEND		0x0020	/* BAR response pending */
+#define	IEEE80211_AGGR_WAITRX		0x0040	/* Wait for first RX frame to define BAW */
 	uint8_t		txa_tid;
 	uint8_t		txa_token;	/* dialog token */
 	int		txa_lastsample;	/* ticks @ last traffic sample */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611101836.uAAIaeUE082291>