Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 31 Jan 2005 21:43:51 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 70053 for review
Message-ID:  <200501312143.j0VLhp77077589@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <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) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200501312143.j0VLhp77077589>