From 68f7a1034ab73897585652ceedd3727d57150c12 Mon Sep 17 00:00:00 2001 From: sam Date: Wed, 20 May 2009 20:00:40 +0000 Subject: 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 --- sys/conf/files | 1 + sys/dev/ath/if_ath.c | 132 ++++++---------- sys/dev/ath/if_athvar.h | 15 +- sys/dev/bwi/if_bwi.c | 43 ++--- sys/dev/bwi/if_bwivar.h | 2 - sys/dev/ipw/if_ipw.c | 44 ++---- sys/dev/ipw/if_ipwvar.h | 9 +- sys/dev/iwi/if_iwi.c | 40 ++--- sys/dev/iwi/if_iwivar.h | 7 +- sys/dev/iwn/if_iwn.c | 53 +++---- sys/dev/iwn/if_iwnvar.h | 2 - sys/dev/malo/if_malo.c | 49 ++---- sys/dev/malo/if_malo.h | 3 - sys/dev/ral/rt2560.c | 77 ++++----- sys/dev/ral/rt2560var.h | 6 +- sys/dev/ral/rt2661.c | 66 ++++---- sys/dev/ral/rt2661var.h | 6 +- sys/dev/usb/wlan/if_rum.c | 55 +++---- sys/dev/usb/wlan/if_rumvar.h | 7 +- sys/dev/usb/wlan/if_uath.c | 73 ++++----- sys/dev/usb/wlan/if_uathvar.h | 31 ++-- sys/dev/usb/wlan/if_upgt.c | 32 ++-- sys/dev/usb/wlan/if_ural.c | 61 +++---- sys/dev/usb/wlan/if_uralvar.h | 6 +- sys/dev/usb/wlan/if_zyd.c | 38 ++--- sys/dev/wi/if_wi.c | 99 ++++++------ sys/dev/wi/if_wireg.h | 4 +- sys/dev/wi/if_wivar.h | 6 +- sys/dev/wpi/if_wpi.c | 30 ++-- sys/dev/wpi/if_wpivar.h | 2 - sys/net80211/ieee80211.c | 11 +- sys/net80211/ieee80211_adhoc.c | 35 ++-- sys/net80211/ieee80211_ddb.c | 6 +- sys/net80211/ieee80211_freebsd.c | 29 ++++ sys/net80211/ieee80211_hostap.c | 42 +++-- sys/net80211/ieee80211_ht.c | 4 +- sys/net80211/ieee80211_input.c | 5 +- sys/net80211/ieee80211_monitor.c | 8 +- sys/net80211/ieee80211_node.c | 6 +- sys/net80211/ieee80211_node.h | 1 - sys/net80211/ieee80211_output.c | 7 - sys/net80211/ieee80211_proto.c | 1 + sys/net80211/ieee80211_proto.h | 7 +- sys/net80211/ieee80211_radiotap.c | 325 ++++++++++++++++++++++++++++++++++++++ sys/net80211/ieee80211_scan.c | 6 +- sys/net80211/ieee80211_scan.h | 5 +- sys/net80211/ieee80211_scan_sta.c | 3 +- sys/net80211/ieee80211_sta.c | 39 ++--- sys/net80211/ieee80211_superg.c | 4 +- sys/net80211/ieee80211_tdma.c | 19 ++- sys/net80211/ieee80211_tdma.h | 2 +- sys/net80211/ieee80211_var.h | 41 ++++- sys/net80211/ieee80211_wds.c | 39 ++--- 53 files changed, 930 insertions(+), 714 deletions(-) create mode 100644 sys/net80211/ieee80211_radiotap.c (limited to 'sys') diff --git a/sys/conf/files b/sys/conf/files index 0d3339e..33b4c6f 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2218,6 +2218,7 @@ net80211/ieee80211_output.c optional wlan 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 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; diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c index 2e75965..22c690c 100644 --- a/sys/net80211/ieee80211.c +++ b/sys/net80211/ieee80211.c @@ -465,6 +465,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap, ieee80211_ht_vattach(vap); ieee80211_scan_vattach(vap); ieee80211_regdomain_vattach(vap); + ieee80211_radiotap_vattach(vap); return 0; } @@ -509,10 +510,11 @@ ieee80211_vap_attach(struct ieee80211vap *vap, vap->iv_output = ifp->if_output; ifp->if_output = ieee80211_output; /* NB: if_mtu set by ether_ifattach to ETHERMTU */ - bpfattach2(ifp, DLT_IEEE802_11, ifp->if_hdrlen, &vap->iv_rawbpf); IEEE80211_LOCK(ic); TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next); + if (vap->iv_opmode == IEEE80211_M_MONITOR) + ic->ic_monvaps++; ieee80211_syncflag_locked(ic, IEEE80211_F_WME); #ifdef IEEE80211_SUPPORT_SUPERG ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP); @@ -573,6 +575,8 @@ ieee80211_vap_detach(struct ieee80211vap *vap) IEEE80211_LOCK(ic); KASSERT(vap->iv_state == IEEE80211_S_INIT , ("vap still running")); TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next); + if (vap->iv_opmode == IEEE80211_M_MONITOR) + ic->ic_monvaps--; ieee80211_syncflag_locked(ic, IEEE80211_F_WME); #ifdef IEEE80211_SUPPORT_SUPERG ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP); @@ -581,16 +585,19 @@ ieee80211_vap_detach(struct ieee80211vap *vap) ieee80211_syncflag_locked(ic, IEEE80211_F_BURST); ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_HT); ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_USEHT40); + /* NB: this handles the bpfdetach done below */ + ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF); ieee80211_syncifflag_locked(ic, IFF_PROMISC); ieee80211_syncifflag_locked(ic, IFF_ALLMULTI); IEEE80211_UNLOCK(ic); /* XXX can't hold com lock */ - /* NB: bpfattach is called by ether_ifdetach and claims all taps */ + /* NB: bpfdetach is called by ether_ifdetach and claims all taps */ ether_ifdetach(ifp); ifmedia_removeall(&vap->iv_media); + ieee80211_radiotap_vdetach(vap); ieee80211_regdomain_vdetach(vap); ieee80211_scan_vdetach(vap); #ifdef IEEE80211_SUPPORT_SUPERG diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c index 3b230e6..8f37808 100644 --- a/sys/net80211/ieee80211_adhoc.c +++ b/sys/net80211/ieee80211_adhoc.c @@ -68,12 +68,11 @@ __FBSDID("$FreeBSD$"); static void adhoc_vattach(struct ieee80211vap *); static int adhoc_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int adhoc_input(struct ieee80211_node *, struct mbuf *, - int rssi, int noise, uint32_t rstamp); +static int adhoc_input(struct ieee80211_node *, struct mbuf *, int, int); static void adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int noise, uint32_t rstamp); + int subtype, int, int); static void ahdemo_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int noise, uint32_t rstamp); + int subtype, int, int); static void adhoc_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype); void @@ -284,8 +283,7 @@ doprint(struct ieee80211vap *vap, int subtype) * by the 802.11 layer. */ static int -adhoc_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp) +adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) { #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) #define HAS_SEQ(type) ((type & 0x4) == 0) @@ -408,8 +406,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, } } IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; if (HAS_SEQ(type)) { uint8_t tid = ieee80211_gettid(wh); if (IEEE80211_QOS_HAS_SEQ(wh) && @@ -536,8 +533,8 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, } /* copy to listener after decrypt */ - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (ieee80211_radiotap_active_vap(vap)) + ieee80211_radiotap_rx(vap, m); need_tap = 0; /* @@ -640,7 +637,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, vap->iv_stats.is_rx_mgtdiscard++; /* XXX */ goto out; } - vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp); + vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); goto out; case IEEE80211_FC0_TYPE_CTL: @@ -659,8 +656,8 @@ err: ifp->if_ierrors++; out: if (m != NULL) { - if (need_tap && bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (need_tap) + ieee80211_radiotap_rx(vap, m); m_freem(m); } return type; @@ -686,7 +683,7 @@ is11bclient(const uint8_t *rates, const uint8_t *xrates) static void adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int noise, uint32_t rstamp) + int subtype, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; @@ -731,8 +728,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, ieee80211_probe_curchan(vap, 1); ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; } - ieee80211_add_scan(vap, &scan, wh, - subtype, rssi, noise, rstamp); + ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf); return; } if (scan.capinfo & IEEE80211_CAPINFO_IBSS) { @@ -756,8 +752,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, } if (ni != NULL) { IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; } } break; @@ -912,7 +907,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, static void ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int noise, uint32_t rstamp) + int subtype, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; @@ -922,7 +917,7 @@ ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, * a site-survey. */ if (ic->ic_flags & IEEE80211_F_SCAN) - adhoc_recv_mgmt(ni, m0, subtype, rssi, noise, rstamp); + adhoc_recv_mgmt(ni, m0, subtype, rssi, nf); else vap->iv_stats.is_rx_mgtdiscard++; } diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c index ea4e89f..8545140 100644 --- a/sys/net80211/ieee80211_ddb.c +++ b/sys/net80211/ieee80211_ddb.c @@ -255,9 +255,9 @@ _db_show_sta(const struct ieee80211_node *ni) db_printf("\trxfrag[0] %p rxfrag[1] %p rxfrag[2] %p\n", ni->ni_rxfrag[0], ni->ni_rxfrag[1], ni->ni_rxfrag[2]); _db_show_key("\tucastkey", 0, &ni->ni_ucastkey); - db_printf("\trstamp %u avgrssi 0x%x (rssi %d) noise %d\n", - ni->ni_rstamp, ni->ni_avgrssi, - IEEE80211_RSSI_GET(ni->ni_avgrssi), ni->ni_noise); + db_printf("\tavgrssi 0x%x (rssi %d) noise %d\n", + ni->ni_avgrssi, IEEE80211_RSSI_GET(ni->ni_avgrssi), + ni->ni_noise); db_printf("\tintval %u capinfo %b\n", ni->ni_intval, ni->ni_capinfo, IEEE80211_CAPINFO_BITS); db_printf("\tbssid %s", ether_sprintf(ni->ni_bssid)); diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c index e96e71d..89292a6 100644 --- a/sys/net80211/ieee80211_freebsd.c +++ b/sys/net80211/ieee80211_freebsd.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -726,6 +727,29 @@ ieee80211_load_module(const char *modname) #endif } +static eventhandler_tag wlan_bpfevent; + +static void +bpf_track(void *arg, struct ifnet *ifp, int attach) +{ + /* NB: identify vap's by if_start */ + if (ifp->if_start == ieee80211_start) { + struct ieee80211vap *vap = ifp->if_softc; + /* + * Track bpf radiotap listener state. We mark the vap + * to indicate if any listener is present and the com + * to indicate if any listener exists on any associated + * vap. This flag is used by drivers to prepare radiotap + * state only when needed. + */ + if (attach) + ieee80211_syncflag_ext(vap, IEEE80211_FEXT_BPF); + /* NB: if_softc is NULL on vap detach */ + else if (vap != NULL && !bpf_peers_present(vap->iv_rawbpf)) + ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_BPF); + } +} + /* * Module glue. * @@ -738,12 +762,17 @@ wlan_modevent(module_t mod, int type, void *unused) case MOD_LOAD: if (bootverbose) printf("wlan: <802.11 Link Layer>\n"); + wlan_bpfevent = EVENTHANDLER_REGISTER(bpf_track, + bpf_track, 0, EVENTHANDLER_PRI_ANY); + if (wlan_bpfevent == NULL) + return ENOMEM; if_clone_attach(&wlan_cloner); if_register_com_alloc(IFT_IEEE80211, wlan_alloc, wlan_free); return 0; case MOD_UNLOAD: if_deregister_com_alloc(IFT_IEEE80211); if_clone_detach(&wlan_cloner); + EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent); return 0; } return EINVAL; diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c index 5bf8baf..9264a71 100644 --- a/sys/net80211/ieee80211_hostap.c +++ b/sys/net80211/ieee80211_hostap.c @@ -67,11 +67,11 @@ __FBSDID("$FreeBSD$"); static void hostap_vattach(struct ieee80211vap *); static int hostap_newstate(struct ieee80211vap *, enum ieee80211_state, int); static int hostap_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp); + int rssi, int nf); static void hostap_deliver_data(struct ieee80211vap *, struct ieee80211_node *, struct mbuf *); static void hostap_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int noise, uint32_t rstamp); + int subtype, int rssi, int nf); static void hostap_recv_ctl(struct ieee80211_node *, struct mbuf *, int); static void hostap_recv_pspoll(struct ieee80211_node *, struct mbuf *); @@ -418,8 +418,7 @@ doprint(struct ieee80211vap *vap, int subtype) * by the 802.11 layer. */ static int -hostap_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp) +hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) { #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) #define HAS_SEQ(type) ((type & 0x4) == 0) @@ -515,8 +514,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, } IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; if (HAS_SEQ(type)) { uint8_t tid = ieee80211_gettid(wh); if (IEEE80211_QOS_HAS_SEQ(wh) && @@ -699,8 +697,8 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, goto out; } /* copy to listener after decrypt */ - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (ieee80211_radiotap_active_vap(vap)) + ieee80211_radiotap_rx(vap, m); need_tap = 0; /* * Finally, strip the 802.11 header. @@ -834,7 +832,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, wh = mtod(m, struct ieee80211_frame *); wh->i_fc[1] &= ~IEEE80211_FC1_WEP; } - vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp); + vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); goto out; case IEEE80211_FC0_TYPE_CTL: @@ -852,8 +850,8 @@ err: ifp->if_ierrors++; out: if (m != NULL) { - if (need_tap && bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (need_tap) + ieee80211_radiotap_rx(vap, m); m_freem(m); } return type; @@ -862,7 +860,7 @@ out: static void hostap_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh, - int rssi, int noise, uint32_t rstamp, uint16_t seq, uint16_t status) + int rssi, int nf, uint16_t seq, uint16_t status) { struct ieee80211vap *vap = ni->ni_vap; @@ -940,7 +938,7 @@ hostap_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh, static void hostap_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh, - uint8_t *frm, uint8_t *efrm, int rssi, int noise, uint32_t rstamp, + uint8_t *frm, uint8_t *efrm, int rssi, int nf, uint16_t seq, uint16_t status) { struct ieee80211vap *vap = ni->ni_vap; @@ -1042,8 +1040,7 @@ hostap_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh, */ ni->ni_flags |= IEEE80211_NODE_ASSOCID; IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; if (!ieee80211_alloc_challenge(ni)) { /* NB: don't return error so they rexmit */ return; @@ -1624,7 +1621,7 @@ is11bclient(const uint8_t *rates, const uint8_t *xrates) static void hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int noise, uint32_t rstamp) + int subtype, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; @@ -1679,8 +1676,7 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, ieee80211_probe_curchan(vap, 1); ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; } - ieee80211_add_scan(vap, &scan, wh, - subtype, rssi, noise, rstamp); + ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf); return; } /* @@ -1843,11 +1839,10 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, return; } if (algo == IEEE80211_AUTH_ALG_SHARED) - hostap_auth_shared(ni, wh, frm + 6, efrm, rssi, - noise, rstamp, seq, status); - else if (algo == IEEE80211_AUTH_ALG_OPEN) - hostap_auth_open(ni, wh, rssi, noise, rstamp, + hostap_auth_shared(ni, wh, frm + 6, efrm, rssi, nf, seq, status); + else if (algo == IEEE80211_AUTH_ALG_OPEN) + hostap_auth_open(ni, wh, rssi, nf, seq, status); else if (algo == IEEE80211_AUTH_ALG_LEAP) { authalgreject(ni, wh, algo, seq+1, IEEE80211_STATUS_ALG); @@ -2063,8 +2058,7 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, return; } IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; ni->ni_intval = lintval; ni->ni_capinfo = capinfo; ni->ni_fhdwell = vap->iv_bss->ni_fhdwell; diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c index 42c232d..198e95d 100644 --- a/sys/net80211/ieee80211_ht.c +++ b/sys/net80211/ieee80211_ht.c @@ -364,8 +364,8 @@ static __inline void ampdu_dispatch(struct ieee80211_node *ni, struct mbuf *m) { m->m_flags |= M_AMPDU_MPDU; /* bypass normal processing */ - /* NB: rssi, noise, and rstamp are ignored w/ M_AMPDU_MPDU set */ - (void) ieee80211_input(ni, m, 0, 0, 0); + /* NB: rssi and noise are ignored w/ M_AMPDU_MPDU set */ + (void) ieee80211_input(ni, m, 0, 0); } /* diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index 2134e29d..6e06918 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -55,8 +55,7 @@ __FBSDID("$FreeBSD$"); #endif int -ieee80211_input_all(struct ieee80211com *ic, - struct mbuf *m, int rssi, int noise, u_int32_t rstamp) +ieee80211_input_all(struct ieee80211com *ic, struct mbuf *m, int rssi, int nf) { struct ieee80211vap *vap; int type = -1; @@ -89,7 +88,7 @@ ieee80211_input_all(struct ieee80211com *ic, m = NULL; } ni = ieee80211_ref_node(vap->iv_bss); - type = ieee80211_input(ni, mcopy, rssi, noise, rstamp); + type = ieee80211_input(ni, mcopy, rssi, nf); ieee80211_free_node(ni); } if (m != NULL) /* no vaps, reclaim mbuf */ diff --git a/sys/net80211/ieee80211_monitor.c b/sys/net80211/ieee80211_monitor.c index b1e98eb..119c87d 100644 --- a/sys/net80211/ieee80211_monitor.c +++ b/sys/net80211/ieee80211_monitor.c @@ -60,7 +60,7 @@ __FBSDID("$FreeBSD$"); static void monitor_vattach(struct ieee80211vap *); static int monitor_newstate(struct ieee80211vap *, enum ieee80211_state, int); static int monitor_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp); + int rssi, int nf); void ieee80211_monitor_attach(struct ieee80211com *ic) @@ -124,13 +124,11 @@ monitor_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) * Process a received frame in monitor mode. */ static int -monitor_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp) +monitor_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + ieee80211_radiotap_rx(vap, m); m_freem(m); return -1; } diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index c23a092..eb56b8d 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -631,6 +631,7 @@ ieee80211_sync_curchan(struct ieee80211com *ic) ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan); IEEE80211_UNLOCK(ic); ic->ic_set_channel(ic); + ieee80211_radiotap_chan_change(ic); IEEE80211_LOCK(ic); } } @@ -754,7 +755,6 @@ ieee80211_sta_join(struct ieee80211vap *vap, struct ieee80211_channel *chan, IEEE80211_ADDR_COPY(ni->ni_bssid, se->se_bssid); ni->ni_esslen = se->se_ssid[1]; memcpy(ni->ni_essid, se->se_ssid+2, ni->ni_esslen); - ni->ni_rstamp = se->se_rstamp; ni->ni_tstamp.tsf = se->se_tstamp.tsf; ni->ni_intval = se->se_intval; ni->ni_capinfo = se->se_capinfo; @@ -2125,8 +2125,8 @@ ieee80211_dump_node(struct ieee80211_node_table *nt, struct ieee80211_node *ni) ni->ni_rxseqs[IEEE80211_NONQOS_TID] >> IEEE80211_SEQ_SEQ_SHIFT, ni->ni_rxseqs[IEEE80211_NONQOS_TID] & IEEE80211_SEQ_FRAG_MASK, ni->ni_rxfragstamp); - printf("\trstamp %u rssi %d noise %d intval %u capinfo 0x%x\n", - ni->ni_rstamp, node_getrssi(ni), ni->ni_noise, + printf("\trssi %d noise %d intval %u capinfo 0x%x\n", + node_getrssi(ni), ni->ni_noise, ni->ni_intval, ni->ni_capinfo); printf("\tbssid %s essid \"%.*s\" channel %u:0x%x\n", ether_sprintf(ni->ni_bssid), diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h index 8f19ce7..a118de5 100644 --- a/sys/net80211/ieee80211_node.h +++ b/sys/net80211/ieee80211_node.h @@ -145,7 +145,6 @@ struct ieee80211_node { struct ieee80211_key ni_ucastkey; /* unicast key */ /* hardware */ - uint32_t ni_rstamp; /* recv timestamp */ uint32_t ni_avgrssi; /* recv ssi state */ int8_t ni_noise; /* noise floor */ diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index 6ee8f52..a46b228 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -307,10 +307,6 @@ ieee80211_start(struct ifnet *ifp) } } - /* XXX fragmented frames not handled */ - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); - error = parent->if_transmit(parent, m); if (error != 0) { /* NB: IFQ_HANDOFF reclaims mbuf */ @@ -420,9 +416,6 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m, if (ieee80211_classify(ni, m)) senderr(EIO); /* XXX */ - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); - IEEE80211_NODE_STAT(ni, tx_data); if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { IEEE80211_NODE_STAT(ni, tx_mcast); diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index 467a362..99b995c8 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -1107,6 +1107,7 @@ update_channel(void *arg, int npending) struct ieee80211com *ic = arg; ic->ic_set_channel(ic); + ieee80211_radiotap_chan_change(ic); } /* diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index 3712c1e..6a55809 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -60,10 +60,9 @@ void ieee80211_syncifflag_locked(struct ieee80211com *, int flag); void ieee80211_syncflag(struct ieee80211vap *, int flag); void ieee80211_syncflag_ext(struct ieee80211vap *, int flag); -#define ieee80211_input(ni, m, rssi, noise, rstamp) \ - ((ni)->ni_vap->iv_input(ni, m, rssi, noise, rstamp)) -int ieee80211_input_all(struct ieee80211com *, struct mbuf *, - int, int, uint32_t); +#define ieee80211_input(ni, m, rssi, nf) \ + ((ni)->ni_vap->iv_input(ni, m, rssi, nf)) +int ieee80211_input_all(struct ieee80211com *, struct mbuf *, int, int); struct ieee80211_bpf_params; int ieee80211_mgmt_output(struct ieee80211_node *, struct mbuf *, int, struct ieee80211_bpf_params *); diff --git a/sys/net80211/ieee80211_radiotap.c b/sys/net80211/ieee80211_radiotap.c new file mode 100644 index 0000000..2c4482f --- /dev/null +++ b/sys/net80211/ieee80211_radiotap.c @@ -0,0 +1,325 @@ +/*- + * Copyright (c) 2009 Sam Leffler, Errno Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * IEEE 802.11 radiotap support. + */ +#include "opt_wlan.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +static int radiotap_offset(struct ieee80211_radiotap_header *, int); + +void +ieee80211_radiotap_attach(struct ieee80211com *ic, + struct ieee80211_radiotap_header *th, int tlen, uint32_t tx_radiotap, + struct ieee80211_radiotap_header *rh, int rlen, uint32_t rx_radiotap) +{ +#define B(_v) (1<<(_v)) + int off; + + th->it_len = htole16(roundup2(tlen, sizeof(uint32_t))); + th->it_present = htole32(tx_radiotap); + ic->ic_th = th; + /* calculate offset to channel data */ + off = -1; + if (tx_radiotap & B(IEEE80211_RADIOTAP_CHANNEL)) + off = radiotap_offset(th, IEEE80211_RADIOTAP_CHANNEL); + else if (tx_radiotap & B(IEEE80211_RADIOTAP_XCHANNEL)) + off = radiotap_offset(th, IEEE80211_RADIOTAP_XCHANNEL); + if (off == -1) { + if_printf(ic->ic_ifp, "%s: no tx channel, radiotap 0x%x", + __func__, tx_radiotap); + /* NB: we handle this case but data will have no chan spec */ + } else + ic->ic_txchan = ((uint8_t *) th) + off; + + rh->it_len = htole16(roundup2(rlen, sizeof(uint32_t))); + rh->it_present = htole32(rx_radiotap); + ic->ic_rh = rh; + /* calculate offset to channel data */ + off = -1; + if (rx_radiotap & B(IEEE80211_RADIOTAP_CHANNEL)) + off = radiotap_offset(rh, IEEE80211_RADIOTAP_CHANNEL); + else if (rx_radiotap & B(IEEE80211_RADIOTAP_XCHANNEL)) + off = radiotap_offset(rh, IEEE80211_RADIOTAP_XCHANNEL); + if (off == -1) { + if_printf(ic->ic_ifp, "%s: no rx channel, radiotap 0x%x", + __func__, rx_radiotap); + /* NB: we handle this case but data will have no chan spec */ + } else + ic->ic_rxchan = ((uint8_t *) rh) + off; +#undef B +} + +void +ieee80211_radiotap_detach(struct ieee80211com *ic) +{ +} + +void +ieee80211_radiotap_vattach(struct ieee80211vap *vap) +{ + struct ieee80211com *ic = vap->iv_ic; + struct ieee80211_radiotap_header *th = ic->ic_th; + + KASSERT(th != NULL, ("no radiotap setup")); + + /* radiotap DLT for raw 802.11 frames */ + bpfattach2(vap->iv_ifp, DLT_IEEE802_11_RADIO, + sizeof(struct ieee80211_frame) + le16toh(th->it_len), + &vap->iv_rawbpf); +} + +void +ieee80211_radiotap_vdetach(struct ieee80211vap *vap) +{ + /* NB: bpfattach is called by ether_ifdetach and claims all taps */ +} + +static void +set_channel(void *p, const struct ieee80211_channel *c) +{ + struct { + uint16_t freq; + uint16_t flags; + } *rc = p; + + rc->freq = htole16(c->ic_freq); + rc->flags = htole16(c->ic_flags); +} + +static void +set_xchannel(void *p, const struct ieee80211_channel *c) +{ + struct { + uint32_t flags; + uint16_t freq; + uint8_t ieee; + uint8_t maxpow; + } *rc = p; + + rc->flags = htole32(c->ic_flags); + rc->freq = htole16(c->ic_freq); + rc->ieee = c->ic_ieee; + rc->maxpow = c->ic_maxregpower; +} + +/* + * Update radiotap state on channel change. + */ +void +ieee80211_radiotap_chan_change(struct ieee80211com *ic) +{ + if (ic->ic_rxchan != NULL) { + struct ieee80211_radiotap_header *rh = ic->ic_rh; + + if (rh->it_present & (1<ic_rxchan, ic->ic_curchan); + else if (rh->it_present & (1<ic_rxchan, ic->ic_curchan); + } + if (ic->ic_txchan != NULL) { + struct ieee80211_radiotap_header *th = ic->ic_th; + + if (th->it_present & (1<ic_txchan, ic->ic_curchan); + else if (th->it_present & (1<ic_txchan, ic->ic_curchan); + } +} + +static void +dispatch_radiotap(struct ieee80211vap *vap0, struct mbuf *m, + struct ieee80211_radiotap_header *rh) +{ + struct ieee80211com *ic = vap0->iv_ic; + int len = le16toh(rh->it_len); + + if (ieee80211_radiotap_active_vap(vap0)) + bpf_mtap2(vap0->iv_rawbpf, rh, len, m); + if (ic->ic_monvaps) { + struct ieee80211vap *vap; + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { + if (vap->iv_opmode == IEEE80211_M_MONITOR && + vap != vap0 && ieee80211_radiotap_active_vap(vap)) + bpf_mtap2(vap->iv_rawbpf, rh, len, m); + } + } +} + +/* + * Dispatch radiotap data for transmitted packet. + */ +void +ieee80211_radiotap_tx(struct ieee80211vap *vap0, struct mbuf *m) +{ + dispatch_radiotap(vap0, m, vap0->iv_ic->ic_th); +} + +/* + * Dispatch radiotap data for received packet. + */ +void +ieee80211_radiotap_rx(struct ieee80211vap *vap0, struct mbuf *m) +{ + dispatch_radiotap(vap0, m, vap0->iv_ic->ic_rh); +} + +/* + * Dispatch radiotap data for a packet received outside the normal + * rx processing path; this is used, for example, to handle frames + * received with errors that would otherwise be dropped. + */ +void +ieee80211_radiotap_rx_all(struct ieee80211com *ic, struct mbuf *m) +{ + struct ieee80211_radiotap_header *rh = ic->ic_rh; + int len = le16toh(rh->it_len); + struct ieee80211vap *vap; + + /* XXX locking? */ + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { + if (ieee80211_radiotap_active_vap(vap)) + bpf_mtap2(vap->iv_rawbpf, rh, len, m); + } +} + +/* + * Return the offset of the specified item in the radiotap + * header description. If the item is not present or is not + * known -1 is returned. + */ +static int +radiotap_offset(struct ieee80211_radiotap_header *rh, int item) +{ + static const struct { + size_t align, width; + } items[] = { + [IEEE80211_RADIOTAP_TSFT] = { + .align = sizeof(uint64_t), + .width = sizeof(uint64_t), + }, + [IEEE80211_RADIOTAP_FLAGS] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_RATE] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_CHANNEL] = { + .align = sizeof(uint16_t), + .width = 2*sizeof(uint16_t), + }, + [IEEE80211_RADIOTAP_FHSS] = { + .align = sizeof(uint16_t), + .width = sizeof(uint16_t), + }, + [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_DBM_ANTNOISE] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_LOCK_QUALITY] = { + .align = sizeof(uint16_t), + .width = sizeof(uint16_t), + }, + [IEEE80211_RADIOTAP_TX_ATTENUATION] = { + .align = sizeof(uint16_t), + .width = sizeof(uint16_t), + }, + [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = { + .align = sizeof(uint16_t), + .width = sizeof(uint16_t), + }, + [IEEE80211_RADIOTAP_DBM_TX_POWER] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_ANTENNA] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_DB_ANTNOISE] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_XCHANNEL] = { + .align = sizeof(uint32_t), + .width = 2*sizeof(uint32_t), + }, + }; + uint32_t present = le32toh(rh->it_present); + int off, i; + + off = sizeof(struct ieee80211_radiotap_header); + for (i = 0; i < IEEE80211_RADIOTAP_EXT; i++) { + if ((present & (1< le16toh(rh->it_len)) { + /* NB: item does not fit in header data */ + printf("%s: item %d not in header data, " + "off %d width %zu len %d\n", __func__, i, + off, items[i].width, le16toh(rh->it_len)); + return -1; + } + return off; + } + off += items[i].width; + } + return -1; +} diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c index c1f4a13..b41ed59 100644 --- a/sys/net80211/ieee80211_scan.c +++ b/sys/net80211/ieee80211_scan.c @@ -920,6 +920,7 @@ scan_task(void *arg, int pending) * completed the channel change. */ ic->ic_set_channel(ic); + ieee80211_radiotap_chan_change(ic); /* * Scan curchan. Drivers for "intelligent hardware" @@ -966,6 +967,7 @@ scan_task(void *arg, int pending) ieee80211_setupcurchan(ic, ic->ic_bsschan); IEEE80211_UNLOCK(ic); ic->ic_set_channel(ic); + ieee80211_radiotap_chan_change(ic); IEEE80211_LOCK(ic); } /* clear internal flags and any indication of a pick */ @@ -1095,7 +1097,7 @@ void ieee80211_add_scan(struct ieee80211vap *vap, const struct ieee80211_scanparams *sp, const struct ieee80211_frame *wh, - int subtype, int rssi, int noise, int rstamp) + int subtype, int rssi, int noise) { struct ieee80211com *ic = vap->iv_ic; struct ieee80211_scan_state *ss = ic->ic_scan; @@ -1115,7 +1117,7 @@ ieee80211_add_scan(struct ieee80211vap *vap, dump_probe_beacon(subtype, 1, wh->i_addr2, sp, rssi); #endif if (ss->ss_ops != NULL && - ss->ss_ops->scan_add(ss, sp, wh, subtype, rssi, noise, rstamp)) { + ss->ss_ops->scan_add(ss, sp, wh, subtype, rssi, noise)) { /* * If we've reached the min dwell time terminate * the timer so we'll switch to the next channel. diff --git a/sys/net80211/ieee80211_scan.h b/sys/net80211/ieee80211_scan.h index edba660..84a57ff 100644 --- a/sys/net80211/ieee80211_scan.h +++ b/sys/net80211/ieee80211_scan.h @@ -150,7 +150,7 @@ struct ieee80211_scanparams; void ieee80211_add_scan(struct ieee80211vap *, const struct ieee80211_scanparams *, const struct ieee80211_frame *, - int subtype, int rssi, int noise, int rstamp); + int subtype, int rssi, int noise); void ieee80211_scan_timeout(struct ieee80211com *); void ieee80211_scan_assoc_success(struct ieee80211vap *, @@ -224,7 +224,6 @@ struct ieee80211_scan_entry { uint8_t se_ssid[2+IEEE80211_NWID_LEN]; uint8_t se_rates[2+IEEE80211_RATE_MAXSIZE]; uint8_t se_xrates[2+IEEE80211_RATE_MAXSIZE]; - uint32_t se_rstamp; /* recv timestamp */ union { uint8_t data[8]; u_int64_t tsf; @@ -269,7 +268,7 @@ struct ieee80211_scanner { int (*scan_add)(struct ieee80211_scan_state *, const struct ieee80211_scanparams *, const struct ieee80211_frame *, - int subtype, int rssi, int noise, int rstamp); + int subtype, int rssi, int noise); /* age and/or purge entries in the cache */ void (*scan_age)(struct ieee80211_scan_state *); /* note that association failed for an entry */ diff --git a/sys/net80211/ieee80211_scan_sta.c b/sys/net80211/ieee80211_scan_sta.c index cef3db4..62ef39e 100644 --- a/sys/net80211/ieee80211_scan_sta.c +++ b/sys/net80211/ieee80211_scan_sta.c @@ -219,7 +219,7 @@ static int sta_add(struct ieee80211_scan_state *ss, const struct ieee80211_scanparams *sp, const struct ieee80211_frame *wh, - int subtype, int rssi, int noise, int rstamp) + int subtype, int rssi, int noise) { #define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) #define PICK1ST(_ss) \ @@ -278,7 +278,6 @@ found: ise->se_rssi = IEEE80211_RSSI_GET(se->se_avgrssi); ise->se_noise = noise; } - ise->se_rstamp = rstamp; memcpy(ise->se_tstamp.data, sp->tstamp, sizeof(ise->se_tstamp)); ise->se_intval = sp->bintval; ise->se_capinfo = sp->capinfo; diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c index 33f6c27..9a52917 100644 --- a/sys/net80211/ieee80211_sta.c +++ b/sys/net80211/ieee80211_sta.c @@ -66,10 +66,9 @@ __FBSDID("$FreeBSD$"); static void sta_vattach(struct ieee80211vap *); static void sta_beacon_miss(struct ieee80211vap *); static int sta_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int sta_input(struct ieee80211_node *, struct mbuf *, - int rssi, int noise, uint32_t rstamp); +static int sta_input(struct ieee80211_node *, struct mbuf *, int, int); static void sta_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int noise, uint32_t rstamp); + int subtype, int rssi, int nf); static void sta_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype); void @@ -490,8 +489,7 @@ doprint(struct ieee80211vap *vap, int subtype) * by the 802.11 layer. */ static int -sta_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp) +sta_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) { #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) #define HAS_SEQ(type) ((type & 0x4) == 0) @@ -566,8 +564,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, goto out; } IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; if (HAS_SEQ(type)) { uint8_t tid = ieee80211_gettid(wh); if (IEEE80211_QOS_HAS_SEQ(wh) && @@ -743,8 +740,8 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, } /* copy to listener after decrypt */ - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (ieee80211_radiotap_active_vap(vap)) + ieee80211_radiotap_tx(vap, m); need_tap = 0; /* @@ -869,7 +866,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, wh = mtod(m, struct ieee80211_frame *); wh->i_fc[1] &= ~IEEE80211_FC1_WEP; } - vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp); + vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); goto out; case IEEE80211_FC0_TYPE_CTL: @@ -888,8 +885,8 @@ err: ifp->if_ierrors++; out: if (m != NULL) { - if (need_tap && bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (need_tap) + ieee80211_radiotap_rx(vap, m); m_freem(m); } return type; @@ -898,7 +895,7 @@ out: static void sta_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh, - int rssi, int noise, uint32_t rstamp, uint16_t seq, uint16_t status) + int rssi, int nf, uint16_t seq, uint16_t status) { struct ieee80211vap *vap = ni->ni_vap; @@ -927,7 +924,7 @@ sta_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh, static void sta_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh, - uint8_t *frm, uint8_t *efrm, int rssi, int noise, uint32_t rstamp, + uint8_t *frm, uint8_t *efrm, int rssi, int nf, uint16_t seq, uint16_t status) { struct ieee80211vap *vap = ni->ni_vap; @@ -1128,7 +1125,7 @@ startbgscan(struct ieee80211vap *vap) static void sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int noise, uint32_t rstamp) + int subtype, int rssi, int nf) { #define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) #define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP) @@ -1264,7 +1261,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, */ if (ic->ic_flags & IEEE80211_F_SCAN) { ieee80211_add_scan(vap, &scan, wh, - subtype, rssi, noise, rstamp); + subtype, rssi, nf); } else if (contbgscan(vap)) { ieee80211_bg_scan(vap, 0); } else if (startbgscan(vap)) { @@ -1293,8 +1290,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, ieee80211_probe_curchan(vap, 1); ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; } - ieee80211_add_scan(vap, &scan, wh, - subtype, rssi, noise, rstamp); + ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf); return; } break; @@ -1329,11 +1325,10 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, return; } if (algo == IEEE80211_AUTH_ALG_SHARED) - sta_auth_shared(ni, wh, frm + 6, efrm, rssi, - noise, rstamp, seq, status); - else if (algo == IEEE80211_AUTH_ALG_OPEN) - sta_auth_open(ni, wh, rssi, noise, rstamp, + sta_auth_shared(ni, wh, frm + 6, efrm, rssi, nf, seq, status); + else if (algo == IEEE80211_AUTH_ALG_OPEN) + sta_auth_open(ni, wh, rssi, nf, seq, status); else { IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, wh, "auth", "unsupported alg %d", algo); diff --git a/sys/net80211/ieee80211_superg.c b/sys/net80211/ieee80211_superg.c index de5df09..d75917b 100644 --- a/sys/net80211/ieee80211_superg.c +++ b/sys/net80211/ieee80211_superg.c @@ -503,9 +503,6 @@ ff_transmit(struct ieee80211_node *ni, struct mbuf *m) struct ifnet *ifp = vap->iv_ifp; struct ifnet *parent = ni->ni_ic->ic_ifp; - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); - error = parent->if_transmit(parent, m); if (error != 0) { /* NB: IFQ_HANDOFF reclaims mbuf */ @@ -835,6 +832,7 @@ ieee80211_dturbo_switch(struct ieee80211vap *vap, int newflags) ic->ic_curchan = chan; ic->ic_rt = ieee80211_get_ratetable(chan); ic->ic_set_channel(ic); + ieee80211_radiotap_chan_change(ic); /* NB: do not need to reset ERP state 'cuz we're in sta mode */ } diff --git a/sys/net80211/ieee80211_tdma.c b/sys/net80211/ieee80211_tdma.c index f9dd317..8747b4e 100644 --- a/sys/net80211/ieee80211_tdma.c +++ b/sys/net80211/ieee80211_tdma.c @@ -108,12 +108,12 @@ static void tdma_vdetach(struct ieee80211vap *vap); static int tdma_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void tdma_beacon_miss(struct ieee80211vap *vap); static void tdma_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int noise, uint32_t rstamp); + int subtype, int rssi, int nf); static int tdma_update(struct ieee80211vap *vap, const struct ieee80211_tdma_param *tdma, struct ieee80211_node *ni, int pickslot); static int tdma_process_params(struct ieee80211_node *ni, - const u_int8_t *ie, u_int32_t rstamp, const struct ieee80211_frame *wh); + const u_int8_t *ie, int rssi, int nf, const struct ieee80211_frame *wh); static void settxparms(struct ieee80211vap *vap, enum ieee80211_phymode mode, int rate) @@ -304,7 +304,7 @@ tdma_beacon_miss(struct ieee80211vap *vap) static void tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int noise, uint32_t rstamp) + int subtype, int rssi, int nf) { struct ieee80211com *ic = ni->ni_ic; struct ieee80211vap *vap = ni->ni_vap; @@ -367,7 +367,7 @@ tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, * Process tdma ie. The contents are used to sync * the slot timing, reconfigure the bss, etc. */ - (void) tdma_process_params(ni, scan.tdma, rstamp, wh); + (void) tdma_process_params(ni, scan.tdma, rssi, nf, wh); return; } /* @@ -375,7 +375,7 @@ tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, * 2x parsing of the frame but should happen infrequently */ } - ts->tdma_recv_mgmt(ni, m0, subtype, rssi, noise, rstamp); + ts->tdma_recv_mgmt(ni, m0, subtype, rssi, nf); } /* @@ -497,8 +497,8 @@ tdma_update(struct ieee80211vap *vap, const struct ieee80211_tdma_param *tdma, * Process received TDMA parameters. */ static int -tdma_process_params(struct ieee80211_node *ni, - const u_int8_t *ie, u_int32_t rstamp, const struct ieee80211_frame *wh) +tdma_process_params(struct ieee80211_node *ni, const u_int8_t *ie, + int rssi, int nf, const struct ieee80211_frame *wh) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_tdma_state *ts = vap->iv_tdma; @@ -563,12 +563,16 @@ tdma_process_params(struct ieee80211_node *ni, /* XXX reschedule swbmiss timer on parameter change */ } else if (tdma->tdma_slot == ts->tdma_slot+1) { uint64_t tstamp; +#if 0 + uint32_t rstamp = (uint32_t) le64toh(rs->tsf); int32_t rtt; +#endif /* * Use returned timstamp to calculate the * roundtrip time. */ memcpy(&tstamp, tdma->tdma_tstamp, 8); +#if 0 /* XXX use only 15 bits of rstamp */ rtt = rstamp - (le64toh(tstamp) & 0x7fff); if (rtt < 0) @@ -578,6 +582,7 @@ tdma_process_params(struct ieee80211_node *ni, "tdma rtt %5u [rstamp %5u tstamp %llu]\n", rtt, rstamp, (unsigned long long) le64toh(tstamp)); +#endif } else if (tdma->tdma_slot == ts->tdma_slot && le64toh(ni->ni_tstamp.tsf) > vap->iv_bss->ni_tstamp.tsf) { /* diff --git a/sys/net80211/ieee80211_tdma.h b/sys/net80211/ieee80211_tdma.h index 41ca09e..2fe591f 100644 --- a/sys/net80211/ieee80211_tdma.h +++ b/sys/net80211/ieee80211_tdma.h @@ -81,7 +81,7 @@ struct ieee80211_tdma_state { int (*tdma_newstate)(struct ieee80211vap *, enum ieee80211_state, int arg); void (*tdma_recv_mgmt)(struct ieee80211_node *, - struct mbuf *, int, int, int, uint32_t); + struct mbuf *, int, int, int); void (*tdma_opdetach)(struct ieee80211vap *); }; diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 09b63d2..27095f4 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -51,6 +51,7 @@ #include #include #include +#include #include #define IEEE80211_TXPOWER_MAX 100 /* .5 dbM (XXX units?) */ @@ -209,6 +210,13 @@ struct ieee80211com { /* optional state for Atheros SuperG protocol extensions */ struct ieee80211_superg *ic_superg; + /* radiotap handling */ + struct ieee80211_radiotap_header *ic_th;/* tx radiotap headers */ + void *ic_txchan; /* channel state in ic_th */ + struct ieee80211_radiotap_header *ic_rh;/* rx radiotap headers */ + void *ic_rxchan; /* channel state in ic_rh */ + int ic_monvaps; /* # monitor mode vaps */ + /* virtual ap create/delete */ struct ieee80211vap* (*ic_vap_create)(struct ieee80211com *, const char name[IFNAMSIZ], int unit, @@ -421,10 +429,9 @@ struct ieee80211vap { void (*iv_opdetach)(struct ieee80211vap *); /* receive processing */ int (*iv_input)(struct ieee80211_node *, - struct mbuf *, int rssi, int noise, - uint32_t rstamp); + struct mbuf *, int, int); void (*iv_recv_mgmt)(struct ieee80211_node *, - struct mbuf *, int, int, int, uint32_t); + struct mbuf *, int, int, int); void (*iv_recv_ctl)(struct ieee80211_node *, struct mbuf *, int); void (*iv_deliver_data)(struct ieee80211vap *, @@ -522,6 +529,7 @@ MALLOC_DECLARE(M_80211_VAP); #define IEEE80211_FEXT_DOTD 0x00001000 /* CONF: 11d enabled */ #define IEEE80211_FEXT_STATEWAIT 0x00002000 /* STATUS: awaiting state chg */ #define IEEE80211_FEXT_REINIT 0x00004000 /* STATUS: INIT state first */ +#define IEEE80211_FEXT_BPF 0x00008000 /* STATUS: BPF tap present */ /* NB: immutable: should be set only when creating a vap */ #define IEEE80211_FEXT_WDSLEGACY 0x00010000 /* CONF: legacy WDS operation */ #define IEEE80211_FEXT_PROBECHAN 0x00020000 /* CONF: probe passive channel*/ @@ -540,7 +548,7 @@ MALLOC_DECLARE(M_80211_VAP); #define IEEE80211_FEXT_BITS \ "\20\1NONHT_PR\2INACT\3SCANWAIT\4BGSCAN\5WPS\6TSN\7SCANREQ\10RESUME" \ "\0114ADDR\12NONEPR_PR\13SWBMISS\14DFS\15DOTD\16STATEWAIT\17REINIT" \ - "\22WDSLEGACY\23PROBECHAN\24HT\25AMDPU_TX\26AMPDU_TX\27AMSDU_TX" \ + "\20BPF\21WDSLEGACY\22PROBECHAN\24HT\25AMDPU_TX\26AMPDU_TX\27AMSDU_TX" \ "\30AMSDU_RX\31USEHT40\32PUREN\33SHORTGI20\34SHORTGI40\35HTCOMPAT" \ "\36RIFS" @@ -637,6 +645,31 @@ struct ieee80211_channel *ieee80211_find_channel_byieee(struct ieee80211com *, int ieee80211_setmode(struct ieee80211com *, enum ieee80211_phymode); enum ieee80211_phymode ieee80211_chan2mode(const struct ieee80211_channel *); +void ieee80211_radiotap_attach(struct ieee80211com *, + struct ieee80211_radiotap_header *th, int tlen, + uint32_t tx_radiotap, + struct ieee80211_radiotap_header *rh, int rlen, + uint32_t rx_radiotap); +void ieee80211_radiotap_detach(struct ieee80211com *); +void ieee80211_radiotap_vattach(struct ieee80211vap *); +void ieee80211_radiotap_vdetach(struct ieee80211vap *); +void ieee80211_radiotap_chan_change(struct ieee80211com *); +void ieee80211_radiotap_tx(struct ieee80211vap *, struct mbuf *); +void ieee80211_radiotap_rx(struct ieee80211vap *, struct mbuf *); +void ieee80211_radiotap_rx_all(struct ieee80211com *, struct mbuf *); + +static __inline int +ieee80211_radiotap_active(const struct ieee80211com *ic) +{ + return (ic->ic_flags_ext & IEEE80211_FEXT_BPF) != 0; +} + +static __inline int +ieee80211_radiotap_active_vap(const struct ieee80211vap *vap) +{ + return (vap->iv_flags_ext & IEEE80211_FEXT_BPF) != 0; +} + /* * Enqueue a task on the state thread. */ diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c index 6ab8f11..85ab544 100644 --- a/sys/net80211/ieee80211_wds.c +++ b/sys/net80211/ieee80211_wds.c @@ -63,10 +63,9 @@ __FBSDID("$FreeBSD$"); static void wds_vattach(struct ieee80211vap *); static int wds_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int wds_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp); +static int wds_input(struct ieee80211_node *ni, struct mbuf *m, int, int); static void wds_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int noise, u_int32_t rstamp); + int subtype, int, int); void ieee80211_wds_attach(struct ieee80211com *ic) @@ -199,12 +198,12 @@ ieee80211_create_wds(struct ieee80211vap *vap, struct ieee80211_channel *chan) * Flush pending frames now that were setup. */ if (ni != NULL && IEEE80211_NODE_WDSQ_QLEN(ni) != 0) { - int8_t rssi, noise; + int8_t rssi, nf; IEEE80211_NOTE(vap, IEEE80211_MSG_WDS, ni, "flush wds queue, %u packets queued", IEEE80211_NODE_WDSQ_QLEN(ni)); - ic->ic_node_getsignal(ni, &rssi, &noise); + ic->ic_node_getsignal(ni, &rssi, &nf); for (;;) { struct mbuf *m; @@ -213,8 +212,7 @@ ieee80211_create_wds(struct ieee80211vap *vap, struct ieee80211_channel *chan) IEEE80211_NODE_WDSQ_UNLOCK(ni); if (m == NULL) break; - /* XXX cheat and re-use last rstamp */ - ieee80211_input(ni, m, rssi, noise, ni->ni_rstamp); + ieee80211_input(ni, m, rssi, nf); } } return (ni == NULL ? ENOENT : 0); @@ -292,9 +290,6 @@ ieee80211_dwds_mcast(struct ieee80211vap *vap0, struct mbuf *m) mcopy->m_flags |= M_MCAST; mcopy->m_pkthdr.rcvif = (void *) ni; - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); - err = parent->if_transmit(parent, mcopy); if (err) { /* NB: IFQ_HANDOFF reclaims mbuf */ @@ -470,8 +465,7 @@ wds_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) * by the 802.11 layer. */ static int -wds_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp) +wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) { #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) #define HAS_SEQ(type) ((type & 0x4) == 0) @@ -553,8 +547,7 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, goto out; } IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; if (HAS_SEQ(type)) { uint8_t tid = ieee80211_gettid(wh); if (IEEE80211_QOS_HAS_SEQ(wh) && @@ -686,8 +679,8 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, } /* copy to listener after decrypt */ - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (ieee80211_radiotap_active_vap(vap)) + ieee80211_radiotap_rx(vap, m); need_tap = 0; /* @@ -786,16 +779,14 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, vap->iv_stats.is_rx_mgtdiscard++; /* XXX */ goto out; } - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); - vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp); - m_freem(m); - return IEEE80211_FC0_TYPE_MGT; + vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); + goto out; case IEEE80211_FC0_TYPE_CTL: vap->iv_stats.is_rx_ctl++; IEEE80211_NODE_STAT(ni, rx_ctrl); goto out; + default: IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, wh, "bad", "frame type 0x%x", type); @@ -806,8 +797,8 @@ err: ifp->if_ierrors++; out: if (m != NULL) { - if (bpf_peers_present(vap->iv_rawbpf) && need_tap) - bpf_mtap(vap->iv_rawbpf, m); + if (need_tap) + ieee80211_radiotap_rx(vap, m); m_freem(m); } return type; @@ -816,7 +807,7 @@ out: static void wds_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int noise, u_int32_t rstamp) + int subtype, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; -- cgit v1.1