summaryrefslogtreecommitdiffstats
path: root/sys/dev/ral
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2009-05-20 20:00:40 +0000
committersam <sam@FreeBSD.org>2009-05-20 20:00:40 +0000
commit68f7a1034ab73897585652ceedd3727d57150c12 (patch)
treec9b0cc01e080db542eb19f65236177aacfa14b5d /sys/dev/ral
parentdf90a80062bff5ee7300c9b15aaeeaa9c1b49b5e (diff)
downloadFreeBSD-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.c77
-rw-r--r--sys/dev/ral/rt2560var.h6
-rw-r--r--sys/dev/ral/rt2661.c66
-rw-r--r--sys/dev/ral/rt2661var.h6
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;
OpenPOWER on IntegriCloud