Path: blob/main/sys/dev/ath/ath_hal/ar5211/ar5211_misc.c
39566 views
/*-1* SPDX-License-Identifier: ISC2*3* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting4* Copyright (c) 2002-2006 Atheros Communications, Inc.5*6* Permission to use, copy, modify, and/or distribute this software for any7* purpose with or without fee is hereby granted, provided that the above8* copyright notice and this permission notice appear in all copies.9*10* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES11* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF12* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR13* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES14* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN15* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF16* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.17*/18#include "opt_ah.h"1920#include "ah.h"21#include "ah_internal.h"2223#include "ar5211/ar5211.h"24#include "ar5211/ar5211reg.h"25#include "ar5211/ar5211phy.h"2627#include "ah_eeprom_v3.h"2829#define AR_NUM_GPIO 6 /* 6 GPIO bits */30#define AR_GPIOD_MASK 0x2f /* 6-bit mask */3132void33ar5211GetMacAddress(struct ath_hal *ah, uint8_t *mac)34{35struct ath_hal_5211 *ahp = AH5211(ah);3637OS_MEMCPY(mac, ahp->ah_macaddr, IEEE80211_ADDR_LEN);38}3940HAL_BOOL41ar5211SetMacAddress(struct ath_hal *ah, const uint8_t *mac)42{43struct ath_hal_5211 *ahp = AH5211(ah);4445OS_MEMCPY(ahp->ah_macaddr, mac, IEEE80211_ADDR_LEN);46return AH_TRUE;47}4849void50ar5211GetBssIdMask(struct ath_hal *ah, uint8_t *mask)51{52static const uint8_t ones[IEEE80211_ADDR_LEN] =53{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };54OS_MEMCPY(mask, ones, IEEE80211_ADDR_LEN);55}5657HAL_BOOL58ar5211SetBssIdMask(struct ath_hal *ah, const uint8_t *mask)59{60return AH_FALSE;61}6263/*64* Read 16 bits of data from the specified EEPROM offset.65*/66HAL_BOOL67ar5211EepromRead(struct ath_hal *ah, u_int off, uint16_t *data)68{69OS_REG_WRITE(ah, AR_EEPROM_ADDR, off);70OS_REG_WRITE(ah, AR_EEPROM_CMD, AR_EEPROM_CMD_READ);7172if (!ath_hal_wait(ah, AR_EEPROM_STS,73AR_EEPROM_STS_READ_COMPLETE | AR_EEPROM_STS_READ_ERROR,74AR_EEPROM_STS_READ_COMPLETE)) {75HALDEBUG(ah, HAL_DEBUG_ANY,76"%s: read failed for entry 0x%x\n", __func__, off);77return AH_FALSE;78}79*data = OS_REG_READ(ah, AR_EEPROM_DATA) & 0xffff;80return AH_TRUE;81}8283#ifdef AH_SUPPORT_WRITE_EEPROM84/*85* Write 16 bits of data to the specified EEPROM offset.86*/87HAL_BOOL88ar5211EepromWrite(struct ath_hal *ah, u_int off, uint16_t data)89{90return AH_FALSE;91}92#endif /* AH_SUPPORT_WRITE_EEPROM */9394/*95* Attempt to change the cards operating regulatory domain to the given value96*/97HAL_BOOL98ar5211SetRegulatoryDomain(struct ath_hal *ah,99uint16_t regDomain, HAL_STATUS *status)100{101HAL_STATUS ecode;102103if (AH_PRIVATE(ah)->ah_currentRD == regDomain) {104ecode = HAL_EINVAL;105goto bad;106}107/*108* Check if EEPROM is configured to allow this; must109* be a proper version and the protection bits must110* permit re-writing that segment of the EEPROM.111*/112if (ath_hal_eepromGetFlag(ah, AR_EEP_WRITEPROTECT)) {113ecode = HAL_EEWRITE;114goto bad;115}116#ifdef AH_SUPPORT_WRITE_REGDOMAIN117if (ar5211EepromWrite(ah, AR_EEPROM_REG_DOMAIN, regDomain)) {118HALDEBUG(ah, HAL_DEBUG_ANY,119"%s: set regulatory domain to %u (0x%x)\n",120__func__, regDomain, regDomain);121AH_PRIVATE(ah)->ah_currentRD = regDomain;122return AH_TRUE;123}124#endif125ecode = HAL_EIO;126bad:127if (status)128*status = ecode;129return AH_FALSE;130}131132/*133* Return the wireless modes (a,b,g,t) supported by hardware.134*135* This value is what is actually supported by the hardware136* and is unaffected by regulatory/country code settings.137*138*/139u_int140ar5211GetWirelessModes(struct ath_hal *ah)141{142u_int mode = 0;143144if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) {145mode = HAL_MODE_11A;146if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO5DISABLE))147mode |= HAL_MODE_TURBO | HAL_MODE_108A;148}149if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE))150mode |= HAL_MODE_11B;151return mode;152}153154#if 0155HAL_BOOL156ar5211GetTurboDisable(struct ath_hal *ah)157{158return (AH5211(ah)->ah_turboDisable != 0);159}160#endif161162/*163* Called if RfKill is supported (according to EEPROM). Set the interrupt and164* GPIO values so the ISR and can disable RF on a switch signal165*/166void167ar5211EnableRfKill(struct ath_hal *ah)168{169uint16_t rfsilent = AH_PRIVATE(ah)->ah_rfsilent;170int select = MS(rfsilent, AR_EEPROM_RFSILENT_GPIO_SEL);171int polarity = MS(rfsilent, AR_EEPROM_RFSILENT_POLARITY);172173/*174* Configure the desired GPIO port for input175* and enable baseband rf silence.176*/177ar5211GpioCfgInput(ah, select);178OS_REG_SET_BIT(ah, AR_PHY_BASE, 0x00002000);179/*180* If radio disable switch connection to GPIO bit x is enabled181* program GPIO interrupt.182* If rfkill bit on eeprom is 1, setupeeprommap routine has already183* verified that it is a later version of eeprom, it has a place for184* rfkill bit and it is set to 1, indicating that GPIO bit x hardware185* connection is present.186*/187ar5211GpioSetIntr(ah, select, (ar5211GpioGet(ah, select) != polarity));188}189190/*191* Configure GPIO Output lines192*/193HAL_BOOL194ar5211GpioCfgOutput(struct ath_hal *ah, uint32_t gpio, HAL_GPIO_MUX_TYPE type)195{196uint32_t reg;197198HALASSERT(gpio < AR_NUM_GPIO);199200reg = OS_REG_READ(ah, AR_GPIOCR);201reg &= ~(AR_GPIOCR_0_CR_A << (gpio * AR_GPIOCR_CR_SHIFT));202reg |= AR_GPIOCR_0_CR_A << (gpio * AR_GPIOCR_CR_SHIFT);203204OS_REG_WRITE(ah, AR_GPIOCR, reg);205return AH_TRUE;206}207208/*209* Configure GPIO Input lines210*/211HAL_BOOL212ar5211GpioCfgInput(struct ath_hal *ah, uint32_t gpio)213{214uint32_t reg;215216HALASSERT(gpio < AR_NUM_GPIO);217218reg = OS_REG_READ(ah, AR_GPIOCR);219reg &= ~(AR_GPIOCR_0_CR_A << (gpio * AR_GPIOCR_CR_SHIFT));220reg |= AR_GPIOCR_0_CR_N << (gpio * AR_GPIOCR_CR_SHIFT);221222OS_REG_WRITE(ah, AR_GPIOCR, reg);223return AH_TRUE;224}225226/*227* Once configured for I/O - set output lines228*/229HAL_BOOL230ar5211GpioSet(struct ath_hal *ah, uint32_t gpio, uint32_t val)231{232uint32_t reg;233234HALASSERT(gpio < AR_NUM_GPIO);235236reg = OS_REG_READ(ah, AR_GPIODO);237reg &= ~(1 << gpio);238reg |= (val&1) << gpio;239240OS_REG_WRITE(ah, AR_GPIODO, reg);241return AH_TRUE;242}243244/*245* Once configured for I/O - get input lines246*/247uint32_t248ar5211GpioGet(struct ath_hal *ah, uint32_t gpio)249{250if (gpio < AR_NUM_GPIO) {251uint32_t val = OS_REG_READ(ah, AR_GPIODI);252val = ((val & AR_GPIOD_MASK) >> gpio) & 0x1;253return val;254} else {255return 0xffffffff;256}257}258259/*260* Set the GPIO 0 Interrupt (gpio is ignored)261*/262void263ar5211GpioSetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel)264{265uint32_t val = OS_REG_READ(ah, AR_GPIOCR);266267/* Clear the bits that we will modify. */268val &= ~(AR_GPIOCR_INT_SEL0 | AR_GPIOCR_INT_SELH | AR_GPIOCR_INT_ENA |269AR_GPIOCR_0_CR_A);270271val |= AR_GPIOCR_INT_SEL0 | AR_GPIOCR_INT_ENA;272if (ilevel)273val |= AR_GPIOCR_INT_SELH;274275/* Don't need to change anything for low level interrupt. */276OS_REG_WRITE(ah, AR_GPIOCR, val);277278/* Change the interrupt mask. */279ar5211SetInterrupts(ah, AH5211(ah)->ah_maskReg | HAL_INT_GPIO);280}281282/*283* Change the LED blinking pattern to correspond to the connectivity284*/285void286ar5211SetLedState(struct ath_hal *ah, HAL_LED_STATE state)287{288static const uint32_t ledbits[8] = {289AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_PROP, /* HAL_LED_INIT */290AR_PCICFG_LEDCTL_PEND|AR_PCICFG_LEDMODE_PROP, /* HAL_LED_SCAN */291AR_PCICFG_LEDCTL_PEND|AR_PCICFG_LEDMODE_PROP, /* HAL_LED_AUTH */292AR_PCICFG_LEDCTL_ASSOC|AR_PCICFG_LEDMODE_PROP,/* HAL_LED_ASSOC*/293AR_PCICFG_LEDCTL_ASSOC|AR_PCICFG_LEDMODE_PROP,/* HAL_LED_RUN */294AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_RAND,295AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_RAND,296AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_RAND,297};298OS_REG_WRITE(ah, AR_PCICFG,299(OS_REG_READ(ah, AR_PCICFG) &~300(AR_PCICFG_LEDCTL | AR_PCICFG_LEDMODE))301| ledbits[state & 0x7]302);303}304305/*306* Change association related fields programmed into the hardware.307* Writing a valid BSSID to the hardware effectively enables the hardware308* to synchronize its TSF to the correct beacons and receive frames coming309* from that BSSID. It is called by the SME JOIN operation.310*/311void312ar5211WriteAssocid(struct ath_hal *ah, const uint8_t *bssid, uint16_t assocId)313{314struct ath_hal_5211 *ahp = AH5211(ah);315316/* XXX save bssid for possible re-use on reset */317OS_MEMCPY(ahp->ah_bssid, bssid, IEEE80211_ADDR_LEN);318OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));319OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid+4) |320((assocId & 0x3fff)<<AR_BSS_ID1_AID_S));321}322323/*324* Get the current hardware tsf for stamlme.325*/326uint64_t327ar5211GetTsf64(struct ath_hal *ah)328{329uint32_t low1, low2, u32;330331/* sync multi-word read */332low1 = OS_REG_READ(ah, AR_TSF_L32);333u32 = OS_REG_READ(ah, AR_TSF_U32);334low2 = OS_REG_READ(ah, AR_TSF_L32);335if (low2 < low1) { /* roll over */336/*337* If we are not preempted this will work. If we are338* then we re-reading AR_TSF_U32 does no good as the339* low bits will be meaningless. Likewise reading340* L32, U32, U32, then comparing the last two reads341* to check for rollover doesn't help if preempted--so342* we take this approach as it costs one less PCI343* read which can be noticeable when doing things344* like timestamping packets in monitor mode.345*/346u32++;347}348return (((uint64_t) u32) << 32) | ((uint64_t) low2);349}350351/*352* Get the current hardware tsf for stamlme.353*/354uint32_t355ar5211GetTsf32(struct ath_hal *ah)356{357return OS_REG_READ(ah, AR_TSF_L32);358}359360/*361* Reset the current hardware tsf for stamlme362*/363void364ar5211ResetTsf(struct ath_hal *ah)365{366uint32_t val = OS_REG_READ(ah, AR_BEACON);367368OS_REG_WRITE(ah, AR_BEACON, val | AR_BEACON_RESET_TSF);369}370371/*372* Grab a semi-random value from hardware registers - may not373* change often374*/375uint32_t376ar5211GetRandomSeed(struct ath_hal *ah)377{378uint32_t nf;379380nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff;381if (nf & 0x100)382nf = 0 - ((nf ^ 0x1ff) + 1);383return (OS_REG_READ(ah, AR_TSF_U32) ^384OS_REG_READ(ah, AR_TSF_L32) ^ nf);385}386387/*388* Detect if our card is present389*/390HAL_BOOL391ar5211DetectCardPresent(struct ath_hal *ah)392{393uint16_t macVersion, macRev;394uint32_t v;395396/*397* Read the Silicon Revision register and compare that398* to what we read at attach time. If the same, we say399* a card/device is present.400*/401v = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID_M;402macVersion = v >> AR_SREV_ID_S;403macRev = v & AR_SREV_REVISION_M;404return (AH_PRIVATE(ah)->ah_macVersion == macVersion &&405AH_PRIVATE(ah)->ah_macRev == macRev);406}407408/*409* Update MIB Counters410*/411void412ar5211UpdateMibCounters(struct ath_hal *ah, HAL_MIB_STATS *stats)413{414stats->ackrcv_bad += OS_REG_READ(ah, AR_ACK_FAIL);415stats->rts_bad += OS_REG_READ(ah, AR_RTS_FAIL);416stats->fcs_bad += OS_REG_READ(ah, AR_FCS_FAIL);417stats->rts_good += OS_REG_READ(ah, AR_RTS_OK);418stats->beacons += OS_REG_READ(ah, AR_BEACON_CNT);419}420421HAL_BOOL422ar5211SetSifsTime(struct ath_hal *ah, u_int us)423{424struct ath_hal_5211 *ahp = AH5211(ah);425426if (us > ath_hal_mac_usec(ah, 0xffff)) {427HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad SIFS time %u\n",428__func__, us);429ahp->ah_sifstime = (u_int) -1; /* restore default handling */430return AH_FALSE;431} else {432/* convert to system clocks */433OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, ath_hal_mac_clks(ah, us));434ahp->ah_slottime = us;435return AH_TRUE;436}437}438439u_int440ar5211GetSifsTime(struct ath_hal *ah)441{442u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SIFS) & 0xffff;443return ath_hal_mac_usec(ah, clks); /* convert from system clocks */444}445446HAL_BOOL447ar5211SetSlotTime(struct ath_hal *ah, u_int us)448{449struct ath_hal_5211 *ahp = AH5211(ah);450451if (us < HAL_SLOT_TIME_9 || us > ath_hal_mac_usec(ah, 0xffff)) {452HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad slot time %u\n",453__func__, us);454ahp->ah_slottime = us; /* restore default handling */455return AH_FALSE;456} else {457/* convert to system clocks */458OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath_hal_mac_clks(ah, us));459ahp->ah_slottime = us;460return AH_TRUE;461}462}463464u_int465ar5211GetSlotTime(struct ath_hal *ah)466{467u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SLOT) & 0xffff;468return ath_hal_mac_usec(ah, clks); /* convert from system clocks */469}470471HAL_BOOL472ar5211SetAckTimeout(struct ath_hal *ah, u_int us)473{474struct ath_hal_5211 *ahp = AH5211(ah);475476if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {477HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad ack timeout %u\n",478__func__, us);479ahp->ah_acktimeout = (u_int) -1; /* restore default handling */480return AH_FALSE;481} else {482/* convert to system clocks */483OS_REG_RMW_FIELD(ah, AR_TIME_OUT,484AR_TIME_OUT_ACK, ath_hal_mac_clks(ah, us));485ahp->ah_acktimeout = us;486return AH_TRUE;487}488}489490u_int491ar5211GetAckTimeout(struct ath_hal *ah)492{493u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_ACK);494return ath_hal_mac_usec(ah, clks); /* convert from system clocks */495}496497u_int498ar5211GetAckCTSRate(struct ath_hal *ah)499{500return ((AH5211(ah)->ah_staId1Defaults & AR_STA_ID1_ACKCTS_6MB) == 0);501}502503HAL_BOOL504ar5211SetAckCTSRate(struct ath_hal *ah, u_int high)505{506struct ath_hal_5211 *ahp = AH5211(ah);507508if (high) {509OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB);510ahp->ah_staId1Defaults &= ~AR_STA_ID1_ACKCTS_6MB;511} else {512OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB);513ahp->ah_staId1Defaults |= AR_STA_ID1_ACKCTS_6MB;514}515return AH_TRUE;516}517518HAL_BOOL519ar5211SetCTSTimeout(struct ath_hal *ah, u_int us)520{521struct ath_hal_5211 *ahp = AH5211(ah);522523if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {524HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad cts timeout %u\n",525__func__, us);526ahp->ah_ctstimeout = (u_int) -1; /* restore default handling */527return AH_FALSE;528} else {529/* convert to system clocks */530OS_REG_RMW_FIELD(ah, AR_TIME_OUT,531AR_TIME_OUT_CTS, ath_hal_mac_clks(ah, us));532ahp->ah_ctstimeout = us;533return AH_TRUE;534}535}536537u_int538ar5211GetCTSTimeout(struct ath_hal *ah)539{540u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS);541return ath_hal_mac_usec(ah, clks); /* convert from system clocks */542}543544HAL_BOOL545ar5211SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en)546{547/* nothing to do */548return AH_TRUE;549}550551void552ar5211SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)553{554}555556HAL_STATUS557ar5211SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration,558uint32_t next_start, HAL_QUIET_FLAG flags)559{560return HAL_OK;561}562563/*564* Control Adaptive Noise Immunity Parameters565*/566HAL_BOOL567ar5211AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)568{569return AH_FALSE;570}571572void573ar5211AniPoll(struct ath_hal *ah, const struct ieee80211_channel *chan)574{575}576577void578ar5211RxMonitor(struct ath_hal *ah, const HAL_NODE_STATS *stats,579const struct ieee80211_channel *chan)580{581}582583void584ar5211MibEvent(struct ath_hal *ah, const HAL_NODE_STATS *stats)585{586}587588/*589* Get the rssi of frame curently being received.590*/591uint32_t592ar5211GetCurRssi(struct ath_hal *ah)593{594return (OS_REG_READ(ah, AR_PHY_CURRENT_RSSI) & 0xff);595}596597u_int598ar5211GetDefAntenna(struct ath_hal *ah)599{600return (OS_REG_READ(ah, AR_DEF_ANTENNA) & 0x7);601}602603void604ar5211SetDefAntenna(struct ath_hal *ah, u_int antenna)605{606OS_REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));607}608609HAL_ANT_SETTING610ar5211GetAntennaSwitch(struct ath_hal *ah)611{612return AH5211(ah)->ah_diversityControl;613}614615HAL_BOOL616ar5211SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)617{618const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;619620if (chan == AH_NULL) {621AH5211(ah)->ah_diversityControl = settings;622return AH_TRUE;623}624return ar5211SetAntennaSwitchInternal(ah, settings, chan);625}626627HAL_STATUS628ar5211GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,629uint32_t capability, uint32_t *result)630{631632switch (type) {633case HAL_CAP_CIPHER: /* cipher handled in hardware */634switch (capability) {635case HAL_CIPHER_AES_OCB:636case HAL_CIPHER_WEP:637case HAL_CIPHER_CLR:638return HAL_OK;639default:640return HAL_ENOTSUPP;641}642default:643return ath_hal_getcapability(ah, type, capability, result);644}645}646647HAL_BOOL648ar5211SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,649uint32_t capability, uint32_t setting, HAL_STATUS *status)650{651switch (type) {652case HAL_CAP_DIAG: /* hardware diagnostic support */653/*654* NB: could split this up into virtual capabilities,655* (e.g. 1 => ACK, 2 => CTS, etc.) but it hardly656* seems worth the additional complexity.657*/658#ifdef AH_DEBUG659AH_PRIVATE(ah)->ah_diagreg = setting;660#else661AH_PRIVATE(ah)->ah_diagreg = setting & 0x6; /* ACK+CTS */662#endif663OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);664return AH_TRUE;665default:666return ath_hal_setcapability(ah, type, capability,667setting, status);668}669}670671HAL_BOOL672ar5211GetDiagState(struct ath_hal *ah, int request,673const void *args, uint32_t argsize,674void **result, uint32_t *resultsize)675{676struct ath_hal_5211 *ahp = AH5211(ah);677678(void) ahp;679if (ath_hal_getdiagstate(ah, request, args, argsize, result, resultsize))680return AH_TRUE;681switch (request) {682case HAL_DIAG_EEPROM:683return ath_hal_eepromDiag(ah, request,684args, argsize, result, resultsize);685case HAL_DIAG_RFGAIN:686*result = &ahp->ah_gainValues;687*resultsize = sizeof(GAIN_VALUES);688return AH_TRUE;689case HAL_DIAG_RFGAIN_CURSTEP:690*result = __DECONST(void *, ahp->ah_gainValues.currStep);691*resultsize = (*result == AH_NULL) ?6920 : sizeof(GAIN_OPTIMIZATION_STEP);693return AH_TRUE;694}695return AH_FALSE;696}697698/*699* Return what percentage of the extension channel is busy.700* This is always disabled for AR5211 series NICs.701*/702uint32_t703ar5211Get11nExtBusy(struct ath_hal *ah)704{705return (0);706}707708/*709* There's no channel survey support for the AR5211.710*/711HAL_BOOL712ar5211GetMibCycleCounts(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hsample)713{714715return (AH_FALSE);716}717718void719ar5211SetChainMasks(struct ath_hal *ah, uint32_t txchainmask,720uint32_t rxchainmask)721{722}723724void725ar5211EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)726{727}728729void730ar5211GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)731{732}733734/*735* Get the current NAV value from the hardware.736*/737u_int738ar5211GetNav(struct ath_hal *ah)739{740uint32_t reg;741742reg = OS_REG_READ(ah, AR_NAV);743return (reg);744}745746/*747* Set the current NAV value to the hardware.748*/749void750ar5211SetNav(struct ath_hal *ah, u_int val)751{752753OS_REG_WRITE(ah, AR_NAV, val);754}755756757758