summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2003-09-05 22:22:49 +0000
committersam <sam@FreeBSD.org>2003-09-05 22:22:49 +0000
commit92be79f8718c8d556f13d3526d8a1886a858be2b (patch)
tree395b7b6c386c076e8aa4c7f0f8926154e7eaf921
parentbdc819fefbf4712e9dabafda6a0950b35837e6d0 (diff)
downloadFreeBSD-src-92be79f8718c8d556f13d3526d8a1886a858be2b.zip
FreeBSD-src-92be79f8718c8d556f13d3526d8a1886a858be2b.tar.gz
Add support for the experimental radiotap capture format. With this
we no longer need the debugging code to dump packets.
-rw-r--r--sys/dev/ath/if_ath.c75
-rw-r--r--sys/dev/ath/if_athioctl.h35
-rw-r--r--sys/dev/ath/if_athvar.h13
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 <sys/taskqueue.h>
#include <contrib/dev/ath/ah.h>
+#include <net80211/ieee80211_radiotap.h>
#include <dev/ath/if_athioctl.h>
#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 *);
OpenPOWER on IntegriCloud