From 92be79f8718c8d556f13d3526d8a1886a858be2b Mon Sep 17 00:00:00 2001 From: sam Date: Fri, 5 Sep 2003 22:22:49 +0000 Subject: Add support for the experimental radiotap capture format. With this we no longer need the debugging code to dump packets. --- sys/dev/ath/if_ath.c | 75 ++++++++++++++++++++++++++++++++++++++++------- sys/dev/ath/if_athioctl.h | 35 ++++++++++++++++++++++ sys/dev/ath/if_athvar.h | 13 ++++++++ 3 files changed, 112 insertions(+), 11 deletions(-) diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 9a4c4bd..0d854b9 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -298,6 +298,21 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) /* complete initialization */ ieee80211_media_init(ifp, ath_media_change, ieee80211_media_status); + bpfattach2(ifp, DLT_IEEE802_11_RADIO, + sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th), + &sc->sc_drvbpf); + /* + * Initialize constant fields. + * + * 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.wt_ihdr.it_len = sizeof(sc->sc_tx_th); + sc->sc_tx_th.wt_ihdr.it_present = ATH_TX_RADIOTAP_PRESENT; + + sc->sc_rx_th.wr_ihdr.it_len = sizeof(sc->sc_rx_th); + sc->sc_rx_th.wr_ihdr.it_present = ATH_RX_RADIOTAP_PRESENT; + if_printf(ifp, "802.11 address: %s\n", ether_sprintf(ic->ic_myaddr)); return 0; @@ -317,6 +332,7 @@ ath_detach(struct ath_softc *sc) mtx_lock(&sc->sc_mtx); ath_stop(ifp); + bpfdetach(ifp); ath_desc_free(sc); ath_hal_detach(sc->sc_ah); ieee80211_ifdetach(ifp); @@ -732,6 +748,23 @@ ath_start(struct ifnet *ifp) if (ic->ic_rawbpf) bpf_mtap(ic->ic_rawbpf, m); + if (sc->sc_drvbpf) { + struct mbuf *mb; + + MGETHDR(mb, M_DONTWAIT, m->m_type); + if (mb != NULL) { + sc->sc_tx_th.wt_rate = + ni->ni_rates.rs_rates[ni->ni_txrate]; + + mb->m_next = m; + mb->m_data = (caddr_t)&sc->sc_tx_th; + mb->m_len = sizeof(sc->sc_tx_th); + mb->m_pkthdr.len += mb->m_len; + bpf_mtap(sc->sc_drvbpf, mb); + m_free(mb); + } + } + /* * TODO: * The duration field of 802.11 header should be filled. @@ -739,12 +772,6 @@ ath_start(struct ifnet *ifp) * doesn't know the detail of parameters such as IFS * for now.. */ - - if (IFF_DUMPPKTS(ifp)) - ieee80211_dump_pkt(mtod(m, u_int8_t *), m->m_len, - ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL, - -1); - if (ath_tx_start(sc, ni, bf, m)) { bad: mtx_lock(&sc->sc_txbuflock); @@ -1526,11 +1553,29 @@ ath_rx_proc(void *arg, int npending) bf->bf_m = NULL; m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = len; - if (IFF_DUMPPKTS(ifp)) { - ieee80211_dump_pkt(mtod(m, u_int8_t *), len, - sc->sc_hwmap[ds->ds_rxstat.rs_rate] & - IEEE80211_RATE_VAL, - ds->ds_rxstat.rs_rssi); + + if (sc->sc_drvbpf) { + struct mbuf *mb; + + /* XXX pre-allocate space when setting up recv's */ + MGETHDR(mb, M_DONTWAIT, m->m_type); + if (mb != NULL) { + sc->sc_rx_th.wr_rate = + sc->sc_hwmap[ds->ds_rxstat.rs_rate]; + sc->sc_rx_th.wr_antsignal = + ds->ds_rxstat.rs_rssi; + sc->sc_rx_th.wr_antenna = + ds->ds_rxstat.rs_antenna; + /* XXX TSF */ + + (void) m_dup_pkthdr(mb, m, M_DONTWAIT); + mb->m_next = m; + mb->m_data = (caddr_t)&sc->sc_rx_th; + mb->m_len = sizeof(sc->sc_rx_th); + mb->m_pkthdr.len += mb->m_len; + bpf_mtap(sc->sc_drvbpf, mb); + m_free(mb); + } } m_adj(m, -IEEE80211_CRC_LEN); @@ -2128,6 +2173,14 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) } /* + * Update BPF state. + */ + sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = + htole16(chan->ic_freq); + sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = + htole16(chan->ic_flags); + + /* * Change channels and update the h/w rate map * if we're switching; e.g. 11a to 11b/g. */ diff --git a/sys/dev/ath/if_athioctl.h b/sys/dev/ath/if_athioctl.h index dcae150..308f9cb 100644 --- a/sys/dev/ath/if_athioctl.h +++ b/sys/dev/ath/if_athioctl.h @@ -91,4 +91,39 @@ struct ath_stats { #define SIOCGATHSTATS _IOWR('i', 137, struct ifreq) +/* + * Radio capture format. + */ +#define ATH_RX_RADIOTAP_PRESENT ( \ + (1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL) | \ + (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \ + (1 << IEEE80211_RADIOTAP_ANTENNA) | \ + 0) + +struct ath_rx_radiotap_header { + struct ieee80211_radiotap_header wr_ihdr; + u_int8_t wr_flags; /* XXX for padding */ + u_int8_t wr_rate; + u_int16_t wr_chan_freq; + u_int16_t wr_chan_flags; + u_int8_t wr_antsignal; + u_int8_t wr_antenna; +}; + +#define ATH_TX_RADIOTAP_PRESENT ( \ + (1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL) | \ + 0) + +struct ath_tx_radiotap_header { + struct ieee80211_radiotap_header wt_ihdr; + u_int8_t wt_flags; /* XXX for padding */ + u_int8_t wt_rate; + u_int16_t wt_chan_freq; + u_int16_t wt_chan_flags; +}; + #endif /* _DEV_ATH_ATHIOCTL_H */ diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index 378a0ba..857ecd5 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -45,6 +45,7 @@ #include #include +#include #include #define ATH_TIMEOUT 1000 @@ -100,6 +101,16 @@ struct ath_softc { u_int8_t sc_hwmap[32]; /* h/w rate ix to IEEE table */ HAL_INT sc_imask; /* interrupt mask copy */ + struct bpf_if *sc_drvbpf; + union { + struct ath_tx_radiotap_header th; + u_int8_t pad[64]; + } u_tx_rt; + union { + struct ath_rx_radiotap_header th; + u_int8_t pad[64]; + } u_rx_rt; + struct ath_desc *sc_desc; /* TX/RX descriptors */ bus_dma_segment_t sc_dseg; bus_dmamap_t sc_ddmamap; /* DMA map for descriptors */ @@ -132,6 +143,8 @@ struct ath_softc { struct callout sc_scan_ch; /* callout handle for scan */ struct ath_stats sc_stats; /* interface statistics */ }; +#define sc_tx_th u_tx_rt.th +#define sc_rx_th u_rx_rt.th int ath_attach(u_int16_t, struct ath_softc *); int ath_detach(struct ath_softc *); -- cgit v1.1