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/ar5212/ar5212_misc.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) 2002-2009 Sam Leffler, Errno Consulting
    5  * Copyright (c) 2002-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 #include "ah_desc.h"                    /* NB: for HAL_PHYERR* */
   27 
   28 #include "ar5212/ar5212.h"
   29 #include "ar5212/ar5212reg.h"
   30 #include "ar5212/ar5212phy.h"
   31 
   32 #include "ah_eeprom_v3.h"
   33 
   34 #define AR_NUM_GPIO     6               /* 6 GPIO pins */
   35 #define AR_GPIOD_MASK   0x0000002F      /* GPIO data reg r/w mask */
   36 
   37 void
   38 ar5212GetMacAddress(struct ath_hal *ah, uint8_t *mac)
   39 {
   40         struct ath_hal_5212 *ahp = AH5212(ah);
   41 
   42         OS_MEMCPY(mac, ahp->ah_macaddr, IEEE80211_ADDR_LEN);
   43 }
   44 
   45 HAL_BOOL
   46 ar5212SetMacAddress(struct ath_hal *ah, const uint8_t *mac)
   47 {
   48         struct ath_hal_5212 *ahp = AH5212(ah);
   49 
   50         OS_MEMCPY(ahp->ah_macaddr, mac, IEEE80211_ADDR_LEN);
   51         return AH_TRUE;
   52 }
   53 
   54 void
   55 ar5212GetBssIdMask(struct ath_hal *ah, uint8_t *mask)
   56 {
   57         struct ath_hal_5212 *ahp = AH5212(ah);
   58 
   59         OS_MEMCPY(mask, ahp->ah_bssidmask, IEEE80211_ADDR_LEN);
   60 }
   61 
   62 HAL_BOOL
   63 ar5212SetBssIdMask(struct ath_hal *ah, const uint8_t *mask)
   64 {
   65         struct ath_hal_5212 *ahp = AH5212(ah);
   66 
   67         /* save it since it must be rewritten on reset */
   68         OS_MEMCPY(ahp->ah_bssidmask, mask, IEEE80211_ADDR_LEN);
   69 
   70         OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));
   71         OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));
   72         return AH_TRUE;
   73 }
   74 
   75 /*
   76  * Attempt to change the cards operating regulatory domain to the given value
   77  */
   78 HAL_BOOL
   79 ar5212SetRegulatoryDomain(struct ath_hal *ah,
   80         uint16_t regDomain, HAL_STATUS *status)
   81 {
   82         HAL_STATUS ecode;
   83 
   84         if (AH_PRIVATE(ah)->ah_currentRD == regDomain) {
   85                 ecode = HAL_EINVAL;
   86                 goto bad;
   87         }
   88         if (ath_hal_eepromGetFlag(ah, AR_EEP_WRITEPROTECT)) {
   89                 ecode = HAL_EEWRITE;
   90                 goto bad;
   91         }
   92 #ifdef AH_SUPPORT_WRITE_REGDOMAIN
   93         if (ath_hal_eepromWrite(ah, AR_EEPROM_REG_DOMAIN, regDomain)) {
   94                 HALDEBUG(ah, HAL_DEBUG_ANY,
   95                     "%s: set regulatory domain to %u (0x%x)\n",
   96                     __func__, regDomain, regDomain);
   97                 AH_PRIVATE(ah)->ah_currentRD = regDomain;
   98                 return AH_TRUE;
   99         }
  100 #endif
  101         ecode = HAL_EIO;
  102 bad:
  103         if (status)
  104                 *status = ecode;
  105         return AH_FALSE;
  106 }
  107 
  108 /*
  109  * Return the wireless modes (a,b,g,t) supported by hardware.
  110  *
  111  * This value is what is actually supported by the hardware
  112  * and is unaffected by regulatory/country code settings.
  113  */
  114 u_int
  115 ar5212GetWirelessModes(struct ath_hal *ah)
  116 {
  117         u_int mode = 0;
  118 
  119         if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) {
  120                 mode = HAL_MODE_11A;
  121                 if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO5DISABLE))
  122                         mode |= HAL_MODE_TURBO | HAL_MODE_108A;
  123                 if (AH_PRIVATE(ah)->ah_caps.halChanHalfRate)
  124                         mode |= HAL_MODE_11A_HALF_RATE;
  125                 if (AH_PRIVATE(ah)->ah_caps.halChanQuarterRate)
  126                         mode |= HAL_MODE_11A_QUARTER_RATE;
  127         }
  128         if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE))
  129                 mode |= HAL_MODE_11B;
  130         if (ath_hal_eepromGetFlag(ah, AR_EEP_GMODE) &&
  131             AH_PRIVATE(ah)->ah_subvendorid != AR_SUBVENDOR_ID_NOG) {
  132                 mode |= HAL_MODE_11G;
  133                 if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO2DISABLE))
  134                         mode |= HAL_MODE_108G;
  135                 if (AH_PRIVATE(ah)->ah_caps.halChanHalfRate)
  136                         mode |= HAL_MODE_11G_HALF_RATE;
  137                 if (AH_PRIVATE(ah)->ah_caps.halChanQuarterRate)
  138                         mode |= HAL_MODE_11G_QUARTER_RATE;
  139         }
  140         return mode;
  141 }
  142 
  143 /*
  144  * Set the interrupt and GPIO values so the ISR can disable RF
  145  * on a switch signal.  Assumes GPIO port and interrupt polarity
  146  * are set prior to call.
  147  */
  148 void
  149 ar5212EnableRfKill(struct ath_hal *ah)
  150 {
  151         uint16_t rfsilent = AH_PRIVATE(ah)->ah_rfsilent;
  152         int select = MS(rfsilent, AR_EEPROM_RFSILENT_GPIO_SEL);
  153         int polarity = MS(rfsilent, AR_EEPROM_RFSILENT_POLARITY);
  154 
  155         /*
  156          * Configure the desired GPIO port for input
  157          * and enable baseband rf silence.
  158          */
  159         ath_hal_gpioCfgInput(ah, select);
  160         OS_REG_SET_BIT(ah, AR_PHY(0), 0x00002000);
  161         /*
  162          * If radio disable switch connection to GPIO bit x is enabled
  163          * program GPIO interrupt.
  164          * If rfkill bit on eeprom is 1, setupeeprommap routine has already
  165          * verified that it is a later version of eeprom, it has a place for
  166          * rfkill bit and it is set to 1, indicating that GPIO bit x hardware
  167          * connection is present.
  168          */
  169         ath_hal_gpioSetIntr(ah, select,
  170             (ath_hal_gpioGet(ah, select) == polarity ? !polarity : polarity));
  171 }
  172 
  173 /*
  174  * Change the LED blinking pattern to correspond to the connectivity
  175  */
  176 void
  177 ar5212SetLedState(struct ath_hal *ah, HAL_LED_STATE state)
  178 {
  179         static const uint32_t ledbits[8] = {
  180                 AR_PCICFG_LEDCTL_NONE,  /* HAL_LED_INIT */
  181                 AR_PCICFG_LEDCTL_PEND,  /* HAL_LED_SCAN */
  182                 AR_PCICFG_LEDCTL_PEND,  /* HAL_LED_AUTH */
  183                 AR_PCICFG_LEDCTL_ASSOC, /* HAL_LED_ASSOC*/
  184                 AR_PCICFG_LEDCTL_ASSOC, /* HAL_LED_RUN */
  185                 AR_PCICFG_LEDCTL_NONE,
  186                 AR_PCICFG_LEDCTL_NONE,
  187                 AR_PCICFG_LEDCTL_NONE,
  188         };
  189         uint32_t bits;
  190 
  191         bits = OS_REG_READ(ah, AR_PCICFG);
  192         if (IS_2417(ah)) {
  193                 /*
  194                  * Enable LED for Nala. There is a bit marked reserved
  195                  * that must be set and we also turn on the power led.
  196                  * Because we mark s/w LED control setting the control
  197                  * status bits below is meangless (the driver must flash
  198                  * the LED(s) using the GPIO lines).
  199                  */
  200                 bits = (bits &~ AR_PCICFG_LEDMODE)
  201                      | SM(AR_PCICFG_LEDMODE_POWON, AR_PCICFG_LEDMODE)
  202 #if 0
  203                      | SM(AR_PCICFG_LEDMODE_NETON, AR_PCICFG_LEDMODE)
  204 #endif
  205                      | 0x08000000;
  206         }
  207         bits = (bits &~ AR_PCICFG_LEDCTL)
  208              | SM(ledbits[state & 0x7], AR_PCICFG_LEDCTL);
  209         OS_REG_WRITE(ah, AR_PCICFG, bits);
  210 }
  211 
  212 /*
  213  * Change association related fields programmed into the hardware.
  214  * Writing a valid BSSID to the hardware effectively enables the hardware
  215  * to synchronize its TSF to the correct beacons and receive frames coming
  216  * from that BSSID. It is called by the SME JOIN operation.
  217  */
  218 void
  219 ar5212WriteAssocid(struct ath_hal *ah, const uint8_t *bssid, uint16_t assocId)
  220 {
  221         struct ath_hal_5212 *ahp = AH5212(ah);
  222 
  223         /* save bssid for possible re-use on reset */
  224         OS_MEMCPY(ahp->ah_bssid, bssid, IEEE80211_ADDR_LEN);
  225         ahp->ah_assocId = assocId;
  226         OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
  227         OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid+4) |
  228                                      ((assocId & 0x3fff)<<AR_BSS_ID1_AID_S));
  229 }
  230 
  231 /*
  232  * Get the current hardware tsf for stamlme
  233  */
  234 uint64_t
  235 ar5212GetTsf64(struct ath_hal *ah)
  236 {
  237         uint32_t low1, low2, u32;
  238 
  239         /* sync multi-word read */
  240         low1 = OS_REG_READ(ah, AR_TSF_L32);
  241         u32 = OS_REG_READ(ah, AR_TSF_U32);
  242         low2 = OS_REG_READ(ah, AR_TSF_L32);
  243         if (low2 < low1) {      /* roll over */
  244                 /*
  245                  * If we are not preempted this will work.  If we are
  246                  * then we re-reading AR_TSF_U32 does no good as the
  247                  * low bits will be meaningless.  Likewise reading
  248                  * L32, U32, U32, then comparing the last two reads
  249                  * to check for rollover doesn't help if preempted--so
  250                  * we take this approach as it costs one less PCI read
  251                  * which can be noticeable when doing things like
  252                  * timestamping packets in monitor mode.
  253                  */
  254                 u32++;
  255         }
  256         return (((uint64_t) u32) << 32) | ((uint64_t) low2);
  257 }
  258 
  259 /*
  260  * Get the current hardware tsf for stamlme
  261  */
  262 uint32_t
  263 ar5212GetTsf32(struct ath_hal *ah)
  264 {
  265         return OS_REG_READ(ah, AR_TSF_L32);
  266 }
  267 
  268 void
  269 ar5212SetTsf64(struct ath_hal *ah, uint64_t tsf64)
  270 {
  271         OS_REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
  272         OS_REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
  273 }
  274 
  275 /*
  276  * Reset the current hardware tsf for stamlme.
  277  */
  278 void
  279 ar5212ResetTsf(struct ath_hal *ah)
  280 {
  281 
  282         uint32_t val = OS_REG_READ(ah, AR_BEACON);
  283 
  284         OS_REG_WRITE(ah, AR_BEACON, val | AR_BEACON_RESET_TSF);
  285         /*
  286          * When resetting the TSF, write twice to the
  287          * corresponding register; each write to the RESET_TSF bit toggles
  288          * the internal signal to cause a reset of the TSF - but if the signal
  289          * is left high, it will reset the TSF on the next chip reset also!
  290          * writing the bit an even number of times fixes this issue
  291          */
  292         OS_REG_WRITE(ah, AR_BEACON, val | AR_BEACON_RESET_TSF);
  293 }
  294 
  295 /*
  296  * Set or clear hardware basic rate bit
  297  * Set hardware basic rate set if basic rate is found
  298  * and basic rate is equal or less than 2Mbps
  299  */
  300 void
  301 ar5212SetBasicRate(struct ath_hal *ah, HAL_RATE_SET *rs)
  302 {
  303         const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
  304         uint32_t reg;
  305         uint8_t xset;
  306         int i;
  307 
  308         if (chan == AH_NULL || !IEEE80211_IS_CHAN_CCK(chan))
  309                 return;
  310         xset = 0;
  311         for (i = 0; i < rs->rs_count; i++) {
  312                 uint8_t rset = rs->rs_rates[i];
  313                 /* Basic rate defined? */
  314                 if ((rset & 0x80) && (rset &= 0x7f) >= xset)
  315                         xset = rset;
  316         }
  317         /*
  318          * Set the h/w bit to reflect whether or not the basic
  319          * rate is found to be equal or less than 2Mbps.
  320          */
  321         reg = OS_REG_READ(ah, AR_STA_ID1);
  322         if (xset && xset/2 <= 2)
  323                 OS_REG_WRITE(ah, AR_STA_ID1, reg | AR_STA_ID1_BASE_RATE_11B);
  324         else
  325                 OS_REG_WRITE(ah, AR_STA_ID1, reg &~ AR_STA_ID1_BASE_RATE_11B);
  326 }
  327 
  328 /*
  329  * Grab a semi-random value from hardware registers - may not
  330  * change often
  331  */
  332 uint32_t
  333 ar5212GetRandomSeed(struct ath_hal *ah)
  334 {
  335         uint32_t nf;
  336 
  337         nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff;
  338         if (nf & 0x100)
  339                 nf = 0 - ((nf ^ 0x1ff) + 1);
  340         return (OS_REG_READ(ah, AR_TSF_U32) ^
  341                 OS_REG_READ(ah, AR_TSF_L32) ^ nf);
  342 }
  343 
  344 /*
  345  * Detect if our card is present
  346  */
  347 HAL_BOOL
  348 ar5212DetectCardPresent(struct ath_hal *ah)
  349 {
  350         uint16_t macVersion, macRev;
  351         uint32_t v;
  352 
  353         /*
  354          * Read the Silicon Revision register and compare that
  355          * to what we read at attach time.  If the same, we say
  356          * a card/device is present.
  357          */
  358         v = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID;
  359         macVersion = v >> AR_SREV_ID_S;
  360         macRev = v & AR_SREV_REVISION;
  361         return (AH_PRIVATE(ah)->ah_macVersion == macVersion &&
  362                 AH_PRIVATE(ah)->ah_macRev == macRev);
  363 }
  364 
  365 void
  366 ar5212EnableMibCounters(struct ath_hal *ah)
  367 {
  368         /* NB: this just resets the mib counter machinery */
  369         OS_REG_WRITE(ah, AR_MIBC,
  370             ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS) & 0x0f);
  371 }
  372 
  373 void 
  374 ar5212DisableMibCounters(struct ath_hal *ah)
  375 {
  376         OS_REG_WRITE(ah, AR_MIBC,  AR_MIBC | AR_MIBC_CMC);
  377 }
  378 
  379 /*
  380  * Update MIB Counters
  381  */
  382 void
  383 ar5212UpdateMibCounters(struct ath_hal *ah, HAL_MIB_STATS* stats)
  384 {
  385         stats->ackrcv_bad += OS_REG_READ(ah, AR_ACK_FAIL);
  386         stats->rts_bad    += OS_REG_READ(ah, AR_RTS_FAIL);
  387         stats->fcs_bad    += OS_REG_READ(ah, AR_FCS_FAIL);
  388         stats->rts_good   += OS_REG_READ(ah, AR_RTS_OK);
  389         stats->beacons    += OS_REG_READ(ah, AR_BEACON_CNT);
  390 }
  391 
  392 /*
  393  * Detect if the HW supports spreading a CCK signal on channel 14
  394  */
  395 HAL_BOOL
  396 ar5212IsJapanChannelSpreadSupported(struct ath_hal *ah)
  397 {
  398         return AH_TRUE;
  399 }
  400 
  401 /*
  402  * Get the rssi of frame curently being received.
  403  */
  404 uint32_t
  405 ar5212GetCurRssi(struct ath_hal *ah)
  406 {
  407         return (OS_REG_READ(ah, AR_PHY_CURRENT_RSSI) & 0xff);
  408 }
  409 
  410 u_int
  411 ar5212GetDefAntenna(struct ath_hal *ah)
  412 {   
  413         return (OS_REG_READ(ah, AR_DEF_ANTENNA) & 0x7);
  414 }   
  415 
  416 void
  417 ar5212SetDefAntenna(struct ath_hal *ah, u_int antenna)
  418 {
  419         OS_REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
  420 }
  421 
  422 HAL_ANT_SETTING
  423 ar5212GetAntennaSwitch(struct ath_hal *ah)
  424 {
  425         return AH5212(ah)->ah_antControl;
  426 }
  427 
  428 HAL_BOOL
  429 ar5212SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING setting)
  430 {
  431         struct ath_hal_5212 *ahp = AH5212(ah);
  432         const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
  433 
  434         if (!ahp->ah_phyPowerOn || chan == AH_NULL) {
  435                 /* PHY powered off, just stash settings */
  436                 ahp->ah_antControl = setting;
  437                 ahp->ah_diversity = (setting == HAL_ANT_VARIABLE);
  438                 return AH_TRUE;
  439         }
  440         return ar5212SetAntennaSwitchInternal(ah, setting, chan);
  441 }
  442 
  443 HAL_BOOL
  444 ar5212IsSleepAfterBeaconBroken(struct ath_hal *ah)
  445 {
  446         return AH_TRUE;
  447 }
  448 
  449 HAL_BOOL
  450 ar5212SetSifsTime(struct ath_hal *ah, u_int us)
  451 {
  452         struct ath_hal_5212 *ahp = AH5212(ah);
  453 
  454         if (us > ath_hal_mac_usec(ah, 0xffff)) {
  455                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad SIFS time %u\n",
  456                     __func__, us);
  457                 ahp->ah_sifstime = (u_int) -1;  /* restore default handling */
  458                 return AH_FALSE;
  459         } else {
  460                 /* convert to system clocks */
  461                 OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, ath_hal_mac_clks(ah, us-2));
  462                 ahp->ah_sifstime = us;
  463                 return AH_TRUE;
  464         }
  465 }
  466 
  467 u_int
  468 ar5212GetSifsTime(struct ath_hal *ah)
  469 {
  470         u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SIFS) & 0xffff;
  471         return ath_hal_mac_usec(ah, clks)+2;    /* convert from system clocks */
  472 }
  473 
  474 HAL_BOOL
  475 ar5212SetSlotTime(struct ath_hal *ah, u_int us)
  476 {
  477         struct ath_hal_5212 *ahp = AH5212(ah);
  478 
  479         if (us < HAL_SLOT_TIME_6 || us > ath_hal_mac_usec(ah, 0xffff)) {
  480                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad slot time %u\n",
  481                     __func__, us);
  482                 ahp->ah_slottime = (u_int) -1;  /* restore default handling */
  483                 return AH_FALSE;
  484         } else {
  485                 /* convert to system clocks */
  486                 OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath_hal_mac_clks(ah, us));
  487                 ahp->ah_slottime = us;
  488                 return AH_TRUE;
  489         }
  490 }
  491 
  492 u_int
  493 ar5212GetSlotTime(struct ath_hal *ah)
  494 {
  495         u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SLOT) & 0xffff;
  496         return ath_hal_mac_usec(ah, clks);      /* convert from system clocks */
  497 }
  498 
  499 HAL_BOOL
  500 ar5212SetAckTimeout(struct ath_hal *ah, u_int us)
  501 {
  502         struct ath_hal_5212 *ahp = AH5212(ah);
  503 
  504         if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
  505                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad ack timeout %u\n",
  506                     __func__, us);
  507                 ahp->ah_acktimeout = (u_int) -1; /* restore default handling */
  508                 return AH_FALSE;
  509         } else {
  510                 /* convert to system clocks */
  511                 OS_REG_RMW_FIELD(ah, AR_TIME_OUT,
  512                         AR_TIME_OUT_ACK, ath_hal_mac_clks(ah, us));
  513                 ahp->ah_acktimeout = us;
  514                 return AH_TRUE;
  515         }
  516 }
  517 
  518 u_int
  519 ar5212GetAckTimeout(struct ath_hal *ah)
  520 {
  521         u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_ACK);
  522         return ath_hal_mac_usec(ah, clks);      /* convert from system clocks */
  523 }
  524 
  525 u_int
  526 ar5212GetAckCTSRate(struct ath_hal *ah)
  527 {
  528         return ((AH5212(ah)->ah_staId1Defaults & AR_STA_ID1_ACKCTS_6MB) == 0);
  529 }
  530 
  531 HAL_BOOL
  532 ar5212SetAckCTSRate(struct ath_hal *ah, u_int high)
  533 {
  534         struct ath_hal_5212 *ahp = AH5212(ah);
  535 
  536         if (high) {
  537                 OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB);
  538                 ahp->ah_staId1Defaults &= ~AR_STA_ID1_ACKCTS_6MB;
  539         } else {
  540                 OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB);
  541                 ahp->ah_staId1Defaults |= AR_STA_ID1_ACKCTS_6MB;
  542         }
  543         return AH_TRUE;
  544 }
  545 
  546 HAL_BOOL
  547 ar5212SetCTSTimeout(struct ath_hal *ah, u_int us)
  548 {
  549         struct ath_hal_5212 *ahp = AH5212(ah);
  550 
  551         if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
  552                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad cts timeout %u\n",
  553                     __func__, us);
  554                 ahp->ah_ctstimeout = (u_int) -1; /* restore default handling */
  555                 return AH_FALSE;
  556         } else {
  557                 /* convert to system clocks */
  558                 OS_REG_RMW_FIELD(ah, AR_TIME_OUT,
  559                         AR_TIME_OUT_CTS, ath_hal_mac_clks(ah, us));
  560                 ahp->ah_ctstimeout = us;
  561                 return AH_TRUE;
  562         }
  563 }
  564 
  565 u_int
  566 ar5212GetCTSTimeout(struct ath_hal *ah)
  567 {
  568         u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS);
  569         return ath_hal_mac_usec(ah, clks);      /* convert from system clocks */
  570 }
  571 
  572 /* Setup decompression for given key index */
  573 HAL_BOOL
  574 ar5212SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en)
  575 {
  576         struct ath_hal_5212 *ahp = AH5212(ah);
  577 
  578         if (keyidx >= HAL_DECOMP_MASK_SIZE)
  579                 return AH_FALSE;
  580         OS_REG_WRITE(ah, AR_DCM_A, keyidx);
  581         OS_REG_WRITE(ah, AR_DCM_D, en ? AR_DCM_D_EN : 0);
  582         ahp->ah_decompMask[keyidx] = en;
  583 
  584         return AH_TRUE;
  585 }
  586 
  587 /* Setup coverage class */
  588 void
  589 ar5212SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
  590 {
  591         uint32_t slot, timeout, eifs;
  592         u_int clkRate;
  593 
  594         AH_PRIVATE(ah)->ah_coverageClass = coverageclass;
  595 
  596         if (now) {
  597                 if (AH_PRIVATE(ah)->ah_coverageClass == 0)
  598                         return;
  599 
  600                 /* Don't apply coverage class to non A channels */
  601                 if (!IEEE80211_IS_CHAN_A(AH_PRIVATE(ah)->ah_curchan))
  602                         return;
  603 
  604                 /* Get core clock rate */
  605                 clkRate = ath_hal_mac_clks(ah, 1);
  606 
  607                 /* Compute EIFS */
  608                 slot = coverageclass * 3 * clkRate;
  609                 eifs = coverageclass * 6 * clkRate;
  610                 if (IEEE80211_IS_CHAN_HALF(AH_PRIVATE(ah)->ah_curchan)) {
  611                         slot += IFS_SLOT_HALF_RATE;
  612                         eifs += IFS_EIFS_HALF_RATE;
  613                 } else if (IEEE80211_IS_CHAN_QUARTER(AH_PRIVATE(ah)->ah_curchan)) {
  614                         slot += IFS_SLOT_QUARTER_RATE;
  615                         eifs += IFS_EIFS_QUARTER_RATE;
  616                 } else { /* full rate */
  617                         slot += IFS_SLOT_FULL_RATE;
  618                         eifs += IFS_EIFS_FULL_RATE;
  619                 }
  620 
  621                 /*
  622                  * Add additional time for air propagation for ACK and CTS
  623                  * timeouts. This value is in core clocks.
  624                  */
  625                 timeout = ACK_CTS_TIMEOUT_11A + (coverageclass * 3 * clkRate);
  626 
  627                 /*
  628                  * Write the values: slot, eifs, ack/cts timeouts.
  629                  */
  630                 OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot);
  631                 OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs);
  632                 OS_REG_WRITE(ah, AR_TIME_OUT,
  633                           SM(timeout, AR_TIME_OUT_CTS)
  634                         | SM(timeout, AR_TIME_OUT_ACK));
  635         }
  636 }
  637 
  638 HAL_STATUS
  639 ar5212SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration,
  640     uint32_t nextStart, HAL_QUIET_FLAG flag)
  641 {
  642         OS_REG_WRITE(ah, AR_QUIET2, period | (duration << AR_QUIET2_QUIET_DUR_S));
  643         if (flag & HAL_QUIET_ENABLE) {
  644                 OS_REG_WRITE(ah, AR_QUIET1, nextStart | (1 << 16));
  645         }
  646         else {
  647                 OS_REG_WRITE(ah, AR_QUIET1, nextStart);
  648         }
  649         return HAL_OK;
  650 }
  651 
  652 void
  653 ar5212SetPCUConfig(struct ath_hal *ah)
  654 {
  655         ar5212SetOperatingMode(ah, AH_PRIVATE(ah)->ah_opmode);
  656 }
  657 
  658 /*
  659  * Return whether an external 32KHz crystal should be used
  660  * to reduce power consumption when sleeping.  We do so if
  661  * the crystal is present (obtained from EEPROM) and if we
  662  * are not running as an AP and are configured to use it.
  663  */
  664 HAL_BOOL
  665 ar5212Use32KHzclock(struct ath_hal *ah, HAL_OPMODE opmode)
  666 {
  667         if (opmode != HAL_M_HOSTAP) {
  668                 struct ath_hal_5212 *ahp = AH5212(ah);
  669                 return ath_hal_eepromGetFlag(ah, AR_EEP_32KHZCRYSTAL) &&
  670                        (ahp->ah_enable32kHzClock == USE_32KHZ ||
  671                         ahp->ah_enable32kHzClock == AUTO_32KHZ);
  672         } else
  673                 return AH_FALSE;
  674 }
  675 
  676 /*
  677  * If 32KHz clock exists, use it to lower power consumption during sleep
  678  *
  679  * Note: If clock is set to 32 KHz, delays on accessing certain
  680  *       baseband registers (27-31, 124-127) are required.
  681  */
  682 void
  683 ar5212SetupClock(struct ath_hal *ah, HAL_OPMODE opmode)
  684 {
  685         if (ar5212Use32KHzclock(ah, opmode)) {
  686                 /*
  687                  * Enable clocks to be turned OFF in BB during sleep
  688                  * and also enable turning OFF 32MHz/40MHz Refclk
  689                  * from A2.
  690                  */
  691                 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f);
  692                 OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
  693                     IS_RAD5112_ANY(ah) || IS_5413(ah) ? 0x14 : 0x18);
  694                 OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32, 1);
  695                 OS_REG_WRITE(ah, AR_TSF_PARM, 61);  /* 32 KHz TSF incr */
  696                 OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_SEL, 1);
  697 
  698                 if (IS_2413(ah) || IS_5413(ah) || IS_2417(ah)) {
  699                         OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT,   0x26);
  700                         OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL,        0x0d);
  701                         OS_REG_WRITE(ah, AR_PHY_M_SLEEP,           0x07);
  702                         OS_REG_WRITE(ah, AR_PHY_REFCLKDLY,         0x3f);
  703                         /* # Set sleep clock rate to 32 KHz. */
  704                         OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0x2);
  705                 } else {
  706                         OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT,   0x0a);
  707                         OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL,        0x0c);
  708                         OS_REG_WRITE(ah, AR_PHY_M_SLEEP,           0x03);
  709                         OS_REG_WRITE(ah, AR_PHY_REFCLKDLY,         0x20);
  710                         OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0x3);
  711                 }
  712         } else {
  713                 OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0x0);
  714                 OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_SEL, 0);
  715 
  716                 OS_REG_WRITE(ah, AR_TSF_PARM, 1);       /* 32MHz TSF inc */
  717 
  718                 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f);
  719                 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT,   0x7f);
  720 
  721                 if (IS_2417(ah))
  722                         OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0a);
  723                 else if (IS_HB63(ah))
  724                         OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x32);
  725                 else
  726                         OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
  727                 OS_REG_WRITE(ah, AR_PHY_M_SLEEP,           0x0c);
  728                 OS_REG_WRITE(ah, AR_PHY_REFCLKDLY,         0xff);
  729                 OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
  730                     IS_RAD5112_ANY(ah) || IS_5413(ah) || IS_2417(ah) ? 0x14 : 0x18);
  731                 OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32,
  732                     IS_RAD5112_ANY(ah) || IS_5413(ah) ? 39 : 31);
  733         }
  734 }
  735 
  736 /*
  737  * If 32KHz clock exists, turn it off and turn back on the 32Mhz
  738  */
  739 void
  740 ar5212RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode)
  741 {
  742         if (ar5212Use32KHzclock(ah, opmode)) {
  743                 /* # Set sleep clock rate back to 32 MHz. */
  744                 OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0);
  745                 OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_SEL, 0);
  746 
  747                 OS_REG_WRITE(ah, AR_TSF_PARM, 1);       /* 32 MHz TSF incr */
  748                 OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32,
  749                     IS_RAD5112_ANY(ah) || IS_5413(ah) ? 39 : 31);
  750 
  751                 /*
  752                  * Restore BB registers to power-on defaults
  753                  */
  754                 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f);
  755                 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT,   0x7f);
  756                 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL,        0x0e);
  757                 OS_REG_WRITE(ah, AR_PHY_M_SLEEP,           0x0c);
  758                 OS_REG_WRITE(ah, AR_PHY_REFCLKDLY,         0xff);
  759                 OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
  760                     IS_RAD5112_ANY(ah) || IS_5413(ah) ?  0x14 : 0x18);
  761         }
  762 }
  763 
  764 /*
  765  * Adjust NF based on statistical values for 5GHz frequencies.
  766  * Default method: this may be overridden by the rf backend.
  767  */
  768 int16_t
  769 ar5212GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c)
  770 {
  771         static const struct {
  772                 uint16_t freqLow;
  773                 int16_t   adjust;
  774         } adjustDef[] = {
  775                 { 5790, 11 },   /* NB: ordered high -> low */
  776                 { 5730, 10 },
  777                 { 5690,  9 },
  778                 { 5660,  8 },
  779                 { 5610,  7 },
  780                 { 5530,  5 },
  781                 { 5450,  4 },
  782                 { 5379,  2 },
  783                 { 5209,  0 },
  784                 { 3000,  1 },
  785                 {    0,  0 },
  786         };
  787         int i;
  788 
  789         for (i = 0; c->channel <= adjustDef[i].freqLow; i++)
  790                 ;
  791         return adjustDef[i].adjust;
  792 }
  793 
  794 HAL_STATUS
  795 ar5212GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
  796         uint32_t capability, uint32_t *result)
  797 {
  798 #define MACVERSION(ah)  AH_PRIVATE(ah)->ah_macVersion
  799         struct ath_hal_5212 *ahp = AH5212(ah);
  800         const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
  801         const struct ar5212AniState *ani;
  802 
  803         switch (type) {
  804         case HAL_CAP_CIPHER:            /* cipher handled in hardware */
  805                 switch (capability) {
  806                 case HAL_CIPHER_AES_CCM:
  807                         return pCap->halCipherAesCcmSupport ?
  808                                 HAL_OK : HAL_ENOTSUPP;
  809                 case HAL_CIPHER_AES_OCB:
  810                 case HAL_CIPHER_TKIP:
  811                 case HAL_CIPHER_WEP:
  812                 case HAL_CIPHER_MIC:
  813                 case HAL_CIPHER_CLR:
  814                         return HAL_OK;
  815                 default:
  816                         return HAL_ENOTSUPP;
  817                 }
  818         case HAL_CAP_TKIP_MIC:          /* handle TKIP MIC in hardware */
  819                 switch (capability) {
  820                 case 0:                 /* hardware capability */
  821                         return HAL_OK;
  822                 case 1:
  823                         return (ahp->ah_staId1Defaults &
  824                             AR_STA_ID1_CRPT_MIC_ENABLE) ?  HAL_OK : HAL_ENXIO;
  825                 }
  826                 return HAL_EINVAL;
  827         case HAL_CAP_TKIP_SPLIT:        /* hardware TKIP uses split keys */
  828                 switch (capability) {
  829                 case 0:                 /* hardware capability */
  830                         return pCap->halTkipMicTxRxKeySupport ?
  831                                 HAL_ENXIO : HAL_OK;
  832                 case 1:                 /* current setting */
  833                         return (ahp->ah_miscMode &
  834                             AR_MISC_MODE_MIC_NEW_LOC_ENABLE) ? HAL_ENXIO : HAL_OK;
  835                 }
  836                 return HAL_EINVAL;
  837         case HAL_CAP_WME_TKIPMIC:       /* hardware can do TKIP MIC w/ WMM */
  838                 /* XXX move to capability bit */
  839                 return MACVERSION(ah) > AR_SREV_VERSION_VENICE ||
  840                     (MACVERSION(ah) == AR_SREV_VERSION_VENICE &&
  841                      AH_PRIVATE(ah)->ah_macRev >= 8) ? HAL_OK : HAL_ENOTSUPP;
  842         case HAL_CAP_DIVERSITY:         /* hardware supports fast diversity */
  843                 switch (capability) {
  844                 case 0:                 /* hardware capability */
  845                         return HAL_OK;
  846                 case 1:                 /* current setting */
  847                         return ahp->ah_diversity ? HAL_OK : HAL_ENXIO;
  848                 case HAL_CAP_STRONG_DIV:
  849                         *result = OS_REG_READ(ah, AR_PHY_RESTART);
  850                         *result = MS(*result, AR_PHY_RESTART_DIV_GC);
  851                         return HAL_OK;
  852                 }
  853                 return HAL_EINVAL;
  854         case HAL_CAP_DIAG:
  855                 *result = AH_PRIVATE(ah)->ah_diagreg;
  856                 return HAL_OK;
  857         case HAL_CAP_TPC:
  858                 switch (capability) {
  859                 case 0:                 /* hardware capability */
  860                         return HAL_OK;
  861                 case 1:
  862                         return ahp->ah_tpcEnabled ? HAL_OK : HAL_ENXIO;
  863                 }
  864                 return HAL_OK;
  865         case HAL_CAP_PHYDIAG:           /* radar pulse detection capability */
  866                 switch (capability) {
  867                 case HAL_CAP_RADAR:
  868                         return ath_hal_eepromGetFlag(ah, AR_EEP_AMODE) ?
  869                             HAL_OK: HAL_ENXIO;
  870                 case HAL_CAP_AR:
  871                         return (ath_hal_eepromGetFlag(ah, AR_EEP_GMODE) ||
  872                             ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) ?
  873                                HAL_OK: HAL_ENXIO;
  874                 }
  875                 return HAL_ENXIO;
  876         case HAL_CAP_MCAST_KEYSRCH:     /* multicast frame keycache search */
  877                 switch (capability) {
  878                 case 0:                 /* hardware capability */
  879                         return pCap->halMcastKeySrchSupport ? HAL_OK : HAL_ENXIO;
  880                 case 1:
  881                         return (ahp->ah_staId1Defaults &
  882                             AR_STA_ID1_MCAST_KSRCH) ? HAL_OK : HAL_ENXIO;
  883                 }
  884                 return HAL_EINVAL;
  885         case HAL_CAP_TSF_ADJUST:        /* hardware has beacon tsf adjust */
  886                 switch (capability) {
  887                 case 0:                 /* hardware capability */
  888                         return pCap->halTsfAddSupport ? HAL_OK : HAL_ENOTSUPP;
  889                 case 1:
  890                         return (ahp->ah_miscMode & AR_MISC_MODE_TX_ADD_TSF) ?
  891                                 HAL_OK : HAL_ENXIO;
  892                 }
  893                 return HAL_EINVAL;
  894         case HAL_CAP_TPC_ACK:
  895                 *result = MS(ahp->ah_macTPC, AR_TPC_ACK);
  896                 return HAL_OK;
  897         case HAL_CAP_TPC_CTS:
  898                 *result = MS(ahp->ah_macTPC, AR_TPC_CTS);
  899                 return HAL_OK;
  900         case HAL_CAP_INTMIT:            /* interference mitigation */
  901                 switch (capability) {
  902                 case HAL_CAP_INTMIT_PRESENT:            /* hardware capability */
  903                         return HAL_OK;
  904                 case HAL_CAP_INTMIT_ENABLE:
  905                         return (ahp->ah_procPhyErr & HAL_ANI_ENA) ?
  906                                 HAL_OK : HAL_ENXIO;
  907                 case HAL_CAP_INTMIT_NOISE_IMMUNITY_LEVEL:
  908                 case HAL_CAP_INTMIT_OFDM_WEAK_SIGNAL_LEVEL:
  909                 case HAL_CAP_INTMIT_CCK_WEAK_SIGNAL_THR:
  910                 case HAL_CAP_INTMIT_FIRSTEP_LEVEL:
  911                 case HAL_CAP_INTMIT_SPUR_IMMUNITY_LEVEL:
  912                         ani = ar5212AniGetCurrentState(ah);
  913                         if (ani == AH_NULL)
  914                                 return HAL_ENXIO;
  915                         switch (capability) {
  916                         case 2: *result = ani->noiseImmunityLevel; break;
  917                         case 3: *result = !ani->ofdmWeakSigDetectOff; break;
  918                         case 4: *result = ani->cckWeakSigThreshold; break;
  919                         case 5: *result = ani->firstepLevel; break;
  920                         case 6: *result = ani->spurImmunityLevel; break;
  921                         }
  922                         return HAL_OK;
  923                 }
  924                 return HAL_EINVAL;
  925         default:
  926                 return ath_hal_getcapability(ah, type, capability, result);
  927         }
  928 #undef MACVERSION
  929 }
  930 
  931 HAL_BOOL
  932 ar5212SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
  933         uint32_t capability, uint32_t setting, HAL_STATUS *status)
  934 {
  935 #define N(a)    (sizeof(a)/sizeof(a[0]))
  936         struct ath_hal_5212 *ahp = AH5212(ah);
  937         const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
  938         uint32_t v;
  939 
  940         switch (type) {
  941         case HAL_CAP_TKIP_MIC:          /* handle TKIP MIC in hardware */
  942                 if (setting)
  943                         ahp->ah_staId1Defaults |= AR_STA_ID1_CRPT_MIC_ENABLE;
  944                 else
  945                         ahp->ah_staId1Defaults &= ~AR_STA_ID1_CRPT_MIC_ENABLE;
  946                 return AH_TRUE;
  947         case HAL_CAP_TKIP_SPLIT:        /* hardware TKIP uses split keys */
  948                 if (!pCap->halTkipMicTxRxKeySupport)
  949                         return AH_FALSE;
  950                 /* NB: true =>'s use split key cache layout */
  951                 if (setting)
  952                         ahp->ah_miscMode &= ~AR_MISC_MODE_MIC_NEW_LOC_ENABLE;
  953                 else
  954                         ahp->ah_miscMode |= AR_MISC_MODE_MIC_NEW_LOC_ENABLE;
  955                 /* NB: write here so keys can be setup w/o a reset */
  956                 OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode);
  957                 return AH_TRUE;
  958         case HAL_CAP_DIVERSITY:
  959                 switch (capability) {
  960                 case 0:
  961                         return AH_FALSE;
  962                 case 1: /* setting */
  963                         if (ahp->ah_phyPowerOn) {
  964                                 if (capability == HAL_CAP_STRONG_DIV) {
  965                                         v = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
  966                                         if (setting)
  967                                                 v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
  968                                         else
  969                                                 v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
  970                                         OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
  971                                 }
  972                         }
  973                         ahp->ah_diversity = (setting != 0);
  974                         return AH_TRUE;
  975 
  976                 case HAL_CAP_STRONG_DIV:
  977                         if (! ahp->ah_phyPowerOn)
  978                                 return AH_FALSE;
  979                         v = OS_REG_READ(ah, AR_PHY_RESTART);
  980                         v &= ~AR_PHY_RESTART_DIV_GC;
  981                         v |= SM(setting, AR_PHY_RESTART_DIV_GC);
  982                         OS_REG_WRITE(ah, AR_PHY_RESTART, v);
  983                         return AH_TRUE;
  984                 default:
  985                         return AH_FALSE;
  986                 }
  987         case HAL_CAP_DIAG:              /* hardware diagnostic support */
  988                 /*
  989                  * NB: could split this up into virtual capabilities,
  990                  *     (e.g. 1 => ACK, 2 => CTS, etc.) but it hardly
  991                  *     seems worth the additional complexity.
  992                  */
  993                 AH_PRIVATE(ah)->ah_diagreg = setting;
  994                 OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
  995                 return AH_TRUE;
  996         case HAL_CAP_TPC:
  997                 ahp->ah_tpcEnabled = (setting != 0);
  998                 return AH_TRUE;
  999         case HAL_CAP_MCAST_KEYSRCH:     /* multicast frame keycache search */
 1000                 if (setting)
 1001                         ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
 1002                 else
 1003                         ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
 1004                 return AH_TRUE;
 1005         case HAL_CAP_TPC_ACK:
 1006         case HAL_CAP_TPC_CTS:
 1007                 setting += ahp->ah_txPowerIndexOffset;
 1008                 if (setting > 63)
 1009                         setting = 63;
 1010                 if (type == HAL_CAP_TPC_ACK) {
 1011                         ahp->ah_macTPC &= AR_TPC_ACK;
 1012                         ahp->ah_macTPC |= MS(setting, AR_TPC_ACK);
 1013                 } else {
 1014                         ahp->ah_macTPC &= AR_TPC_CTS;
 1015                         ahp->ah_macTPC |= MS(setting, AR_TPC_CTS);
 1016                 }
 1017                 OS_REG_WRITE(ah, AR_TPC, ahp->ah_macTPC);
 1018                 return AH_TRUE;
 1019         case HAL_CAP_INTMIT: {          /* interference mitigation */
 1020                 /* This maps the public ANI commands to the internal ANI commands */
 1021                 /* Private: HAL_ANI_CMD; Public: HAL_CAP_INTMIT_CMD */
 1022                 static const HAL_ANI_CMD cmds[] = {
 1023                         HAL_ANI_PRESENT,
 1024                         HAL_ANI_MODE,
 1025                         HAL_ANI_NOISE_IMMUNITY_LEVEL,
 1026                         HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
 1027                         HAL_ANI_CCK_WEAK_SIGNAL_THR,
 1028                         HAL_ANI_FIRSTEP_LEVEL,
 1029                         HAL_ANI_SPUR_IMMUNITY_LEVEL,
 1030                 };
 1031                 return capability < N(cmds) ?
 1032                         AH5212(ah)->ah_aniControl(ah, cmds[capability], setting) :
 1033                         AH_FALSE;
 1034         }
 1035         case HAL_CAP_TSF_ADJUST:        /* hardware has beacon tsf adjust */
 1036                 if (pCap->halTsfAddSupport) {
 1037                         if (setting)
 1038                                 ahp->ah_miscMode |= AR_MISC_MODE_TX_ADD_TSF;
 1039                         else
 1040                                 ahp->ah_miscMode &= ~AR_MISC_MODE_TX_ADD_TSF;
 1041                         return AH_TRUE;
 1042                 }
 1043                 /* fall thru... */
 1044         default:
 1045                 return ath_hal_setcapability(ah, type, capability,
 1046                                 setting, status);
 1047         }
 1048 #undef N
 1049 }
 1050 
 1051 HAL_BOOL
 1052 ar5212GetDiagState(struct ath_hal *ah, int request,
 1053         const void *args, uint32_t argsize,
 1054         void **result, uint32_t *resultsize)
 1055 {
 1056         struct ath_hal_5212 *ahp = AH5212(ah);
 1057         HAL_ANI_STATS *astats;
 1058 
 1059         (void) ahp;
 1060         if (ath_hal_getdiagstate(ah, request, args, argsize, result, resultsize))
 1061                 return AH_TRUE;
 1062         switch (request) {
 1063         case HAL_DIAG_EEPROM:
 1064         case HAL_DIAG_EEPROM_EXP_11A:
 1065         case HAL_DIAG_EEPROM_EXP_11B:
 1066         case HAL_DIAG_EEPROM_EXP_11G:
 1067         case HAL_DIAG_RFGAIN:
 1068                 return ath_hal_eepromDiag(ah, request,
 1069                     args, argsize, result, resultsize);
 1070         case HAL_DIAG_RFGAIN_CURSTEP:
 1071                 *result = __DECONST(void *, ahp->ah_gainValues.currStep);
 1072                 *resultsize = (*result == AH_NULL) ?
 1073                         0 : sizeof(GAIN_OPTIMIZATION_STEP);
 1074                 return AH_TRUE;
 1075         case HAL_DIAG_PCDAC:
 1076                 *result = ahp->ah_pcdacTable;
 1077                 *resultsize = ahp->ah_pcdacTableSize;
 1078                 return AH_TRUE;
 1079         case HAL_DIAG_TXRATES:
 1080                 *result = &ahp->ah_ratesArray[0];
 1081                 *resultsize = sizeof(ahp->ah_ratesArray);
 1082                 return AH_TRUE;
 1083         case HAL_DIAG_ANI_CURRENT:
 1084                 *result = ar5212AniGetCurrentState(ah);
 1085                 *resultsize = (*result == AH_NULL) ?
 1086                         0 : sizeof(struct ar5212AniState);
 1087                 return AH_TRUE;
 1088         case HAL_DIAG_ANI_STATS:
 1089                 OS_MEMZERO(&ahp->ext_ani_stats, sizeof(ahp->ext_ani_stats));
 1090                 astats = ar5212AniGetCurrentStats(ah);
 1091                 if (astats == NULL) {
 1092                         *result = NULL;
 1093                         *resultsize = 0;
 1094                 } else {
 1095                         OS_MEMCPY(&ahp->ext_ani_stats, astats, sizeof(HAL_ANI_STATS));
 1096                         *result = &ahp->ext_ani_stats;
 1097                         *resultsize = sizeof(ahp->ext_ani_stats);
 1098                 }
 1099                 return AH_TRUE;
 1100         case HAL_DIAG_ANI_CMD:
 1101                 if (argsize != 2*sizeof(uint32_t))
 1102                         return AH_FALSE;
 1103                 AH5212(ah)->ah_aniControl(ah, ((const uint32_t *)args)[0],
 1104                         ((const uint32_t *)args)[1]);
 1105                 return AH_TRUE;
 1106         case HAL_DIAG_ANI_PARAMS:
 1107                 /*
 1108                  * NB: We assume struct ar5212AniParams is identical
 1109                  * to HAL_ANI_PARAMS; if they diverge then we'll need
 1110                  * to handle it here
 1111                  */
 1112                 if (argsize == 0 && args == AH_NULL) {
 1113                         struct ar5212AniState *aniState =
 1114                             ar5212AniGetCurrentState(ah);
 1115                         if (aniState == AH_NULL)
 1116                                 return AH_FALSE;
 1117                         *result = __DECONST(void *, aniState->params);
 1118                         *resultsize = sizeof(struct ar5212AniParams);
 1119                         return AH_TRUE;
 1120                 } else {
 1121                         if (argsize != sizeof(struct ar5212AniParams))
 1122                                 return AH_FALSE;
 1123                         return ar5212AniSetParams(ah, args, args);
 1124                 }
 1125                 break;
 1126         }
 1127         return AH_FALSE;
 1128 }
 1129 
 1130 /*
 1131  * Check whether there's an in-progress NF completion.
 1132  *
 1133  * Returns AH_TRUE if there's a in-progress NF calibration, AH_FALSE
 1134  * otherwise.
 1135  */
 1136 HAL_BOOL
 1137 ar5212IsNFCalInProgress(struct ath_hal *ah)
 1138 {
 1139         if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF)
 1140                 return AH_TRUE;
 1141         return AH_FALSE;
 1142 }
 1143 
 1144 /*
 1145  * Wait for an in-progress NF calibration to complete.
 1146  *
 1147  * The completion function waits "i" times 10uS.
 1148  * It returns AH_TRUE if the NF calibration completed (or was never
 1149  * in progress); AH_FALSE if it was still in progress after "i" checks.
 1150  */
 1151 HAL_BOOL
 1152 ar5212WaitNFCalComplete(struct ath_hal *ah, int i)
 1153 {
 1154         int j;
 1155         if (i <= 0)
 1156                 i = 1;    /* it should run at least once */
 1157         for (j = 0; j < i; j++) {
 1158                 if (! ar5212IsNFCalInProgress(ah))
 1159                         return AH_TRUE;
 1160                 OS_DELAY(10);
 1161         }
 1162         return AH_FALSE;
 1163 }
 1164 
 1165 void
 1166 ar5212EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
 1167 {
 1168         uint32_t val;
 1169         val = OS_REG_READ(ah, AR_PHY_RADAR_0);
 1170 
 1171         if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) {
 1172                 val &= ~AR_PHY_RADAR_0_FIRPWR;
 1173                 val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR);
 1174         }
 1175         if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) {
 1176                 val &= ~AR_PHY_RADAR_0_RRSSI;
 1177                 val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI);
 1178         }
 1179         if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) {
 1180                 val &= ~AR_PHY_RADAR_0_HEIGHT;
 1181                 val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT);
 1182         }
 1183         if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) {
 1184                 val &= ~AR_PHY_RADAR_0_PRSSI;
 1185                 val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
 1186         }
 1187         if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) {
 1188                 val &= ~AR_PHY_RADAR_0_INBAND;
 1189                 val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND);
 1190         }
 1191         if (pe->pe_enabled)
 1192                 val |= AR_PHY_RADAR_0_ENA;
 1193         else
 1194                 val &= ~ AR_PHY_RADAR_0_ENA;
 1195 
 1196         if (IS_5413(ah)) {
 1197                 if (pe->pe_blockradar == 1)
 1198                         OS_REG_SET_BIT(ah, AR_PHY_RADAR_2,
 1199                             AR_PHY_RADAR_2_BLOCKOFDMWEAK);
 1200                 else
 1201                         OS_REG_CLR_BIT(ah, AR_PHY_RADAR_2,
 1202                             AR_PHY_RADAR_2_BLOCKOFDMWEAK);
 1203 
 1204                 if (pe->pe_en_relstep_check == 1)
 1205                         OS_REG_SET_BIT(ah, AR_PHY_RADAR_2,
 1206                             AR_PHY_RADAR_2_ENRELSTEPCHK);
 1207                 else
 1208                         OS_REG_CLR_BIT(ah, AR_PHY_RADAR_2,
 1209                             AR_PHY_RADAR_2_ENRELSTEPCHK);
 1210 
 1211                 if (pe->pe_usefir128 == 1)
 1212                         OS_REG_SET_BIT(ah, AR_PHY_RADAR_2,
 1213                             AR_PHY_RADAR_2_USEFIR128);
 1214                 else
 1215                         OS_REG_CLR_BIT(ah, AR_PHY_RADAR_2,
 1216                             AR_PHY_RADAR_2_USEFIR128);
 1217 
 1218                 if (pe->pe_enmaxrssi == 1)
 1219                         OS_REG_SET_BIT(ah, AR_PHY_RADAR_2,
 1220                             AR_PHY_RADAR_2_ENMAXRSSI);
 1221                 else
 1222                         OS_REG_CLR_BIT(ah, AR_PHY_RADAR_2,
 1223                             AR_PHY_RADAR_2_ENMAXRSSI);
 1224 
 1225                 if (pe->pe_enrelpwr == 1)
 1226                         OS_REG_SET_BIT(ah, AR_PHY_RADAR_2,
 1227                             AR_PHY_RADAR_2_ENRELPWRCHK);
 1228                 else
 1229                         OS_REG_CLR_BIT(ah, AR_PHY_RADAR_2,
 1230                             AR_PHY_RADAR_2_ENRELPWRCHK);
 1231 
 1232                 if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL)
 1233                         OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_2,
 1234                             AR_PHY_RADAR_2_RELPWR, pe->pe_relpwr);
 1235 
 1236                 if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL)
 1237                         OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_2,
 1238                             AR_PHY_RADAR_2_RELSTEP, pe->pe_relstep);
 1239 
 1240                 if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL)
 1241                         OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_2,
 1242                             AR_PHY_RADAR_2_MAXLEN, pe->pe_maxlen);
 1243         }
 1244 
 1245         OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
 1246 }
 1247 
 1248 /*
 1249  * Parameters for the AR5212 PHY.
 1250  */
 1251 #define AR5212_DFS_FIRPWR       -35
 1252 #define AR5212_DFS_RRSSI        20
 1253 #define AR5212_DFS_HEIGHT       14
 1254 #define AR5212_DFS_PRSSI        6
 1255 #define AR5212_DFS_INBAND       4
 1256 
 1257 /*
 1258  * Default parameters for the AR5413 PHY.
 1259  */
 1260 #define AR5413_DFS_FIRPWR       -34
 1261 #define AR5413_DFS_RRSSI        20
 1262 #define AR5413_DFS_HEIGHT       10
 1263 #define AR5413_DFS_PRSSI        15
 1264 #define AR5413_DFS_INBAND       6
 1265 #define AR5413_DFS_RELPWR       8
 1266 #define AR5413_DFS_RELSTEP      31
 1267 #define AR5413_DFS_MAXLEN       255
 1268 
 1269 HAL_BOOL
 1270 ar5212GetDfsDefaultThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
 1271 {
 1272 
 1273         if (IS_5413(ah)) {
 1274                 pe->pe_firpwr = AR5413_DFS_FIRPWR;
 1275                 pe->pe_rrssi = AR5413_DFS_RRSSI;
 1276                 pe->pe_height = AR5413_DFS_HEIGHT;
 1277                 pe->pe_prssi = AR5413_DFS_PRSSI;
 1278                 pe->pe_inband = AR5413_DFS_INBAND;
 1279                 pe->pe_relpwr = AR5413_DFS_RELPWR;
 1280                 pe->pe_relstep = AR5413_DFS_RELSTEP;
 1281                 pe->pe_maxlen = AR5413_DFS_MAXLEN;
 1282                 pe->pe_usefir128 = 0;
 1283                 pe->pe_blockradar = 1;
 1284                 pe->pe_enmaxrssi = 1;
 1285                 pe->pe_enrelpwr = 1;
 1286                 pe->pe_en_relstep_check = 0;
 1287         } else {
 1288                 pe->pe_firpwr = AR5212_DFS_FIRPWR;
 1289                 pe->pe_rrssi = AR5212_DFS_RRSSI;
 1290                 pe->pe_height = AR5212_DFS_HEIGHT;
 1291                 pe->pe_prssi = AR5212_DFS_PRSSI;
 1292                 pe->pe_inband = AR5212_DFS_INBAND;
 1293                 pe->pe_relpwr = 0;
 1294                 pe->pe_relstep = 0;
 1295                 pe->pe_maxlen = 0;
 1296                 pe->pe_usefir128 = 0;
 1297                 pe->pe_blockradar = 0;
 1298                 pe->pe_enmaxrssi = 0;
 1299                 pe->pe_enrelpwr = 0;
 1300                 pe->pe_en_relstep_check = 0;
 1301         }
 1302 
 1303         return (AH_TRUE);
 1304 }
 1305 
 1306 void
 1307 ar5212GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
 1308 {
 1309         uint32_t val,temp;
 1310 
 1311         val = OS_REG_READ(ah, AR_PHY_RADAR_0);
 1312 
 1313         temp = MS(val,AR_PHY_RADAR_0_FIRPWR);
 1314         temp |= 0xFFFFFF80;
 1315         pe->pe_firpwr = temp;
 1316         pe->pe_rrssi = MS(val, AR_PHY_RADAR_0_RRSSI);
 1317         pe->pe_height =  MS(val, AR_PHY_RADAR_0_HEIGHT);
 1318         pe->pe_prssi = MS(val, AR_PHY_RADAR_0_PRSSI);
 1319         pe->pe_inband = MS(val, AR_PHY_RADAR_0_INBAND);
 1320         pe->pe_enabled = !! (val & AR_PHY_RADAR_0_ENA);
 1321 
 1322         pe->pe_relpwr = 0;
 1323         pe->pe_relstep = 0;
 1324         pe->pe_maxlen = 0;
 1325         pe->pe_usefir128 = 0;
 1326         pe->pe_blockradar = 0;
 1327         pe->pe_enmaxrssi = 0;
 1328         pe->pe_enrelpwr = 0;
 1329         pe->pe_en_relstep_check = 0;
 1330         pe->pe_extchannel = AH_FALSE;
 1331 
 1332         if (IS_5413(ah)) {
 1333                 val = OS_REG_READ(ah, AR_PHY_RADAR_2);
 1334                 pe->pe_relpwr = !! MS(val, AR_PHY_RADAR_2_RELPWR);
 1335                 pe->pe_relstep = !! MS(val, AR_PHY_RADAR_2_RELSTEP);
 1336                 pe->pe_maxlen = !! MS(val, AR_PHY_RADAR_2_MAXLEN);
 1337 
 1338                 pe->pe_usefir128 = !! (val & AR_PHY_RADAR_2_USEFIR128);
 1339                 pe->pe_blockradar = !! (val & AR_PHY_RADAR_2_BLOCKOFDMWEAK);
 1340                 pe->pe_enmaxrssi = !! (val & AR_PHY_RADAR_2_ENMAXRSSI);
 1341                 pe->pe_enrelpwr = !! (val & AR_PHY_RADAR_2_ENRELPWRCHK);
 1342                 pe->pe_en_relstep_check =
 1343                     !! (val & AR_PHY_RADAR_2_ENRELSTEPCHK);
 1344         }
 1345 }
 1346 
 1347 /*
 1348  * Process the radar phy error and extract the pulse duration.
 1349  */
 1350 HAL_BOOL
 1351 ar5212ProcessRadarEvent(struct ath_hal *ah, struct ath_rx_status *rxs,
 1352     uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event)
 1353 {
 1354         uint8_t dur;
 1355         uint8_t rssi;
 1356 
 1357         /* Check whether the given phy error is a radar event */
 1358         if ((rxs->rs_phyerr != HAL_PHYERR_RADAR) &&
 1359             (rxs->rs_phyerr != HAL_PHYERR_FALSE_RADAR_EXT))
 1360                 return AH_FALSE;
 1361 
 1362         /*
 1363          * The first byte is the pulse width - if there's
 1364          * no data, simply set the duration to 0
 1365          */
 1366         if (rxs->rs_datalen >= 1)
 1367                 /* The pulse width is byte 0 of the data */
 1368                 dur = ((uint8_t) buf[0]) & 0xff;
 1369         else
 1370                 dur = 0;
 1371 
 1372         /* Pulse RSSI is the normal reported RSSI */
 1373         rssi = (uint8_t) rxs->rs_rssi;
 1374 
 1375         /* 0 duration/rssi is not a valid radar event */
 1376         if (dur == 0 && rssi == 0)
 1377                 return AH_FALSE;
 1378 
 1379         HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, dur=%d\n",
 1380             __func__, rssi, dur);
 1381 
 1382         /* Record the event */
 1383         event->re_full_ts = fulltsf;
 1384         event->re_ts = rxs->rs_tstamp;
 1385         event->re_rssi = rssi;
 1386         event->re_dur = dur;
 1387         event->re_flags = HAL_DFS_EVENT_PRICH;
 1388 
 1389         return AH_TRUE;
 1390 }
 1391 
 1392 /*
 1393  * Return whether 5GHz fast-clock (44MHz) is enabled.
 1394  * It's always disabled for AR5212 series NICs.
 1395  */
 1396 HAL_BOOL
 1397 ar5212IsFastClockEnabled(struct ath_hal *ah)
 1398 {
 1399         return AH_FALSE;
 1400 }
 1401 
 1402 /*
 1403  * Return what percentage of the extension channel is busy.
 1404  * This is always disabled for AR5212 series NICs.
 1405  */
 1406 uint32_t
 1407 ar5212Get11nExtBusy(struct ath_hal *ah)
 1408 {
 1409         return 0;
 1410 }
 1411 
 1412 /*
 1413  * Channel survey support.
 1414  */
 1415 HAL_BOOL
 1416 ar5212GetMibCycleCounts(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hsample)
 1417 {
 1418         struct ath_hal_5212 *ahp = AH5212(ah);
 1419         u_int32_t good = AH_TRUE;
 1420 
 1421         /* XXX freeze/unfreeze mib counters */
 1422         uint32_t rc = OS_REG_READ(ah, AR_RCCNT);
 1423         uint32_t rf = OS_REG_READ(ah, AR_RFCNT);
 1424         uint32_t tf = OS_REG_READ(ah, AR_TFCNT);
 1425         uint32_t cc = OS_REG_READ(ah, AR_CCCNT); /* read cycles last */
 1426 
 1427         if (ahp->ah_cycleCount == 0 || ahp->ah_cycleCount > cc) {
 1428                 /*
 1429                  * Cycle counter wrap (or initial call); it's not possible
 1430                  * to accurately calculate a value because the registers
 1431                  * right shift rather than wrap--so punt and return 0.
 1432                  */
 1433                 HALDEBUG(ah, HAL_DEBUG_ANY,
 1434                     "%s: cycle counter wrap. ExtBusy = 0\n", __func__);
 1435                 good = AH_FALSE;
 1436         } else {
 1437                 hsample->cycle_count = cc - ahp->ah_cycleCount;
 1438                 hsample->chan_busy = rc - ahp->ah_ctlBusy;
 1439                 hsample->ext_chan_busy = 0;
 1440                 hsample->rx_busy = rf - ahp->ah_rxBusy;
 1441                 hsample->tx_busy = tf - ahp->ah_txBusy;
 1442         }
 1443 
 1444         /*
 1445          * Keep a copy of the MIB results so the next sample has something
 1446          * to work from.
 1447          */
 1448         ahp->ah_cycleCount = cc;
 1449         ahp->ah_rxBusy = rf;
 1450         ahp->ah_ctlBusy = rc;
 1451         ahp->ah_txBusy = tf;
 1452 
 1453         return (good);
 1454 }
 1455 
 1456 void
 1457 ar5212SetChainMasks(struct ath_hal *ah, uint32_t tx_chainmask,
 1458     uint32_t rx_chainmask)
 1459 {
 1460 }
 1461 
 1462 /*
 1463  * Get the current NAV value from the hardware.
 1464  *
 1465  * 0xdeadbeef indicates the hardware is currently powered off.
 1466  */
 1467 u_int
 1468 ar5212GetNav(struct ath_hal *ah)
 1469 {
 1470         uint32_t reg;
 1471 
 1472         reg = OS_REG_READ(ah, AR_NAV);
 1473 
 1474         if (reg == 0xdeadbeef)
 1475                 return (0);
 1476         return (reg);
 1477 }
 1478 
 1479 /*
 1480  * Set the current NAV value to the hardware.
 1481  */
 1482 void
 1483 ar5212SetNav(struct ath_hal *ah, u_int val)
 1484 {
 1485 
 1486         OS_REG_WRITE(ah, AR_NAV, val);
 1487 }

Cache object: ef50910fdcbb2fd7cc174ca5621dc67d


[ 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.