PERFORCE change 70053 for review
Sam Leffler
sam at FreeBSD.org
Mon Jan 31 13:43:53 PST 2005
http://perforce.freebsd.org/chv.cgi?CH=70053
Change 70053 by sam at sam_ebb on 2005/01/31 21:42:54
checkpoint vap work
Affected files ...
.. //depot/projects/vap/sys/dev/ath/ath_rate/onoe/onoe.c#2 edit
.. //depot/projects/vap/sys/dev/ath/ath_rate/onoe/onoe.h#2 edit
.. //depot/projects/vap/sys/dev/ath/if_ath.c#2 edit
.. //depot/projects/vap/sys/dev/ath/if_athrate.h#2 edit
.. //depot/projects/vap/sys/dev/ath/if_athvar.h#2 edit
.. //depot/projects/vap/sys/dev/iwi/if_iwi.c#2 edit
.. //depot/projects/vap/sys/dev/iwi/if_iwivar.h#2 edit
.. //depot/projects/vap/sys/dev/wi/if_wi.c#2 edit
.. //depot/projects/vap/sys/dev/wi/if_wivar.h#2 edit
.. //depot/projects/vap/sys/net/if_media.h#2 edit
.. //depot/projects/vap/sys/net80211/_ieee80211.h#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_acl.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_crypto.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_crypto.h#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_crypto_ccmp.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_crypto_none.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_crypto_tkip.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_crypto_wep.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_freebsd.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_freebsd.h#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_input.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_ioctl.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_ioctl.h#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_node.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_node.h#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_output.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_proto.c#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_proto.h#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_var.h#2 edit
.. //depot/projects/vap/sys/net80211/ieee80211_xauth.c#2 edit
.. //depot/projects/vap/tools/tools/ath/80211debug.c#2 edit
.. //depot/projects/vap/tools/tools/ath/80211stats.c#2 edit
.. //depot/projects/vap/tools/tools/ath/athstats.c#2 edit
.. //depot/projects/wifi/sbin/ifconfig/ifconfig.c#10 edit
.. //depot/projects/wifi/sbin/ifconfig/ifieee80211.c#36 edit
Differences ...
==== //depot/projects/vap/sys/dev/ath/ath_rate/onoe/onoe.c#2 (text+ko) ====
@@ -111,7 +111,6 @@
static int ath_rate_raise = 10; /* add credit threshold */
static int ath_rate_raise_threshold = 10; /* rate ctl raise threshold */
-static void ath_ratectl(void *);
static void ath_rate_update(struct ath_softc *, struct ieee80211_node *,
int rate);
static void ath_rate_ctl_start(struct ath_softc *, struct ieee80211_node *);
@@ -169,6 +168,11 @@
on->on_tx_err++;
on->on_tx_retr += ds->ds_txstat.ts_shortretry
+ ds->ds_txstat.ts_longretry;
+ if (ticks >= on->on_nextcheck) { /* XXX fixed rate */
+ ath_rate_ctl(sc, &an->an_node);
+ /* XXX halve rate for station mode */
+ on->on_nextcheck = ticks + (ath_rateinterval * hz) / 1000;
+ }
}
void
@@ -264,11 +268,11 @@
ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni)
{
#define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = ni->ni_vap;
int srate;
KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates"));
- if (ic->ic_fixed_rate == -1) {
+ if (vap->iv_fixed_rate == -1) {
/*
* No fixed rate is requested. For 11b start with
* the highest negotiated rate; otherwise, for 11g
@@ -287,21 +291,23 @@
}
} else {
/*
- * A fixed rate is to be used; ic_fixed_rate is an
+ * A fixed rate is to be used; iv_fixed_rate is an
* index into the supported rate set. Convert this
* to the index into the negotiated rate set for
* the node. We know the rate is there because the
* rate set is checked when the station associates.
*/
+ struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211vap *vap = ni->ni_vap;
const struct ieee80211_rateset *rs =
&ic->ic_sup_rates[ic->ic_curmode];
- int r = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
+ int r = rs->rs_rates[vap->iv_fixed_rate] & IEEE80211_RATE_VAL;
/* NB: the rate set is assumed sorted */
srate = ni->ni_rates.rs_nrates - 1;
for (; srate >= 0 && RATE(srate) != r; srate--)
;
KASSERT(srate >= 0,
- ("fixed rate %d not in rate set", ic->ic_fixed_rate));
+ ("fixed rate %d not in rate set", vap->iv_fixed_rate));
}
ath_rate_update(sc, ni, srate);
#undef RATE
@@ -317,22 +323,18 @@
* Reset the rate control state for each 802.11 state transition.
*/
void
-ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state)
+ath_rate_newstate(struct ieee80211vap *vap, enum ieee80211_state state)
{
- struct onoe_softc *osc = (struct onoe_softc *) sc->sc_rc;
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211com *ic = vap->iv_ic;
+ struct ath_softc *sc = ic->ic_ifp->if_softc;
struct ieee80211_node *ni;
- if (state == IEEE80211_S_INIT) {
- callout_stop(&osc->timer);
- return;
- }
- if (ic->ic_opmode == IEEE80211_M_STA) {
+ if (vap->iv_opmode == IEEE80211_M_STA) {
/*
* Reset local xmit state; this is really only
* meaningful when operating in station mode.
*/
- ni = ic->ic_bss;
+ ni = vap->iv_bss;
if (state == IEEE80211_S_RUN) {
ath_rate_ctl_start(sc, ni);
} else {
@@ -340,26 +342,11 @@
}
} else {
/*
- * When operating as a station the node table holds
- * the AP's that were discovered during scanning.
- * For any other operating mode we want to reset the
- * tx rate state of each node.
+ * Reset the tx rate state of each station/neighbor.
*/
ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, 0);
- ath_rate_update(sc, ic->ic_bss, 0);
+ ath_rate_update(sc, vap->iv_bss, 0);
}
- if (ic->ic_fixed_rate == -1 && state == IEEE80211_S_RUN) {
- int interval;
- /*
- * Start the background rate control thread if we
- * are not configured to use a fixed xmit rate.
- */
- interval = ath_rateinterval;
- if (ic->ic_opmode == IEEE80211_M_STA)
- interval /= 2;
- callout_reset(&osc->timer, (interval * hz) / 1000,
- ath_ratectl, &sc->sc_if);
- }
}
/*
@@ -373,6 +360,8 @@
struct ieee80211_rateset *rs = &ni->ni_rates;
int dir = 0, nrate, enough;
+ sc->sc_stats.ast_rate_calls++;
+
/*
* Rate control
* XXX: very primitive version.
@@ -434,30 +423,6 @@
}
static void
-ath_ratectl(void *arg)
-{
- struct ifnet *ifp = arg;
- struct ath_softc *sc = ifp->if_softc;
- struct onoe_softc *osc = (struct onoe_softc *) sc->sc_rc;
- struct ieee80211com *ic = &sc->sc_ic;
- int interval;
-
- if (ifp->if_flags & IFF_RUNNING) {
- sc->sc_stats.ast_rate_calls++;
-
- if (ic->ic_opmode == IEEE80211_M_STA)
- ath_rate_ctl(sc, ic->ic_bss); /* NB: no reference */
- else
- ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_ctl, sc);
- }
- interval = ath_rateinterval;
- if (ic->ic_opmode == IEEE80211_M_STA)
- interval /= 2;
- callout_reset(&osc->timer, (interval * hz) / 1000,
- ath_ratectl, &sc->sc_if);
-}
-
-static void
ath_rate_sysctlattach(struct ath_softc *sc)
{
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
@@ -484,7 +449,6 @@
if (osc == NULL)
return NULL;
osc->arc.arc_space = sizeof(struct onoe_node);
- callout_init(&osc->timer, debug_mpsafenet ? CALLOUT_MPSAFE : 0);
ath_rate_sysctlattach(sc);
return &osc->arc;
@@ -495,7 +459,6 @@
{
struct onoe_softc *osc = (struct onoe_softc *) arc;
- callout_drain(&osc->timer);
free(osc, M_DEVBUF);
}
==== //depot/projects/vap/sys/dev/ath/ath_rate/onoe/onoe.h#2 (text+ko) ====
@@ -45,7 +45,6 @@
/* per-device state */
struct onoe_softc {
struct ath_ratectrl arc; /* base state */
- struct callout timer; /* periodic timer */
};
/* per-node state */
@@ -64,6 +63,7 @@
u_int8_t on_tx_rate1sp; /* series 1 short preamble h/w rate */
u_int8_t on_tx_rate2sp; /* series 2 short preamble h/w rate */
u_int8_t on_tx_rate3sp; /* series 3 short preamble h/w rate */
+ int on_nextcheck; /* time of next check for rate drop */
};
#define ATH_NODE_ONOE(an) ((struct onoe_node *)&an[1])
#endif /* _DEV_ATH_RATE_ONOE_H */
==== //depot/projects/vap/sys/dev/ath/if_ath.c#2 (text+ko) ====
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.72 2005/01/18 19:33:06 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.66 2004/12/31 22:41:45 sam Exp $");
/*
* Driver for the Atheros Wireless LAN controller.
@@ -99,18 +99,19 @@
ATH_LED_POLL,
};
+static struct ieee80211vap *ath_vap_create(struct ieee80211com *, int opmode);
+static void ath_vap_delete(struct ieee80211vap *);
static void ath_init(void *);
static void ath_stop_locked(struct ifnet *);
static void ath_stop(struct ifnet *);
static void ath_start(struct ifnet *);
static int ath_reset(struct ifnet *);
-static int ath_media_change(struct ifnet *);
+static int ath_reset_vap(struct ifnet *);
static void ath_watchdog(struct ifnet *);
static int ath_ioctl(struct ifnet *, u_long, caddr_t);
static void ath_fatal_proc(void *, int);
static void ath_rxorn_proc(void *, int);
static void ath_bmiss_proc(void *, int);
-static void ath_initkeytable(struct ath_softc *);
static int ath_key_alloc(struct ieee80211com *,
const struct ieee80211_key *);
static int ath_key_delete(struct ieee80211com *,
@@ -137,8 +138,7 @@
static void ath_node_free(struct ieee80211_node *);
static u_int8_t ath_node_getrssi(const struct ieee80211_node *);
static int ath_rxbuf_init(struct ath_softc *, struct ath_buf *);
-static void ath_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
- struct ieee80211_node *ni,
+static void ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
int subtype, int rssi, u_int32_t rstamp);
static void ath_setdefantenna(struct ath_softc *, u_int);
static void ath_rx_proc(void *, int);
@@ -159,9 +159,8 @@
static void ath_chan_change(struct ath_softc *, struct ieee80211_channel *);
static void ath_next_scan(void *);
static void ath_calibrate(void *);
-static int ath_newstate(struct ieee80211com *, enum ieee80211_state, int);
-static void ath_newassoc(struct ieee80211com *,
- struct ieee80211_node *, int);
+static int ath_newstate(struct ieee80211vap *, enum ieee80211_state, int);
+static void ath_newassoc(struct ieee80211_node *, int);
static int ath_getchannels(struct ath_softc *, u_int cc,
HAL_BOOL outdoor, HAL_BOOL xchanmode);
static void ath_led_event(struct ath_softc *, int);
@@ -467,8 +466,8 @@
ifp->if_softc = sc;
ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
+ ifp->if_watchdog = ath_watchdog;
ifp->if_start = ath_start;
- ifp->if_watchdog = ath_watchdog;
ifp->if_ioctl = ath_ioctl;
ifp->if_init = ath_init;
IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
@@ -476,13 +475,12 @@
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
- ic->ic_reset = ath_reset;
+ ic->ic_reset = ath_reset_vap;
ic->ic_newassoc = ath_newassoc;
ic->ic_updateslot = ath_updateslot;
ic->ic_wme.wme_update = ath_wme_update;
/* XXX not right but it's not used anywhere important */
ic->ic_phytype = IEEE80211_T_OFDM;
- ic->ic_opmode = IEEE80211_M_STA;
ic->ic_caps =
IEEE80211_C_IBSS /* ibss, nee adhoc, mode */
| IEEE80211_C_HOSTAP /* hostap mode */
@@ -575,21 +573,21 @@
ic->ic_node_getrssi = ath_node_getrssi;
sc->sc_recv_mgmt = ic->ic_recv_mgmt;
ic->ic_recv_mgmt = ath_recv_mgmt;
- sc->sc_newstate = ic->ic_newstate;
- ic->ic_newstate = ath_newstate;
- ic->ic_crypto.cs_key_alloc = ath_key_alloc;
- ic->ic_crypto.cs_key_delete = ath_key_delete;
- ic->ic_crypto.cs_key_set = ath_key_set;
- ic->ic_crypto.cs_key_update_begin = ath_key_update_begin;
- ic->ic_crypto.cs_key_update_end = ath_key_update_end;
- /* complete initialization */
- ieee80211_media_init(ic, ath_media_change, ieee80211_media_status);
+ ic->ic_key_alloc = ath_key_alloc;
+ ic->ic_key_delete = ath_key_delete;
+ ic->ic_key_set = ath_key_set;
+ ic->ic_key_update_begin = ath_key_update_begin;
+ ic->ic_key_update_end = ath_key_update_end;
+
+ ic->ic_vap_create = ath_vap_create;
+ ic->ic_vap_delete = ath_vap_delete;
ath_bpfattach(sc);
if (bootverbose)
ieee80211_announce(ic);
ath_announce(sc);
+
return 0;
bad2:
ath_tx_cleanup(sc);
@@ -632,6 +630,78 @@
return 0;
}
+static struct ieee80211vap *
+ath_vap_create(struct ieee80211com *ic, int opmode)
+{
+ struct ath_softc *sc = ic->ic_ifp->if_softc;
+ struct ieee80211vap *vap;
+
+ /* XXX ic unlocked and race against add */
+ switch (opmode) {
+ case IEEE80211_M_STA:
+ /* XXX sta+ap for repeater application */
+ if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one for now */
+ return NULL;
+ ic->ic_opmode = opmode;
+ break;
+ case IEEE80211_M_IBSS:
+ case IEEE80211_M_AHDEMO:
+ if ((ic->ic_caps & (IEEE80211_C_IBSS << opmode)) == 0)
+ return NULL;
+ if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one for now */
+ return NULL;
+ ic->ic_opmode = opmode;
+ break;
+ case IEEE80211_M_HOSTAP:
+ case IEEE80211_M_WDS:
+ /* permit multiple ap's and/or wds links */
+ /* XXX device capability */
+ /* XXX max count */
+ /* XXX sta+ap for repeater/bridge application */
+ if (!TAILQ_EMPTY(&ic->ic_vaps) &&
+ ic->ic_opmode != IEEE80211_M_HOSTAP)
+ return NULL;
+ /*
+ * XXX Not sure if this is correct when operating only
+ * with WDS links.
+ */
+ ic->ic_opmode = IEEE80211_M_HOSTAP;
+ break;
+ case IEEE80211_M_MONITOR:
+ /* XXX always allow, is that ok? */
+ if (TAILQ_EMPTY(&ic->ic_vaps))
+ ic->ic_opmode = IEEE80211_M_MONITOR;
+ break;
+ default:
+ return NULL;
+ }
+ MALLOC(vap, struct ieee80211vap *, sizeof(struct ieee80211vap),
+ M_80211_VAP, M_NOWAIT | M_ZERO);
+ if (vap == NULL) {
+ /* XXX msg */
+ return NULL;
+ }
+ ieee80211_vap_setup(ic, vap, opmode);
+ /* override with driver methods */
+ sc->sc_newstate = vap->iv_newstate; /* XXX per-vap */
+ vap->iv_newstate = ath_newstate;
+ /* XXX multi-bssid */
+
+ /* XXX allocate+setup beacon state for hostap/ibss */
+
+ (void) ieee80211_vap_attach(vap,
+ ieee80211_media_change, ieee80211_media_status);
+
+ return vap;
+}
+
+void
+ath_vap_delete(struct ieee80211vap *vap)
+{
+ ieee80211_vap_detach(vap);
+ FREE(vap, M_80211_VAP);
+}
+
void
ath_suspend(struct ath_softc *sc)
{
@@ -639,7 +709,6 @@
DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags %x\n",
__func__, ifp->if_flags);
-
ath_stop(ifp);
}
@@ -665,7 +734,6 @@
DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags %x\n",
__func__, ifp->if_flags);
-
ath_stop(ifp);
}
@@ -763,8 +831,7 @@
* Let the hal handle the event. We assume it will
* clear whatever condition caused the interrupt.
*/
- ath_hal_mibevent(ah,
- &ATH_NODE(sc->sc_ic.ic_bss)->an_halstats);
+ ath_hal_mibevent(ah, &sc->sc_halstats);
ath_hal_intrset(ah, sc->sc_imask);
}
}
@@ -794,22 +861,9 @@
ath_bmiss_proc(void *arg, int pending)
{
struct ath_softc *sc = arg;
- struct ieee80211com *ic = &sc->sc_ic;
DPRINTF(sc, ATH_DEBUG_ANY, "%s: pending %u\n", __func__, pending);
- KASSERT(ic->ic_opmode == IEEE80211_M_STA,
- ("unexpect operating mode %u", ic->ic_opmode));
- if (ic->ic_state == IEEE80211_S_RUN) {
- /*
- * Rather than go directly to scan state, try to
- * reassociate first. If that fails then the state
- * machine will drop us into scanning after timing
- * out waiting for a probe response.
- */
- NET_LOCK_GIANT();
- ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
- NET_UNLOCK_GIANT();
- }
+ ieee80211_beacon_miss(&sc->sc_ic);
}
static u_int
@@ -839,7 +893,6 @@
struct ath_softc *sc = (struct ath_softc *) arg;
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &sc->sc_if;
- struct ieee80211_node *ni;
struct ath_hal *ah = sc->sc_ah;
HAL_STATUS status;
@@ -881,7 +934,9 @@
* in the frame output path; there's nothing to do
* here except setup the interrupt mask.
*/
+#if 0
ath_initkeytable(sc); /* XXX still needed? */
+#endif
if (ath_startrecv(sc) != 0) {
if_printf(ifp, "unable to start recv logic\n");
goto done;
@@ -901,22 +956,13 @@
sc->sc_imask |= HAL_INT_MIB;
ath_hal_intrset(ah, sc->sc_imask);
- ifp->if_flags |= IFF_RUNNING;
- ic->ic_state = IEEE80211_S_INIT;
-
/*
* The hardware should be ready to go now so it's safe
* to kick the 802.11 state machine as it's likely to
* immediately call back to us to send mgmt frames.
*/
- ni = ic->ic_bss;
- ni->ni_chan = ic->ic_ibss_chan;
- ath_chan_change(sc, ni->ni_chan);
- if (ic->ic_opmode != IEEE80211_M_MONITOR) {
- if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
- ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
- } else
- ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+ ath_chan_change(sc, ic->ic_ibss_chan);
+ ieee80211_start_running(ic); /* NB: marks IFF_RUNNING */
done:
ATH_UNLOCK(sc);
}
@@ -928,8 +974,8 @@
struct ieee80211com *ic = &sc->sc_ic;
struct ath_hal *ah = sc->sc_ah;
- DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n",
- __func__, sc->sc_invalid, ifp->if_flags);
+ DPRINTF(sc, ATH_DEBUG_ANY, "%s: %svalid, if_flags 0x%x\n",
+ __func__, sc->sc_invalid ? "in" : "", ifp->if_flags);
ATH_LOCK_ASSERT(sc);
if (ifp->if_flags & IFF_RUNNING) {
@@ -948,9 +994,7 @@
* Note that some of this work is not possible if the
* hardware is gone (invalid).
*/
- ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
- ifp->if_flags &= ~IFF_RUNNING;
- ifp->if_timer = 0;
+ ieee80211_stop_running(ic); /* NB: marks IFF_RUNNING */
if (!sc->sc_invalid) {
if (sc->sc_softled) {
callout_stop(&sc->sc_ledtimer);
@@ -1033,7 +1077,7 @@
* might change as a result.
*/
ath_chan_change(sc, c);
- if (ic->ic_state == IEEE80211_S_RUN)
+ if (sc->sc_beacons)
ath_beacon_config(sc); /* restart beacons */
ath_hal_intrset(ah, sc->sc_imask);
@@ -1041,6 +1085,14 @@
return 0;
}
+static int
+ath_reset_vap(struct ifnet *ifp)
+{
+ struct ieee80211vap *vap = ifp->if_softc;
+
+ return ath_reset(vap->iv_ic->ic_ifp);
+}
+
static int
ath_ff_always(struct ath_txq *txq, struct ath_buf *bf)
{
@@ -1093,7 +1145,7 @@
sc->sc_stats.ast_ff_flush++;
/* encap and xmit */
- bf->bf_m = ieee80211_encap(&sc->sc_ic, bf->bf_m, ni);
+ bf->bf_m = ieee80211_encap(ni, bf->bf_m);
if (bf->bf_m == NULL) {
DPRINTF(sc, ATH_DEBUG_XMIT | ATH_DEBUG_FF,
"%s: discard, encapsulation failure\n",
@@ -1211,7 +1263,6 @@
ath_ff_check(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf, struct mbuf *m, struct ieee80211_node *ni)
{
- struct ieee80211com *ic = ni->ni_ic;
struct ath_node *an = ATH_NODE(ni);
struct ath_buf *bfstaged;
int ff_flush, pri;
@@ -1302,7 +1353,7 @@
ether_sprintf(an->an_node.ni_macaddr));
/* encap and xmit */
- bfstaged->bf_m = ieee80211_encap(ic, bfstaged->bf_m, ni);
+ bfstaged->bf_m = ieee80211_encap(ni, bfstaged->bf_m);
if (bfstaged->bf_m == NULL) {
DPRINTF(sc, ATH_DEBUG_XMIT | ATH_DEBUG_FF,
"%s: discard, encap failure\n", __func__);
@@ -1354,13 +1405,12 @@
ath_start(struct ifnet *ifp)
{
struct ath_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ath_hal *ah = sc->sc_ah;
- struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
struct ath_buf *bf;
struct mbuf *m;
struct ieee80211_frame *wh;
- struct ether_header *eh;
struct ath_txq *txq;
int pri;
@@ -1388,19 +1438,6 @@
*/
IF_DEQUEUE(&ic->ic_mgtq, m);
if (m == NULL) {
- /*
- * No data frames go out unless we're associated.
- */
- if (ic->ic_state != IEEE80211_S_RUN) {
- DPRINTF(sc, ATH_DEBUG_ANY,
- "%s: ignore data packet, state %u\n",
- __func__, ic->ic_state);
- sc->sc_stats.ast_tx_discard++;
- ATH_TXBUF_LOCK(sc);
- STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
- ATH_TXBUF_UNLOCK(sc);
- break;
- }
IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */
if (m == NULL) {
ATH_TXBUF_LOCK(sc);
@@ -1408,39 +1445,9 @@
ATH_TXBUF_UNLOCK(sc);
break;
}
- /*
- * Find the node for the destination so we can do
- * things like power save and fast frames aggregation.
- */
- if (m->m_len < sizeof(struct ether_header) &&
- (m = m_pullup(m, sizeof(struct ether_header))) == NULL) {
- ic->ic_stats.is_tx_nobuf++; /* XXX */
- ni = NULL;
- goto bad;
- }
- eh = mtod(m, struct ether_header *);
- ni = ieee80211_find_txnode(ic, eh->ether_dhost);
- if (ni == NULL) {
- /* NB: ieee80211_find_txnode does stat+msg */
- goto bad;
- }
- if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
- (m->m_flags & M_PWR_SAV) == 0) {
- /*
- * Station in power save mode; pass the frame
- * to the 802.11 layer and continue. We'll get
- * the frame back when the time is right.
- */
- ieee80211_pwrsave(ic, ni, m);
- goto reclaim;
- }
- /* calculate priority so we can find the tx queue */
- if (ieee80211_classify(ic, m, ni)) {
- DPRINTF(sc, ATH_DEBUG_XMIT,
- "%s: discard, classification failure\n",
- __func__);
- goto bad;
- }
+ ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
+ m->m_pkthdr.rcvif = NULL;
+
pri = M_WME_GETAC(m);
txq = sc->sc_ac2q[pri];
if (ni->ni_flags & IEEE80211_NODE_FF) {
@@ -1464,11 +1471,10 @@
}
}
ifp->if_opackets++;
- BPF_MTAP(ifp, m);
/*
* Encapsulate the packet in prep for transmission.
*/
- m = ieee80211_encap(ic, m, ni);
+ m = ieee80211_encap(ni, m);
if (m == NULL) {
DPRINTF(sc, ATH_DEBUG_ANY,
"%s: encapsulation failure\n",
@@ -1519,34 +1525,16 @@
}
sc->sc_tx_timer = 5;
- ifp->if_timer = 1;
#if 0
/*
* Flush stale frames from the fast-frame staging queue.
*/
- if (ic->ic_opmode != IEEE80211_M_STA)
+ if (vap->iv_opmode != IEEE80211_M_STA)
ath_ff_stageq_flush(sc, txq, ath_ff_ageflushtestdone);
#endif
}
}
-static int
-ath_media_change(struct ifnet *ifp)
-{
-#define IS_UP(ifp) \
- ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
- int error;
-
- error = ieee80211_media_change(ifp);
- if (error == ENETRESET) {
- if (IS_UP(ifp))
- ath_init(ifp); /* XXX lose error */
- error = 0;
- }
- return error;
-#undef IS_UP
-}
-
#ifdef AR_DEBUG
static void
ath_keyprint(const char *tag, u_int ix,
@@ -1671,6 +1659,7 @@
#undef N
}
+#if 0
/*
* Fill the hardware key cache with key entries.
*/
@@ -1684,7 +1673,7 @@
int i;
/* XXX maybe should reset all keys when !PRIVACY */
- if (ic->ic_state == IEEE80211_S_SCAN)
+ if (ic->ic_flags & IEEE80211_F_SCAN)
bssid = ifp->if_broadcastaddr;
else
bssid = ic->ic_bss->ni_bssid;
@@ -1700,6 +1689,7 @@
}
}
}
+#endif
/*
* Allocate tx/rx key slots for TKIP. We allocate two slots for
@@ -1915,7 +1905,7 @@
* - when scanning
*/
static u_int32_t
-ath_calcrxfilter(struct ath_softc *sc, enum ieee80211_state state)
+ath_calcrxfilter(struct ath_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ath_hal *ah = sc->sc_ah;
@@ -1931,7 +1921,7 @@
rfilt |= HAL_RX_FILTER_PROM;
if (ic->ic_opmode == IEEE80211_M_STA ||
ic->ic_opmode == IEEE80211_M_IBSS ||
- state == IEEE80211_S_SCAN)
+ (ic->ic_flags & IEEE80211_F_SCAN))
rfilt |= HAL_RX_FILTER_BEACON;
return rfilt;
}
@@ -1939,15 +1929,15 @@
static void
ath_mode_init(struct ath_softc *sc)
{
+ struct ath_hal *ah = sc->sc_ah;
struct ieee80211com *ic = &sc->sc_ic;
- struct ath_hal *ah = sc->sc_ah;
struct ifnet *ifp = &sc->sc_if;
u_int32_t rfilt, mfilt[2], val;
u_int8_t pos;
struct ifmultiaddr *ifma;
/* configure rx filter */
- rfilt = ath_calcrxfilter(sc, ic->ic_state);
+ rfilt = ath_calcrxfilter(sc);
ath_hal_setrxfilter(ah, rfilt);
/* configure operational mode */
@@ -2058,7 +2048,6 @@
static int
ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_node *ni)
{
- struct ieee80211com *ic = ni->ni_ic;
struct ath_buf *bf;
struct mbuf *m;
int error;
@@ -2074,7 +2063,7 @@
* we assume the mbuf routines will return us something
* with this alignment (perhaps should assert).
*/
- m = ieee80211_beacon_alloc(ic, ni, &sc->sc_boff);
+ m = ieee80211_beacon_alloc(ni, &sc->sc_boff);
if (m == NULL) {
DPRINTF(sc, ATH_DEBUG_BEACON, "%s: cannot get mbuf\n",
__func__);
@@ -2224,7 +2213,7 @@
*/
m = bf->bf_m;
ncabq = ath_hal_numtxpending(ah, sc->sc_cabq->axq_qnum);
- if (ieee80211_beacon_update(ic, bf->bf_node, &sc->sc_boff, m, ncabq)) {
+ if (ieee80211_beacon_update(bf->bf_node, &sc->sc_boff, m, ncabq)) {
/* XXX too conservative? */
bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_dmamap, m,
@@ -2348,9 +2337,10 @@
ath_beacon_config(struct ath_softc *sc)
{
#define MS_TO_TU(x) (((x) * 1000) / 1024)
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); /*XXX*/
struct ath_hal *ah = sc->sc_ah;
- struct ieee80211com *ic = &sc->sc_ic;
- struct ieee80211_node *ni = ic->ic_bss;
+ struct ieee80211_node *ni = vap->iv_bss;
u_int32_t nexttbtt, intval;
nexttbtt = (LE_READ_4(ni->ni_tstamp.data + 4) << 22) |
@@ -2362,7 +2352,7 @@
nexttbtt = roundup(nexttbtt, intval);
DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
__func__, nexttbtt, intval, ni->ni_intval);
- if (ic->ic_opmode == IEEE80211_M_STA) {
+ if (vap->iv_opmode == IEEE80211_M_STA) {
HAL_BEACON_STATE bs;
/* NB: no PCF support right now */
@@ -2427,7 +2417,7 @@
ath_hal_intrset(ah, 0);
if (nexttbtt == intval)
intval |= HAL_BEACON_RESET_TSF;
- if (ic->ic_opmode == IEEE80211_M_IBSS) {
+ if (vap->iv_opmode == IEEE80211_M_IBSS) {
/*
* In IBSS mode enable the beacon timers but only
* enable SWBA interrupts if we need to manually
@@ -2438,7 +2428,7 @@
intval |= HAL_BEACON_ENA;
if (!sc->sc_hasveol)
sc->sc_imask |= HAL_INT_SWBA;
- } else if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+ } else if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
/*
* In AP mode we enable the beacon timers and
* SWBA interrupts to prepare beacon frames.
@@ -2453,7 +2443,7 @@
* When using a self-linked beacon descriptor in
* ibss mode load it once here.
*/
- if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol)
+ if (vap->iv_opmode == IEEE80211_M_IBSS && sc->sc_hasveol)
ath_beacon_proc(sc, 0);
}
#undef MS_TO_TU
@@ -2782,25 +2772,26 @@
* and to do ibss merges.
*/
static void
-ath_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
- struct ieee80211_node *ni,
+ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
int subtype, int rssi, u_int32_t rstamp)
{
- struct ath_softc *sc = ic->ic_ifp->if_softc;
+ struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct ieee80211vap *vap;
/*
* Call up first so subsequent work can use information
* potentially stored in the node (e.g. for ibss merge).
*/
- sc->sc_recv_mgmt(ic, m, ni, subtype, rssi, rstamp);
+ sc->sc_recv_mgmt(ni, m, subtype, rssi, rstamp);
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_BEACON:
/* update rssi statistics for use by the hal */
ATH_RSSI_LPF(ATH_NODE(ni)->an_halstats.ns_avgbrssi, rssi);
/* fall thru... */
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
- if (ic->ic_opmode == IEEE80211_M_IBSS &&
- ic->ic_state == IEEE80211_S_RUN) {
+ vap = ni->ni_vap;
+ if (vap->iv_opmode == IEEE80211_M_IBSS &&
+ vap->iv_state == IEEE80211_S_RUN) {
struct ath_hal *ah = sc->sc_ah;
/* XXX extend rstamp */
u_int64_t tsf = ath_hal_gettsf64(ah);
@@ -2816,7 +2807,7 @@
* from RUN -> RUN when this happens.
*/
if (le64toh(ni->ni_tstamp.tsf) >= tsf)
- (void) ieee80211_ibss_merge(ic, ni);
+ (void) ieee80211_ibss_merge(ni);
}
break;
}
@@ -2852,7 +2843,6 @@
struct ath_desc *ds;
struct mbuf *m;
struct ieee80211_node *ni;
- struct ath_node *an;
int len;
u_int phyerr;
HAL_STATUS status;
@@ -2935,12 +2925,15 @@
bus_dmamap_sync(sc->sc_dmat,
bf->bf_dmamap,
BUS_DMASYNC_POSTREAD);
- ieee80211_notify_michael_failure(ic,
+#if 0
+/* XXX revalidate MIC, lookup ni to find vap */
+ ieee80211_notify_michael_failure(vap,
mtod(m, struct ieee80211_frame *),
sc->sc_splitmic ?
ds->ds_rxstat.rs_keyix-32 :
ds->ds_rxstat.rs_keyix
);
+#endif
}
}
ifp->if_ierrors++;
@@ -3015,8 +3008,6 @@
sc->sc_stats.ast_ant_rx[ds->ds_rxstat.rs_antenna]++;
if (sc->sc_drvbpf) {
- const void *data;
- int hdrsize, hdrspace;
u_int8_t rix;
/*
@@ -3037,33 +3028,8 @@
sc->sc_rx_th.wr_antenna = ds->ds_rxstat.rs_antenna;
/* XXX TSF */
- /*
- * Gag, deal with hardware padding of headers. This
- * only happens for QoS frames. We copy the 802.11
- * header out-of-line and supply it separately, then
- * adjust the mbuf chain. It would be better if we
- * could just flag the packet in the radiotap header
- * and have applications DTRT.
- */
- if (len > sizeof(struct ieee80211_qosframe)) {
- data = mtod(m, const void *);
- hdrsize = ieee80211_anyhdrsize(data);
- if (hdrsize & 3) {
- bcopy(data, &sc->sc_rx_wh, hdrsize);
- hdrspace = roundup(hdrsize,
- sizeof(u_int32_t));
- m->m_data += hdrspace;
- m->m_len -= hdrspace;
- bpf_mtap2(sc->sc_drvbpf, &sc->sc_rx,
- sc->sc_rx_rt_len + hdrsize, m);
- m->m_data -= hdrspace;
- m->m_len += hdrspace;
- } else
- bpf_mtap2(sc->sc_drvbpf,
- &sc->sc_rx, sc->sc_rx_rt_len, m);
- } else
- bpf_mtap2(sc->sc_drvbpf,
- &sc->sc_rx, sc->sc_rx_rt_len, m);
+ bpf_mtap2(sc->sc_drvbpf,
+ &sc->sc_rx, sc->sc_rx_rt_len, m);
}
/*
@@ -3079,7 +3045,14 @@
}
if (IFF_DUMPPKTS(sc, ATH_DEBUG_RECV)) {
- ieee80211_dump_pkt(ic, mtod(m, caddr_t), len,
+ const struct ieee80211_frame *wh =
+ mtod(m, const struct ieee80211_frame *);
+ u_int8_t type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+ u_int8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+ if (type == IEEE80211_FC0_TYPE_DATA ||
+ (type == IEEE80211_FC0_TYPE_MGT &&
+ subtype != IEEE80211_FC0_SUBTYPE_BEACON))
+ ieee80211_dump_pkt(ic, mtod(m, caddr_t), len,
sc->sc_hwmap[ds->ds_rxstat.rs_rate].ieeerate,
ds->ds_rxstat.rs_rssi);
}
@@ -3089,13 +3062,22 @@
/*
* Locate the node for sender, track state, and then
* pass the (referenced) node up to the 802.11 layer
- * for its use.
+ * for its use. If the sender is unknown spam the
+ * frame; it'll be dropped where it's not wanted.
*/
ni = ieee80211_find_rxnode(ic,
mtod(m, const struct ieee80211_frame_min *));
+ if (ni != NULL) {
+ struct ath_node *an = ATH_NODE(ni);
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list