Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 May 2009 20:00:40 +0000 (UTC)
From:      Sam Leffler <sam@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r192468 - in head/sys: conf dev/ath dev/bwi dev/ipw dev/iwi dev/iwn dev/malo dev/ral dev/usb/wlan dev/wi dev/wpi net80211
Message-ID:  <200905202000.n4KK0evZ042089@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sam
Date: Wed May 20 20:00:40 2009
New Revision: 192468
URL: http://svn.freebsd.org/changeset/base/192468

Log:
  Overhaul monitor mode handling:
  o replace DLT_IEEE802_11 support in net80211 with DLT_IEEE802_11_RADIO
    and remove explicit bpf support from wireless drivers; drivers now
    use ieee80211_radiotap_attach to setup shared data structures that
    hold the radiotap header for each packet tx/rx
  o remove rx timestamp from the rx path; it was used only by the tdma support
    for debugging and was mostly useless due to it being 32-bits and mostly
    unavailable
  o track DLT_IEEE80211_RADIO bpf attachments and maintain per-vap and
    per-com state when there are active taps
  o track the number of monitor mode vaps
  o use bpf tap and monitor mode vap state to decide when to collect radiotap
    state and dispatch frames; drivers no longer explicitly directly check
    bpf state or use bpf calls to tap frames
  o handle radiotap state updates on channel change in net80211; drivers
    should not do this (unless they bypass net80211 which is almost always
    a mistake)
  o update various drivers to be more consistent/correct in handling radiotap
  o update ral to include TSF in radiotap'd frames
  o add promisc mode callback to wi
  
  Reviewed by:	cbzimmer, rpaulo, thompsa

Added:
  head/sys/net80211/ieee80211_radiotap.c   (contents, props changed)
Modified:
  head/sys/conf/files
  head/sys/dev/ath/if_ath.c
  head/sys/dev/ath/if_athvar.h
  head/sys/dev/bwi/if_bwi.c
  head/sys/dev/bwi/if_bwivar.h
  head/sys/dev/ipw/if_ipw.c
  head/sys/dev/ipw/if_ipwvar.h
  head/sys/dev/iwi/if_iwi.c
  head/sys/dev/iwi/if_iwivar.h
  head/sys/dev/iwn/if_iwn.c
  head/sys/dev/iwn/if_iwnvar.h
  head/sys/dev/malo/if_malo.c
  head/sys/dev/malo/if_malo.h
  head/sys/dev/ral/rt2560.c
  head/sys/dev/ral/rt2560var.h
  head/sys/dev/ral/rt2661.c
  head/sys/dev/ral/rt2661var.h
  head/sys/dev/usb/wlan/if_rum.c
  head/sys/dev/usb/wlan/if_rumvar.h
  head/sys/dev/usb/wlan/if_uath.c
  head/sys/dev/usb/wlan/if_uathvar.h
  head/sys/dev/usb/wlan/if_upgt.c
  head/sys/dev/usb/wlan/if_ural.c
  head/sys/dev/usb/wlan/if_uralvar.h
  head/sys/dev/usb/wlan/if_zyd.c
  head/sys/dev/wi/if_wi.c
  head/sys/dev/wi/if_wireg.h
  head/sys/dev/wi/if_wivar.h
  head/sys/dev/wpi/if_wpi.c
  head/sys/dev/wpi/if_wpivar.h
  head/sys/net80211/ieee80211.c
  head/sys/net80211/ieee80211_adhoc.c
  head/sys/net80211/ieee80211_ddb.c
  head/sys/net80211/ieee80211_freebsd.c
  head/sys/net80211/ieee80211_hostap.c
  head/sys/net80211/ieee80211_ht.c
  head/sys/net80211/ieee80211_input.c
  head/sys/net80211/ieee80211_monitor.c
  head/sys/net80211/ieee80211_node.c
  head/sys/net80211/ieee80211_node.h
  head/sys/net80211/ieee80211_output.c
  head/sys/net80211/ieee80211_proto.c
  head/sys/net80211/ieee80211_proto.h
  head/sys/net80211/ieee80211_scan.c
  head/sys/net80211/ieee80211_scan.h
  head/sys/net80211/ieee80211_scan_sta.c
  head/sys/net80211/ieee80211_sta.c
  head/sys/net80211/ieee80211_superg.c
  head/sys/net80211/ieee80211_tdma.c
  head/sys/net80211/ieee80211_tdma.h
  head/sys/net80211/ieee80211_var.h
  head/sys/net80211/ieee80211_wds.c

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Wed May 20 19:53:10 2009	(r192467)
+++ head/sys/conf/files	Wed May 20 20:00:40 2009	(r192468)
@@ -2218,6 +2218,7 @@ net80211/ieee80211_output.c	optional wla
 net80211/ieee80211_phy.c	optional wlan
 net80211/ieee80211_power.c	optional wlan
 net80211/ieee80211_proto.c	optional wlan
+net80211/ieee80211_radiotap.c	optional wlan
 net80211/ieee80211_regdomain.c	optional wlan
 net80211/ieee80211_rssadapt.c	optional wlan wlan_rssadapt
 net80211/ieee80211_scan.c	optional wlan

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Wed May 20 19:53:10 2009	(r192467)
+++ head/sys/dev/ath/if_ath.c	Wed May 20 20:00:40 2009	(r192468)
@@ -172,7 +172,7 @@ static void	ath_node_getsignal(const str
 			int8_t *, int8_t *);
 static int	ath_rxbuf_init(struct ath_softc *, struct ath_buf *);
 static void	ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
-			int subtype, int rssi, int noise, u_int32_t rstamp);
+			int subtype, int rssi, int nf);
 static void	ath_setdefantenna(struct ath_softc *, u_int);
 static void	ath_rx_proc(void *, int);
 static void	ath_txq_init(struct ath_softc *sc, struct ath_txq *, int);
