38c38
< __FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 155491 2006-02-09 21:48:51Z sam $");
---
> __FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 155492 2006-02-09 22:03:26Z sam $");
834a835,844
> u_int64_t lastrx = sc->sc_lastrx;
> u_int64_t tsf = ath_hal_gettsf64(sc->sc_ah);
> u_int bmisstimeout =
> ic->ic_bmissthreshold * ic->ic_bss->ni_intval * 1024;
>
> DPRINTF(sc, ATH_DEBUG_BEACON,
> "%s: tsf %llu lastrx %lld (%llu) bmiss %u\n",
> __func__, (unsigned long long) tsf,
> (unsigned long long)(tsf - lastrx),
> (unsigned long long) lastrx, bmisstimeout);
836,839c846,850
< * Rather than go directly to scan state, try to
< * reassociate first. If that fails then the state
< * machine will drop us into scanning after timing
< * out waiting for a probe response.
---
> * Workaround phantom bmiss interrupts by sanity-checking
> * the time of our last rx'd frame. If it is within the
> * beacon miss interval then ignore the interrupt. If it's
> * truly a bmiss we'll get another interrupt soon and that'll
> * be dispatched up for processing.
841,843c852,857
< NET_LOCK_GIANT();
< ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
< NET_UNLOCK_GIANT();
---
> if (tsf - lastrx > bmisstimeout) {
> NET_LOCK_GIANT();
> ieee80211_beacon_miss(ic);
> NET_UNLOCK_GIANT();
> } else
> sc->sc_stats.ast_bmiss_phantom++;
2711c2725
< int len, type;
---
> int len, type, ngood;
2719a2734
> ngood = 0;
2926a2942,2949
> /*
> * Arrange to update the last rx timestamp only for
> * frames from our ap when operating in station mode.
> * This assumes the rx key is always setup when associated.
> */
> if (ic->ic_opmode == IEEE80211_M_STA &&
> ds->ds_rxstat.rs_keyix != HAL_RXKEYIX_INVALID)
> ngood++;
2932a2956,2957
> if (ngood)
> sc->sc_lastrx = tsf;
3669c3694
< static void
---
> static int
3678c3703
< int sr, lr, pri;
---
> int sr, lr, pri, nacked;
3684a3710
> nacked = 0;
3741c3767,3773
< (bf->bf_flags & HAL_TXDESC_NOACK) == 0)
---
> (bf->bf_flags & HAL_TXDESC_NOACK) == 0) {
> /*
> * If frame was ack'd update the last rx time
> * used to workaround phantom bmiss interrupts.
> */
> if (ds->ds_txstat.ts_status == 0)
> nacked++;
3742a3775
> }
3762a3796
> return nacked;
3764a3799,3805
> static __inline int
> txqactive(struct ath_hal *ah, int qnum)
> {
> /* XXX not yet */
> return 1;
> }
>
3775c3816,3819
< ath_tx_processq(sc, &sc->sc_txq[0]);
---
> if (txqactive(sc->sc_ah, 0) && ath_tx_processq(sc, &sc->sc_txq[0]))
> sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah);
> if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum))
> ath_tx_processq(sc, sc->sc_cabq);
3794a3839
> int nacked;
3799,3803c3844,3856
< ath_tx_processq(sc, &sc->sc_txq[0]);
< ath_tx_processq(sc, &sc->sc_txq[1]);
< ath_tx_processq(sc, &sc->sc_txq[2]);
< ath_tx_processq(sc, &sc->sc_txq[3]);
< ath_tx_processq(sc, sc->sc_cabq);
---
> nacked = 0;
> if (txqactive(sc->sc_ah, 0))
> nacked += ath_tx_processq(sc, &sc->sc_txq[0]);
> if (txqactive(sc->sc_ah, 1))
> nacked += ath_tx_processq(sc, &sc->sc_txq[1]);
> if (txqactive(sc->sc_ah, 2))
> nacked += ath_tx_processq(sc, &sc->sc_txq[2]);
> if (txqactive(sc->sc_ah, 3))
> nacked += ath_tx_processq(sc, &sc->sc_txq[3]);
> if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum))
> ath_tx_processq(sc, sc->sc_cabq);
> if (nacked)
> sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah);
3822c3875
< int i;
---
> int i, nacked;
3827c3880
< /* XXX faster to read ISR_S0_S and ISR_S1_S to determine q's? */
---
> nacked = 0;
3829,3830c3882,3885
< if (ATH_TXQ_SETUP(sc, i))
< ath_tx_processq(sc, &sc->sc_txq[i]);
---
> if (ATH_TXQ_SETUP(sc, i) && txqactive(sc->sc_ah, i))
> nacked += ath_tx_processq(sc, &sc->sc_txq[i]);
> if (nacked)
> sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah);
< __FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 155491 2006-02-09 21:48:51Z sam $");
---
> __FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 155492 2006-02-09 22:03:26Z sam $");
834a835,844
> u_int64_t lastrx = sc->sc_lastrx;
> u_int64_t tsf = ath_hal_gettsf64(sc->sc_ah);
> u_int bmisstimeout =
> ic->ic_bmissthreshold * ic->ic_bss->ni_intval * 1024;
>
> DPRINTF(sc, ATH_DEBUG_BEACON,
> "%s: tsf %llu lastrx %lld (%llu) bmiss %u\n",
> __func__, (unsigned long long) tsf,
> (unsigned long long)(tsf - lastrx),
> (unsigned long long) lastrx, bmisstimeout);
836,839c846,850
< * Rather than go directly to scan state, try to
< * reassociate first. If that fails then the state
< * machine will drop us into scanning after timing
< * out waiting for a probe response.
---
> * Workaround phantom bmiss interrupts by sanity-checking
> * the time of our last rx'd frame. If it is within the
> * beacon miss interval then ignore the interrupt. If it's
> * truly a bmiss we'll get another interrupt soon and that'll
> * be dispatched up for processing.
841,843c852,857
< NET_LOCK_GIANT();
< ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
< NET_UNLOCK_GIANT();
---
> if (tsf - lastrx > bmisstimeout) {
> NET_LOCK_GIANT();
> ieee80211_beacon_miss(ic);
> NET_UNLOCK_GIANT();
> } else
> sc->sc_stats.ast_bmiss_phantom++;
2711c2725
< int len, type;
---
> int len, type, ngood;
2719a2734
> ngood = 0;
2926a2942,2949
> /*
> * Arrange to update the last rx timestamp only for
> * frames from our ap when operating in station mode.
> * This assumes the rx key is always setup when associated.
> */
> if (ic->ic_opmode == IEEE80211_M_STA &&
> ds->ds_rxstat.rs_keyix != HAL_RXKEYIX_INVALID)
> ngood++;
2932a2956,2957
> if (ngood)
> sc->sc_lastrx = tsf;
3669c3694
< static void
---
> static int
3678c3703
< int sr, lr, pri;
---
> int sr, lr, pri, nacked;
3684a3710
> nacked = 0;
3741c3767,3773
< (bf->bf_flags & HAL_TXDESC_NOACK) == 0)
---
> (bf->bf_flags & HAL_TXDESC_NOACK) == 0) {
> /*
> * If frame was ack'd update the last rx time
> * used to workaround phantom bmiss interrupts.
> */
> if (ds->ds_txstat.ts_status == 0)
> nacked++;
3742a3775
> }
3762a3796
> return nacked;
3764a3799,3805
> static __inline int
> txqactive(struct ath_hal *ah, int qnum)
> {
> /* XXX not yet */
> return 1;
> }
>
3775c3816,3819
< ath_tx_processq(sc, &sc->sc_txq[0]);
---
> if (txqactive(sc->sc_ah, 0) && ath_tx_processq(sc, &sc->sc_txq[0]))
> sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah);
> if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum))
> ath_tx_processq(sc, sc->sc_cabq);
3794a3839
> int nacked;
3799,3803c3844,3856
< ath_tx_processq(sc, &sc->sc_txq[0]);
< ath_tx_processq(sc, &sc->sc_txq[1]);
< ath_tx_processq(sc, &sc->sc_txq[2]);
< ath_tx_processq(sc, &sc->sc_txq[3]);
< ath_tx_processq(sc, sc->sc_cabq);
---
> nacked = 0;
> if (txqactive(sc->sc_ah, 0))
> nacked += ath_tx_processq(sc, &sc->sc_txq[0]);
> if (txqactive(sc->sc_ah, 1))
> nacked += ath_tx_processq(sc, &sc->sc_txq[1]);
> if (txqactive(sc->sc_ah, 2))
> nacked += ath_tx_processq(sc, &sc->sc_txq[2]);
> if (txqactive(sc->sc_ah, 3))
> nacked += ath_tx_processq(sc, &sc->sc_txq[3]);
> if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum))
> ath_tx_processq(sc, sc->sc_cabq);
> if (nacked)
> sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah);
3822c3875
< int i;
---
> int i, nacked;
3827c3880
< /* XXX faster to read ISR_S0_S and ISR_S1_S to determine q's? */
---
> nacked = 0;
3829,3830c3882,3885
< if (ATH_TXQ_SETUP(sc, i))
< ath_tx_processq(sc, &sc->sc_txq[i]);
---
> if (ATH_TXQ_SETUP(sc, i) && txqactive(sc->sc_ah, i))
> nacked += ath_tx_processq(sc, &sc->sc_txq[i]);
> if (nacked)
> sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah);