svn commit: r361878 - head/sys/net80211

Adrian Chadd adrian at FreeBSD.org
Sat Jun 6 22:25:00 UTC 2020


Author: adrian
Date: Sat Jun  6 22:25:00 2020
New Revision: 361878
URL: https://svnweb.freebsd.org/changeset/base/361878

Log:
  [net80211] Flip on A-MPDU, A-MSDU, A-MPDU+A-MSDU and Fast frames options.
  
  This updates the logic to allow:
  
  * A-MPDU if available;
  * A-MSDU if available and A-MPDU is off/NACKed;
  * A-MPDU+A-MSDU if it's available and negotiated;
  * Fast frames if the node is 11abg (and not HT/VHT.)
  
  This allows for things to fail back to A-MSDU or fast frames
  if A-MPDU isn't available rather than needing to be non-HT/non-VHT.
  It also allows A-MPDU+A-MSDU to work if it's negotiated.
  
  Tested:
  
  * AR9380, STA + AP mode (A-MPDU, A-MSDU, FF, A-MPDU+A-MSDU)
  * RT5350, STA mode (A-MSDU, FF)
  * AR9170, STA mode (A-MSDU, FF)

Modified:
  head/sys/net80211/ieee80211_output.c

Modified: head/sys/net80211/ieee80211_output.c
==============================================================================
--- head/sys/net80211/ieee80211_output.c	Sat Jun  6 21:26:34 2020	(r361877)
+++ head/sys/net80211/ieee80211_output.c	Sat Jun  6 22:25:00 2020	(r361878)
@@ -125,6 +125,11 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, 
 	struct ieee80211com *ic = vap->iv_ic;
 	struct ifnet *ifp = vap->iv_ifp;
 	int mcast;
+	int do_ampdu = 0;
+	int do_amsdu = 0;
+	int do_ampdu_amsdu = 0;
+	int no_ampdu = 1; /* Will be set to 0 if ampdu is active */
+	int do_ff = 0;
 
 	if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
 	    (m->m_flags & M_PWR_SAV) == 0) {
@@ -169,7 +174,28 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, 
 
 	BPF_MTAP(ifp, m);		/* 802.3 tx */
 
+
 	/*
+	 * Figure out if we can do A-MPDU, A-MSDU or FF.
+	 *
+	 * A-MPDU depends upon vap/node config.
+	 * A-MSDU depends upon vap/node config.
+	 * FF depends upon vap config, IE and whether
+	 *  it's 11abg (and not 11n/11ac/etc.)
+	 *
+	 * Note that these flags indiciate whether we can do
+	 * it at all, rather than the situation (eg traffic type.)
+	 */
+	do_ampdu = ((ni->ni_flags & IEEE80211_NODE_AMPDU_TX) &&
+	    (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_TX));
+	do_amsdu = ((ni->ni_flags & IEEE80211_NODE_AMSDU_TX) &&
+	    (vap->iv_flags_ht & IEEE80211_FHT_AMSDU_TX));
+	do_ff =
+	    ((ni->ni_flags & IEEE80211_NODE_HT) == 0) &&
+	    ((ni->ni_flags & IEEE80211_NODE_VHT) == 0) &&
+	    (IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF));
+
+	/*
 	 * Check if A-MPDU tx aggregation is setup or if we
 	 * should try to enable it.  The sta must be associated
 	 * with HT and A-MPDU enabled for use.  When the policy
@@ -186,8 +212,7 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, 
 	 * frames will always have sequence numbers allocated from the NON_QOS
 	 * TID.
 	 */
-	if ((ni->ni_flags & IEEE80211_NODE_AMPDU_TX) &&
-	    (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_TX)) {
+	if (do_ampdu) {
 		if ((m->m_flags & M_EAPOL) == 0 && (! mcast)) {
 			int tid = WME_AC_TO_TID(M_WME_GETAC(m));
 			struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[tid];
@@ -208,6 +233,23 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, 
 				ieee80211_ampdu_request(ni, tap);
 				/* XXX hold frame for reply? */
 			}
+			/*
+			 * Now update the no-ampdu flag.  A-MPDU may have been
+			 * started or administratively disabled above; so now we
+			 * know whether we're running yet or not.
+			 *
+			 * This will let us know whether we should be doing A-MSDU
+			 * at this point.  We only do A-MSDU if we're either not
+			 * doing A-MPDU, or A-MPDU is NACKed, or A-MPDU + A-MSDU
+			 * is available.
+			 *
+			 * Whilst here, update the amsdu-ampdu flag.  The above may
+			 * have also set or cleared the amsdu-in-ampdu txa_flags
+			 * combination so we can correctly do A-MPDU + A-MSDU.
+			 */
+			no_ampdu = (! IEEE80211_AMPDU_RUNNING(tap)
+			    || (IEEE80211_AMPDU_NACKED(tap)));
+			do_ampdu_amsdu = IEEE80211_AMPDU_RUNNING_AMSDU(tap);
 		}
 	}
 
@@ -222,15 +264,11 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, 
 	 * to really need to.  For A-MSDU we'd have to set the
 	 * A-MSDU QoS bit in the wifi header, so we just plain
 	 * can't do it.
-	 *
-	 * Strictly speaking, we could actually /do/ A-MSDU / FF
-	 * with A-MPDU together which for certain circumstances
-	 * is beneficial (eg A-MSDU of TCK ACKs.)  However,
-	 * I'll ignore that for now so existing behaviour is maintained.
-	 * Later on it would be good to make "amsdu + ampdu" configurable.
 	 */
-	else if (__predict_true((vap->iv_caps & IEEE80211_C_8023ENCAP) == 0)) {
-		if ((! mcast) && ieee80211_amsdu_tx_ok(ni)) {
+	if (__predict_true((vap->iv_caps & IEEE80211_C_8023ENCAP) == 0)) {
+		if ((! mcast) &&
+		    (do_ampdu_amsdu || (no_ampdu && do_amsdu)) &&
+		    ieee80211_amsdu_tx_ok(ni)) {
 			m = ieee80211_amsdu_check(ni, m);
 			if (m == NULL) {
 				/* NB: any ni ref held on stageq */
@@ -239,8 +277,7 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, 
 				    __func__);
 				return (0);
 			}
-		} else if ((! mcast) && IEEE80211_ATH_CAP(vap, ni,
-		    IEEE80211_NODE_FF)) {
+		} else if ((! mcast) && do_ff) {
 			m = ieee80211_ff_check(ni, m);
 			if (m == NULL) {
 				/* NB: any ni ref held on stageq */


More information about the svn-src-head mailing list