Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Jan 2004 12:13:00 -0800 (PST)
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 46014 for review
Message-ID:  <200401272013.i0RKD0Ti090061@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=46014

Change 46014 by sam@sam_ebb on 2004/01/27 12:12:00

	Checkpoint in-progress merge of the netbsd and madwifi work.

Affected files ...

.. //depot/projects/netperf+sockets/sys/conf/files#7 edit
.. //depot/projects/netperf+sockets/sys/dev/ath/if_ath.c#18 edit
.. //depot/projects/netperf+sockets/sys/dev/ath/if_ath_pci.c#3 edit
.. //depot/projects/netperf+sockets/sys/dev/ath/if_athioctl.h#6 edit
.. //depot/projects/netperf+sockets/sys/dev/ath/if_athvar.h#5 edit
.. //depot/projects/netperf+sockets/sys/dev/awi/awi.c#6 edit
.. //depot/projects/netperf+sockets/sys/dev/awi/awivar.h#3 edit
.. //depot/projects/netperf+sockets/sys/dev/wi/if_wi.c#7 edit
.. //depot/projects/netperf+sockets/sys/dev/wi/if_wivar.h#3 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211.c#7 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211.h#7 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_compat.c#3 delete
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_compat.h#4 delete
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_crypto.c#4 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_crypto.h#4 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_freebsd.c#1 add
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_freebsd.h#1 add
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_input.c#6 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.c#11 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.h#4 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_linux.c#1 add
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_linux.h#1 add
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_linux.o#1 add
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_netbsd.c#1 add
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_netbsd.h#1 add
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_node.c#4 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_node.h#4 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_output.c#7 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_proto.c#5 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_proto.h#4 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_radiotap.h#5 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_var.h#7 edit

Differences ...

==== //depot/projects/netperf+sockets/sys/conf/files#7 (text+ko) ====

@@ -1267,6 +1267,7 @@
 net/zlib.c		optional crypto
 net80211/ieee80211.c	optional wlan
 net80211/ieee80211_crypto.c	optional wlan
+net80211/ieee80211_freebsd.c	optional wlan
 net80211/ieee80211_input.c	optional wlan
 net80211/ieee80211_ioctl.c	optional wlan
 net80211/ieee80211_node.c	optional wlan

==== //depot/projects/netperf+sockets/sys/dev/ath/if_ath.c#18 (text+ko) ====

@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -105,7 +105,7 @@
 static void	ath_initkeytable(struct ath_softc *);
 static void	ath_mode_init(struct ath_softc *);
 static int	ath_beacon_alloc(struct ath_softc *, struct ieee80211_node *);
-static void	ath_beacon_proc(void *, int);
+static void	ath_beacon_proc(struct ath_softc *);
 static void	ath_beacon_free(struct ath_softc *);
 static void	ath_beacon_config(struct ath_softc *);
 static int	ath_desc_alloc(struct ath_softc *);
@@ -121,6 +121,7 @@
 static int	ath_tx_start(struct ath_softc *, struct ieee80211_node *,
 			     struct ath_buf *, struct mbuf *);
 static void	ath_tx_proc(void *, int);
+static void	ath_chan_change(struct ath_softc *, struct ieee80211_channel *);
 static int	ath_chan_set(struct ath_softc *, struct ieee80211_channel *);
 static void	ath_draintxq(struct ath_softc *);
 static void	ath_stoprecv(struct ath_softc *);
@@ -131,9 +132,9 @@
 static void	ath_newassoc(struct ieee80211com *,
 			struct ieee80211_node *, int);
 static int	ath_getchannels(struct ath_softc *, u_int cc,
-			HAL_BOOL outdoor, HAL_BOOL xchans);
+			HAL_BOOL outdoor, HAL_BOOL xchanmode);
 
-static int	ath_rate_setup(struct ath_softc *sc, u_int mode);
+static int	ath_rate_setup(struct ath_softc *, u_int mode);
 static void	ath_setcurmode(struct ath_softc *, enum ieee80211_phymode);
 static void	ath_rate_update(struct ath_softc *, struct ieee80211_node *,
 			int rate);
@@ -204,7 +205,7 @@
 ath_attach(u_int16_t devid, struct ath_softc *sc)
 {
 	struct ieee80211com *ic = &sc->sc_ic;
-	struct ifnet *ifp = &ic->ic_if;
+	struct ifnet *ifp = &sc->sc_if;
 	struct ath_hal *ah;
 	HAL_STATUS status;
 	int error = 0;
@@ -290,7 +291,6 @@
 
 	TASK_INIT(&sc->sc_txtask, 0, ath_tx_proc, sc);
 	TASK_INIT(&sc->sc_rxtask, 0, ath_rx_proc, sc);
-	TASK_INIT(&sc->sc_swbatask, 0, ath_beacon_proc, sc);
 	TASK_INIT(&sc->sc_rxorntask, 0, ath_rxorn_proc, sc);
 	TASK_INIT(&sc->sc_fataltask, 0, ath_fatal_proc, sc);
 	TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc);
