Date: Mon, 28 Sep 2015 00:59:08 +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: r288318 - head/sys/net80211 Message-ID: <201509280059.t8S0x8UM079123@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Mon Sep 28 00:59:07 2015 New Revision: 288318 URL: https://svnweb.freebsd.org/changeset/base/288318 Log: Migrate the fast-frames transmit support away from using the txa_private field and into a separate fast-frames staging pointer in ieee80211_node. The A-MPDU TX path allows txa_private to be used by drivers. So it will clash with any attempt to use fast-frames. Now, fast-frames is not really anything special - it's just a custom ethernet frame type that contains two MSDUs into one MPDU. So all the NIC has to support doing is transmitting up to a 4KiB frame with an arbitrary ethertype and bam! Fast-frames. However, using txa_private means we can /either/ do fast-frames or A-MPDU TX, so fast frames has been turned off in the Atheros HAL for 11n chipsets. This is a bit silly - it actually means that 802.11 performance to/from 11abg Atheros chips is actually better than between an 11abg atheros device and an 11n Atheros device. So: * create a new mbuf staging queue for fast frames. It only queues a single frame in the staging queue (and there's a top-level ic staging queue used for expiry/tracking) so it's just an mbuf pointer per TID. * Still use the ampdu TX packet counter to determine whether to do aggregation or not. It'll double count if we start doing both A-MPDU TX and fast frames, but that's not all that important right now. * Initialise the pps tracker so ticks isn't zero. This ensures that fast-frames actually gets used - without it, the ticks math overflows and the pps math always sets txa_pps=0. This is the same bug that plagued A-MPDU TX starting logic. This actually allows fast-frames transmit to occur between the AR9331 (in 11n HT/20 mode) and AR9170 (if_otus) in 11bg mode. Now, this is a great big no-op on atheros 11n hardware, so don't worry. It may mean you start seeing more reliable fast-frames transmission on 11abg hardware which may expose some more amusing bugs. TODO: * further testing and debugging of all of this before flipping on fast-frames in if_ath (for 11n) and if_otus. Modified: head/sys/net80211/ieee80211_node.h head/sys/net80211/ieee80211_superg.c Modified: head/sys/net80211/ieee80211_node.h ============================================================================== --- head/sys/net80211/ieee80211_node.h Mon Sep 28 00:51:24 2015 (r288317) +++ head/sys/net80211/ieee80211_node.h Mon Sep 28 00:59:07 2015 (r288318) @@ -219,6 +219,9 @@ struct ieee80211_node { struct ieee80211_tx_ampdu ni_tx_ampdu[WME_NUM_TID]; struct ieee80211_rx_ampdu ni_rx_ampdu[WME_NUM_TID]; + /* fast-frames state */ + struct mbuf * ni_tx_superg[WME_NUM_TID]; + /* others */ short ni_inact; /* inactivity mark count */ short ni_inact_reload;/* inactivity reload value */ Modified: head/sys/net80211/ieee80211_superg.c ============================================================================== --- head/sys/net80211/ieee80211_superg.c Mon Sep 28 00:51:24 2015 (r288317) +++ head/sys/net80211/ieee80211_superg.c Mon Sep 28 00:59:07 2015 (r288318) @@ -530,7 +530,6 @@ ieee80211_ff_age(struct ieee80211com *ic { struct mbuf *m, *head; struct ieee80211_node *ni; - struct ieee80211_tx_ampdu *tap; #if 0 KASSERT(sq->head != NULL, ("stageq empty")); @@ -541,11 +540,10 @@ ieee80211_ff_age(struct ieee80211com *ic while ((m = sq->head) != NULL && M_AGE_GET(m) < quanta) { int tid = WME_AC_TO_TID(M_WME_GETAC(m)); - /* clear tap ref to frame */ + /* clear staging ref to frame */ ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - tap = &ni->ni_tx_ampdu[tid]; - KASSERT(tap->txa_private == m, ("staging queue empty")); - tap->txa_private = NULL; + KASSERT(ni->ni_tx_superg[tid] == m, ("staging queue empty")); + ni->ni_tx_superg[tid] = NULL; sq->head = m->m_nextpkt; sq->depth--; @@ -658,7 +656,12 @@ ieee80211_ff_check(struct ieee80211_node */ IEEE80211_LOCK(ic); tap = &ni->ni_tx_ampdu[WME_AC_TO_TID(pri)]; - mstaged = tap->txa_private; /* NB: we reuse AMPDU state */ + mstaged = ni->ni_tx_superg[WME_AC_TO_TID(pri)]; + /* XXX NOTE: reusing packet counter state from A-MPDU */ + /* + * XXX NOTE: this means we're double-counting; it should just + * be done in ieee80211_output.c once for both superg and A-MPDU. + */ ieee80211_txampdu_count_packet(tap); /* @@ -676,6 +679,8 @@ ieee80211_ff_check(struct ieee80211_node * If there is no frame to combine with and the pps is * too low; then do not attempt to aggregate this frame. */ + IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG, + "%s: staged: %p; pps: %d\n", __func__, mstaged, ieee80211_txampdu_getpps(tap)); if (mstaged == NULL && ieee80211_txampdu_getpps(tap) < ieee80211_ffppsmin) { IEEE80211_UNLOCK(ic); @@ -698,7 +703,7 @@ ieee80211_ff_check(struct ieee80211_node "%s: txtime %u exceeds txop limit %u\n", __func__, txtime, limit); - tap->txa_private = NULL; + ni->ni_tx_superg[WME_AC_TO_TID(pri)] = NULL; if (mstaged != NULL) stageq_remove(ic, sq, mstaged); IEEE80211_UNLOCK(ic); @@ -721,7 +726,7 @@ ieee80211_ff_check(struct ieee80211_node * hold their node reference. */ if (mstaged != NULL) { - tap->txa_private = NULL; + ni->ni_tx_superg[WME_AC_TO_TID(pri)] = NULL; stageq_remove(ic, sq, mstaged); IEEE80211_UNLOCK(ic); @@ -739,9 +744,10 @@ ieee80211_ff_check(struct ieee80211_node mstaged->m_nextpkt = m; mstaged->m_flags |= M_FF; /* NB: mark for encap work */ } else { - KASSERT(tap->txa_private == NULL, - ("txa_private %p", tap->txa_private)); - tap->txa_private = m; + KASSERT(ni->ni_tx_superg[WME_AC_TO_TID(pri)]== NULL, + ("ni_tx_superg[]: %p", + ni->ni_tx_superg[WME_AC_TO_TID(pri)])); + ni->ni_tx_superg[WME_AC_TO_TID(pri)] = m; stageq_add(ic, sq, m); IEEE80211_UNLOCK(ic); @@ -769,7 +775,6 @@ ieee80211_ff_node_cleanup(struct ieee802 { struct ieee80211com *ic = ni->ni_ic; struct ieee80211_superg *sg = ic->ic_superg; - struct ieee80211_tx_ampdu *tap; struct mbuf *m, *next_m, *head; int tid; @@ -777,11 +782,16 @@ ieee80211_ff_node_cleanup(struct ieee802 head = NULL; for (tid = 0; tid < WME_NUM_TID; tid++) { int ac = TID_TO_WME_AC(tid); - - tap = &ni->ni_tx_ampdu[tid]; - m = tap->txa_private; + /* + * XXX Initialise the packet counter. + * + * This may be double-work for 11n stations; + * but without it we never setup things. + */ + ieee80211_txampdu_init_pps(&ni->ni_tx_ampdu[tid]); + m = ni->ni_tx_superg[tid]; if (m != NULL) { - tap->txa_private = NULL; + ni->ni_tx_superg[tid] = NULL; stageq_remove(ic, &sg->ff_stageq[ac], m); m->m_nextpkt = head; head = m;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201509280059.t8S0x8UM079123>