| 1 | /* |
| 2 | * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting |
| 3 | * Copyright (c) 2002-2008 Atheros Communications, Inc. |
| 4 | * |
| 5 | * Permission to use, copy, modify, and/or distribute this software for any |
| 6 | * purpose with or without fee is hereby granted, provided that the above |
| 7 | * copyright notice and this permission notice appear in all copies. |
| 8 | * |
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 16 | * |
| 17 | * $Id: ah_internal.h,v 1.6 2011/03/07 11:25:42 cegger Exp $ |
| 18 | */ |
| 19 | #ifndef _ATH_AH_INTERAL_H_ |
| 20 | #define _ATH_AH_INTERAL_H_ |
| 21 | /* |
| 22 | * Atheros Device Hardware Access Layer (HAL). |
| 23 | * |
| 24 | * Internal definitions. |
| 25 | */ |
| 26 | #define AH_NULL 0 |
| 27 | #define AH_MIN(a,b) ((a)<(b)?(a):(b)) |
| 28 | #define AH_MAX(a,b) ((a)>(b)?(a):(b)) |
| 29 | |
| 30 | #ifndef NBBY |
| 31 | #define NBBY 8 /* number of bits/byte */ |
| 32 | #endif |
| 33 | |
| 34 | #ifndef roundup |
| 35 | #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */ |
| 36 | #endif |
| 37 | #ifndef howmany |
| 38 | #define howmany(x, y) (((x)+((y)-1))/(y)) |
| 39 | #endif |
| 40 | |
| 41 | #ifndef offsetof |
| 42 | #define offsetof(type, field) ((size_t)(&((type *)0)->field)) |
| 43 | #endif |
| 44 | |
| 45 | /* |
| 46 | * Remove const in a way that keeps the compiler happy. |
| 47 | * This works for gcc but may require other magic for |
| 48 | * other compilers (not sure where this should reside). |
| 49 | * Note that uintptr_t is C99. |
| 50 | */ |
| 51 | #ifndef __DECONST |
| 52 | #define __DECONST(type, var) ((type)(unsigned long)(const void *)(var)) |
| 53 | #endif |
| 54 | |
| 55 | typedef struct { |
| 56 | uint16_t start; /* first register */ |
| 57 | uint16_t end; /* ending register or zero */ |
| 58 | } HAL_REGRANGE; |
| 59 | |
| 60 | typedef struct { |
| 61 | uint32_t addr; /* register address/offset */ |
| 62 | uint32_t value; /* value to write */ |
| 63 | } HAL_REGWRITE; |
| 64 | |
| 65 | /* |
| 66 | * Transmit power scale factor. |
| 67 | * |
| 68 | * NB: This is not public because we want to discourage the use of |
| 69 | * scaling; folks should use the tx power limit interface. |
| 70 | */ |
| 71 | typedef enum { |
| 72 | HAL_TP_SCALE_MAX = 0, /* no scaling (default) */ |
| 73 | HAL_TP_SCALE_50 = 1, /* 50% of max (-3 dBm) */ |
| 74 | HAL_TP_SCALE_25 = 2, /* 25% of max (-6 dBm) */ |
| 75 | HAL_TP_SCALE_12 = 3, /* 12% of max (-9 dBm) */ |
| 76 | HAL_TP_SCALE_MIN = 4, /* min, but still on */ |
| 77 | } HAL_TP_SCALE; |
| 78 | |
| 79 | typedef enum { |
| 80 | HAL_CAP_RADAR = 0, /* Radar capability */ |
| 81 | HAL_CAP_AR = 1, /* AR capability */ |
| 82 | } HAL_PHYDIAG_CAPS; |
| 83 | |
| 84 | /* |
| 85 | * Each chip or class of chips registers to offer support. |
| 86 | */ |
| 87 | struct ath_hal_chip { |
| 88 | const char *name; |
| 89 | const char *(*probe)(uint16_t vendorid, uint16_t devid); |
| 90 | struct ath_hal *(*attach)(uint16_t devid, HAL_SOFTC, |
| 91 | HAL_BUS_TAG, HAL_BUS_HANDLE, HAL_STATUS *error); |
| 92 | }; |
| 93 | #ifndef AH_CHIP |
| 94 | #define AH_CHIP(_name, _probe, _attach) \ |
| 95 | static struct ath_hal_chip _name##_chip = { \ |
| 96 | .name = #_name, \ |
| 97 | .probe = _probe, \ |
| 98 | .attach = _attach \ |
| 99 | }; \ |
| 100 | OS_DATA_SET(ah_chips, _name##_chip) |
| 101 | #endif |
| 102 | |
| 103 | /* |
| 104 | * Each RF backend registers to offer support; this is mostly |
| 105 | * used by multi-chip 5212 solutions. Single-chip solutions |
| 106 | * have a fixed idea about which RF to use. |
| 107 | */ |
| 108 | struct ath_hal_rf { |
| 109 | const char *name; |
| 110 | HAL_BOOL (*probe)(struct ath_hal *ah); |
| 111 | HAL_BOOL (*attach)(struct ath_hal *ah, HAL_STATUS *ecode); |
| 112 | }; |
| 113 | #ifndef AH_RF |
| 114 | #define AH_RF(_name, _probe, _attach) \ |
| 115 | static struct ath_hal_rf _name##_rf = { \ |
| 116 | .name = __STRING(_name), \ |
| 117 | .probe = _probe, \ |
| 118 | .attach = _attach \ |
| 119 | }; \ |
| 120 | OS_DATA_SET(ah_rfs, _name##_rf) |
| 121 | #endif |
| 122 | |
| 123 | struct ath_hal_rf *ath_hal_rfprobe(struct ath_hal *ah, HAL_STATUS *ecode); |
| 124 | |
| 125 | /* |
| 126 | * Internal form of a HAL_CHANNEL. Note that the structure |
| 127 | * must be defined such that you can cast references to a |
| 128 | * HAL_CHANNEL so don't shuffle the first two members. |
| 129 | */ |
| 130 | typedef struct { |
| 131 | uint32_t channelFlags; |
| 132 | uint16_t channel; /* NB: must be first for casting */ |
| 133 | uint8_t privFlags; |
| 134 | int8_t maxRegTxPower; |
| 135 | int8_t maxTxPower; |
| 136 | int8_t minTxPower; /* as above... */ |
| 137 | |
| 138 | HAL_BOOL bssSendHere; |
| 139 | uint8_t gainI; |
| 140 | HAL_BOOL iqCalValid; |
| 141 | uint8_t calValid; /* bitmask of cal types */ |
| 142 | int8_t iCoff; |
| 143 | int8_t qCoff; |
| 144 | int16_t rawNoiseFloor; |
| 145 | int16_t noiseFloorAdjust; |
| 146 | int8_t antennaMax; |
| 147 | uint32_t regDmnFlags; /* Flags for channel use in reg */ |
| 148 | uint32_t conformanceTestLimit; /* conformance test limit from reg domain */ |
| 149 | uint16_t mainSpur; /* cached spur value for this cahnnel */ |
| 150 | } HAL_CHANNEL_INTERNAL; |
| 151 | |
| 152 | typedef struct { |
| 153 | uint32_t halChanSpreadSupport : 1, |
| 154 | halSleepAfterBeaconBroken : 1, |
| 155 | halCompressSupport : 1, |
| 156 | halBurstSupport : 1, |
| 157 | halFastFramesSupport : 1, |
| 158 | halChapTuningSupport : 1, |
| 159 | halTurboGSupport : 1, |
| 160 | halTurboPrimeSupport : 1, |
| 161 | halMicAesCcmSupport : 1, |
| 162 | halMicCkipSupport : 1, |
| 163 | halMicTkipSupport : 1, |
| 164 | halTkipMicTxRxKeySupport : 1, |
| 165 | halCipherAesCcmSupport : 1, |
| 166 | halCipherCkipSupport : 1, |
| 167 | halCipherTkipSupport : 1, |
| 168 | halPSPollBroken : 1, |
| 169 | halVEOLSupport : 1, |
| 170 | halBssIdMaskSupport : 1, |
| 171 | halMcastKeySrchSupport : 1, |
| 172 | halTsfAddSupport : 1, |
| 173 | halChanHalfRate : 1, |
| 174 | halChanQuarterRate : 1, |
| 175 | halHTSupport : 1, |
| 176 | halRfSilentSupport : 1, |
| 177 | halHwPhyCounterSupport : 1, |
| 178 | halWowSupport : 1, |
| 179 | halWowMatchPatternExact : 1, |
| 180 | halAutoSleepSupport : 1, |
| 181 | halFastCCSupport : 1, |
| 182 | halBtCoexSupport : 1; |
| 183 | uint32_t halRxStbcSupport : 1, |
| 184 | halTxStbcSupport : 1, |
| 185 | halGTTSupport : 1, |
| 186 | halCSTSupport : 1, |
| 187 | halRifsRxSupport : 1, |
| 188 | halRifsTxSupport : 1, |
| 189 | halExtChanDfsSupport : 1, |
| 190 | halForcePpmSupport : 1, |
| 191 | halEnhancedPmSupport : 1, |
| 192 | halMbssidAggrSupport : 1, |
| 193 | halBssidMatchSupport : 1; |
| 194 | uint32_t halWirelessModes; |
| 195 | uint16_t halTotalQueues; |
| 196 | uint16_t halKeyCacheSize; |
| 197 | uint16_t halLow5GhzChan, halHigh5GhzChan; |
| 198 | uint16_t halLow2GhzChan, halHigh2GhzChan; |
| 199 | int halTstampPrecision; |
| 200 | int halRtsAggrLimit; |
| 201 | uint8_t halTxChainMask; |
| 202 | uint8_t halRxChainMask; |
| 203 | uint8_t halNumGpioPins; |
| 204 | uint8_t halNumAntCfg2GHz; |
| 205 | uint8_t halNumAntCfg5GHz; |
| 206 | uint32_t halIntrMask; |
| 207 | } HAL_CAPABILITIES; |
| 208 | |
| 209 | /* |
| 210 | * The ``private area'' follows immediately after the ``public area'' |
| 211 | * in the data structure returned by ath_hal_attach. Private data are |
| 212 | * used by device-independent code such as the regulatory domain support. |
| 213 | * In general, code within the HAL should never depend on data in the |
| 214 | * public area. Instead any public data needed internally should be |
| 215 | * shadowed here. |
| 216 | * |
| 217 | * When declaring a device-specific ath_hal data structure this structure |
| 218 | * is assumed to at the front; e.g. |
| 219 | * |
| 220 | * struct ath_hal_5212 { |
| 221 | * struct ath_hal_private ah_priv; |
| 222 | * ... |
| 223 | * }; |
| 224 | * |
| 225 | * It might be better to manage the method pointers in this structure |
| 226 | * using an indirect pointer to a read-only data structure but this would |
| 227 | * disallow class-style method overriding. |
| 228 | */ |
| 229 | struct ath_hal_private { |
| 230 | struct ath_hal h; /* public area */ |
| 231 | |
| 232 | /* NB: all methods go first to simplify initialization */ |
| 233 | HAL_BOOL (*ah_getChannelEdges)(struct ath_hal*, |
| 234 | uint16_t channelFlags, |
| 235 | uint16_t *lowChannel, uint16_t *highChannel); |
| 236 | u_int (*ah_getWirelessModes)(struct ath_hal*); |
| 237 | HAL_BOOL (*ah_eepromRead)(struct ath_hal *, u_int off, |
| 238 | uint16_t *data); |
| 239 | HAL_BOOL (*ah_eepromWrite)(struct ath_hal *, u_int off, |
| 240 | uint16_t data); |
| 241 | HAL_BOOL (*ah_gpioCfgOutput)(struct ath_hal *, |
| 242 | uint32_t gpio, HAL_GPIO_MUX_TYPE); |
| 243 | HAL_BOOL (*ah_gpioCfgInput)(struct ath_hal *, uint32_t gpio); |
| 244 | uint32_t (*ah_gpioGet)(struct ath_hal *, uint32_t gpio); |
| 245 | HAL_BOOL (*ah_gpioSet)(struct ath_hal *, |
| 246 | uint32_t gpio, uint32_t val); |
| 247 | void (*ah_gpioSetIntr)(struct ath_hal*, u_int, uint32_t); |
| 248 | HAL_BOOL (*ah_getChipPowerLimits)(struct ath_hal *, |
| 249 | HAL_CHANNEL *, uint32_t); |
| 250 | int16_t (*ah_getNfAdjust)(struct ath_hal *, |
| 251 | const HAL_CHANNEL_INTERNAL*); |
| 252 | void (*ah_getNoiseFloor)(struct ath_hal *, |
| 253 | int16_t nfarray[]); |
| 254 | |
| 255 | void *ah_eeprom; /* opaque EEPROM state */ |
| 256 | uint16_t ah_eeversion; /* EEPROM version */ |
| 257 | void (*ah_eepromDetach)(struct ath_hal *); |
| 258 | HAL_STATUS (*ah_eepromGet)(struct ath_hal *, int, void *); |
| 259 | HAL_BOOL (*ah_eepromSet)(struct ath_hal *, int, int); |
| 260 | uint16_t (*ah_getSpurChan)(struct ath_hal *, int, HAL_BOOL); |
| 261 | HAL_BOOL (*ah_eepromDiag)(struct ath_hal *, int request, |
| 262 | const void *args, uint32_t argsize, |
| 263 | void **result, uint32_t *resultsize); |
| 264 | |
| 265 | /* |
| 266 | * Device revision information. |
| 267 | */ |
| 268 | uint16_t ah_devid; /* PCI device ID */ |
| 269 | uint16_t ah_subvendorid; /* PCI subvendor ID */ |
| 270 | uint32_t ah_macVersion; /* MAC version id */ |
| 271 | uint16_t ah_macRev; /* MAC revision */ |
| 272 | uint16_t ah_phyRev; /* PHY revision */ |
| 273 | uint16_t ah_analog5GhzRev; /* 2GHz radio revision */ |
| 274 | uint16_t ah_analog2GhzRev; /* 5GHz radio revision */ |
| 275 | uint8_t ah_ispcie; /* PCIE, special treatment */ |
| 276 | |
| 277 | |
| 278 | HAL_OPMODE ah_opmode; /* operating mode from reset */ |
| 279 | HAL_CAPABILITIES ah_caps; /* device capabilities */ |
| 280 | uint32_t ah_diagreg; /* user-specified AR_DIAG_SW */ |
| 281 | int16_t ah_powerLimit; /* tx power cap */ |
| 282 | uint16_t ah_maxPowerLevel; /* calculated max tx power */ |
| 283 | u_int ah_tpScale; /* tx power scale factor */ |
| 284 | uint32_t ah_11nCompat; /* 11n compat controls */ |
| 285 | |
| 286 | /* |
| 287 | * State for regulatory domain handling. |
| 288 | */ |
| 289 | HAL_REG_DOMAIN ah_currentRD; /* Current regulatory domain */ |
| 290 | HAL_CTRY_CODE ah_countryCode; /* current country code */ |
| 291 | HAL_CHANNEL_INTERNAL ah_channels[256]; /* calculated channel list */ |
| 292 | u_int ah_nchan; /* valid channels in list */ |
| 293 | HAL_CHANNEL_INTERNAL *ah_curchan; /* current channel */ |
| 294 | |
| 295 | uint8_t ah_coverageClass; /* coverage class */ |
| 296 | HAL_BOOL ah_regdomainUpdate; /* regdomain is updated? */ |
| 297 | /* |
| 298 | * RF Silent handling; setup according to the EEPROM. |
| 299 | */ |
| 300 | uint16_t ah_rfsilent; /* GPIO pin + polarity */ |
| 301 | HAL_BOOL ah_rfkillEnabled; /* enable/disable RfKill */ |
| 302 | /* |
| 303 | * Diagnostic support for discriminating HIUERR reports. |
| 304 | */ |
| 305 | uint32_t ah_fatalState[6]; /* AR_ISR+shadow regs */ |
| 306 | int ah_rxornIsFatal; /* how to treat HAL_INT_RXORN */ |
| 307 | }; |
| 308 | |
| 309 | #define AH_PRIVATE(_ah) ((struct ath_hal_private *)(_ah)) |
| 310 | |
| 311 | #define ath_hal_getChannelEdges(_ah, _cf, _lc, _hc) \ |
| 312 | AH_PRIVATE(_ah)->ah_getChannelEdges(_ah, _cf, _lc, _hc) |
| 313 | #define ath_hal_getWirelessModes(_ah) \ |
| 314 | AH_PRIVATE(_ah)->ah_getWirelessModes(_ah) |
| 315 | #define ath_hal_eepromRead(_ah, _off, _data) \ |
| 316 | AH_PRIVATE(_ah)->ah_eepromRead(_ah, _off, _data) |
| 317 | #define ath_hal_eepromWrite(_ah, _off, _data) \ |
| 318 | AH_PRIVATE(_ah)->ah_eepromWrite(_ah, _off, _data) |
| 319 | #define ath_hal_gpioCfgOutput(_ah, _gpio, _type) \ |
| 320 | AH_PRIVATE(_ah)->ah_gpioCfgOutput(_ah, _gpio, _type) |
| 321 | #define ath_hal_gpioCfgInput(_ah, _gpio) \ |
| 322 | AH_PRIVATE(_ah)->ah_gpioCfgInput(_ah, _gpio) |
| 323 | #define ath_hal_gpioGet(_ah, _gpio) \ |
| 324 | AH_PRIVATE(_ah)->ah_gpioGet(_ah, _gpio) |
| 325 | #define ath_hal_gpioSet(_ah, _gpio, _val) \ |
| 326 | AH_PRIVATE(_ah)->ah_gpioGet(_ah, _gpio, _val) |
| 327 | #define ath_hal_gpioSetIntr(_ah, _gpio, _ilevel) \ |
| 328 | AH_PRIVATE(_ah)->ah_gpioSetIntr(_ah, _gpio, _ilevel) |
| 329 | #define ath_hal_getpowerlimits(_ah, _chans, _nchan) \ |
| 330 | AH_PRIVATE(_ah)->ah_getChipPowerLimits(_ah, _chans, _nchan) |
| 331 | #define ath_hal_getNfAdjust(_ah, _c) \ |
| 332 | AH_PRIVATE(_ah)->ah_getNfAdjust(_ah, _c) |
| 333 | #define ath_hal_getNoiseFloor(_ah, _nfArray) \ |
| 334 | AH_PRIVATE(_ah)->ah_getNoiseFloor(_ah, _nfArray) |
| 335 | #define ath_hal_configPCIE(_ah, _reset) \ |
| 336 | (_ah)->ah_configPCIE(_ah, _reset) |
| 337 | #define ath_hal_disablePCIE(_ah) \ |
| 338 | (_ah)->ah_disablePCIE(_ah) |
| 339 | #define ath_hal_setInterrupts(_ah, _mask) \ |
| 340 | (_ah)->ah_setInterrupts(_ah, _mask) |
| 341 | |
| 342 | #define ath_hal_eepromDetach(_ah) \ |
| 343 | do { \ |
| 344 | if (AH_PRIVATE(_ah)->ah_eepromDetach != NULL) \ |
| 345 | AH_PRIVATE(_ah)->ah_eepromDetach(_ah); \ |
| 346 | } while (/*CONSTCOND*/0) |
| 347 | #define ath_hal_eepromGet(_ah, _param, _val) \ |
| 348 | AH_PRIVATE(_ah)->ah_eepromGet(_ah, _param, _val) |
| 349 | #define ath_hal_eepromSet(_ah, _param, _val) \ |
| 350 | AH_PRIVATE(_ah)->ah_eepromSet(_ah, _param, _val) |
| 351 | #define ath_hal_eepromGetFlag(_ah, _param) \ |
| 352 | (AH_PRIVATE(_ah)->ah_eepromGet(_ah, _param, AH_NULL) == HAL_OK) |
| 353 | #define ath_hal_getSpurChan(_ah, _ix, _is2G) \ |
| 354 | AH_PRIVATE(_ah)->ah_getSpurChan(_ah, _ix, _is2G) |
| 355 | #define ath_hal_eepromDiag(_ah, _request, _a, _asize, _r, _rsize) \ |
| 356 | AH_PRIVATE(_ah)->ah_eepromDiag(_ah, _request, _a, _asize, _r, _rsize) |
| 357 | |
| 358 | #if !defined(_NET_IF_IEEE80211_H_) && !defined(_NET80211__IEEE80211_H_) |
| 359 | /* |
| 360 | * Stuff that would naturally come from _ieee80211.h |
| 361 | */ |
| 362 | #define IEEE80211_ADDR_LEN 6 |
| 363 | |
| 364 | #define IEEE80211_WEP_KEYLEN 5 /* 40bit */ |
| 365 | #define IEEE80211_WEP_IVLEN 3 /* 24bit */ |
| 366 | #define IEEE80211_WEP_KIDLEN 1 /* 1 octet */ |
| 367 | #define IEEE80211_WEP_CRCLEN 4 /* CRC-32 */ |
| 368 | |
| 369 | #define IEEE80211_CRC_LEN 4 |
| 370 | |
| 371 | #define IEEE80211_MTU 1500 |
| 372 | #define IEEE80211_MAX_LEN (2300 + IEEE80211_CRC_LEN + \ |
| 373 | (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN)) |
| 374 | |
| 375 | enum { |
| 376 | IEEE80211_T_DS, /* direct sequence spread spectrum */ |
| 377 | IEEE80211_T_FH, /* frequency hopping */ |
| 378 | IEEE80211_T_OFDM, /* frequency division multiplexing */ |
| 379 | IEEE80211_T_TURBO, /* high rate DS */ |
| 380 | IEEE80211_T_HT, /* HT - full GI */ |
| 381 | }; |
| 382 | #define IEEE80211_T_CCK IEEE80211_T_DS /* more common nomenclatur */ |
| 383 | #endif /* _NET_IF_IEEE80211_H_ */ |
| 384 | |
| 385 | /* NB: these are defined privately until XR support is announced */ |
| 386 | enum { |
| 387 | ATHEROS_T_XR = IEEE80211_T_HT+1, /* extended range */ |
| 388 | }; |
| 389 | |
| 390 | #define HAL_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001 |
| 391 | |
| 392 | #define INIT_AIFS 2 |
| 393 | #define INIT_CWMIN 15 |
| 394 | #define INIT_CWMIN_11B 31 |
| 395 | #define INIT_CWMAX 1023 |
| 396 | #define INIT_SH_RETRY 10 |
| 397 | #define INIT_LG_RETRY 10 |
| 398 | #define INIT_SSH_RETRY 32 |
| 399 | #define INIT_SLG_RETRY 32 |
| 400 | |
| 401 | typedef struct { |
| 402 | uint32_t tqi_ver; /* HAL TXQ verson */ |
| 403 | HAL_TX_QUEUE tqi_type; /* hw queue type*/ |
| 404 | HAL_TX_QUEUE_SUBTYPE tqi_subtype; /* queue subtype, if applicable */ |
| 405 | HAL_TX_QUEUE_FLAGS tqi_qflags; /* queue flags */ |
| 406 | uint32_t tqi_priority; |
| 407 | uint32_t tqi_aifs; /* aifs */ |
| 408 | uint32_t tqi_cwmin; /* cwMin */ |
| 409 | uint32_t tqi_cwmax; /* cwMax */ |
| 410 | uint16_t tqi_shretry; /* frame short retry limit */ |
| 411 | uint16_t tqi_lgretry; /* frame long retry limit */ |
| 412 | uint32_t tqi_cbrPeriod; |
| 413 | uint32_t tqi_cbrOverflowLimit; |
| 414 | uint32_t tqi_burstTime; |
| 415 | uint32_t tqi_readyTime; |
| 416 | uint32_t tqi_physCompBuf; |
| 417 | uint32_t tqi_intFlags; /* flags for internal use */ |
| 418 | } HAL_TX_QUEUE_INFO; |
| 419 | |
| 420 | extern HAL_BOOL ath_hal_setTxQProps(struct ath_hal *ah, |
| 421 | HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo); |
| 422 | extern HAL_BOOL ath_hal_getTxQProps(struct ath_hal *ah, |
| 423 | HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi); |
| 424 | |
| 425 | typedef enum { |
| 426 | HAL_ANI_PRESENT, /* is ANI support present */ |
| 427 | HAL_ANI_NOISE_IMMUNITY_LEVEL, /* set level */ |
| 428 | HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, /* enable/disable */ |
| 429 | HAL_ANI_CCK_WEAK_SIGNAL_THR, /* enable/disable */ |
| 430 | HAL_ANI_FIRSTEP_LEVEL, /* set level */ |
| 431 | HAL_ANI_SPUR_IMMUNITY_LEVEL, /* set level */ |
| 432 | HAL_ANI_MODE = 6, /* 0 => manual, 1 => auto (XXX do not change) */ |
| 433 | HAL_ANI_PHYERR_RESET, /* reset phy error stats */ |
| 434 | } HAL_ANI_CMD; |
| 435 | |
| 436 | #define HAL_SPUR_VAL_MASK 0x3FFF |
| 437 | #define HAL_SPUR_CHAN_WIDTH 87 |
| 438 | #define HAL_BIN_WIDTH_BASE_100HZ 3125 |
| 439 | #define HAL_BIN_WIDTH_TURBO_100HZ 6250 |
| 440 | #define HAL_MAX_BINS_ALLOWED 28 |
| 441 | |
| 442 | /* |
| 443 | * A = 5GHZ|OFDM |
| 444 | * T = 5GHZ|OFDM|TURBO |
| 445 | * |
| 446 | * IS_CHAN_A(T) will return TRUE. This is probably |
| 447 | * not the default behavior we want. We should migrate to a better mask -- |
| 448 | * perhaps CHANNEL_ALL. |
| 449 | * |
| 450 | * For now, IS_CHAN_G() masks itself with CHANNEL_108G. |
| 451 | * |
| 452 | */ |
| 453 | |
| 454 | #define IS_CHAN_A(_c) (((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) |
| 455 | #define IS_CHAN_B(_c) (((_c)->channelFlags & CHANNEL_B) == CHANNEL_B) |
| 456 | #define IS_CHAN_G(_c) (((_c)->channelFlags & (CHANNEL_108G|CHANNEL_G)) == CHANNEL_G) |
| 457 | #define IS_CHAN_108G(_c)(((_c)->channelFlags & CHANNEL_108G) == CHANNEL_108G) |
| 458 | #define IS_CHAN_T(_c) (((_c)->channelFlags & CHANNEL_T) == CHANNEL_T) |
| 459 | #define IS_CHAN_PUREG(_c) \ |
| 460 | (((_c)->channelFlags & CHANNEL_PUREG) == CHANNEL_PUREG) |
| 461 | |
| 462 | #define IS_CHAN_TURBO(_c) (((_c)->channelFlags & CHANNEL_TURBO) != 0) |
| 463 | #define IS_CHAN_CCK(_c) (((_c)->channelFlags & CHANNEL_CCK) != 0) |
| 464 | #define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0) |
| 465 | #define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0) |
| 466 | #define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0) |
| 467 | #define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0) |
| 468 | #define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0) |
| 469 | #define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0) |
| 470 | |
| 471 | #define IS_CHAN_IN_PUBLIC_SAFETY_BAND(_c) ((_c) > 4940 && (_c) < 4990) |
| 472 | |
| 473 | #define CHANNEL_HT40 (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS) |
| 474 | #define CHANNEL_HT (CHANNEL_HT20 | CHANNEL_HT40) |
| 475 | #define IS_CHAN_HT(_c) (((_c)->channelFlags & CHANNEL_HT) != 0) |
| 476 | #define IS_CHAN_HT20(_c) (((_c)->channelFlags & CHANNEL_HT) == CHANNEL_HT20) |
| 477 | #define IS_CHAN_HT40(_c) (((_c)->channelFlags & CHANNEL_HT40) != 0) |
| 478 | |
| 479 | /* |
| 480 | * Deduce if the host cpu has big- or litt-endian byte order. |
| 481 | */ |
| 482 | static __inline__ int |
| 483 | isBigEndian(void) |
| 484 | { |
| 485 | union { |
| 486 | int32_t i; |
| 487 | char c[4]; |
| 488 | } u; |
| 489 | u.i = 1; |
| 490 | return (u.c[0] == 0); |
| 491 | } |
| 492 | |
| 493 | /* unalligned little endian access */ |
| 494 | #define LE_READ_2(p) \ |
| 495 | ((uint16_t) \ |
| 496 | ((((const uint8_t *)(p))[0] ) | (((const uint8_t *)(p))[1]<< 8))) |
| 497 | #define LE_READ_4(p) \ |
| 498 | ((uint32_t) \ |
| 499 | ((((const uint8_t *)(p))[0] ) | (((const uint8_t *)(p))[1]<< 8) |\ |
| 500 | (((const uint8_t *)(p))[2]<<16) | (((const uint8_t *)(p))[3]<<24))) |
| 501 | |
| 502 | /* |
| 503 | * Register manipulation macros that expect bit field defines |
| 504 | * to follow the convention that an _S suffix is appended for |
| 505 | * a shift count, while the field mask has no suffix. |
| 506 | */ |
| 507 | #define SM(_v, _f) (((_v) << _f##_S) & (_f)) |
| 508 | #define MS(_v, _f) (((_v) & (_f)) >> _f##_S) |
| 509 | #define OS_REG_RMW_FIELD(_a, _r, _f, _v) \ |
| 510 | OS_REG_WRITE(_a, _r, \ |
| 511 | (OS_REG_READ(_a, _r) &~ (_f)) | (((_v) << _f##_S) & (_f))) |
| 512 | #define OS_REG_SET_BIT(_a, _r, _f) \ |
| 513 | OS_REG_WRITE(_a, _r, OS_REG_READ(_a, _r) | (_f)) |
| 514 | #define OS_REG_CLR_BIT(_a, _r, _f) \ |
| 515 | OS_REG_WRITE(_a, _r, OS_REG_READ(_a, _r) &~ (_f)) |
| 516 | |
| 517 | /* |
| 518 | * Regulatory domain support. |
| 519 | */ |
| 520 | |
| 521 | /* |
| 522 | * Return the max allowed antenna gain based on the current |
| 523 | * regulatory domain. |
| 524 | */ |
| 525 | extern u_int ath_hal_getantennareduction(struct ath_hal *, |
| 526 | HAL_CHANNEL *, u_int twiceGain); |
| 527 | /* |
| 528 | * Return the test group for the specific channel based on |
| 529 | * the current regulator domain. |
| 530 | */ |
| 531 | extern u_int ath_hal_getctl(struct ath_hal *, HAL_CHANNEL *); |
| 532 | /* |
| 533 | * Return whether or not a noise floor check is required |
| 534 | * based on the current regulatory domain for the specified |
| 535 | * channel. |
| 536 | */ |
| 537 | extern HAL_BOOL ath_hal_getnfcheckrequired(struct ath_hal *, HAL_CHANNEL *); |
| 538 | |
| 539 | /* |
| 540 | * Map a public channel definition to the corresponding |
| 541 | * internal data structure. This implicitly specifies |
| 542 | * whether or not the specified channel is ok to use |
| 543 | * based on the current regulatory domain constraints. |
| 544 | */ |
| 545 | extern HAL_CHANNEL_INTERNAL *ath_hal_checkchannel(struct ath_hal *, |
| 546 | const HAL_CHANNEL *); |
| 547 | |
| 548 | /* system-configurable parameters */ |
| 549 | extern int ath_hal_dma_beacon_response_time; /* in TU's */ |
| 550 | extern int ath_hal_sw_beacon_response_time; /* in TU's */ |
| 551 | extern int ath_hal_additional_swba_backoff; /* in TU's */ |
| 552 | |
| 553 | /* wait for the register contents to have the specified value */ |
| 554 | extern HAL_BOOL ath_hal_wait(struct ath_hal *, u_int reg, |
| 555 | uint32_t mask, uint32_t val); |
| 556 | |
| 557 | /* return the first n bits in val reversed */ |
| 558 | extern uint32_t ath_hal_reverseBits(uint32_t val, uint32_t n); |
| 559 | |
| 560 | /* printf interfaces */ |
| 561 | extern void ath_hal_printf(struct ath_hal *, const char*, ...) |
| 562 | __printflike(2,3); |
| 563 | extern void ath_hal_vprintf(struct ath_hal *, const char*, va_list) |
| 564 | __printflike(2, 0); |
| 565 | extern const char* ath_hal_ether_sprintf(const uint8_t *mac); |
| 566 | |
| 567 | /* allocate and free memory */ |
| 568 | extern void *ath_hal_malloc(size_t); |
| 569 | extern void ath_hal_free(void *); |
| 570 | |
| 571 | /* common debugging interfaces */ |
| 572 | #ifdef AH_DEBUG |
| 573 | #include "ah_debug.h" |
| 574 | extern int ath_hal_debug; |
| 575 | extern void HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...) |
| 576 | __printflike(3,4); |
| 577 | #else |
| 578 | #define HALDEBUG(_ah, __m, _fmt, ...) |
| 579 | #endif /* AH_DEBUG */ |
| 580 | |
| 581 | /* |
| 582 | * Register logging definitions shared with ardecode. |
| 583 | */ |
| 584 | #include "ah_decode.h" |
| 585 | |
| 586 | /* |
| 587 | * Common assertion interface. Note: it is a bad idea to generate |
| 588 | * an assertion failure for any recoverable event. Instead catch |
| 589 | * the violation and, if possible, fix it up or recover from it; either |
| 590 | * with an error return value or a diagnostic messages. System software |
| 591 | * does not panic unless the situation is hopeless. |
| 592 | */ |
| 593 | #ifdef AH_ASSERT |
| 594 | extern void ath_hal_assert_failed(const char* filename, |
| 595 | int lineno, const char* msg); |
| 596 | |
| 597 | #define HALASSERT(_x) do { \ |
| 598 | if (!(_x)) { \ |
| 599 | ath_hal_assert_failed(__FILE__, __LINE__, #_x); \ |
| 600 | } \ |
| 601 | } while (0) |
| 602 | #else |
| 603 | #define HALASSERT(_x) |
| 604 | #endif /* AH_ASSERT */ |
| 605 | |
| 606 | /* |
| 607 | * Return the h/w frequency for a channel. This may be |
| 608 | * different from ic_freq if this is a GSM device that |
| 609 | * takes 2.4GHz frequencies and down-converts them. |
| 610 | */ |
| 611 | static OS_INLINE uint16_t |
| 612 | ath_hal_gethwchannel(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c) |
| 613 | { |
| 614 | return ath_hal_checkchannel(ah, (const HAL_CHANNEL *)c)->channel; |
| 615 | } |
| 616 | |
| 617 | /* |
| 618 | * Convert between microseconds and core system clocks. |
| 619 | */ |
| 620 | extern u_int ath_hal_mac_clks(struct ath_hal *ah, u_int usecs); |
| 621 | extern u_int ath_hal_mac_usec(struct ath_hal *ah, u_int clks); |
| 622 | |
| 623 | /* |
| 624 | * Generic get/set capability support. Each chip overrides |
| 625 | * this routine to support chip-specific capabilities. |
| 626 | */ |
| 627 | extern HAL_STATUS ath_hal_getcapability(struct ath_hal *ah, |
| 628 | HAL_CAPABILITY_TYPE type, uint32_t capability, |
| 629 | uint32_t *result); |
| 630 | extern HAL_BOOL ath_hal_setcapability(struct ath_hal *ah, |
| 631 | HAL_CAPABILITY_TYPE type, uint32_t capability, |
| 632 | uint32_t setting, HAL_STATUS *status); |
| 633 | |
| 634 | /* |
| 635 | * Diagnostic interface. This is an open-ended interface that |
| 636 | * is opaque to applications. Diagnostic programs use this to |
| 637 | * retrieve internal data structures, etc. There is no guarantee |
| 638 | * that calling conventions for calls other than HAL_DIAG_REVS |
| 639 | * are stable between HAL releases; a diagnostic application must |
| 640 | * use the HAL revision information to deal with ABI/API differences. |
| 641 | * |
| 642 | * NB: do not renumber these, certain codes are publicly used. |
| 643 | */ |
| 644 | enum { |
| 645 | HAL_DIAG_REVS = 0, /* MAC/PHY/Radio revs */ |
| 646 | HAL_DIAG_EEPROM = 1, /* EEPROM contents */ |
| 647 | HAL_DIAG_EEPROM_EXP_11A = 2, /* EEPROM 5112 power exp for 11a */ |
| 648 | HAL_DIAG_EEPROM_EXP_11B = 3, /* EEPROM 5112 power exp for 11b */ |
| 649 | HAL_DIAG_EEPROM_EXP_11G = 4, /* EEPROM 5112 power exp for 11g */ |
| 650 | HAL_DIAG_ANI_CURRENT = 5, /* ANI current channel state */ |
| 651 | HAL_DIAG_ANI_OFDM = 6, /* ANI OFDM timing error stats */ |
| 652 | HAL_DIAG_ANI_CCK = 7, /* ANI CCK timing error stats */ |
| 653 | HAL_DIAG_ANI_STATS = 8, /* ANI statistics */ |
| 654 | HAL_DIAG_RFGAIN = 9, /* RfGain GAIN_VALUES */ |
| 655 | HAL_DIAG_RFGAIN_CURSTEP = 10, /* RfGain GAIN_OPTIMIZATION_STEP */ |
| 656 | HAL_DIAG_PCDAC = 11, /* PCDAC table */ |
| 657 | HAL_DIAG_TXRATES = 12, /* Transmit rate table */ |
| 658 | HAL_DIAG_REGS = 13, /* Registers */ |
| 659 | HAL_DIAG_ANI_CMD = 14, /* ANI issue command (XXX do not change!) */ |
| 660 | HAL_DIAG_SETKEY = 15, /* Set keycache backdoor */ |
| 661 | HAL_DIAG_RESETKEY = 16, /* Reset keycache backdoor */ |
| 662 | HAL_DIAG_EEREAD = 17, /* Read EEPROM word */ |
| 663 | HAL_DIAG_EEWRITE = 18, /* Write EEPROM word */ |
| 664 | /* 19 was HAL_DIAG_TXCONT, 20-23 were for radar */ |
| 665 | HAL_DIAG_REGREAD = 24, /* Reg reads */ |
| 666 | HAL_DIAG_REGWRITE = 25, /* Reg writes */ |
| 667 | HAL_DIAG_GET_REGBASE = 26, /* Get register base */ |
| 668 | HAL_DIAG_RDWRITE = 27, /* Write regulatory domain */ |
| 669 | HAL_DIAG_RDREAD = 28, /* Get regulatory domain */ |
| 670 | HAL_DIAG_FATALERR = 29, /* Read cached interrupt state */ |
| 671 | HAL_DIAG_11NCOMPAT = 30, /* 11n compatibility tweaks */ |
| 672 | HAL_DIAG_ANI_PARAMS = 31, /* ANI noise immunity parameters */ |
| 673 | HAL_DIAG_CHECK_HANGS = 32, /* check h/w hangs */ |
| 674 | }; |
| 675 | |
| 676 | enum { |
| 677 | HAL_BB_HANG_DFS = 0x0001, |
| 678 | HAL_BB_HANG_RIFS = 0x0002, |
| 679 | HAL_BB_HANG_RX_CLEAR = 0x0004, |
| 680 | HAL_BB_HANG_UNKNOWN = 0x0080, |
| 681 | |
| 682 | HAL_MAC_HANG_SIG1 = 0x0100, |
| 683 | HAL_MAC_HANG_SIG2 = 0x0200, |
| 684 | HAL_MAC_HANG_UNKNOWN = 0x8000, |
| 685 | |
| 686 | HAL_BB_HANGS = HAL_BB_HANG_DFS |
| 687 | | HAL_BB_HANG_RIFS |
| 688 | | HAL_BB_HANG_RX_CLEAR |
| 689 | | HAL_BB_HANG_UNKNOWN, |
| 690 | HAL_MAC_HANGS = HAL_MAC_HANG_SIG1 |
| 691 | | HAL_MAC_HANG_SIG2 |
| 692 | | HAL_MAC_HANG_UNKNOWN, |
| 693 | }; |
| 694 | |
| 695 | /* |
| 696 | * Device revision information. |
| 697 | */ |
| 698 | typedef struct { |
| 699 | uint16_t ah_devid; /* PCI device ID */ |
| 700 | uint16_t ah_subvendorid; /* PCI subvendor ID */ |
| 701 | uint32_t ah_macVersion; /* MAC version id */ |
| 702 | uint16_t ah_macRev; /* MAC revision */ |
| 703 | uint16_t ah_phyRev; /* PHY revision */ |
| 704 | uint16_t ah_analog5GhzRev; /* 2GHz radio revision */ |
| 705 | uint16_t ah_analog2GhzRev; /* 5GHz radio revision */ |
| 706 | } HAL_REVS; |
| 707 | |
| 708 | /* |
| 709 | * Argument payload for HAL_DIAG_SETKEY. |
| 710 | */ |
| 711 | typedef struct { |
| 712 | HAL_KEYVAL dk_keyval; |
| 713 | uint16_t dk_keyix; /* key index */ |
| 714 | uint8_t dk_mac[IEEE80211_ADDR_LEN]; |
| 715 | int dk_xor; /* XOR key data */ |
| 716 | } HAL_DIAG_KEYVAL; |
| 717 | |
| 718 | /* |
| 719 | * Argument payload for HAL_DIAG_EEWRITE. |
| 720 | */ |
| 721 | typedef struct { |
| 722 | uint16_t ee_off; /* eeprom offset */ |
| 723 | uint16_t ee_data; /* write data */ |
| 724 | } HAL_DIAG_EEVAL; |
| 725 | |
| 726 | |
| 727 | typedef struct { |
| 728 | u_int offset; /* reg offset */ |
| 729 | uint32_t val; /* reg value */ |
| 730 | } HAL_DIAG_REGVAL; |
| 731 | |
| 732 | /* |
| 733 | * 11n compatibility tweaks. |
| 734 | */ |
| 735 | #define HAL_DIAG_11N_SERVICES 0x00000003 |
| 736 | #define HAL_DIAG_11N_SERVICES_S 0 |
| 737 | #define HAL_DIAG_11N_TXSTOMP 0x0000000c |
| 738 | #define HAL_DIAG_11N_TXSTOMP_S 2 |
| 739 | |
| 740 | typedef struct { |
| 741 | int maxNoiseImmunityLevel; /* [0..4] */ |
| 742 | int totalSizeDesired[5]; |
| 743 | int coarseHigh[5]; |
| 744 | int coarseLow[5]; |
| 745 | int firpwr[5]; |
| 746 | |
| 747 | int maxSpurImmunityLevel; /* [0..7] */ |
| 748 | int cycPwrThr1[8]; |
| 749 | |
| 750 | int maxFirstepLevel; /* [0..2] */ |
| 751 | int firstep[3]; |
| 752 | |
| 753 | uint32_t ofdmTrigHigh; |
| 754 | uint32_t ofdmTrigLow; |
| 755 | int32_t cckTrigHigh; |
| 756 | int32_t cckTrigLow; |
| 757 | int32_t ; |
| 758 | int32_t ; |
| 759 | |
| 760 | int period; /* update listen period */ |
| 761 | } HAL_ANI_PARAMS; |
| 762 | |
| 763 | extern HAL_BOOL ath_hal_getdiagstate(struct ath_hal *ah, int request, |
| 764 | const void *args, uint32_t argsize, |
| 765 | void **result, uint32_t *resultsize); |
| 766 | |
| 767 | /* |
| 768 | * Setup a h/w rate table for use. |
| 769 | */ |
| 770 | extern void ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt); |
| 771 | |
| 772 | /* |
| 773 | * Common routine for implementing getChanNoise api. |
| 774 | */ |
| 775 | extern int16_t ath_hal_getChanNoise(struct ath_hal *ah, HAL_CHANNEL *chan); |
| 776 | |
| 777 | /* |
| 778 | * Initialization support. |
| 779 | */ |
| 780 | typedef struct { |
| 781 | const uint32_t *data; |
| 782 | int rows, cols; |
| 783 | } HAL_INI_ARRAY; |
| 784 | |
| 785 | #define HAL_INI_INIT(_ia, _data, _cols) do { \ |
| 786 | (_ia)->data = (const uint32_t *)(_data); \ |
| 787 | (_ia)->rows = sizeof(_data) / sizeof((_data)[0]); \ |
| 788 | (_ia)->cols = (_cols); \ |
| 789 | } while (0) |
| 790 | #define HAL_INI_VAL(_ia, _r, _c) \ |
| 791 | ((_ia)->data[((_r)*(_ia)->cols) + (_c)]) |
| 792 | |
| 793 | /* |
| 794 | * OS_DELAY() does a PIO READ on the PCI bus which allows |
| 795 | * other cards' DMA reads to complete in the middle of our reset. |
| 796 | */ |
| 797 | #define DMA_YIELD(x) do { \ |
| 798 | if ((++(x) % 64) == 0) \ |
| 799 | OS_DELAY(1); \ |
| 800 | } while (0) |
| 801 | |
| 802 | #define HAL_INI_WRITE_ARRAY(ah, regArray, col, regWr) do { \ |
| 803 | int r; \ |
| 804 | for (r = 0; r < N(regArray); r++) { \ |
| 805 | OS_REG_WRITE(ah, (regArray)[r][0], (regArray)[r][col]); \ |
| 806 | DMA_YIELD(regWr); \ |
| 807 | } \ |
| 808 | } while (0) |
| 809 | |
| 810 | #define HAL_INI_WRITE_BANK(ah, regArray, bankData, regWr) do { \ |
| 811 | int r; \ |
| 812 | for (r = 0; r < N(regArray); r++) { \ |
| 813 | OS_REG_WRITE(ah, (regArray)[r][0], (bankData)[r]); \ |
| 814 | DMA_YIELD(regWr); \ |
| 815 | } \ |
| 816 | } while (0) |
| 817 | |
| 818 | extern int ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, |
| 819 | int col, int regWr); |
| 820 | extern void ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia, |
| 821 | int col); |
| 822 | extern int ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, |
| 823 | const uint32_t data[], int regWr); |
| 824 | |
| 825 | #define WLAN_CTRL_FRAME_SIZE (2+2+6+4) /* ACK+FCS */ |
| 826 | #endif /* _ATH_AH_INTERAL_H_ */ |
| 827 | |