@@ -308,7 +308,7 @@
 	);
 	if (sc->sc_txhalq == (u_int) -1) {
 		if_printf(ifp, "unable to setup a data xmit queue!\n");
-		goto bad;
+		goto bad2;
 	}
 	sc->sc_bhalq = ath_hal_setuptxqueue(ah,
 		HAL_TX_QUEUE_BEACON,
@@ -316,7 +316,7 @@
 	);
 	if (sc->sc_bhalq == (u_int) -1) {
 		if_printf(ifp, "unable to setup a beacon xmit queue!\n");
-		goto bad;
+		goto bad2;
 	}
 
 	ifp->if_softc = sc;
@@ -327,7 +327,7 @@
 	ifp->if_init = ath_init;
 	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
 
-	ic->ic_softc = sc;
+	ic->ic_ifp = ifp;
 	ic->ic_reset = ath_reset;
 	ic->ic_newassoc = ath_newassoc;
 	/* XXX not right but it's not used anywhere important */
@@ -346,7 +346,7 @@
 	ath_hal_getmac(ah, ic->ic_myaddr);
 
 	/* call MI attach routine. */
-	ieee80211_ifattach(ifp);
+	ieee80211_ifattach(ic);
 	/* override default methods */
 	ic->ic_node_alloc = ath_node_alloc;
 	ic->ic_node_free = ath_node_free;
@@ -355,7 +355,7 @@
 	sc->sc_newstate = ic->ic_newstate;
 	ic->ic_newstate = ath_newstate;
 	/* complete initialization */
-	ieee80211_media_init(ifp, ath_media_change, ieee80211_media_status);
+	ieee80211_media_init(ic, ath_media_change, ieee80211_media_status);
 
 	bpfattach2(ifp, DLT_IEEE802_11_RADIO,
 		sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th),
@@ -375,6 +375,8 @@
 	if_printf(ifp, "802.11 address: %s\n", ether_sprintf(ic->ic_myaddr));
 
 	return 0;
+bad2:
+	ath_desc_free(sc);
 bad:
 	if (ah)
 		ath_hal_detach(ah);
@@ -385,7 +387,8 @@
 int
 ath_detach(struct ath_softc *sc)
 {
-	struct ifnet *ifp = &sc->sc_ic.ic_if;
+	struct ifnet *ifp = &sc->sc_if;
+	struct ieee80211com *ic = &sc->sc_ic;
 
 	DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags));
 
@@ -395,7 +398,7 @@
 	ATH_TXQ_LOCK_DESTROY(sc);
 	ath_desc_free(sc);
 	ath_hal_detach(sc->sc_ah);
-	ieee80211_ifdetach(ifp);
+	ieee80211_ifdetach(ic);
 
 	return 0;
 }
@@ -403,7 +406,7 @@
 void
 ath_suspend(struct ath_softc *sc)
 {
-	struct ifnet *ifp = &sc->sc_ic.ic_if;
+	struct ifnet *ifp = &sc->sc_if;
 
 	DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags));
 
@@ -413,7 +416,7 @@
 void
 ath_resume(struct ath_softc *sc)
 {
-	struct ifnet *ifp = &sc->sc_ic.ic_if;
+	struct ifnet *ifp = &sc->sc_if;
 
 	DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags));
 
@@ -427,19 +430,22 @@
 void
 ath_shutdown(struct ath_softc *sc)
 {
-	struct ifnet *ifp = &sc->sc_ic.ic_if;
+	struct ifnet *ifp = &sc->sc_if;
 
 	DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags));
 
 	ath_stop(ifp);
 }
 
