ath9k: Fix maximum tx fifo settings for single stream devices
authorLuis R. Rodriguez <lrodriguez@atheros.com>
Wed, 16 Dec 2009 16:51:43 +0000 (11:51 -0500)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 18 Dec 2009 22:05:22 +0000 (14:05 -0800)
This is a backport of upstream commit: f4709fdf683e1ed37b321c258b614ebe39752bf3

Atheros single stream AR9285 and AR9271 have half the PCU TX FIFO
buffer size of that of dual stream devices. Dual stream devices
have a max PCU TX FIFO size of 8 KB while single stream devices
have 4 KB. Single stream devices have an issue though and require
hardware only to use half of the amount of its capable PCU TX FIFO
size, 2 KB and this requires a change in software.

Technically a change would not have been required (except for frame
burst considerations of 128 bytes) if these devices would have been
able to use the full 4 KB of the PCU TX FIFO size but our systems
engineers recommend 2 KB to be used only. We enforce this through
software by reducing the max frame triggger level to 2 KB.

Fixing the max frame trigger level should then have a few benefits:

  * The PER will now be adjusted as designed for underruns when the
    max trigger level is reached. This should help alleviate the
    bus as the rate control algorithm chooses a slower rate which
    should ensure frames are transmitted properly under high system
    bus load.

  * The poll we use on our TX queues should now trigger and work
    as designed for single stream devices. The hardware passes
    data from each TX queue on the PCU TX FIFO queue respecting each
    queue's priority. The new trigger level ensures this seeding of
    the PCU TX FIFO queue occurs as designed which could mean avoiding
    false resets and actually reseting hw correctly when a TX queue
    is indeed stuck.

  * Some undocumented / unsupported behaviour could have been triggered
    when the max trigger level level was being set to 4 KB on single
    stream devices. Its not clear what this issue was to me yet.

Cc: Kyungwan Nam <kyungwan.nam@atheros.com>
Cc: Bennyam Malavazi <bennyam.malavazi@atheros.com>
Cc: Stephen Chen <stephen.chen@atheros.com>
Cc: Shan Palanisamy <shan.palanisamy@atheros.com>
Cc: Paul Shaw <paul.shaw@atheros.com>
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/mac.c

index ca7694caf36425bf278d786af0bdd95c3713b99e..c7aa05a82877194496d20de7be0d3e75adea66df 100644 (file)
@@ -937,6 +937,11 @@ int ath9k_hw_init(struct ath_hw *ah)
        DPRINTF(ah->ah_sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
                ah->config.serialize_regmode);
 
+       if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+               ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1;
+       else
+               ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
+
        if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) {
                DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
                        "Mac Chip Rev 0x%02x.%x is not supported by "
@@ -3670,7 +3675,11 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
                pCap->keycache_size = AR_KEYTABLE_SIZE;
 
        pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
-       pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
+
+       if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
+               pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1;
+       else
+               pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
 
        if (AR_SREV_9285_10_OR_LATER(ah))
                pCap->num_gpio_pins = AR9285_NUM_GPIO;
index b8923457182992df11bc43c90e39ae5b3bff8d4a..57f14630e2a10992db1b71fdb77d92322205a390 100644 (file)
@@ -218,6 +218,7 @@ struct ath9k_ops_config {
 #define AR_SPUR_FEEQ_BOUND_HT20 10
        int spurmode;
        u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
+       u8 max_txtrig_level;
 };
 
 enum ath9k_int {
index 561a40ed056422204d0ea4aca3f6075eb3945689..d4d9d828aff44121a70d4a0991f3586aed3ea6d4 100644 (file)
@@ -70,7 +70,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
        u32 txcfg, curLevel, newLevel;
        enum ath9k_int omask;
 
-       if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD)
+       if (ah->tx_trig_level >= ah->config.max_txtrig_level)
                return false;
 
        omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL);
@@ -79,7 +79,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
        curLevel = MS(txcfg, AR_FTRIG);
        newLevel = curLevel;
        if (bIncTrigLevel) {
-               if (curLevel < MAX_TX_FIFO_THRESHOLD)
+               if (curLevel < ah->config.max_txtrig_level)
                        newLevel++;
        } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
                newLevel--;