Date: Thu, 7 Aug 2003 14:36:40 -0700 (PDT) From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 35736 for review Message-ID: <200308072136.h77LaeIm020659@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=35736 Change 35736 by sam@sam_ebb on 2003/08/07 14:36:26 o revamp input path to pass reference'd node up to wlan layer o add radiotap packet capture support o add device-specific rssi conversion support for converting rssi values to dbm for recording in radiotap captured frames Affected files ... .. //depot/projects/netperf/sys/dev/wi/if_wi.c#2 edit .. //depot/projects/netperf/sys/dev/wi/if_wi_pccard.c#2 edit .. //depot/projects/netperf/sys/dev/wi/if_wi_pci.c#3 edit .. //depot/projects/netperf/sys/dev/wi/if_wireg.h#2 edit .. //depot/projects/netperf/sys/dev/wi/if_wivar.h#2 edit Differences ... ==== //depot/projects/netperf/sys/dev/wi/if_wi.c#2 (text+ko) ==== @@ -100,6 +100,7 @@ #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 @@ #include <net/bpf.h> #include <dev/wi/if_wavelan_ieee.h> +#include <dev/wi/if_wireg.h> #include <dev/wi/if_wivar.h> -#include <dev/wi/if_wireg.h> #define IF_POLL(ifq, m) ((m) = (ifq)->ifq_head) #define IFQ_POLL(ifq, m) IF_POLL((ifq), (m)) @@ -372,6 +373,10 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); } @@ -901,10 +930,9 @@ 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); @@ -1355,6 +1383,7 @@ struct wi_frame frmhdr; struct mbuf *m; struct ieee80211_frame *wh; + struct ieee80211_node *ni; int fid, len, off, rssi; u_int8_t dir; u_int16_t status; @@ -1445,12 +1474,23 @@ 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); @@ -1471,7 +1511,32 @@ if (ic->ic_opmode == IEEE80211_M_IBSS && dir == IEEE80211_FC1_DIR_NODS) wi_sync_bssid(sc, wh->i_addr3); - ieee80211_input(ifp, m, rssi, rstamp, 0); + /* + * Locate the node for sender, track state, and + * then pass this node (referenced) up to the 802.11 + * layer for its use. We are required to pass + * something so we fallback to ic_bss when this frame + * is from an unknown sender. + */ + if (ic->ic_opmode != IEEE80211_M_STA) { + ni = ieee80211_find_node(ic, wh->i_addr2); + if (ni == NULL) + ni = ieee80211_ref_node(ic->ic_bss); + } else + ni = ieee80211_ref_node(ic->ic_bss); + /* + * Send frame up for processing. + */ + ieee80211_input(ifp, m, ni, rssi, rstamp); + /* + * The frame may have caused the node to be marked for + * reclamation (e.g. in response to a DEAUTH message) + * so use free_node here instead of unref_node. + */ + if (ni == ic->ic_bss) + ieee80211_unref_node(&ni); + else + ieee80211_free_node(ic, ni); } static void @@ -1808,7 +1873,7 @@ &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; @@ -2579,6 +2644,12 @@ 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++; ==== //depot/projects/netperf/sys/dev/wi/if_wi_pccard.c#2 (text+ko) ==== @@ -62,6 +62,7 @@ #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 @@ #endif #include <dev/wi/if_wavelan_ieee.h> +#include <dev/wi/if_wireg.h> #include <dev/wi/if_wivar.h> -#include <dev/wi/if_wireg.h> #ifdef WI_SYMBOL_FIRMWARE #include <dev/wi/spectrum24t_cf.h> #endif ==== //depot/projects/netperf/sys/dev/wi/if_wi_pci.c#3 (text+ko) ==== @@ -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_wireg.h> #include <dev/wi/if_wivar.h> -#include <dev/wi/if_wireg.h> static int wi_pci_probe(device_t); static int wi_pci_attach(device_t); ==== //depot/projects/netperf/sys/dev/wi/if_wireg.h#2 (text+ko) ==== @@ -679,3 +679,37 @@ */ #define WI_HFA386X_CR_A_D_TEST_MODES2 0x1A #define WI_HFA386X_CR_MANUAL_TX_POWER 0x3E + +/* + * 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; +}; ==== //depot/projects/netperf/sys/dev/wi/if_wivar.h#2 (text+ko) ==== @@ -106,7 +106,11 @@ 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 @@ 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 @@ 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200308072136.h77LaeIm020659>