Author: adrian
Date: Thu Mar 10 02:09:06 2011
New Revision: 219441
URL: http://svn.freebsd.org/changeset/base/219441

Log:
  Introduce the Merlin PWDCLKIND workaround.
  
  This is something bus clock related from what I can gather. It is needed for
  the AR9220 based Ubiquiti SR71-12 and SR71-15 Mini-PCI NICs.
  
  (Note: those NICs don't work right now because of earlier changes to handle
  power table offset correctly. That'll be resolved in a follow-up commit.)

Modified:
  head/sys/dev/ath/ath_hal/ah_eeprom.h
  head/sys/dev/ath/ath_hal/ah_eeprom_v14.c
  head/sys/dev/ath/ath_hal/ah_eeprom_v14.h
  head/sys/dev/ath/ath_hal/ar5416/ar5416.h
  head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c

Modified: head/sys/dev/ath/ath_hal/ah_eeprom.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ah_eeprom.h        Thu Mar 10 01:02:53 2011        
(r219440)
+++ head/sys/dev/ath/ath_hal/ah_eeprom.h        Thu Mar 10 02:09:06 2011        
(r219441)
@@ -100,7 +100,8 @@ enum {
        AR_EEP_ANTGAINMAX_5,    /* int8_t* */
        AR_EEP_ANTGAINMAX_2,    /* int8_t* */
        AR_EEP_WRITEPROTECT,    /* use ath_hal_eepromGetFlag */
-       AR_EEP_PWR_TABLE_OFFSET /* int8_t* */
+       AR_EEP_PWR_TABLE_OFFSET,/* int8_t* */
+       AR_EEP_PWDCLKIND        /* uint8_t* */
 };
 
 typedef struct {

Modified: head/sys/dev/ath/ath_hal/ah_eeprom_v14.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ah_eeprom_v14.c    Thu Mar 10 01:02:53 2011        
(r219440)
+++ head/sys/dev/ath/ath_hal/ah_eeprom_v14.c    Thu Mar 10 02:09:06 2011        
(r219441)
@@ -132,6 +132,12 @@ v14EepromGet(struct ath_hal *ah, int par
                else
                        *(int8_t *) val = AR5416_PWR_TABLE_OFFSET_DB;
                return HAL_OK;
+       case AR_EEP_PWDCLKIND:
+               if (IS_VERS(>=, AR5416_EEP_MINOR_VER_10)) {
+                       *(uint8_t *) val = pBase->pwdclkind;
+                       return HAL_OK;
+               }
+               return HAL_EIO;
                
         default:
                HALASSERT(0);

Modified: head/sys/dev/ath/ath_hal/ah_eeprom_v14.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ah_eeprom_v14.h    Thu Mar 10 01:02:53 2011        
(r219440)
+++ head/sys/dev/ath/ath_hal/ah_eeprom_v14.h    Thu Mar 10 02:09:06 2011        
(r219441)
@@ -49,6 +49,7 @@
 #define AR5416_EEP_MINOR_VER_3         0x3
 #define AR5416_EEP_MINOR_VER_7         0x7
 #define AR5416_EEP_MINOR_VER_9         0x9
+#define AR5416_EEP_MINOR_VER_10                0xa
 #define AR5416_EEP_MINOR_VER_16                0x10
 #define AR5416_EEP_MINOR_VER_17                0x11
 #define AR5416_EEP_MINOR_VER_19                0x13

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416.h    Thu Mar 10 01:02:53 2011        
(r219440)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416.h    Thu Mar 10 02:09:06 2011        
(r219441)
@@ -105,6 +105,8 @@ struct ath_hal_5416 {
        struct ar5416NfLimits nf_5g;
 
        int             initPDADC;
+
+       int             ah_need_an_top2_fixup;  /* merlin or later chips that 
may need this workaround */
 };
 #define        AH5416(_ah)     ((struct ath_hal_5416 *)(_ah))
 

Modified: head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c     Thu Mar 10 01:02:53 
2011        (r219440)
+++ head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c     Thu Mar 10 02:09:06 
2011        (r219441)
@@ -114,6 +114,7 @@ ar9280Attach(uint16_t devid, HAL_SOFTC s
        HAL_STATUS ecode;
        HAL_BOOL rfStatus;
        int8_t pwr_table_offset;
+       uint8_t pwr;
 
        HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
            __func__, sc, (void*) st, (void*) sh);
@@ -246,6 +247,20 @@ ar9280Attach(uint16_t devid, HAL_SOFTC s
                goto bad;
        }
 
+       /* Enable fixup for AR_AN_TOP2 if necessary */
+       /*
+        * The v14 EEPROM layer returns HAL_EIO if PWDCLKIND isn't supported
+        * by the EEPROM version.
+        *
+        * ath9k checks the EEPROM minor version is >= 0x0a here, instead of
+        * the abstracted EEPROM access layer.
+        */
+       ecode = ath_hal_eepromGet(ah, AR_EEP_PWDCLKIND, &pwr);
+       if (AR_SREV_MERLIN_20_OR_LATER(ah) && ecode == HAL_OK && pwr == 0) {
+               printf("[ath] enabling AN_TOP2_FIXUP\n");
+               AH5416(ah)->ah_need_an_top2_fixup = 1;
+       }
+
         /*
          * Check whether the power table offset isn't the default.
          * This can occur with eeprom minor V21 or greater on Merlin.
@@ -362,6 +377,8 @@ ar9280WriteIni(struct ath_hal *ah, const
 {
        u_int modesIndex, freqIndex;
        int regWrites = 0;
+       int i;
+       const HAL_INI_ARRAY *ia;
 
        /* Setup the indices for the next set of register array writes */
        /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */
@@ -386,10 +403,33 @@ ar9280WriteIni(struct ath_hal *ah, const
        OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
        OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
 
-       /* XXX Merlin ini fixups */
-       /* XXX Merlin 100us delay for shift registers */
+       /*
+        * This is unwound because at the moment, there's a requirement
+        * for Merlin (and later, perhaps) to have a specific bit fixed
+        * in the AR_AN_TOP2 register before writing it.
+        */
+       ia = &AH5212(ah)->ah_ini_modes;
+#if 0
        regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes,
            modesIndex, regWrites);
+#endif
+       HALASSERT(modesIndex < ia->cols);
+       for (i = 0; i < ia->rows; i++) {
+               uint32_t reg = HAL_INI_VAL(ia, i, 0);
+               uint32_t val = HAL_INI_VAL(ia, i, modesIndex);
+
+               if (reg == AR_AN_TOP2 && AH5416(ah)->ah_need_an_top2_fixup)
+                       val &= ~AR_AN_TOP2_PWDCLKIND;
+
+               OS_REG_WRITE(ah, reg, val);
+
+               /* Analog shift register delay seems needed for Merlin - PR 
kern/154220 */
+               if (reg >= 0x7800 && reg < 0x78a0)
+                       OS_DELAY(100);
+
+               DMA_YIELD(regWrites);
+       }
+
        if (AR_SREV_MERLIN_20_OR_LATER(ah)) {
                regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_rxgain,
                    modesIndex, regWrites);
_______________________________________________
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