From owner-p4-projects@FreeBSD.ORG Mon Jan 31 21:43:53 2005 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0D07716A4D1; Mon, 31 Jan 2005 21:43:53 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D223C16A4CE for ; Mon, 31 Jan 2005 21:43:52 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7887C43D45 for ; Mon, 31 Jan 2005 21:43:52 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j0VLhqde077592 for ; Mon, 31 Jan 2005 21:43:52 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j0VLhp77077589 for perforce@freebsd.org; Mon, 31 Jan 2005 21:43:51 GMT (envelope-from sam@freebsd.org) Date: Mon, 31 Jan 2005 21:43:51 GMT Message-Id: <200501312143.j0VLhp77077589@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Subject: PERFORCE change 70053 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 31 Jan 2005 21:43:53 -0000 http://perforce.freebsd.org/chv.cgi?CH=70053 Change 70053 by sam@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 -__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) <<<