+/*
+ * Interrupt handler.  Most of the actual processing is
+ * deferred to tasklets.
+ */
 void
 ath_intr(void *arg)
 {
 	struct ath_softc *sc = arg;
-	struct ieee80211com *ic = &sc->sc_ic;
-	struct ifnet *ifp = &ic->ic_if;
+	struct ifnet *ifp = &sc->sc_if;
 	struct ath_hal *ah = sc->sc_ah;
 	HAL_INT status;
 
@@ -495,8 +501,14 @@
 			taskqueue_enqueue(taskqueue_swi, &sc->sc_rxtask);
 		if (status & HAL_INT_TX)
 			taskqueue_enqueue(taskqueue_swi, &sc->sc_txtask);
-		if (status & HAL_INT_SWBA)
-			taskqueue_enqueue(taskqueue_swi, &sc->sc_swbatask);
+		if (status & HAL_INT_SWBA) {
+			/*
+			 * Handle beacon transmission directly; deferring
+			 * this is too slow to meet timing constraints
+			 * under load.
+			 */
+			ath_beacon_proc(sc);
+		}
 		if (status & HAL_INT_BMISS) {
 			sc->sc_stats.ast_bmiss++;
 			taskqueue_enqueue(taskqueue_swi, &sc->sc_bmisstask);
@@ -559,8 +571,8 @@
 ath_init(void *arg)
 {
 	struct ath_softc *sc = (struct ath_softc *) arg;
+	struct ifnet *ifp = &sc->sc_if;
 	struct ieee80211com *ic = &sc->sc_ic;
-	struct ifnet *ifp = &ic->ic_if;
 	struct ieee80211_node *ni;
 	enum ieee80211_phymode mode;
 	struct ath_hal *ah = sc->sc_ah;
@@ -577,7 +589,20 @@
 	 */
 	ath_stop(ifp);
 
+#if 0
 	/*
+	 * For the MAC address.  When this is changed we
+	 * are called after if_setlladdr has already copied
+	 * the new address to the arpcom structure so just
+	 * take it from there.
+	 *
+	 * XXX not right for multiple vap's
+	 */
+	IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_ac.ac_enaddr);
+	ath_hal_setmac(ah, ic->ic_myaddr);
+#endif
+
+	/*
 	 * The basic interface to setting the hardware in a good
 	 * state is ``reset''.  On return the hardware is known to
 	 * be powered up and with interrupts disabled.  This must
@@ -637,8 +662,8 @@
 static void
 ath_stop(struct ifnet *ifp)
 {
-	struct ieee80211com *ic = (struct ieee80211com *) ifp;
 	struct ath_softc *sc = ifp->if_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_hal *ah = sc->sc_ah;
 
 	DPRINTF(ATH_DEBUG_ANY, ("%s: invalid %u if_flags 0x%x\n",
@@ -688,7 +713,7 @@
 static int
 ath_reset(struct ieee80211com *ic)
 {
-	struct ifnet *ifp = &ic->ic_if;
+	struct ifnet *ifp = ic->ic_ifp;
 	struct ath_softc *sc = ifp->if_softc;
 	struct ath_hal *ah = sc->sc_ah;
 	struct ieee80211_channel *c;
@@ -716,12 +741,19 @@
 	 *     hardware state we do this regardless.
 	 */
 	ath_initkeytable(sc);
-	ath_hal_intrset(ah, sc->sc_imask);
 	if (ath_startrecv(sc) != 0)	/* restart recv */
 		if_printf(ifp, "%s: unable to start recv logic\n", __func__);
-	ath_start(ifp);			/* restart xmit */
+	/*
+	 * We may be doing a reset in response to an ioctl
+	 * that changes the channel so update any state that
+	 * might change as a result.
+	 */
+	ath_chan_change(sc, c);
 	if (ic->ic_state == IEEE80211_S_RUN)
 		ath_beacon_config(sc);	/* restart beacons */
+	ath_hal_intrset(ah, sc->sc_imask);
+
+	ath_start(ifp);			/* restart xmit */
 	return 0;
 }
 
@@ -785,7 +817,7 @@
 			/*
 			 * Encapsulate the packet in prep for transmission.
 			 */
-			m = ieee80211_encap(ifp, m, &ni);
+			m = ieee80211_encap(ic, m, &ni);
 			if (m == NULL) {
 				DPRINTF(ATH_DEBUG_ANY,
 					("%s: encapsulation failure\n",
@@ -849,7 +881,7 @@
 	if (error == ENETRESET) {
 		if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
 		    (IFF_RUNNING|IFF_UP))
-			ath_init(ifp);		/* XXX lose error */
+			ath_init(ifp->if_softc);	/* XXX lose error */
 		error = 0;
 	}
 	return error;
@@ -888,7 +920,7 @@
 		else
 			ieee80211_iterate_nodes(ic, ath_rate_ctl, sc);
 	}
-	ieee80211_watchdog(ifp);
+	ieee80211_watchdog(ic);
 }
 
 static int
@@ -897,6 +929,7 @@
 #define	UP_RUNNING(_ifp) \
 	(((_ifp)->if_flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING))
 	struct ath_softc *sc = ifp->if_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
 	struct ifreq *ifr = (struct ifreq *)data;
 	int error = 0;
 
@@ -921,7 +954,7 @@
 			 * probably a better way to deal with this.
 			 */
 			if (!sc->sc_invalid)
-				ath_init(ifp);	/* XXX lose error */
+				ath_init(sc);	/* XXX lose error */
 		} else {
 			/*
 			 * Interface marked down; clear the hardware.
@@ -959,7 +992,7 @@
 		break;
 	}
 	default:
-		error = ieee80211_ioctl(ifp, cmd, data);
+		error = ieee80211_ioctl(ic, cmd, data);
 		if (error == ENETRESET) {
 			if (UP_RUNNING(ifp))
 				ath_init(sc);
@@ -1011,9 +1044,9 @@
 static u_int32_t
 ath_calcrxfilter(struct ath_softc *sc)
 {
+	struct ifnet *ifp = &sc->sc_if;
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_hal *ah = sc->sc_ah;
-	struct ifnet *ifp = &ic->ic_if;
 	u_int32_t rfilt;
 
 	rfilt = (ath_hal_getrxfilter(ah) & HAL_RX_FILTER_PHYERR)
@@ -1033,9 +1066,8 @@
 static void
 ath_mode_init(struct ath_softc *sc)
 {
-	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_hal *ah = sc->sc_ah;
-	struct ifnet *ifp = &ic->ic_if;
+	struct ifnet *ifp = &sc->sc_if;
 	u_int32_t rfilt, mfilt[2], val;
 	u_int8_t pos;
 	struct ifmultiaddr *ifma;
@@ -1162,14 +1194,13 @@
 }
 
 static void
-ath_beacon_proc(void *arg, int pending)
+ath_beacon_proc(struct ath_softc *sc)
 {
-	struct ath_softc *sc = arg;
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_buf *bf = sc->sc_bcbuf;
 	struct ath_hal *ah = sc->sc_ah;
 
-	DPRINTF(ATH_DEBUG_BEACON_PROC, ("%s: pending %u\n", __func__, pending));
+	DPRINTF(ATH_DEBUG_BEACON_PROC, ("%s\n", __func__));
 	if (ic->ic_opmode == IEEE80211_M_STA ||
 	    bf == NULL || bf->bf_m == NULL) {
 		DPRINTF(ATH_DEBUG_ANY, ("%s: ic_flags=%x bf=%p bf_m=%p\n",
@@ -1432,7 +1463,8 @@
 	struct ath_node *an =
 		malloc(sizeof(struct ath_node), M_DEVBUF, M_NOWAIT | M_ZERO);
 	if (an) {
-		struct ath_softc *sc = ic->ic_if.if_softc;
+		struct ifnet *ifp = ic->ic_ifp;
+		struct ath_softc *sc = ifp->if_softc;
 		int i;
 
 		for (i = 0; i < ATH_RHIST_SIZE; i++)
@@ -1447,7 +1479,8 @@
 static void
 ath_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
 {
-        struct ath_softc *sc = ic->ic_if.if_softc;
+	struct ifnet *ifp = ic->ic_ifp;
+	struct ath_softc *sc = ifp->if_softc;
 	struct ath_buf *bf;
 
 	TAILQ_FOREACH(bf, &sc->sc_txq, bf_list) {
@@ -1578,9 +1611,9 @@
 	((struct ath_desc *)((caddr_t)(_sc)->sc_desc + \
 		((_pa) - (_sc)->sc_desc_paddr)))
 	struct ath_softc *sc = arg;
+	struct ifnet *ifp = &sc->sc_if;
+	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_buf *bf;
-	struct ieee80211com *ic = &sc->sc_ic;
-	struct ifnet *ifp = &ic->ic_if;
 	struct ath_hal *ah = sc->sc_ah;
 	struct ath_desc *ds;
 	struct mbuf *m;
@@ -1630,7 +1663,26 @@
 		if (status == HAL_EINPROGRESS)
 			break;
 		TAILQ_REMOVE(&sc->sc_rxbuf, bf, bf_list);
-		if (ds->ds_rxstat.rs_status != 0) {
+
+		if (ds->ds_rxstat.rs_more) {
+			/*
+			 * Frame spans multiple descriptors; this
+			 * cannot happen yet as we don't support
+			 * jumbograms.  If not in monitor mode,
+			 * discard the frame.
+			 */
+#ifdef ERROR_FRAMES
+			/*
+			 * Enable this if you want to see
+			 * error frames in Monitor mode.
+			 */
+			if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+				/* XXX statistic */
+				goto rx_next;
+			}
+#endif
+			/* fall thru for monitor mode handling... */
+		} else if (ds->ds_rxstat.rs_status != 0) {
 			if (ds->ds_rxstat.rs_status & HAL_RXERR_CRC)
 				sc->sc_stats.ast_rx_crcerr++;
 			if (ds->ds_rxstat.rs_status & HAL_RXERR_FIFO)
@@ -1641,6 +1693,7 @@
 				sc->sc_stats.ast_rx_phyerr++;
 				phyerr = ds->ds_rxstat.rs_phyerr & 0x1f;
 				sc->sc_stats.ast_rx_phy[phyerr]++;
+				goto rx_next;
 			} else {
 				/*
 				 * NB: don't count PHY errors as input errors;
@@ -1651,7 +1704,14 @@
 				 */
 				ifp->if_ierrors++;
 			}
