summaryrefslogtreecommitdiffstats
path: root/sys/dev/ath/if_ath_rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ath/if_ath_rx.c')
-rw-r--r--sys/dev/ath/if_ath_rx.c250
1 files changed, 21 insertions, 229 deletions
diff --git a/sys/dev/ath/if_ath_rx.c b/sys/dev/ath/if_ath_rx.c
index bed9488..d9e212b 100644
--- a/sys/dev/ath/if_ath_rx.c
+++ b/sys/dev/ath/if_ath_rx.c
@@ -73,7 +73,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <net/if.h>
-#include <net/if_var.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/if_types.h>
@@ -166,22 +165,10 @@ ath_calcrxfilter(struct ath_softc *sc)
/* XXX ic->ic_monvaps != 0? */
if (ic->ic_opmode == IEEE80211_M_MONITOR || (ifp->if_flags & IFF_PROMISC))
rfilt |= HAL_RX_FILTER_PROM;
-
- /*
- * Only listen to all beacons if we're scanning.
- *
- * Otherwise we only really need to hear beacons from
- * our own BSSID.
- */
if (ic->ic_opmode == IEEE80211_M_STA ||
- ic->ic_opmode == IEEE80211_M_IBSS || sc->sc_swbmiss) {
- if (sc->sc_do_mybeacon && ! sc->sc_scanning) {
- rfilt |= HAL_RX_FILTER_MYBEACON;
- } else { /* scanning, non-mybeacon chips */
- rfilt |= HAL_RX_FILTER_BEACON;
- }
- }
-
+ ic->ic_opmode == IEEE80211_M_IBSS ||
+ sc->sc_swbmiss || sc->sc_scanning)
+ rfilt |= HAL_RX_FILTER_BEACON;
/*
* NB: We don't recalculate the rx filter when
* ic_protmode changes; otherwise we could do
@@ -245,8 +232,6 @@ ath_legacy_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf)
struct mbuf *m;
struct ath_desc *ds;
- /* XXX TODO: ATH_RX_LOCK_ASSERT(sc); */
-
m = bf->bf_m;
if (m == NULL) {
/*
@@ -331,23 +316,6 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
{
struct ieee80211vap *vap = ni->ni_vap;
struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
- uint64_t tsf_beacon_old, tsf_beacon;
- uint64_t nexttbtt;
- int64_t tsf_delta;
- int32_t tsf_delta_bmiss;
- int32_t tsf_remainder;
- uint64_t tsf_beacon_target;
- int tsf_intval;
-
- tsf_beacon_old = ((uint64_t) LE_READ_4(ni->ni_tstamp.data + 4)) << 32;
- tsf_beacon_old |= LE_READ_4(ni->ni_tstamp.data);
-
-#define TU_TO_TSF(_tu) (((u_int64_t)(_tu)) << 10)
- tsf_intval = 1;
- if (ni->ni_intval > 0) {
- tsf_intval = TU_TO_TSF(ni->ni_intval);
- }
-#undef TU_TO_TSF
/*
* Call up first so subsequent work can use information
@@ -359,79 +327,14 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
/* update rssi statistics for use by the hal */
/* XXX unlocked check against vap->iv_bss? */
ATH_RSSI_LPF(sc->sc_halstats.ns_avgbrssi, rssi);
-
- tsf_beacon = ((uint64_t) LE_READ_4(ni->ni_tstamp.data + 4)) << 32;
- tsf_beacon |= LE_READ_4(ni->ni_tstamp.data);
-
- nexttbtt = ath_hal_getnexttbtt(sc->sc_ah);
-
- /*
- * Let's calculate the delta and remainder, so we can see
- * if the beacon timer from the AP is varying by more than
- * a few TU. (Which would be a huge, huge problem.)
- */
- tsf_delta = (long long) tsf_beacon - (long long) tsf_beacon_old;
-
- tsf_delta_bmiss = tsf_delta / tsf_intval;
-
- /*
- * If our delta is greater than half the beacon interval,
- * let's round the bmiss value up to the next beacon
- * interval. Ie, we're running really, really early
- * on the next beacon.
- */
- if (tsf_delta % tsf_intval > (tsf_intval / 2))
- tsf_delta_bmiss ++;
-
- tsf_beacon_target = tsf_beacon_old +
- (((unsigned long long) tsf_delta_bmiss) * (long long) tsf_intval);
-
- /*
- * The remainder using '%' is between 0 .. intval-1.
- * If we're actually running too fast, then the remainder
- * will be some large number just under intval-1.
- * So we need to look at whether we're running
- * before or after the target beacon interval
- * and if we are, modify how we do the remainder
- * calculation.
- */
- if (tsf_beacon < tsf_beacon_target) {
- tsf_remainder =
- -(tsf_intval - ((tsf_beacon - tsf_beacon_old) % tsf_intval));
- } else {
- tsf_remainder = (tsf_beacon - tsf_beacon_old) % tsf_intval;
- }
-
- DPRINTF(sc, ATH_DEBUG_BEACON, "%s: old_tsf=%llu, new_tsf=%llu, target_tsf=%llu, delta=%lld, bmiss=%d, remainder=%d\n",
- __func__,
- (unsigned long long) tsf_beacon_old,
- (unsigned long long) tsf_beacon,
- (unsigned long long) tsf_beacon_target,
- (long long) tsf_delta,
- tsf_delta_bmiss,
- tsf_remainder);
-
- DPRINTF(sc, ATH_DEBUG_BEACON, "%s: tsf=%llu, nexttbtt=%llu, delta=%d\n",
- __func__,
- (unsigned long long) tsf_beacon,
- (unsigned long long) nexttbtt,
- (int32_t) tsf_beacon - (int32_t) nexttbtt + tsf_intval);
-
if (sc->sc_syncbeacon &&
- ni == vap->iv_bss &&
- (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP)) {
- DPRINTF(sc, ATH_DEBUG_BEACON,
- "%s: syncbeacon=1; syncing\n",
- __func__);
+ ni == vap->iv_bss && vap->iv_state == IEEE80211_S_RUN) {
/*
* Resync beacon timers using the tsf of the beacon
* frame we just received.
*/
ath_beacon_config(sc, vap);
- sc->sc_syncbeacon = 0;
}
-
-
/* fall thru... */
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
if (vap->iv_opmode == IEEE80211_M_IBSS &&
@@ -704,7 +607,7 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status,
rs->rs_keyix-32 : rs->rs_keyix);
}
}
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ ifp->if_ierrors++;
rx_error:
/*
* Cleanup any pending partial frame.
@@ -830,7 +733,7 @@ rx_accept:
rs->rs_antenna |= 0x4;
}
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
+ ifp->if_ipackets++;
sc->sc_stats.ast_ant_rx[rs->rs_antenna]++;
/*
@@ -976,14 +879,6 @@ rx_next:
#define ATH_RX_MAX 128
-/*
- * XXX TODO: break out the "get buffers" from "call ath_rx_pkt()" like
- * the EDMA code does.
- *
- * XXX TODO: then, do all of the RX list management stuff inside
- * ATH_RX_LOCK() so we don't end up potentially racing. The EDMA
- * code is doing it right.
- */
static void
ath_rx_proc(struct ath_softc *sc, int resched)
{
@@ -1005,7 +900,6 @@ ath_rx_proc(struct ath_softc *sc, int resched)
u_int64_t tsf;
int npkts = 0;
int kickpcu = 0;
- int ret;
/* XXX we must not hold the ATH_LOCK here */
ATH_UNLOCK_ASSERT(sc);
@@ -1016,10 +910,6 @@ ath_rx_proc(struct ath_softc *sc, int resched)
kickpcu = sc->sc_kickpcu;
ATH_PCU_UNLOCK(sc);
- ATH_LOCK(sc);
- ath_power_set_power_state(sc, HAL_PM_AWAKE);
- ATH_UNLOCK(sc);
-
DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: called\n", __func__);
ngood = 0;
nf = ath_hal_getchannoise(ah, sc->sc_curchan);
@@ -1105,26 +995,8 @@ ath_rx_proc(struct ath_softc *sc, int resched)
if (ath_rx_pkt(sc, rs, status, tsf, nf, HAL_RX_QUEUE_HP, bf, m))
ngood++;
rx_proc_next:
- /*
- * If there's a holding buffer, insert that onto
- * the RX list; the hardware is now definitely not pointing
- * to it now.
- */
- ret = 0;
- if (sc->sc_rxedma[HAL_RX_QUEUE_HP].m_holdbf != NULL) {
- TAILQ_INSERT_TAIL(&sc->sc_rxbuf,
- sc->sc_rxedma[HAL_RX_QUEUE_HP].m_holdbf,
- bf_list);
- ret = ath_rxbuf_init(sc,
- sc->sc_rxedma[HAL_RX_QUEUE_HP].m_holdbf);
- }
- /*
- * Next, throw our buffer into the holding entry. The hardware
- * may use the descriptor to read the link pointer before
- * DMAing the next descriptor in to write out a packet.
- */
- sc->sc_rxedma[HAL_RX_QUEUE_HP].m_holdbf = bf;
- } while (ret == 0);
+ TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
+ } while (ath_rxbuf_init(sc, bf) == 0);
/* rx signal state monitoring */
ath_hal_rxmonitor(ah, &sc->sc_halstats, sc->sc_curchan);
@@ -1156,13 +1028,6 @@ rx_proc_next:
* constantly write over the same frame, leading
* the RX driver code here to get heavily confused.
*/
- /*
- * XXX Has RX DMA stopped enough here to just call
- * ath_startrecv()?
- * XXX Do we need to use the holding buffer to restart
- * RX DMA by appending entries to the final
- * descriptor? Quite likely.
- */
#if 1
ath_startrecv(sc);
#else
@@ -1200,13 +1065,6 @@ rx_proc_next:
#undef PA2DESC
/*
- * Put the hardware to sleep again if we're done with it.
- */
- ATH_LOCK(sc);
- ath_power_restore_power_state(sc);
- ATH_UNLOCK(sc);
-
- /*
* If we hit the maximum number of frames in this round,
* reschedule for another immediate pass. This gives
* the TX and TX completion routines time to run, which
@@ -1253,58 +1111,6 @@ ath_legacy_flushrecv(struct ath_softc *sc)
ath_rx_proc(sc, 0);
}
-static void
-ath_legacy_flush_rxpending(struct ath_softc *sc)
-{
-
- /* XXX ATH_RX_LOCK_ASSERT(sc); */
-
- if (sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending != NULL) {
- m_freem(sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending);
- sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending = NULL;
- }
- if (sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending != NULL) {
- m_freem(sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending);
- sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending = NULL;
- }
-}
-
-static int
-ath_legacy_flush_rxholdbf(struct ath_softc *sc)
-{
- struct ath_buf *bf;
-
- /* XXX ATH_RX_LOCK_ASSERT(sc); */
- /*
- * If there are RX holding buffers, free them here and return
- * them to the list.
- *
- * XXX should just verify that bf->bf_m is NULL, as it must
- * be at this point!
- */
- bf = sc->sc_rxedma[HAL_RX_QUEUE_HP].m_holdbf;
- if (bf != NULL) {
- if (bf->bf_m != NULL)
- m_freem(bf->bf_m);
- bf->bf_m = NULL;
- TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
- (void) ath_rxbuf_init(sc, bf);
- }
- sc->sc_rxedma[HAL_RX_QUEUE_HP].m_holdbf = NULL;
-
- bf = sc->sc_rxedma[HAL_RX_QUEUE_LP].m_holdbf;
- if (bf != NULL) {
- if (bf->bf_m != NULL)
- m_freem(bf->bf_m);
- bf->bf_m = NULL;
- TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
- (void) ath_rxbuf_init(sc, bf);
- }
- sc->sc_rxedma[HAL_RX_QUEUE_LP].m_holdbf = NULL;
-
- return (0);
-}
-
/*
* Disable the receive h/w in preparation for a reset.
*/
@@ -1316,8 +1122,6 @@ ath_legacy_stoprecv(struct ath_softc *sc, int dodelay)
((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
struct ath_hal *ah = sc->sc_ah;
- ATH_RX_LOCK(sc);
-
ath_hal_stoppcurecv(ah); /* disable PCU */
ath_hal_setrxfilter(ah, 0); /* clear recv filter */
ath_hal_stopdmarecv(ah); /* disable DMA engine */
@@ -1351,23 +1155,22 @@ ath_legacy_stoprecv(struct ath_softc *sc, int dodelay)
}
}
#endif
-
- (void) ath_legacy_flush_rxpending(sc);
- (void) ath_legacy_flush_rxholdbf(sc);
-
+ /*
+ * Free both high/low RX pending, just in case.
+ */
+ if (sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending != NULL) {
+ m_freem(sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending);
+ sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending = NULL;
+ }
+ if (sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending != NULL) {
+ m_freem(sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending);
+ sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending = NULL;
+ }
sc->sc_rxlink = NULL; /* just in case */
-
- ATH_RX_UNLOCK(sc);
#undef PA2DESC
}
/*
- * XXX TODO: something was calling startrecv without calling
- * stoprecv. Let's figure out what/why. It was showing up
- * as a mbuf leak (rxpending) and ath_buf leak (holdbf.)
- */
-
-/*
* Enable the receive h/w following a reset.
*/
static int
@@ -1376,18 +1179,9 @@ ath_legacy_startrecv(struct ath_softc *sc)
struct ath_hal *ah = sc->sc_ah;
struct ath_buf *bf;
- ATH_RX_LOCK(sc);
-
- /*
- * XXX should verify these are already all NULL!
- */
sc->sc_rxlink = NULL;
- (void) ath_legacy_flush_rxpending(sc);
- (void) ath_legacy_flush_rxholdbf(sc);
-
- /*
- * Re-chain all of the buffers in the RX buffer list.
- */
+ sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending = NULL;
+ sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending = NULL;
TAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
int error = ath_rxbuf_init(sc, bf);
if (error != 0) {
@@ -1403,8 +1197,6 @@ ath_legacy_startrecv(struct ath_softc *sc)
ath_hal_rxena(ah); /* enable recv descriptors */
ath_mode_init(sc); /* set filters, etc. */
ath_hal_startpcurecv(ah); /* re-enable PCU/DMA engine */
-
- ATH_RX_UNLOCK(sc);
return 0;
}
OpenPOWER on IntegriCloud