Author: adrian
Date: Wed Sep 28 03:05:04 2011
New Revision: 225820
URL: http://svn.freebsd.org/changeset/base/225820

Log:
  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

Modified:
  head/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
  head/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c

Modified: head/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c       Wed Sep 28 03:03:23 
2011        (r225819)
+++ head/sys/dev/ath/ath_hal/ar5212/ar5212_xmit.c       Wed Sep 28 03:05:04 
2011        (r225820)
@@ -263,6 +263,7 @@ ar5212ReleaseTxQueue(struct ath_hal *ah,
  * 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
        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
                      |  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
 
        return AH_TRUE;
 }
+#undef TU_TO_USEC
 
 /*
  * Get the TXDP for the specified queue

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c       Wed Sep 28 03:03:23 
2011        (r225819)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c       Wed Sep 28 03:05:04 
2011        (r225820)
@@ -879,6 +879,7 @@ setTxQInterrupts(struct ath_hal *ah, HAL
  * 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
        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
                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
                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
 
        return AH_TRUE;
 }
+#undef TU_TO_USEC
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to