-			goto rx_next;
+			/*
+			 * Reject error frames, we normally don't want
+			 * to see them in monitor mode (in monitor mode
+			 * allow through packets that cannot be decrypted.)
+			 */
+			if ((ds->ds_rxstat.rs_status & ~HAL_RXERR_DECRYPT) ||
+			    sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR)
+				goto rx_next;
 		}
 
 		len = ds->ds_rxstat.rs_datalen;
@@ -1670,6 +1730,17 @@
 		m->m_pkthdr.rcvif = ifp;
 		m->m_pkthdr.len = m->m_len = len;
 
+		/*
+		 * Strip the CRC before tapping the frame as some
+		 * applications get confused otherwise.  If there's
+		 * a good reason to send the CRC to applications
+		 * we'll need to define a radiotap flag for that.
+		 */
+		m_adj(m, -IEEE80211_CRC_LEN);
+
+		/*
+		 * Tap and/or dump the received frame.
+		 */
 		if (sc->sc_drvbpf) {
 			sc->sc_rx_th.wr_rate =
 				sc->sc_hwmap[ds->ds_rxstat.rs_rate];
@@ -1680,8 +1751,13 @@
 			bpf_mtap2(sc->sc_drvbpf,
 				&sc->sc_rx_th, sizeof(sc->sc_rx_th), m);
 		}
