Path: blob/main/sys/dev/ath/ath_hal/ah_internal.h
104185 views
/*-1* SPDX-License-Identifier: ISC2*3* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting4* Copyright (c) 2002-2008 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#ifndef _ATH_AH_INTERAL_H_19#define _ATH_AH_INTERAL_H_20/*21* Atheros Device Hardware Access Layer (HAL).22*23* Internal definitions.24*/25#define AH_NULL 026#define AH_MIN(a,b) ((a)<(b)?(a):(b))27#define AH_MAX(a,b) ((a)>(b)?(a):(b))2829#include <net80211/_ieee80211.h>30#include <sys/queue.h> /* XXX for reasons */3132#ifndef NBBY33#define NBBY 8 /* number of bits/byte */34#endif3536#ifndef roundup37#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */38#endif39#ifndef howmany40#define howmany(x, y) (((x)+((y)-1))/(y))41#endif4243#ifndef offsetof44#define offsetof(type, field) ((size_t)(&((type *)0)->field))45#endif4647typedef struct {48uint32_t start; /* first register */49uint32_t end; /* ending register or zero */50} HAL_REGRANGE;5152typedef struct {53uint32_t addr; /* regiser address/offset */54uint32_t value; /* value to write */55} HAL_REGWRITE;5657/*58* Transmit power scale factor.59*60* NB: This is not public because we want to discourage the use of61* scaling; folks should use the tx power limit interface.62*/63typedef enum {64HAL_TP_SCALE_MAX = 0, /* no scaling (default) */65HAL_TP_SCALE_50 = 1, /* 50% of max (-3 dBm) */66HAL_TP_SCALE_25 = 2, /* 25% of max (-6 dBm) */67HAL_TP_SCALE_12 = 3, /* 12% of max (-9 dBm) */68HAL_TP_SCALE_MIN = 4, /* min, but still on */69} HAL_TP_SCALE;7071typedef enum {72HAL_CAP_RADAR = 0, /* Radar capability */73HAL_CAP_AR = 1, /* AR capability */74} HAL_PHYDIAG_CAPS;7576/*77* Enable/disable strong signal fast diversity78*/79#define HAL_CAP_STRONG_DIV 28081/*82* Each chip or class of chips registers to offer support.83*84* Compiled-in versions will include a linker set to iterate through the85* linked in code.86*87* Modules will have to register HAL backends separately.88*/89struct ath_hal_chip {90const char *name;91const char *(*probe)(uint16_t vendorid, uint16_t devid);92struct ath_hal *(*attach)(uint16_t devid, HAL_SOFTC,93HAL_BUS_TAG, HAL_BUS_HANDLE, uint16_t *eepromdata,94HAL_OPS_CONFIG *ah,95HAL_STATUS *error);96TAILQ_ENTRY(ath_hal_chip) node;97};98#ifndef AH_CHIP99#define AH_CHIP(_name, _probe, _attach) \100struct ath_hal_chip _name##_chip = { \101.name = #_name, \102.probe = _probe, \103.attach = _attach, \104}; \105OS_DATA_SET(ah_chips, _name##_chip)106#endif107108/*109* Each RF backend registers to offer support; this is mostly110* used by multi-chip 5212 solutions. Single-chip solutions111* have a fixed idea about which RF to use.112*113* Compiled in versions will include this linker set to iterate through114* the linked in code.115*116* Modules will have to register RF backends separately.117*/118struct ath_hal_rf {119const char *name;120HAL_BOOL (*probe)(struct ath_hal *ah);121HAL_BOOL (*attach)(struct ath_hal *ah, HAL_STATUS *ecode);122TAILQ_ENTRY(ath_hal_rf) node;123};124#ifndef AH_RF125#define AH_RF(_name, _probe, _attach) \126struct ath_hal_rf _name##_rf = { \127.name = __STRING(_name), \128.probe = _probe, \129.attach = _attach, \130}; \131OS_DATA_SET(ah_rfs, _name##_rf)132#endif133134struct ath_hal_rf *ath_hal_rfprobe(struct ath_hal *ah, HAL_STATUS *ecode);135136/*137* Maximum number of internal channels. Entries are per unique138* frequency so this might be need to be increased to handle all139* usage cases; typically no more than 32 are really needed but140* dynamically allocating the data structures is a bit painful141* right now.142*/143#ifndef AH_MAXCHAN144#define AH_MAXCHAN 128145#endif146147#define HAL_NF_CAL_HIST_LEN_FULL 5148#define HAL_NF_CAL_HIST_LEN_SMALL 1149#define HAL_NUM_NF_READINGS 6 /* 3 chains * (ctl + ext) */150#define HAL_NF_LOAD_DELAY 1000151152/*153* PER_CHAN doesn't work for now, as it looks like the device layer154* has to pre-populate the per-channel list with nominal values.155*/156//#define ATH_NF_PER_CHAN 1157158typedef struct {159u_int8_t curr_index;160int8_t invalidNFcount; /* TO DO: REMOVE THIS! */161int16_t priv_nf[HAL_NUM_NF_READINGS];162} HAL_NFCAL_BASE;163164typedef struct {165HAL_NFCAL_BASE base;166int16_t nf_cal_buffer[HAL_NF_CAL_HIST_LEN_FULL][HAL_NUM_NF_READINGS];167} HAL_NFCAL_HIST_FULL;168169typedef struct {170HAL_NFCAL_BASE base;171int16_t nf_cal_buffer[HAL_NF_CAL_HIST_LEN_SMALL][HAL_NUM_NF_READINGS];172} HAL_NFCAL_HIST_SMALL;173174#ifdef ATH_NF_PER_CHAN175typedef HAL_NFCAL_HIST_FULL HAL_CHAN_NFCAL_HIST;176#define AH_HOME_CHAN_NFCAL_HIST(ah, ichan) (ichan ? &ichan->nf_cal_hist: NULL)177#else178typedef HAL_NFCAL_HIST_SMALL HAL_CHAN_NFCAL_HIST;179#define AH_HOME_CHAN_NFCAL_HIST(ah, ichan) (&AH_PRIVATE(ah)->nf_cal_hist)180#endif /* ATH_NF_PER_CHAN */181182/*183* Internal per-channel state. These are found184* using ic_devdata in the ieee80211_channel.185*/186typedef struct {187uint16_t channel; /* h/w frequency, NB: may be mapped */188uint8_t privFlags;189#define CHANNEL_IQVALID 0x01 /* IQ calibration valid */190#define CHANNEL_ANI_INIT 0x02 /* ANI state initialized */191#define CHANNEL_ANI_SETUP 0x04 /* ANI state setup */192#define CHANNEL_MIMO_NF_VALID 0x04 /* Mimo NF values are valid */193uint8_t calValid; /* bitmask of cal types */194int8_t iCoff;195int8_t qCoff;196int16_t rawNoiseFloor;197int16_t noiseFloorAdjust;198int16_t noiseFloorCtl[AH_MAX_CHAINS];199int16_t noiseFloorExt[AH_MAX_CHAINS];200uint16_t mainSpur; /* cached spur value for this channel */201202/*XXX TODO: make these part of privFlags */203uint8_t paprd_done:1, /* 1: PAPRD DONE, 0: PAPRD Cal not done */204paprd_table_write_done:1; /* 1: DONE, 0: Cal data write not done */205int one_time_cals_done;206HAL_CHAN_NFCAL_HIST nf_cal_hist;207} HAL_CHANNEL_INTERNAL;208209/* channel requires noise floor check */210#define CHANNEL_NFCREQUIRED IEEE80211_CHAN_PRIV0211212/* all full-width channels */213#define IEEE80211_CHAN_ALLFULL \214(IEEE80211_CHAN_ALL - (IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER))215#define IEEE80211_CHAN_ALLTURBOFULL \216(IEEE80211_CHAN_ALLTURBO - \217(IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER))218219typedef struct {220uint32_t halChanSpreadSupport : 1,221halSleepAfterBeaconBroken : 1,222halCompressSupport : 1,223halBurstSupport : 1,224halFastFramesSupport : 1,225halChapTuningSupport : 1,226halTurboGSupport : 1,227halTurboPrimeSupport : 1,228halMicAesCcmSupport : 1,229halMicCkipSupport : 1,230halMicTkipSupport : 1,231halTkipMicTxRxKeySupport : 1,232halCipherAesCcmSupport : 1,233halCipherCkipSupport : 1,234halCipherTkipSupport : 1,235halPSPollBroken : 1,236halVEOLSupport : 1,237halBssIdMaskSupport : 1,238halMcastKeySrchSupport : 1,239halTsfAddSupport : 1,240halChanHalfRate : 1,241halChanQuarterRate : 1,242halHTSupport : 1,243halHTSGI20Support : 1,244halRfSilentSupport : 1,245halHwPhyCounterSupport : 1,246halWowSupport : 1,247halWowMatchPatternExact : 1,248halAutoSleepSupport : 1,249halFastCCSupport : 1,250halBtCoexSupport : 1;251uint32_t halRxStbcSupport : 1,252halTxStbcSupport : 1,253halGTTSupport : 1,254halCSTSupport : 1,255halRifsRxSupport : 1,256halRifsTxSupport : 1,257hal4AddrAggrSupport : 1,258halExtChanDfsSupport : 1,259halUseCombinedRadarRssi : 1,260halForcePpmSupport : 1,261halEnhancedPmSupport : 1,262halEnhancedDfsSupport : 1,263halMbssidAggrSupport : 1,264halBssidMatchSupport : 1,265hal4kbSplitTransSupport : 1,266halHasRxSelfLinkedTail : 1,267halSupportsFastClock5GHz : 1,268halHasBBReadWar : 1,269halSerialiseRegWar : 1,270halMciSupport : 1,271halRxTxAbortSupport : 1,272halPaprdEnabled : 1,273halHasUapsdSupport : 1,274halWpsPushButtonSupport : 1,275halBtCoexApsmWar : 1,276halGenTimerSupport : 1,277halLDPCSupport : 1,278halHwBeaconProcSupport : 1,279halEnhancedDmaSupport : 1;280uint32_t halIsrRacSupport : 1,281halApmEnable : 1,282halIntrMitigation : 1,283hal49GhzSupport : 1,284halAntDivCombSupport : 1,285halAntDivCombSupportOrg : 1,286halRadioRetentionSupport : 1,287halSpectralScanSupport : 1,288halRxUsingLnaMixing : 1,289halRxDoMyBeacon : 1,290halHwUapsdTrig : 1;291292uint32_t halWirelessModes;293uint16_t halTotalQueues;294uint16_t halKeyCacheSize;295uint16_t halLow5GhzChan, halHigh5GhzChan;296uint16_t halLow2GhzChan, halHigh2GhzChan;297int halTxTstampPrecision;298int halRxTstampPrecision;299int halRtsAggrLimit;300uint8_t halTxChainMask;301uint8_t halRxChainMask;302uint8_t halNumGpioPins;303uint8_t halNumAntCfg2GHz;304uint8_t halNumAntCfg5GHz;305uint32_t halIntrMask;306uint8_t halTxStreams;307uint8_t halRxStreams;308HAL_MFP_OPT_T halMfpSupport;309310/* AR9300 HAL porting capabilities */311int hal_paprd_enabled;312int hal_pcie_lcr_offset;313int hal_pcie_lcr_extsync_en;314int halNumTxMaps;315int halTxDescLen;316int halTxStatusLen;317int halRxStatusLen;318int halRxHpFifoDepth;319int halRxLpFifoDepth;320uint32_t halRegCap; /* XXX needed? */321int halNumMRRetries;322int hal_ani_poll_interval;323int hal_channel_switch_time_usec;324} HAL_CAPABILITIES;325326struct regDomain;327328/*329* Definitions for ah_flags in ath_hal_private330*/331#define AH_USE_EEPROM 0x1332#define AH_IS_HB63 0x2333334/*335* The ``private area'' follows immediately after the ``public area''336* in the data structure returned by ath_hal_attach. Private data are337* used by device-independent code such as the regulatory domain support.338* In general, code within the HAL should never depend on data in the339* public area. Instead any public data needed internally should be340* shadowed here.341*342* When declaring a device-specific ath_hal data structure this structure343* is assumed to at the front; e.g.344*345* struct ath_hal_5212 {346* struct ath_hal_private ah_priv;347* ...348* };349*350* It might be better to manage the method pointers in this structure351* using an indirect pointer to a read-only data structure but this would352* disallow class-style method overriding.353*/354struct ath_hal_private {355struct ath_hal h; /* public area */356357/* NB: all methods go first to simplify initialization */358HAL_BOOL (*ah_getChannelEdges)(struct ath_hal*,359uint16_t channelFlags,360uint16_t *lowChannel, uint16_t *highChannel);361u_int (*ah_getWirelessModes)(struct ath_hal*);362HAL_BOOL (*ah_eepromRead)(struct ath_hal *, u_int off,363uint16_t *data);364HAL_BOOL (*ah_eepromWrite)(struct ath_hal *, u_int off,365uint16_t data);366HAL_BOOL (*ah_getChipPowerLimits)(struct ath_hal *,367struct ieee80211_channel *);368int16_t (*ah_getNfAdjust)(struct ath_hal *,369const HAL_CHANNEL_INTERNAL*);370void (*ah_getNoiseFloor)(struct ath_hal *,371int16_t nfarray[]);372373void *ah_eeprom; /* opaque EEPROM state */374uint16_t ah_eeversion; /* EEPROM version */375void (*ah_eepromDetach)(struct ath_hal *);376HAL_STATUS (*ah_eepromGet)(struct ath_hal *, int, void *);377HAL_STATUS (*ah_eepromSet)(struct ath_hal *, int, int);378uint16_t (*ah_getSpurChan)(struct ath_hal *, int, HAL_BOOL);379HAL_BOOL (*ah_eepromDiag)(struct ath_hal *, int request,380const void *args, uint32_t argsize,381void **result, uint32_t *resultsize);382383/*384* Device revision information.385*/386uint16_t ah_devid; /* PCI device ID */387uint16_t ah_subvendorid; /* PCI subvendor ID */388uint32_t ah_macVersion; /* MAC version id */389uint16_t ah_macRev; /* MAC revision */390uint16_t ah_phyRev; /* PHY revision */391uint16_t ah_analog5GhzRev; /* 2GHz radio revision */392uint16_t ah_analog2GhzRev; /* 5GHz radio revision */393uint32_t ah_flags; /* misc flags */394uint8_t ah_ispcie; /* PCIE, special treatment */395uint8_t ah_devType; /* card type - CB, PCI, PCIe */396397HAL_OPMODE ah_opmode; /* operating mode from reset */398const struct ieee80211_channel *ah_curchan;/* operating channel */399HAL_CAPABILITIES ah_caps; /* device capabilities */400uint32_t ah_diagreg; /* user-specified AR_DIAG_SW */401int16_t ah_powerLimit; /* tx power cap */402uint16_t ah_maxPowerLevel; /* calculated max tx power */403u_int ah_tpScale; /* tx power scale factor */404u_int16_t ah_extraTxPow; /* low rates extra-txpower */405uint32_t ah_11nCompat; /* 11n compat controls */406407/*408* State for regulatory domain handling.409*/410HAL_REG_DOMAIN ah_currentRD; /* EEPROM regulatory domain */411HAL_REG_DOMAIN ah_currentRDext; /* EEPROM extended regdomain flags */412HAL_DFS_DOMAIN ah_dfsDomain; /* current DFS domain */413HAL_CHANNEL_INTERNAL ah_channels[AH_MAXCHAN]; /* private chan state */414u_int ah_nchan; /* valid items in ah_channels */415const struct regDomain *ah_rd2GHz; /* reg state for 2G band */416const struct regDomain *ah_rd5GHz; /* reg state for 5G band */417418uint8_t ah_coverageClass; /* coverage class */419/*420* RF Silent handling; setup according to the EEPROM.421*/422uint16_t ah_rfsilent; /* GPIO pin + polarity */423HAL_BOOL ah_rfkillEnabled; /* enable/disable RfKill */424/*425* Diagnostic support for discriminating HIUERR reports.426*/427uint32_t ah_fatalState[6]; /* AR_ISR+shadow regs */428int ah_rxornIsFatal; /* how to treat HAL_INT_RXORN */429430/* Only used if ATH_NF_PER_CHAN is defined */431HAL_NFCAL_HIST_FULL nf_cal_hist;432433/*434* Channel survey history - current channel only.435*/436HAL_CHANNEL_SURVEY ah_chansurvey; /* channel survey */437};438439#define AH_PRIVATE(_ah) ((struct ath_hal_private *)(_ah))440441#define ath_hal_getChannelEdges(_ah, _cf, _lc, _hc) \442AH_PRIVATE(_ah)->ah_getChannelEdges(_ah, _cf, _lc, _hc)443#define ath_hal_getWirelessModes(_ah) \444AH_PRIVATE(_ah)->ah_getWirelessModes(_ah)445#define ath_hal_eepromRead(_ah, _off, _data) \446AH_PRIVATE(_ah)->ah_eepromRead(_ah, _off, _data)447#define ath_hal_eepromWrite(_ah, _off, _data) \448AH_PRIVATE(_ah)->ah_eepromWrite(_ah, _off, _data)449#define ath_hal_gpioCfgOutput(_ah, _gpio, _type) \450(_ah)->ah_gpioCfgOutput(_ah, _gpio, _type)451#define ath_hal_gpioCfgInput(_ah, _gpio) \452(_ah)->ah_gpioCfgInput(_ah, _gpio)453#define ath_hal_gpioGet(_ah, _gpio) \454(_ah)->ah_gpioGet(_ah, _gpio)455#define ath_hal_gpioSet(_ah, _gpio, _val) \456(_ah)->ah_gpioSet(_ah, _gpio, _val)457#define ath_hal_gpioSetIntr(_ah, _gpio, _ilevel) \458(_ah)->ah_gpioSetIntr(_ah, _gpio, _ilevel)459#define ath_hal_getpowerlimits(_ah, _chan) \460AH_PRIVATE(_ah)->ah_getChipPowerLimits(_ah, _chan)461#define ath_hal_getNfAdjust(_ah, _c) \462AH_PRIVATE(_ah)->ah_getNfAdjust(_ah, _c)463#define ath_hal_getNoiseFloor(_ah, _nfArray) \464AH_PRIVATE(_ah)->ah_getNoiseFloor(_ah, _nfArray)465#define ath_hal_configPCIE(_ah, _reset, _poweroff) \466(_ah)->ah_configPCIE(_ah, _reset, _poweroff)467#define ath_hal_disablePCIE(_ah) \468(_ah)->ah_disablePCIE(_ah)469#define ath_hal_setInterrupts(_ah, _mask) \470(_ah)->ah_setInterrupts(_ah, _mask)471472#define ath_hal_isrfkillenabled(_ah) \473(ath_hal_getcapability(_ah, HAL_CAP_RFSILENT, 1, AH_NULL) == HAL_OK)474#define ath_hal_enable_rfkill(_ah, _v) \475ath_hal_setcapability(_ah, HAL_CAP_RFSILENT, 1, _v, AH_NULL)476#define ath_hal_hasrfkill_int(_ah) \477(ath_hal_getcapability(_ah, HAL_CAP_RFSILENT, 3, AH_NULL) == HAL_OK)478479#define ath_hal_eepromDetach(_ah) do { \480if (AH_PRIVATE(_ah)->ah_eepromDetach != AH_NULL) \481AH_PRIVATE(_ah)->ah_eepromDetach(_ah); \482} while (0)483#define ath_hal_eepromGet(_ah, _param, _val) \484AH_PRIVATE(_ah)->ah_eepromGet(_ah, _param, _val)485#define ath_hal_eepromSet(_ah, _param, _val) \486AH_PRIVATE(_ah)->ah_eepromSet(_ah, _param, _val)487#define ath_hal_eepromGetFlag(_ah, _param) \488(AH_PRIVATE(_ah)->ah_eepromGet(_ah, _param, AH_NULL) == HAL_OK)489#define ath_hal_getSpurChan(_ah, _ix, _is2G) \490AH_PRIVATE(_ah)->ah_getSpurChan(_ah, _ix, _is2G)491#define ath_hal_eepromDiag(_ah, _request, _a, _asize, _r, _rsize) \492AH_PRIVATE(_ah)->ah_eepromDiag(_ah, _request, _a, _asize, _r, _rsize)493494#ifndef _NET_IF_IEEE80211_H_495/*496* Stuff that would naturally come from _ieee80211.h497*/498#define IEEE80211_ADDR_LEN 6499500#define IEEE80211_WEP_IVLEN 3 /* 24bit */501#define IEEE80211_WEP_KIDLEN 1 /* 1 octet */502#define IEEE80211_WEP_CRCLEN 4 /* CRC-32 */503504#define IEEE80211_CRC_LEN 4505506#define IEEE80211_MAX_LEN (2300 + IEEE80211_CRC_LEN + \507(IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN))508#endif /* _NET_IF_IEEE80211_H_ */509510#define HAL_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001511512#define INIT_AIFS 2513#define INIT_CWMIN 15514#define INIT_CWMIN_11B 31515#define INIT_CWMAX 1023516#define INIT_SH_RETRY 10517#define INIT_LG_RETRY 10518#define INIT_SSH_RETRY 32519#define INIT_SLG_RETRY 32520521typedef struct {522uint32_t tqi_ver; /* HAL TXQ verson */523HAL_TX_QUEUE tqi_type; /* hw queue type*/524HAL_TX_QUEUE_SUBTYPE tqi_subtype; /* queue subtype, if applicable */525HAL_TX_QUEUE_FLAGS tqi_qflags; /* queue flags */526uint32_t tqi_priority;527uint32_t tqi_aifs; /* aifs */528uint32_t tqi_cwmin; /* cwMin */529uint32_t tqi_cwmax; /* cwMax */530uint16_t tqi_shretry; /* frame short retry limit */531uint16_t tqi_lgretry; /* frame long retry limit */532uint32_t tqi_cbrPeriod;533uint32_t tqi_cbrOverflowLimit;534uint32_t tqi_burstTime;535uint32_t tqi_readyTime;536uint32_t tqi_physCompBuf;537uint32_t tqi_intFlags; /* flags for internal use */538} HAL_TX_QUEUE_INFO;539540extern HAL_BOOL ath_hal_setTxQProps(struct ath_hal *ah,541HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo);542extern HAL_BOOL ath_hal_getTxQProps(struct ath_hal *ah,543HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi);544545#define HAL_SPUR_VAL_MASK 0x3FFF546#define HAL_SPUR_CHAN_WIDTH 87547#define HAL_BIN_WIDTH_BASE_100HZ 3125548#define HAL_BIN_WIDTH_TURBO_100HZ 6250549#define HAL_MAX_BINS_ALLOWED 28550551#define IS_CHAN_5GHZ(_c) ((_c)->channel > 4900)552#define IS_CHAN_2GHZ(_c) (!IS_CHAN_5GHZ(_c))553554#define IS_CHAN_IN_PUBLIC_SAFETY_BAND(_c) ((_c) > 4940 && (_c) < 4990)555556/*557* Deduce if the host cpu has big- or litt-endian byte order.558*/559static __inline__ int560isBigEndian(void)561{562union {563int32_t i;564char c[4];565} u;566u.i = 1;567return (u.c[0] == 0);568}569570/* unalligned little endian access */571#define LE_READ_2(p) \572((uint16_t) \573((((const uint8_t *)(p))[0] ) | (((const uint8_t *)(p))[1]<< 8)))574#define LE_READ_4(p) \575((uint32_t) \576((((const uint8_t *)(p))[0] ) | (((const uint8_t *)(p))[1]<< 8) |\577(((const uint8_t *)(p))[2]<<16) | (((const uint8_t *)(p))[3]<<24)))578579/*580* Register manipulation macros that expect bit field defines581* to follow the convention that an _S suffix is appended for582* a shift count, while the field mask has no suffix.583*/584#define SM(_v, _f) (((_v) << _f##_S) & (_f))585#define MS(_v, _f) (((_v) & (_f)) >> _f##_S)586#define OS_REG_RMW(_a, _r, _set, _clr) \587OS_REG_WRITE(_a, _r, (OS_REG_READ(_a, _r) & ~(_clr)) | (_set))588#define OS_REG_RMW_FIELD(_a, _r, _f, _v) \589OS_REG_WRITE(_a, _r, \590(OS_REG_READ(_a, _r) &~ (_f)) | (((_v) << _f##_S) & (_f)))591#define OS_REG_SET_BIT(_a, _r, _f) \592OS_REG_WRITE(_a, _r, OS_REG_READ(_a, _r) | (_f))593#define OS_REG_CLR_BIT(_a, _r, _f) \594OS_REG_WRITE(_a, _r, OS_REG_READ(_a, _r) &~ (_f))595#define OS_REG_IS_BIT_SET(_a, _r, _f) \596((OS_REG_READ(_a, _r) & (_f)) != 0)597#define OS_REG_RMW_FIELD_ALT(_a, _r, _f, _v) \598OS_REG_WRITE(_a, _r, \599(OS_REG_READ(_a, _r) &~(_f<<_f##_S)) | \600(((_v) << _f##_S) & (_f<<_f##_S)))601#define OS_REG_READ_FIELD(_a, _r, _f) \602(((OS_REG_READ(_a, _r) & _f) >> _f##_S))603#define OS_REG_READ_FIELD_ALT(_a, _r, _f) \604((OS_REG_READ(_a, _r) >> (_f##_S))&(_f))605606/* Analog register writes may require a delay between each one (eg Merlin?) */607#define OS_A_REG_RMW_FIELD(_a, _r, _f, _v) \608do { OS_REG_WRITE(_a, _r, (OS_REG_READ(_a, _r) &~ (_f)) | \609(((_v) << _f##_S) & (_f))) ; OS_DELAY(100); } while (0)610#define OS_A_REG_WRITE(_a, _r, _v) \611do { OS_REG_WRITE(_a, _r, _v); OS_DELAY(100); } while (0)612613/* wait for the register contents to have the specified value */614extern HAL_BOOL ath_hal_wait(struct ath_hal *, u_int reg,615uint32_t mask, uint32_t val);616extern HAL_BOOL ath_hal_waitfor(struct ath_hal *, u_int reg,617uint32_t mask, uint32_t val, uint32_t timeout);618619/* return the first n bits in val reversed */620extern uint32_t ath_hal_reverseBits(uint32_t val, uint32_t n);621622/* printf interfaces */623extern void ath_hal_printf(struct ath_hal *, const char*, ...)624__printflike(2,3);625extern void ath_hal_vprintf(struct ath_hal *, const char*, __va_list)626__printflike(2, 0);627extern const char* ath_hal_ether_sprintf(const uint8_t *mac);628629/* allocate and free memory */630extern void *ath_hal_malloc(size_t);631extern void ath_hal_free(void *);632633/* common debugging interfaces */634#ifdef AH_DEBUG635#include "ah_debug.h"636extern int ath_hal_debug; /* Global debug flags */637638/*639* The typecast is purely because some callers will pass in640* AH_NULL directly rather than using a NULL ath_hal pointer.641*/642#define HALDEBUG(_ah, __m, ...) \643do { \644if ((__m) == HAL_DEBUG_UNMASKABLE || \645ath_hal_debug & (__m) || \646((_ah) != NULL && \647((struct ath_hal *) (_ah))->ah_config.ah_debug & (__m))) { \648DO_HALDEBUG((_ah), (__m), __VA_ARGS__); \649} \650} while(0);651652extern void DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...)653__printflike(3,4);654#else655#define HALDEBUG(_ah, __m, ...)656#endif /* AH_DEBUG */657658/*659* Register logging definitions shared with ardecode.660*/661#include "ah_decode.h"662663/*664* Common assertion interface. Note: it is a bad idea to generate665* an assertion failure for any recoverable event. Instead catch666* the violation and, if possible, fix it up or recover from it; either667* with an error return value or a diagnostic messages. System software668* does not panic unless the situation is hopeless.669*/670#ifdef AH_ASSERT671extern void ath_hal_assert_failed(const char* filename,672int lineno, const char* msg);673674#define HALASSERT(_x) do { \675if (!(_x)) { \676ath_hal_assert_failed(__FILE__, __LINE__, #_x); \677} \678} while (0)679#else680#define HALASSERT(_x)681#endif /* AH_ASSERT */682683/*684* Regulatory domain support.685*/686687/*688* Return the max allowed antenna gain and apply any regulatory689* domain specific changes.690*/691u_int ath_hal_getantennareduction(struct ath_hal *ah,692const struct ieee80211_channel *chan, u_int twiceGain);693694/*695* Return the test group for the specific channel based on696* the current regulatory setup.697*/698u_int ath_hal_getctl(struct ath_hal *, const struct ieee80211_channel *);699700/*701* Map a public channel definition to the corresponding702* internal data structure. This implicitly specifies703* whether or not the specified channel is ok to use704* based on the current regulatory domain constraints.705*/706#ifndef AH_DEBUG707static OS_INLINE HAL_CHANNEL_INTERNAL *708ath_hal_checkchannel(struct ath_hal *ah, const struct ieee80211_channel *c)709{710HAL_CHANNEL_INTERNAL *cc;711712HALASSERT(c->ic_devdata < AH_PRIVATE(ah)->ah_nchan);713cc = &AH_PRIVATE(ah)->ah_channels[c->ic_devdata];714HALASSERT(c->ic_freq == cc->channel || IEEE80211_IS_CHAN_GSM(c));715return cc;716}717#else718/* NB: non-inline version that checks state */719HAL_CHANNEL_INTERNAL *ath_hal_checkchannel(struct ath_hal *,720const struct ieee80211_channel *);721#endif /* AH_DEBUG */722723/*724* Return the h/w frequency for a channel. This may be725* different from ic_freq if this is a GSM device that726* takes 2.4GHz frequencies and down-converts them.727*/728static OS_INLINE uint16_t729ath_hal_gethwchannel(struct ath_hal *ah, const struct ieee80211_channel *c)730{731return ath_hal_checkchannel(ah, c)->channel;732}733734/*735* Generic get/set capability support. Each chip overrides736* this routine to support chip-specific capabilities.737*/738extern HAL_STATUS ath_hal_getcapability(struct ath_hal *ah,739HAL_CAPABILITY_TYPE type, uint32_t capability,740uint32_t *result);741extern HAL_BOOL ath_hal_setcapability(struct ath_hal *ah,742HAL_CAPABILITY_TYPE type, uint32_t capability,743uint32_t setting, HAL_STATUS *status);744745/* The diagnostic codes used to be internally defined here -adrian */746#include "ah_diagcodes.h"747748/*749* The AR5416 and later HALs have MAC and baseband hang checking.750*/751typedef struct {752uint32_t hang_reg_offset;753uint32_t hang_val;754uint32_t hang_mask;755uint32_t hang_offset;756} hal_hw_hang_check_t;757758typedef struct {759uint32_t dma_dbg_3;760uint32_t dma_dbg_4;761uint32_t dma_dbg_5;762uint32_t dma_dbg_6;763} mac_dbg_regs_t;764765typedef enum {766dcu_chain_state = 0x1,767dcu_complete_state = 0x2,768qcu_state = 0x4,769qcu_fsp_ok = 0x8,770qcu_fsp_state = 0x10,771qcu_stitch_state = 0x20,772qcu_fetch_state = 0x40,773qcu_complete_state = 0x80774} hal_mac_hangs_t;775776typedef struct {777int states;778uint8_t dcu_chain_state;779uint8_t dcu_complete_state;780uint8_t qcu_state;781uint8_t qcu_fsp_ok;782uint8_t qcu_fsp_state;783uint8_t qcu_stitch_state;784uint8_t qcu_fetch_state;785uint8_t qcu_complete_state;786} hal_mac_hang_check_t;787788enum {789HAL_BB_HANG_DFS = 0x0001,790HAL_BB_HANG_RIFS = 0x0002,791HAL_BB_HANG_RX_CLEAR = 0x0004,792HAL_BB_HANG_UNKNOWN = 0x0080,793794HAL_MAC_HANG_SIG1 = 0x0100,795HAL_MAC_HANG_SIG2 = 0x0200,796HAL_MAC_HANG_UNKNOWN = 0x8000,797798HAL_BB_HANGS = HAL_BB_HANG_DFS799| HAL_BB_HANG_RIFS800| HAL_BB_HANG_RX_CLEAR801| HAL_BB_HANG_UNKNOWN,802HAL_MAC_HANGS = HAL_MAC_HANG_SIG1803| HAL_MAC_HANG_SIG2804| HAL_MAC_HANG_UNKNOWN,805};806807/* Merge these with above */808typedef enum hal_hw_hangs {809HAL_DFS_BB_HANG_WAR = 0x1,810HAL_RIFS_BB_HANG_WAR = 0x2,811HAL_RX_STUCK_LOW_BB_HANG_WAR = 0x4,812HAL_MAC_HANG_WAR = 0x8,813HAL_PHYRESTART_CLR_WAR = 0x10,814HAL_MAC_HANG_DETECTED = 0x40000000,815HAL_BB_HANG_DETECTED = 0x80000000816} hal_hw_hangs_t;817818/*819* Device revision information.820*/821typedef struct {822uint16_t ah_devid; /* PCI device ID */823uint16_t ah_subvendorid; /* PCI subvendor ID */824uint32_t ah_macVersion; /* MAC version id */825uint16_t ah_macRev; /* MAC revision */826uint16_t ah_phyRev; /* PHY revision */827uint16_t ah_analog5GhzRev; /* 2GHz radio revision */828uint16_t ah_analog2GhzRev; /* 5GHz radio revision */829} HAL_REVS;830831/*832* Argument payload for HAL_DIAG_SETKEY.833*/834typedef struct {835HAL_KEYVAL dk_keyval;836uint16_t dk_keyix; /* key index */837uint8_t dk_mac[IEEE80211_ADDR_LEN];838int dk_xor; /* XOR key data */839} HAL_DIAG_KEYVAL;840841/*842* Argument payload for HAL_DIAG_EEWRITE.843*/844typedef struct {845uint16_t ee_off; /* eeprom offset */846uint16_t ee_data; /* write data */847} HAL_DIAG_EEVAL;848849typedef struct {850u_int offset; /* reg offset */851uint32_t val; /* reg value */852} HAL_DIAG_REGVAL;853854/*855* 11n compatibility tweaks.856*/857#define HAL_DIAG_11N_SERVICES 0x00000003858#define HAL_DIAG_11N_SERVICES_S 0859#define HAL_DIAG_11N_TXSTOMP 0x0000000c860#define HAL_DIAG_11N_TXSTOMP_S 2861862typedef struct {863int maxNoiseImmunityLevel; /* [0..4] */864int totalSizeDesired[5];865int coarseHigh[5];866int coarseLow[5];867int firpwr[5];868869int maxSpurImmunityLevel; /* [0..7] */870int cycPwrThr1[8];871872int maxFirstepLevel; /* [0..2] */873int firstep[3];874875uint32_t ofdmTrigHigh;876uint32_t ofdmTrigLow;877int32_t cckTrigHigh;878int32_t cckTrigLow;879int32_t rssiThrLow;880int32_t rssiThrHigh;881882int period; /* update listen period */883} HAL_ANI_PARAMS;884885extern HAL_BOOL ath_hal_getdiagstate(struct ath_hal *ah, int request,886const void *args, uint32_t argsize,887void **result, uint32_t *resultsize);888889/*890* Setup a h/w rate table for use.891*/892extern void ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt);893894/*895* Common routine for implementing getChanNoise api.896*/897int16_t ath_hal_getChanNoise(struct ath_hal *, const struct ieee80211_channel *);898899/*900* Initialization support.901*/902typedef struct {903const uint32_t *data;904int rows, cols;905} HAL_INI_ARRAY;906907#define HAL_INI_INIT(_ia, _data, _cols) do { \908(_ia)->data = (const uint32_t *)(_data); \909(_ia)->rows = sizeof(_data) / sizeof((_data)[0]); \910(_ia)->cols = (_cols); \911} while (0)912#define HAL_INI_VAL(_ia, _r, _c) \913((_ia)->data[((_r)*(_ia)->cols) + (_c)])914915/*916* OS_DELAY() does a PIO READ on the PCI bus which allows917* other cards' DMA reads to complete in the middle of our reset.918*/919#define DMA_YIELD(x) do { \920if ((++(x) % 64) == 0) \921OS_DELAY(1); \922} while (0)923924#define HAL_INI_WRITE_ARRAY(ah, regArray, col, regWr) do { \925int r; \926for (r = 0; r < N(regArray); r++) { \927OS_REG_WRITE(ah, (regArray)[r][0], (regArray)[r][col]); \928DMA_YIELD(regWr); \929} \930} while (0)931932#define HAL_INI_WRITE_BANK(ah, regArray, bankData, regWr) do { \933int r; \934for (r = 0; r < N(regArray); r++) { \935OS_REG_WRITE(ah, (regArray)[r][0], (bankData)[r]); \936DMA_YIELD(regWr); \937} \938} while (0)939940extern int ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,941int col, int regWr);942extern void ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia,943int col);944extern int ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,945const uint32_t data[], int regWr);946947#define CCK_SIFS_TIME 10948#define CCK_PREAMBLE_BITS 144949#define CCK_PLCP_BITS 48950951#define OFDM_SIFS_TIME 16952#define OFDM_PREAMBLE_TIME 20953#define OFDM_PLCP_BITS 22954#define OFDM_SYMBOL_TIME 4955956#define OFDM_HALF_SIFS_TIME 32957#define OFDM_HALF_PREAMBLE_TIME 40958#define OFDM_HALF_PLCP_BITS 22959#define OFDM_HALF_SYMBOL_TIME 8960961#define OFDM_QUARTER_SIFS_TIME 64962#define OFDM_QUARTER_PREAMBLE_TIME 80963#define OFDM_QUARTER_PLCP_BITS 22964#define OFDM_QUARTER_SYMBOL_TIME 16965966#define TURBO_SIFS_TIME 8967#define TURBO_PREAMBLE_TIME 14968#define TURBO_PLCP_BITS 22969#define TURBO_SYMBOL_TIME 4970971#define WLAN_CTRL_FRAME_SIZE (2+2+6+4) /* ACK+FCS */972973/* Generic EEPROM board value functions */974extern HAL_BOOL ath_ee_getLowerUpperIndex(uint8_t target, uint8_t *pList,975uint16_t listSize, uint16_t *indexL, uint16_t *indexR);976extern HAL_BOOL ath_ee_FillVpdTable(uint8_t pwrMin, uint8_t pwrMax,977uint8_t *pPwrList, uint8_t *pVpdList, uint16_t numIntercepts,978uint8_t *pRetVpdList);979extern int16_t ath_ee_interpolate(uint16_t target, uint16_t srcLeft,980uint16_t srcRight, int16_t targetLeft, int16_t targetRight);981982/* Whether 5ghz fast clock is needed */983/*984* The chipset (Merlin, AR9300/later) should set the capability flag below;985* this flag simply says that the hardware can do it, not that the EEPROM986* says it can.987*988* Merlin 2.0/2.1 chips with an EEPROM version > 16 do 5ghz fast clock989* if the relevant eeprom flag is set.990* Merlin 2.0/2.1 chips with an EEPROM version <= 16 do 5ghz fast clock991* by default.992*/993#define IS_5GHZ_FAST_CLOCK_EN(_ah, _c) \994(IEEE80211_IS_CHAN_5GHZ(_c) && \995AH_PRIVATE((_ah))->ah_caps.halSupportsFastClock5GHz && \996ath_hal_eepromGetFlag((_ah), AR_EEP_FSTCLK_5G))997998/*999* Fetch the maximum regulatory domain power for the given channel1000* in 1/2dBm steps.1001*/1002static inline int1003ath_hal_get_twice_max_regpower(struct ath_hal_private *ahp,1004const HAL_CHANNEL_INTERNAL *ichan, const struct ieee80211_channel *chan)1005{1006struct ath_hal *ah = &ahp->h;10071008if (! chan) {1009ath_hal_printf(ah, "%s: called with chan=NULL!\n", __func__);1010return (0);1011}1012return (chan->ic_maxpower);1013}10141015/*1016* Get the maximum antenna gain allowed, in 1/2dBm steps.1017*/1018static inline int1019ath_hal_getantennaallowed(struct ath_hal *ah,1020const struct ieee80211_channel *chan)1021{10221023if (! chan)1024return (0);10251026return (chan->ic_maxantgain);1027}10281029/*1030* Map the given 2GHz channel to an IEEE number.1031*/1032extern int ath_hal_mhz2ieee_2ghz(struct ath_hal *, int freq);10331034/*1035* Clear the channel survey data.1036*/1037extern void ath_hal_survey_clear(struct ath_hal *ah);10381039/*1040* Add a sample to the channel survey data.1041*/1042extern void ath_hal_survey_add_sample(struct ath_hal *ah,1043HAL_SURVEY_SAMPLE *hs);10441045/*1046* Chip registration - for modules.1047*/1048extern int ath_hal_add_chip(struct ath_hal_chip *ahc);1049extern int ath_hal_remove_chip(struct ath_hal_chip *ahc);1050extern int ath_hal_add_rf(struct ath_hal_rf *arf);1051extern int ath_hal_remove_rf(struct ath_hal_rf *arf);10521053#endif /* _ATH_AH_INTERAL_H_ */105410551056