The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ath/ath_hal/ar9002/ar9280_attach.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: ISC
    3  *
    4  * Copyright (c) 2008-2009 Sam Leffler, Errno Consulting
    5  * Copyright (c) 2008 Atheros Communications, Inc.
    6  *
    7  * Permission to use, copy, modify, and/or distribute this software for any
    8  * purpose with or without fee is hereby granted, provided that the above
    9  * copyright notice and this permission notice appear in all copies.
   10  *
   11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   18  *
   19  * $FreeBSD$
   20  */
   21 #include "opt_ah.h"
   22 
   23 #include "ah.h"
   24 #include "ah_internal.h"
   25 #include "ah_devid.h"
   26 
   27 #include "ah_eeprom_v14.h"              /* XXX for tx/rx gain */
   28 
   29 #include "ar9002/ar9280.h"
   30 #include "ar5416/ar5416reg.h"
   31 #include "ar5416/ar5416phy.h"
   32 
   33 #include "ar9002/ar9280v1.ini"
   34 #include "ar9002/ar9280v2.ini"
   35 #include "ar9002/ar9280_olc.h"
   36 
   37 static const HAL_PERCAL_DATA ar9280_iq_cal = {          /* single sample */
   38         .calName = "IQ", .calType = IQ_MISMATCH_CAL,
   39         .calNumSamples  = MIN_CAL_SAMPLES,
   40         .calCountMax    = PER_MAX_LOG_COUNT,
   41         .calCollect     = ar5416IQCalCollect,
   42         .calPostProc    = ar5416IQCalibration
   43 };
   44 static const HAL_PERCAL_DATA ar9280_adc_gain_cal = {    /* single sample */
   45         .calName = "ADC Gain", .calType = ADC_GAIN_CAL,
   46         .calNumSamples  = MIN_CAL_SAMPLES,
   47         .calCountMax    = PER_MAX_LOG_COUNT,
   48         .calCollect     = ar5416AdcGainCalCollect,
   49         .calPostProc    = ar5416AdcGainCalibration
   50 };
   51 static const HAL_PERCAL_DATA ar9280_adc_dc_cal = {      /* single sample */
   52         .calName = "ADC DC", .calType = ADC_DC_CAL,
   53         .calNumSamples  = MIN_CAL_SAMPLES,
   54         .calCountMax    = PER_MAX_LOG_COUNT,
   55         .calCollect     = ar5416AdcDcCalCollect,
   56         .calPostProc    = ar5416AdcDcCalibration
   57 };
   58 static const HAL_PERCAL_DATA ar9280_adc_init_dc_cal = {
   59         .calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL,
   60         .calNumSamples  = MIN_CAL_SAMPLES,
   61         .calCountMax    = INIT_LOG_COUNT,
   62         .calCollect     = ar5416AdcDcCalCollect,
   63         .calPostProc    = ar5416AdcDcCalibration
   64 };
   65 
   66 static void ar9280ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore,
   67                 HAL_BOOL power_off);
   68 static void ar9280DisablePCIE(struct ath_hal *ah);
   69 static HAL_BOOL ar9280FillCapabilityInfo(struct ath_hal *ah);
   70 static void ar9280WriteIni(struct ath_hal *ah,
   71         const struct ieee80211_channel *chan);
   72 
   73 static void
   74 ar9280AniSetup(struct ath_hal *ah)
   75 {
   76         /*
   77          * These are the parameters from the AR5416 ANI code;
   78          * they likely need quite a bit of adjustment for the
   79          * AR9280.
   80          */
   81         static const struct ar5212AniParams aniparams = {
   82                 .maxNoiseImmunityLevel  = 4,    /* levels 0..4 */
   83                 .totalSizeDesired       = { -55, -55, -55, -55, -62 },
   84                 .coarseHigh             = { -14, -14, -14, -14, -12 },
   85                 .coarseLow              = { -64, -64, -64, -64, -70 },
   86                 .firpwr                 = { -78, -78, -78, -78, -80 },
   87                 .maxSpurImmunityLevel   = 7,
   88                 .cycPwrThr1             = { 2, 4, 6, 8, 10, 12, 14, 16 },
   89                 .maxFirstepLevel        = 2,    /* levels 0..2 */
   90                 .firstep                = { 0, 4, 8 },
   91                 .ofdmTrigHigh           = 500,
   92                 .ofdmTrigLow            = 200,
   93                 .cckTrigHigh            = 200,
   94                 .cckTrigLow             = 100,
   95                 .rssiThrHigh            = 40,
   96                 .rssiThrLow             = 7,
   97                 .period                 = 100,
   98         };
   99         /* NB: disable ANI noise immmunity for reliable RIFS rx */
  100         AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL);
  101 
  102         /* NB: ANI is not enabled yet */
  103         ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
  104 }
  105 
  106 void
  107 ar9280InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan)
  108 {
  109         uint32_t pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV);
  110 
  111         if (AR_SREV_MERLIN_20(ah) &&
  112             chan != AH_NULL && IEEE80211_IS_CHAN_5GHZ(chan)) {
  113                 /*
  114                  * PLL WAR for Merlin 2.0/2.1
  115                  * When doing fast clock, set PLL to 0x142c
  116                  * Else, set PLL to 0x2850 to prevent reset-to-reset variation 
  117                  */
  118                 pll = IS_5GHZ_FAST_CLOCK_EN(ah, chan) ? 0x142c : 0x2850;
  119                 if (IEEE80211_IS_CHAN_HALF(chan))
  120                         pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL);
  121                 else if (IEEE80211_IS_CHAN_QUARTER(chan))
  122                         pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL);
  123         } else if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
  124                 pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV);
  125                 if (chan != AH_NULL) {
  126                         if (IEEE80211_IS_CHAN_HALF(chan))
  127                                 pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL);
  128                         else if (IEEE80211_IS_CHAN_QUARTER(chan))
  129                                 pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL);
  130                         if (IEEE80211_IS_CHAN_5GHZ(chan))
  131                                 pll |= SM(0x28, AR_RTC_SOWL_PLL_DIV);
  132                         else
  133                                 pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV);
  134                 } else
  135                         pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV);
  136         }
  137 
  138         OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
  139         OS_DELAY(RTC_PLL_SETTLE_DELAY);
  140         OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_SLEEP_DERIVED_CLK);
  141 }
  142 
  143 /* XXX shouldn't be here! */
  144 #define EEP_MINOR(_ah) \
  145         (AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK)
  146 
  147 /*
  148  * Attach for an AR9280 part.
  149  */
  150 static struct ath_hal *
  151 ar9280Attach(uint16_t devid, HAL_SOFTC sc,
  152         HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
  153         HAL_OPS_CONFIG *ah_config,
  154         HAL_STATUS *status)
  155 {
  156         struct ath_hal_9280 *ahp9280;
  157         struct ath_hal_5212 *ahp;
  158         struct ath_hal *ah;
  159         uint32_t val;
  160         HAL_STATUS ecode;
  161         HAL_BOOL rfStatus;
  162         int8_t pwr_table_offset;
  163         uint8_t pwr;
  164 
  165         HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
  166             __func__, sc, (void*) st, (void*) sh);
  167 
  168         /* NB: memory is returned zero'd */
  169         ahp9280 = ath_hal_malloc(sizeof (struct ath_hal_9280));
  170         if (ahp9280 == AH_NULL) {
  171                 HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
  172                     "%s: cannot allocate memory for state block\n", __func__);
  173                 *status = HAL_ENOMEM;
  174                 return AH_NULL;
  175         }
  176         ahp = AH5212(ahp9280);
  177         ah = &ahp->ah_priv.h;
  178 
  179         ar5416InitState(AH5416(ah), devid, sc, st, sh, status);
  180 
  181         /*
  182          * Use the "local" EEPROM data given to us by the higher layers.
  183          * This is a private copy out of system flash. The Linux ath9k
  184          * commit for the initial AR9130 support mentions MMIO flash
  185          * access is "unreliable." -adrian
  186          */
  187         if (eepromdata != AH_NULL) {
  188                 AH_PRIVATE((ah))->ah_eepromRead = ath_hal_EepromDataRead;
  189                 AH_PRIVATE((ah))->ah_eepromWrite = NULL;
  190                 ah->ah_eepromdata = eepromdata;
  191         }
  192 
  193         /* XXX override with 9280 specific state */
  194         /* override 5416 methods for our needs */
  195         AH5416(ah)->ah_initPLL = ar9280InitPLL;
  196 
  197         ah->ah_setAntennaSwitch         = ar9280SetAntennaSwitch;
  198         ah->ah_configPCIE               = ar9280ConfigPCIE;
  199         ah->ah_disablePCIE              = ar9280DisablePCIE;
  200 
  201         AH5416(ah)->ah_cal.iqCalData.calData = &ar9280_iq_cal;
  202         AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9280_adc_gain_cal;
  203         AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9280_adc_dc_cal;
  204         AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9280_adc_init_dc_cal;
  205         AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
  206 
  207         AH5416(ah)->ah_spurMitigate     = ar9280SpurMitigate;
  208         AH5416(ah)->ah_writeIni         = ar9280WriteIni;
  209         AH5416(ah)->ah_olcInit          = ar9280olcInit;
  210         AH5416(ah)->ah_olcTempCompensation = ar9280olcTemperatureCompensation;
  211         AH5416(ah)->ah_setPowerCalTable = ar9280SetPowerCalTable;
  212 
  213         AH5416(ah)->ah_rx_chainmask     = AR9280_DEFAULT_RXCHAINMASK;
  214         AH5416(ah)->ah_tx_chainmask     = AR9280_DEFAULT_TXCHAINMASK;
  215 
  216         if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
  217                 /* reset chip */
  218                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n",
  219                     __func__);
  220                 ecode = HAL_EIO;
  221                 goto bad;
  222         }
  223 
  224         if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
  225                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
  226                     __func__);
  227                 ecode = HAL_EIO;
  228                 goto bad;
  229         }
  230         /* Read Revisions from Chips before taking out of reset */
  231         val = OS_REG_READ(ah, AR_SREV);
  232         HALDEBUG(ah, HAL_DEBUG_ATTACH,
  233             "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
  234             __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION),
  235             MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION));
  236         /* NB: include chip type to differentiate from pre-Sowl versions */
  237         AH_PRIVATE(ah)->ah_macVersion =
  238             (val & AR_XSREV_VERSION) >> AR_XSREV_TYPE_S;
  239         AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION);
  240         AH_PRIVATE(ah)->ah_ispcie = (val & AR_XSREV_TYPE_HOST_MODE) == 0;
  241 
  242         /* setup common ini data; rf backends handle remainder */
  243         if (AR_SREV_MERLIN_20_OR_LATER(ah)) {
  244                 HAL_INI_INIT(&ahp->ah_ini_modes, ar9280Modes_v2, 6);
  245                 HAL_INI_INIT(&ahp->ah_ini_common, ar9280Common_v2, 2);
  246                 HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
  247                     ar9280PciePhy_clkreq_always_on_L1_v2, 2);
  248                 HAL_INI_INIT(&ahp9280->ah_ini_xmodes,
  249                     ar9280Modes_fast_clock_v2, 3);
  250         } else {
  251                 HAL_INI_INIT(&ahp->ah_ini_modes, ar9280Modes_v1, 6);
  252                 HAL_INI_INIT(&ahp->ah_ini_common, ar9280Common_v1, 2);
  253                 HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
  254                     ar9280PciePhy_v1, 2);
  255         }
  256         ar5416AttachPCIE(ah);
  257 
  258         ecode = ath_hal_v14EepromAttach(ah);
  259         if (ecode != HAL_OK)
  260                 goto bad;
  261 
  262         if (!ar5416ChipReset(ah, AH_NULL, HAL_RESET_NORMAL)) {  /* reset chip */
  263                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
  264                 ecode = HAL_EIO;
  265                 goto bad;
  266         }
  267 
  268         AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);
  269 
  270         if (!ar5212ChipTest(ah)) {
  271                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
  272                     __func__);
  273                 ecode = HAL_ESELFTEST;
  274                 goto bad;
  275         }
  276 
  277         /*
  278          * Set correct Baseband to analog shift
  279          * setting to access analog chips.
  280          */
  281         OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
  282 
  283         /* Read Radio Chip Rev Extract */
  284         AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah);
  285         switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
  286         case AR_RAD2133_SREV_MAJOR:     /* Sowl: 2G/3x3 */
  287         case AR_RAD5133_SREV_MAJOR:     /* Sowl: 2+5G/3x3 */
  288                 break;
  289         default:
  290                 if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
  291                         AH_PRIVATE(ah)->ah_analog5GhzRev =
  292                                 AR_RAD5133_SREV_MAJOR;
  293                         break;
  294                 }
  295 #ifdef AH_DEBUG
  296                 HALDEBUG(ah, HAL_DEBUG_ANY,
  297                     "%s: 5G Radio Chip Rev 0x%02X is not supported by "
  298                     "this driver\n", __func__,
  299                     AH_PRIVATE(ah)->ah_analog5GhzRev);
  300                 ecode = HAL_ENOTSUPP;
  301                 goto bad;
  302 #endif
  303         }
  304         rfStatus = ar9280RfAttach(ah, &ecode);
  305         if (!rfStatus) {
  306                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
  307                     __func__, ecode);
  308                 goto bad;
  309         }
  310 
  311         /* Enable fixup for AR_AN_TOP2 if necessary */
  312         /*
  313          * The v14 EEPROM layer returns HAL_EIO if PWDCLKIND isn't supported
  314          * by the EEPROM version.
  315          *
  316          * ath9k checks the EEPROM minor version is >= 0x0a here, instead of
  317          * the abstracted EEPROM access layer.
  318          */
  319         ecode = ath_hal_eepromGet(ah, AR_EEP_PWDCLKIND, &pwr);
  320         if (AR_SREV_MERLIN_20_OR_LATER(ah) && ecode == HAL_OK && pwr == 0) {
  321                 printf("[ath] enabling AN_TOP2_FIXUP\n");
  322                 AH5416(ah)->ah_need_an_top2_fixup = 1;
  323         }
  324 
  325         /*
  326          * Check whether the power table offset isn't the default.
  327          * This can occur with eeprom minor V21 or greater on Merlin.
  328          */
  329         (void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET, &pwr_table_offset);
  330         if (pwr_table_offset != AR5416_PWR_TABLE_OFFSET_DB)
  331                 ath_hal_printf(ah, "[ath]: default pwr offset: %d dBm != EEPROM pwr offset: %d dBm; curves will be adjusted.\n",
  332                     AR5416_PWR_TABLE_OFFSET_DB, (int) pwr_table_offset);
  333 
  334         /* XXX check for >= minor ver 17 */
  335         if (AR_SREV_MERLIN_20(ah)) {
  336                 /* setup rxgain table */
  337                 switch (ath_hal_eepromGet(ah, AR_EEP_RXGAIN_TYPE, AH_NULL)) {
  338                 case AR5416_EEP_RXGAIN_13dB_BACKOFF:
  339                         HAL_INI_INIT(&ahp9280->ah_ini_rxgain,
  340                             ar9280Modes_backoff_13db_rxgain_v2, 6);
  341                         break;
  342                 case AR5416_EEP_RXGAIN_23dB_BACKOFF:
  343                         HAL_INI_INIT(&ahp9280->ah_ini_rxgain,
  344                             ar9280Modes_backoff_23db_rxgain_v2, 6);
  345                         break;
  346                 case AR5416_EEP_RXGAIN_ORIG:
  347                         HAL_INI_INIT(&ahp9280->ah_ini_rxgain,
  348                             ar9280Modes_original_rxgain_v2, 6);
  349                         break;
  350                 default:
  351                         HALASSERT(AH_FALSE);
  352                         goto bad;               /* XXX ? try to continue */
  353                 }
  354         }
  355 
  356         /* XXX check for >= minor ver 19 */
  357         if (AR_SREV_MERLIN_20(ah)) {
  358                 /* setp txgain table */
  359                 switch (ath_hal_eepromGet(ah, AR_EEP_TXGAIN_TYPE, AH_NULL)) {
  360                 case AR5416_EEP_TXGAIN_HIGH_POWER:
  361                         HAL_INI_INIT(&ahp9280->ah_ini_txgain,
  362                             ar9280Modes_high_power_tx_gain_v2, 6);
  363                         break;
  364                 case AR5416_EEP_TXGAIN_ORIG:
  365                         HAL_INI_INIT(&ahp9280->ah_ini_txgain,
  366                             ar9280Modes_original_tx_gain_v2, 6);
  367                         break;
  368                 default:
  369                         HALASSERT(AH_FALSE);
  370                         goto bad;               /* XXX ? try to continue */
  371                 }
  372         }
  373 
  374         /*
  375          * Got everything we need now to setup the capabilities.
  376          */
  377         if (!ar9280FillCapabilityInfo(ah)) {
  378                 ecode = HAL_EEREAD;
  379                 goto bad;
  380         }
  381 
  382         ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
  383         if (ecode != HAL_OK) {
  384                 HALDEBUG(ah, HAL_DEBUG_ANY,
  385                     "%s: error getting mac address from EEPROM\n", __func__);
  386                 goto bad;
  387         }
  388         /* XXX How about the serial number ? */
  389         /* Read Reg Domain */
  390         AH_PRIVATE(ah)->ah_currentRD =
  391             ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
  392         AH_PRIVATE(ah)->ah_currentRDext =
  393             ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL);
  394 
  395         /*
  396          * ah_miscMode is populated by ar5416FillCapabilityInfo()
  397          * starting from griffin. Set here to make sure that
  398          * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
  399          * placed into hardware.
  400          */
  401         if (ahp->ah_miscMode != 0)
  402                 OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode);
  403 
  404         ar9280AniSetup(ah);                     /* Anti Noise Immunity */
  405 
  406         /* Setup noise floor min/max/nominal values */
  407         AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ;
  408         AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ;
  409         AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9280_2GHZ;
  410         AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ;
  411         AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ;
  412         AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9280_5GHZ;
  413 
  414         ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
  415 
  416         HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
  417 
  418         return ah;
  419 bad:
  420         if (ah != AH_NULL)
  421                 ah->ah_detach(ah);
  422         if (status)
  423                 *status = ecode;
  424         return AH_NULL;
  425 }
  426 
  427 static void
  428 ar9280ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore, HAL_BOOL power_off)
  429 {
  430         uint32_t val;
  431 
  432         if (AH_PRIVATE(ah)->ah_ispcie && !restore) {
  433                 ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0);
  434                 OS_DELAY(1000);
  435         }
  436 
  437         /*
  438          * Set PCIe workaround bits
  439          *
  440          * NOTE:
  441          *
  442          * In Merlin and Kite, bit 14 in WA register (disable L1) should only
  443          * be set when device enters D3 and be cleared when device comes back
  444          * to D0.
  445          */
  446         if (power_off) {                /* Power-off */
  447                 OS_REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
  448 
  449                 val = OS_REG_READ(ah, AR_WA);
  450 
  451                 /*
  452                  * Disable bit 6 and 7 before entering D3 to prevent
  453                  * system hang.
  454                  */
  455                 val &= ~(AR_WA_BIT6 | AR_WA_BIT7);
  456 
  457                 /*
  458                  * XXX Not sure, is specified in the reference HAL.
  459                  */
  460                 val |= AR_WA_BIT22;
  461 
  462                 /*
  463                  * See above: set AR_WA_D3_L1_DISABLE when entering D3 state.
  464                  *
  465                  * XXX The reference HAL does it this way - it only sets
  466                  * AR_WA_D3_L1_DISABLE if it's set in AR9280_WA_DEFAULT,
  467                  * which it (currently) isn't.  So the following statement
  468                  * is currently a NOP.
  469                  */
  470                 if (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE)
  471                         val |= AR_WA_D3_L1_DISABLE;
  472 
  473                 OS_REG_WRITE(ah, AR_WA, val);
  474         } else {                        /* Power-on */
  475                 val = AR9280_WA_DEFAULT;
  476 
  477                 /*
  478                  * See note above: make sure L1_DISABLE is not set.
  479                  */
  480                 val &= (~AR_WA_D3_L1_DISABLE);
  481                 OS_REG_WRITE(ah, AR_WA, val);
  482 
  483                 /* set bit 19 to allow forcing of pcie core into L1 state */
  484                 OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
  485         }
  486 }
  487 
  488 static void
  489 ar9280DisablePCIE(struct ath_hal *ah)
  490 {
  491 }
  492 
  493 static void
  494 ar9280WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
  495 {
  496         u_int modesIndex, freqIndex;
  497         int regWrites = 0;
  498         int i;
  499         const HAL_INI_ARRAY *ia;
  500 
  501         /* Setup the indices for the next set of register array writes */
  502         /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */
  503         if (IEEE80211_IS_CHAN_2GHZ(chan)) {
  504                 freqIndex = 2;
  505                 if (IEEE80211_IS_CHAN_HT40(chan))
  506                         modesIndex = 3;
  507                 else if (IEEE80211_IS_CHAN_108G(chan))
  508                         modesIndex = 5;
  509                 else
  510                         modesIndex = 4;
  511         } else {
  512                 freqIndex = 1;
  513                 if (IEEE80211_IS_CHAN_HT40(chan) ||
  514                     IEEE80211_IS_CHAN_TURBO(chan))
  515                         modesIndex = 2;
  516                 else
  517                         modesIndex = 1;
  518         }
  519 
  520         /* Set correct Baseband to analog shift setting to access analog chips. */
  521         OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
  522         OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
  523 
  524         /*
  525          * This is unwound because at the moment, there's a requirement
  526          * for Merlin (and later, perhaps) to have a specific bit fixed
  527          * in the AR_AN_TOP2 register before writing it.
  528          */
  529         ia = &AH5212(ah)->ah_ini_modes;
  530 #if 0
  531         regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes,
  532             modesIndex, regWrites);
  533 #endif
  534         HALASSERT(modesIndex < ia->cols);
  535         for (i = 0; i < ia->rows; i++) {
  536                 uint32_t reg = HAL_INI_VAL(ia, i, 0);
  537                 uint32_t val = HAL_INI_VAL(ia, i, modesIndex);
  538 
  539                 if (reg == AR_AN_TOP2 && AH5416(ah)->ah_need_an_top2_fixup)
  540                         val &= ~AR_AN_TOP2_PWDCLKIND;
  541 
  542                 OS_REG_WRITE(ah, reg, val);
  543 
  544                 /* Analog shift register delay seems needed for Merlin - PR kern/154220 */
  545                 if (reg >= 0x7800 && reg < 0x7900)
  546                         OS_DELAY(100);
  547 
  548                 DMA_YIELD(regWrites);
  549         }
  550 
  551         if (AR_SREV_MERLIN_20_OR_LATER(ah)) {
  552                 regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_rxgain,
  553                     modesIndex, regWrites);
  554                 regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_txgain,
  555                     modesIndex, regWrites);
  556         }
  557         /* XXX Merlin 100us delay for shift registers */
  558         regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common,
  559             1, regWrites);
  560 
  561         if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
  562                 /* 5GHz channels w/ Fast Clock use different modal values */
  563                 regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_xmodes,
  564                     modesIndex, regWrites);
  565         }
  566 }
  567 
  568 #define AR_BASE_FREQ_2GHZ       2300
  569 #define AR_BASE_FREQ_5GHZ       4900
  570 #define AR_SPUR_FEEQ_BOUND_HT40 19
  571 #define AR_SPUR_FEEQ_BOUND_HT20 10
  572 
  573 void
  574 ar9280SpurMitigate(struct ath_hal *ah, const struct ieee80211_channel *chan)
  575 {
  576     static const int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
  577                 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 };
  578     static const int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
  579                 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 };
  580     static int inc[4] = { 0, 100, 0, 0 };
  581 
  582     int bb_spur = AR_NO_SPUR;
  583     int freq;
  584     int bin, cur_bin;
  585     int bb_spur_off, spur_subchannel_sd;
  586     int spur_freq_sd;
  587     int spur_delta_phase;
  588     int denominator;
  589     int upper, lower, cur_vit_mask;
  590     int tmp, newVal;
  591     int i;
  592     CHAN_CENTERS centers;
  593 
  594     int8_t mask_m[123];
  595     int8_t mask_p[123];
  596     int8_t mask_amt;
  597     int tmp_mask;
  598     int cur_bb_spur;
  599     HAL_BOOL is2GHz = IEEE80211_IS_CHAN_2GHZ(chan);
  600 
  601     OS_MEMZERO(&mask_m, sizeof(int8_t) * 123);
  602     OS_MEMZERO(&mask_p, sizeof(int8_t) * 123);
  603 
  604     ar5416GetChannelCenters(ah, chan, &centers);
  605     freq = centers.synth_center;
  606 
  607     /*
  608      * Need to verify range +/- 9.38 for static ht20 and +/- 18.75 for ht40,
  609      * otherwise spur is out-of-band and can be ignored.
  610      */
  611     for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
  612         cur_bb_spur = ath_hal_getSpurChan(ah, i, is2GHz);
  613         /* Get actual spur freq in MHz from EEPROM read value */ 
  614         if (is2GHz) {
  615             cur_bb_spur =  (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
  616         } else {
  617             cur_bb_spur =  (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
  618         }
  619 
  620         if (AR_NO_SPUR == cur_bb_spur)
  621             break;
  622         cur_bb_spur = cur_bb_spur - freq;
  623 
  624         if (IEEE80211_IS_CHAN_HT40(chan)) {
  625             if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) && 
  626                 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
  627                 bb_spur = cur_bb_spur;
  628                 break;
  629             }
  630         } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
  631                    (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
  632             bb_spur = cur_bb_spur;
  633             break;
  634         }
  635     }
  636 
  637     if (AR_NO_SPUR == bb_spur) {
  638 #if 1
  639         /*
  640          * MRC CCK can interfere with beacon detection and cause deaf/mute.
  641          * Disable MRC CCK for now.
  642          */
  643         OS_REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
  644 #else
  645         /* Enable MRC CCK if no spur is found in this channel. */
  646         OS_REG_SET_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
  647 #endif
  648         return;
  649     } else {
  650         /* 
  651          * For Merlin, spur can break CCK MRC algorithm. Disable CCK MRC if spur
  652          * is found in this channel.
  653          */
  654         OS_REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
  655     }
  656 
  657     bin = bb_spur * 320;
  658 
  659     tmp = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4_CHAIN(0));
  660 
  661     newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
  662         AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
  663         AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
  664         AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
  665     OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4_CHAIN(0), newVal);
  666 
  667     newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
  668         AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
  669         AR_PHY_SPUR_REG_MASK_RATE_SELECT |
  670         AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
  671         SM(AR5416_SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
  672     OS_REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
  673 
  674     /* Pick control or extn channel to cancel the spur */
  675     if (IEEE80211_IS_CHAN_HT40(chan)) {
  676         if (bb_spur < 0) {
  677             spur_subchannel_sd = 1;
  678             bb_spur_off = bb_spur + 10;
  679         } else {
  680             spur_subchannel_sd = 0;
  681             bb_spur_off = bb_spur - 10;
  682         }
  683     } else {
  684         spur_subchannel_sd = 0;
  685         bb_spur_off = bb_spur;
  686     }
  687 
  688     /*
  689      * spur_delta_phase = bb_spur/40 * 2**21 for static ht20,
  690      * /80 for dyn2040.
  691      */
  692     if (IEEE80211_IS_CHAN_HT40(chan))
  693         spur_delta_phase = ((bb_spur * 262144) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;    
  694     else
  695         spur_delta_phase = ((bb_spur * 524288) / 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
  696 
  697     /*
  698      * in 11A mode the denominator of spur_freq_sd should be 40 and
  699      * it should be 44 in 11G
  700      */
  701     denominator = IEEE80211_IS_CHAN_2GHZ(chan) ? 44 : 40;
  702     spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
  703 
  704     newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
  705         SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
  706         SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
  707     OS_REG_WRITE(ah, AR_PHY_TIMING11, newVal);
  708 
  709     /* Choose to cancel between control and extension channels */
  710     newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
  711     OS_REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
  712 
  713     /*
  714      * ============================================
  715      * Set Pilot and Channel Masks
  716      *
  717      * pilot mask 1 [31:0] = +6..-26, no 0 bin
  718      * pilot mask 2 [19:0] = +26..+7
  719      *
  720      * channel mask 1 [31:0] = +6..-26, no 0 bin
  721      * channel mask 2 [19:0] = +26..+7
  722      */
  723     cur_bin = -6000;
  724     upper = bin + 100;
  725     lower = bin - 100;
  726 
  727     for (i = 0; i < 4; i++) {
  728         int pilot_mask = 0;
  729         int chan_mask  = 0;
  730         int bp         = 0;
  731         for (bp = 0; bp < 30; bp++) {
  732             if ((cur_bin > lower) && (cur_bin < upper)) {
  733                 pilot_mask = pilot_mask | 0x1 << bp;
  734                 chan_mask  = chan_mask | 0x1 << bp;
  735             }
  736             cur_bin += 100;
  737         }
  738         cur_bin += inc[i];
  739         OS_REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
  740         OS_REG_WRITE(ah, chan_mask_reg[i], chan_mask);
  741     }
  742 
  743     /* =================================================
  744      * viterbi mask 1 based on channel magnitude
  745      * four levels 0-3
  746      *  - mask (-27 to 27) (reg 64,0x9900 to 67,0x990c)
  747      *      [1 2 2 1] for -9.6 or [1 2 1] for +16
  748      *  - enable_mask_ppm, all bins move with freq
  749      *
  750      *  - mask_select,    8 bits for rates (reg 67,0x990c)
  751      *  - mask_rate_cntl, 8 bits for rates (reg 67,0x990c)
  752      *      choose which mask to use mask or mask2
  753      */
  754 
  755     /*
  756      * viterbi mask 2  2nd set for per data rate puncturing
  757      * four levels 0-3
  758      *  - mask_select, 8 bits for rates (reg 67)
  759      *  - mask (-27 to 27) (reg 98,0x9988 to 101,0x9994)
  760      *      [1 2 2 1] for -9.6 or [1 2 1] for +16
  761      */
  762     cur_vit_mask = 6100;
  763     upper        = bin + 120;
  764     lower        = bin - 120;
  765 
  766     for (i = 0; i < 123; i++) {
  767         if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
  768             if ((abs(cur_vit_mask - bin)) < 75) {
  769                 mask_amt = 1;
  770             } else {
  771                 mask_amt = 0;
  772             }
  773             if (cur_vit_mask < 0) {
  774                 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
  775             } else {
  776                 mask_p[cur_vit_mask / 100] = mask_amt;
  777             }
  778         }
  779         cur_vit_mask -= 100;
  780     }
  781 
  782     tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
  783           | (mask_m[48] << 26) | (mask_m[49] << 24)
  784           | (mask_m[50] << 22) | (mask_m[51] << 20)
  785           | (mask_m[52] << 18) | (mask_m[53] << 16)
  786           | (mask_m[54] << 14) | (mask_m[55] << 12)
  787           | (mask_m[56] << 10) | (mask_m[57] <<  8)
  788           | (mask_m[58] <<  6) | (mask_m[59] <<  4)
  789           | (mask_m[60] <<  2) | (mask_m[61] <<  0);
  790     OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
  791     OS_REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
  792 
  793     tmp_mask =             (mask_m[31] << 28)
  794           | (mask_m[32] << 26) | (mask_m[33] << 24)
  795           | (mask_m[34] << 22) | (mask_m[35] << 20)
  796           | (mask_m[36] << 18) | (mask_m[37] << 16)
  797           | (mask_m[48] << 14) | (mask_m[39] << 12)
  798           | (mask_m[40] << 10) | (mask_m[41] <<  8)
  799           | (mask_m[42] <<  6) | (mask_m[43] <<  4)
  800           | (mask_m[44] <<  2) | (mask_m[45] <<  0);
  801     OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
  802     OS_REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
  803 
  804     tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
  805           | (mask_m[18] << 26) | (mask_m[18] << 24)
  806           | (mask_m[20] << 22) | (mask_m[20] << 20)
  807           | (mask_m[22] << 18) | (mask_m[22] << 16)
  808           | (mask_m[24] << 14) | (mask_m[24] << 12)
  809           | (mask_m[25] << 10) | (mask_m[26] <<  8)
  810           | (mask_m[27] <<  6) | (mask_m[28] <<  4)
  811           | (mask_m[29] <<  2) | (mask_m[30] <<  0);
  812     OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
  813     OS_REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
  814 
  815     tmp_mask = (mask_m[ 0] << 30) | (mask_m[ 1] << 28)
  816           | (mask_m[ 2] << 26) | (mask_m[ 3] << 24)
  817           | (mask_m[ 4] << 22) | (mask_m[ 5] << 20)
  818           | (mask_m[ 6] << 18) | (mask_m[ 7] << 16)
  819           | (mask_m[ 8] << 14) | (mask_m[ 9] << 12)
  820           | (mask_m[10] << 10) | (mask_m[11] <<  8)
  821           | (mask_m[12] <<  6) | (mask_m[13] <<  4)
  822           | (mask_m[14] <<  2) | (mask_m[15] <<  0);
  823     OS_REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
  824     OS_REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
  825 
  826     tmp_mask =             (mask_p[15] << 28)
  827           | (mask_p[14] << 26) | (mask_p[13] << 24)
  828           | (mask_p[12] << 22) | (mask_p[11] << 20)
  829           | (mask_p[10] << 18) | (mask_p[ 9] << 16)
  830           | (mask_p[ 8] << 14) | (mask_p[ 7] << 12)
  831           | (mask_p[ 6] << 10) | (mask_p[ 5] <<  8)
  832           | (mask_p[ 4] <<  6) | (mask_p[ 3] <<  4)
  833           | (mask_p[ 2] <<  2) | (mask_p[ 1] <<  0);
  834     OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
  835     OS_REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
  836 
  837     tmp_mask =             (mask_p[30] << 28)
  838           | (mask_p[29] << 26) | (mask_p[28] << 24)
  839           | (mask_p[27] << 22) | (mask_p[26] << 20)
  840           | (mask_p[25] << 18) | (mask_p[24] << 16)
  841           | (mask_p[23] << 14) | (mask_p[22] << 12)
  842           | (mask_p[21] << 10) | (mask_p[20] <<  8)
  843           | (mask_p[19] <<  6) | (mask_p[18] <<  4)
  844           | (mask_p[17] <<  2) | (mask_p[16] <<  0);
  845     OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
  846     OS_REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
  847 
  848     tmp_mask =             (mask_p[45] << 28)
  849           | (mask_p[44] << 26) | (mask_p[43] << 24)
  850           | (mask_p[42] << 22) | (mask_p[41] << 20)
  851           | (mask_p[40] << 18) | (mask_p[39] << 16)
  852           | (mask_p[38] << 14) | (mask_p[37] << 12)
  853           | (mask_p[36] << 10) | (mask_p[35] <<  8)
  854           | (mask_p[34] <<  6) | (mask_p[33] <<  4)
  855           | (mask_p[32] <<  2) | (mask_p[31] <<  0);
  856     OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
  857     OS_REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
  858 
  859     tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
  860           | (mask_p[59] << 26) | (mask_p[58] << 24)
  861           | (mask_p[57] << 22) | (mask_p[56] << 20)
  862           | (mask_p[55] << 18) | (mask_p[54] << 16)
  863           | (mask_p[53] << 14) | (mask_p[52] << 12)
  864           | (mask_p[51] << 10) | (mask_p[50] <<  8)
  865           | (mask_p[49] <<  6) | (mask_p[48] <<  4)
  866           | (mask_p[47] <<  2) | (mask_p[46] <<  0);
  867     OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
  868     OS_REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
  869 }
  870 
  871 /*
  872  * Fill all software cached or static hardware state information.
  873  * Return failure if capabilities are to come from EEPROM and
  874  * cannot be read.
  875  */
  876 static HAL_BOOL
  877 ar9280FillCapabilityInfo(struct ath_hal *ah)
  878 {
  879         HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
  880 
  881         if (!ar5416FillCapabilityInfo(ah))
  882                 return AH_FALSE;
  883         pCap->halNumGpioPins = 10;
  884         pCap->halWowSupport = AH_TRUE;
  885         pCap->halWowMatchPatternExact = AH_TRUE;
  886 #if 0
  887         pCap->halWowMatchPatternDword = AH_TRUE;
  888 #endif
  889         pCap->halCSTSupport = AH_TRUE;
  890         pCap->halRifsRxSupport = AH_TRUE;
  891         pCap->halRifsTxSupport = AH_TRUE;
  892         pCap->halRtsAggrLimit = 64*1024;        /* 802.11n max */
  893         pCap->halExtChanDfsSupport = AH_TRUE;
  894         pCap->halUseCombinedRadarRssi = AH_TRUE;
  895 #if 0
  896         /* XXX bluetooth */
  897         pCap->halBtCoexSupport = AH_TRUE;
  898 #endif
  899         pCap->halAutoSleepSupport = AH_FALSE;   /* XXX? */
  900         pCap->hal4kbSplitTransSupport = AH_FALSE;
  901         /* Disable this so Block-ACK works correctly */
  902         pCap->halHasRxSelfLinkedTail = AH_FALSE;
  903         pCap->halMbssidAggrSupport = AH_TRUE;
  904         pCap->hal4AddrAggrSupport = AH_TRUE;
  905         pCap->halSpectralScanSupport = AH_TRUE;
  906 
  907         if (AR_SREV_MERLIN_20(ah)) {
  908                 pCap->halPSPollBroken = AH_FALSE;
  909                 /*
  910                  * This just enables the support; it doesn't
  911                  * state 5ghz fast clock will always be used.
  912                  */
  913                 pCap->halSupportsFastClock5GHz = AH_TRUE;
  914         }
  915         pCap->halRxStbcSupport = 1;
  916         pCap->halTxStbcSupport = 1;
  917         pCap->halEnhancedDfsSupport = AH_TRUE;
  918 
  919         return AH_TRUE;
  920 }
  921 
  922 /*
  923  * This has been disabled - having the HAL flip chainmasks on/off
  924  * when attempting to implement 11n disrupts things. For now, just
  925  * leave this flipped off and worry about implementing TX diversity
  926  * for legacy and MCS0-7 when 11n is fully functioning.
  927  */
  928 HAL_BOOL
  929 ar9280SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
  930 {
  931 #define ANTENNA0_CHAINMASK    0x1
  932 #define ANTENNA1_CHAINMASK    0x2
  933 #if 0
  934         struct ath_hal_5416 *ahp = AH5416(ah);
  935 
  936         /* Antenna selection is done by setting the tx/rx chainmasks approp. */
  937         switch (settings) {
  938         case HAL_ANT_FIXED_A:
  939                 /* Enable first antenna only */
  940                 ahp->ah_tx_chainmask = ANTENNA0_CHAINMASK;
  941                 ahp->ah_rx_chainmask = ANTENNA0_CHAINMASK;
  942                 break;
  943         case HAL_ANT_FIXED_B:
  944                 /* Enable second antenna only, after checking capability */
  945                 if (AH_PRIVATE(ah)->ah_caps.halTxChainMask > ANTENNA1_CHAINMASK)
  946                         ahp->ah_tx_chainmask = ANTENNA1_CHAINMASK;
  947                 ahp->ah_rx_chainmask = ANTENNA1_CHAINMASK;
  948                 break;
  949         case HAL_ANT_VARIABLE:
  950                 /* Restore original chainmask settings */
  951                 /* XXX */
  952                 ahp->ah_tx_chainmask = AR9280_DEFAULT_TXCHAINMASK;
  953                 ahp->ah_rx_chainmask = AR9280_DEFAULT_RXCHAINMASK;
  954                 break;
  955         }
  956 
  957         HALDEBUG(ah, HAL_DEBUG_ANY, "%s: settings=%d, tx/rx chainmask=%d/%d\n",
  958             __func__, settings, ahp->ah_tx_chainmask, ahp->ah_rx_chainmask);
  959 
  960 #endif
  961         return AH_TRUE;
  962 #undef ANTENNA0_CHAINMASK
  963 #undef ANTENNA1_CHAINMASK
  964 }
  965 
  966 static const char*
  967 ar9280Probe(uint16_t vendorid, uint16_t devid)
  968 {
  969         if (vendorid == ATHEROS_VENDOR_ID) {
  970                 if (devid == AR9280_DEVID_PCI)
  971                         return "Atheros 9220";
  972                 if (devid == AR9280_DEVID_PCIE)
  973                         return "Atheros 9280";
  974         }
  975         return AH_NULL;
  976 }
  977 AH_CHIP(AR9280, ar9280Probe, ar9280Attach);

Cache object: f3471bb49a6c10cc2ab309d6fcba5374


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.