+		if (IFF_DUMPPKTS(ifp, ATH_DEBUG_RECV)) {
+			ieee80211_dump_pkt(mtod(m, u_int8_t *), len,
+				   sc->sc_hwmap[ds->ds_rxstat.rs_rate] &
+				   	IEEE80211_RATE_VAL,
+				   ds->ds_rxstat.rs_rssi);
+		}
 
-		m_adj(m, -IEEE80211_CRC_LEN);
 		wh = mtod(m, struct ieee80211_frame *);
 		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
 			/*
@@ -1727,7 +1803,7 @@
 		/*
 		 * Send frame up for processing.
 		 */
-		ieee80211_input(ifp, m, ni,
+		ieee80211_input(ic, m, ni,
 			ds->ds_rxstat.rs_rssi, ds->ds_rxstat.rs_tstamp);
 
 		/*
@@ -1739,7 +1815,7 @@
 			ieee80211_unref_node(&ni);
 		else
 			ieee80211_free_node(ic, ni);
-  rx_next:
+rx_next:
 		TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
 	} while (ath_rxbuf_init(sc, bf) == 0);
 
@@ -1758,8 +1834,8 @@
     struct mbuf *m0)
 {
 	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = &sc->sc_if;
 	struct ath_hal *ah = sc->sc_ah;
-	struct ifnet *ifp = &sc->sc_ic.ic_if;
 	int i, error, iswep, hdrlen, pktlen, try0;
 	u_int8_t rix, cix, txrate, ctsrate;
 	struct ath_desc *ds;
@@ -1785,7 +1861,7 @@
 		m_adj(m0, hdrlen);
 		M_PREPEND(m0, sizeof(hdrbuf), M_DONTWAIT);
 		if (m0 == NULL) {
-			sc->sc_stats.ast_tx_nombuf++;
+			sc->sc_stats.ast_tx_nobuf++;
 			return ENOMEM;
 		}
 		ivp = hdrbuf + hdrlen;
@@ -1845,7 +1921,7 @@
 		sc->sc_stats.ast_tx_linear++;
 		MGETHDR(m, M_DONTWAIT, MT_DATA);
 		if (m == NULL) {
-			sc->sc_stats.ast_tx_nombuf++;
+			sc->sc_stats.ast_tx_nobuf++;
 			m_freem(m0);
 			return ENOMEM;
 		}
@@ -2038,6 +2114,11 @@
 			&sc->sc_tx_th, sizeof(sc->sc_tx_th), m0);
 	}
 
+	if (IFF_DUMPPKTS(ifp, ATH_DEBUG_XMIT))
+		ieee80211_dump_pkt(mtod(m0, u_int8_t *), pktlen,
+		    ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL,
+		    -1);
+
 	/*
 	 * Formulate first tx descriptor with tx controls.
 	 */
@@ -2132,10 +2213,10 @@
 ath_tx_proc(void *arg, int npending)
 {
 	struct ath_softc *sc = arg;
+	struct ifnet *ifp = &sc->sc_if;
 	struct ath_hal *ah = sc->sc_ah;
 	struct ath_buf *bf;
 	struct ieee80211com *ic = &sc->sc_ic;
-	struct ifnet *ifp = &ic->ic_if;
 	struct ath_desc *ds;
 	struct ieee80211_node *ni;
 	struct ath_node *an;
@@ -2225,9 +2306,9 @@
 static void
 ath_draintxq(struct ath_softc *sc)
 {
+	struct ifnet *ifp = &sc->sc_if;
 	struct ath_hal *ah = sc->sc_ah;
 	struct ieee80211com *ic = &sc->sc_ic;
-	struct ifnet *ifp = &ic->ic_if;
 	struct ieee80211_node *ni;
 	struct ath_buf *bf;
 
@@ -2339,6 +2420,32 @@
 	return 0;
 }
 
+/* 
+ * Update internal state after a channel change.
+ */
+static void
+ath_chan_change(struct ath_softc *sc, struct ieee80211_channel *chan)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	enum ieee80211_phymode mode;
+
+	/*
+	 * Change channels and update the h/w rate map
+	 * if we're switching; e.g. 11a to 11b/g.
+	 */
+	mode = ieee80211_chan2mode(ic, chan);
+	if (mode != sc->sc_curmode)
+		ath_setcurmode(sc, mode);
+
+	/*
+	 * Update BPF state.
+	 */
+	sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
+		htole16(chan->ic_freq);
+	sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
+		htole16(chan->ic_flags);
+}
+
 /*
  * Set/change channels.  If the channel is really being changed,
  * it's done by resetting the chip.  To accomplish this we must
@@ -2358,7 +2465,6 @@
 	if (chan != ic->ic_ibss_chan) {
 		HAL_STATUS status;
 		HAL_CHANNEL hchan;
-		enum ieee80211_phymode mode;
 
 		/*
 		 * To switch channels clear any pending DMA operations;
@@ -2377,7 +2483,7 @@
 		hchan.channel = chan->ic_freq;
 		hchan.channelFlags = ath_chan2flags(ic, chan);
 		if (!ath_hal_reset(ah, ic->ic_opmode, &hchan, AH_TRUE, &status)) {
-			if_printf(&ic->ic_if, "ath_chan_set: unable to reset "
+			if_printf(&sc->sc_if, "ath_chan_set: unable to reset "
 				"channel %u (%u Mhz)\n",
 				ieee80211_chan2ieee(ic, chan), chan->ic_freq);
 			return EIO;
@@ -2386,27 +2492,17 @@
 		 * Re-enable rx framework.
 		 */
 		if (ath_startrecv(sc) != 0) {
-			if_printf(&ic->ic_if,
+			if_printf(&sc->sc_if,
 				"ath_chan_set: unable to restart recv logic\n");
 			return EIO;
 		}
 
 		/*
-		 * Update BPF state.
-		 */
-		sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
-			htole16(chan->ic_freq);
-		sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
-			htole16(chan->ic_flags);
-
-		/*
 		 * Change channels and update the h/w rate map
 		 * if we're switching; e.g. 11a to 11b/g.
 		 */
 		ic->ic_ibss_chan = chan;
-		mode = ieee80211_chan2mode(ic, chan);
-		if (mode != sc->sc_curmode)
-			ath_setcurmode(sc, mode);
+		ath_chan_change(sc, chan);
 
 		/*
 		 * Re-enable interrupts.
@@ -2421,10 +2517,9 @@
 {
 	struct ath_softc *sc = arg;
 	struct ieee80211com *ic = &sc->sc_ic;
-	struct ifnet *ifp = &ic->ic_if;
 
 	if (ic->ic_state == IEEE80211_S_SCAN)
-		ieee80211_next_scan(ifp);
+		ieee80211_next_scan(ic);
 }
 
 /*
@@ -2473,7 +2568,7 @@
 static int
 ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
 {
-	struct ifnet *ifp = &ic->ic_if;
+	struct ifnet *ifp = ic->ic_ifp;
 	struct ath_softc *sc = ifp->if_softc;
 	struct ath_hal *ah = sc->sc_ah;
 	struct ieee80211_node *ni;
@@ -2592,8 +2687,8 @@
 ath_getchannels(struct ath_softc *sc, u_int cc,
 	HAL_BOOL outdoor, HAL_BOOL xchanmode)
 {
+	struct ifnet *ifp = &sc->sc_if;
 	struct ieee80211com *ic = &sc->sc_ic;
-	struct ifnet *ifp = &ic->ic_if;
 	struct ath_hal *ah = sc->sc_ah;
 	HAL_CHANNEL *chans;
 	int i, ix, nchan;
@@ -2787,25 +2882,45 @@
 {
 #define	RATE(_ix)	(ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
 	struct ieee80211com *ic = &sc->sc_ic;
+	int srate;
 
+	KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates"));
 	if (ic->ic_fixed_rate == -1) {
-		KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates"));
-		/* start with highest negotiated rate */
-		int srate = ni->ni_rates.rs_nrates - 1;
+		/*
+		 * No fixed rate is requested. For 11b start with
+		 * the highest negotiated rate; otherwise, for 11g
+		 * and 11a, we start "in the middle" at 24Mb or 36Mb.
+		 */
+		srate = ni->ni_rates.rs_nrates - 1;
 		if (sc->sc_curmode != IEEE80211_MODE_11B) {
 			/*
-			 * 11a and 11g work better if you start at 24Mb
-			 * or 36Mb and raise the rate.  Scan the negotiated
-			 * rate set to find the closest rate.
+			 * Scan the negotiated rate set to find the
+			 * closest rate.
 			 */
-			/* NB: rate set assumed sorted */
+			/* NB: the rate set is assumed sorted */
 			for (; srate >= 0 && RATE(srate) > 72; srate--)
 				;
 			KASSERT(srate >= 0, ("bogus rate set"));
 		}
-		ath_rate_update(sc, ni, srate);
-	} else
-		ath_rate_update(sc, ni, ic->ic_fixed_rate);
+	} else {
+		/*
+		 * A fixed rate is to be used; ic_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.
+		 */
+		const struct ieee80211_rateset *rs =
+			&ic->ic_sup_rates[ic->ic_curmode];
+		int r = rs->rs_rates[ic->ic_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));
+	}
+	ath_rate_update(sc, ni, srate);
 #undef RATE
 }
 
