commit 11669f3f3189da8e2598eb6cd580ff3d06796e17 Author: Jiri Slaby Date: Wed Jul 25 09:06:10 2007 +0200 MONITOR mode diff --git a/ath.c b/ath.c index 686d850..e4c79ba 100644 --- a/ath.c +++ b/ath.c @@ -61,6 +61,7 @@ DPRINTF(struct ath_softc *sc, unsigned int m, const char *fmt, ...) } #endif enum { + ATH_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ ATH_DEBUG_RESET = 0x00000020, /* reset processing */ ATH_DEBUG_MODE = 0x00000040, /* mode init/setup */ ATH_DEBUG_BEACON = 0x00000080, /* beacon handling */ @@ -343,6 +344,16 @@ static unsigned int ath_rx_decrypted(struct ath_softc *sc, return 0; } +static inline u64 ath_extend_tsf(struct ath_hw *ah, u32 rstamp) +{ + u64 tsf = ath5k_hw_get_tsf64(ah); + + if ((tsf & 0x7fff) < rstamp) + tsf -= 0x8000; + + return (tsf &~ 0x7fff) | rstamp; +} + static void ath_tasklet_rx(unsigned long data) { struct ieee80211_rx_status rxs = {}; @@ -424,7 +435,10 @@ static void ath_tasklet_rx(unsigned long data) goto accept; } - goto next; + /* let crypto-error packets fall through in MNTR */ + if ((stat &~ (AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || + sc->opmode != IEEE80211_IF_TYPE_MNTR) + goto next; } accept: len = ds->ds_rxstat.rs_datalen; @@ -441,7 +455,11 @@ accept: sc->stats.ast_ant_rx[ds->ds_rxstat.rs_antenna]++; - rxs.mactime = ds->ds_rxstat.rs_tstamp; + if (sc->opmode == IEEE80211_IF_TYPE_MNTR) + rxs.mactime = ath_extend_tsf(sc->ah, + ds->ds_rxstat.rs_tstamp); + else + rxs.mactime = ds->ds_rxstat.rs_tstamp; rxs.freq = sc->curchan->freq; rxs.channel = sc->curchan->chan; rxs.phymode = sc->curmode; @@ -729,6 +747,9 @@ static u32 ath_calcrxfilter(struct ath_softc *sc) AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST | AR5K_RX_FILTER_MCAST | AR5K_RX_FILTER_RADARERR; + if (sc->opmode == IEEE80211_IF_TYPE_MNTR) + rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON | + AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM; if (opmode != IEEE80211_IF_TYPE_STA) rfilt |= AR5K_RX_FILTER_PROBEREQ; if (opmode != IEEE80211_IF_TYPE_AP && sc->promisc) @@ -1235,6 +1256,9 @@ static int ath_tx(struct ieee80211_hw *hw, struct sk_buff *skb, ath_dump_skb(skb, "t"); + if (sc->opmode == IEEE80211_IF_TYPE_MNTR) + DPRINTF(sc, ATH_DEBUG_XMIT, "tx in monitor (scan?)\n"); + sc->led_txrate = ctl->tx_rate; spin_lock_irqsave(&sc->txbuflock, flags); @@ -1343,6 +1367,7 @@ static int ath_add_interface(struct ieee80211_hw *hw, switch (conf->type) { case IEEE80211_IF_TYPE_STA: case IEEE80211_IF_TYPE_IBSS: + case IEEE80211_IF_TYPE_MNTR: sc->opmode = conf->type; break; default: