diff options
Diffstat (limited to 'sys/net80211')
-rw-r--r-- | sys/net80211/ieee80211_superg.c | 35 | ||||
-rw-r--r-- | sys/net80211/ieee80211_superg.h | 39 | ||||
-rw-r--r-- | sys/net80211/ieee80211_var.h | 12 |
3 files changed, 65 insertions, 21 deletions
diff --git a/sys/net80211/ieee80211_superg.c b/sys/net80211/ieee80211_superg.c index c6e2d28..de5df09 100644 --- a/sys/net80211/ieee80211_superg.c +++ b/sys/net80211/ieee80211_superg.c @@ -90,17 +90,38 @@ int ieee80211_ffagemax = -1; /* max time frames held on stage q */ void ieee80211_superg_attach(struct ieee80211com *ic) { + struct ieee80211_superg *sg; + + if (ic->ic_caps & IEEE80211_C_FF) { + sg = (struct ieee80211_superg *) malloc( + sizeof(struct ieee80211_superg), M_80211_VAP, + M_NOWAIT | M_ZERO); + if (sg == NULL) { + printf("%s: cannot allocate SuperG state block\n", + __func__); + return; + } + ic->ic_superg = sg; + } ieee80211_ffagemax = msecs_to_ticks(150); } void ieee80211_superg_detach(struct ieee80211com *ic) { + if (ic->ic_superg != NULL) { + free(ic->ic_superg, M_80211_VAP); + ic->ic_superg = NULL; + } } void ieee80211_superg_vattach(struct ieee80211vap *vap) { + struct ieee80211com *ic = vap->iv_ic; + + if (ic->ic_superg == NULL) /* NB: can't do fast-frames w/o state */ + vap->iv_caps &= ~IEEE80211_C_FF; if (vap->iv_caps & IEEE80211_C_FF) vap->iv_flags |= IEEE80211_F_FF; /* NB: we only implement sta mode */ @@ -527,8 +548,10 @@ ff_flush(struct mbuf *head, struct mbuf *last) * Age frames on the staging queue. */ void -ieee80211_ff_age(struct ieee80211com *ic, struct ieee80211_stageq *sq, int quanta) +ieee80211_ff_age(struct ieee80211com *ic, struct ieee80211_stageq *sq, + int quanta) { + struct ieee80211_superg *sg = ic->ic_superg; struct mbuf *m, *head; struct ieee80211_node *ni; struct ieee80211_tx_ampdu *tap; @@ -546,7 +569,7 @@ ieee80211_ff_age(struct ieee80211com *ic, struct ieee80211_stageq *sq, int quant sq->head = m->m_nextpkt; sq->depth--; - ic->ic_stageqdepth--; + sg->ff_stageqdepth--; } if (m == NULL) sq->tail = NULL; @@ -631,6 +654,7 @@ ieee80211_ff_check(struct ieee80211_node *ni, struct mbuf *m) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; + struct ieee80211_superg *sg = ic->ic_superg; const int pri = M_WME_GETAC(m); struct ieee80211_stageq *sq; struct ieee80211_tx_ampdu *tap; @@ -669,7 +693,7 @@ ieee80211_ff_check(struct ieee80211_node *ni, struct mbuf *m) IEEE80211_UNLOCK(ic); return m; } - sq = &ic->ic_ff_stageq[pri]; + sq = &sg->ff_stageq[pri]; /* * Check the txop limit to insure the aggregate fits. */ @@ -730,7 +754,7 @@ ieee80211_ff_check(struct ieee80211_node *ni, struct mbuf *m) tap->txa_private = m; stageq_add(sq, m); - ic->ic_stageqdepth++; + sg->ff_stageqdepth++; IEEE80211_UNLOCK(ic); IEEE80211_NOTE(vap, IEEE80211_MSG_SUPERG, ni, @@ -755,6 +779,7 @@ void 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, *head; int ac; @@ -766,7 +791,7 @@ ieee80211_ff_node_cleanup(struct ieee80211_node *ni) m = tap->txa_private; if (m != NULL) { tap->txa_private = NULL; - stageq_remove(&ic->ic_ff_stageq[ac], m); + stageq_remove(&sg->ff_stageq[ac], m); m->m_nextpkt = head; head = m; } diff --git a/sys/net80211/ieee80211_superg.h b/sys/net80211/ieee80211_superg.h index d627ab0..970a5fe 100644 --- a/sys/net80211/ieee80211_superg.h +++ b/sys/net80211/ieee80211_superg.h @@ -57,6 +57,18 @@ struct ieee80211_ath_ie { #define ATH_OUI_SUBTYPE 0x01 #ifdef _KERNEL +struct ieee80211_stageq { + struct mbuf *head; /* frames linked w/ m_nextpkt */ + struct mbuf *tail; /* last frame in queue */ + int depth; /* # items on head */ +}; + +struct ieee80211_superg { + /* fast-frames staging q */ + struct ieee80211_stageq ff_stageq[WME_NUM_AC]; + int ff_stageqdepth; /* cumulative depth */ +}; + void ieee80211_superg_attach(struct ieee80211com *); void ieee80211_superg_detach(struct ieee80211com *); void ieee80211_superg_vattach(struct ieee80211vap *); @@ -72,20 +84,33 @@ void ieee80211_ff_node_init(struct ieee80211_node *); void ieee80211_ff_node_cleanup(struct ieee80211_node *); struct mbuf *ieee80211_ff_check(struct ieee80211_node *, struct mbuf *); -void ieee80211_ff_age(struct ieee80211com *, struct ieee80211_stageq *, int); +void ieee80211_ff_age(struct ieee80211com *, struct ieee80211_stageq *, + int quanta); static __inline void -ieee80211_flush_stageq(struct ieee80211com *ic, int ac) +ieee80211_ff_flush(struct ieee80211com *ic, int ac) { - if (ic->ic_ff_stageq[ac].depth) - ieee80211_ff_age(ic, &ic->ic_ff_stageq[ac], 0x7fffffff); + struct ieee80211_superg *sg = ic->ic_superg; + + if (sg != NULL && sg->ff_stageq[ac].depth) + ieee80211_ff_age(ic, &sg->ff_stageq[ac], 0x7fffffff); } static __inline void -ieee80211_age_stageq(struct ieee80211com *ic, int ac, int quanta) +ieee80211_ff_age_all(struct ieee80211com *ic, int quanta) { - if (ic->ic_ff_stageq[ac].depth) - ieee80211_ff_age(ic, &ic->ic_ff_stageq[ac], quanta); + struct ieee80211_superg *sg = ic->ic_superg; + + if (sg != NULL && sg->ff_stageqdepth) { + if (sg->ff_stageq[WME_AC_VO].depth) + ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_VO], quanta); + if (sg->ff_stageq[WME_AC_VI].depth) + ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_VI], quanta); + if (sg->ff_stageq[WME_AC_BE].depth) + ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_BE], quanta); + if (sg->ff_stageq[WME_AC_BK].depth) + ieee80211_ff_age(ic, &sg->ff_stageq[WME_AC_BK], quanta); + } } struct mbuf *ieee80211_ff_encap(struct ieee80211vap *, struct mbuf *, diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 6c4ee74..09b63d2 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -110,12 +110,7 @@ struct ieee80211_tdma_param; struct ieee80211_rate_table; struct ieee80211_tx_ampdu; struct ieee80211_rx_ampdu; - -struct ieee80211_stageq { - struct mbuf *head; /* frames linked w/ m_nextpkt */ - struct mbuf *tail; /* last frame in queue */ - int depth; /* # items on head */ -}; +struct ieee80211_superg; struct ieee80211com { struct ifnet *ic_ifp; /* associated device */ @@ -211,9 +206,8 @@ struct ieee80211com { int ic_lastnonerp; /* last time non-ERP sta noted*/ int ic_lastnonht; /* last time non-HT sta noted */ - /* fast-frames staging q */ - struct ieee80211_stageq ic_ff_stageq[WME_NUM_AC]; - int ic_stageqdepth; /* cumulative depth */ + /* optional state for Atheros SuperG protocol extensions */ + struct ieee80211_superg *ic_superg; /* virtual ap create/delete */ struct ieee80211vap* (*ic_vap_create)(struct ieee80211com *, |