@@ -2849,7 +2964,7 @@
 ath_rate_ctl(void *arg, struct ieee80211_node *ni)
 {
 	struct ath_softc *sc = arg;
-	struct ath_node *an = (struct ath_node *) ni;
+	struct ath_node *an = ATH_NODE(ni);
 	struct ieee80211_rateset *rs = &ni->ni_rates;
 	int mod = 0, nrate, enough;
 

==== //depot/projects/netperf+sockets/sys/dev/ath/if_ath_pci.c#3 (text+ko) ====

@@ -67,10 +67,6 @@
 #include <net/if_llc.h>
 #include <net/if_arp.h>
 
-#include <net80211/ieee80211.h>
-#include <net80211/ieee80211_crypto.h>
-#include <net80211/ieee80211_node.h>
-#include <net80211/ieee80211_proto.h>
 #include <net80211/ieee80211_var.h>
 
 #ifdef INET

==== //depot/projects/netperf+sockets/sys/dev/ath/if_athioctl.h#6 (text+ko) ====

@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -55,7 +55,7 @@
 	u_int32_t	ast_tx_qstop;	/* output stopped 'cuz no buffer */
 	u_int32_t	ast_tx_encap;	/* tx encapsulation failed */
 	u_int32_t	ast_tx_nonode;	/* tx failed 'cuz no node */
-	u_int32_t	ast_tx_nombuf;	/* tx failed 'cuz no mbuf */
+	u_int32_t	ast_tx_nobuf;	/* tx failed 'cuz no buf */
 	u_int32_t	ast_tx_nomcl;	/* tx failed 'cuz no cluster */
 	u_int32_t	ast_tx_linear;	/* tx linearized to cluster */
 	u_int32_t	ast_tx_nodata;	/* tx discarded empty frame */
@@ -77,10 +77,10 @@
 	u_int32_t	ast_rx_crcerr;	/* rx failed 'cuz of bad CRC */
 	u_int32_t	ast_rx_fifoerr;	/* rx failed 'cuz of FIFO overrun */
 	u_int32_t	ast_rx_badcrypt;/* rx failed 'cuz decryption */
-	u_int32_t	ast_rx_phyerr;	/* rx failed 'cuz of PHY err */
+	u_int32_t	ast_rx_phyerr;	/* rx PHY error summary count */
 	u_int32_t	ast_rx_phy[32];	/* rx PHY error per-code counts */
 	u_int32_t	ast_rx_tooshort;/* rx discarded 'cuz frame too short */
-	u_int32_t	ast_rx_ctl;	/* rx discarded 'cuz ctl frame */
+	u_int8_t	ast_rx_ctl;	/* control frames received */
 	u_int32_t	ast_be_nombuf;	/* beacon setup failed 'cuz no mbuf */
 	u_int32_t	ast_per_cal;	/* periodic calibration calls */
 	u_int32_t	ast_per_calfail;/* periodic calibration failed */

==== //depot/projects/netperf+sockets/sys/dev/ath/if_athvar.h#5 (text+ko) ====

@@ -103,6 +103,7 @@
 };
 
 struct ath_softc {
+	struct arpcom		sc_ac;
 	struct ieee80211com	sc_ic;		/* IEEE 802.11 common */
 	int			(*sc_newstate)(struct ieee80211com *,
 					enum ieee80211_state, int);
@@ -157,13 +158,13 @@
 	u_int			sc_bhalq;	/* HAL q for outgoing beacons */
 	struct ath_buf		*sc_bcbuf;	/* beacon buffer */
 	struct ath_buf		*sc_bufptr;	/* allocated buffer ptr */
-	struct task		sc_swbatask;	/* swba int processing */
 	struct task		sc_bmisstask;	/* bmiss int processing */
 
 	struct callout		sc_cal_ch;	/* callout handle for cals */
 	struct callout		sc_scan_ch;	/* callout handle for scan */
 	struct ath_stats	sc_stats;	/* interface statistics */
 };
