diff options
author | Marcus Glocker <mglocker@cvs.openbsd.org> | 2007-09-24 19:51:19 +0000 |
---|---|---|
committer | Marcus Glocker <mglocker@cvs.openbsd.org> | 2007-09-24 19:51:19 +0000 |
commit | 2e49c8f494c42df7e3c836796ae95cc203380e52 (patch) | |
tree | 783086bf1f95017e8fe6912180a1ccc5b672663f /sys | |
parent | 9c23173c6c68b311a5bdf6289adefe0860bb7c8d (diff) |
Add radio tap support. We still need to calculate correct RX rate and
RX signal strength.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ic/bwi.c | 67 | ||||
-rw-r--r-- | sys/dev/ic/bwivar.h | 53 |
2 files changed, 114 insertions, 6 deletions
diff --git a/sys/dev/ic/bwi.c b/sys/dev/ic/bwi.c index 6b3d5c895ec..6f1be456bc5 100644 --- a/sys/dev/ic/bwi.c +++ b/sys/dev/ic/bwi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bwi.c,v 1.45 2007/09/23 22:59:44 mglocker Exp $ */ +/* $OpenBSD: bwi.c,v 1.46 2007/09/24 19:51:18 mglocker Exp $ */ /* * Copyright (c) 2007 The DragonFly Project. All rights reserved. @@ -769,6 +769,19 @@ bwi_attach(struct bwi_softc *sc) goto fail; } +#if NBPFILTER > 0 + bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO, + sizeof(struct ieee80211_frame) + 64); + + sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); + sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); + sc->sc_rxtap.wr_ihdr.it_present = htole32(BWI_RX_RADIOTAP_PRESENT); + + sc->sc_txtap_len = sizeof(sc->sc_txtapu); + sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); + sc->sc_txtap.wt_ihdr.it_present = htole32(BWI_TX_RADIOTAP_PRESENT); +#endif + return (0); fail: return (error); @@ -7376,8 +7389,6 @@ bwi_set_chan(struct bwi_softc *sc, u_int8_t chan) bwi_rf_set_chan(mac, chan, 0); - /* TODO: radio tap */ - return (0); } @@ -7449,7 +7460,32 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx) m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr); m_adj(m, sizeof(*hdr) + wh_ofs); - /* TODO: radio tap */ +#if NBPFILTER > 0 + /* RX radio tap */ + if (sc->sc_drvbpf != NULL) { + struct mbuf mb; + struct bwi_rx_radiotap_hdr *tap = &sc->sc_rxtap; + + /* TODO: calculate rate and signal */ + tap->wr_tsf = hdr->rxh_tsf; + tap->wr_flags = 0; + tap->wr_rate = 0; + tap->wr_chan_freq = + htole16(ic->ic_bss->ni_chan->ic_freq); + tap->wr_chan_flags = + htole16(ic->ic_bss->ni_chan->ic_flags); + tap->wr_antsignal = 0; + tap->wr_antnoise = 0; + + mb.m_data = (caddr_t)tap; + mb.m_len = sc->sc_rxtap_len; + mb.m_next = m; + mb.m_nextpkt = NULL; + mb.m_type = 0; + mb.m_flags = 0; + bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN); + } +#endif m_adj(m, -IEEE80211_CRC_LEN); @@ -7923,7 +7959,28 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, rate = rate_fb = (1 * 2); /* Force 1Mbytes/s */ } - /* TODO: radio tap */ +#if NBPFILTER > 0 + /* TX radio tap */ + if (sc->sc_drvbpf != NULL) { + struct mbuf mb; + struct bwi_tx_radiotap_hdr *tap = &sc->sc_txtap; + + tap->wt_flags = 0; + tap->wt_rate = rate; + tap->wt_chan_freq = + htole16(ic->ic_bss->ni_chan->ic_freq); + tap->wt_chan_flags = + htole16(ic->ic_bss->ni_chan->ic_flags); + + mb.m_data = (caddr_t)tap; + mb.m_len = sc->sc_txtap_len; + mb.m_next = m; + mb.m_nextpkt = NULL; + mb.m_type = 0; + mb.m_flags = 0; + bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT); + } +#endif /* * Setup the embedded TX header diff --git a/sys/dev/ic/bwivar.h b/sys/dev/ic/bwivar.h index 18d055de580..84a8d2c19d1 100644 --- a/sys/dev/ic/bwivar.h +++ b/sys/dev/ic/bwivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bwivar.h,v 1.11 2007/09/18 17:35:38 mglocker Exp $ */ +/* $OpenBSD: bwivar.h,v 1.12 2007/09/24 19:51:18 mglocker Exp $ */ /* * Copyright (c) 2007 The DragonFly Project. All rights reserved. @@ -430,6 +430,39 @@ enum bwi_bus_space { BWI_BUS_SPACE_64BIT }; +#define BWI_TX_RADIOTAP_PRESENT \ + ((1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL)) + +struct bwi_tx_radiotap_hdr { + struct ieee80211_radiotap_header wt_ihdr; + uint8_t wt_flags; + uint8_t wt_rate; + uint16_t wt_chan_freq; + uint16_t wt_chan_flags; +}; + +#define BWI_RX_RADIOTAP_PRESENT \ + ((1 << IEEE80211_RADIOTAP_TSFT) | \ + (1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) + +struct bwi_rx_radiotap_hdr { + struct ieee80211_radiotap_header wr_ihdr; + uint64_t wr_tsf; + uint8_t wr_flags; + uint8_t wr_rate; + uint16_t wr_chan_freq; + uint16_t wr_chan_flags; + int8_t wr_antsignal; + int8_t wr_antnoise; + /* TODO: sq */ +}; + struct bwi_softc { struct device sc_dev; struct ieee80211com sc_ic; @@ -515,6 +548,24 @@ struct bwi_softc { /* Sysctl variables */ int sc_fw_version; /* BWI_FW_VERSION[34] */ int sc_dwell_time; /* milliseconds */ + +#if NBPFILTER > 0 + caddr_t sc_drvbpf; + + union { + struct bwi_rx_radiotap_hdr th; + uint8_t pad[64]; + } sc_rxtapu; +#define sc_rxtap sc_rxtapu.th + int sc_rxtap_len; + + union { + struct bwi_tx_radiotap_hdr th; + uint8_t pad[64]; + } sc_txtapu; +#define sc_txtap sc_txtapu.th + int sc_txtap_len; +#endif }; #define BWI_F_BUS_INITED 0x1 |