o add experimental radiotap capture format

o add netbsd logic to convert rssi to device-independent values

Obtained from:	NetBSD (rssi conversion code)
This commit is contained in:
sam 2003-09-05 22:29:30 +00:00
parent 92be79f871
commit 61e32060eb
5 changed files with 125 additions and 13 deletions

View File

@ -100,6 +100,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_ioctl.h>
#include <net80211/ieee80211_radiotap.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@ -110,8 +111,8 @@ __FBSDID("$FreeBSD$");
#include <net/bpf.h>
#include <dev/wi/if_wavelan_ieee.h>
#include <dev/wi/if_wivar.h>
#include <dev/wi/if_wireg.h>
#include <dev/wi/if_wivar.h>
#define IF_POLL(ifq, m) ((m) = (ifq)->ifq_head)
#define IFQ_POLL(ifq, m) IF_POLL((ifq), (m))
@ -372,6 +373,10 @@ wi_attach(device_t dev)
ic->ic_caps |= IEEE80211_C_MONITOR;
}
sc->sc_ibss_port = htole16(1);
sc->sc_min_rssi = WI_LUCENT_MIN_RSSI;
sc->sc_max_rssi = WI_LUCENT_MAX_RSSI;
sc->sc_dbm_offset = WI_LUCENT_DBM_OFFSET;
break;
case WI_INTERSIL:
@ -393,6 +398,10 @@ wi_attach(device_t dev)
if (sc->sc_sta_firmware_ver >= 803)
ic->ic_caps |= IEEE80211_C_HOSTAP;
sc->sc_ibss_port = htole16(0);
sc->sc_min_rssi = WI_PRISM_MIN_RSSI;
sc->sc_max_rssi = WI_PRISM_MAX_RSSI;
sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET;
break;
case WI_SYMBOL:
@ -401,6 +410,10 @@ wi_attach(device_t dev)
if (sc->sc_sta_firmware_ver >= 25000)
ic->ic_caps |= IEEE80211_C_IBSS;
sc->sc_ibss_port = htole16(4);
sc->sc_min_rssi = WI_PRISM_MIN_RSSI;
sc->sc_max_rssi = WI_PRISM_MAX_RSSI;
sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET;
break;
}
@ -431,9 +444,8 @@ wi_attach(device_t dev)
buflen = sizeof(val);
if ((sc->sc_flags & WI_FLAGS_HAS_DBMADJUST) &&
wi_read_rid(sc, WI_RID_DBM_ADJUST, &val, &buflen) == 0) {
sc->sc_dbm_adjust = le16toh(val);
} else
sc->sc_dbm_adjust = 100; /* default */
sc->sc_dbm_offset = le16toh(val);
}
sc->sc_max_datalen = 2304;
sc->sc_system_scale = 1;
@ -460,6 +472,23 @@ wi_attach(device_t dev)
ic->ic_newstate = wi_newstate;
ieee80211_media_init(ifp, wi_media_change, wi_media_status);
#if NBPFILTER > 0
bpfattach2(ifp, DLT_IEEE802_11_RADIO,
sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th),
&sc->sc_drvbpf);
/*
* Initialize constant fields.
*
* NB: the channel is setup each time we transition to the
* RUN state to avoid filling it in for each frame.
*/
sc->sc_tx_th.wt_ihdr.it_len = sizeof(sc->sc_tx_th);
sc->sc_tx_th.wt_ihdr.it_present = WI_TX_RADIOTAP_PRESENT;
sc->sc_rx_th.wr_ihdr.it_len = sizeof(sc->sc_rx_th);
sc->sc_rx_th.wr_ihdr.it_present = WI_RX_RADIOTAP_PRESENT0;
sc->sc_rx_th.wr_present1 = WI_RX_RADIOTAP_PRESENT1;
#endif
return (0);
}
@ -477,6 +506,9 @@ wi_detach(device_t dev)
wi_stop(ifp, 0);
#if NBPFILTER > 0
bpfdetach(ifp);
#endif
ieee80211_ifdetach(ifp);
WI_UNLOCK(sc);
bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
@ -902,10 +934,9 @@ wi_start(struct ifnet *ifp)
MGETHDR(mb, M_DONTWAIT, m0->m_type);
if (mb != NULL) {
(void) m_dup_pkthdr(mb, m0, M_DONTWAIT);
mb->m_next = m0;
mb->m_data = (caddr_t)&frmhdr;
mb->m_len = sizeof(frmhdr);
mb->m_data = (caddr_t)&sc->sc_tx_th;
mb->m_len = sizeof(sc->sc_tx_th);
mb->m_pkthdr.len += mb->m_len;
bpf_mtap(sc->sc_drvbpf, mb);
m_free(mb);
@ -1449,12 +1480,23 @@ wi_rx_intr(struct wi_softc *sc)
if (sc->sc_drvbpf) {
struct mbuf *mb;
/* XXX pre-allocate space when setting up recv's */
MGETHDR(mb, M_DONTWAIT, m->m_type);
if (mb != NULL) {
/* XXX replace divide by table */
sc->sc_rx_th.wr_rate = frmhdr.wi_rx_rate / 5;
sc->sc_rx_th.wr_antsignal =
WI_RSSI_TO_DBM(sc, frmhdr.wi_rx_signal);
sc->sc_rx_th.wr_antnoise =
WI_RSSI_TO_DBM(sc, frmhdr.wi_rx_silence);
sc->sc_rx_th.wr_time =
htole32((frmhdr.wi_rx_tstamp1 << 16) |
frmhdr.wi_rx_tstamp0);
(void) m_dup_pkthdr(mb, m, M_DONTWAIT);
mb->m_next = m;
mb->m_data = (caddr_t)&frmhdr;
mb->m_len = sizeof(frmhdr);
mb->m_data = (caddr_t)&sc->sc_rx_th;
mb->m_len = sizeof(sc->sc_rx_th);
mb->m_pkthdr.len += mb->m_len;
bpf_mtap(sc->sc_drvbpf, mb);
m_free(mb);
@ -1837,7 +1879,7 @@ wi_get_cfg(struct ifnet *ifp, u_long cmd, caddr_t data)
&len);
break;
}
wreq.wi_val[0] = htole16(sc->sc_dbm_adjust);
wreq.wi_val[0] = htole16(sc->sc_dbm_offset);
len = sizeof(u_int16_t);
break;
@ -2608,6 +2650,12 @@ wi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
wi_read_rid(sc, WI_RID_CURRENT_CHAN, &val, &buflen);
/* XXX validate channel */
ni->ni_chan = &ic->ic_channels[le16toh(val)];
#if NBPFILTER > 0
sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
htole16(ni->ni_chan->ic_freq);
sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
htole16(ni->ni_chan->ic_flags);
#endif
if (IEEE80211_ADDR_EQ(old_bssid, ni->ni_bssid))
sc->sc_false_syns++;

View File

@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include <net/if_types.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/pccard/pccardvar.h>
#if __FreeBSD_version >= 500000
@ -69,8 +70,8 @@ __FBSDID("$FreeBSD$");
#endif
#include <dev/wi/if_wavelan_ieee.h>
#include <dev/wi/if_wivar.h>
#include <dev/wi/if_wireg.h>
#include <dev/wi/if_wivar.h>
#ifdef WI_SYMBOL_FIRMWARE
#include <dev/wi/spectrum24t_cf.h>
#endif

View File

@ -62,10 +62,11 @@
#include <net/if_types.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/wi/if_wavelan_ieee.h>
#include <dev/wi/if_wivar.h>
#include <dev/wi/if_wireg.h>
#include <dev/wi/if_wivar.h>
static int wi_pci_probe(device_t);
static int wi_pci_attach(device_t);

View File

@ -679,3 +679,39 @@ struct wi_frame {
*/
#define WI_HFA386X_CR_A_D_TEST_MODES2 0x1A
#define WI_HFA386X_CR_MANUAL_TX_POWER 0x3E
#ifdef IEEE80211_RADIOTAP_F_CFP
/*
* Radio capture format for Prism.
*/
#define WI_RX_RADIOTAP_PRESENT0 \
((1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
(1 << IEEE80211_RADIOTAP_DB_ANTNOISE) | \
(1 << IEEE80211_RADIOTAP_EXT))
#define WI_RX_RADIOTAP_PRESENT1 (1 << (IEEE80211_RADIOTAP_TIME - 32))
struct wi_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
u_int32_t wr_present1;
u_int8_t wr_flags;
u_int8_t wr_rate;
u_int16_t wr_chan_freq;
u_int16_t wr_chan_flags;
u_int8_t wr_antsignal;
u_int8_t wr_antnoise;
u_int32_t wr_time;
};
#define WI_TX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_CHANNEL))
struct wi_tx_radiotap_header {
struct ieee80211_radiotap_header wt_ihdr;
u_int16_t wt_chan_freq;
u_int16_t wt_chan_flags;
};
#endif /* IEEE80211_RADIOTAP_F_CFP */

View File

@ -106,7 +106,11 @@ struct wi_softc {
u_int16_t sc_procframe;
u_int16_t sc_portnum;
u_int16_t sc_dbm_adjust;
/* RSSI interpretation */
u_int16_t sc_min_rssi; /* clamp sc_min_rssi < RSSI */
u_int16_t sc_max_rssi; /* clamp RSSI < sc_max_rssi */
u_int16_t sc_dbm_offset; /* dBm ~ RSSI - sc_dbm_offset */
u_int16_t sc_max_datalen;
u_int16_t sc_system_scale;
u_int16_t sc_cnfauthmode;
@ -158,8 +162,19 @@ struct wi_softc {
int sc_false_syns;
u_int16_t sc_txbuf[IEEE80211_MAX_LEN/2];
union {
struct wi_tx_radiotap_header th;
u_int8_t pad[64];
} u_tx_rt;
union {
struct wi_rx_radiotap_header th;
u_int8_t pad[64];
} u_rx_rt;
};
#define sc_if sc_ic.ic_if
#define sc_tx_th u_tx_rt.th
#define sc_rx_th u_rx_rt.th
/* maximum consecutive false change-of-BSSID indications */
#define WI_MAX_FALSE_SYNS 10
@ -184,6 +199,17 @@ struct wi_card_ident {
u_int8_t firm_type;
};
#define WI_PRISM_MIN_RSSI 0x1b
#define WI_PRISM_MAX_RSSI 0x9a
#define WI_PRISM_DBM_OFFSET 100 /* XXX */
#define WI_LUCENT_MIN_RSSI 47
#define WI_LUCENT_MAX_RSSI 138
#define WI_LUCENT_DBM_OFFSET 149
#define WI_RSSI_TO_DBM(sc, rssi) (MIN((sc)->sc_max_rssi, \
MAX((sc)->sc_min_rssi, (rssi))) - (sc)->sc_dbm_offset)
#if __FreeBSD_version < 500000
/*
* Various compat hacks/kludges