summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2009-05-02 20:16:55 +0000
committersam <sam@FreeBSD.org>2009-05-02 20:16:55 +0000
commit81f398305ad92fe26044bdd2aa59cb0799f3751b (patch)
tree30f6ca4cbd6d3ef52796d2af9945c2c555ff14f7 /sys/net80211
parented7c3176b96444dc82c6a07114013192611024f3 (diff)
downloadFreeBSD-src-81f398305ad92fe26044bdd2aa59cb0799f3751b.zip
FreeBSD-src-81f398305ad92fe26044bdd2aa59cb0799f3751b.tar.gz
make superg/fast-frames state dynamically-allocated (and indirect off
the com structure instead of embedded); this reduces the overhead when not configured and reduces visibility of the contents
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_superg.c35
-rw-r--r--sys/net80211/ieee80211_superg.h39
-rw-r--r--sys/net80211/ieee80211_var.h12
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 *,
OpenPOWER on IntegriCloud