summaryrefslogtreecommitdiffstats
path: root/sys/dev/ipw
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/ipw
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/ipw')
-rw-r--r--sys/dev/ipw/if_ipw.c44
-rw-r--r--sys/dev/ipw/if_ipwvar.h9
2 files changed, 21 insertions, 32 deletions
diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c
index c69ab6d..1c4e492 100644
--- a/sys/dev/ipw/if_ipw.c
+++ b/sys/dev/ipw/if_ipw.c
@@ -346,16 +346,11 @@ ipw_attach(device_t dev)
ic->ic_vap_create = ipw_vap_create;
ic->ic_vap_delete = ipw_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(IPW_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(IPW_TX_RADIOTAP_PRESENT);
+ ieee80211_radiotap_attach(ic,
+ &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
+ IPW_TX_RADIOTAP_PRESENT,
+ &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
+ IPW_RX_RADIOTAP_PRESENT);
/*
* Add a few sysctl knobs.
@@ -407,7 +402,6 @@ ipw_detach(device_t dev)
ieee80211_draintask(ic, &sc->sc_init_task);
ipw_stop(sc);
- bpfdetach(ifp);
ieee80211_ifdetach(ic);
callout_drain(&sc->sc_wdtimer);
@@ -1107,10 +1101,7 @@ ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan)
struct ieee80211com *ic = ifp->if_l2com;
ic->ic_curchan = chan;
- sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq =
- htole16(ic->ic_curchan->ic_freq);
- sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags =
- htole16(ic->ic_curchan->ic_flags);
+ ieee80211_radiotap_chan_change(ic);
}
/*
@@ -1172,6 +1163,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
struct ieee80211_node *ni;
bus_addr_t physaddr;
int error;
+ int8_t rssi, nf;
IPW_LOCK_DECL;
DPRINTFN(5, ("received frame len=%u, rssi=%u\n", le32toh(status->len),
@@ -1226,15 +1218,14 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = le32toh(status->len);
- if (bpf_peers_present(ifp->if_bpf)) {
+ rssi = status->rssi + IPW_RSSI_TO_DBM;
+ nf = -95;
+ if (ieee80211_radiotap_active(ic)) {
struct ipw_rx_radiotap_header *tap = &sc->sc_rxtap;
tap->wr_flags = 0;
- tap->wr_antsignal = status->rssi + IPW_RSSI_TO_DBM;
- tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
+ tap->wr_antsignal = rssi;
+ tap->wr_antnoise = nf;
}
if (sc->flags & IPW_FLAG_SCANNING)
@@ -1243,10 +1234,10 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
IPW_UNLOCK(sc);
ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
if (ni != NULL) {
- (void) ieee80211_input(ni, m, status->rssi, -95, 0);
+ (void) ieee80211_input(ni, m, rssi, nf);
ieee80211_free_node(ni);
} else
- (void) ieee80211_input_all(ic, m, status->rssi, -95, 0);
+ (void) ieee80211_input_all(ic, m, rssi, nf);
IPW_LOCK(sc);
bus_dmamap_sync(sc->rbd_dmat, sc->rbd_map, BUS_DMASYNC_PREWRITE);
@@ -1570,6 +1561,7 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ipw_softc *sc = ifp->if_softc;
struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_frame *wh;
struct ipw_soft_bd *sbd;
struct ipw_soft_hdr *shdr;
@@ -1592,14 +1584,12 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni)
wh = mtod(m0, struct ieee80211_frame *);
}
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ieee80211_radiotap_active_vap(vap)) {
struct ipw_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
- 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);
}
shdr = SLIST_FIRST(&sc->free_shdr);
diff --git a/sys/dev/ipw/if_ipwvar.h b/sys/dev/ipw/if_ipwvar.h
index 24fb8e8..8d9e049 100644
--- a/sys/dev/ipw/if_ipwvar.h
+++ b/sys/dev/ipw/if_ipwvar.h
@@ -57,13 +57,15 @@ struct ipw_rx_radiotap_header {
uint8_t wr_flags;
uint16_t wr_chan_freq;
uint16_t wr_chan_flags;
- uint8_t wr_antsignal;
+ int8_t wr_antsignal;
+ int8_t wr_antnoise;
};
#define IPW_RX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
+ (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
+ (1 << IEEE80211_RADIOTAP_DB_ANTNOISE))
struct ipw_tx_radiotap_header {
struct ieee80211_radiotap_header wt_ihdr;
@@ -155,10 +157,7 @@ struct ipw_softc {
int txfree;
struct ipw_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
-
struct ipw_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
};
/*
OpenPOWER on IntegriCloud