summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2009-05-20 20:00:40 +0000
committersam <sam@FreeBSD.org>2009-05-20 20:00:40 +0000
commit68f7a1034ab73897585652ceedd3727d57150c12 (patch)
treec9b0cc01e080db542eb19f65236177aacfa14b5d /sys/dev
parentdf90a80062bff5ee7300c9b15aaeeaa9c1b49b5e (diff)
downloadFreeBSD-src-68f7a1034ab73897585652ceedd3727d57150c12.zip
FreeBSD-src-68f7a1034ab73897585652ceedd3727d57150c12.tar.gz
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
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ath/if_ath.c132
-rw-r--r--sys/dev/ath/if_athvar.h15
-rw-r--r--sys/dev/bwi/if_bwi.c43
-rw-r--r--sys/dev/bwi/if_bwivar.h2
-rw-r--r--sys/dev/ipw/if_ipw.c44
-rw-r--r--sys/dev/ipw/if_ipwvar.h9
-rw-r--r--sys/dev/iwi/if_iwi.c40
-rw-r--r--sys/dev/iwi/if_iwivar.h7
-rw-r--r--sys/dev/iwn/if_iwn.c53
-rw-r--r--sys/dev/iwn/if_iwnvar.h2
-rw-r--r--sys/dev/malo/if_malo.c49
-rw-r--r--sys/dev/malo/if_malo.h3
-rw-r--r--sys/dev/ral/rt2560.c77
-rw-r--r--sys/dev/ral/rt2560var.h6
-rw-r--r--sys/dev/ral/rt2661.c66
-rw-r--r--sys/dev/ral/rt2661var.h6
-rw-r--r--sys/dev/usb/wlan/if_rum.c55
-rw-r--r--sys/dev/usb/wlan/if_rumvar.h7
-rw-r--r--sys/dev/usb/wlan/if_uath.c73
-rw-r--r--sys/dev/usb/wlan/if_uathvar.h31
-rw-r--r--sys/dev/usb/wlan/if_upgt.c32
-rw-r--r--sys/dev/usb/wlan/if_ural.c61
-rw-r--r--sys/dev/usb/wlan/if_uralvar.h6
-rw-r--r--sys/dev/usb/wlan/if_zyd.c38
-rw-r--r--sys/dev/wi/if_wi.c99
-rw-r--r--sys/dev/wi/if_wireg.h4
-rw-r--r--sys/dev/wi/if_wivar.h6
-rw-r--r--sys/dev/wpi/if_wpi.c30
-rw-r--r--sys/dev/wpi/if_wpivar.h2
29 files changed, 426 insertions, 572 deletions
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index aa52a3e..05930e3 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -172,7 +172,7 @@ static void ath_node_getsignal(const struct ieee80211_node *,
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_softc *, enum ieee80211_phymode);
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_softc *sc)
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_t tsf)
*/
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, struct mbuf *m,
* 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, struct mbuf *m,
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, u_int antenna)
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 mbuf *m,
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 mbuf *m,
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, struct ieee80211_node *ni, struct ath_buf *bf
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, struct ieee80211_node *ni, struct ath_buf *bf
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, struct ieee80211_channel *chan)
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, enum ieee80211_phymode mode)
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, struct ieee80211_node *ni,
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, struct ieee80211_node *ni,
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 *ni,
}
/* 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 *ni,
* 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);
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index 8f88b59..9d9e459 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -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 (-) */
};
diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c
index 1cb8c0b..48580a5 100644
--- a/sys/dev/bwi/if_bwi.c
+++ b/sys/dev/bwi/if_bwi.c
@@ -123,7 +123,7 @@ static int bwi_calc_rssi(struct bwi_softc *, const struct bwi_rxbuf_hdr *);
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_idx)
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_idx)
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, struct mbuf *m,
/*
* 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, struct mbuf *m,
}
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 idx, struct mbuf *m,
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 idx, struct mbuf *m,
/*
* 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 idx, struct mbuf *m,
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_ds_plcp_hdr *hdr)
}
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, struct mbuf *m,
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
diff --git a/sys/dev/bwi/if_bwivar.h b/sys/dev/bwi/if_bwivar.h
index 311e38f..af4b0ea 100644
--- a/sys/dev/bwi/if_bwivar.h
+++ b/sys/dev/bwi/if_bwivar.h
@@ -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;
diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c
index c69ab6d..1c4e492 100644
--- a/sys/dev/ipw/if_ipw.c
+++ b/sys/dev/ipw/if_ipw.c
@@ -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, struct ieee80211_channel *chan)
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, struct ipw_status *status,
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, struct ipw_status *status,
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, struct ipw_status *status,
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 mbuf *m0, struct ieee80211_node *ni)
{
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 mbuf *m0, struct ieee80211_node *ni)
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);
diff --git a/sys/dev/ipw/if_ipwvar.h b/sys/dev/ipw/if_ipwvar.h
index 24fb8e8..8d9e049 100644
--- a/sys/dev/ipw/if_ipwvar.h
+++ b/sys/dev/ipw/if_ipwvar.h
@@ -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;
};
/*
diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c
index f7d891e..dcfde7e 100644
--- a/sys/dev/iwi/if_iwi.c
+++ b/sys/dev/iwi/if_iwi.c
@@ -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 chan)
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, struct iwi_rx_data *data, int i,
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, struct iwi_rx_data *data, int i,
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 mbuf *m0, struct ieee80211_node *ni,
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];
diff --git a/sys/dev/iwi/if_iwivar.h b/sys/dev/iwi/if_iwivar.h
index b31af36..1acb6c3 100644
--- a/sys/dev/iwi/if_iwivar.h
+++ b/sys/dev/iwi/if_iwivar.h
@@ -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 { \
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index 9913d90..cc12828 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -185,7 +185,6 @@ static void iwn_scan_mindwell(struct ieee80211_scan_state *);
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 iwn_rx_desc *desc,
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 mbuf *m0, struct ieee80211_node *ni,
} 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 mbuf *m0, struct ieee80211_node *ni,
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, struct mbuf *m0,
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, struct mbuf *m0,
/* 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);
diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h
index d956525..19cc025 100644
--- a/sys/dev/iwn/if_iwnvar.h
+++ b/sys/dev/iwn/if_iwnvar.h
@@ -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;
diff --git a/sys/dev/malo/if_malo.c b/sys/dev/malo/if_malo.c
index c17e98c..e9c6716 100644
--- a/sys/dev/malo/if_malo.c
+++ b/sys/dev/malo/if_malo.c
@@ -144,7 +144,6 @@ static void malo_scan_end(struct ieee80211com *);
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_softc *sc)
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, struct ieee80211_node *ni,
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, struct ieee80211_node *ni,
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 */
if (iswep)
sc->malo_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
sc->malo_tx_th.wt_txpower = ni->ni_txpower;
sc->malo_tx_th.wt_antenna = sc->malo_txantenna;
- bpf_mtap2(ifp->if_bpf, &sc->malo_tx_th, sc->malo_tx_th_len, m0);
+ ieee80211_radiotap_tx(vap, m0);
}
/*
@@ -1900,32 +1904,6 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
}
static void
-malo_bpfattach(struct malo_softc *sc)
-{
- struct ifnet *ifp = sc->malo_ifp;
-
- bpfattach(ifp, DLT_IEEE802_11_RADIO,
- sizeof(struct ieee80211_frame) + sizeof(sc->malo_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->malo_tx_th_len = roundup(sizeof(sc->malo_tx_th), sizeof(uint32_t));
- sc->malo_tx_th.wt_ihdr.it_len = htole16(sc->malo_tx_th_len);
- sc->malo_tx_th.wt_ihdr.it_present = htole32(MALO_TX_RADIOTAP_PRESENT);
-
- sc->malo_rx_th_len = roundup(sizeof(sc->malo_rx_th), sizeof(uint32_t));
- sc->malo_rx_th.wr_ihdr.it_len = htole16(sc->malo_rx_th_len);
- sc->malo_rx_th.wr_ihdr.it_present = htole32(MALO_RX_RADIOTAP_PRESENT);
-}
-
-static void
malo_sysctlattach(struct malo_softc *sc)
{
#ifdef MALO_DEBUG
@@ -2173,14 +2151,11 @@ malo_rx_proc(void *arg, int npending)
*(uint16_t *)wh->i_qos = ds->qosctrl;
}
}
- if (sc->malo_drvbpf != NULL) {
+ if (ieee80211_radiotap_active(ic)) {
sc->malo_rx_th.wr_flags = 0;
sc->malo_rx_th.wr_rate = ds->rate;
sc->malo_rx_th.wr_antsignal = rssi;
sc->malo_rx_th.wr_antnoise = ds->nf;
-
- bpf_mtap2(ifp->if_bpf, &sc->malo_rx_th,
- sc->malo_rx_th_len, m);
}
#ifdef MALO_DEBUG
if (IFF_DUMPPKTS_RECV(sc, wh)) {
@@ -2194,10 +2169,10 @@ malo_rx_proc(void *arg, int npending)
ni = ieee80211_find_rxnode(ic,
(struct ieee80211_frame_min *)wh);
if (ni != NULL) {
- (void) ieee80211_input(ni, m, rssi, ds->nf, 0);
+ (void) ieee80211_input(ni, m, rssi, ds->nf);
ieee80211_free_node(ni);
} else
- (void) ieee80211_input_all(ic, m, rssi, ds->nf, 0);
+ (void) ieee80211_input_all(ic, m, rssi, ds->nf);
rx_next:
/* NB: ignore ENOMEM so we process more descriptors */
(void) malo_rxbuf_init(sc, bf);
@@ -2253,8 +2228,6 @@ malo_detach(struct malo_softc *sc)
sc->malo_tq = NULL;
}
- bpfdetach(ifp);
-
/*
* NB: the order of these is important:
* o call the 802.11 layer before detaching the hal to
diff --git a/sys/dev/malo/if_malo.h b/sys/dev/malo/if_malo.h
index 070649a..7e3a7e8 100644
--- a/sys/dev/malo/if_malo.h
+++ b/sys/dev/malo/if_malo.h
@@ -551,11 +551,8 @@ struct malo_softc {
struct malo_txq malo_txq[MALO_NUM_TX_QUEUES];
struct task malo_txtask; /* tx int processing */
- struct bpf_if *malo_drvbpf;
struct malo_tx_radiotap_header malo_tx_th;
- int malo_tx_th_len;
struct malo_rx_radiotap_header malo_rx_th;
- int malo_rx_th_len;
struct malo_stats malo_stats; /* interface statistics */
int malo_debug;
diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c
index 936fe8e..95c5ebd 100644
--- a/sys/dev/ral/rt2560.c
+++ b/sys/dev/ral/rt2560.c
@@ -144,6 +144,7 @@ static void rt2560_set_chan(struct rt2560_softc *,
static void rt2560_disable_rf_tune(struct rt2560_softc *);
#endif
static void rt2560_enable_tsf_sync(struct rt2560_softc *);
+static void rt2560_enable_tsf(struct rt2560_softc *);
static void rt2560_update_plcp(struct rt2560_softc *);
static void rt2560_update_slot(struct ifnet *);
static void rt2560_set_basicrates(struct rt2560_softc *);
@@ -313,16 +314,11 @@ rt2560_attach(device_t dev, int id)
ic->ic_vap_create = rt2560_vap_create;
ic->ic_vap_delete = rt2560_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(RT2560_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(RT2560_TX_RADIOTAP_PRESENT);
+ ieee80211_radiotap_attach(ic,
+ &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
+ RT2560_TX_RADIOTAP_PRESENT,
+ &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+ RT2560_RX_RADIOTAP_PRESENT);
/*
* Add a few sysctl knobs.
@@ -364,7 +360,6 @@ rt2560_detach(void *xsc)
rt2560_stop(sc);
- bpfdetach(ifp);
ieee80211_ifdetach(ic);
rt2560_free_tx_ring(sc, &sc->txq);
@@ -833,6 +828,8 @@ rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
if (vap->iv_opmode != IEEE80211_M_MONITOR)
rt2560_enable_tsf_sync(sc);
+ else
+ rt2560_enable_tsf(sc);
}
return error;
}
@@ -1146,6 +1143,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
struct ieee80211_node *ni;
struct mbuf *mnew, *m;
int hw, error;
+ int8_t rssi, nf;
/* retrieve last decriptor index processed by cipher engine */
hw = RAL_READ(sc, RT2560_SECCSR0) - sc->rxq.physaddr;
@@ -1222,7 +1220,9 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
m->m_pkthdr.len = m->m_len =
(le32toh(desc->flags) >> 16) & 0xfff;
- if (bpf_peers_present(ifp->if_bpf)) {
+ rssi = RT2560_RSSI(sc, desc->rssi);
+ nf = RT2560_NOISE_FLOOR;
+ if (ieee80211_radiotap_active(ic)) {
struct rt2560_rx_radiotap_header *tap = &sc->sc_rxtap;
uint32_t tsf_lo, tsf_hi;
@@ -1237,9 +1237,8 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
(desc->flags & htole32(RT2560_RX_OFDM)) ?
IEEE80211_T_OFDM : IEEE80211_T_CCK);
tap->wr_antenna = sc->rx_ant;
- tap->wr_antsignal = RT2560_RSSI(sc, desc->rssi);
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
+ tap->wr_antsignal = nf + rssi;
+ tap->wr_antnoise = nf;
}
sc->sc_flags |= RT2560_F_INPUT_RUNNING;
@@ -1248,12 +1247,10 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
ni = ieee80211_find_rxnode(ic,
(struct ieee80211_frame_min *)wh);
if (ni != NULL) {
- (void) ieee80211_input(ni, m,
- RT2560_RSSI(sc, desc->rssi), RT2560_NOISE_FLOOR, 0);
+ (void) ieee80211_input(ni, m, rssi, nf);
ieee80211_free_node(ni);
} else
- (void) ieee80211_input_all(ic, m,
- RT2560_RSSI(sc, desc->rssi), RT2560_NOISE_FLOOR, 0);
+ (void) ieee80211_input_all(ic, m, rssi, nf);
RAL_LOCK(sc);
sc->sc_flags &= ~RT2560_F_INPUT_RUNNING;
@@ -1507,8 +1504,6 @@ rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0,
struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = sc->sc_ifp;
struct rt2560_tx_desc *desc;
struct rt2560_tx_data *data;
bus_dma_segment_t segs[RT2560_MAX_SCATTER];
@@ -1529,16 +1524,14 @@ rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0,
return error;
}
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active_vap(vap)) {
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
tap->wt_antenna = sc->tx_ant;
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
+ ieee80211_radiotap_tx(vap, m0);
}
data->m = m0;
@@ -1565,7 +1558,6 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0,
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = sc->sc_ifp;
struct rt2560_tx_desc *desc;
struct rt2560_tx_data *data;
struct ieee80211_frame *wh;
@@ -1599,16 +1591,14 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0,
return error;
}
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active_vap(vap)) {
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
tap->wt_antenna = sc->tx_ant;
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
+ ieee80211_radiotap_tx(vap, m0);
}
data->m = m0;
@@ -1724,8 +1714,7 @@ static int
rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0,
struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211vap *vap = ni->ni_vap;
struct rt2560_tx_desc *desc;
struct rt2560_tx_data *data;
bus_dma_segment_t segs[RT2560_MAX_SCATTER];
@@ -1767,16 +1756,14 @@ rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0,
return error;
}
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active_vap(vap)) {
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
tap->wt_antenna = sc->tx_ant;
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
+ ieee80211_radiotap_tx(ni->ni_vap, m0);
}
data->m = m0;
@@ -1808,7 +1795,6 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = sc->sc_ifp;
struct rt2560_tx_desc *desc;
struct rt2560_tx_data *data;
struct ieee80211_frame *wh;
@@ -1897,14 +1883,14 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
wh = mtod(m0, struct ieee80211_frame *);
}
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active_vap(vap)) {
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
tap->wt_rate = rate;
tap->wt_antenna = sc->tx_ant;
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
+ ieee80211_radiotap_tx(vap, m0);
}
data->m = m0;
@@ -2234,11 +2220,6 @@ rt2560_set_channel(struct ieee80211com *ic)
RAL_LOCK(sc);
rt2560_set_chan(sc, ic->ic_curchan);
-
- sc->sc_txtap.wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- sc->sc_txtap.wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
- sc->sc_rxtap.wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- sc->sc_rxtap.wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
RAL_UNLOCK(sc);
}
@@ -2303,6 +2284,14 @@ rt2560_enable_tsf_sync(struct rt2560_softc *sc)
}
static void
+rt2560_enable_tsf(struct rt2560_softc *sc)
+{
+ RAL_WRITE(sc, RT2560_CSR14, 0);
+ RAL_WRITE(sc, RT2560_CSR14,
+ RT2560_ENABLE_TSF_SYNC(2) | RT2560_ENABLE_TSF);
+}
+
+static void
rt2560_update_plcp(struct rt2560_softc *sc)
{
struct ifnet *ifp = sc->sc_ifp;
diff --git a/sys/dev/ral/rt2560var.h b/sys/dev/ral/rt2560var.h
index d53c0d1..288577b 100644
--- a/sys/dev/ral/rt2560var.h
+++ b/sys/dev/ral/rt2560var.h
@@ -24,8 +24,9 @@ struct rt2560_rx_radiotap_header {
uint8_t wr_rate;
uint16_t wr_chan_freq;
uint16_t wr_chan_flags;
+ int8_t wr_antsignal;
+ int8_t wr_antnoise;
uint8_t wr_antenna;
- uint8_t wr_antsignal;
};
#define RT2560_RX_RADIOTAP_PRESENT \
@@ -34,7 +35,8 @@ struct rt2560_rx_radiotap_header {
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
- (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
+ (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
+ (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
struct rt2560_tx_radiotap_header {
struct ieee80211_radiotap_header wt_ihdr;
diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c
index a3b1986..8b30c9b 100644
--- a/sys/dev/ral/rt2661.c
+++ b/sys/dev/ral/rt2661.c
@@ -169,6 +169,7 @@ static int rt2661_radar_stop(struct rt2661_softc *);
static int rt2661_prepare_beacon(struct rt2661_softc *,
struct ieee80211vap *);
static void rt2661_enable_tsf_sync(struct rt2661_softc *);
+static void rt2661_enable_tsf(struct rt2661_softc *);
static int rt2661_get_rssi(struct rt2661_softc *, uint8_t);
static const struct {
@@ -319,16 +320,11 @@ rt2661_attach(device_t dev, int id)
ic->ic_vap_create = rt2661_vap_create;
ic->ic_vap_delete = rt2661_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(RT2661_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(RT2661_TX_RADIOTAP_PRESENT);
+ ieee80211_radiotap_attach(ic,
+ &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
+ RT2661_TX_RADIOTAP_PRESENT,
+ &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+ RT2661_RX_RADIOTAP_PRESENT);
#ifdef RAL_DEBUG
SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
@@ -359,7 +355,6 @@ rt2661_detach(void *xsc)
rt2661_stop_locked(sc);
RAL_UNLOCK(sc);
- bpfdetach(ifp);
ieee80211_ifdetach(ic);
rt2661_free_tx_ring(sc, &sc->txq[0]);
@@ -830,6 +825,8 @@ rt2661_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
}
if (vap->iv_opmode != IEEE80211_M_MONITOR)
rt2661_enable_tsf_sync(sc);
+ else
+ rt2661_enable_tsf(sc);
}
return error;
}
@@ -1025,7 +1022,7 @@ rt2661_rx_intr(struct rt2661_softc *sc)
BUS_DMASYNC_POSTREAD);
for (;;) {
- int rssi;
+ int8_t rssi, nf;
desc = &sc->rxq.desc[sc->rxq.cur];
data = &sc->rxq.data[sc->rxq.cur];
@@ -1100,8 +1097,12 @@ rt2661_rx_intr(struct rt2661_softc *sc)
(le32toh(desc->flags) >> 16) & 0xfff;
rssi = rt2661_get_rssi(sc, desc->rssi);
+ /* Error happened during RSSI conversion. */
+ if (rssi < 0)
+ rssi = -30; /* XXX ignored by net80211 */
+ nf = RT2661_NOISE_FLOOR;
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active(ic)) {
struct rt2661_rx_radiotap_header *tap = &sc->sc_rxtap;
uint32_t tsf_lo, tsf_hi;
@@ -1115,9 +1116,8 @@ rt2661_rx_intr(struct rt2661_softc *sc)
tap->wr_rate = ieee80211_plcp2rate(desc->rate,
(desc->flags & htole32(RT2661_RX_OFDM)) ?
IEEE80211_T_OFDM : IEEE80211_T_CCK);
- tap->wr_antsignal = rssi < 0 ? 0 : rssi;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
+ tap->wr_antsignal = nf + rssi;
+ tap->wr_antnoise = nf;
}
sc->sc_flags |= RAL_INPUT_RUNNING;
RAL_UNLOCK(sc);
@@ -1127,16 +1127,10 @@ rt2661_rx_intr(struct rt2661_softc *sc)
ni = ieee80211_find_rxnode(ic,
(struct ieee80211_frame_min *)wh);
if (ni != NULL) {
- /* Error happened during RSSI conversion. */
- if (rssi < 0)
- rssi = -30; /* XXX ignored by net80211 */
-
- (void) ieee80211_input(ni, m, rssi,
- RT2661_NOISE_FLOOR, 0);
+ (void) ieee80211_input(ni, m, rssi, nf);
ieee80211_free_node(ni);
} else
- (void) ieee80211_input_all(ic, m, rssi,
- RT2661_NOISE_FLOOR, 0);
+ (void) ieee80211_input_all(ic, m, rssi, nf);
RAL_LOCK(sc);
sc->sc_flags &= ~RAL_INPUT_RUNNING;
@@ -1332,7 +1326,6 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0,
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = sc->sc_ifp;
struct rt2661_tx_desc *desc;
struct rt2661_tx_data *data;
struct ieee80211_frame *wh;
@@ -1366,13 +1359,13 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0,
return error;
}
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active_vap(vap)) {
struct rt2661_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);
}
data->m = m0;
@@ -1587,15 +1580,13 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
wh = mtod(m0, struct ieee80211_frame *);
}
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active_vap(vap)) {
struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
tap->wt_rate = rate;
- 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);
}
data->m = m0;
@@ -2789,6 +2780,14 @@ rt2661_enable_tsf_sync(struct rt2661_softc *sc)
RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp);
}
+static void
+rt2661_enable_tsf(struct rt2661_softc *sc)
+{
+ RAL_WRITE(sc, RT2661_TXRX_CSR9,
+ (RAL_READ(sc, RT2661_TXRX_CSR9) & 0xff000000)
+ | RT2661_TSF_TICKING | RT2661_TSF_MODE(2));
+}
+
/*
* Retrieve the "Received Signal Strength Indicator" from the raw values
* contained in Rx descriptors. The computation depends on which band the
@@ -2869,11 +2868,6 @@ rt2661_set_channel(struct ieee80211com *ic)
RAL_LOCK(sc);
rt2661_set_chan(sc, ic->ic_curchan);
-
- sc->sc_txtap.wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- sc->sc_txtap.wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
- sc->sc_rxtap.wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- sc->sc_rxtap.wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
RAL_UNLOCK(sc);
}
diff --git a/sys/dev/ral/rt2661var.h b/sys/dev/ral/rt2661var.h
index 6fc958a..db1d4de 100644
--- a/sys/dev/ral/rt2661var.h
+++ b/sys/dev/ral/rt2661var.h
@@ -24,7 +24,8 @@ struct rt2661_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;
} __packed;
#define RT2661_RX_RADIOTAP_PRESENT \
@@ -32,7 +33,8 @@ struct rt2661_rx_radiotap_header {
(1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
+ (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
+ (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
struct rt2661_tx_radiotap_header {
struct ieee80211_radiotap_header wt_ihdr;
diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
index 0c3012e..9d8e575 100644
--- a/sys/dev/usb/wlan/if_rum.c
+++ b/sys/dev/usb/wlan/if_rum.c
@@ -196,6 +196,7 @@ static void rum_select_band(struct rum_softc *,
static void rum_set_chan(struct rum_softc *,
struct ieee80211_channel *);
static void rum_enable_tsf_sync(struct rum_softc *);
+static void rum_enable_tsf(struct rum_softc *);
static void rum_update_slot(struct ifnet *);
static void rum_set_bssid(struct rum_softc *, const uint8_t *);
static void rum_set_macaddr(struct rum_softc *, const uint8_t *);
@@ -522,16 +523,11 @@ rum_attach(device_t self)
ic->ic_vap_create = rum_vap_create;
ic->ic_vap_delete = rum_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(RT2573_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(RT2573_TX_RADIOTAP_PRESENT);
+ ieee80211_radiotap_attach(ic,
+ &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
+ RT2573_TX_RADIOTAP_PRESENT,
+ &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+ RT2573_RX_RADIOTAP_PRESENT);
if (bootverbose)
ieee80211_announce(ic);
@@ -560,7 +556,6 @@ rum_detach(device_t self)
if (ifp) {
ic = ifp->if_l2com;
- bpfdetach(ifp);
ieee80211_ifdetach(ic);
if_free(ifp);
}
@@ -752,9 +747,11 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
if (vap->iv_opmode != IEEE80211_M_MONITOR)
rum_enable_tsf_sync(sc);
+ else
+ rum_enable_tsf(sc);
/* enable automatic rate adaptation */
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
+ tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
rum_amrr_start(sc, ni);
break;
@@ -771,8 +768,7 @@ rum_bulk_write_callback(struct usb2_xfer *xfer)
{
struct rum_softc *sc = xfer->priv_sc;
struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211_channel *c = ic->ic_curchan;
+ struct ieee80211vap *vap;
struct rum_tx_data *data;
struct mbuf *m;
unsigned int len;
@@ -807,16 +803,15 @@ tr_setup:
usb2_m_copy_in(xfer->frbuffers, RT2573_TX_DESC_SIZE, m,
0, m->m_pkthdr.len);
- if (bpf_peers_present(ifp->if_bpf)) {
+ vap = data->ni->ni_vap;
+ if (ieee80211_radiotap_active_vap(vap)) {
struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
tap->wt_rate = data->rate;
- tap->wt_chan_freq = htole16(c->ic_freq);
- tap->wt_chan_flags = htole16(c->ic_flags);
tap->wt_antenna = sc->tx_ant;
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
+ ieee80211_radiotap_tx(vap, m);
}
/* align end on a 4-bytes boundary */
@@ -911,19 +906,17 @@ rum_bulk_read_callback(struct usb2_xfer *xfer)
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active(ic)) {
struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
- tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
+ /* XXX read tsf */
+ tap->wr_flags = 0;
tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
(flags & RT2573_RX_OFDM) ?
IEEE80211_T_OFDM : IEEE80211_T_CCK);
- tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
+ tap->wr_antsignal = RT2573_NOISE_FLOOR + rssi;
+ tap->wr_antnoise = RT2573_NOISE_FLOOR;
tap->wr_antenna = sc->rx_ant;
- tap->wr_antsignal = rssi;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
}
/* FALLTHROUGH */
case USB_ST_SETUP:
@@ -942,11 +935,11 @@ tr_setup:
mtod(m, struct ieee80211_frame_min *));
if (ni != NULL) {
(void) ieee80211_input(ni, m, rssi,
- RT2573_NOISE_FLOOR, 0);
+ RT2573_NOISE_FLOOR);
ieee80211_free_node(ni);
} else
(void) ieee80211_input_all(ic, m, rssi,
- RT2573_NOISE_FLOOR, 0);
+ RT2573_NOISE_FLOOR);
RUM_LOCK(sc);
}
return;
@@ -1737,6 +1730,14 @@ rum_enable_tsf_sync(struct rum_softc *sc)
}
static void
+rum_enable_tsf(struct rum_softc *sc)
+{
+ rum_write(sc, RT2573_TXRX_CSR9,
+ (rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000) |
+ RT2573_TSF_TICKING | RT2573_TSF_MODE(2));
+}
+
+static void
rum_update_slot(struct ifnet *ifp)
{
struct rum_softc *sc = ifp->if_softc;
diff --git a/sys/dev/usb/wlan/if_rumvar.h b/sys/dev/usb/wlan/if_rumvar.h
index 2ba4007..13b84f7 100644
--- a/sys/dev/usb/wlan/if_rumvar.h
+++ b/sys/dev/usb/wlan/if_rumvar.h
@@ -26,16 +26,19 @@ struct rum_rx_radiotap_header {
uint8_t wr_rate;
uint16_t wr_chan_freq;
uint16_t wr_chan_flags;
+ int8_t wr_antsignal;
+ int8_t wr_antnoise;
uint8_t wr_antenna;
- uint8_t wr_antsignal;
};
#define RT2573_RX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
+ (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
+ (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
- (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
+ 0)
struct rum_tx_radiotap_header {
struct ieee80211_radiotap_header wt_ihdr;
diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c
index f647dae..f5f1b1a 100644
--- a/sys/dev/usb/wlan/if_uath.c
+++ b/sys/dev/usb/wlan/if_uath.c
@@ -481,16 +481,11 @@ uath_attach(device_t dev)
ic->ic_update_mcast = uath_update_mcast;
ic->ic_update_promisc = uath_update_promisc;
- 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(UATH_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(UATH_TX_RADIOTAP_PRESENT);
+ ieee80211_radiotap_attach(ic,
+ &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
+ UATH_TX_RADIOTAP_PRESENT,
+ &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+ UATH_RX_RADIOTAP_PRESENT);
if (bootverbose)
ieee80211_announce(ic);
@@ -531,7 +526,6 @@ uath_detach(device_t dev)
uath_free_cmd_list(sc, sc->sc_cmd, UATH_CMD_LIST_COUNT);
UATH_UNLOCK(sc);
- bpfdetach(ifp);
if_free(ifp);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -1601,8 +1595,6 @@ static int
uath_tx_start(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
struct uath_data *data)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = ni->ni_vap;
struct uath_chunk *chunk;
struct uath_tx_desc *desc;
@@ -1617,16 +1609,14 @@ uath_tx_start(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
chunk = (struct uath_chunk *)data->buf;
desc = (struct uath_tx_desc *)(chunk + 1);
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active_vap(vap)) {
struct uath_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
if (m0->m_flags & M_FRAG)
tap->wt_flags |= IEEE80211_RADIOTAP_F_FRAG;
- 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);
}
wh = mtod(m0, struct ieee80211_frame *);
@@ -1921,7 +1911,7 @@ uath_set_channel(struct ieee80211com *ic)
static int
uath_set_rxmulti_filter(struct uath_softc *sc)
{
-
+ /* XXX broken */
return (0);
}
static void
@@ -1929,13 +1919,14 @@ uath_update_mcast(struct ifnet *ifp)
{
struct uath_softc *sc = ifp->if_softc;
+ UATH_LOCK(sc);
/*
* this is for avoiding the race condition when we're try to
* connect to the AP with WPA.
*/
- if (!(sc->sc_flags & UATH_FLAG_INITDONE))
- return;
- (void)uath_set_rxmulti_filter(sc);
+ if (sc->sc_flags & UATH_FLAG_INITDONE)
+ (void)uath_set_rxmulti_filter(sc);
+ UATH_UNLOCK(sc);
}
static void
@@ -1943,12 +1934,14 @@ uath_update_promisc(struct ifnet *ifp)
{
struct uath_softc *sc = ifp->if_softc;
- if (!(sc->sc_flags & UATH_FLAG_INITDONE))
- return;
- uath_set_rxfilter(sc,
- UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST |
- UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON |
- UATH_FILTER_RX_PROM, UATH_FILTER_OP_SET);
+ UATH_LOCK(sc);
+ if (sc->sc_flags & UATH_FLAG_INITDONE) {
+ uath_set_rxfilter(sc,
+ UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST |
+ UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON |
+ UATH_FILTER_RX_PROM, UATH_FILTER_OP_SET);
+ }
+ UATH_UNLOCK(sc);
}
static int
@@ -2653,14 +2646,22 @@ uath_data_rxeof(struct usb2_xfer *xfer, struct uath_data *data,
}
/* there are a lot more fields in the RX descriptor */
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active(ic)) {
struct uath_rx_radiotap_header *tap = &sc->sc_rxtap;
-
- tap->wr_chan_freq = htole16(be32toh(desc->channel));
- tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wr_dbm_antsignal = (int8_t)be32toh(desc->rssi);
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
+ uint32_t tsf_hi = be32toh(desc->tstamp_high);
+ uint32_t tsf_lo = be32toh(desc->tstamp_low);
+
+ /* XXX only get low order 24bits of tsf from h/w */
+ tap->wr_tsf = htole64(((uint64_t)tsf_hi << 32) | tsf_lo);
+ tap->wr_flags = 0;
+ if (be32toh(desc->status) == UATH_STATUS_CRC_ERR)
+ tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
+ /* XXX map other status to BADFCS? */
+ /* XXX ath h/w rate code, need to map */
+ tap->wr_rate = be32toh(desc->rate);
+ tap->wr_antenna = be32toh(desc->antenna);
+ tap->wr_antsignal = -95 + be32toh(desc->rssi);
+ tap->wr_antnoise = -95;
}
ifp->if_ipackets++;
@@ -2721,12 +2722,12 @@ setup:
nf = -95; /* XXX */
if (ni != NULL) {
(void) ieee80211_input(ni, m,
- (int)be32toh(desc->rssi), nf, 0);
+ (int)be32toh(desc->rssi), nf);
/* node is no longer needed */
ieee80211_free_node(ni);
} else
(void) ieee80211_input_all(ic, m,
- (int)be32toh(desc->rssi), nf, 0);
+ (int)be32toh(desc->rssi), nf);
m = NULL;
desc = NULL;
}
diff --git a/sys/dev/usb/wlan/if_uathvar.h b/sys/dev/usb/wlan/if_uathvar.h
index 2757ad4..9b0a126 100644
--- a/sys/dev/usb/wlan/if_uathvar.h
+++ b/sys/dev/usb/wlan/if_uathvar.h
@@ -44,22 +44,31 @@ enum {
struct uath_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
- uint8_t wr_flags;
- uint16_t wr_chan_freq;
- uint16_t wr_chan_flags;
- int8_t wr_dbm_antsignal;
+ u_int64_t wr_tsf;
+ u_int8_t wr_flags;
+ u_int8_t wr_rate;
+ uint16_t wr_chan_freq;
+ uint16_t wr_chan_flags;
+ int8_t wr_antsignal;
+ int8_t wr_antnoise;
+ u_int8_t wr_antenna;
} __packed;
-#define UATH_RX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL))
+#define UATH_RX_RADIOTAP_PRESENT ( \
+ (1 << IEEE80211_RADIOTAP_TSFT) | \
+ (1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
+ (1 << IEEE80211_RADIOTAP_ANTENNA) | \
+ (1 << IEEE80211_RADIOTAP_CHANNEL) | \
+ (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
+ (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
+ 0)
struct uath_tx_radiotap_header {
struct ieee80211_radiotap_header wt_ihdr;
- uint8_t wt_flags;
- uint16_t wt_chan_freq;
- uint16_t wt_chan_flags;
+ uint8_t wt_flags;
+ uint16_t wt_chan_freq;
+ uint16_t wt_chan_flags;
} __packed;
#define UATH_TX_RADIOTAP_PRESENT \
diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c
index d99c740..c10e8ec 100644
--- a/sys/dev/usb/wlan/if_upgt.c
+++ b/sys/dev/usb/wlan/if_upgt.c
@@ -367,14 +367,11 @@ upgt_attach(device_t dev)
ic->ic_vap_delete = upgt_vap_delete;
ic->ic_update_mcast = upgt_update_mcast;
- 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(UPGT_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(UPGT_TX_RADIOTAP_PRESENT);
+ ieee80211_radiotap_attach(ic,
+ &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
+ UPGT_TX_RADIOTAP_PRESENT,
+ &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+ UPGT_RX_RADIOTAP_PRESENT);
upgt_sysctl_node(sc);
@@ -1507,16 +1504,12 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
m->m_len = m->m_pkthdr.len = pkglen - IEEE80211_CRC_LEN;
m->m_pkthdr.rcvif = ifp;
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active(ic)) {
struct upgt_rx_radiotap_header *tap = &sc->sc_rxtap;
tap->wr_flags = 0;
tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate);
- tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
tap->wr_antsignal = rxdesc->rssi;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
}
ifp->if_ipackets++;
@@ -2011,7 +2004,6 @@ upgt_detach(device_t dev)
upgt_free_rx(sc);
upgt_free_tx(sc);
- bpfdetach(ifp);
if_free(ifp);
mtx_destroy(&sc->sc_mtx);
@@ -2157,11 +2149,11 @@ static int
upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
struct upgt_data *data)
{
+ struct ieee80211vap *vap = ni->ni_vap;
int error = 0, len;
struct ieee80211_frame *wh;
struct ieee80211_key *k;
struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
struct upgt_lmac_mem *mem;
struct upgt_lmac_tx_desc *txdesc;
@@ -2211,15 +2203,13 @@ upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
txdesc->type = htole32(UPGT_TX_DESC_TYPE_DATA);
txdesc->pad3[0] = UPGT_TX_DESC_PAD3_SIZE;
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active_vap(vap)) {
struct upgt_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
tap->wt_rate = 0; /* XXX where to get from? */
- 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, m);
+ ieee80211_radiotap_tx(vap, m);
}
/* copy frame below our TX descriptor header */
@@ -2299,11 +2289,11 @@ setup:
(struct ieee80211_frame_min *)wh);
nf = -95; /* XXX */
if (ni != NULL) {
- (void) ieee80211_input(ni, m, rssi, nf, 0);
+ (void) ieee80211_input(ni, m, rssi, nf);
/* node is no longer needed */
ieee80211_free_node(ni);
} else
- (void) ieee80211_input_all(ic, m, rssi, nf, 0);
+ (void) ieee80211_input_all(ic, m, rssi, nf);
m = NULL;
}
UPGT_LOCK(sc);
diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c
index 523cc61..732b520 100644
--- a/sys/dev/usb/wlan/if_ural.c
+++ b/sys/dev/usb/wlan/if_ural.c
@@ -176,6 +176,7 @@ static void ural_set_chan(struct ural_softc *,
struct ieee80211_channel *);
static void ural_disable_rf_tune(struct ural_softc *);
static void ural_enable_tsf_sync(struct ural_softc *);
+static void ural_enable_tsf(struct ural_softc *);
static void ural_update_slot(struct ifnet *);
static void ural_set_txpreamble(struct ural_softc *);
static void ural_set_basicrates(struct ural_softc *,
@@ -513,16 +514,11 @@ ural_attach(device_t self)
ic->ic_vap_create = ural_vap_create;
ic->ic_vap_delete = ural_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(RAL_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(RAL_TX_RADIOTAP_PRESENT);
+ ieee80211_radiotap_attach(ic,
+ &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
+ RAL_TX_RADIOTAP_PRESENT,
+ &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+ RAL_RX_RADIOTAP_PRESENT);
if (bootverbose)
ieee80211_announce(ic);
@@ -551,7 +547,6 @@ ural_detach(device_t self)
if (ifp) {
ic = ifp->if_l2com;
- bpfdetach(ifp);
ieee80211_ifdetach(ic);
if_free(ifp);
}
@@ -761,9 +756,12 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
if (vap->iv_opmode != IEEE80211_M_MONITOR)
ural_enable_tsf_sync(sc);
+ else
+ ural_enable_tsf(sc);
/* enable automatic rate adaptation */
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
+ /* XXX should use ic_bsschan but not valid until after newstate call below */
+ tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
ural_amrr_start(sc, ni);
@@ -783,8 +781,7 @@ ural_bulk_write_callback(struct usb2_xfer *xfer)
{
struct ural_softc *sc = xfer->priv_sc;
struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211_channel *c = ic->ic_curchan;
+ struct ieee80211vap *vap;
struct ural_tx_data *data;
struct mbuf *m;
unsigned int len;
@@ -819,16 +816,15 @@ tr_setup:
usb2_m_copy_in(xfer->frbuffers, RAL_TX_DESC_SIZE, m, 0,
m->m_pkthdr.len);
- if (bpf_peers_present(ifp->if_bpf)) {
+ vap = data->ni->ni_vap;
+ if (ieee80211_radiotap_active_vap(vap)) {
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
tap->wt_rate = data->rate;
- tap->wt_chan_freq = htole16(c->ic_freq);
- tap->wt_chan_flags = htole16(c->ic_flags);
tap->wt_antenna = sc->tx_ant;
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
+ ieee80211_radiotap_tx(vap, m);
}
/* xfer length needs to be a multiple of two! */
@@ -877,7 +873,7 @@ ural_bulk_read_callback(struct usb2_xfer *xfer)
struct ieee80211_node *ni;
struct mbuf *m = NULL;
uint32_t flags;
- uint8_t rssi = 0;
+ int8_t rssi = 0, nf = 0;
unsigned int len;
switch (USB_GET_STATE(xfer)) {
@@ -899,6 +895,7 @@ ural_bulk_read_callback(struct usb2_xfer *xfer)
RAL_RX_DESC_SIZE);
rssi = URAL_RSSI(sc->sc_rx_desc.rssi);
+ nf = RAL_NOISE_FLOOR;
flags = le32toh(sc->sc_rx_desc.flags);
if (flags & (RAL_RX_PHY_ERROR | RAL_RX_CRC_ERROR)) {
/*
@@ -923,19 +920,17 @@ ural_bulk_read_callback(struct usb2_xfer *xfer)
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active(ic)) {
struct ural_rx_radiotap_header *tap = &sc->sc_rxtap;
- tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
+ /* XXX set once */
+ tap->wr_flags = 0;
tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
(flags & RAL_RX_OFDM) ?
IEEE80211_T_OFDM : IEEE80211_T_CCK);
- tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
tap->wr_antenna = sc->rx_ant;
- tap->wr_antsignal = rssi;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
+ tap->wr_antsignal = nf + rssi;
+ tap->wr_antnoise = nf;
}
/* Strip trailing 802.11 MAC FCS. */
m_adj(m, -IEEE80211_CRC_LEN);
@@ -956,12 +951,10 @@ tr_setup:
ni = ieee80211_find_rxnode(ic,
mtod(m, struct ieee80211_frame_min *));
if (ni != NULL) {
- (void) ieee80211_input(ni, m, rssi,
- RAL_NOISE_FLOOR, 0);
+ (void) ieee80211_input(ni, m, rssi, nf);
ieee80211_free_node(ni);
} else
- (void) ieee80211_input_all(ic, m, rssi,
- RAL_NOISE_FLOOR, 0);
+ (void) ieee80211_input_all(ic, m, rssi, nf);
RAL_LOCK(sc);
}
return;
@@ -1799,6 +1792,14 @@ ural_enable_tsf_sync(struct ural_softc *sc)
DPRINTF("enabling TSF synchronization\n");
}
+static void
+ural_enable_tsf(struct ural_softc *sc)
+{
+ /* first, disable TSF synchronization */
+ ural_write(sc, RAL_TXRX_CSR19, 0);
+ ural_write(sc, RAL_TXRX_CSR19, RAL_ENABLE_TSF | RAL_ENABLE_TSF_SYNC(2));
+}
+
#define RAL_RXTX_TURNAROUND 5 /* us */
static void
ural_update_slot(struct ifnet *ifp)
diff --git a/sys/dev/usb/wlan/if_uralvar.h b/sys/dev/usb/wlan/if_uralvar.h
index 5149f6b..663e0c1 100644
--- a/sys/dev/usb/wlan/if_uralvar.h
+++ b/sys/dev/usb/wlan/if_uralvar.h
@@ -31,8 +31,9 @@ struct ural_rx_radiotap_header {
uint8_t wr_rate;
uint16_t wr_chan_freq;
uint16_t wr_chan_flags;
+ int8_t wr_antsignal;
+ int8_t wr_antnoise;
uint8_t wr_antenna;
- uint8_t wr_antsignal;
};
#define RAL_RX_RADIOTAP_PRESENT \
@@ -40,7 +41,8 @@ struct ural_rx_radiotap_header {
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
- (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
+ (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
+ (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
struct ural_tx_radiotap_header {
struct ieee80211_radiotap_header wt_ihdr;
diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
index c386ea8..ecf1e88 100644
--- a/sys/dev/usb/wlan/if_zyd.c
+++ b/sys/dev/usb/wlan/if_zyd.c
@@ -421,14 +421,11 @@ zyd_attach(device_t dev)
ic->ic_update_mcast = zyd_update_mcast;
ic->ic_update_promisc = zyd_update_mcast;
- 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(ZYD_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(ZYD_TX_RADIOTAP_PRESENT);
+ ieee80211_radiotap_attach(ic,
+ &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
+ ZYD_TX_RADIOTAP_PRESENT,
+ &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+ ZYD_RX_RADIOTAP_PRESENT);
if (bootverbose)
ieee80211_announce(ic);
@@ -455,7 +452,6 @@ zyd_detach(device_t dev)
if (ifp) {
ic = ifp->if_l2com;
- bpfdetach(ifp);
ieee80211_ifdetach(ic);
if_free(ifp);
}
@@ -2132,6 +2128,7 @@ zyd_rx_data(struct usb2_xfer *xfer, int offset, uint16_t len)
{
struct zyd_softc *sc = xfer->priv_sc;
struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
struct zyd_plcphdr plcp;
struct zyd_rx_stat stat;
struct mbuf *m;
@@ -2180,7 +2177,7 @@ zyd_rx_data(struct usb2_xfer *xfer, int offset, uint16_t len)
usb2_copy_out(xfer->frbuffers, offset + sizeof(plcp),
mtod(m, uint8_t *), rlen);
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active(ic)) {
struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap;
tap->wr_flags = 0;
@@ -2194,8 +2191,6 @@ zyd_rx_data(struct usb2_xfer *xfer, int offset, uint16_t len)
IEEE80211_T_OFDM : IEEE80211_T_CCK);
tap->wr_antsignal = stat.rssi + -95;
tap->wr_antnoise = -95; /* XXX */
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
}
rssi = (stat.rssi > 63) ? 127 : 2 * stat.rssi;
@@ -2272,10 +2267,10 @@ tr_setup:
ni = ieee80211_find_rxnode(ic,
mtod(m, struct ieee80211_frame_min *));
if (ni != NULL) {
- (void)ieee80211_input(ni, m, rssi, nf, 0);
+ (void)ieee80211_input(ni, m, rssi, nf);
ieee80211_free_node(ni);
} else
- (void)ieee80211_input_all(ic, m, rssi, nf, 0);
+ (void)ieee80211_input_all(ic, m, rssi, nf);
}
ZYD_LOCK(sc);
break;
@@ -2331,7 +2326,6 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = sc->sc_ifp;
struct zyd_tx_desc *desc;
struct zyd_tx_data *data;
struct ieee80211_frame *wh;
@@ -2409,13 +2403,13 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
desc->plcp_service |= ZYD_PLCP_LENGEXT;
}
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active_vap(vap)) {
struct zyd_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);
}
DPRINTF(sc, ZYD_DEBUG_XMIT,
@@ -2434,8 +2428,7 @@ zyd_bulk_write_callback(struct usb2_xfer *xfer)
{
struct zyd_softc *sc = xfer->priv_sc;
struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211_channel *c = ic->ic_curchan;
+ struct ieee80211vap *vap;
struct zyd_tx_data *data;
struct mbuf *m;
@@ -2470,15 +2463,14 @@ tr_setup:
usb2_m_copy_in(xfer->frbuffers, ZYD_TX_DESC_SIZE, m, 0,
m->m_pkthdr.len);
- if (bpf_peers_present(ifp->if_bpf)) {
+ vap = data->ni->ni_vap;
+ if (ieee80211_radiotap_active_vap(vap)) {
struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
tap->wt_rate = data->rate;
- tap->wt_chan_freq = htole16(c->ic_freq);
- tap->wt_chan_flags = htole16(c->ic_flags);
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
+ ieee80211_radiotap_tx(vap, m);
}
xfer->frlengths[0] = ZYD_TX_DESC_SIZE + m->m_pkthdr.len;
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index 3dc329b..5cdec5f 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -121,9 +121,10 @@ static int wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr,
static int wi_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static int wi_newstate_sta(struct ieee80211vap *, enum ieee80211_state, int);
-static int wi_newstate_hostap(struct ieee80211vap *, enum ieee80211_state, int);
+static int wi_newstate_hostap(struct ieee80211vap *, enum ieee80211_state,
+ int);
static void wi_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 int wi_reset(struct wi_softc *);
static void wi_watchdog(void *);
static int wi_ioctl(struct ifnet *, u_long, caddr_t);
@@ -139,6 +140,7 @@ static int wi_write_txrate(struct wi_softc *, struct ieee80211vap *);
static int wi_write_wep(struct wi_softc *, struct ieee80211vap *);
static int wi_write_multi(struct wi_softc *);
static void wi_update_mcast(struct ifnet *);
+static void wi_update_promisc(struct ifnet *);
static int wi_alloc_fid(struct wi_softc *, int, int *);
static void wi_read_nicid(struct wi_softc *);
static int wi_write_ssid(struct wi_softc *, int, u_int8_t *, int);
@@ -455,25 +457,13 @@ wi_attach(device_t dev)
ic->ic_vap_create = wi_vap_create;
ic->ic_vap_delete = wi_vap_delete;
ic->ic_update_mcast = wi_update_mcast;
+ ic->ic_update_promisc = wi_update_promisc;
- 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(WI_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(WI_RX_RADIOTAP_PRESENT);
+ ieee80211_radiotap_attach(ic,
+ &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
+ WI_TX_RADIOTAP_PRESENT,
+ &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
+ WI_RX_RADIOTAP_PRESENT);
if (bootverbose)
ieee80211_announce(ic);
@@ -482,7 +472,6 @@ wi_attach(device_t dev)
NULL, wi_intr, sc, &sc->wi_intrhand);
if (error) {
device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
- bpfdetach(ifp);
ieee80211_ifdetach(ic);
if_free(sc->sc_ifp);
wi_free(dev);
@@ -506,7 +495,6 @@ wi_detach(device_t dev)
wi_stop_locked(sc, 0);
WI_UNLOCK(sc);
- bpfdetach(ifp);
ieee80211_ifdetach(ic);
bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
@@ -761,11 +749,6 @@ wi_set_channel(struct ieee80211com *ic)
WI_LOCK(sc);
wi_write_val(sc, WI_RID_OWN_CHNL,
ieee80211_chan2ieee(ic, ic->ic_curchan));
-
- sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
- htole16(ic->ic_curchan->ic_freq);
- sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
- htole16(ic->ic_curchan->ic_flags);
WI_UNLOCK(sc);
}
@@ -812,7 +795,7 @@ wi_scan_end(struct ieee80211com *ic)
static void
wi_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;
@@ -823,7 +806,7 @@ wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
/* NB: filter frames that trigger state changes */
return;
}
- WI_VAP(vap)->wv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp);
+ WI_VAP(vap)->wv_recv_mgmt(ni, m, subtype, rssi, nf);
}
static int
@@ -1025,10 +1008,9 @@ wi_start_locked(struct ifnet *ifp)
frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
}
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active_vap(ni->ni_vap)) {
sc->sc_tx_th.wt_rate = ni->ni_txrate;
- bpf_mtap2(ifp->if_bpf,
- &sc->sc_tx_th, sc->sc_tx_th_len, m0);
+ ieee80211_radiotap_tx(ni->ni_vap, m0);
}
m_copydata(m0, 0, sizeof(struct ieee80211_frame),
@@ -1088,6 +1070,7 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
{
struct ieee80211com *ic = ni->ni_ic;
struct ifnet *ifp = ic->ic_ifp;
+ struct ieee80211vap *vap = ni->ni_vap;
struct wi_softc *sc = ifp->if_softc;
struct ieee80211_key *k;
struct ieee80211_frame *wh;
@@ -1127,9 +1110,9 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
}
frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
}
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active_vap(vap)) {
sc->sc_tx_th.wt_rate = ni->ni_txrate;
- bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m0);
+ ieee80211_radiotap_tx(vap, m0);
}
m_copydata(m0, 0, sizeof(struct ieee80211_frame),
(caddr_t)&frmhdr.wi_whdr);
@@ -1328,10 +1311,10 @@ wi_rx_intr(struct wi_softc *sc)
struct mbuf *m;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
- int fid, len, off, rssi;
+ int fid, len, off;
u_int8_t dir;
u_int16_t status;
- u_int32_t rstamp;
+ int8_t rssi, nf;
fid = CSR_READ_2(sc, WI_RX_FID);
@@ -1353,9 +1336,6 @@ wi_rx_intr(struct wi_softc *sc)
DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status));
return;
}
- rssi = frmhdr.wi_rx_signal;
- rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) |
- le16toh(frmhdr.wi_rx_tstamp1);
len = le16toh(frmhdr.wi_dat_len);
off = ALIGN(sizeof(struct ieee80211_frame));
@@ -1393,17 +1373,24 @@ wi_rx_intr(struct wi_softc *sc)
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
- if (bpf_peers_present(ifp->if_bpf)) {
+ rssi = frmhdr.wi_rx_signal;
+ nf = frmhdr.wi_rx_silence;
+ if (ieee80211_radiotap_active(ic)) {
+ struct wi_rx_radiotap_header *tap = &sc->sc_rx_th;
+ uint32_t rstamp;
+
+ rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) |
+ le16toh(frmhdr.wi_rx_tstamp1);
+ tap->wr_tsf = htole64(rstamp);
/* XXX replace divide by table */
- sc->sc_rx_th.wr_rate = frmhdr.wi_rx_rate / 5;
- sc->sc_rx_th.wr_antsignal = frmhdr.wi_rx_signal;
- sc->sc_rx_th.wr_antnoise = frmhdr.wi_rx_silence;
- sc->sc_rx_th.wr_flags = 0;
+ tap->wr_rate = frmhdr.wi_rx_rate / 5;
+ tap->wr_flags = 0;
if (frmhdr.wi_status & WI_STAT_PCF)
- sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_CFP;
+ tap->wr_flags |= IEEE80211_RADIOTAP_F_CFP;
if (m->m_flags & M_WEP)
- sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
- bpf_mtap2(ifp->if_bpf, &sc->sc_rx_th, sc->sc_rx_th_len, m);
+ tap->wr_flags |= IEEE80211_RADIOTAP_F_WEP;
+ tap->wr_antsignal = rssi;
+ tap->wr_antnoise = nf;
}
/* synchronize driver's BSSID with firmware's BSSID */
@@ -1416,10 +1403,10 @@ wi_rx_intr(struct wi_softc *sc)
ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
if (ni != NULL) {
- (void) ieee80211_input(ni, m, rssi, -95/*XXX*/, rstamp);
+ (void) ieee80211_input(ni, m, rssi, nf);
ieee80211_free_node(ni);
} else
- (void) ieee80211_input_all(ic, m, rssi, -95/*XXX*/, rstamp);
+ (void) ieee80211_input_all(ic, m, rssi, nf);
WI_LOCK(sc);
}
@@ -1615,6 +1602,20 @@ wi_update_mcast(struct ifnet *ifp)
}
static void
+wi_update_promisc(struct ifnet *ifp)
+{
+ struct wi_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = ifp->if_l2com;
+
+ WI_LOCK(sc);
+ /* XXX handle WEP special case handling? */
+ wi_write_val(sc, WI_RID_PROMISC,
+ (ic->ic_opmode == IEEE80211_M_MONITOR ||
+ (ifp->if_flags & IFF_PROMISC)));
+ WI_UNLOCK(sc);
+}
+
+static void
wi_read_nicid(struct wi_softc *sc)
{
struct wi_card_ident *id;
diff --git a/sys/dev/wi/if_wireg.h b/sys/dev/wi/if_wireg.h
index 176e4a0..d99e597 100644
--- a/sys/dev/wi/if_wireg.h
+++ b/sys/dev/wi/if_wireg.h
@@ -691,7 +691,8 @@ struct wi_frame {
* Radio capture format for Prism.
*/
#define WI_RX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
+ ((1 << IEEE80211_RADIOTAP_TSFT) | \
+ (1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
@@ -699,6 +700,7 @@ struct wi_frame {
struct wi_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
+ u_int64_t wr_tsf;
u_int8_t wr_flags;
u_int8_t wr_rate;
u_int16_t wr_chan_freq;
diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h
index 3739a8e..c5bc139 100644
--- a/sys/dev/wi/if_wivar.h
+++ b/sys/dev/wi/if_wivar.h
@@ -60,8 +60,8 @@ struct wi_vap {
struct ieee80211vap wv_vap;
struct ieee80211_beacon_offsets wv_bo;
- void (*wv_recv_mgmt)(struct ieee80211_node *,
- struct mbuf *, int, int, int, u_int32_t);
+ void (*wv_recv_mgmt)(struct ieee80211_node *, struct mbuf *,
+ int, int, int);
int (*wv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
};
@@ -141,9 +141,7 @@ struct wi_softc {
u_int16_t sc_txbuf[IEEE80211_MAX_LEN/2];
struct wi_tx_radiotap_header sc_tx_th;
- int sc_tx_th_len;
struct wi_rx_radiotap_header sc_rx_th;
- int sc_rx_th_len;
};
/* maximum consecutive false change-of-BSSID indications */
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c
index 9537dd4..4378164 100644
--- a/sys/dev/wpi/if_wpi.c
+++ b/sys/dev/wpi/if_wpi.c
@@ -681,16 +681,11 @@ wpi_attach(device_t dev)
ic->ic_vap_create = wpi_vap_create;
ic->ic_vap_delete = wpi_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(WPI_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(WPI_TX_RADIOTAP_PRESENT);
+ ieee80211_radiotap_attach(ic,
+ &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
+ WPI_TX_RADIOTAP_PRESENT,
+ &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+ WPI_RX_RADIOTAP_PRESENT);
/*
* Hook our interrupt after all initialization is complete.
@@ -728,7 +723,6 @@ wpi_detach(device_t dev)
wpi_stop(sc);
callout_drain(&sc->watchdog_to);
callout_drain(&sc->calib_to);
- bpfdetach(ifp);
ieee80211_ifdetach(ic);
}
@@ -1519,7 +1513,7 @@ wpi_rx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc,
/* update Rx descriptor */
ring->desc[ring->cur] = htole32(paddr);
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active(ic)) {
struct wpi_rx_radiotap_header *tap = &sc->sc_rxtap;
tap->wr_flags = 0;
@@ -1551,18 +1545,16 @@ wpi_rx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc,
}
if (le16toh(head->flags) & 0x4)
tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
}
WPI_UNLOCK(sc);
ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
if (ni != NULL) {
- (void) ieee80211_input(ni, m, stat->rssi, 0, 0);
+ (void) ieee80211_input(ni, m, stat->rssi, 0);
ieee80211_free_node(ni);
} else
- (void) ieee80211_input_all(ic, m, stat->rssi, 0, 0);
+ (void) ieee80211_input_all(ic, m, stat->rssi, 0);
WPI_LOCK(sc);
}
@@ -1938,17 +1930,15 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
tx->data_ntries = 15; /* XXX way too high */
#endif
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active_vap(vap)) {
struct wpi_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
- tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
- tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
tap->wt_rate = rate;
tap->wt_hwqueue = ac;
if (wh->i_fc[1] & IEEE80211_FC1_WEP)
tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
+ ieee80211_radiotap_tx(vap, m0);
}
/* save and trim IEEE802.11 header */
diff --git a/sys/dev/wpi/if_wpivar.h b/sys/dev/wpi/if_wpivar.h
index 36da3b1..811624b 100644
--- a/sys/dev/wpi/if_wpivar.h
+++ b/sys/dev/wpi/if_wpivar.h
@@ -182,9 +182,7 @@ struct wpi_softc {
struct bpf_if *sc_drvbpf;
struct wpi_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
struct wpi_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
/* firmware image */
const struct firmware *fw_fp;
OpenPOWER on IntegriCloud