From 353d29772b7685686172f330219b825d464fff51 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Wed, 28 Sep 2011 03:05:04 +0000 Subject: [PATCH] Change the default CABQ time to be 70% of the beacon interval, rather than the whole beacon interval. The reference driver and Linux ath9k both choose 80% of the beacon interval and they do it in the driver rather than the HAL (Ath reference) or ath9k_hw (ath9k.) This quietens stuck beacon conditions on my AR9220/AR9280 based NICs when a lot of burst broadcast/multicast traffic is going on. It doesn't seem to annoy the earlier MACs as much as the AR9280 and later one. Obtained from: Linux ath9k, Atheros --- sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c | 37 +++++++++++++++--- sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c | 49 +++++++++++++++++++----- 2 files changed, 71 insertions(+), 15 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c b/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c index 3c6ddc0035fe..fa0e883d2211 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c @@ -263,6 +263,7 @@ ar5212ReleaseTxQueue(struct ath_hal *ah, u_int q) * Assumes: * phwChannel has been set to point to the current channel */ +#define TU_TO_USEC(_tu) ((_tu) << 10) HAL_BOOL ar5212ResetTxQueue(struct ath_hal *ah, u_int q) { @@ -270,7 +271,7 @@ ar5212ResetTxQueue(struct ath_hal *ah, u_int q) HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan; HAL_TX_QUEUE_INFO *qi; - uint32_t cwMin, chanCwMin, value, qmisc, dmisc; + uint32_t cwMin, chanCwMin, qmisc, dmisc; if (q >= pCap->halTotalQueues) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n", @@ -409,17 +410,40 @@ ar5212ResetTxQueue(struct ath_hal *ah, u_int q) | AR_Q_MISC_CBR_INCR_DIS1 | AR_Q_MISC_CBR_INCR_DIS0; - if (!qi->tqi_readyTime) { + if (qi->tqi_readyTime) { + HALDEBUG(ah, HAL_DEBUG_TXQUEUE, + "%s: using tqi_readyTime\n", __func__); + OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), + SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_INT) | + AR_Q_RDYTIMECFG_ENA); + } else { + int value; /* * NB: don't set default ready time if driver * has explicitly specified something. This is * here solely for backwards compatibility. */ - value = (ahp->ah_beaconInterval + /* + * XXX for now, hard-code a CAB interval of 70% + * XXX of the total beacon interval. + */ + + value = (ahp->ah_beaconInterval * 70 / 100) - (ah->ah_config.ah_sw_beacon_response_time - - ah->ah_config.ah_dma_beacon_response_time) - - ah->ah_config.ah_additional_swba_backoff) * 1024; - OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), value | AR_Q_RDYTIMECFG_ENA); + + ah->ah_config.ah_dma_beacon_response_time) + - ah->ah_config.ah_additional_swba_backoff; + /* + * XXX Ensure it isn't too low - nothing lower + * XXX than 10 TU + */ + if (value < 10) + value = 10; + HALDEBUG(ah, HAL_DEBUG_TXQUEUE, + "%s: defaulting to rdytime = %d uS\n", + __func__, value); + OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), + SM(TU_TO_USEC(value), AR_Q_RDYTIMECFG_INT) | + AR_Q_RDYTIMECFG_ENA); } dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, AR_D_MISC_ARB_LOCKOUT_CNTRL); @@ -481,6 +505,7 @@ ar5212ResetTxQueue(struct ath_hal *ah, u_int q) return AH_TRUE; } +#undef TU_TO_USEC /* * Get the TXDP for the specified queue diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c index 20791e8a5a50..3341b522bc6d 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c @@ -879,6 +879,7 @@ setTxQInterrupts(struct ath_hal *ah, HAL_TX_QUEUE_INFO *qi) * Assumes: * phwChannel has been set to point to the current channel */ +#define TU_TO_USEC(_tu) ((_tu) << 10) HAL_BOOL ar5416ResetTxQueue(struct ath_hal *ah, u_int q) { @@ -886,7 +887,7 @@ ar5416ResetTxQueue(struct ath_hal *ah, u_int q) HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan; HAL_TX_QUEUE_INFO *qi; - uint32_t cwMin, chanCwMin, value, qmisc, dmisc; + uint32_t cwMin, chanCwMin, qmisc, dmisc; if (q >= pCap->halTotalQueues) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n", @@ -956,7 +957,8 @@ ar5416ResetTxQueue(struct ath_hal *ah, u_int q) if (qi->tqi_cbrOverflowLimit) qmisc |= AR_Q_MISC_CBR_EXP_CNTR_LIMIT; } - if (qi->tqi_readyTime) { + + if (qi->tqi_readyTime && (qi->tqi_type != HAL_TX_QUEUE_CAB)) { OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_INT) | AR_Q_RDYTIMECFG_ENA); @@ -1027,18 +1029,46 @@ ar5416ResetTxQueue(struct ath_hal *ah, u_int q) qmisc |= AR_Q_MISC_FSP_DBA_GATED | AR_Q_MISC_CBR_INCR_DIS1 | AR_Q_MISC_CBR_INCR_DIS0; - - if (!qi->tqi_readyTime) { + HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: CAB: tqi_readyTime = %d\n", + __func__, qi->tqi_readyTime); + if (qi->tqi_readyTime) { + HALDEBUG(ah, HAL_DEBUG_TXQUEUE, + "%s: using tqi_readyTime\n", __func__); + OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), + SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_INT) | + AR_Q_RDYTIMECFG_ENA); + } else { + int value; /* * NB: don't set default ready time if driver * has explicitly specified something. This is * here solely for backwards compatibility. */ - value = (ahp->ah_beaconInterval - - (ah->ah_config.ah_sw_beacon_response_time - - ah->ah_config.ah_dma_beacon_response_time) - - ah->ah_config.ah_additional_swba_backoff) * 1024; - OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), value | AR_Q_RDYTIMECFG_ENA); + /* + * XXX for now, hard-code a CAB interval of 70% + * XXX of the total beacon interval. + * + * XXX This keeps Merlin and later based MACs + * XXX quite a bit happier (stops stuck beacons, + * XXX which I gather is because of such a long + * XXX cabq time.) + */ + value = (ahp->ah_beaconInterval * 70 / 100) + - (ah->ah_config.ah_sw_beacon_response_time + + ah->ah_config.ah_dma_beacon_response_time) + - ah->ah_config.ah_additional_swba_backoff; + /* + * XXX Ensure it isn't too low - nothing lower + * XXX than 10 TU + */ + if (value < 10) + value = 10; + HALDEBUG(ah, HAL_DEBUG_TXQUEUE, + "%s: defaulting to rdytime = %d uS\n", + __func__, value); + OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), + SM(TU_TO_USEC(value), AR_Q_RDYTIMECFG_INT) | + AR_Q_RDYTIMECFG_ENA); } dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, AR_D_MISC_ARB_LOCKOUT_CNTRL); @@ -1106,3 +1136,4 @@ ar5416ResetTxQueue(struct ath_hal *ah, u_int q) return AH_TRUE; } +#undef TU_TO_USEC