@@ -214,7 +214,6 @@ static void	ath_setcurmode(struct ath_so
 static void	ath_sysctlattach(struct ath_softc *);
 static int	ath_raw_xmit(struct ieee80211_node *,
 			struct mbuf *, const struct ieee80211_bpf_params *);
-static void	ath_bpfattach(struct ath_softc *);
 static void	ath_announce(struct ath_softc *);
 
 #ifdef IEEE80211_SUPPORT_TDMA
@@ -715,7 +714,12 @@ ath_attach(u_int16_t devid, struct ath_s
 	ic->ic_scan_end = ath_scan_end;
 	ic->ic_set_channel = ath_set_channel;
 
-	ath_bpfattach(sc);
+	ieee80211_radiotap_attach(ic,
+	    &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
+		ATH_TX_RADIOTAP_PRESENT,
+	    &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
+		ATH_RX_RADIOTAP_PRESENT);
+
 	/*
 	 * Setup dynamic sysctl's now that country code and
 	 * regdomain are available from the hal.
@@ -753,8 +757,6 @@ ath_detach(struct ath_softc *sc)
 	 *   insure callbacks into the driver to delete global
 	 *   key cache entries can be handled
 	 * o free the taskqueue which drains any pending tasks
-	 * o reclaim the bpf tap now that we know nothing will use
-	 *   it (e.g. rx processing from the task q thread)
 	 * o reclaim the tx queue data structures after calling
 	 *   the 802.11 layer as we'll get called back to reclaim
 	 *   node state and potentially want to use them
@@ -765,7 +767,6 @@ ath_detach(struct ath_softc *sc)
 	ath_stop(ifp);
 	ieee80211_ifdetach(ifp->if_l2com);
 	taskqueue_free(sc->sc_tq);
-	bpfdetach(ifp);
 #ifdef ATH_TX99_DIAG
 	if (sc->sc_tx99 != NULL)
 		sc->sc_tx99->detach(sc->sc_tx99);
@@ -2353,6 +2354,7 @@ ath_calcrxfilter(struct ath_softc *sc)
 		rfilt |= HAL_RX_FILTER_PHYERR;
 	if (ic->ic_opmode != IEEE80211_M_STA)
 		rfilt |= HAL_RX_FILTER_PROBEREQ;
+	/* XXX ic->ic_monvaps != 0? */
 	if (ic->ic_opmode == IEEE80211_M_MONITOR || (ifp->if_flags & IFF_PROMISC))
 		rfilt |= HAL_RX_FILTER_PROM;
 	if (ic->ic_opmode == IEEE80211_M_STA ||
@@ -3573,7 +3575,7 @@ ath_extend_tsf(u_int32_t rstamp, u_int64
  */
 static void
 ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
-	int subtype, int rssi, int noise, u_int32_t rstamp)
+	int subtype, int rssi, int nf)
 {
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
@@ -3582,7 +3584,7 @@ ath_recv_mgmt(struct ieee80211_node *ni,
 	 * Call up first so subsequent work can use information
 	 * potentially stored in the node (e.g. for ibss merge).
 	 */
-	ATH_VAP(vap)->av_recv_mgmt(ni, m, subtype, rssi, noise, rstamp);
+	ATH_VAP(vap)->av_recv_mgmt(ni, m, subtype, rssi, nf);
 	switch (subtype) {
 	case IEEE80211_FC0_SUBTYPE_BEACON:
 		/* update rssi statistics for use by the hal */
@@ -3599,6 +3601,7 @@ ath_recv_mgmt(struct ieee80211_node *ni,
 	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
 		if (vap->iv_opmode == IEEE80211_M_IBSS &&
 		    vap->iv_state == IEEE80211_S_RUN) {
+			uint32_t rstamp = sc->sc_lastrs->rs_tstamp;
 			u_int64_t tsf = ath_extend_tsf(rstamp,
 				ath_hal_gettsf64(sc->sc_ah));
 			/*
@@ -3639,7 +3642,7 @@ ath_setdefantenna(struct ath_softc *sc, 
 	sc->sc_rxotherant = 0;
 }
 
-static int
+static void
 ath_rx_tap(struct ifnet *ifp, struct mbuf *m,
 	const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf)
 {
@@ -3651,15 +3654,6 @@ ath_rx_tap(struct ifnet *ifp, struct mbu
 	const HAL_RATE_TABLE *rt;
 	uint8_t rix;
 
-	/*
-	 * Discard anything shorter than an ack or cts.
-	 */
-	if (m->m_pkthdr.len < IEEE80211_ACK_LEN) {
-		DPRINTF(sc, ATH_DEBUG_RECV, "%s: runt packet %d\n",
-			__func__, m->m_pkthdr.len);
-		sc->sc_stats.ast_rx_tooshort++;
-		return 0;
-	}
 	rt = sc->sc_currates;
 	KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
 	rix = rt->rateCodeToIndex[rs->rs_rate];
@@ -3684,13 +3678,9 @@ ath_rx_tap(struct ifnet *ifp, struct mbu
 	if (rs->rs_status & HAL_RXERR_CRC)
 		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
 	/* XXX propagate other error flags from descriptor */
-	sc->sc_rx_th.wr_antsignal = rs->rs_rssi + nf;
 	sc->sc_rx_th.wr_antnoise = nf;
+	sc->sc_rx_th.wr_antsignal = nf + rs->rs_rssi;
 	sc->sc_rx_th.wr_antenna = rs->rs_antenna;
-
-	bpf_mtap2(ifp->if_bpf, &sc->sc_rx_th, sc->sc_rx_th_len, m);
-
-	return 1;
 #undef CHAN_HT
 #undef CHAN_HT20
 #undef CHAN_HT40U
@@ -3812,7 +3802,7 @@ ath_rx_proc(void *arg, int npending)
 				sc->sc_stats.ast_rx_badmic++;
 				/*
 				 * Do minimal work required to hand off
-				 * the 802.11 header for notifcation.
+				 * the 802.11 header for notification.
 				 */
 				/* XXX frag's and qos frames */
 				len = rs->rs_datalen;
@@ -3841,14 +3831,15 @@ rx_error:
 			 * pass decrypt+mic errors but others may be
 			 * interesting (e.g. crc).
 			 */
-			if (bpf_peers_present(ifp->if_bpf) &&
+			if (ieee80211_radiotap_active(ic) &&
 			    (rs->rs_status & sc->sc_monpass)) {
 				bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
 				    BUS_DMASYNC_POSTREAD);
 				/* NB: bpf needs the mbuf length setup */
 				len = rs->rs_datalen;
 				m->m_pkthdr.len = m->m_len = len;
-				(void) ath_rx_tap(ifp, m, rs, tsf, nf);
+				ath_rx_tap(ifp, m, rs, tsf, nf);
+				ieee80211_radiotap_rx_all(ic, m);
 			}
 			/* XXX pass MIC errors up for s/w reclaculation */
 			goto rx_next;
@@ -3906,20 +3897,29 @@ rx_accept:
 		ifp->if_ipackets++;
 		sc->sc_stats.ast_ant_rx[rs->rs_antenna]++;
 
-		if (bpf_peers_present(ifp->if_bpf) &&
-		    !ath_rx_tap(ifp, m, rs, tsf, nf)) {
-			m_freem(m);		/* XXX reclaim */
-			goto rx_next;
-		}
+		/*
+		 * Populate the rx status block.  When there are bpf
+		 * listeners we do the additional work to provide
+		 * complete status.  Otherwise we fill in only the
+		 * material required by ieee80211_input.  Note that
+		 * noise setting is filled in above.
+		 */
+		if (ieee80211_radiotap_active(ic))
+			ath_rx_tap(ifp, m, rs, tsf, nf);
 
 		/*
 		 * From this point on we assume the frame is at least
 		 * as large as ieee80211_frame_min; verify that.
 		 */
 		if (len < IEEE80211_MIN_LEN) {
-			DPRINTF(sc, ATH_DEBUG_RECV, "%s: short packet %d\n",
-				__func__, len);
-			sc->sc_stats.ast_rx_tooshort++;
+			if (!ieee80211_radiotap_active(ic)) {
+				DPRINTF(sc, ATH_DEBUG_RECV,
+				    "%s: short packet %d\n", __func__, len);
+				sc->sc_stats.ast_rx_tooshort++;
+			} else {
+				/* NB: in particular this captures ack's */
+				ieee80211_radiotap_rx_all(ic, m);
+			}
 			m_freem(m);
 			goto rx_next;
 		}
@@ -3947,11 +3947,8 @@ rx_accept:
 			/*
 			 * Sending station is known, dispatch directly.
 			 */
-#ifdef IEEE80211_SUPPORT_TDMA
-			sc->sc_tdmars = rs;
-#endif
-			type = ieee80211_input(ni, m,
-			    rs->rs_rssi, nf, rs->rs_tstamp);
+			sc->sc_lastrs = rs;
+			type = ieee80211_input(ni, m, rs->rs_rssi, nf);
 			ieee80211_free_node(ni);
 			/*
 			 * Arrange to update the last rx timestamp only for
@@ -3963,8 +3960,7 @@ rx_accept:
 			    rs->rs_keyix != HAL_RXKEYIX_INVALID)
 				ngood++;
 		} else {
-			type = ieee80211_input_all(ic, m,
-			    rs->rs_rssi, nf, rs->rs_tstamp);
+			type = ieee80211_input_all(ic, m, rs->rs_rssi, nf);
 		}
 		/*
 		 * Track rx rssi and do any rx antenna management.
@@ -4781,7 +4777,7 @@ ath_tx_start(struct ath_softc *sc, struc
 		ieee80211_dump_pkt(ic, mtod(m0, const uint8_t *), m0->m_len,
 		    sc->sc_hwmap[rix].ieeerate, -1);
 
-	if (bpf_peers_present(ifp->if_bpf)) {
+	if (ieee80211_radiotap_active_vap(vap)) {
 		u_int64_t tsf = ath_hal_gettsf64(ah);
 
 		sc->sc_tx_th.wt_tsf = htole64(tsf);
@@ -4794,7 +4790,7 @@ ath_tx_start(struct ath_softc *sc, struc
 		sc->sc_tx_th.wt_txpower = ni->ni_txpower;
 		sc->sc_tx_th.wt_antenna = sc->sc_txantenna;
 
-		bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m0);
+		ieee80211_radiotap_tx(vap, m0);
 	}
 
 	/*
@@ -5289,15 +5285,6 @@ ath_chan_change(struct ath_softc *sc, st
 	if (mode != sc->sc_curmode)
 		ath_setcurmode(sc, mode);
 	sc->sc_curchan = chan;
-
-	sc->sc_rx_th.wr_chan_flags = htole32(chan->ic_flags);
-	sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags;
-	sc->sc_rx_th.wr_chan_freq = htole16(chan->ic_freq);
-	sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq;
-	sc->sc_rx_th.wr_chan_ieee = chan->ic_ieee;
-	sc->sc_tx_th.wt_chan_ieee = sc->sc_rx_th.wr_chan_ieee;
-	sc->sc_rx_th.wr_chan_maxpow = chan->ic_maxregpower;
-	sc->sc_tx_th.wt_chan_maxpow = sc->sc_rx_th.wr_chan_maxpow;
 }
 
 /*
@@ -5988,10 +5975,7 @@ ath_setcurmode(struct ath_softc *sc, enu
 		if (rt->info[i].shortPreamble ||
 		    rt->info[i].phy == IEEE80211_T_OFDM)
 			sc->sc_hwmap[i].txflags |= IEEE80211_RADIOTAP_F_SHORTPRE;
-		/* NB: receive frames include FCS */
-		sc->sc_hwmap[i].rxflags = sc->sc_hwmap[i].txflags |
-			IEEE80211_RADIOTAP_F_FCS;
-		/* setup blink rate table to avoid per-packet lookup */
+		sc->sc_hwmap[i].rxflags = sc->sc_hwmap[i].txflags;
 		for (j = 0; j < N(blinkrates)-1; j++)
 			if (blinkrates[j].rate == sc->sc_hwmap[i].ieeerate)
 				break;
@@ -6627,31 +6611,6 @@ ath_sysctlattach(struct ath_softc *sc)
 #endif
 }
 
-static void
-ath_bpfattach(struct ath_softc *sc)
-{
-	struct ifnet *ifp = sc->sc_ifp;
-
-	bpfattach(ifp, DLT_IEEE802_11_RADIO,
-		sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th));
-	/*
-	 * Initialize constant fields.
-	 * XXX make header lengths a multiple of 32-bits so subsequent
-	 *     headers are properly aligned; this is a kludge to keep
-	 *     certain applications happy.
-	 *
-	 * NB: the channel is setup each time we transition to the
-	 *     RUN state to avoid filling it in for each frame.
-	 */
-	sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(u_int32_t));
-	sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len);
-	sc->sc_tx_th.wt_ihdr.it_present = htole32(ATH_TX_RADIOTAP_PRESENT);
-
-	sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(u_int32_t));
-	sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len);
-	sc->sc_rx_th.wr_ihdr.it_present = htole32(ATH_RX_RADIOTAP_PRESENT);
-}
-
 static int
 ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
 	struct ath_buf *bf, struct mbuf *m0,
@@ -6660,6 +6619,7 @@ ath_tx_raw_start(struct ath_softc *sc, s
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct ath_hal *ah = sc->sc_ah;
+	struct ieee80211vap *vap = ni->ni_vap;
 	int error, ismcast, ismrr;
 	int keyix, hdrlen, pktlen, try0, txantenna;
 	u_int8_t rix, cix, txrate, ctsrate, rate1, rate2, rate3;
@@ -6791,18 +6751,20 @@ ath_tx_raw_start(struct ath_softc *sc, s
 		ieee80211_dump_pkt(ic, mtod(m0, caddr_t), m0->m_len,
 		    sc->sc_hwmap[rix].ieeerate, -1);
 	
-	if (bpf_peers_present(ifp->if_bpf)) {
+	if (ieee80211_radiotap_active_vap(vap)) {
 		u_int64_t tsf = ath_hal_gettsf64(ah);
 
 		sc->sc_tx_th.wt_tsf = htole64(tsf);
 		sc->sc_tx_th.wt_flags = sc->sc_hwmap[rix].txflags;
 		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
+		if (m0->m_flags & M_FRAG)
+			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_FRAG;
 		sc->sc_tx_th.wt_rate = sc->sc_hwmap[rix].ieeerate;
 		sc->sc_tx_th.wt_txpower = ni->ni_txpower;
 		sc->sc_tx_th.wt_antenna = sc->sc_txantenna;
 
-		bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m0);
+		ieee80211_radiotap_tx(vap, m0);
 	}
 
 	/*
@@ -7141,8 +7103,9 @@ ath_tdma_update(struct ieee80211_node *n
 	}
 
 	/* extend rx timestamp to 64 bits */
+	rs = sc->sc_lastrs;
 	tsf = ath_hal_gettsf64(ah);
-	rstamp = ath_extend_tsf(ni->ni_rstamp, tsf);
+	rstamp = ath_extend_tsf(rs->rs_tstamp, tsf);
 	/*
 	 * The rx timestamp is set by the hardware on completing
 	 * reception (at the point where the rx descriptor is DMA'd
@@ -7150,7 +7113,6 @@ ath_tdma_update(struct ieee80211_node *n
 	 * must adjust this time by the time required to send
 	 * the packet just received.
 	 */
-	rs = sc->sc_tdmars;
 	rix = rt->rateCodeToIndex[rs->rs_rate];
 	txtime = ath_hal_computetxtime(ah, rt, rs->rs_datalen, rix,
 	    rt->info[rix].shortPreamble);

Modified: head/sys/dev/ath/if_athvar.h
==============================================================================
--- head/sys/dev/ath/if_athvar.h	Wed May 20 19:53:10 2009	(r192467)
+++ head/sys/dev/ath/if_athvar.h	Wed May 20 20:00:40 2009	(r192468)
@@ -187,7 +187,7 @@ struct ath_vap {
 	struct ath_txq	av_mcastq;	/* buffered mcast s/w queue */
 
 	void		(*av_recv_mgmt)(struct ieee80211_node *,
-				struct mbuf *, int, int, int, u_int32_t);
+				struct mbuf *, int, int, int);
 	int		(*av_newstate)(struct ieee80211vap *,
 				enum ieee80211_state, int);
 	void		(*av_bmiss)(struct ieee80211vap *);
@@ -284,12 +284,6 @@ struct ath_softc {
 	u_int			sc_rfsilentpin;	/* GPIO pin for rfkill int */
 	u_int			sc_rfsilentpol;	/* pin setting for rfkill on */
 
-	struct ath_tx_radiotap_header sc_tx_th;
-	int			sc_tx_th_len;
-	struct ath_rx_radiotap_header sc_rx_th;
-	int			sc_rx_th_len;
-	u_int			sc_monpass;	/* frames to pass in mon.mode */
-
 	struct ath_descdma	sc_rxdma;	/* RX descriptors */
 	ath_bufhead		sc_rxbuf;	/* receive buffer */
 	struct mbuf		*sc_rxpending;	/* pending receive data */
@@ -298,6 +292,10 @@ struct ath_softc {
 	u_int8_t		sc_defant;	/* current default antenna */
 	u_int8_t		sc_rxotherant;	/* rx's on non-default antenna*/
 	u_int64_t		sc_lastrx;	/* tsf at last rx'd frame */
+	struct ath_rx_status	*sc_lastrs;	/* h/w status of last rx */
+	struct ath_rx_radiotap_header sc_rx_th;
+	int			sc_rx_th_len;
+	u_int			sc_monpass;	/* frames to pass in mon.mode */
 
 	struct ath_descdma	sc_txdma;	/* TX descriptors */
 	ath_bufhead		sc_txbuf;	/* transmit buffer */
@@ -310,6 +308,8 @@ struct ath_softc {
 	struct task		sc_txtask;	/* tx int processing */
 	int			sc_wd_timer;	/* count down for wd timer */
 	struct callout		sc_wd_ch;	/* tx watchdog timer */
+	struct ath_tx_radiotap_header sc_tx_th;
+	int			sc_tx_th_len;
 
 	struct ath_descdma	sc_bdma;	/* beacon descriptors */
 	ath_bufhead		sc_bbuf;	/* beacon buffers */
@@ -338,7 +338,6 @@ struct ath_softc {
 	u_int32_t		sc_tdmabintval;	/* TDMA beacon interval (TU) */
 	u_int32_t		sc_tdmaguard;	/* TDMA guard time (usec) */
 	u_int			sc_tdmaslotlen;	/* TDMA slot length (usec) */
-	struct ath_rx_status	*sc_tdmars;	/* TDMA status of last rx */
 	u_int32_t		sc_avgtsfdeltap;/* TDMA slot adjust (+) */
 	u_int32_t		sc_avgtsfdeltam;/* TDMA slot adjust (-) */
 };

Modified: head/sys/dev/bwi/if_bwi.c
==============================================================================
--- head/sys/dev/bwi/if_bwi.c	Wed May 20 19:53:10 2009	(r192467)
+++ head/sys/dev/bwi/if_bwi.c	Wed May 20 20:00:40 2009	(r192468)
@@ -123,7 +123,7 @@ static int	bwi_calc_rssi(struct bwi_soft
 static int	bwi_calc_noise(struct bwi_softc *);
 static __inline uint8_t bwi_ofdm_plcp2rate(const uint32_t *);
 static __inline uint8_t bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *);
-static void	bwi_rx_radiotap(struct ifnet *, struct mbuf *,
+static void	bwi_rx_radiotap(struct bwi_softc *, struct mbuf *,
 			struct bwi_rxbuf_hdr *, const void *, int, int, int);
 
 static void	bwi_restart(void *, int);
@@ -532,19 +532,11 @@ bwi_attach(struct bwi_softc *sc)
 
 	sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
 
-	/*
-	 * Attach bpf.
-	 */
-	bpfattach(ifp, DLT_IEEE802_11_RADIO,
-	    sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th));
-
-	sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(uint32_t));
-	sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len);
-	sc->sc_tx_th.wt_ihdr.it_present = htole32(BWI_TX_RADIOTAP_PRESENT);
-
-	sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(uint32_t));
-	sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len);
-	sc->sc_rx_th.wr_ihdr.it_present = htole32(BWI_RX_RADIOTAP_PRESENT);
+	ieee80211_radiotap_attach(ic,
+	    &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
+		BWI_TX_RADIOTAP_PRESENT,
+	    &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
+		BWI_RX_RADIOTAP_PRESENT);
 
 	/*
 	 * Add sysctl nodes
@@ -2675,8 +2667,8 @@ bwi_rxeof(struct bwi_softc *sc, int end_
 			rate = bwi_ds_plcp2rate(plcp);
 
 		/* RX radio tap */
-		if (bpf_peers_present(ifp->if_bpf))
-			bwi_rx_radiotap(ifp, m, hdr, plcp, rate, rssi, noise);
+		if (ieee80211_radiotap_active(ic))
+			bwi_rx_radiotap(sc, m, hdr, plcp, rate, rssi, noise);
 
 		m_adj(m, -IEEE80211_CRC_LEN);
 
@@ -2685,11 +2677,10 @@ bwi_rxeof(struct bwi_softc *sc, int end_
 		wh = mtod(m, struct ieee80211_frame_min *);
 		ni = ieee80211_find_rxnode(ic, wh);
 		if (ni != NULL) {
-			type = ieee80211_input(ni, m, rssi - noise, noise, 0);
+			type = ieee80211_input(ni, m, rssi - noise, noise);
 			ieee80211_free_node(ni);
 		} else
-			type = ieee80211_input_all(ic, m, rssi - noise,
-			    noise, 0);
+			type = ieee80211_input_all(ic, m, rssi - noise, noise);
 		if (type == IEEE80211_FC0_TYPE_DATA) {
 			rx_data = 1;
 			sc->sc_rx_rate = rate;
@@ -3001,7 +2992,7 @@ bwi_encap(struct bwi_softc *sc, int idx,
 	/*
 	 * TX radio tap
 	 */
-	if (bpf_peers_present(ifp->if_bpf)) {
+	if (ieee80211_radiotap_active_vap(vap)) {
 		sc->sc_tx_th.wt_flags = 0;
 		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
@@ -3012,7 +3003,7 @@ bwi_encap(struct bwi_softc *sc, int idx,
 		}
 		sc->sc_tx_th.wt_rate = rate;
 
-		bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m);
+		ieee80211_radiotap_tx(vap, m);
 	}
 
 	/*
@@ -3134,6 +3125,7 @@ bwi_encap_raw(struct bwi_softc *sc, int 
 	  struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
 {
 	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211vap *vap = ni->ni_vap;
 	struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
 	struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
 	struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
@@ -3169,7 +3161,7 @@ bwi_encap_raw(struct bwi_softc *sc, int 
 	/*
 	 * TX radio tap
 	 */
-	if (bpf_peers_present(ifp->if_bpf)) {
+	if (ieee80211_radiotap_active_vap(vap)) {
 		sc->sc_tx_th.wt_flags = 0;
 		/* XXX IEEE80211_BPF_CRYPTO */
 		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
@@ -3178,7 +3170,7 @@ bwi_encap_raw(struct bwi_softc *sc, int 
 			sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
 		sc->sc_tx_th.wt_rate = rate;
 
-		bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m);
+		ieee80211_radiotap_tx(vap, m);
 	}
 
 	/*
@@ -3806,10 +3798,9 @@ bwi_ds_plcp2rate(const struct ieee80211_
 }
 
 static void
-bwi_rx_radiotap(struct ifnet *ifp, struct mbuf *m,
+bwi_rx_radiotap(struct bwi_softc *sc, struct mbuf *m,
     struct bwi_rxbuf_hdr *hdr, const void *plcp, int rate, int rssi, int noise)
 {
-	struct bwi_softc *sc = ifp->if_softc;
 	const struct ieee80211_frame_min *wh;
 
 	sc->sc_rx_th.wr_flags = IEEE80211_RADIOTAP_F_FCS;
@@ -3824,8 +3815,6 @@ bwi_rx_radiotap(struct ifnet *ifp, struc
 	sc->sc_rx_th.wr_rate = rate;
 	sc->sc_rx_th.wr_antsignal = rssi;
 	sc->sc_rx_th.wr_antnoise = noise;
-
-	bpf_mtap2(ifp->if_bpf, &sc->sc_rx_th, sc->sc_rx_th_len, m);
 }
 
 static void

Modified: head/sys/dev/bwi/if_bwivar.h
==============================================================================
--- head/sys/dev/bwi/if_bwivar.h	Wed May 20 19:53:10 2009	(r192467)
+++ head/sys/dev/bwi/if_bwivar.h	Wed May 20 20:00:40 2009	(r192468)
@@ -615,9 +615,7 @@ struct bwi_softc {
 	const struct ieee80211_rate_table *sc_rates;
 
 	struct bwi_tx_radiotap_hdr sc_tx_th;
-	int			sc_tx_th_len;
 	struct bwi_rx_radiotap_hdr sc_rx_th;
-	int			sc_rx_th_len;
 
 	struct taskqueue	*sc_tq;
 	struct task		sc_restart_task;

Modified: head/sys/dev/ipw/if_ipw.c
==============================================================================
--- head/sys/dev/ipw/if_ipw.c	Wed May 20 19:53:10 2009	(r192467)
+++ head/sys/dev/ipw/if_ipw.c	Wed May 20 20:00:40 2009	(r192468)
@@ -346,16 +346,11 @@ ipw_attach(device_t dev)
 	ic->ic_vap_create = ipw_vap_create;
 	ic->ic_vap_delete = ipw_vap_delete;
 
-	bpfattach(ifp, DLT_IEEE802_11_RADIO,
-	    sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap));
-
-	sc->sc_rxtap_len = sizeof sc->sc_rxtap;
-	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
-	sc->sc_rxtap.wr_ihdr.it_present = htole32(IPW_RX_RADIOTAP_PRESENT);
-
-	sc->sc_txtap_len = sizeof sc->sc_txtap;
-	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
-	sc->sc_txtap.wt_ihdr.it_present = htole32(IPW_TX_RADIOTAP_PRESENT);
+	ieee80211_radiotap_attach(ic,
+	    &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
+		IPW_TX_RADIOTAP_PRESENT,
+	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+		IPW_RX_RADIOTAP_PRESENT);
 
 	/*
 	 * Add a few sysctl knobs.
@@ -407,7 +402,6 @@ ipw_detach(device_t dev)
 	ieee80211_draintask(ic, &sc->sc_init_task);
 	ipw_stop(sc);
 
-	bpfdetach(ifp);
 	ieee80211_ifdetach(ic);
 
 	callout_drain(&sc->sc_wdtimer);
@@ -1107,10 +1101,7 @@ ipw_setcurchan(struct ipw_softc *sc, str
 	struct ieee80211com *ic = ifp->if_l2com;
 
 	ic->ic_curchan = chan;
-	sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq =
-		htole16(ic->ic_curchan->ic_freq);
-	sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags =
-		htole16(ic->ic_curchan->ic_flags);
+	ieee80211_radiotap_chan_change(ic);
 }
 
 /*
@@ -1172,6 +1163,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, s
 	struct ieee80211_node *ni;
 	bus_addr_t physaddr;
 	int error;
+	int8_t rssi, nf;
 	IPW_LOCK_DECL;
 
 	DPRINTFN(5, ("received frame len=%u, rssi=%u\n", le32toh(status->len),
@@ -1226,15 +1218,14 @@ ipw_rx_data_intr(struct ipw_softc *sc, s
 	m->m_pkthdr.rcvif = ifp;
 	m->m_pkthdr.len = m->m_len = le32toh(status->len);
 
-	if (bpf_peers_present(ifp->if_bpf)) {
+	rssi = status->rssi + IPW_RSSI_TO_DBM;
+	nf = -95;
+	if (ieee80211_radiotap_active(ic)) {
 		struct ipw_rx_radiotap_header *tap = &sc->sc_rxtap;
 
 		tap->wr_flags = 0;
-		tap->wr_antsignal = status->rssi + IPW_RSSI_TO_DBM;
-		tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
-		tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
-
-		bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
+		tap->wr_antsignal = rssi;
+		tap->wr_antnoise = nf;
 	}
 
 	if (sc->flags & IPW_FLAG_SCANNING)
@@ -1243,10 +1234,10 @@ ipw_rx_data_intr(struct ipw_softc *sc, s
 	IPW_UNLOCK(sc);
 	ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
 	if (ni != NULL) {
-		(void) ieee80211_input(ni, m, status->rssi, -95, 0);
+		(void) ieee80211_input(ni, m, rssi, nf);
 		ieee80211_free_node(ni);
 	} else
-		(void) ieee80211_input_all(ic, m, status->rssi, -95, 0);
+		(void) ieee80211_input_all(ic, m, rssi, nf);
 	IPW_LOCK(sc);
 
 	bus_dmamap_sync(sc->rbd_dmat, sc->rbd_map, BUS_DMASYNC_PREWRITE);
@@ -1570,6 +1561,7 @@ ipw_tx_start(struct ifnet *ifp, struct m
 {
 	struct ipw_softc *sc = ifp->if_softc;
 	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211_frame *wh;
 	struct ipw_soft_bd *sbd;
 	struct ipw_soft_hdr *shdr;
@@ -1592,14 +1584,12 @@ ipw_tx_start(struct ifnet *ifp, struct m
 		wh = mtod(m0, struct ieee80211_frame *);
 	}
 
-	if (bpf_peers_present(ifp->if_bpf)) {
+	if (ieee80211_radiotap_active_vap(vap)) {
 		struct ipw_tx_radiotap_header *tap = &sc->sc_txtap;
 
 		tap->wt_flags = 0;
-		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
-		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
 
-		bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
+		ieee80211_radiotap_tx(vap, m0);
 	}
 
 	shdr = SLIST_FIRST(&sc->free_shdr);

Modified: head/sys/dev/ipw/if_ipwvar.h
==============================================================================
--- head/sys/dev/ipw/if_ipwvar.h	Wed May 20 19:53:10 2009	(r192467)
+++ head/sys/dev/ipw/if_ipwvar.h	Wed May 20 20:00:40 2009	(r192468)
@@ -57,13 +57,15 @@ struct ipw_rx_radiotap_header {
 	uint8_t		wr_flags;
 	uint16_t	wr_chan_freq;
 	uint16_t	wr_chan_flags;
-	uint8_t		wr_antsignal;
+	int8_t		wr_antsignal;
+	int8_t		wr_antnoise;
 };
 
 #define IPW_RX_RADIOTAP_PRESENT						\
 	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
 	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
-	 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
+	 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) |			\
+	 (1 << IEEE80211_RADIOTAP_DB_ANTNOISE))
 
 struct ipw_tx_radiotap_header {
 	struct ieee80211_radiotap_header wt_ihdr;
@@ -155,10 +157,7 @@ struct ipw_softc {
 	int				txfree;
 
 	struct ipw_rx_radiotap_header	sc_rxtap;
-	int				sc_rxtap_len;
-
 	struct ipw_tx_radiotap_header	sc_txtap;
-	int				sc_txtap_len;
 };
 
 /*

Modified: head/sys/dev/iwi/if_iwi.c
==============================================================================
--- head/sys/dev/iwi/if_iwi.c	Wed May 20 19:53:10 2009	(r192467)
+++ head/sys/dev/iwi/if_iwi.c	Wed May 20 20:00:40 2009	(r192468)
@@ -419,16 +419,11 @@ iwi_attach(device_t dev)
 	ic->ic_vap_create = iwi_vap_create;
 	ic->ic_vap_delete = iwi_vap_delete;
 
-	bpfattach(ifp, DLT_IEEE802_11_RADIO,
-	    sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap));
-
-	sc->sc_rxtap_len = sizeof sc->sc_rxtap;
-	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
-	sc->sc_rxtap.wr_ihdr.it_present = htole32(IWI_RX_RADIOTAP_PRESENT);
-
-	sc->sc_txtap_len = sizeof sc->sc_txtap;
-	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
-	sc->sc_txtap.wt_ihdr.it_present = htole32(IWI_TX_RADIOTAP_PRESENT);
+	ieee80211_radiotap_attach(ic,
+	    &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
+		IWI_TX_RADIOTAP_PRESENT,
+	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+		IWI_RX_RADIOTAP_PRESENT);
 
 	iwi_sysctlattach(sc);
 	iwi_ledattach(sc);
@@ -468,7 +463,6 @@ iwi_detach(device_t dev)
 
 	iwi_stop(sc);
 
-	bpfdetach(ifp);
 	ieee80211_ifdetach(ic);
 
 	iwi_put_firmware(sc);
@@ -1196,11 +1190,7 @@ iwi_setcurchan(struct iwi_softc *sc, int
 	struct ieee80211com *ic = ifp->if_l2com;
 
 	sc->curchan = chan;
-
-	sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq =
-		htole16(ic->ic_curchan->ic_freq);
-	sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags =
-		htole16(ic->ic_curchan->ic_flags);
+	ieee80211_radiotap_chan_change(ic);
 }
 
 static void
@@ -1212,6 +1202,7 @@ iwi_frame_intr(struct iwi_softc *sc, str
 	struct mbuf *mnew, *m;
 	struct ieee80211_node *ni;
 	int type, error, framelen;
+	int8_t rssi, nf;
 	IWI_LOCK_DECL;
 
 	framelen = le16toh(frame->len);
@@ -1283,24 +1274,25 @@ iwi_frame_intr(struct iwi_softc *sc, str
 
 	m_adj(m, sizeof (struct iwi_hdr) + sizeof (struct iwi_frame));
 
-	if (bpf_peers_present(ifp->if_bpf)) {
+	rssi = frame->signal;
+	nf = -95;
+	if (ieee80211_radiotap_active(ic)) {
 		struct iwi_rx_radiotap_header *tap = &sc->sc_rxtap;
 
 		tap->wr_flags = 0;
+		tap->wr_antsignal = rssi;
+		tap->wr_antnoise = nf;
 		tap->wr_rate = iwi_cvtrate(frame->rate);
-		tap->wr_antsignal = frame->signal;
 		tap->wr_antenna = frame->antenna;
-
-		bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
 	}
 	IWI_UNLOCK(sc);
 
 	ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
 	if (ni != NULL) {
-		type = ieee80211_input(ni, m, frame->rssi_dbm, 0, 0);
+		type = ieee80211_input(ni, m, rssi, nf);
 		ieee80211_free_node(ni);
 	} else
-		type = ieee80211_input_all(ic, m, frame->rssi_dbm, 0, 0);
+		type = ieee80211_input_all(ic, m, rssi, nf);
 
 	IWI_LOCK(sc);
 	if (sc->sc_softled) {
@@ -1852,12 +1844,12 @@ iwi_tx_start(struct ifnet *ifp, struct m
 		wh = mtod(m0, struct ieee80211_frame *);
 	}
 
-	if (bpf_peers_present(ifp->if_bpf)) {
+	if (ieee80211_radiotap_active_vap(vap)) {
 		struct iwi_tx_radiotap_header *tap = &sc->sc_txtap;
 
 		tap->wt_flags = 0;
 
-		bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
+		ieee80211_radiotap_tx(vap, m0);
 	}
 
 	data = &txq->data[txq->cur];

Modified: head/sys/dev/iwi/if_iwivar.h
==============================================================================
--- head/sys/dev/iwi/if_iwivar.h	Wed May 20 19:53:10 2009	(r192467)
+++ head/sys/dev/iwi/if_iwivar.h	Wed May 20 20:00:40 2009	(r192468)
@@ -33,7 +33,8 @@ struct iwi_rx_radiotap_header {
 	uint8_t		wr_rate;
 	uint16_t	wr_chan_freq;
 	uint16_t	wr_chan_flags;
-	uint8_t		wr_antsignal;
+	int8_t		wr_antsignal;
+	int8_t		wr_antnoise;
 	uint8_t		wr_antenna;
 };
 
@@ -42,6 +43,7 @@ struct iwi_rx_radiotap_header {
 	 (1 << IEEE80211_RADIOTAP_RATE) |				\
 	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
 	 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) |			\
+	 (1 << IEEE80211_RADIOTAP_DB_ANTNOISE) |			\
 	 (1 << IEEE80211_RADIOTAP_ANTENNA))
 
 struct iwi_tx_radiotap_header {
@@ -213,10 +215,7 @@ struct iwi_softc {
 	int			sc_busy_timer;	/* firmware cmd timer */
 
 	struct iwi_rx_radiotap_header sc_rxtap;
-	int			sc_rxtap_len;
-
 	struct iwi_tx_radiotap_header sc_txtap;
-	int			sc_txtap_len;
 };
 
 #define	IWI_STATE_BEGIN(_sc, _state)	do {			\

Modified: head/sys/dev/iwn/if_iwn.c
==============================================================================
--- head/sys/dev/iwn/if_iwn.c	Wed May 20 19:53:10 2009	(r192467)
+++ head/sys/dev/iwn/if_iwn.c	Wed May 20 20:00:40 2009	(r192468)
@@ -185,7 +185,6 @@ static void 	iwn_scan_mindwell(struct ie
 static void	iwn_hwreset(void *, int);
 static void	iwn_radioon(void *, int);
 static void	iwn_radiooff(void *, int);
-static void	iwn_bpfattach(struct iwn_softc *);
 static void	iwn_sysctlattach(struct iwn_softc *);
 
 #define IWN_DEBUG
@@ -426,7 +425,12 @@ iwn_attach(device_t dev)
         ic->ic_scan_curchan = iwn_scan_curchan;
         ic->ic_scan_mindwell = iwn_scan_mindwell;
 
-	iwn_bpfattach(sc);
+	ieee80211_radiotap_attach(ic,
+            &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
+		IWN_TX_RADIOTAP_PRESENT,
+            &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+		IWN_RX_RADIOTAP_PRESENT);
+
 	iwn_sysctlattach(sc);
 
         /*
@@ -471,7 +475,6 @@ iwn_cleanup(device_t dev)
 	if (ifp != NULL) {
 		iwn_stop(sc);
 		callout_drain(&sc->sc_timer_to);
-		bpfdetach(ifp);
 		ieee80211_ifdetach(ic);
 	}
 
@@ -1472,29 +1475,26 @@ iwn_rx_intr(struct iwn_softc *sc, struct
 	nf = (ni != NULL && ni->ni_vap->iv_state == IEEE80211_S_RUN &&
 	    (ic->ic_flags & IEEE80211_F_SCAN) == 0) ? sc->noise : -95;
 
-	if (bpf_peers_present(ifp->if_bpf)) {
+	if (ieee80211_radiotap_active(ic)) {
 		struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
 
-		tap->wr_flags = 0;
-		tap->wr_dbm_antsignal = rssi;
-		tap->wr_dbm_antnoise = nf;
-		tap->wr_rate = maprate(stat->rate);
 		tap->wr_tsft = htole64(stat->tstamp);
-
+		tap->wr_flags = 0;
 		if (stat->flags & htole16(IWN_CONFIG_SHPREAMBLE))
 			tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
-
-		bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
+		tap->wr_rate = maprate(stat->rate);
+		tap->wr_dbm_antsignal = rssi;
+		tap->wr_dbm_antnoise = nf;
 	}
 
 	IWN_UNLOCK(sc);
 
 	/* send the frame to the 802.11 layer */
 	if (ni != NULL) {
-		(void) ieee80211_input(ni, m, rssi - nf, nf, 0);
+		(void) ieee80211_input(ni, m, rssi - nf, nf);
 		ieee80211_free_node(ni);
 	} else
-		(void) ieee80211_input_all(ic, m, rssi - nf, nf, 0);
+		(void) ieee80211_input_all(ic, m, rssi - nf, nf);
 
 	IWN_LOCK(sc);
 }
@@ -1931,7 +1931,7 @@ iwn_tx_data(struct iwn_softc *sc, struct
 	} else
 		k = NULL;
 
-	if (bpf_peers_present(ifp->if_bpf)) {
+	if (ieee80211_radiotap_active_vap(vap)) {
 		struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
 
 		tap->wt_flags = 0;
@@ -1939,7 +1939,7 @@ iwn_tx_data(struct iwn_softc *sc, struct
 		if (k != NULL)
 			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
 
-		bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
+		ieee80211_radiotap_tx(vap, m0);
 	}
 
 	flags = IWN_TX_AUTO_SEQ;
@@ -2226,7 +2226,7 @@ iwn_tx_data_raw(struct iwn_softc *sc, st
     struct ieee80211_node *ni, struct iwn_tx_ring *ring,
     const struct ieee80211_bpf_params *params)
 {
-	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211vap *vap = ni->ni_vap;
 	struct iwn_tx_cmd *cmd;
 	struct iwn_cmd_data *tx;
 	struct ieee80211_frame *wh;
@@ -2264,13 +2264,13 @@ iwn_tx_data_raw(struct iwn_softc *sc, st
 	/* pick a tx rate */
 	rate = params->ibp_rate0;
 
-	if (bpf_peers_present(ifp->if_bpf)) {
+	if (ieee80211_radiotap_active_vap(vap)) {
 		struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
 
 		tap->wt_flags = 0;
 		tap->wt_rate = rate;
 
-		bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
+		ieee80211_radiotap_tx(vap, m0);
 	}
 
 	cmd = &ring->cmd[ring->cur];
@@ -4412,23 +4412,6 @@ iwn_radiooff(void *arg0, int pending)
 }
 
 static void
-iwn_bpfattach(struct iwn_softc *sc)
-{
-	struct ifnet *ifp = sc->sc_ifp;
-
-        bpfattach(ifp, DLT_IEEE802_11_RADIO,
-            sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap));
-
-        sc->sc_rxtap_len = sizeof sc->sc_rxtap;
-        sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
-        sc->sc_rxtap.wr_ihdr.it_present = htole32(IWN_RX_RADIOTAP_PRESENT);
-
-        sc->sc_txtap_len = sizeof sc->sc_txtap;
-        sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
-        sc->sc_txtap.wt_ihdr.it_present = htole32(IWN_TX_RADIOTAP_PRESENT);
-}
-
-static void
 iwn_sysctlattach(struct iwn_softc *sc)
 {
 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);

Modified: head/sys/dev/iwn/if_iwnvar.h
==============================================================================
--- head/sys/dev/iwn/if_iwnvar.h	Wed May 20 19:53:10 2009	(r192467)
+++ head/sys/dev/iwn/if_iwnvar.h	Wed May 20 20:00:40 2009	(r192468)
@@ -144,9 +144,7 @@ struct iwn_softc {
 	const struct ieee80211_channel *sc_curchan;
 
         struct iwn_rx_radiotap_header sc_rxtap;
-        int                     sc_rxtap_len;
         struct iwn_tx_radiotap_header sc_txtap;
-        int                     sc_txtap_len;
 
 	/* locks */
 	struct mtx		sc_mtx;

Modified: head/sys/dev/malo/if_malo.c
==============================================================================
--- head/sys/dev/malo/if_malo.c	Wed May 20 19:53:10 2009	(r192467)
+++ head/sys/dev/malo/if_malo.c	Wed May 20 20:00:40 2009	(r192468)
@@ -144,7 +144,6 @@ static	void	malo_scan_end(struct ieee802
 static	void	malo_set_channel(struct ieee80211com *);
 static	int	malo_raw_xmit(struct ieee80211_node *, struct mbuf *,
 		    const struct ieee80211_bpf_params *);
-static	void	malo_bpfattach(struct malo_softc *);
 static	void	malo_sysctlattach(struct malo_softc *);
 static	void	malo_announce(struct malo_softc *);
 static	void	malo_dma_cleanup(struct malo_softc *);
@@ -317,7 +316,11 @@ malo_attach(uint16_t devid, struct malo_
 
 	sc->malo_invalid = 0;		/* ready to go, enable int handling */
 
-	malo_bpfattach(sc);
+	ieee80211_radiotap_attach(ic,
+	    &sc->malo_tx_th.wt_ihdr, sizeof(sc->malo_tx_th),
+		MALO_TX_RADIOTAP_PRESENT,
+	    &sc->malo_rx_th.wr_ihdr, sizeof(sc->malo_rx_th),
+		MALO_RX_RADIOTAP_PRESENT);
 
 	/*
 	 * Setup dynamic sysctl's.
@@ -1091,6 +1094,7 @@ malo_tx_start(struct malo_softc *sc, str
 	struct ieee80211_frame *wh;
 	struct ifnet *ifp = sc->malo_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
+	struct ieee80211vap *vap = ni->ni_vap;
 	struct malo_txdesc *ds;
 	struct malo_txrec *tr;
 	struct malo_txq *txq;
@@ -1148,14 +1152,14 @@ malo_tx_start(struct malo_softc *sc, str
 		wh = mtod(m0, struct ieee80211_frame *);
 	}
 
-	if (bpf_peers_present(ifp->if_bpf)) {
+	if (ieee80211_radiotap_active_vap(vap)) {
 		sc->malo_tx_th.wt_flags = 0;	/* XXX */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



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