diff options
author | sam <sam@FreeBSD.org> | 2009-05-20 20:00:40 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2009-05-20 20:00:40 +0000 |
commit | 68f7a1034ab73897585652ceedd3727d57150c12 (patch) | |
tree | c9b0cc01e080db542eb19f65236177aacfa14b5d /sys/dev/ral | |
parent | df90a80062bff5ee7300c9b15aaeeaa9c1b49b5e (diff) | |
download | FreeBSD-src-68f7a1034ab73897585652ceedd3727d57150c12.zip FreeBSD-src-68f7a1034ab73897585652ceedd3727d57150c12.tar.gz |
Overhaul monitor mode handling:
o replace DLT_IEEE802_11 support in net80211 with DLT_IEEE802_11_RADIO
and remove explicit bpf support from wireless drivers; drivers now
use ieee80211_radiotap_attach to setup shared data structures that
hold the radiotap header for each packet tx/rx
o remove rx timestamp from the rx path; it was used only by the tdma support
for debugging and was mostly useless due to it being 32-bits and mostly
unavailable
o track DLT_IEEE80211_RADIO bpf attachments and maintain per-vap and
per-com state when there are active taps
o track the number of monitor mode vaps
o use bpf tap and monitor mode vap state to decide when to collect radiotap
state and dispatch frames; drivers no longer explicitly directly check
bpf state or use bpf calls to tap frames
o handle radiotap state updates on channel change in net80211; drivers
should not do this (unless they bypass net80211 which is almost always
a mistake)
o update various drivers to be more consistent/correct in handling radiotap
o update ral to include TSF in radiotap'd frames
o add promisc mode callback to wi
Reviewed by: cbzimmer, rpaulo, thompsa
Diffstat (limited to 'sys/dev/ral')
-rw-r--r-- | sys/dev/ral/rt2560.c | 77 | ||||
-rw-r--r-- | sys/dev/ral/rt2560var.h | 6 | ||||
-rw-r--r-- | sys/dev/ral/rt2661.c | 66 | ||||
-rw-r--r-- | sys/dev/ral/rt2661var.h | 6 |
4 files changed, 71 insertions, 84 deletions
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; |