summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2015-09-28 00:59:07 +0000
committeradrian <adrian@FreeBSD.org>2015-09-28 00:59:07 +0000
commit9f48c0215b9ab17be341d50b60a4fcaf14b9815b (patch)
tree14d760051a6360864836b2524b5f30e7460d283c /sys/net80211
parent4c97ea521c88b4d617af0a68f26ba8669fcb2d57 (diff)
downloadFreeBSD-src-9f48c0215b9ab17be341d50b60a4fcaf14b9815b.zip
FreeBSD-src-9f48c0215b9ab17be341d50b60a4fcaf14b9815b.tar.gz
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.
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_node.h3
-rw-r--r--sys/net80211/ieee80211_superg.c42
2 files changed, 29 insertions, 16 deletions
diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h
index bb31136..e9b7393 100644
--- a/sys/net80211/ieee80211_node.h
+++ b/sys/net80211/ieee80211_node.h
@@ -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 */
diff --git a/sys/net80211/ieee80211_superg.c b/sys/net80211/ieee80211_superg.c
index 2e2bbd1..173d4e7 100644
--- a/sys/net80211/ieee80211_superg.c
+++ b/sys/net80211/ieee80211_superg.c
@@ -530,7 +530,6 @@ ieee80211_ff_age(struct ieee80211com *ic, struct ieee80211_stageq *sq,
{
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, struct ieee80211_stageq *sq,
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 *ni, struct mbuf *m)
*/
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 *ni, struct mbuf *m)
* 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 *ni, struct mbuf *m)
"%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 *ni, struct mbuf *m)
* 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 *ni, struct mbuf *m)
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 ieee80211_node *ni)
{
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 ieee80211_node *ni)
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;
OpenPOWER on IntegriCloud