Add IEEE802.11 radiotap support. From Damien Bergamini.

This commit is contained in:
lukem 2004-09-14 00:31:20 +00:00
parent 2cc0c73c82
commit 9e6574e2c2
2 changed files with 87 additions and 3 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ipw.c,v 1.3 2004/08/27 00:02:02 lukem Exp $ */
/* $NetBSD: if_ipw.c,v 1.4 2004/09/14 00:31:20 lukem Exp $ */
/* Id: if_ipw.c,v 1.1.2.7 2004/08/20 11:20:11 damien Exp */
/*-
@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_ipw.c,v 1.3 2004/08/27 00:02:02 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_ipw.c,v 1.4 2004/09/14 00:31:20 lukem Exp $");
/*-
* Intel(R) PRO/Wireless 2100 MiniPCI driver
@ -67,6 +67,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_ipw.c,v 1.3 2004/08/27 00:02:02 lukem Exp $");
#include <net/if_types.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@ -267,6 +268,19 @@ ipw_attach(struct device *parent, struct device *self, void *aux)
ic->ic_newstate = ipw_newstate;
ieee80211_media_init(ifp, ipw_media_change, ieee80211_media_status);
#if NBPFILTER > 0
bpfattach2(ifp, DLT_IEEE802_11_RADIO,
sizeof (struct ieee80211_frame) + 64, &sc->sc_drvbpf);
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(IPW_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(IPW_TX_RADIOTAP_PRESENT);
#endif
}
static int
@ -277,6 +291,9 @@ ipw_detach(struct device* self, int flags)
ipw_reset(sc);
#if NBPFILTER > 0
bpfdetach(ifp);
#endif
ieee80211_ifdetach(ifp);
if_detach(ifp);
@ -424,6 +441,19 @@ ipw_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 NBPFILTER > 0
if (sc->sc_drvbpf != NULL) {
struct ipw_rx_radiotap_header *tap = &sc->sc_rxtap;
tap->wr_flags = 0;
tap->wr_antsignal = status->rssi;
tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
}
#endif
wh = mtod(m, struct ieee80211_frame *);
if (ic->ic_opmode != IEEE80211_M_STA) {
@ -678,6 +708,18 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni)
return ENOBUFS;
}
#if NBPFILTER > 0
if (sc->sc_drvbpf != NULL) {
struct ipw_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m);
}
#endif
wh = mtod(m, struct ieee80211_frame *);
shdr = TAILQ_FIRST(&sc->sc_free_shdr);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ipwvar.h,v 1.3 2004/09/14 00:27:26 lukem Exp $ */
/* $NetBSD: if_ipwvar.h,v 1.4 2004/09/14 00:31:20 lukem Exp $ */
/*-
* Copyright (c) 2004
@ -50,6 +50,30 @@ struct ipw_soft_buf {
TAILQ_ENTRY(ipw_soft_buf) next;
};
struct ipw_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
u_int8_t wr_flags;
u_int16_t wr_chan_freq;
u_int16_t wr_chan_flags;
u_int8_t wr_antsignal;
};
#define IPW_RX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
struct ipw_tx_radiotap_header {
struct ieee80211_radiotap_header wt_ihdr;
u_int8_t wt_flags;
u_int16_t wt_chan_freq;
u_int16_t wt_chan_flags;
};
#define IPW_TX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_CHANNEL))
struct ipw_softc {
struct device sc_dev;
@ -102,6 +126,24 @@ struct ipw_softc {
u_int32_t txcur;
u_int32_t txold;
u_int32_t rxcur;
#if NBPFILTER > 0
struct bpf_if *sc_drvbpf;
union {
struct ipw_rx_radiotap_header th;
u_int8_t pad[64];
} sc_rxtapu;
#define sc_rxtap sc_rxtapu.th
int sc_rxtap_len;
union {
struct ipw_tx_radiotap_header th;
u_int8_t pad[64];
} sc_txtapu;
#define sc_txtap sc_txtapu.th
int sc_txtap_len;
#endif
};
#define SIOCSLOADFW _IOW('i', 137, struct ifreq)