MFC: update monitoring support
This commit is contained in:
parent
198715ce2a
commit
85dc376f3a
@ -2540,14 +2540,11 @@ ath_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf)
|
||||
|
||||
/*
|
||||
* Extend 15-bit time stamp from rx descriptor to
|
||||
* a full 64-bit TSF using the current h/w TSF.
|
||||
* a full 64-bit TSF using the specified TSF.
|
||||
*/
|
||||
static __inline u_int64_t
|
||||
ath_extend_tsf(struct ath_hal *ah, u_int32_t rstamp)
|
||||
ath_extend_tsf(u_int32_t rstamp, u_int64_t tsf)
|
||||
{
|
||||
u_int64_t tsf;
|
||||
|
||||
tsf = ath_hal_gettsf64(ah);
|
||||
if ((tsf & 0x7fff) < rstamp)
|
||||
tsf -= 0x8000;
|
||||
return ((tsf &~ 0x7fff) | rstamp);
|
||||
@ -2577,7 +2574,8 @@ ath_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
|
||||
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
|
||||
if (ic->ic_opmode == IEEE80211_M_IBSS &&
|
||||
ic->ic_state == IEEE80211_S_RUN) {
|
||||
u_int64_t tsf = ath_extend_tsf(sc->sc_ah, rstamp);
|
||||
u_int64_t tsf = ath_extend_tsf(rstamp,
|
||||
ath_hal_gettsf64(sc->sc_ah));
|
||||
/*
|
||||
* Handle ibss merge as needed; check the tsf on the
|
||||
* frame before attempting the merge. The 802.11 spec
|
||||
@ -2616,6 +2614,40 @@ ath_setdefantenna(struct ath_softc *sc, u_int antenna)
|
||||
sc->sc_rxotherant = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ath_rx_tap(struct ath_softc *sc, struct mbuf *m,
|
||||
const struct ath_desc *ds, u_int64_t tsf, int16_t nf)
|
||||
{
|
||||
u_int8_t rix;
|
||||
|
||||
KASSERT(sc->sc_drvbpf != NULL, ("no tap"));
|
||||
|
||||
/*
|
||||
* Discard anything shorter than an ack or cts.
|
||||
*/
|
||||
if (m->m_pkthdr.len < IEEE80211_ACK_LEN) {
|
||||
DPRINTF(sc, ATH_DEBUG_RECV, "%s: runt packet %d\n",
|
||||
__func__, m->m_pkthdr.len);
|
||||
sc->sc_stats.ast_rx_tooshort++;
|
||||
return 0;
|
||||
}
|
||||
sc->sc_rx_th.wr_tsf = htole64(
|
||||
ath_extend_tsf(ds->ds_rxstat.rs_tstamp, tsf));
|
||||
rix = ds->ds_rxstat.rs_rate;
|
||||
sc->sc_rx_th.wr_flags = sc->sc_hwmap[rix].rxflags;
|
||||
if (ds->ds_rxstat.rs_status & HAL_RXERR_CRC)
|
||||
sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
|
||||
/* XXX propagate other error flags from descriptor */
|
||||
sc->sc_rx_th.wr_rate = sc->sc_hwmap[rix].ieeerate;
|
||||
sc->sc_rx_th.wr_antsignal = ds->ds_rxstat.rs_rssi + nf;
|
||||
sc->sc_rx_th.wr_antnoise = nf;
|
||||
sc->sc_rx_th.wr_antenna = ds->ds_rxstat.rs_antenna;
|
||||
|
||||
bpf_mtap2(sc->sc_drvbpf, &sc->sc_rx_th, sc->sc_rx_th_len, m);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
ath_rx_proc(void *arg, int npending)
|
||||
{
|
||||
@ -2634,10 +2666,14 @@ ath_rx_proc(void *arg, int npending)
|
||||
int len, type;
|
||||
u_int phyerr;
|
||||
HAL_STATUS status;
|
||||
int16_t nf;
|
||||
u_int64_t tsf;
|
||||
|
||||
NET_LOCK_GIANT(); /* XXX */
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending);
|
||||
nf = ath_hal_getchannoise(ah, &sc->sc_curchan);
|
||||
tsf = ath_hal_gettsf64(ah);
|
||||
do {
|
||||
bf = STAILQ_FIRST(&sc->sc_rxbuf);
|
||||
if (bf == NULL) { /* NB: shouldn't happen */
|
||||
@ -2735,14 +2771,22 @@ ath_rx_proc(void *arg, int npending)
|
||||
}
|
||||
ifp->if_ierrors++;
|
||||
/*
|
||||
* Reject error frames, we normally don't want
|
||||
* to see them in monitor mode (in monitor mode
|
||||
* allow through packets that have crypto problems).
|
||||
* When a tap is present pass error frames
|
||||
* that have been requested. By default we
|
||||
* pass decrypt+mic errors but others may be
|
||||
* interesting (e.g. crc).
|
||||
*/
|
||||
if ((ds->ds_rxstat.rs_status &~
|
||||
(HAL_RXERR_DECRYPT|HAL_RXERR_MIC)) ||
|
||||
sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR)
|
||||
goto rx_next;
|
||||
if (sc->sc_drvbpf != NULL &&
|
||||
(ds->ds_rxstat.rs_status & sc->sc_monpass)) {
|
||||
bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
/* NB: bpf needs the mbuf length setup */
|
||||
len = ds->ds_rxstat.rs_datalen;
|
||||
m->m_pkthdr.len = m->m_len = len;
|
||||
(void) ath_rx_tap(sc, m, ds, tsf, nf);
|
||||
}
|
||||
/* XXX pass MIC errors up for s/w reclaculation */
|
||||
goto rx_next;
|
||||
}
|
||||
rx_accept:
|
||||
/*
|
||||
@ -2763,29 +2807,9 @@ rx_accept:
|
||||
|
||||
sc->sc_stats.ast_ant_rx[ds->ds_rxstat.rs_antenna]++;
|
||||
|
||||
if (sc->sc_drvbpf) {
|
||||
u_int8_t rix;
|
||||
|
||||
/*
|
||||
* Discard anything shorter than an ack or cts.
|
||||
*/
|
||||
if (len < IEEE80211_ACK_LEN) {
|
||||
DPRINTF(sc, ATH_DEBUG_RECV,
|
||||
"%s: runt packet %d\n",
|
||||
__func__, len);
|
||||
sc->sc_stats.ast_rx_tooshort++;
|
||||
m_freem(m);
|
||||
goto rx_next;
|
||||
}
|
||||
rix = ds->ds_rxstat.rs_rate;
|
||||
sc->sc_rx_th.wr_flags = sc->sc_hwmap[rix].rxflags;
|
||||
sc->sc_rx_th.wr_rate = sc->sc_hwmap[rix].ieeerate;
|
||||
sc->sc_rx_th.wr_antsignal = ds->ds_rxstat.rs_rssi;
|
||||
sc->sc_rx_th.wr_antenna = ds->ds_rxstat.rs_antenna;
|
||||
/* XXX TSF */
|
||||
|
||||
bpf_mtap2(sc->sc_drvbpf,
|
||||
&sc->sc_rx_th, sc->sc_rx_th_len, m);
|
||||
if (sc->sc_drvbpf != NULL && !ath_rx_tap(sc, m, ds, tsf, nf)) {
|
||||
m_freem(m); /* XXX reclaim */
|
||||
goto rx_next;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3442,6 +3466,9 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf
|
||||
if (ic->ic_rawbpf)
|
||||
bpf_mtap(ic->ic_rawbpf, m0);
|
||||
if (sc->sc_drvbpf) {
|
||||
u_int64_t tsf = ath_hal_gettsf64(ah);
|
||||
|
||||
sc->sc_tx_th.wt_tsf = htole64(tsf);
|
||||
sc->sc_tx_th.wt_flags = sc->sc_hwmap[txrate].txflags;
|
||||
if (iswep)
|
||||
sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
|
||||
@ -4024,6 +4051,10 @@ ath_calibrate(void *arg)
|
||||
__func__, sc->sc_curchan.channel);
|
||||
sc->sc_stats.ast_per_calfail++;
|
||||
}
|
||||
/*
|
||||
* Calibrate noise floor data again in case of change.
|
||||
*/
|
||||
ath_hal_process_noisefloor(ah);
|
||||
callout_reset(&sc->sc_cal_ch, ath_calinterval * hz, ath_calibrate, sc);
|
||||
}
|
||||
|
||||
@ -4138,6 +4169,11 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Let the hal process statistics collected during a
|
||||
* scan so it can provide calibrated noise floor data.
|
||||
*/
|
||||
ath_hal_process_noisefloor(ah);
|
||||
/*
|
||||
* Configure the beacon and sleep timers.
|
||||
*/
|
||||
@ -4861,6 +4897,10 @@ ath_sysctlattach(struct ath_softc *sc)
|
||||
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
|
||||
"tpc", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
|
||||
ath_sysctl_tpc, "I", "enable/disable per-packet TPC");
|
||||
sc->sc_monpass = HAL_RXERR_DECRYPT | HAL_RXERR_MIC;
|
||||
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
|
||||
"monpass", CTLFLAG_RW, &sc->sc_monpass, 0,
|
||||
"mask of error frames to pass when monitoring");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -128,24 +128,29 @@ struct ath_diag {
|
||||
* Radio capture format.
|
||||
*/
|
||||
#define ATH_RX_RADIOTAP_PRESENT ( \
|
||||
(1 << IEEE80211_RADIOTAP_TSFT) | \
|
||||
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
|
||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
|
||||
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
|
||||
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
|
||||
0)
|
||||
|
||||
struct ath_rx_radiotap_header {
|
||||
struct ieee80211_radiotap_header wr_ihdr;
|
||||
u_int8_t wr_flags; /* XXX for padding */
|
||||
u_int64_t wr_tsf;
|
||||
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_antenna;
|
||||
u_int8_t wr_antsignal;
|
||||
u_int8_t wr_antnoise;
|
||||
u_int8_t wr_antenna;
|
||||
};
|
||||
|
||||
#define ATH_TX_RADIOTAP_PRESENT ( \
|
||||
(1 << IEEE80211_RADIOTAP_TSFT) | \
|
||||
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||
@ -155,7 +160,8 @@ struct ath_rx_radiotap_header {
|
||||
|
||||
struct ath_tx_radiotap_header {
|
||||
struct ieee80211_radiotap_header wt_ihdr;
|
||||
u_int8_t wt_flags; /* XXX for padding */
|
||||
u_int64_t wt_tsf;
|
||||
u_int8_t wt_flags;
|
||||
u_int8_t wt_rate;
|
||||
u_int16_t wt_chan_freq;
|
||||
u_int16_t wt_chan_flags;
|
||||
|
@ -232,6 +232,7 @@ struct ath_softc {
|
||||
u_int8_t pad[64];
|
||||
} u_rx_rt;
|
||||
int sc_rx_th_len;
|
||||
u_int sc_monpass; /* frames to pass in mon.mode */
|
||||
|
||||
struct task sc_fataltask; /* fatal int processing */
|
||||
|
||||
@ -480,6 +481,15 @@ void ath_intr(void *);
|
||||
#else
|
||||
#define ath_hal_getmcastkeysearch(_ah) 0
|
||||
#endif
|
||||
#if HAL_ABI_VERSION < 0x05120700
|
||||
#define ath_hal_process_noisefloor(_ah)
|
||||
#define ath_hal_getchannoise(_ah, _c) (-96)
|
||||
#define HAL_CAP_TPC_ACK 100
|
||||
#define HAL_CAP_TPC_CTS 101
|
||||
#else
|
||||
#define ath_hal_getchannoise(_ah, _c) \
|
||||
((*(_ah)->ah_getChanNoise)((_ah), (_c)))
|
||||
#endif
|
||||
|
||||
#define ath_hal_setuprxdesc(_ah, _ds, _size, _intreq) \
|
||||
((*(_ah)->ah_setupRxDesc)((_ah), (_ds), (_size), (_intreq)))
|
||||
|
Loading…
x
Reference in New Issue
Block a user