+#define	sc_if			sc_ac.ac_if
 #define	sc_tx_th		u_tx_rt.th
 #define	sc_rx_th		u_rx_rt.th
 
@@ -211,6 +212,8 @@
 #define	ath_hal_getcountrycode(_ah)	(_ah)->ah_countryCode
 #define	ath_hal_getmac(_ah, _mac) \
 	((*(_ah)->ah_getMacAddress)((_ah), (_mac)))
+#define	ath_hal_setmac(_ah, _mac) \
+	((*(_ah)->ah_setMacAddress)((_ah), (_mac)))
 #define	ath_hal_detach(_ah) \
 	((*(_ah)->ah_detach)((_ah)))
 #define	ath_hal_intrset(_ah, _mask) \

==== //depot/projects/netperf+sockets/sys/dev/awi/awi.c#6 (text+ko) ====

@@ -257,7 +257,7 @@
 awi_attach(struct awi_softc *sc)
 {
 	struct ieee80211com *ic = &sc->sc_ic;
-	struct ifnet *ifp = &ic->ic_if;
+	struct ifnet *ifp = &sc->sc_if;
 	int s, i, error, nrate;
 	int mword;
 	enum ieee80211_phymode mode;
@@ -324,7 +324,9 @@
 #ifdef __NetBSD__
 	if_attach(ifp);
 #endif
-	ieee80211_ifattach(ifp);
+	ic->ic_ifp = ifp;
+
+	ieee80211_ifattach(ic);
 
 	sc->sc_newstate = ic->ic_newstate;
 	ic->ic_newstate = awi_newstate;
@@ -335,7 +337,7 @@
 	sc->sc_send_mgmt = ic->ic_send_mgmt;
 	ic->ic_send_mgmt = awi_send_mgmt;
 
-	ieee80211_media_init(ifp, awi_media_change, awi_media_status);
+	ieee80211_media_init(ic, awi_media_change, awi_media_status);
 
 	/* Melco compatibility mode. */
 #define	ADD(s, o)	ifmedia_add(&ic->ic_media, \
@@ -371,7 +373,8 @@
 int
 awi_detach(struct awi_softc *sc)
 {
-	struct ifnet *ifp = &sc->sc_ic.ic_if;
+	struct ifnet *ifp = &sc->sc_if;
+	struct ieee80211com *ic = &sc->sc_ic;
 	int s;
 
 	if (!sc->sc_attached)
@@ -386,7 +389,7 @@
 		(void)tsleep(sc, PWAIT, "awidet", 1);
 	}
 	sc->sc_attached = 0;
-	ieee80211_ifdetach(ifp);
+	ieee80211_ifdetach(ic);
 #ifdef __NetBSD__
 	if_detach(ifp);
 	shutdownhook_disestablish(sc->sc_sdhook);
@@ -401,7 +404,7 @@
 awi_activate(struct device *self, enum devact act)
 {
 	struct awi_softc *sc = (struct awi_softc *)self;
-	struct ifnet *ifp = &sc->sc_ic.ic_if;
+	struct ifnet *ifp = &sc->sc_if;
 	int s, error = 0;
 
 	s = splnet();
@@ -422,7 +425,7 @@
 awi_power(int why, void *arg)
 {
 	struct awi_softc *sc = arg;
-	struct ifnet *ifp = &sc->sc_ic.ic_if;
+	struct ifnet *ifp = &sc->sc_if;
 	int s;
 	int ocansleep;
 
@@ -455,7 +458,7 @@
 awi_shutdown(void *arg)
 {
 	struct awi_softc *sc = arg;
-	struct ifnet *ifp = &sc->sc_ic.ic_if;
+	struct ifnet *ifp = &sc->sc_if;
 
 	if (sc->sc_attached)
 		awi_stop(ifp, 1);
@@ -526,7 +529,7 @@
 		if (status & AWI_INT_SCAN_CMPLT) {
 			if (sc->sc_ic.ic_state == IEEE80211_S_SCAN &&
 			    sc->sc_substate == AWI_ST_NONE)
-				ieee80211_next_scan(&sc->sc_ic.ic_if);
+				ieee80211_next_scan(&sc->sc_ic);
 		}
 	}
 	sc->sc_cansleep = ocansleep;
@@ -541,7 +544,7 @@
 {
 	struct awi_softc *sc = arg;
 
-	(void)awi_init(&sc->sc_ic.ic_if);
+	(void)awi_init(&sc->sc_if);
 }
 #endif
 
@@ -801,7 +804,7 @@
 			if ((ifp->if_flags & IFF_LINK0) || sc->sc_adhoc_ap)
 				m0 = awi_ether_encap(sc, m0);
 			else
-				m0 = ieee80211_encap(ifp, m0, &ni);
+				m0 = ieee80211_encap(ic, m0, &ni);
 			if (m0 == NULL) {
 				ifp->if_oerrors++;
 				continue;
@@ -826,7 +829,7 @@
 			bpf_mtap(ic->ic_rawbpf, m0);
 #endif
 		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
-			if ((m0 = ieee80211_wep_crypt(ifp, m0, 1)) == NULL) {
+			if ((m0 = ieee80211_wep_crypt(ic, m0, 1)) == NULL) {
 				ifp->if_oerrors++;
 				continue;
 			}
@@ -834,7 +837,7 @@
 #ifdef DIAGNOSTIC
 		if (m0->m_pkthdr.len != len) {
 			printf("%s: length %d should be %d\n",
-			    ic->ic_if.if_xname, m0->m_pkthdr.len, len);
+			    sc->sc_if.if_xname, m0->m_pkthdr.len, len);
 			m_freem(m0);
 			ifp->if_oerrors++;
 			continue;
@@ -874,6 +877,7 @@
 awi_watchdog(struct ifnet *ifp)
 {
 	struct awi_softc *sc = ifp->if_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
 	u_int32_t prevdone;
 	int ocansleep;
 
@@ -899,15 +903,14 @@
 	if (sc->sc_rx_timer) {
 		if (--sc->sc_rx_timer == 0) {
 			if (sc->sc_ic.ic_state == IEEE80211_S_RUN) {
-				ieee80211_new_state(&sc->sc_ic,
-				    IEEE80211_S_SCAN, -1);
+				ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
 				goto out;
 			}

>>> TRUNCATED FOR MAIL (1000 lines) <<<



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