diff options
Diffstat (limited to 'sys/dev/ath/if_ath_rx.c')
-rw-r--r-- | sys/dev/ath/if_ath_rx.c | 250 |
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; } |