PERFORCE change 35739 for review
Sam Leffler
sam at FreeBSD.org
Thu Aug 7 14:38:48 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=35739
Change 35739 by sam at sam_ebb on 2003/08/07 14:38:31
o record rx antenna state in driver-private node state
o revamp input path to pass (referenced) node up into the wlan layer
and to capture the rx antenna state
o add radiotap packet capture support
o delay interrupt re-enable on channel change until all state
has been changed
Affected files ...
.. //depot/projects/netperf/sys/dev/ath/if_ath.c#5 edit
.. //depot/projects/netperf/sys/dev/ath/if_athioctl.h#2 edit
.. //depot/projects/netperf/sys/dev/ath/if_athvar.h#2 edit
Differences ...
==== //depot/projects/netperf/sys/dev/ath/if_ath.c#5 (text+ko) ====
@@ -70,10 +70,6 @@
#include <net/ethernet.h>
#include <net/if_llc.h>
-#include <net80211/ieee80211.h>
-#include <net80211/ieee80211_crypto.h>
-#include <net80211/ieee80211_node.h>
-#include <net80211/ieee80211_proto.h>
#include <net80211/ieee80211_var.h>
#include <net/bpf.h>
@@ -302,6 +298,21 @@
/* complete initialization */
ieee80211_media_init(ifp, ath_media_change, ieee80211_media_status);
+ 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 = ATH_TX_RADIOTAP_PRESENT;
+
+ sc->sc_rx_th.wr_ihdr.it_len = sizeof(sc->sc_rx_th);
+ sc->sc_rx_th.wr_ihdr.it_present = ATH_RX_RADIOTAP_PRESENT;
+
if_printf(ifp, "802.11 address: %s\n", ether_sprintf(ic->ic_myaddr));
return 0;
@@ -744,6 +755,23 @@
} else
ni = ic->ic_bss;
+ if (sc->sc_drvbpf) {
+ struct mbuf *mb;
+
+ MGETHDR(mb, M_DONTWAIT, m->m_type);
+ if (mb != NULL) {
+ sc->sc_tx_th.wt_rate =
+ ni->ni_rates.rs_rates[ni->ni_txrate];
+
+ mb->m_next = m;
+ 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);
+ }
+ }
+
/*
* TODO:
* The duration field of 802.11 header should be filled.
@@ -751,12 +779,6 @@
* doesn't know the detail of parameters such as IFS
* for now..
*/
-
- if (IFF_DUMPPKTS(ifp))
- ieee80211_dump_pkt(mtod(m, u_int8_t *), m->m_len,
- ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL,
- -1);
-
if (ath_tx_start(sc, ni, bf, m)) {
bad:
mtx_lock(&sc->sc_txbuflock);
@@ -1371,7 +1393,7 @@
{
struct ath_node *an =
malloc(sizeof(struct ath_node), M_DEVBUF, M_NOWAIT | M_ZERO);
- return an ? &an->st_node : NULL;
+ return an ? &an->an_node : NULL;
}
static void
@@ -1455,11 +1477,13 @@
{
struct ath_softc *sc = arg;
struct ath_buf *bf;
- struct ifnet *ifp = &sc->sc_ic.ic_if;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
struct ath_hal *ah = sc->sc_ah;
struct ath_desc *ds;
struct mbuf *m;
struct ieee80211_frame *wh, whbuf;
+ struct ieee80211_node *ni;
int len;
u_int phyerr;
HAL_STATUS status;
@@ -1524,12 +1548,29 @@
bf->bf_m = NULL;
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = len;
- if (IFF_DUMPPKTS(ifp)) {
- struct ieee80211com *ic = &sc->sc_ic;
- const HAL_RATE_TABLE *rt = sc->sc_rates[ic->ic_curmode];
- ieee80211_dump_pkt(mtod(m, u_int8_t *), len,
- rt ? rt->info[rt->rateCodeToIndex[ds->ds_rxstat.rs_rate]].dot11Rate & IEEE80211_RATE_VAL : 0,
- ds->ds_rxstat.rs_rssi);
+
+ 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) {
+ sc->sc_rx_th.wr_rate =
+ sc->sc_hwmap[ds->ds_rxstat.rs_rate];
+ sc->sc_rx_th.wr_antsignal =
+ ds->ds_rxstat.rs_rssi;
+ sc->sc_rx_th.wr_antenna =
+ ds->ds_rxstat.rs_antenna;
+ /* XXX TSF */
+
+ (void) m_dup_pkthdr(mb, m, M_DONTWAIT);
+ mb->m_next = m;
+ 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);
+ }
}
m_adj(m, -IEEE80211_CRC_LEN);
if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
@@ -1546,10 +1587,35 @@
*/
m_adj(m, -IEEE80211_WEP_CRCLEN);
}
- ieee80211_input(ifp, m,
- ds->ds_rxstat.rs_rssi,
- ds->ds_rxstat.rs_tstamp,
- ds->ds_rxstat.rs_antenna);
+
+ /*
+ * 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 fall back 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);
+ ATH_NODE(ni)->an_rx_antenna = ds->ds_rxstat.rs_antenna;
+ /*
+ * Send frame up for processing.
+ */
+ ieee80211_input(ifp, m, ni,
+ ds->ds_rxstat.rs_rssi, ds->ds_rxstat.rs_tstamp);
+ /*
+ * 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);
rx_next:
TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
} while (ath_rxbuf_init(sc, bf) == 0);
@@ -1790,7 +1856,7 @@
if (an->an_tx_antenna)
antenna = an->an_tx_antenna;
else
- antenna = ni->ni_rantenna;
+ antenna = an->an_rx_antenna;
/*
* Formulate first tx descriptor with tx controls.
@@ -2091,9 +2157,12 @@
}
/*
- * Re-enable interrupts.
+ * Update BPF state.
*/
- ath_hal_intrset(ah, sc->sc_imask);
+ sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
+ htole16(chan->ic_freq);
+ sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
+ htole16(chan->ic_flags);
/*
* Change channels and update the h/w rate map
@@ -2103,6 +2172,11 @@
mode = ieee80211_chan2mode(ic, chan);
if (mode != sc->sc_curmode)
ath_setcurmode(sc, mode);
+
+ /*
+ * Re-enable interrupts.
+ */
+ ath_hal_intrset(ah, sc->sc_imask);
}
return 0;
}
@@ -2397,6 +2471,9 @@
KASSERT(rt != NULL, ("no h/w rate set for phy mode %u", mode));
for (i = 0; i < rt->rateCount; i++)
sc->sc_rixmap[rt->info[i].dot11Rate & IEEE80211_RATE_VAL] = i;
+ memset(sc->sc_hwmap, 0, sizeof(sc->sc_hwmap));
+ for (i = 0; i < 32; i++)
+ sc->sc_hwmap[i] = rt->info[rt->rateCodeToIndex[i]].dot11Rate;
sc->sc_currates = rt;
sc->sc_curmode = mode;
}
==== //depot/projects/netperf/sys/dev/ath/if_athioctl.h#2 (text+ko) ====
@@ -90,4 +90,39 @@
#define SIOCGATHSTATS _IOWR('i', 137, struct ifreq)
+/*
+ * Radio capture format.
+ */
+#define ATH_RX_RADIOTAP_PRESENT ( \
+ (1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
+ (1 << IEEE80211_RADIOTAP_CHANNEL) | \
+ (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
+ (1 << IEEE80211_RADIOTAP_ANTENNA) | \
+ 0)
+
+struct ath_rx_radiotap_header {
+ struct ieee80211_radiotap_header wr_ihdr;
+ u_int8_t wr_flags; /* XXX for padding */
+ 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_antenna;
+};
+
+#define ATH_TX_RADIOTAP_PRESENT ( \
+ (1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
+ (1 << IEEE80211_RADIOTAP_CHANNEL) | \
+ 0)
+
+struct ath_tx_radiotap_header {
+ struct ieee80211_radiotap_header wt_ihdr;
+ u_int8_t wt_flags; /* XXX for padding */
+ u_int8_t wt_rate;
+ u_int16_t wt_chan_freq;
+ u_int16_t wt_chan_flags;
+};
+
#endif /* _DEV_ATH_ATHIOCTL_H */
==== //depot/projects/netperf/sys/dev/ath/if_athvar.h#2 (text+ko) ====
@@ -45,6 +45,7 @@
#include <sys/taskqueue.h>
#include <contrib/dev/ath/ah.h>
+#include <net80211/ieee80211_radiotap.h>
#include <dev/ath/if_athioctl.h>
#define ATH_TIMEOUT 1000
@@ -55,13 +56,15 @@
/* driver-specific node */
struct ath_node {
- struct ieee80211_node st_node; /* base class */
+ struct ieee80211_node an_node; /* base class */
u_int an_tx_ok; /* tx ok pkt */
u_int an_tx_err; /* tx !ok pkt */
u_int an_tx_retr; /* tx retry count */
int an_tx_upper; /* tx upper rate req cnt */
u_int an_tx_antenna; /* antenna for last good frame */
+ u_int an_rx_antenna; /* antenna for last rcvd frame */
};
+#define ATH_NODE(_n) ((struct ath_node *)(_n))
struct ath_buf {
TAILQ_ENTRY(ath_buf) bf_list;
@@ -95,8 +98,19 @@
const HAL_RATE_TABLE *sc_currates; /* current rate table */
enum ieee80211_phymode sc_curmode; /* current phy mode */
u_int8_t sc_rixmap[256]; /* IEEE to h/w rate table ix */
+ u_int8_t sc_hwmap[32]; /* h/w rate ix to IEEE table */
HAL_INT sc_imask; /* interrupt mask copy */
+ struct bpf_if *sc_drvbpf;
+ union {
+ struct ath_tx_radiotap_header th;
+ u_int8_t pad[64];
+ } u_tx_rt;
+ union {
+ struct ath_rx_radiotap_header th;
+ u_int8_t pad[64];
+ } u_rx_rt;
+
struct ath_desc *sc_desc; /* TX/RX descriptors */
bus_dma_segment_t sc_dseg;
bus_dmamap_t sc_ddmamap; /* DMA map for descriptors */
@@ -129,6 +143,8 @@
struct callout sc_scan_ch; /* callout handle for scan */
struct ath_stats sc_stats; /* interface statistics */
};
+#define sc_tx_th u_tx_rt.th
+#define sc_rx_th u_rx_rt.th
int ath_attach(u_int16_t, struct ath_softc *);
int ath_detach(struct ath_softc *);
More information about the p4-projects
mailing list