Update to later code from my repository:
o many bug fixes o add new periodic calibration api o break up 5416 periodic calibration code in preparation for 928x o move get noise floor to rf backends o 5416-specific ani (still disabled) o modularize 5210 eeprom format a la other eeprom formats o start cleaning up regdomain code o prepare for proper 1/2 and 1/4 width channel support o bring back 900MHz card support o clean up 5212 rf version handling o add 1/2 and 1/4 width channel support for 5212 parts o split 5212 rfgain handling out o improve ani debugging o add AH_USE_INIPDGAIN compile option o purge a bunch of dead 5212 state o add 1/2 and 1/4 rate modes o remove HAL_CAP_CHAN_HALFRATE and HAL_CAP_CHAN_QUARTERRATE; the same info can now be deduced from the set of supported modes
This commit is contained in:
parent
89eac01a28
commit
d143488650
71
ah.c
71
ah.c
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ah.c,v 1.13 2008/11/10 04:08:00 sam Exp $
|
||||
* $Id: ah.c,v 1.15 2008/11/15 22:15:44 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -46,6 +46,14 @@ extern struct ath_hal *ar5416Attach(uint16_t, HAL_SOFTC,
|
||||
extern struct ath_hal *ar9160Attach(uint16_t, HAL_SOFTC,
|
||||
HAL_BUS_TAG, HAL_BUS_HANDLE, HAL_STATUS*);
|
||||
#endif
|
||||
#ifdef AH_SUPPORT_AR9280
|
||||
extern struct ath_hal *ar9280Attach(uint16_t, HAL_SOFTC,
|
||||
HAL_BUS_TAG, HAL_BUS_HANDLE, HAL_STATUS*);
|
||||
#endif
|
||||
#ifdef AH_SUPPORT_AR9285
|
||||
extern struct ath_hal *ar9285Attach(uint16_t, HAL_SOFTC,
|
||||
HAL_BUS_TAG, HAL_BUS_HANDLE, HAL_STATUS*);
|
||||
#endif
|
||||
|
||||
#include "version.h"
|
||||
char ath_hal_version[] = ATH_HAL_VERSION;
|
||||
@ -68,6 +76,12 @@ const char* ath_hal_buildopts[] = {
|
||||
#ifdef AH_SUPPORT_AR9180
|
||||
"AR9180",
|
||||
#endif
|
||||
#ifdef AH_SUPPORT_AR9280
|
||||
"AR9280",
|
||||
#endif
|
||||
#ifdef AH_SUPPORT_AR9285
|
||||
"AR9285",
|
||||
#endif
|
||||
#ifdef AH_SUPPORT_5111
|
||||
"RF5111",
|
||||
#endif
|
||||
@ -110,12 +124,21 @@ const char* ath_hal_buildopts[] = {
|
||||
#ifdef AH_PRIVATE_DIAG
|
||||
"PRIVATE_DIAG",
|
||||
#endif
|
||||
#ifdef AH_SUPPORT_WRITE_EEPROM
|
||||
"WRITE_EEPROM",
|
||||
#endif
|
||||
#ifdef AH_SUPPORT_WRITE_REGDOMAIN
|
||||
"WRITE_REGDOMAIN",
|
||||
#endif
|
||||
#ifdef AH_DEBUG_COUNTRY
|
||||
"DEBUG_COUNTRY",
|
||||
#endif
|
||||
#ifdef AH_NEED_DESC_SWAP
|
||||
"TX_DESC_SWAP",
|
||||
#endif
|
||||
#ifdef AH_USE_INIPDGAIN
|
||||
"INIPDGAIN",
|
||||
#endif
|
||||
#ifdef AH_DISABLE_WME
|
||||
"DISABLE_WME",
|
||||
#endif
|
||||
@ -169,6 +192,11 @@ ath_hal_devname(uint16_t devid)
|
||||
return "Atheros 5416";
|
||||
case AR9160_DEVID_PCI:
|
||||
return "Atheros 9160";
|
||||
case AR9280_DEVID_PCI:
|
||||
case AR9280_DEVID_PCIE:
|
||||
return "Atheros 9280";
|
||||
case AR9285_DEVID_PCIE:
|
||||
return "Atheros 9285";
|
||||
}
|
||||
return AH_NULL;
|
||||
}
|
||||
@ -246,6 +274,17 @@ ath_hal_attach(uint16_t devid, HAL_SOFTC sc,
|
||||
case AR9160_DEVID_PCI:
|
||||
ah = ar9160Attach(devid, sc, st, sh, error);
|
||||
break;
|
||||
#endif
|
||||
#ifdef AH_SUPPORT_AR9280
|
||||
case AR9280_DEVID_PCI:
|
||||
case AR9280_DEVID_PCIE:
|
||||
ah = ar9280Attach(devid, sc, st, sh, error);
|
||||
break;
|
||||
#endif
|
||||
#ifdef AH_SUPPORT_AR9285
|
||||
case AR9285_DEVID_PCIE:
|
||||
ah = ar9285Attach(devid, sc, st, sh, error);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ah = AH_NULL;
|
||||
@ -418,6 +457,19 @@ ath_hal_computetxtime(struct ath_hal *ah,
|
||||
return txTime;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
mapgsm(u_int freq, u_int flags)
|
||||
{
|
||||
freq *= 10;
|
||||
if (flags & CHANNEL_QUARTER)
|
||||
freq += 5;
|
||||
else if (flags & CHANNEL_HALF)
|
||||
freq += 10;
|
||||
else
|
||||
freq += 20;
|
||||
return (freq - 24220) / 5;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
mappsb(u_int freq, u_int flags)
|
||||
{
|
||||
@ -434,6 +486,8 @@ ath_hal_mhz2ieee(struct ath_hal *ah, u_int freq, u_int flags)
|
||||
if (freq == 2484)
|
||||
return 14;
|
||||
if (freq < 2484) {
|
||||
if (ath_hal_isgsmsku(ah))
|
||||
return mapgsm(freq, flags);
|
||||
return ((int)freq - 2407) / 5;
|
||||
} else
|
||||
return 15 + ((freq - 2512) / 20);
|
||||
@ -450,6 +504,8 @@ ath_hal_mhz2ieee(struct ath_hal *ah, u_int freq, u_int flags)
|
||||
if (freq == 2484)
|
||||
return 14;
|
||||
if (freq < 2484) {
|
||||
if (ath_hal_isgsmsku(ah))
|
||||
return mapgsm(freq, flags);
|
||||
return ((int)freq - 2407) / 5;
|
||||
}
|
||||
if (freq < 5000) {
|
||||
@ -641,10 +697,6 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
|
||||
return pCap->halMcastKeySrchSupport ? HAL_OK : HAL_ENOTSUPP;
|
||||
case HAL_CAP_TSF_ADJUST: /* hardware has beacon tsf adjust */
|
||||
return HAL_ENOTSUPP;
|
||||
case HAL_CAP_CHAN_HALFRATE:
|
||||
return pCap->halChanHalfRate ? HAL_OK : HAL_ENOTSUPP;
|
||||
case HAL_CAP_CHAN_QUARTERRATE:
|
||||
return pCap->halChanQuarterRate ? HAL_OK : HAL_ENOTSUPP;
|
||||
case HAL_CAP_RFSILENT: /* rfsilent support */
|
||||
switch (capability) {
|
||||
case 0: /* facility is supported */
|
||||
@ -789,6 +841,15 @@ ath_hal_getdiagstate(struct ath_hal *ah, int request,
|
||||
if (argsize != sizeof(uint16_t))
|
||||
return AH_FALSE;
|
||||
return ah->ah_resetKeyCacheEntry(ah, *(const uint16_t *)args);
|
||||
#ifdef AH_SUPPORT_WRITE_EEPROM
|
||||
case HAL_DIAG_EEWRITE: {
|
||||
const HAL_DIAG_EEVAL *ee;
|
||||
if (argsize != sizeof(HAL_DIAG_EEVAL))
|
||||
return AH_FALSE;
|
||||
ee = (const HAL_DIAG_EEVAL *)args;
|
||||
return ath_hal_eepromWrite(ah, ee->ee_off, ee->ee_data);
|
||||
}
|
||||
#endif /* AH_SUPPORT_WRITE_EEPROM */
|
||||
#endif /* AH_PRIVATE_DIAG */
|
||||
case HAL_DIAG_11NCOMPAT:
|
||||
if (argsize == 0) {
|
||||
|
20
ah.h
20
ah.h
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ah.h,v 1.13 2008/11/10 04:08:00 sam Exp $
|
||||
* $Id: ah.h,v 1.15 2008/11/15 03:43:50 sam Exp $
|
||||
*/
|
||||
|
||||
#ifndef _ATH_AH_H_
|
||||
@ -105,8 +105,8 @@ typedef enum {
|
||||
HAL_CAP_TSF_ADJUST = 20, /* hardware has beacon tsf adjust */
|
||||
/* 21 was HAL_CAP_XR */
|
||||
HAL_CAP_WME_TKIPMIC = 22, /* hardware can support TKIP MIC when WMM is turned on */
|
||||
HAL_CAP_CHAN_HALFRATE = 23, /* hardware can support half rate channels */
|
||||
HAL_CAP_CHAN_QUARTERRATE = 24, /* hardware can support quarter rate channels */
|
||||
/* 23 was HAL_CAP_CHAN_HALFRATE */
|
||||
/* 24 was HAL_CAP_CHAN_QUARTERRATE */
|
||||
HAL_CAP_RFSILENT = 25, /* hardware has rfsilent support */
|
||||
HAL_CAP_TPC_ACK = 26, /* ack txpower with per-packet tpc */
|
||||
HAL_CAP_TPC_CTS = 27, /* cts txpower with per-packet tpc */
|
||||
@ -466,8 +466,10 @@ enum {
|
||||
#endif
|
||||
HAL_MODE_108G = 0x020, /* 11g+Turbo channels */
|
||||
HAL_MODE_108A = 0x040, /* 11a+Turbo channels */
|
||||
HAL_MODE_11A_HALF_RATE = 0x200, /* 11A half rate channels */
|
||||
HAL_MODE_11A_QUARTER_RATE = 0x400, /* 11A quarter rate channels */
|
||||
HAL_MODE_11A_HALF_RATE = 0x200, /* 11a half width channels */
|
||||
HAL_MODE_11A_QUARTER_RATE = 0x400, /* 11a quarter width channels */
|
||||
HAL_MODE_11G_HALF_RATE = 0x800, /* 11g half width channels */
|
||||
HAL_MODE_11G_QUARTER_RATE = 0x1000, /* 11g quarter width channels */
|
||||
HAL_MODE_11NG_HT20 = 0x008000,
|
||||
HAL_MODE_11NA_HT20 = 0x010000,
|
||||
HAL_MODE_11NG_HT40PLUS = 0x020000,
|
||||
@ -654,7 +656,7 @@ struct ath_rx_status;
|
||||
struct ath_hal {
|
||||
uint32_t ah_magic; /* consistency check magic number */
|
||||
uint32_t ah_abi; /* HAL ABI version */
|
||||
#define HAL_ABI_VERSION 0x08110600 /* YYMMDDnn */
|
||||
#define HAL_ABI_VERSION 0x08111400 /* YYMMDDnn */
|
||||
uint16_t ah_devid; /* PCI device ID */
|
||||
uint16_t ah_subvendorid; /* PCI subvendor ID */
|
||||
HAL_SOFTC ah_sc; /* back pointer to driver/os state */
|
||||
@ -680,7 +682,11 @@ struct ath_hal {
|
||||
HAL_BOOL __ahdecl(*ah_phyDisable)(struct ath_hal *);
|
||||
HAL_BOOL __ahdecl(*ah_disable)(struct ath_hal *);
|
||||
void __ahdecl(*ah_setPCUConfig)(struct ath_hal *);
|
||||
HAL_BOOL __ahdecl(*ah_perCalibration)(struct ath_hal*, HAL_CHANNEL *, HAL_BOOL *);
|
||||
HAL_BOOL __ahdecl(*ah_perCalibration)(struct ath_hal*, HAL_CHANNEL *,
|
||||
HAL_BOOL *);
|
||||
HAL_BOOL __ahdecl(*ah_perCalibrationN)(struct ath_hal *, HAL_CHANNEL *,
|
||||
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
|
||||
HAL_BOOL __ahdecl(*ah_resetCalValid)(struct ath_hal *, HAL_CHANNEL *);
|
||||
HAL_BOOL __ahdecl(*ah_setTxPowerLimit)(struct ath_hal *, uint32_t);
|
||||
|
||||
/* Transmit functions */
|
||||
|
@ -167,7 +167,8 @@ enum {
|
||||
|
||||
/*
|
||||
* Definitions for the software frame/packet descriptors used by
|
||||
* the Atheros HAL. Drivers are expected to fillin the
|
||||
* the Atheros HAL. This definition obscures hardware-specific
|
||||
* details from the driver. Drivers are expected to fillin the
|
||||
* portions of a descriptor that are not opaque then use HAL calls
|
||||
* to complete the work. Status for completed frames is returned
|
||||
* in a device-independent format.
|
||||
|
@ -23,8 +23,8 @@
|
||||
#define ATHEROS_VENDOR_ID 0x168c /* Atheros PCI vendor ID */
|
||||
/*
|
||||
* NB: all Atheros-based devices should have a PCI vendor ID
|
||||
* of 0x168c, but some vendors do not follow this so we
|
||||
* must handle them specially.
|
||||
* of 0x168c, but some vendors, in their infinite wisdom
|
||||
* do not follow this so we must handle them specially.
|
||||
*/
|
||||
#define ATHEROS_3COM_VENDOR_ID 0xa727 /* 3Com 3CRPAG175 vendor ID */
|
||||
#define ATHEROS_3COM2_VENDOR_ID 0x10b7 /* 3Com 3CRDAG675 vendor ID */
|
||||
|
20
ah_eeprom.h
20
ah_eeprom.h
@ -14,11 +14,12 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ah_eeprom.h,v 1.6 2008/11/10 04:08:00 sam Exp $
|
||||
* $Id: ah_eeprom.h,v 1.11 2008/11/27 22:32:48 sam Exp $
|
||||
*/
|
||||
#ifndef _ATH_AH_EEPROM_H_
|
||||
#define _ATH_AH_EEPROM_H_
|
||||
|
||||
#define AR_EEPROM_VER1 0x1000 /* Version 1.0; 5210 only */
|
||||
/*
|
||||
* Version 3 EEPROMs are all 16K.
|
||||
* 3.1 adds turbo limit, antenna gain, 16 CTL's, 11g info,
|
||||
@ -34,15 +35,17 @@
|
||||
#define AR_EEPROM_VER3_2 0x3002 /* Version 3.2 */
|
||||
#define AR_EEPROM_VER3_3 0x3003 /* Version 3.3 */
|
||||
#define AR_EEPROM_VER3_4 0x3004 /* Version 3.4 */
|
||||
#define AR_EEPROM_VER4 0x4000 /* Version 4.x */
|
||||
#define AR_EEPROM_VER4_0 0x4000 /* Version 4.0 */
|
||||
#define AR_EEPROM_VER4_1 0x4001 /* Version 4.0 */
|
||||
#define AR_EEPROM_VER4_2 0x4002 /* Version 4.0 */
|
||||
#define AR_EEPROM_VER4_3 0x4003 /* Version 4.0 */
|
||||
#define AR_EEPROM_VER4_6 0x4006 /* Version 4.0 */
|
||||
#define AR_EEPROM_VER4_7 0x3007 /* Version 4.7 */
|
||||
#define AR_EEPROM_VER4_9 0x4009 /* EEPROM EAR futureproofing */
|
||||
#define AR_EEPROM_VER5_0 0x5000 /* Adds new 2413 cal powers and added params */
|
||||
#define AR_EEPROM_VER5_1 0x5001 /* Adds capability values */
|
||||
#define AR_EEPROM_VER4_9 0x4009 /* EEPROM EAR futureproofing */
|
||||
#define AR_EEPROM_VER5 0x5000 /* Version 5.x */
|
||||
#define AR_EEPROM_VER5_0 0x5000 /* Adds new 2413 cal powers and added params */
|
||||
#define AR_EEPROM_VER5_1 0x5001 /* Adds capability values */
|
||||
#define AR_EEPROM_VER5_3 0x5003 /* Adds spur mitigation table */
|
||||
#define AR_EEPROM_VER5_4 0x5004
|
||||
/*
|
||||
@ -50,7 +53,8 @@
|
||||
* 14.2 adds txFrameToPaOn, txFrameToDataStart, ht40PowerInc
|
||||
* 14.3 adds bswAtten, bswMargin, swSettle, and base OpFlags for HT20/40
|
||||
*/
|
||||
#define AR_EEPROM_VER14_1 0xE001 /* 11n support */
|
||||
#define AR_EEPROM_VER14 0xE000 /* Version 14.x */
|
||||
#define AR_EEPROM_VER14_1 0xE001 /* Adds 11n support */
|
||||
#define AR_EEPROM_VER14_2 0xE002
|
||||
#define AR_EEPROM_VER14_3 0xE003
|
||||
#define AR_EEPROM_VER14_7 0xE007
|
||||
@ -75,8 +79,8 @@ enum {
|
||||
AR_EEP_BURST, /* use ath_hal_eepromGetFlag */
|
||||
AR_EEP_MAXQCU, /* uint16_t* */
|
||||
AR_EEP_KCENTRIES, /* uint16_t* */
|
||||
AR_EEP_NFTHRESH_5, /* uint8_t* */
|
||||
AR_EEP_NFTHRESH_2, /* uint8_t* */
|
||||
AR_EEP_NFTHRESH_5, /* int16_t* */
|
||||
AR_EEP_NFTHRESH_2, /* int16_t* */
|
||||
AR_EEP_REGDMN_0, /* uint16_t* */
|
||||
AR_EEP_REGDMN_1, /* uint16_t* */
|
||||
AR_EEP_OPCAP, /* uint16_t* */
|
||||
@ -122,6 +126,8 @@ typedef struct {
|
||||
/* XXX exposed to chip code */
|
||||
#define MAX_RATE_POWER 63
|
||||
|
||||
HAL_STATUS ath_hal_v1EepromAttach(struct ath_hal *ah);
|
||||
HAL_STATUS ath_hal_legacyEepromAttach(struct ath_hal *ah);
|
||||
HAL_STATUS ath_hal_v14EepromAttach(struct ath_hal *ah);
|
||||
HAL_STATUS ath_hal_v4kEepromAttach(struct ath_hal *ah);
|
||||
#endif /* _ATH_AH_EEPROM_H_ */
|
||||
|
253
ah_eeprom_v1.c
Normal file
253
ah_eeprom_v1.c
Normal file
@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Sam Leffler, Errno Consulting
|
||||
* Copyright (c) 2008 Atheros Communications, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ah_eeprom_v1.c,v 1.1 2008/11/11 02:40:11 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
#include "ah.h"
|
||||
#include "ah_internal.h"
|
||||
#include "ah_eeprom_v1.h"
|
||||
|
||||
static HAL_STATUS
|
||||
v1EepromGet(struct ath_hal *ah, int param, void *val)
|
||||
{
|
||||
HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom;
|
||||
uint32_t sum;
|
||||
uint16_t eeval;
|
||||
uint8_t *macaddr;
|
||||
int i;
|
||||
|
||||
switch (param) {
|
||||
case AR_EEP_MACADDR: /* Get MAC Address */
|
||||
sum = 0;
|
||||
macaddr = val;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!ath_hal_eepromRead(ah, AR_EEPROM_MAC(i), &eeval)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: cannot read EEPROM location %u\n",
|
||||
__func__, i);
|
||||
return HAL_EEREAD;
|
||||
}
|
||||
sum += eeval;
|
||||
macaddr[2*i + 0] = eeval >> 8;
|
||||
macaddr[2*i + 1] = eeval & 0xff;
|
||||
}
|
||||
if (sum == 0 || sum == 0xffff*3) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad mac address %s\n",
|
||||
__func__, ath_hal_ether_sprintf(macaddr));
|
||||
return HAL_EEBADMAC;
|
||||
}
|
||||
return HAL_OK;
|
||||
case AR_EEP_REGDMN_0:
|
||||
*(uint16_t *) val = ee->ee_regDomain[0];
|
||||
return HAL_OK;
|
||||
case AR_EEP_RFKILL:
|
||||
HALASSERT(val == AH_NULL);
|
||||
return ee->ee_rfKill ? HAL_OK : HAL_EIO;
|
||||
case AR_EEP_WRITEPROTECT:
|
||||
HALASSERT(val == AH_NULL);
|
||||
return (ee->ee_protect & AR_EEPROM_PROTOTECT_WP_128_191) ?
|
||||
HAL_OK : HAL_EIO;
|
||||
default:
|
||||
HALASSERT(0);
|
||||
return HAL_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static HAL_BOOL
|
||||
v1EepromSet(struct ath_hal *ah, int param, int v)
|
||||
{
|
||||
return HAL_EINVAL;
|
||||
}
|
||||
|
||||
static HAL_BOOL
|
||||
v1EepromDiag(struct ath_hal *ah, int request,
|
||||
const void *args, uint32_t argsize, void **result, uint32_t *resultsize)
|
||||
{
|
||||
HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom;
|
||||
|
||||
switch (request) {
|
||||
case HAL_DIAG_EEPROM:
|
||||
*result = ee;
|
||||
*resultsize = sizeof(*ee);
|
||||
return AH_TRUE;
|
||||
}
|
||||
return AH_FALSE;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
v1EepromGetSpurChan(struct ath_hal *ah, int ix, HAL_BOOL is2GHz)
|
||||
{
|
||||
return AR_NO_SPUR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reclaim any EEPROM-related storage.
|
||||
*/
|
||||
static void
|
||||
v1EepromDetach(struct ath_hal *ah)
|
||||
{
|
||||
HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom;
|
||||
|
||||
ath_hal_free(ee);
|
||||
AH_PRIVATE(ah)->ah_eeprom = AH_NULL;
|
||||
}
|
||||
|
||||
HAL_STATUS
|
||||
ath_hal_v1EepromAttach(struct ath_hal *ah)
|
||||
{
|
||||
HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom;
|
||||
uint16_t athvals[AR_EEPROM_ATHEROS_MAX]; /* XXX off stack */
|
||||
uint16_t protect, version, eeval;
|
||||
uint32_t sum;
|
||||
int i, loc;
|
||||
|
||||
HALASSERT(ee == AH_NULL);
|
||||
|
||||
if (!ath_hal_eepromRead(ah, AR_EEPROM_MAGIC, &eeval)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: cannot read EEPROM magic number\n", __func__);
|
||||
return HAL_EEREAD;
|
||||
}
|
||||
if (eeval != 0x5aa5) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: invalid EEPROM magic number 0x%x\n", __func__, eeval);
|
||||
return HAL_EEMAGIC;
|
||||
}
|
||||
|
||||
if (!ath_hal_eepromRead(ah, AR_EEPROM_PROTECT, &protect)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: cannot read EEPROM protection bits; read locked?\n",
|
||||
__func__);
|
||||
return HAL_EEREAD;
|
||||
}
|
||||
HALDEBUG(ah, HAL_DEBUG_ATTACH, "EEPROM protect 0x%x\n", protect);
|
||||
/* XXX check proper access before continuing */
|
||||
|
||||
if (!ath_hal_eepromRead(ah, AR_EEPROM_VERSION, &version)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: unable to read EEPROM version\n", __func__);
|
||||
return HAL_EEREAD;
|
||||
}
|
||||
if (((version>>12) & 0xf) != 1) {
|
||||
/*
|
||||
* This code only groks the version 1 EEPROM layout.
|
||||
*/
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: unsupported EEPROM version 0x%x found\n",
|
||||
__func__, version);
|
||||
return HAL_EEVERSION;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the Atheros EEPROM entries and calculate the checksum.
|
||||
*/
|
||||
sum = 0;
|
||||
for (i = 0; i < AR_EEPROM_ATHEROS_MAX; i++) {
|
||||
if (!ath_hal_eepromRead(ah, AR_EEPROM_ATHEROS(i), &athvals[i]))
|
||||
return HAL_EEREAD;
|
||||
sum ^= athvals[i];
|
||||
}
|
||||
if (sum != 0xffff) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad EEPROM checksum 0x%x\n",
|
||||
__func__, sum);
|
||||
return HAL_EEBADSUM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Valid checksum, fetch the regulatory domain and save values.
|
||||
*/
|
||||
if (!ath_hal_eepromRead(ah, AR_EEPROM_REG_DOMAIN, &eeval)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: cannot read regdomain from EEPROM\n", __func__);
|
||||
return HAL_EEREAD;
|
||||
}
|
||||
|
||||
ee = ath_hal_malloc(sizeof(HAL_EEPROM_v1));
|
||||
if (ee == AH_NULL) {
|
||||
/* XXX message */
|
||||
return HAL_ENOMEM;
|
||||
}
|
||||
|
||||
ee->ee_version = version;
|
||||
ee->ee_protect = protect;
|
||||
ee->ee_antenna = athvals[2];
|
||||
ee->ee_biasCurrents = athvals[3];
|
||||
ee->ee_thresh62 = athvals[4] & 0xff;
|
||||
ee->ee_xlnaOn = (athvals[4] >> 8) & 0xff;
|
||||
ee->ee_xpaOn = athvals[5] & 0xff;
|
||||
ee->ee_xpaOff = (athvals[5] >> 8) & 0xff;
|
||||
ee->ee_regDomain[0] = (athvals[6] >> 8) & 0xff;
|
||||
ee->ee_regDomain[1] = athvals[6] & 0xff;
|
||||
ee->ee_regDomain[2] = (athvals[7] >> 8) & 0xff;
|
||||
ee->ee_regDomain[3] = athvals[7] & 0xff;
|
||||
ee->ee_rfKill = athvals[8] & 0x1;
|
||||
ee->ee_devType = (athvals[8] >> 1) & 0x7;
|
||||
|
||||
for (i = 0, loc = AR_EEPROM_ATHEROS_TP_SETTINGS; i < AR_CHANNELS_MAX; i++, loc += AR_TP_SETTINGS_SIZE) {
|
||||
struct tpcMap *chan = &ee->ee_tpc[i];
|
||||
|
||||
/* Copy pcdac and gain_f values from EEPROM */
|
||||
chan->pcdac[0] = (athvals[loc] >> 10) & 0x3F;
|
||||
chan->gainF[0] = (athvals[loc] >> 4) & 0x3F;
|
||||
chan->pcdac[1] = ((athvals[loc] << 2) & 0x3C)
|
||||
| ((athvals[loc+1] >> 14) & 0x03);
|
||||
chan->gainF[1] = (athvals[loc+1] >> 8) & 0x3F;
|
||||
chan->pcdac[2] = (athvals[loc+1] >> 2) & 0x3F;
|
||||
chan->gainF[2] = ((athvals[loc+1] << 4) & 0x30)
|
||||
| ((athvals[loc+2] >> 12) & 0x0F);
|
||||
chan->pcdac[3] = (athvals[loc+2] >> 6) & 0x3F;
|
||||
chan->gainF[3] = athvals[loc+2] & 0x3F;
|
||||
chan->pcdac[4] = (athvals[loc+3] >> 10) & 0x3F;
|
||||
chan->gainF[4] = (athvals[loc+3] >> 4) & 0x3F;
|
||||
chan->pcdac[5] = ((athvals[loc+3] << 2) & 0x3C)
|
||||
| ((athvals[loc+4] >> 14) & 0x03);
|
||||
chan->gainF[5] = (athvals[loc+4] >> 8) & 0x3F;
|
||||
chan->pcdac[6] = (athvals[loc+4] >> 2) & 0x3F;
|
||||
chan->gainF[6] = ((athvals[loc+4] << 4) & 0x30)
|
||||
| ((athvals[loc+5] >> 12) & 0x0F);
|
||||
chan->pcdac[7] = (athvals[loc+5] >> 6) & 0x3F;
|
||||
chan->gainF[7] = athvals[loc+5] & 0x3F;
|
||||
chan->pcdac[8] = (athvals[loc+6] >> 10) & 0x3F;
|
||||
chan->gainF[8] = (athvals[loc+6] >> 4) & 0x3F;
|
||||
chan->pcdac[9] = ((athvals[loc+6] << 2) & 0x3C)
|
||||
| ((athvals[loc+7] >> 14) & 0x03);
|
||||
chan->gainF[9] = (athvals[loc+7] >> 8) & 0x3F;
|
||||
chan->pcdac[10] = (athvals[loc+7] >> 2) & 0x3F;
|
||||
chan->gainF[10] = ((athvals[loc+7] << 4) & 0x30)
|
||||
| ((athvals[loc+8] >> 12) & 0x0F);
|
||||
|
||||
/* Copy Regulatory Domain and Rate Information from EEPROM */
|
||||
chan->rate36 = (athvals[loc+8] >> 6) & 0x3F;
|
||||
chan->rate48 = athvals[loc+8] & 0x3F;
|
||||
chan->rate54 = (athvals[loc+9] >> 10) & 0x3F;
|
||||
chan->regdmn[0] = (athvals[loc+9] >> 4) & 0x3F;
|
||||
chan->regdmn[1] = ((athvals[loc+9] << 2) & 0x3C)
|
||||
| ((athvals[loc+10] >> 14) & 0x03);
|
||||
chan->regdmn[2] = (athvals[loc+10] >> 8) & 0x3F;
|
||||
chan->regdmn[3] = (athvals[loc+10] >> 2) & 0x3F;
|
||||
}
|
||||
|
||||
AH_PRIVATE(ah)->ah_eeprom = ee;
|
||||
AH_PRIVATE(ah)->ah_eeversion = version;
|
||||
AH_PRIVATE(ah)->ah_eepromDetach = v1EepromDetach;
|
||||
AH_PRIVATE(ah)->ah_eepromGet = v1EepromGet;
|
||||
AH_PRIVATE(ah)->ah_eepromSet = v1EepromSet;
|
||||
AH_PRIVATE(ah)->ah_getSpurChan = v1EepromGetSpurChan;
|
||||
AH_PRIVATE(ah)->ah_eepromDiag = v1EepromDiag;
|
||||
return HAL_OK;
|
||||
}
|
99
ah_eeprom_v1.h
Normal file
99
ah_eeprom_v1.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
|
||||
* Copyright (c) 2002-2008 Atheros Communications, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ah_eeprom_v1.h,v 1.1 2008/11/11 02:40:11 sam Exp $
|
||||
*/
|
||||
#ifndef _ATH_AH_EEPROM_V1_H_
|
||||
#define _ATH_AH_EEPROM_V1_H_
|
||||
|
||||
#include "ah_eeprom.h"
|
||||
|
||||
/*
|
||||
* EEPROM defines for Version 1 Crete EEPROM.
|
||||
*
|
||||
* The EEPROM is segmented into three sections:
|
||||
*
|
||||
* PCI/Cardbus default configuration settings
|
||||
* Cardbus CIS tuples and vendor-specific data
|
||||
* Atheros-specific data
|
||||
*
|
||||
* EEPROM entries are read 32-bits at a time through the PCI bus
|
||||
* interface but are all 16-bit values.
|
||||
*
|
||||
* Access to the Atheros-specific data is controlled by protection
|
||||
* bits and the data is checksum'd. The driver reads the Atheros
|
||||
* data from the EEPROM at attach and caches it in its private state.
|
||||
* This data includes the local regulatory domain, channel calibration
|
||||
* settings, and phy-related configuration settings.
|
||||
*/
|
||||
#define AR_EEPROM_MAC(i) (0x1f-(i))/* MAC address word */
|
||||
#define AR_EEPROM_MAGIC 0x3d /* magic number */
|
||||
#define AR_EEPROM_PROTECT 0x3f /* Atheros segment protect register */
|
||||
#define AR_EEPROM_PROTOTECT_WP_128_191 0x80
|
||||
#define AR_EEPROM_REG_DOMAIN 0xbf /* Current regulatory domain register */
|
||||
#define AR_EEPROM_ATHEROS_BASE 0xc0 /* Base of Atheros-specific data */
|
||||
#define AR_EEPROM_ATHEROS_MAX 64 /* 64x2=128 bytes of EEPROM settings */
|
||||
#define AR_EEPROM_ATHEROS(n) (AR_EEPROM_ATHEROS_BASE+(n))
|
||||
#define AR_EEPROM_VERSION AR_EEPROM_ATHEROS(1)
|
||||
#define AR_EEPROM_ATHEROS_TP_SETTINGS 0x09 /* Transmit power settings */
|
||||
#define AR_REG_DOMAINS_MAX 4 /* # of Regulatory Domains */
|
||||
#define AR_CHANNELS_MAX 5 /* # of Channel calibration groups */
|
||||
#define AR_TP_SETTINGS_SIZE 11 /* # locations/Channel group */
|
||||
#define AR_TP_SCALING_ENTRIES 11 /* # entries in transmit power dBm->pcdac */
|
||||
|
||||
/*
|
||||
* NB: we store the rfsilent select+polarity data packed
|
||||
* with the encoding used in later parts so values
|
||||
* returned to applications are consistent.
|
||||
*/
|
||||
#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
|
||||
#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
|
||||
#define AR_EEPROM_RFSILENT_POLARITY 0x0002
|
||||
#define AR_EEPROM_RFSILENT_POLARITY_S 1
|
||||
|
||||
#define AR_I2DBM(x) ((uint8_t)((x * 2) + 3))
|
||||
|
||||
/*
|
||||
* Transmit power and channel calibration settings.
|
||||
*/
|
||||
struct tpcMap {
|
||||
uint8_t pcdac[AR_TP_SCALING_ENTRIES];
|
||||
uint8_t gainF[AR_TP_SCALING_ENTRIES];
|
||||
uint8_t rate36;
|
||||
uint8_t rate48;
|
||||
uint8_t rate54;
|
||||
uint8_t regdmn[AR_REG_DOMAINS_MAX];
|
||||
};
|
||||
|
||||
/*
|
||||
* Information retrieved from EEPROM.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t ee_version; /* Version field */
|
||||
uint16_t ee_protect; /* EEPROM protect field */
|
||||
uint16_t ee_antenna; /* Antenna Settings */
|
||||
uint16_t ee_biasCurrents; /* OB, DB */
|
||||
uint8_t ee_thresh62; /* thresh62 */
|
||||
uint8_t ee_xlnaOn; /* External LNA timing */
|
||||
uint8_t ee_xpaOff; /* Extern output stage timing */
|
||||
uint8_t ee_xpaOn; /* Extern output stage timing */
|
||||
uint8_t ee_rfKill; /* Single low bit signalling if RF Kill is implemented */
|
||||
uint8_t ee_devType; /* Type: PCI, miniPCI, CB */
|
||||
uint8_t ee_regDomain[AR_REG_DOMAINS_MAX];
|
||||
/* calibrated reg domains */
|
||||
struct tpcMap ee_tpc[AR_CHANNELS_MAX];
|
||||
} HAL_EEPROM_v1;
|
||||
#endif /* _ATH_AH_EEPROM_V1_H_ */
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ah_eeprom_v14.c,v 1.3 2008/11/10 04:08:00 sam Exp $
|
||||
* $Id: ah_eeprom_v14.c,v 1.4 2008/11/10 19:04:26 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -37,10 +37,10 @@ v14EepromGet(struct ath_hal *ah, int param, void *val)
|
||||
|
||||
switch (param) {
|
||||
case AR_EEP_NFTHRESH_5:
|
||||
*(int8_t *)val = pModal[0].noiseFloorThreshCh[0];
|
||||
*(int16_t *)val = pModal[0].noiseFloorThreshCh[0];
|
||||
return HAL_OK;
|
||||
case AR_EEP_NFTHRESH_2:
|
||||
*(int8_t *)val = pModal[1].noiseFloorThreshCh[0];
|
||||
*(int16_t *)val = pModal[1].noiseFloorThreshCh[0];
|
||||
return HAL_OK;
|
||||
case AR_EEP_MACADDR: /* Get MAC Address */
|
||||
sum = 0;
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ah_eeprom_v3.c,v 1.3 2008/11/10 04:08:00 sam Exp $
|
||||
* $Id: ah_eeprom_v3.c,v 1.4 2008/11/27 22:39:42 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -1765,9 +1765,8 @@ legacyEepromDetach(struct ath_hal *ah)
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Need to talk to Praveen about this, these are
|
||||
* not valid 2.4 channels, either we change these
|
||||
* or I need to change the beanie coding to accept these
|
||||
* These are not valid 2.4 channels, either we change 'em
|
||||
* or we need to change the coding to accept them.
|
||||
*/
|
||||
static const uint16_t channels11b[] = { 2412, 2447, 2484 };
|
||||
static const uint16_t channels11g[] = { 2312, 2412, 2484 };
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ah_internal.h,v 1.17 2008/11/10 04:08:00 sam Exp $
|
||||
* $Id: ah_internal.h,v 1.21 2008/11/27 22:29:27 sam Exp $
|
||||
*/
|
||||
#ifndef _ATH_AH_INTERAL_H_
|
||||
#define _ATH_AH_INTERAL_H_
|
||||
@ -66,6 +66,9 @@ typedef struct {
|
||||
|
||||
/*
|
||||
* Transmit power scale factor.
|
||||
*
|
||||
* NB: This is not public because we want to discourage the use of
|
||||
* scaling; folks should use the tx power limit interface.
|
||||
*/
|
||||
typedef enum {
|
||||
HAL_TP_SCALE_MAX = 0, /* no scaling (default) */
|
||||
@ -165,7 +168,23 @@ typedef struct {
|
||||
|
||||
/*
|
||||
* The ``private area'' follows immediately after the ``public area''
|
||||
* in the data structure returned by ath_hal_attach.
|
||||
* in the data structure returned by ath_hal_attach. Private data are
|
||||
* used by device-independent code such as the regulatory domain support.
|
||||
* In general, code within the HAL should never depend on data in the
|
||||
* public area. Instead any public data needed internally should be
|
||||
* shadowed here.
|
||||
*
|
||||
* When declaring a device-specific ath_hal data structure this structure
|
||||
* is assumed to at the front; e.g.
|
||||
*
|
||||
* struct ath_hal_5212 {
|
||||
* struct ath_hal_private ah_priv;
|
||||
* ...
|
||||
* };
|
||||
*
|
||||
* It might be better to manage the method pointers in this structure
|
||||
* using an indirect pointer to a read-only data structure but this would
|
||||
* disallow class-style method overriding.
|
||||
*/
|
||||
struct ath_hal_private {
|
||||
struct ath_hal h; /* public area */
|
||||
@ -189,6 +208,8 @@ struct ath_hal_private {
|
||||
HAL_CHANNEL *, uint32_t);
|
||||
int16_t (*ah_getNfAdjust)(struct ath_hal *,
|
||||
const HAL_CHANNEL_INTERNAL*);
|
||||
void (*ah_getNoiseFloor)(struct ath_hal *,
|
||||
int16_t nfarray[]);
|
||||
|
||||
void *ah_eeprom; /* opaque EEPROM state */
|
||||
uint16_t ah_eeversion; /* EEPROM version */
|
||||
@ -267,6 +288,8 @@ struct ath_hal_private {
|
||||
AH_PRIVATE(_ah)->ah_getChipPowerLimits(_ah, _chans, _nchan)
|
||||
#define ath_hal_getNfAdjust(_ah, _c) \
|
||||
AH_PRIVATE(_ah)->ah_getNfAdjust(_ah, _c)
|
||||
#define ath_hal_getNoiseFloor(_ah, _nfArray) \
|
||||
AH_PRIVATE(_ah)->ah_getNoiseFloor(_ah, _nfArray)
|
||||
|
||||
#define ath_hal_eepromDetach(_ah) \
|
||||
AH_PRIVATE(_ah)->ah_eepromDetach(_ah)
|
||||
|
1967
ah_regdomain.c
1967
ah_regdomain.c
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5210.h,v 1.6 2008/11/10 04:08:02 sam Exp $
|
||||
* $Id: ar5210.h,v 1.8 2008/11/11 02:40:13 sam Exp $
|
||||
*/
|
||||
#ifndef _ATH_AR5210_H_
|
||||
#define _ATH_AR5210_H_
|
||||
@ -90,67 +90,7 @@
|
||||
#define INIT_PROTO_TIME_CNTRL_TURBO ( (INIT_CARR_SENSE_EN << 26) | (INIT_EIFS_TURBO << 12) | \
|
||||
(INIT_ProgIFS_TURBO) )
|
||||
|
||||
/*
|
||||
* EEPROM defines for Version 1 Crete EEPROM.
|
||||
*
|
||||
* The EEPROM is segmented into three sections:
|
||||
*
|
||||
* PCI/Cardbus default configuration settings
|
||||
* Cardbus CIS tuples and vendor-specific data
|
||||
* Atheros-specific data
|
||||
*
|
||||
* EEPROM entries are read 32-bits at a time through the PCI bus
|
||||
* interface but are all 16-bit values.
|
||||
*
|
||||
* Access to the Atheros-specific data is controlled by protection
|
||||
* bits and the data is checksum'd. The driver reads the Atheros
|
||||
* data from the EEPROM at attach and caches it in its private state.
|
||||
* This data includes the local regulatory domain, channel calibration
|
||||
* settings, and phy-related configuration settings.
|
||||
*/
|
||||
#define AR_EEPROM_MAC(i) (0x1f-(i))/* MAC address word */
|
||||
#define AR_EEPROM_MAGIC 0x3d /* magic number */
|
||||
#define AR_EEPROM_PROTECT 0x3f /* Atheros segment protect register */
|
||||
#define AR_EEPROM_PROTOTECT_WP_128_191 0x80
|
||||
#define AR_EEPROM_REG_DOMAIN 0xbf /* Current regulatory domain register */
|
||||
#define AR_EEPROM_ATHEROS_BASE 0xc0 /* Base of Atheros-specific data */
|
||||
#define AR_EEPROM_ATHEROS_MAX 64 /* 64x2=128 bytes of EEPROM settings */
|
||||
#define AR_EEPROM_ATHEROS(n) (AR_EEPROM_ATHEROS_BASE+(n))
|
||||
#define AR_EEPROM_VERSION AR_EEPROM_ATHEROS(1)
|
||||
#define AR_EEPROM_ATHEROS_TP_SETTINGS 0x09 /* Transmit power settings */
|
||||
#define AR_REG_DOMAINS_MAX 4 /* # of Regulatory Domains */
|
||||
#define AR_CHANNELS_MAX 5 /* # of Channel calibration groups */
|
||||
#define AR_TP_SETTINGS_SIZE 11 /* # locations/Channel group */
|
||||
#define AR_TP_SCALING_ENTRIES 11 /* # entries in transmit power dBm->pcdac */
|
||||
|
||||
/*
|
||||
* NB: we store the rfsilent select+polarity data packed
|
||||
* with the encoding used in later parts so values
|
||||
* returned to applications are consistent.
|
||||
*/
|
||||
#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
|
||||
#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
|
||||
#define AR_EEPROM_RFSILENT_POLARITY 0x0002
|
||||
#define AR_EEPROM_RFSILENT_POLARITY_S 1
|
||||
|
||||
#define AR_I2DBM(x) ((uint8_t)((x * 2) + 3))
|
||||
|
||||
/*
|
||||
* Transmit power and channel calibration settings.
|
||||
*/
|
||||
struct tpcMap {
|
||||
uint8_t pcdac[AR_TP_SCALING_ENTRIES];
|
||||
uint8_t gainF[AR_TP_SCALING_ENTRIES];
|
||||
uint8_t rate36;
|
||||
uint8_t rate48;
|
||||
uint8_t rate54;
|
||||
uint8_t regdmn[AR_REG_DOMAINS_MAX];
|
||||
};
|
||||
|
||||
/* NB: this is in ah_eeprom.h which isn't used for 5210 support */
|
||||
#ifndef MAX_RATE_POWER
|
||||
#define MAX_RATE_POWER 60
|
||||
#endif
|
||||
#define AR5210_MAX_RATE_POWER 60
|
||||
|
||||
#undef HAL_NUM_TX_QUEUES /* from ah.h */
|
||||
#define HAL_NUM_TX_QUEUES 3
|
||||
@ -158,22 +98,6 @@ struct tpcMap {
|
||||
struct ath_hal_5210 {
|
||||
struct ath_hal_private ah_priv; /* base definitions */
|
||||
|
||||
/*
|
||||
* Information retrieved from EEPROM
|
||||
*/
|
||||
uint16_t ah_eeversion; /* EEPROM Version field */
|
||||
uint16_t ah_eeprotect; /* EEPROM protection settings */
|
||||
uint16_t ah_antenna; /* Antenna Settings */
|
||||
uint16_t ah_biasCurrents; /* OB, DB */
|
||||
uint8_t ah_thresh62; /* thresh62 */
|
||||
uint8_t ah_xlnaOn; /* External LNA timing */
|
||||
uint8_t ah_xpaOff; /* Extern output stage timing */
|
||||
uint8_t ah_xpaOn; /* Extern output stage timing */
|
||||
uint8_t ah_rfKill; /* Single low bit signalling if RF Kill is implemented */
|
||||
uint8_t ah_devType; /* Type: PCI, miniPCI, CB */
|
||||
uint8_t ah_regDomain[AR_REG_DOMAINS_MAX];
|
||||
/* calibrated reg domains */
|
||||
struct tpcMap ah_tpc[AR_CHANNELS_MAX];
|
||||
uint8_t ah_macaddr[IEEE80211_ADDR_LEN];
|
||||
/*
|
||||
* Runtime state.
|
||||
@ -213,6 +137,9 @@ extern HAL_BOOL ar5210PhyDisable(struct ath_hal *);
|
||||
extern HAL_BOOL ar5210Disable(struct ath_hal *);
|
||||
extern HAL_BOOL ar5210ChipReset(struct ath_hal *, HAL_CHANNEL *);
|
||||
extern HAL_BOOL ar5210PerCalibration(struct ath_hal *, HAL_CHANNEL *, HAL_BOOL *);
|
||||
extern HAL_BOOL ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
|
||||
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
|
||||
extern HAL_BOOL ar5210ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan);
|
||||
extern int16_t ar5210GetNoiseFloor(struct ath_hal *);
|
||||
extern int16_t ar5210GetNfAdjust(struct ath_hal *,
|
||||
const HAL_CHANNEL_INTERNAL *);
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5210_attach.c,v 1.7 2008/11/10 04:08:02 sam Exp $
|
||||
* $Id: ar5210_attach.c,v 1.9 2008/11/11 02:40:13 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -27,6 +27,8 @@
|
||||
#include "ar5210/ar5210reg.h"
|
||||
#include "ar5210/ar5210phy.h"
|
||||
|
||||
#include "ah_eeprom_v1.h"
|
||||
|
||||
static HAL_BOOL ar5210GetChannelEdges(struct ath_hal *,
|
||||
uint16_t flags, uint16_t *low, uint16_t *high);
|
||||
static HAL_BOOL ar5210GetChipPowerLimits(struct ath_hal *ah,
|
||||
@ -46,6 +48,8 @@ static const struct ath_hal_private ar5210hal = {{
|
||||
.ah_disable = ar5210Disable,
|
||||
.ah_setPCUConfig = ar5210SetPCUConfig,
|
||||
.ah_perCalibration = ar5210PerCalibration,
|
||||
.ah_perCalibrationN = ar5210PerCalibrationN,
|
||||
.ah_resetCalValid = ar5210ResetCalValid,
|
||||
.ah_setTxPowerLimit = ar5210SetTxPowerLimit,
|
||||
.ah_getChanNoise = ath_hal_getChanNoise,
|
||||
|
||||
@ -93,6 +97,7 @@ static const struct ath_hal_private ar5210hal = {{
|
||||
.ah_setMacAddress = ar5210SetMacAddress,
|
||||
.ah_getBssIdMask = ar5210GetBssIdMask,
|
||||
.ah_setBssIdMask = ar5210SetBssIdMask,
|
||||
.ah_setRegulatoryDomain = ar5210SetRegulatoryDomain,
|
||||
.ah_setLedState = ar5210SetLedState,
|
||||
.ah_writeAssocid = ar5210WriteAssocid,
|
||||
.ah_gpioCfgInput = ar5210GpioCfgInput,
|
||||
@ -171,10 +176,10 @@ ar5210Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HA
|
||||
#define N(a) (sizeof(a)/sizeof(a[0]))
|
||||
struct ath_hal_5210 *ahp;
|
||||
struct ath_hal *ah;
|
||||
u_int i, loc;
|
||||
uint32_t revid, pcicfg, sum;
|
||||
uint16_t athvals[AR_EEPROM_ATHEROS_MAX], eeval;
|
||||
uint32_t revid, pcicfg;
|
||||
uint16_t eeval;
|
||||
HAL_STATUS ecode;
|
||||
int i;
|
||||
|
||||
HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH,
|
||||
"%s: devid 0x%x sc %p st %p sh %p\n", __func__, devid,
|
||||
@ -199,7 +204,7 @@ ar5210Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HA
|
||||
AH_PRIVATE(ah)->ah_devid = devid;
|
||||
AH_PRIVATE(ah)->ah_subvendorid = 0; /* XXX */
|
||||
|
||||
AH_PRIVATE(ah)->ah_powerLimit = MAX_RATE_POWER;
|
||||
AH_PRIVATE(ah)->ah_powerLimit = AR5210_MAX_RATE_POWER;
|
||||
AH_PRIVATE(ah)->ah_tpScale = HAL_TP_SCALE_MAX; /* no scaling */
|
||||
|
||||
ahp->ah_powerMode = HAL_PM_UNDEFINED;
|
||||
@ -234,169 +239,40 @@ ar5210Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HA
|
||||
|
||||
/*
|
||||
* Read all the settings from the EEPROM and stash
|
||||
* ones we'll use later in our state block.
|
||||
* ones we'll use later.
|
||||
*/
|
||||
pcicfg = OS_REG_READ(ah, AR_PCICFG);
|
||||
OS_REG_WRITE(ah, AR_PCICFG, pcicfg | AR_PCICFG_EEPROMSEL);
|
||||
|
||||
if (!ar5210EepromRead(ah, AR_EEPROM_MAGIC, &eeval)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: cannot read EEPROM magic number\n", __func__);
|
||||
ecode = HAL_EEREAD;
|
||||
ecode = ath_hal_v1EepromAttach(ah);
|
||||
if (ecode != HAL_OK) {
|
||||
goto eebad;
|
||||
}
|
||||
if (eeval != 0x5aa5) {
|
||||
ecode = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, &eeval);
|
||||
if (ecode != HAL_OK) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: invalid EEPROM magic number 0x%x\n", __func__, eeval);
|
||||
ecode = HAL_EEMAGIC;
|
||||
goto eebad;
|
||||
}
|
||||
|
||||
if (!ar5210EepromRead(ah, AR_EEPROM_PROTECT, &eeval)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: cannot read EEPROM protection bits; read locked?\n",
|
||||
"%s: cannot read regulatory domain from EEPROM\n",
|
||||
__func__);
|
||||
ecode = HAL_EEREAD;
|
||||
goto eebad;
|
||||
}
|
||||
HALDEBUG(ah, HAL_DEBUG_ATTACH, "EEPROM protect 0x%x\n", eeval);
|
||||
ahp->ah_eeprotect = eeval;
|
||||
/* XXX check proper access before continuing */
|
||||
|
||||
if (!ar5210EepromRead(ah, AR_EEPROM_VERSION, &eeval)) {
|
||||
}
|
||||
AH_PRIVATE(ah)->ah_currentRD = eeval;
|
||||
ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
|
||||
if (ecode != HAL_OK) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: unable to read EEPROM version\n", __func__);
|
||||
ecode = HAL_EEREAD;
|
||||
"%s: error getting mac address from EEPROM\n", __func__);
|
||||
goto eebad;
|
||||
}
|
||||
ahp->ah_eeversion = (eeval>>12) & 0xf;
|
||||
if (ahp->ah_eeversion != 1) {
|
||||
/*
|
||||
* This driver only groks the version 1 EEPROM layout.
|
||||
*/
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: unsupported EEPROM version %u (0x%x) found\n",
|
||||
__func__, ahp->ah_eeversion, eeval);
|
||||
ecode = HAL_EEVERSION;
|
||||
goto eebad;
|
||||
}
|
||||
}
|
||||
OS_REG_WRITE(ah, AR_PCICFG, pcicfg); /* disable EEPROM access */
|
||||
|
||||
/*
|
||||
* Read the Atheros EEPROM entries and calculate the checksum.
|
||||
*/
|
||||
sum = 0;
|
||||
for (i = 0; i < AR_EEPROM_ATHEROS_MAX; i++) {
|
||||
if (!ar5210EepromRead(ah, AR_EEPROM_ATHEROS(i), &athvals[i])) {
|
||||
ecode = HAL_EEREAD;
|
||||
goto eebad;
|
||||
}
|
||||
sum ^= athvals[i];
|
||||
}
|
||||
if (sum != 0xffff) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad EEPROM checksum 0x%x\n",
|
||||
__func__, sum);
|
||||
ecode = HAL_EEBADSUM;
|
||||
goto eebad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Valid checksum, fetch the regulatory domain and save values.
|
||||
*/
|
||||
if (!ar5210EepromRead(ah, AR_EEPROM_REG_DOMAIN, &eeval)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: cannot read regdomain from EEPROM\n", __func__);
|
||||
ecode = HAL_EEREAD;
|
||||
goto eebad;
|
||||
}
|
||||
|
||||
AH_PRIVATE(ah)->ah_currentRD = eeval & 0xff;
|
||||
ahp->ah_antenna = athvals[2];
|
||||
ahp->ah_biasCurrents = athvals[3];
|
||||
ahp->ah_thresh62 = athvals[4] & 0xff;
|
||||
ahp->ah_xlnaOn = (athvals[4] >> 8) & 0xff;
|
||||
ahp->ah_xpaOn = athvals[5] & 0xff;
|
||||
ahp->ah_xpaOff = (athvals[5] >> 8) & 0xff;
|
||||
ahp->ah_regDomain[0] = (athvals[6] >> 8) & 0xff;
|
||||
ahp->ah_regDomain[1] = athvals[6] & 0xff;
|
||||
ahp->ah_regDomain[2] = (athvals[7] >> 8) & 0xff;
|
||||
ahp->ah_regDomain[3] = athvals[7] & 0xff;
|
||||
ahp->ah_rfKill = athvals[8] & 0x1;
|
||||
ahp->ah_devType = (athvals[8] >> 1) & 0x7;
|
||||
AH_PRIVATE(ah)->ah_getNfAdjust = ar5210GetNfAdjust;
|
||||
|
||||
for (i = 0, loc = AR_EEPROM_ATHEROS_TP_SETTINGS; i < AR_CHANNELS_MAX; i++, loc += AR_TP_SETTINGS_SIZE) {
|
||||
struct tpcMap *chan = &ahp->ah_tpc[i];
|
||||
|
||||
/* Copy pcdac and gain_f values from EEPROM */
|
||||
chan->pcdac[0] = (athvals[loc] >> 10) & 0x3F;
|
||||
chan->gainF[0] = (athvals[loc] >> 4) & 0x3F;
|
||||
chan->pcdac[1] = ((athvals[loc] << 2) & 0x3C)
|
||||
| ((athvals[loc+1] >> 14) & 0x03);
|
||||
chan->gainF[1] = (athvals[loc+1] >> 8) & 0x3F;
|
||||
chan->pcdac[2] = (athvals[loc+1] >> 2) & 0x3F;
|
||||
chan->gainF[2] = ((athvals[loc+1] << 4) & 0x30)
|
||||
| ((athvals[loc+2] >> 12) & 0x0F);
|
||||
chan->pcdac[3] = (athvals[loc+2] >> 6) & 0x3F;
|
||||
chan->gainF[3] = athvals[loc+2] & 0x3F;
|
||||
chan->pcdac[4] = (athvals[loc+3] >> 10) & 0x3F;
|
||||
chan->gainF[4] = (athvals[loc+3] >> 4) & 0x3F;
|
||||
chan->pcdac[5] = ((athvals[loc+3] << 2) & 0x3C)
|
||||
| ((athvals[loc+4] >> 14) & 0x03);
|
||||
chan->gainF[5] = (athvals[loc+4] >> 8) & 0x3F;
|
||||
chan->pcdac[6] = (athvals[loc+4] >> 2) & 0x3F;
|
||||
chan->gainF[6] = ((athvals[loc+4] << 4) & 0x30)
|
||||
| ((athvals[loc+5] >> 12) & 0x0F);
|
||||
chan->pcdac[7] = (athvals[loc+5] >> 6) & 0x3F;
|
||||
chan->gainF[7] = athvals[loc+5] & 0x3F;
|
||||
chan->pcdac[8] = (athvals[loc+6] >> 10) & 0x3F;
|
||||
chan->gainF[8] = (athvals[loc+6] >> 4) & 0x3F;
|
||||
chan->pcdac[9] = ((athvals[loc+6] << 2) & 0x3C)
|
||||
| ((athvals[loc+7] >> 14) & 0x03);
|
||||
chan->gainF[9] = (athvals[loc+7] >> 8) & 0x3F;
|
||||
chan->pcdac[10] = (athvals[loc+7] >> 2) & 0x3F;
|
||||
chan->gainF[10] = ((athvals[loc+7] << 4) & 0x30)
|
||||
| ((athvals[loc+8] >> 12) & 0x0F);
|
||||
|
||||
/* Copy Regulatory Domain and Rate Information from EEPROM */
|
||||
chan->rate36 = (athvals[loc+8] >> 6) & 0x3F;
|
||||
chan->rate48 = athvals[loc+8] & 0x3F;
|
||||
chan->rate54 = (athvals[loc+9] >> 10) & 0x3F;
|
||||
chan->regdmn[0] = (athvals[loc+9] >> 4) & 0x3F;
|
||||
chan->regdmn[1] = ((athvals[loc+9] << 2) & 0x3C)
|
||||
| ((athvals[loc+10] >> 14) & 0x03);
|
||||
chan->regdmn[2] = (athvals[loc+10] >> 8) & 0x3F;
|
||||
chan->regdmn[3] = (athvals[loc+10] >> 2) & 0x3F;
|
||||
}
|
||||
/*
|
||||
* Got everything we need now to setup the capabilities.
|
||||
*/
|
||||
(void) ar5210FillCapabilityInfo(ah);
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!ar5210EepromRead(ah, AR_EEPROM_MAC(i), &eeval)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: cannot read EEPROM location %u\n", __func__, i);
|
||||
ecode = HAL_EEREAD;
|
||||
goto bad;
|
||||
}
|
||||
sum += eeval;
|
||||
ahp->ah_macaddr[2*i + 0] = eeval >> 8;
|
||||
ahp->ah_macaddr[2*i + 1] = eeval & 0xff;
|
||||
}
|
||||
if (sum == 0 || sum == 0xffff*3) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: mac address read failed: %s\n",
|
||||
__func__, ath_hal_ether_sprintf(ahp->ah_macaddr));
|
||||
ecode = HAL_EEBADMAC;
|
||||
goto eebad;
|
||||
}
|
||||
|
||||
OS_REG_WRITE(ah, AR_PCICFG, pcicfg); /* disable EEPROM access */
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
|
||||
|
||||
return ah;
|
||||
|
||||
eebad:
|
||||
OS_REG_WRITE(ah, AR_PCICFG, pcicfg); /* disable EEPROM access */
|
||||
bad:
|
||||
@ -416,6 +292,7 @@ ar5210Detach(struct ath_hal *ah)
|
||||
HALASSERT(ah != AH_NULL);
|
||||
HALASSERT(ah->ah_magic == AR5210_MAGIC);
|
||||
|
||||
ath_hal_eepromDetach(ah);
|
||||
ath_hal_free(ah);
|
||||
}
|
||||
|
||||
@ -447,7 +324,7 @@ ar5210GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans
|
||||
HALDEBUG(ah, HAL_DEBUG_ATTACH,
|
||||
"%s: no min/max power for %u/0x%x\n",
|
||||
__func__, chan->channel, chan->channelFlags);
|
||||
chan->maxTxPower = MAX_RATE_POWER;
|
||||
chan->maxTxPower = AR5210_MAX_RATE_POWER;
|
||||
chan->minTxPower = 0;
|
||||
}
|
||||
return AH_TRUE;
|
||||
@ -477,7 +354,7 @@ ar5210FillCapabilityInfo(struct ath_hal *ah)
|
||||
pCap->halChanHalfRate = AH_FALSE;
|
||||
pCap->halChanQuarterRate = AH_FALSE;
|
||||
|
||||
if (AH5210(ah)->ah_rfKill) {
|
||||
if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL)) {
|
||||
/*
|
||||
* Setup initial rfsilent settings based on the EEPROM
|
||||
* contents. Pin 0, polarity 0 is fixed; record this
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5210_misc.c,v 1.4 2008/11/10 04:08:02 sam Exp $
|
||||
* $Id: ar5210_misc.c,v 1.6 2008/11/27 22:29:37 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -27,6 +27,8 @@
|
||||
#include "ar5210/ar5210reg.h"
|
||||
#include "ar5210/ar5210phy.h"
|
||||
|
||||
#include "ah_eeprom_v1.h"
|
||||
|
||||
#define AR_NUM_GPIO 6 /* 6 GPIO bits */
|
||||
#define AR_GPIOD_MASK 0x2f /* 6-bit mask */
|
||||
|
||||
@ -78,6 +80,46 @@ ar5210EepromRead(struct ath_hal *ah, u_int off, uint16_t *data)
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
||||
#ifdef AH_SUPPORT_WRITE_EEPROM
|
||||
/*
|
||||
* Write 16 bits of data to the specified EEPROM offset.
|
||||
*/
|
||||
HAL_BOOL
|
||||
ar5210EepromWrite(struct ath_hal *ah, u_int off, uint16_t data)
|
||||
{
|
||||
return AH_FALSE;
|
||||
}
|
||||
#endif /* AH_SUPPORT_WRITE_EEPROM */
|
||||
|
||||
/*
|
||||
* Attempt to change the cards operating regulatory domain to the given value
|
||||
*/
|
||||
HAL_BOOL
|
||||
ar5210SetRegulatoryDomain(struct ath_hal *ah,
|
||||
uint16_t regDomain, HAL_STATUS *status)
|
||||
{
|
||||
HAL_STATUS ecode;
|
||||
|
||||
if (AH_PRIVATE(ah)->ah_currentRD == regDomain) {
|
||||
ecode = HAL_EINVAL;
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
* Check if EEPROM is configured to allow this; must
|
||||
* be a proper version and the protection bits must
|
||||
* permit re-writing that segment of the EEPROM.
|
||||
*/
|
||||
if (ath_hal_eepromGetFlag(ah, AR_EEP_WRITEPROTECT)) {
|
||||
ecode = HAL_EEWRITE;
|
||||
goto bad;
|
||||
}
|
||||
ecode = HAL_EIO; /* disallow all writes */
|
||||
bad:
|
||||
if (status)
|
||||
*status = ecode;
|
||||
return AH_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the wireless modes (a,b,g,t) supported by hardware.
|
||||
*
|
||||
@ -302,11 +344,10 @@ ar5210GetTsf64(struct ath_hal *ah)
|
||||
* then we re-reading AR_TSF_U32 does no good as the
|
||||
* low bits will be meaningless. Likewise reading
|
||||
* L32, U32, U32, then comparing the last two reads
|
||||
* to check for rollover
|
||||
* doesn't help if preempted--so we take this approach
|
||||
* as it costs one less PCI read which can be noticeable
|
||||
* when doing things like timestamping packets in
|
||||
* monitor mode.
|
||||
* to check for rollover doesn't help if preempted--so
|
||||
* we take this approach as it costs one less PCI
|
||||
* read which can be noticeable when doing things
|
||||
* like timestamping packets in monitor mode.
|
||||
*/
|
||||
u32++;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5210_reset.c,v 1.5 2008/11/10 04:08:02 sam Exp $
|
||||
* $Id: ar5210_reset.c,v 1.8 2008/11/11 17:25:16 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -27,6 +27,8 @@
|
||||
#include "ar5210/ar5210reg.h"
|
||||
#include "ar5210/ar5210phy.h"
|
||||
|
||||
#include "ah_eeprom_v1.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t Offset;
|
||||
uint32_t Value;
|
||||
@ -73,6 +75,7 @@ ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
|
||||
#define N(a) (sizeof (a) /sizeof (a[0]))
|
||||
#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
|
||||
struct ath_hal_5210 *ahp = AH5210(ah);
|
||||
const HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom;
|
||||
HAL_CHANNEL_INTERNAL *ichan;
|
||||
HAL_STATUS ecode;
|
||||
uint32_t ledstate;
|
||||
@ -214,22 +217,22 @@ ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
|
||||
|
||||
OS_REG_WRITE(ah, AR_PHY(10),
|
||||
(OS_REG_READ(ah, AR_PHY(10)) & 0xFFFF00FF) |
|
||||
(ahp->ah_xlnaOn << 8));
|
||||
(ee->ee_xlnaOn << 8));
|
||||
OS_REG_WRITE(ah, AR_PHY(13),
|
||||
(ahp->ah_xpaOff << 24) | (ahp->ah_xpaOff << 16) |
|
||||
(ahp->ah_xpaOn << 8) | ahp->ah_xpaOn);
|
||||
(ee->ee_xpaOff << 24) | (ee->ee_xpaOff << 16) |
|
||||
(ee->ee_xpaOn << 8) | ee->ee_xpaOn);
|
||||
OS_REG_WRITE(ah, AR_PHY(17),
|
||||
(OS_REG_READ(ah, AR_PHY(17)) & 0xFFFFC07F) |
|
||||
((ahp->ah_antenna >> 1) & 0x3F80));
|
||||
((ee->ee_antenna >> 1) & 0x3F80));
|
||||
OS_REG_WRITE(ah, AR_PHY(18),
|
||||
(OS_REG_READ(ah, AR_PHY(18)) & 0xFFFC0FFF) |
|
||||
((ahp->ah_antenna << 10) & 0x3F000));
|
||||
((ee->ee_antenna << 10) & 0x3F000));
|
||||
OS_REG_WRITE(ah, AR_PHY(25),
|
||||
(OS_REG_READ(ah, AR_PHY(25)) & 0xFFF80FFF) |
|
||||
((ahp->ah_thresh62 << 12) & 0x7F000));
|
||||
((ee->ee_thresh62 << 12) & 0x7F000));
|
||||
OS_REG_WRITE(ah, AR_PHY(68),
|
||||
(OS_REG_READ(ah, AR_PHY(68)) & 0xFFFFFFFC) |
|
||||
(ahp->ah_antenna & 0x3));
|
||||
(ee->ee_antenna & 0x3));
|
||||
|
||||
if (!ar5210SetChannel(ah, ichan)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set channel\n",
|
||||
@ -443,7 +446,8 @@ enum {
|
||||
* changes.
|
||||
*/
|
||||
HAL_BOOL
|
||||
ar5210PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
|
||||
HAL_BOOL longCal, HAL_BOOL *isCalDone)
|
||||
{
|
||||
uint32_t regBeacon;
|
||||
uint32_t reg9858, reg985c, reg9868;
|
||||
@ -559,11 +563,23 @@ ar5210PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
/* Re-enable Beacons */
|
||||
OS_REG_WRITE(ah, AR_BEACON, regBeacon);
|
||||
|
||||
*isIQdone = AH_TRUE;
|
||||
*isCalDone = AH_TRUE;
|
||||
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
||||
HAL_BOOL
|
||||
ar5210PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
{
|
||||
return ar5210PerCalibrationN(ah, chan, 0x1, AH_TRUE, isIQdone);
|
||||
}
|
||||
|
||||
HAL_BOOL
|
||||
ar5210ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
{
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes the given reset bit mask into the reset register
|
||||
*/
|
||||
@ -600,7 +616,7 @@ ar5210SetResetReg(struct ath_hal *ah, uint32_t resetMask, u_int delay)
|
||||
* Returns: the pcdac value
|
||||
*/
|
||||
static uint8_t
|
||||
getPcdac(struct ath_hal *ah, struct tpcMap *pRD, uint8_t dBm)
|
||||
getPcdac(struct ath_hal *ah, const struct tpcMap *pRD, uint8_t dBm)
|
||||
{
|
||||
int32_t i;
|
||||
int useNextEntry = AH_FALSE;
|
||||
@ -643,7 +659,8 @@ getPcdac(struct ath_hal *ah, struct tpcMap *pRD, uint8_t dBm)
|
||||
* Find or interpolates the gainF value from the table ptr.
|
||||
*/
|
||||
static uint8_t
|
||||
getGainF(struct ath_hal *ah, struct tpcMap *pRD, uint8_t pcdac, uint8_t *dBm)
|
||||
getGainF(struct ath_hal *ah, const struct tpcMap *pRD,
|
||||
uint8_t pcdac, uint8_t *dBm)
|
||||
{
|
||||
uint32_t interp;
|
||||
int low, high, i;
|
||||
@ -705,7 +722,7 @@ getGainF(struct ath_hal *ah, struct tpcMap *pRD, uint8_t pcdac, uint8_t *dBm)
|
||||
HAL_BOOL
|
||||
ar5210SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
|
||||
{
|
||||
AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER);
|
||||
AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, AR5210_MAX_RATE_POWER);
|
||||
/* XXX flush to h/w */
|
||||
return AH_TRUE;
|
||||
}
|
||||
@ -716,15 +733,15 @@ ar5210SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
|
||||
static HAL_BOOL
|
||||
setupPowerSettings(struct ath_hal *ah, HAL_CHANNEL *chan, uint8_t cp[17])
|
||||
{
|
||||
struct ath_hal_5210 *ahp = AH5210(ah);
|
||||
const HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom;
|
||||
uint8_t gainFRD, gainF36, gainF48, gainF54;
|
||||
uint8_t dBmRD, dBm36, dBm48, dBm54, dontcare;
|
||||
uint32_t rd, group;
|
||||
struct tpcMap *pRD;
|
||||
const struct tpcMap *pRD;
|
||||
|
||||
/* Set OB/DB Values regardless of channel */
|
||||
cp[15] = (ahp->ah_biasCurrents >> 4) & 0x7;
|
||||
cp[16] = ahp->ah_biasCurrents & 0x7;
|
||||
cp[15] = (ee->ee_biasCurrents >> 4) & 0x7;
|
||||
cp[16] = ee->ee_biasCurrents & 0x7;
|
||||
|
||||
if (chan->channel < 5170 || chan->channel > 5320) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u\n",
|
||||
@ -732,11 +749,12 @@ setupPowerSettings(struct ath_hal *ah, HAL_CHANNEL *chan, uint8_t cp[17])
|
||||
return AH_FALSE;
|
||||
}
|
||||
|
||||
HALASSERT(ahp->ah_eeversion == 1);
|
||||
HALASSERT(ee->ee_version >= AR_EEPROM_VER1 &&
|
||||
ee->ee_version < AR_EEPROM_VER3);
|
||||
|
||||
/* Match regulatory domain */
|
||||
for (rd = 0; rd < AR_REG_DOMAINS_MAX; rd++)
|
||||
if (AH_PRIVATE(ah)->ah_currentRD == ahp->ah_regDomain[rd])
|
||||
if (AH_PRIVATE(ah)->ah_currentRD == ee->ee_regDomain[rd])
|
||||
break;
|
||||
if (rd == AR_REG_DOMAINS_MAX) {
|
||||
#ifdef AH_DEBUG
|
||||
@ -756,7 +774,7 @@ setupPowerSettings(struct ath_hal *ah, HAL_CHANNEL *chan, uint8_t cp[17])
|
||||
|
||||
/* Integer divide will set group from 0 to 4 */
|
||||
group = group / 3;
|
||||
pRD = &ahp->ah_tpc[group];
|
||||
pRD = &ee->ee_tpc[group];
|
||||
|
||||
/* Set PC DAC Values */
|
||||
cp[14] = pRD->regdmn[rd];
|
||||
@ -773,7 +791,7 @@ setupPowerSettings(struct ath_hal *ah, HAL_CHANNEL *chan, uint8_t cp[17])
|
||||
/* Power Scale if requested */
|
||||
if (AH_PRIVATE(ah)->ah_tpScale != HAL_TP_SCALE_MAX) {
|
||||
static const uint16_t tpcScaleReductionTable[5] =
|
||||
{ 0, 3, 6, 9, MAX_RATE_POWER };
|
||||
{ 0, 3, 6, 9, AR5210_MAX_RATE_POWER };
|
||||
uint16_t tpScale;
|
||||
|
||||
tpScale = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale];
|
||||
@ -860,7 +878,7 @@ ar5210SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
for (i = 7; i < 15; i++)
|
||||
cp[i] = ath_hal_reverseBits(cp[i], 6);
|
||||
|
||||
/* merge transmit power values into the register */
|
||||
/* merge transmit power values into the register - quite gross */
|
||||
pwr_regs[0] |= ((cp[1] << 5) & 0xE0) | (cp[0] & 0x1F);
|
||||
pwr_regs[1] |= ((cp[3] << 7) & 0x80) | ((cp[2] << 2) & 0x7C) |
|
||||
((cp[1] >> 3) & 0x03);
|
||||
|
@ -68,7 +68,7 @@ struct ar5210_desc {
|
||||
/* TX ds_ctl1 */
|
||||
#define AR_BufLen 0x00000fff /* data buffer length */
|
||||
#define AR_More 0x00001000 /* more desc in this frame */
|
||||
#define AR_EncryptKeyIdx 0x0007e000 /* encrypt key table index */
|
||||
#define AR_EncryptKeyIdx 0x0007e000 /* ecnrypt key table index */
|
||||
#define AR_EncryptKeyIdx_S 13
|
||||
#define AR_RTSDuration 0xfff80000 /* lower 13bit of duration */
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5211.h,v 1.7 2008/11/10 04:08:02 sam Exp $
|
||||
* $Id: ar5211.h,v 1.8 2008/11/10 22:08:47 sam Exp $
|
||||
*/
|
||||
#ifndef _ATH_AR5211_H_
|
||||
#define _ATH_AR5211_H_
|
||||
@ -155,6 +155,9 @@ extern HAL_BOOL ar5211PhyDisable(struct ath_hal *);
|
||||
extern HAL_BOOL ar5211Disable(struct ath_hal *);
|
||||
extern HAL_BOOL ar5211ChipReset(struct ath_hal *, uint16_t);
|
||||
extern HAL_BOOL ar5211PerCalibration(struct ath_hal *, HAL_CHANNEL *, HAL_BOOL *);
|
||||
extern HAL_BOOL ar5211PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
|
||||
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
|
||||
extern HAL_BOOL ar5211ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan);
|
||||
extern HAL_BOOL ar5211SetTxPowerLimit(struct ath_hal *, uint32_t limit);
|
||||
extern HAL_BOOL ar5211SetTransmitPower(struct ath_hal *, HAL_CHANNEL *);
|
||||
extern HAL_BOOL ar5211CalNoiseFloor(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
|
||||
@ -224,6 +227,9 @@ extern HAL_BOOL ar5211SetMacAddress(struct ath_hal *ah, const uint8_t *);
|
||||
extern void ar5211GetBssIdMask(struct ath_hal *, uint8_t *);
|
||||
extern HAL_BOOL ar5211SetBssIdMask(struct ath_hal *, const uint8_t *);
|
||||
extern HAL_BOOL ar5211EepromRead(struct ath_hal *, u_int off, uint16_t *data);
|
||||
extern HAL_BOOL ar5211EepromWrite(struct ath_hal *, u_int off, uint16_t data);
|
||||
extern HAL_BOOL ar5211SetRegulatoryDomain(struct ath_hal *,
|
||||
uint16_t, HAL_STATUS *);
|
||||
extern u_int ar5211GetWirelessModes(struct ath_hal *);
|
||||
extern void ar5211EnableRfKill(struct ath_hal *);
|
||||
extern uint32_t ar5211GpioGet(struct ath_hal *, uint32_t gpio);
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5211_attach.c,v 1.8 2008/11/10 04:08:02 sam Exp $
|
||||
* $Id: ar5211_attach.c,v 1.11 2008/11/27 22:29:52 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -49,6 +49,8 @@ static const struct ath_hal_private ar5211hal = {{
|
||||
.ah_disable = ar5211Disable,
|
||||
.ah_setPCUConfig = ar5211SetPCUConfig,
|
||||
.ah_perCalibration = ar5211PerCalibration,
|
||||
.ah_perCalibrationN = ar5211PerCalibrationN,
|
||||
.ah_resetCalValid = ar5211ResetCalValid,
|
||||
.ah_setTxPowerLimit = ar5211SetTxPowerLimit,
|
||||
.ah_getChanNoise = ath_hal_getChanNoise,
|
||||
|
||||
@ -96,6 +98,7 @@ static const struct ath_hal_private ar5211hal = {{
|
||||
.ah_setMacAddress = ar5211SetMacAddress,
|
||||
.ah_getBssIdMask = ar5211GetBssIdMask,
|
||||
.ah_setBssIdMask = ar5211SetBssIdMask,
|
||||
.ah_setRegulatoryDomain = ar5211SetRegulatoryDomain,
|
||||
.ah_setLedState = ar5211SetLedState,
|
||||
.ah_writeAssocid = ar5211WriteAssocid,
|
||||
.ah_gpioCfgInput = ar5211GpioCfgInput,
|
||||
@ -329,7 +332,7 @@ ar5211Attach(uint16_t devid, HAL_SOFTC sc,
|
||||
}
|
||||
AH_PRIVATE(ah)->ah_currentRD = eeval;
|
||||
AH_PRIVATE(ah)->ah_getNfAdjust = ar5211GetNfAdjust;
|
||||
|
||||
|
||||
/*
|
||||
* Got everything we need now to setup the capabilities.
|
||||
*/
|
||||
@ -459,9 +462,6 @@ ar5211FillCapabilityInfo(struct ath_hal *ah)
|
||||
struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
|
||||
HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;
|
||||
|
||||
if (AH_PRIVATE(ah)->ah_currentRD == 1)
|
||||
return AH_FALSE;
|
||||
|
||||
/* Construct wireless mode from EEPROM */
|
||||
pCap->halWirelessModes = 0;
|
||||
if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) {
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5211_interrupts.c,v 1.5 2008/11/10 04:08:02 sam Exp $
|
||||
* $Id: ar5211_interrupts.c,v 1.6 2008/11/27 22:29:52 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -67,7 +67,9 @@ ar5211GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked)
|
||||
if (isr & (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR | AR_ISR_TXEOL))
|
||||
*masked |= HAL_INT_TX;
|
||||
/*
|
||||
* RXORN can hang the receive path so we force a hardware
|
||||
* Receive overrun is usually non-fatal on Oahu/Spirit.
|
||||
* BUT on some parts rx could fail and the chip must be reset.
|
||||
* So we force a hardware reset in all cases.
|
||||
*/
|
||||
if ((isr & AR_ISR_RXORN) && AH_PRIVATE(ah)->ah_rxornIsFatal) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5211_misc.c,v 1.6 2008/11/10 04:08:02 sam Exp $
|
||||
* $Id: ar5211_misc.c,v 1.7 2008/11/27 22:29:52 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -83,6 +83,55 @@ ar5211EepromRead(struct ath_hal *ah, u_int off, uint16_t *data)
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
||||
#ifdef AH_SUPPORT_WRITE_EEPROM
|
||||
/*
|
||||
* Write 16 bits of data to the specified EEPROM offset.
|
||||
*/
|
||||
HAL_BOOL
|
||||
ar5211EepromWrite(struct ath_hal *ah, u_int off, uint16_t data)
|
||||
{
|
||||
return AH_FALSE;
|
||||
}
|
||||
#endif /* AH_SUPPORT_WRITE_EEPROM */
|
||||
|
||||
/*
|
||||
* Attempt to change the cards operating regulatory domain to the given value
|
||||
*/
|
||||
HAL_BOOL
|
||||
ar5211SetRegulatoryDomain(struct ath_hal *ah,
|
||||
uint16_t regDomain, HAL_STATUS *status)
|
||||
{
|
||||
HAL_STATUS ecode;
|
||||
|
||||
if (AH_PRIVATE(ah)->ah_currentRD == regDomain) {
|
||||
ecode = HAL_EINVAL;
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
* Check if EEPROM is configured to allow this; must
|
||||
* be a proper version and the protection bits must
|
||||
* permit re-writing that segment of the EEPROM.
|
||||
*/
|
||||
if (ath_hal_eepromGetFlag(ah, AR_EEP_WRITEPROTECT)) {
|
||||
ecode = HAL_EEWRITE;
|
||||
goto bad;
|
||||
}
|
||||
#ifdef AH_SUPPORT_WRITE_REGDOMAIN
|
||||
if (ar5211EepromWrite(ah, AR_EEPROM_REG_DOMAIN, regDomain)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: set regulatory domain to %u (0x%x)\n",
|
||||
__func__, regDomain, regDomain);
|
||||
AH_PRIVATE(ah)->ah_currentRD = regDomain;
|
||||
return AH_TRUE;
|
||||
}
|
||||
#endif
|
||||
ecode = HAL_EIO;
|
||||
bad:
|
||||
if (status)
|
||||
*status = ecode;
|
||||
return AH_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the wireless modes (a,b,g,t) supported by hardware.
|
||||
*
|
||||
@ -292,11 +341,10 @@ ar5211GetTsf64(struct ath_hal *ah)
|
||||
* then we re-reading AR_TSF_U32 does no good as the
|
||||
* low bits will be meaningless. Likewise reading
|
||||
* L32, U32, U32, then comparing the last two reads
|
||||
* to check for rollover
|
||||
* doesn't help if preempted--so we take this approach
|
||||
* as it costs one less PCI read which can be noticeable
|
||||
* when doing things like timestamping packets in
|
||||
* monitor mode.
|
||||
* to check for rollover doesn't help if preempted--so
|
||||
* we take this approach as it costs one less PCI
|
||||
* read which can be noticeable when doing things
|
||||
* like timestamping packets in monitor mode.
|
||||
*/
|
||||
u32++;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5211_reset.c,v 1.6 2008/11/10 04:08:03 sam Exp $
|
||||
* $Id: ar5211_reset.c,v 1.9 2008/11/27 22:29:52 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -222,7 +222,7 @@ uint32_t softLedCfg, softLedState;
|
||||
* not accurate enough (e.g. 1 ms resolution).
|
||||
* 2. It would still not be accurate.
|
||||
*
|
||||
* The most important aspect of this solution,
|
||||
* The most important aspect of this workaround,
|
||||
* is that, after reset, the TSF is behind
|
||||
* other STAs TSFs. This will allow the STA to
|
||||
* properly resynchronize its TSF in adhoc mode.
|
||||
@ -408,7 +408,7 @@ uint32_t softLedCfg, softLedState;
|
||||
/*
|
||||
* for pre-Production Oahu only.
|
||||
* Disable clock gating in all DMA blocks. Helps when using
|
||||
* 11B and AES. This will result in higher power consumption.
|
||||
* 11B and AES but results in higher power consumption.
|
||||
*/
|
||||
if (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_OAHU &&
|
||||
AH_PRIVATE(ah)->ah_macRev < AR_SREV_OAHU_PROD) {
|
||||
@ -665,7 +665,8 @@ ar5211ChipReset(struct ath_hal *ah, uint16_t channelFlags)
|
||||
* changes.
|
||||
*/
|
||||
HAL_BOOL
|
||||
ar5211PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
ar5211PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
|
||||
HAL_BOOL longCal, HAL_BOOL *isCalDone)
|
||||
{
|
||||
struct ath_hal_5211 *ahp = AH5211(ah);
|
||||
HAL_CHANNEL_INTERNAL *ichan;
|
||||
@ -729,31 +730,44 @@ ar5211PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4, data);
|
||||
}
|
||||
}
|
||||
*isCalDone = !ahp->ah_bIQCalibration;
|
||||
|
||||
/* Perform noise floor and set status */
|
||||
if (!ar5211IsNfGood(ah, ichan)) {
|
||||
/* report up and clear internal state */
|
||||
chan->channelFlags |= CHANNEL_CW_INT;
|
||||
ichan->channelFlags &= ~CHANNEL_CW_INT;
|
||||
return AH_FALSE;
|
||||
}
|
||||
if (!ar5211CalNoiseFloor(ah, ichan)) {
|
||||
/*
|
||||
* Delay 5ms before retrying the noise floor
|
||||
* just to make sure, as we are in an error
|
||||
* condition here.
|
||||
*/
|
||||
OS_DELAY(5000);
|
||||
if (!ar5211CalNoiseFloor(ah, ichan)) {
|
||||
if (!IS_CHAN_CCK(chan))
|
||||
chan->channelFlags |= CHANNEL_CW_INT;
|
||||
if (longCal) {
|
||||
/* Perform noise floor and set status */
|
||||
if (!ar5211IsNfGood(ah, ichan)) {
|
||||
/* report up and clear internal state */
|
||||
chan->channelFlags |= CHANNEL_CW_INT;
|
||||
ichan->channelFlags &= ~CHANNEL_CW_INT;
|
||||
return AH_FALSE;
|
||||
}
|
||||
if (!ar5211CalNoiseFloor(ah, ichan)) {
|
||||
/*
|
||||
* Delay 5ms before retrying the noise floor
|
||||
* just to make sure, as we are in an error
|
||||
* condition here.
|
||||
*/
|
||||
OS_DELAY(5000);
|
||||
if (!ar5211CalNoiseFloor(ah, ichan)) {
|
||||
if (!IS_CHAN_CCK(chan))
|
||||
chan->channelFlags |= CHANNEL_CW_INT;
|
||||
return AH_FALSE;
|
||||
}
|
||||
}
|
||||
ar5211RequestRfgain(ah);
|
||||
}
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
||||
ar5211RequestRfgain(ah);
|
||||
*isIQdone = !ahp->ah_bIQCalibration;
|
||||
HAL_BOOL
|
||||
ar5211PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
{
|
||||
return ar5211PerCalibrationN(ah, chan, 0x1, AH_TRUE, isIQdone);
|
||||
}
|
||||
|
||||
HAL_BOOL
|
||||
ar5211ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
{
|
||||
/* XXX */
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
||||
|
@ -364,7 +364,7 @@ ar5211ResetTxQueue(struct ath_hal *ah, u_int q)
|
||||
|
||||
#ifndef AH_DISABLE_WME
|
||||
/*
|
||||
* This is a really not the right way to do it, but
|
||||
* Yes, this is a hack and not the right way to do it, but
|
||||
* it does get the lockout bits and backoff set for the
|
||||
* high-pri WME queues for testing. We need to either extend
|
||||
* the meaning of queueInfo->mode, or create something like
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar2316.c,v 1.8 2008/11/10 04:08:03 sam Exp $
|
||||
* $Id: ar2316.c,v 1.9 2008/11/15 22:15:46 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -519,8 +519,11 @@ ar2316SetPowerTable(struct ath_hal *ah,
|
||||
int16_t minCalPower2316_t2;
|
||||
uint16_t *pdadcValues = ahp->ah_pcdacTable;
|
||||
uint16_t gainBoundaries[4];
|
||||
uint32_t i, reg32, regoffset, tpcrg1;
|
||||
int numPdGainsUsed;
|
||||
uint32_t reg32, regoffset;
|
||||
int i, numPdGainsUsed;
|
||||
#ifndef AH_USE_INIPDGAIN
|
||||
uint32_t tpcrg1;
|
||||
#endif
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan 0x%x flag 0x%x\n",
|
||||
__func__, chan->channel,chan->channelFlags);
|
||||
@ -542,10 +545,16 @@ ar2316SetPowerTable(struct ath_hal *ah,
|
||||
&minCalPower2316_t2,gainBoundaries, rfXpdGain, pdadcValues);
|
||||
HALASSERT(1 <= numPdGainsUsed && numPdGainsUsed <= 3);
|
||||
|
||||
#if 0
|
||||
#ifdef AH_USE_INIPDGAIN
|
||||
/*
|
||||
* Use pd_gains curve from eeprom; Atheros always uses
|
||||
* the default curve from the ini file but some vendors
|
||||
* (e.g. Zcomax) want to override this curve and not
|
||||
* honoring their settings results in tx power 5dBm low.
|
||||
*/
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
|
||||
(pRawDataset->pDataPerChannel[0].numPdGains - 1));
|
||||
#endif
|
||||
#else
|
||||
tpcrg1 = OS_REG_READ(ah, AR_PHY_TPCRG1);
|
||||
tpcrg1 = (tpcrg1 &~ AR_PHY_TPCRG1_NUM_PD_GAIN)
|
||||
| SM(numPdGainsUsed-1, AR_PHY_TPCRG1_NUM_PD_GAIN);
|
||||
@ -570,6 +579,7 @@ ar2316SetPowerTable(struct ath_hal *ah,
|
||||
__func__, OS_REG_READ(ah, AR_PHY_TPCRG1), tpcrg1);
|
||||
#endif
|
||||
OS_REG_WRITE(ah, AR_PHY_TPCRG1, tpcrg1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note the pdadc table may not start at 0 dBm power, could be
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar2317.c,v 1.7 2008/11/10 04:08:03 sam Exp $
|
||||
* $Id: ar2317.c,v 1.8 2008/11/15 22:15:46 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -496,8 +496,11 @@ ar2317SetPowerTable(struct ath_hal *ah,
|
||||
int16_t minCalPower2317_t2;
|
||||
uint16_t *pdadcValues = ahp->ah_pcdacTable;
|
||||
uint16_t gainBoundaries[4];
|
||||
uint32_t i, reg32, regoffset, tpcrg1;
|
||||
int numPdGainsUsed;
|
||||
uint32_t reg32, regoffset;
|
||||
int i, numPdGainsUsed;
|
||||
#ifndef AH_USE_INIPDGAIN
|
||||
uint32_t tpcrg1;
|
||||
#endif
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan 0x%x flag 0x%x\n",
|
||||
__func__, chan->channel,chan->channelFlags);
|
||||
@ -519,16 +522,16 @@ ar2317SetPowerTable(struct ath_hal *ah,
|
||||
&minCalPower2317_t2,gainBoundaries, rfXpdGain, pdadcValues);
|
||||
HALASSERT(1 <= numPdGainsUsed && numPdGainsUsed <= 3);
|
||||
|
||||
#ifdef AH_USE_INIPDGAIN
|
||||
/*
|
||||
* Use pd_gains curve from eeprom; Atheros always uses
|
||||
* the default curve from the ini file but some vendors
|
||||
* (e.g. Zcomax) want to override this curve and not
|
||||
* honoring their settings results in tx power 5dBm low.
|
||||
*/
|
||||
#if 0
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
|
||||
(pRawDataset->pDataPerChannel[0].numPdGains - 1));
|
||||
#endif
|
||||
#else
|
||||
tpcrg1 = OS_REG_READ(ah, AR_PHY_TPCRG1);
|
||||
tpcrg1 = (tpcrg1 &~ AR_PHY_TPCRG1_NUM_PD_GAIN)
|
||||
| SM(numPdGainsUsed-1, AR_PHY_TPCRG1_NUM_PD_GAIN);
|
||||
@ -553,6 +556,7 @@ ar2317SetPowerTable(struct ath_hal *ah,
|
||||
__func__, OS_REG_READ(ah, AR_PHY_TPCRG1), tpcrg1);
|
||||
#endif
|
||||
OS_REG_WRITE(ah, AR_PHY_TPCRG1, tpcrg1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note the pdadc table may not start at 0 dBm power, could be
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar2413.c,v 1.7 2008/11/10 04:08:03 sam Exp $
|
||||
* $Id: ar2413.c,v 1.8 2008/11/15 22:15:46 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -513,8 +513,11 @@ ar2413SetPowerTable(struct ath_hal *ah,
|
||||
int16_t minCalPower2413_t2;
|
||||
uint16_t *pdadcValues = ahp->ah_pcdacTable;
|
||||
uint16_t gainBoundaries[4];
|
||||
uint32_t i, reg32, regoffset, tpcrg1;
|
||||
int numPdGainsUsed;
|
||||
uint32_t reg32, regoffset;
|
||||
int i, numPdGainsUsed;
|
||||
#ifndef AH_USE_INIPDGAIN
|
||||
uint32_t tpcrg1;
|
||||
#endif
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan 0x%x flag 0x%x\n",
|
||||
__func__, chan->channel,chan->channelFlags);
|
||||
@ -536,10 +539,16 @@ ar2413SetPowerTable(struct ath_hal *ah,
|
||||
&minCalPower2413_t2,gainBoundaries, rfXpdGain, pdadcValues);
|
||||
HALASSERT(1 <= numPdGainsUsed && numPdGainsUsed <= 3);
|
||||
|
||||
#if 0
|
||||
#ifdef AH_USE_INIPDGAIN
|
||||
/*
|
||||
* Use pd_gains curve from eeprom; Atheros always uses
|
||||
* the default curve from the ini file but some vendors
|
||||
* (e.g. Zcomax) want to override this curve and not
|
||||
* honoring their settings results in tx power 5dBm low.
|
||||
*/
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
|
||||
(pRawDataset->pDataPerChannel[0].numPdGains - 1));
|
||||
#endif
|
||||
#else
|
||||
tpcrg1 = OS_REG_READ(ah, AR_PHY_TPCRG1);
|
||||
tpcrg1 = (tpcrg1 &~ AR_PHY_TPCRG1_NUM_PD_GAIN)
|
||||
| SM(numPdGainsUsed-1, AR_PHY_TPCRG1_NUM_PD_GAIN);
|
||||
@ -564,6 +573,7 @@ ar2413SetPowerTable(struct ath_hal *ah,
|
||||
__func__, OS_REG_READ(ah, AR_PHY_TPCRG1), tpcrg1);
|
||||
#endif
|
||||
OS_REG_WRITE(ah, AR_PHY_TPCRG1, tpcrg1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note the pdadc table may not start at 0 dBm power, could be
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar2425.c,v 1.7 2008/11/10 04:08:03 sam Exp $
|
||||
* $Id: ar2425.c,v 1.8 2008/11/16 21:33:05 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -160,12 +160,10 @@ ar2425SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
|
||||
for (i = 0; i < N(ar5212Bank##_ix##_2425); i++) \
|
||||
(_priv)->Bank##_ix##Data[i] = ar5212Bank##_ix##_2425[i][_col];\
|
||||
} while (0)
|
||||
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
#if 0
|
||||
uint16_t ob2GHz = 0, db2GHz = 0;
|
||||
#endif
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
|
||||
struct ar2425State *priv = AR2425(ah);
|
||||
uint16_t ob2GHz = 0, db2GHz = 0;
|
||||
int regWrites = 0;
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM,
|
||||
@ -173,24 +171,24 @@ ar2425SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
|
||||
__func__, chan->channel, chan->channelFlags, modesIndex);
|
||||
|
||||
HALASSERT(priv);
|
||||
#if 0
|
||||
|
||||
/* Setup rf parameters */
|
||||
switch (chan->channelFlags & CHANNEL_ALL) {
|
||||
case CHANNEL_B:
|
||||
ob2GHz = ahp->ah_obFor24;
|
||||
db2GHz = ahp->ah_dbFor24;
|
||||
break;
|
||||
case CHANNEL_G:
|
||||
case CHANNEL_108G:
|
||||
ob2GHz = ahp->ah_obFor24g;
|
||||
db2GHz = ahp->ah_dbFor24g;
|
||||
break;
|
||||
default:
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
|
||||
__func__, chan->channelFlags);
|
||||
return AH_FALSE;
|
||||
}
|
||||
#endif
|
||||
switch (chan->channelFlags & CHANNEL_ALL) {
|
||||
case CHANNEL_B:
|
||||
ob2GHz = ee->ee_obFor24;
|
||||
db2GHz = ee->ee_dbFor24;
|
||||
break;
|
||||
case CHANNEL_G:
|
||||
case CHANNEL_108G:
|
||||
ob2GHz = ee->ee_obFor24g;
|
||||
db2GHz = ee->ee_dbFor24g;
|
||||
break;
|
||||
default:
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
|
||||
__func__, chan->channelFlags);
|
||||
return AH_FALSE;
|
||||
}
|
||||
|
||||
/* Bank 1 Write */
|
||||
RF_BANK_SETUP(priv, 1, 1);
|
||||
|
||||
@ -202,10 +200,10 @@ ar2425SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
|
||||
|
||||
/* Bank 6 Write */
|
||||
RF_BANK_SETUP(priv, 6, modesIndex);
|
||||
#if 0
|
||||
|
||||
ar5212ModifyRfBuffer(priv->Bank6Data, ob2GHz, 3, 193, 0);
|
||||
ar5212ModifyRfBuffer(priv->Bank6Data, db2GHz, 3, 190, 0);
|
||||
#endif
|
||||
|
||||
/* Bank 7 Setup */
|
||||
RF_BANK_SETUP(priv, 7, modesIndex);
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5212.h,v 1.9 2008/11/10 04:08:03 sam Exp $
|
||||
* $Id: ar5212.h,v 1.16 2008/11/22 07:42:00 sam Exp $
|
||||
*/
|
||||
#ifndef _ATH_AR5212_H_
|
||||
#define _ATH_AR5212_H_
|
||||
@ -267,10 +267,12 @@ struct ath_hal_5212 {
|
||||
uint32_t ah_txEolInterruptMask;
|
||||
uint32_t ah_txUrnInterruptMask;
|
||||
HAL_TX_QUEUE_INFO ah_txq[HAL_NUM_TX_QUEUES];
|
||||
uint32_t ah_intrTxqs; /* tx q interrupt state */
|
||||
/* decomp mask array */
|
||||
uint8_t ah_decompMask[HAL_DECOMP_MASK_SIZE];
|
||||
uint8_t ah_decompMask[HAL_DECOMP_MASK_SIZE];
|
||||
HAL_POWER_MODE ah_powerMode;
|
||||
HAL_ANT_SETTING ah_diversityControl; /* antenna setting */
|
||||
HAL_ANT_SETTING ah_antControl; /* antenna setting */
|
||||
HAL_BOOL ah_diversity; /* fast diversity setting */
|
||||
enum {
|
||||
IQ_CAL_INACTIVE,
|
||||
IQ_CAL_RUNNING,
|
||||
@ -283,6 +285,8 @@ struct ath_hal_5212 {
|
||||
uint32_t ah_rssiThr; /* RSSI_THR settings */
|
||||
HAL_BOOL ah_cwCalRequire; /* for ap51 */
|
||||
HAL_BOOL ah_tpcEnabled; /* per-packet tpc enabled */
|
||||
HAL_BOOL ah_phyPowerOn; /* PHY power state */
|
||||
HAL_BOOL ah_isHb63; /* cached HB63 check */
|
||||
uint32_t ah_macTPC; /* tpc register */
|
||||
uint32_t ah_beaconInterval; /* XXX */
|
||||
enum {
|
||||
@ -301,18 +305,12 @@ struct ath_hal_5212 {
|
||||
u_int ah_acktimeout; /* user-specified ack timeout */
|
||||
u_int ah_ctstimeout; /* user-specified cts timeout */
|
||||
u_int ah_sifstime; /* user-specified sifs time */
|
||||
/*
|
||||
* XXX
|
||||
* 11g-specific stuff; belongs in the driver.
|
||||
*/
|
||||
uint8_t ah_gBeaconRate; /* fixed rate for G beacons */
|
||||
/*
|
||||
* RF Silent handling; setup according to the EEPROM.
|
||||
*/
|
||||
uint32_t ah_gpioSelect; /* GPIO pin to use */
|
||||
uint32_t ah_polarity; /* polarity to disable RF */
|
||||
uint32_t ah_gpioBit; /* after init, prev value */
|
||||
HAL_BOOL ah_eepEnabled; /* EEPROM bit for capability */
|
||||
/*
|
||||
* ANI support.
|
||||
*/
|
||||
@ -330,30 +328,16 @@ struct ath_hal_5212 {
|
||||
uint16_t *ah_pcdacTable;
|
||||
u_int ah_pcdacTableSize;
|
||||
uint16_t ah_ratesArray[16];
|
||||
|
||||
/*
|
||||
* Tx queue interrupt state.
|
||||
*/
|
||||
uint32_t ah_intrTxqs;
|
||||
|
||||
HAL_BOOL ah_isHb63; /* cached HB63 check */
|
||||
};
|
||||
#define AH5212(_ah) ((struct ath_hal_5212 *)(_ah))
|
||||
|
||||
#define IS_5112(ah) \
|
||||
((AH_PRIVATE(ah)->ah_analog5GhzRev&0xf0) >= AR_RAD5112_SREV_MAJOR \
|
||||
&& (AH_PRIVATE(ah)->ah_analog5GhzRev&0xf0) < AR_RAD2316_SREV_MAJOR )
|
||||
#define IS_RAD5112_REV1(ah) \
|
||||
((AH_PRIVATE(ah)->ah_analog5GhzRev&0x0f) < (AR_RAD5112_SREV_2_0&0x0f))
|
||||
#define IS_RADX112_REV2(ah) \
|
||||
(IS_5112(ah) && \
|
||||
((AH_PRIVATE(ah)->ah_analog5GhzRev == AR_RAD5112_SREV_2_0) || \
|
||||
(AH_PRIVATE(ah)->ah_analog5GhzRev == AR_RAD2112_SREV_2_0) || \
|
||||
(AH_PRIVATE(ah)->ah_analog5GhzRev == AR_RAD2112_SREV_2_1) || \
|
||||
(AH_PRIVATE(ah)->ah_analog5GhzRev == AR_RAD5112_SREV_2_1)))
|
||||
#define IS_5312_2_X(ah) \
|
||||
(((AH_PRIVATE(ah)->ah_macVersion) == AR_SREV_VERSION_VENICE) && \
|
||||
(((AH_PRIVATE(ah)->ah_macRev) == 2) || ((AH_PRIVATE(ah)->ah_macRev) == 7)))
|
||||
/*
|
||||
* IS_XXXX macros test the MAC version
|
||||
* IS_RADXXX macros test the radio/RF version (matching both 2G-only and 2/5G)
|
||||
*
|
||||
* Some single chip radios have equivalent radio/RF (e.g. 5112)
|
||||
* for those use IS_RADXXX_ANY macros.
|
||||
*/
|
||||
#define IS_2317(ah) \
|
||||
((AH_PRIVATE(ah)->ah_devid == AR5212_AR2317_REV1) || \
|
||||
(AH_PRIVATE(ah)->ah_devid == AR5212_AR2317_REV2))
|
||||
@ -375,6 +359,29 @@ struct ath_hal_5212 {
|
||||
|
||||
#define IS_PCIE(ah) (IS_5424(ah) || IS_2425(ah))
|
||||
|
||||
#define AH_RADIO_MAJOR(ah) \
|
||||
(AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)
|
||||
#define AH_RADIO_MINOR(ah) \
|
||||
(AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MINOR)
|
||||
#define IS_RAD5111(ah) \
|
||||
(AH_RADIO_MAJOR(ah) == AR_RAD5111_SREV_MAJOR || \
|
||||
AH_RADIO_MAJOR(ah) == AR_RAD2111_SREV_MAJOR)
|
||||
#define IS_RAD5112(ah) \
|
||||
(AH_RADIO_MAJOR(ah) == AR_RAD5112_SREV_MAJOR || \
|
||||
AH_RADIO_MAJOR(ah) == AR_RAD2112_SREV_MAJOR)
|
||||
/* NB: does not include 5413 as Atheros' IS_5112 macro does */
|
||||
#define IS_RAD5112_ANY(ah) \
|
||||
(AR_RAD5112_SREV_MAJOR <= AH_RADIO_MAJOR(ah) && \
|
||||
AH_RADIO_MAJOR(ah) <= AR_RAD2413_SREV_MAJOR)
|
||||
#define IS_RAD5112_REV1(ah) \
|
||||
(IS_RAD5112(ah) && \
|
||||
AH_RADIO_MINOR(ah) < (AR_RAD5112_SREV_2_0 & AR_RADIO_SREV_MINOR))
|
||||
#define IS_RADX112_REV2(ah) \
|
||||
(AH_PRIVATE(ah)->ah_analog5GhzRev == AR_RAD5112_SREV_2_0 || \
|
||||
AH_PRIVATE(ah)->ah_analog5GhzRev == AR_RAD2112_SREV_2_0 || \
|
||||
AH_PRIVATE(ah)->ah_analog5GhzRev == AR_RAD2112_SREV_2_1 || \
|
||||
AH_PRIVATE(ah)->ah_analog5GhzRev == AR_RAD5112_SREV_2_1)
|
||||
|
||||
#define ar5212RfDetach(ah) do { \
|
||||
if (AH5212(ah)->ah_rfHal != AH_NULL) \
|
||||
AH5212(ah)->ah_rfHal->rfDetach(ah); \
|
||||
@ -534,7 +541,11 @@ extern void ar5212SetOperatingMode(struct ath_hal *ah, int opmode);
|
||||
extern HAL_BOOL ar5212PhyDisable(struct ath_hal *ah);
|
||||
extern HAL_BOOL ar5212Disable(struct ath_hal *ah);
|
||||
extern HAL_BOOL ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *);
|
||||
extern HAL_BOOL ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone);
|
||||
extern HAL_BOOL ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan,
|
||||
HAL_BOOL *isIQdone);
|
||||
extern HAL_BOOL ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
|
||||
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
|
||||
extern HAL_BOOL ar5212ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan);
|
||||
extern int16_t ar5212GetNoiseFloor(struct ath_hal *ah);
|
||||
extern void ar5212InitNfCalHistBuffer(struct ath_hal *);
|
||||
extern int16_t ar5212GetNfHistMid(const int16_t calData[]);
|
||||
@ -546,6 +557,7 @@ extern HAL_BOOL ar5212GetChipPowerLimits(struct ath_hal *ah,
|
||||
HAL_CHANNEL *chans, uint32_t nchans);
|
||||
extern void ar5212InitializeGainValues(struct ath_hal *);
|
||||
extern HAL_RFGAIN ar5212GetRfgain(struct ath_hal *ah);
|
||||
extern void ar5212RequestRfgain(struct ath_hal *);
|
||||
|
||||
extern HAL_BOOL ar5212UpdateTxTrigLevel(struct ath_hal *,
|
||||
HAL_BOOL IncTrigLevel);
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5212_ani.c,v 1.5 2008/11/10 04:08:03 sam Exp $
|
||||
* $Id: ar5212_ani.c,v 1.7 2008/11/21 00:16:21 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -435,13 +435,17 @@ ar5212AniOfdmErrTrigger(struct ath_hal *ah)
|
||||
aniState = ahp->ah_curani;
|
||||
params = aniState->params;
|
||||
/* First, raise noise immunity level, up to max */
|
||||
if (aniState->noiseImmunityLevel < params->maxNoiseImmunityLevel) {
|
||||
if (aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: raise NI to %u\n", __func__,
|
||||
aniState->noiseImmunityLevel + 1);
|
||||
ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
|
||||
aniState->noiseImmunityLevel + 1);
|
||||
return;
|
||||
}
|
||||
/* then, raise spur immunity level, up to max */
|
||||
if (aniState->spurImmunityLevel < params->maxSpurImmunityLevel) {
|
||||
if (aniState->spurImmunityLevel+1 < params->maxSpurImmunityLevel) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: raise SI to %u\n", __func__,
|
||||
aniState->spurImmunityLevel + 1);
|
||||
ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
|
||||
aniState->spurImmunityLevel + 1);
|
||||
return;
|
||||
@ -455,6 +459,8 @@ ar5212AniOfdmErrTrigger(struct ath_hal *ah)
|
||||
* weak sig detect.
|
||||
*/
|
||||
if (!aniState->ofdmWeakSigDetectOff) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: rssi %d OWSD off\n", __func__, rssi);
|
||||
ar5212AniControl(ah,
|
||||
HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
AH_FALSE);
|
||||
@ -466,7 +472,10 @@ ar5212AniOfdmErrTrigger(struct ath_hal *ah)
|
||||
* If weak sig detect is already off, as last resort,
|
||||
* raise firstep level
|
||||
*/
|
||||
if (aniState->firstepLevel < params->maxFirstepLevel) {
|
||||
if (aniState->firstepLevel+1 < params->maxFirstepLevel) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: rssi %d raise ST %u\n", __func__, rssi,
|
||||
aniState->firstepLevel+1);
|
||||
ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel + 1);
|
||||
return;
|
||||
@ -476,13 +485,20 @@ ar5212AniOfdmErrTrigger(struct ath_hal *ah)
|
||||
* Beacon rssi in mid range, need ofdm weak signal
|
||||
* detect, but we can raise firststepLevel.
|
||||
*/
|
||||
if (aniState->ofdmWeakSigDetectOff)
|
||||
if (aniState->ofdmWeakSigDetectOff) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: rssi %d OWSD on\n", __func__, rssi);
|
||||
ar5212AniControl(ah,
|
||||
HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
AH_TRUE);
|
||||
if (aniState->firstepLevel < params->maxFirstepLevel)
|
||||
}
|
||||
if (aniState->firstepLevel+1 < params->maxFirstepLevel) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: rssi %d raise ST %u\n", __func__, rssi,
|
||||
aniState->firstepLevel+1);
|
||||
ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel + 1);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
@ -492,13 +508,22 @@ ar5212AniOfdmErrTrigger(struct ath_hal *ah)
|
||||
*/
|
||||
/* XXX can optimize */
|
||||
if (IS_CHAN_B(chan) || IS_CHAN_G(chan)) {
|
||||
if (!aniState->ofdmWeakSigDetectOff)
|
||||
if (!aniState->ofdmWeakSigDetectOff) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: rssi %d OWSD off\n",
|
||||
__func__, rssi);
|
||||
ar5212AniControl(ah,
|
||||
HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
AH_FALSE);
|
||||
if (aniState->firstepLevel > 0)
|
||||
}
|
||||
if (aniState->firstepLevel > 0) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: rssi %d zero ST (was %u)\n",
|
||||
__func__, rssi,
|
||||
aniState->firstepLevel);
|
||||
ar5212AniControl(ah,
|
||||
HAL_ANI_FIRSTEP_LEVEL, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -521,7 +546,9 @@ ar5212AniCckErrTrigger(struct ath_hal *ah)
|
||||
/* first, raise noise immunity level, up to max */
|
||||
aniState = ahp->ah_curani;
|
||||
params = aniState->params;
|
||||
if (aniState->noiseImmunityLevel < params->maxNoiseImmunityLevel) {
|
||||
if (aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: raise NI to %u\n", __func__,
|
||||
aniState->noiseImmunityLevel + 1);
|
||||
ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
|
||||
aniState->noiseImmunityLevel + 1);
|
||||
return;
|
||||
@ -534,9 +561,13 @@ ar5212AniCckErrTrigger(struct ath_hal *ah)
|
||||
* Beacon signal in mid and high range,
|
||||
* raise firstep level.
|
||||
*/
|
||||
if (aniState->firstepLevel < params->maxFirstepLevel)
|
||||
if (aniState->firstepLevel+1 < params->maxFirstepLevel) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: rssi %d raise ST %u\n", __func__, rssi,
|
||||
aniState->firstepLevel+1);
|
||||
ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel + 1);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Beacon rssi is low, zero firstep level to maximize
|
||||
@ -544,9 +575,14 @@ ar5212AniCckErrTrigger(struct ath_hal *ah)
|
||||
*/
|
||||
/* XXX can optimize */
|
||||
if (IS_CHAN_B(chan) || IS_CHAN_G(chan)) {
|
||||
if (aniState->firstepLevel > 0)
|
||||
if (aniState->firstepLevel > 0) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: rssi %d zero ST (was %u)\n",
|
||||
__func__, rssi,
|
||||
aniState->firstepLevel);
|
||||
ar5212AniControl(ah,
|
||||
HAL_ANI_FIRSTEP_LEVEL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -564,9 +600,6 @@ ar5212AniRestart(struct ath_hal *ah, struct ar5212AniState *aniState)
|
||||
* NB: these are written on reset based on the
|
||||
* ini so we must re-write them!
|
||||
*/
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: Writing ofdmbase=%u cckbase=%u\n", __func__,
|
||||
params->ofdmPhyErrBase, params->cckPhyErrBase);
|
||||
OS_REG_WRITE(ah, AR_PHYCNT1, params->ofdmPhyErrBase);
|
||||
OS_REG_WRITE(ah, AR_PHYCNT2, params->cckPhyErrBase);
|
||||
OS_REG_WRITE(ah, AR_PHYCNTMASK1, AR_PHY_ERR_OFDM_TIMING);
|
||||
@ -781,12 +814,17 @@ ar5212AniLowerImmunity(struct ath_hal *ah)
|
||||
* detection or lower firstep level.
|
||||
*/
|
||||
if (aniState->ofdmWeakSigDetectOff) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: rssi %d OWSD on\n", __func__, rssi);
|
||||
ar5212AniControl(ah,
|
||||
HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
AH_TRUE);
|
||||
return;
|
||||
}
|
||||
if (aniState->firstepLevel > 0) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: rssi %d lower ST %u\n", __func__, rssi,
|
||||
aniState->firstepLevel-1);
|
||||
ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel - 1);
|
||||
return;
|
||||
@ -796,6 +834,9 @@ ar5212AniLowerImmunity(struct ath_hal *ah)
|
||||
* Beacon rssi is low, reduce firstep level.
|
||||
*/
|
||||
if (aniState->firstepLevel > 0) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: rssi %d lower ST %u\n", __func__, rssi,
|
||||
aniState->firstepLevel-1);
|
||||
ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel - 1);
|
||||
return;
|
||||
@ -804,6 +845,8 @@ ar5212AniLowerImmunity(struct ath_hal *ah)
|
||||
}
|
||||
/* then lower spur immunity level, down to zero */
|
||||
if (aniState->spurImmunityLevel > 0) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: lower SI %u\n",
|
||||
__func__, aniState->spurImmunityLevel-1);
|
||||
ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
|
||||
aniState->spurImmunityLevel - 1);
|
||||
return;
|
||||
@ -813,6 +856,8 @@ ar5212AniLowerImmunity(struct ath_hal *ah)
|
||||
* zero for now
|
||||
*/
|
||||
if (aniState->noiseImmunityLevel > 0) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: lower NI %u\n",
|
||||
__func__, aniState->noiseImmunityLevel-1);
|
||||
ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
|
||||
aniState->noiseImmunityLevel - 1);
|
||||
return;
|
||||
@ -956,10 +1001,16 @@ ar5212AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
|
||||
/* check to see if need to raise immunity */
|
||||
if (aniState->ofdmPhyErrCount > aniState->listenTime *
|
||||
params->ofdmTrigHigh / 1000) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: OFDM err %u listenTime %u\n", __func__,
|
||||
aniState->ofdmPhyErrCount, aniState->listenTime);
|
||||
ar5212AniOfdmErrTrigger(ah);
|
||||
ar5212AniRestart(ah, aniState);
|
||||
} else if (aniState->cckPhyErrCount > aniState->listenTime *
|
||||
params->cckTrigHigh / 1000) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: CCK err %u listenTime %u\n", __func__,
|
||||
aniState->cckPhyErrCount, aniState->listenTime);
|
||||
ar5212AniCckErrTrigger(ah);
|
||||
ar5212AniRestart(ah, aniState);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5212_attach.c,v 1.12 2008/11/10 04:08:03 sam Exp $
|
||||
* $Id: ar5212_attach.c,v 1.18 2008/11/19 22:10:42 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -56,6 +56,8 @@ static const struct ath_hal_private ar5212hal = {{
|
||||
.ah_disable = ar5212Disable,
|
||||
.ah_setPCUConfig = ar5212SetPCUConfig,
|
||||
.ah_perCalibration = ar5212PerCalibration,
|
||||
.ah_perCalibrationN = ar5212PerCalibrationN,
|
||||
.ah_resetCalValid = ar5212ResetCalValid,
|
||||
.ah_setTxPowerLimit = ar5212SetTxPowerLimit,
|
||||
.ah_getChanNoise = ath_hal_getChanNoise,
|
||||
|
||||
@ -103,6 +105,7 @@ static const struct ath_hal_private ar5212hal = {{
|
||||
.ah_setMacAddress = ar5212SetMacAddress,
|
||||
.ah_getBssIdMask = ar5212GetBssIdMask,
|
||||
.ah_setBssIdMask = ar5212SetBssIdMask,
|
||||
.ah_setRegulatoryDomain = ar5212SetRegulatoryDomain,
|
||||
.ah_setLedState = ar5212SetLedState,
|
||||
.ah_writeAssocid = ar5212WriteAssocid,
|
||||
.ah_gpioCfgInput = ar5212GpioCfgInput,
|
||||
@ -271,7 +274,8 @@ ar5212InitState(struct ath_hal_5212 *ahp, uint16_t devid, HAL_SOFTC sc,
|
||||
AH_PRIVATE(ah)->ah_powerLimit = MAX_RATE_POWER;
|
||||
AH_PRIVATE(ah)->ah_tpScale = HAL_TP_SCALE_MAX; /* no scaling */
|
||||
|
||||
ahp->ah_diversityControl = HAL_ANT_VARIABLE;
|
||||
ahp->ah_antControl = HAL_ANT_VARIABLE;
|
||||
ahp->ah_diversity = AH_TRUE;
|
||||
ahp->ah_bIQCalibration = AH_FALSE;
|
||||
/*
|
||||
* Enable MIC handling.
|
||||
@ -279,6 +283,7 @@ ar5212InitState(struct ath_hal_5212 *ahp, uint16_t devid, HAL_SOFTC sc,
|
||||
ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
|
||||
ahp->ah_rssiThr = INIT_RSSI_THR;
|
||||
ahp->ah_tpcEnabled = AH_FALSE; /* disabled by default */
|
||||
ahp->ah_phyPowerOn = AH_FALSE;
|
||||
ahp->ah_macTPC = SM(MAX_RATE_POWER, AR_TPC_ACK)
|
||||
| SM(MAX_RATE_POWER, AR_TPC_CTS)
|
||||
| SM(MAX_RATE_POWER, AR_TPC_CHIRP);
|
||||
@ -289,11 +294,6 @@ ar5212InitState(struct ath_hal_5212 *ahp, uint16_t devid, HAL_SOFTC sc,
|
||||
ahp->ah_ctstimeout = (u_int) -1;
|
||||
ahp->ah_sifstime = (u_int) -1;
|
||||
OS_MEMCPY(&ahp->ah_bssidmask, defbssidmask, IEEE80211_ADDR_LEN);
|
||||
|
||||
/*
|
||||
* 11g-specific stuff
|
||||
*/
|
||||
ahp->ah_gBeaconRate = 0; /* adhoc beacon fixed rate */
|
||||
#undef N
|
||||
}
|
||||
|
||||
@ -444,15 +444,18 @@ ar5212Attach(uint16_t devid, HAL_SOFTC sc,
|
||||
break;
|
||||
}
|
||||
if (IS_2413(ah)) { /* Griffin */
|
||||
AH_PRIVATE(ah)->ah_analog5GhzRev = 0x51;
|
||||
AH_PRIVATE(ah)->ah_analog5GhzRev =
|
||||
AR_RAD2413_SREV_MAJOR | 0x1;
|
||||
break;
|
||||
}
|
||||
if (IS_5413(ah)) { /* Eagle */
|
||||
AH_PRIVATE(ah)->ah_analog5GhzRev = 0x62;
|
||||
AH_PRIVATE(ah)->ah_analog5GhzRev =
|
||||
AR_RAD5413_SREV_MAJOR | 0x2;
|
||||
break;
|
||||
}
|
||||
if (IS_2425(ah) || IS_2417(ah)) {/* Swan or Nala */
|
||||
AH_PRIVATE(ah)->ah_analog5GhzRev = 0xA2;
|
||||
AH_PRIVATE(ah)->ah_analog5GhzRev =
|
||||
AR_RAD5424_SREV_MAJOR | 0x2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -465,7 +468,7 @@ ar5212Attach(uint16_t devid, HAL_SOFTC sc,
|
||||
goto bad;
|
||||
#endif
|
||||
}
|
||||
if (!IS_5413(ah) && IS_5112(ah) && IS_RAD5112_REV1(ah)) {
|
||||
if (IS_RAD5112_REV1(ah)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: 5112 Rev 1 is not supported by this "
|
||||
"driver (analog5GhzRev 0x%x)\n", __func__,
|
||||
@ -565,7 +568,7 @@ ar5212Attach(uint16_t devid, HAL_SOFTC sc,
|
||||
#else
|
||||
ecode = HAL_ENOTSUPP;
|
||||
#endif
|
||||
else if (IS_5112(ah))
|
||||
else if (IS_RAD5112(ah))
|
||||
#ifdef AH_SUPPORT_5112
|
||||
rfStatus = ar5112RfAttach(ah, &ecode);
|
||||
#else
|
||||
@ -577,7 +580,7 @@ ar5212Attach(uint16_t devid, HAL_SOFTC sc,
|
||||
#else
|
||||
ecode = HAL_ENOTSUPP;
|
||||
#endif
|
||||
else
|
||||
else if (IS_RAD5111(ah))
|
||||
#ifdef AH_SUPPORT_5111
|
||||
rfStatus = ar5111RfAttach(ah, &ecode);
|
||||
#else
|
||||
@ -788,7 +791,8 @@ ar5212FillCapabilityInfo(struct ath_hal *ah)
|
||||
}
|
||||
|
||||
pCap->halLow2GhzChan = 2312;
|
||||
if (IS_5112(ah) || IS_2413(ah) || IS_5413(ah) || IS_2425(ah))
|
||||
/* XXX 2417 too? */
|
||||
if (IS_RAD5112_ANY(ah) || IS_5413(ah) || IS_2425(ah) || IS_2417(ah))
|
||||
pCap->halHigh2GhzChan = 2500;
|
||||
else
|
||||
pCap->halHigh2GhzChan = 2732;
|
||||
@ -850,14 +854,8 @@ ar5212FillCapabilityInfo(struct ath_hal *ah)
|
||||
else
|
||||
pCap->halKeyCacheSize = AR_KEYTABLE_SIZE;
|
||||
|
||||
if (IS_5112(ah)) {
|
||||
pCap->halChanHalfRate = AH_TRUE;
|
||||
pCap->halChanQuarterRate = AH_TRUE;
|
||||
} else {
|
||||
/* XXX not needed */
|
||||
pCap->halChanHalfRate = AH_FALSE;
|
||||
pCap->halChanQuarterRate = AH_FALSE;
|
||||
}
|
||||
pCap->halChanHalfRate = AH_TRUE;
|
||||
pCap->halChanQuarterRate = AH_TRUE;
|
||||
|
||||
if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL) &&
|
||||
ath_hal_eepromGet(ah, AR_EEP_RFSILENT, &ahpriv->ah_rfsilent) == HAL_OK) {
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5212_interrupts.c,v 1.5 2008/11/10 04:08:03 sam Exp $
|
||||
* $Id: ar5212_interrupts.c,v 1.6 2008/11/27 22:30:00 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -96,7 +96,9 @@ ar5212GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked)
|
||||
}
|
||||
|
||||
/*
|
||||
* RXORN can hang the receive path so we force a hardware
|
||||
* Receive overrun is usually non-fatal on Oahu/Spirit.
|
||||
* BUT on some parts rx could fail and the chip must be reset.
|
||||
* So we force a hardware reset in all cases.
|
||||
*/
|
||||
if ((isr & AR_ISR_RXORN) && AH_PRIVATE(ah)->ah_rxornIsFatal) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5212_misc.c,v 1.8 2008/11/10 04:08:03 sam Exp $
|
||||
* $Id: ar5212_misc.c,v 1.12 2008/11/27 22:30:00 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -79,12 +79,44 @@ ar5212SetBssIdMask(struct ath_hal *ah, const uint8_t *mask)
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to change the cards operating regulatory domain to the given value
|
||||
*/
|
||||
HAL_BOOL
|
||||
ar5212SetRegulatoryDomain(struct ath_hal *ah,
|
||||
uint16_t regDomain, HAL_STATUS *status)
|
||||
{
|
||||
HAL_STATUS ecode;
|
||||
|
||||
if (AH_PRIVATE(ah)->ah_currentRD == regDomain) {
|
||||
ecode = HAL_EINVAL;
|
||||
goto bad;
|
||||
}
|
||||
if (ath_hal_eepromGetFlag(ah, AR_EEP_WRITEPROTECT)) {
|
||||
ecode = HAL_EEWRITE;
|
||||
goto bad;
|
||||
}
|
||||
#ifdef AH_SUPPORT_WRITE_REGDOMAIN
|
||||
if (ath_hal_eepromWrite(ah, AR_EEPROM_REG_DOMAIN, regDomain)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: set regulatory domain to %u (0x%x)\n",
|
||||
__func__, regDomain, regDomain);
|
||||
AH_PRIVATE(ah)->ah_currentRD = regDomain;
|
||||
return AH_TRUE;
|
||||
}
|
||||
#endif
|
||||
ecode = HAL_EIO;
|
||||
bad:
|
||||
if (status)
|
||||
*status = ecode;
|
||||
return AH_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the wireless modes (a,b,g,t) supported by hardware.
|
||||
*
|
||||
* This value is what is actually supported by the hardware
|
||||
* and is unaffected by regulatory/country code settings.
|
||||
*
|
||||
*/
|
||||
u_int
|
||||
ar5212GetWirelessModes(struct ath_hal *ah)
|
||||
@ -95,6 +127,10 @@ ar5212GetWirelessModes(struct ath_hal *ah)
|
||||
mode = HAL_MODE_11A;
|
||||
if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO5DISABLE))
|
||||
mode |= HAL_MODE_TURBO | HAL_MODE_108A;
|
||||
if (AH_PRIVATE(ah)->ah_caps.halChanHalfRate)
|
||||
mode |= HAL_MODE_11A_HALF_RATE;
|
||||
if (AH_PRIVATE(ah)->ah_caps.halChanQuarterRate)
|
||||
mode |= HAL_MODE_11A_QUARTER_RATE;
|
||||
}
|
||||
if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE))
|
||||
mode |= HAL_MODE_11B;
|
||||
@ -103,6 +139,10 @@ ar5212GetWirelessModes(struct ath_hal *ah)
|
||||
mode |= HAL_MODE_11G;
|
||||
if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO2DISABLE))
|
||||
mode |= HAL_MODE_108G;
|
||||
if (AH_PRIVATE(ah)->ah_caps.halChanHalfRate)
|
||||
mode |= HAL_MODE_11G_HALF_RATE;
|
||||
if (AH_PRIVATE(ah)->ah_caps.halChanQuarterRate)
|
||||
mode |= HAL_MODE_11G_QUARTER_RATE;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
@ -212,11 +252,10 @@ ar5212GetTsf64(struct ath_hal *ah)
|
||||
* then we re-reading AR_TSF_U32 does no good as the
|
||||
* low bits will be meaningless. Likewise reading
|
||||
* L32, U32, U32, then comparing the last two reads
|
||||
* to check for rollover
|
||||
* doesn't help if preempted--so we take this approach
|
||||
* as it costs one less PCI read which can be noticeable
|
||||
* when doing things like timestamping packets in
|
||||
* monitor mode.
|
||||
* to check for rollover doesn't help if preempted--so
|
||||
* we take this approach as it costs one less PCI read
|
||||
* which can be noticeable when doing things like
|
||||
* timestamping packets in monitor mode.
|
||||
*/
|
||||
u32++;
|
||||
}
|
||||
@ -382,19 +421,22 @@ ar5212SetDefAntenna(struct ath_hal *ah, u_int antenna)
|
||||
HAL_ANT_SETTING
|
||||
ar5212GetAntennaSwitch(struct ath_hal *ah)
|
||||
{
|
||||
return AH5212(ah)->ah_diversityControl;
|
||||
return AH5212(ah)->ah_antControl;
|
||||
}
|
||||
|
||||
HAL_BOOL
|
||||
ar5212SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
|
||||
ar5212SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING setting)
|
||||
{
|
||||
const HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
const HAL_CHANNEL_INTERNAL *ichan = AH_PRIVATE(ah)->ah_curchan;
|
||||
|
||||
if (chan == AH_NULL) {
|
||||
AH5212(ah)->ah_diversityControl = settings;
|
||||
if (!ahp->ah_phyPowerOn || ichan == AH_NULL) {
|
||||
/* PHY powered off, just stash settings */
|
||||
ahp->ah_antControl = setting;
|
||||
ahp->ah_diversity = (setting == HAL_ANT_VARIABLE);
|
||||
return AH_TRUE;
|
||||
}
|
||||
return ar5212SetAntennaSwitchInternal(ah, settings, chan);
|
||||
return ar5212SetAntennaSwitchInternal(ah, setting, ichan);
|
||||
}
|
||||
|
||||
HAL_BOOL
|
||||
@ -632,7 +674,8 @@ ar5212SetupClock(struct ath_hal *ah, HAL_OPMODE opmode)
|
||||
* from A2.
|
||||
*/
|
||||
OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKPD, IS_5112(ah) ? 0x14 : 0x18);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
|
||||
IS_RAD5112_ANY(ah) || IS_5413(ah) ? 0x14 : 0x18);
|
||||
OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32, 1);
|
||||
OS_REG_WRITE(ah, AR_TSF_PARM, 61); /* 32 KHz TSF incr */
|
||||
OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_SEL, 1);
|
||||
@ -669,8 +712,9 @@ ar5212SetupClock(struct ath_hal *ah, HAL_OPMODE opmode)
|
||||
OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x0c);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0xff);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
|
||||
IS_5112(ah) || IS_2417(ah) ? 0x14 : 0x18);
|
||||
OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32, IS_5112(ah) ? 39 : 31);
|
||||
IS_RAD5112_ANY(ah) || IS_5413(ah) || IS_2417(ah) ? 0x14 : 0x18);
|
||||
OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32,
|
||||
IS_RAD5112_ANY(ah) || IS_5413(ah) ? 39 : 31);
|
||||
}
|
||||
}
|
||||
|
||||
@ -686,7 +730,8 @@ ar5212RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode)
|
||||
OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_SEL, 0);
|
||||
|
||||
OS_REG_WRITE(ah, AR_TSF_PARM, 1); /* 32 MHz TSF incr */
|
||||
OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32, IS_5112(ah) ? 39 : 31);
|
||||
OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32,
|
||||
IS_RAD5112_ANY(ah) || IS_5413(ah) ? 39 : 31);
|
||||
|
||||
/*
|
||||
* Restore BB registers to power-on defaults
|
||||
@ -696,7 +741,8 @@ ar5212RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode)
|
||||
OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
|
||||
OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x0c);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0xff);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKPD, IS_5112(ah) ? 0x14 : 0x18);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
|
||||
IS_RAD5112_ANY(ah) || IS_5413(ah) ? 0x14 : 0x18);
|
||||
}
|
||||
}
|
||||
|
||||
@ -782,9 +828,7 @@ ar5212GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
|
||||
case 0: /* hardware capability */
|
||||
return HAL_OK;
|
||||
case 1: /* current setting */
|
||||
return (OS_REG_READ(ah, AR_PHY_CCK_DETECT) &
|
||||
AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
|
||||
HAL_OK : HAL_ENXIO;
|
||||
return ahp->ah_diversity ? HAL_OK : HAL_ENXIO;
|
||||
}
|
||||
return HAL_EINVAL;
|
||||
case HAL_CAP_DIAG:
|
||||
@ -892,12 +936,15 @@ ar5212SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
|
||||
OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
|
||||
return AH_TRUE;
|
||||
case HAL_CAP_DIVERSITY:
|
||||
v = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
|
||||
if (setting)
|
||||
v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
|
||||
else
|
||||
v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
|
||||
OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
|
||||
if (ahp->ah_phyPowerOn) {
|
||||
v = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
|
||||
if (setting)
|
||||
v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
|
||||
else
|
||||
v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
|
||||
OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
|
||||
}
|
||||
ahp->ah_diversity = (setting != 0);
|
||||
return AH_TRUE;
|
||||
case HAL_CAP_DIAG: /* hardware diagnostic support */
|
||||
/*
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5212_phy.c,v 1.4 2008/11/10 01:19:38 sam Exp $
|
||||
* $Id: ar5212_phy.c,v 1.5 2008/11/15 03:43:53 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -47,7 +47,7 @@ HAL_RATE_TABLE ar5212_11a_table = {
|
||||
},
|
||||
};
|
||||
|
||||
HAL_RATE_TABLE ar5212_11a_half_table = {
|
||||
HAL_RATE_TABLE ar5212_half_table = {
|
||||
8, /* number of rates */
|
||||
{ 0 },
|
||||
{
|
||||
@ -64,7 +64,7 @@ HAL_RATE_TABLE ar5212_11a_half_table = {
|
||||
},
|
||||
};
|
||||
|
||||
HAL_RATE_TABLE ar5212_11a_quarter_table = {
|
||||
HAL_RATE_TABLE ar5212_quarter_table = {
|
||||
8, /* number of rates */
|
||||
{ 0 },
|
||||
{
|
||||
@ -184,10 +184,12 @@ ar5212GetRateTable(struct ath_hal *ah, u_int mode)
|
||||
rt = &ar5212_turbog_table;
|
||||
break;
|
||||
case HAL_MODE_11A_HALF_RATE:
|
||||
rt = &ar5212_11a_half_table;
|
||||
case HAL_MODE_11G_HALF_RATE:
|
||||
rt = &ar5212_half_table;
|
||||
break;
|
||||
case HAL_MODE_11A_QUARTER_RATE:
|
||||
rt = &ar5212_11a_quarter_table;
|
||||
case HAL_MODE_11G_QUARTER_RATE:
|
||||
rt = &ar5212_quarter_table;
|
||||
break;
|
||||
default:
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid mode 0x%x\n",
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5212_reset.c,v 1.12 2008/11/10 04:08:03 sam Exp $
|
||||
* $Id: ar5212_reset.c,v 1.20 2008/11/27 22:30:00 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -47,32 +47,23 @@ void ar5212SetDeltaSlope(struct ath_hal *, HAL_CHANNEL *);
|
||||
HAL_BOOL ar5212SetTransmitPower(struct ath_hal *ah,
|
||||
HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain);
|
||||
static HAL_BOOL ar5212SetRateTable(struct ath_hal *,
|
||||
HAL_CHANNEL *, int16_t tpcScaleReduction, int16_t powerLimit,
|
||||
HAL_BOOL commit,
|
||||
int16_t *minPower, int16_t *maxPower);
|
||||
HAL_CHANNEL *, int16_t tpcScaleReduction, int16_t powerLimit,
|
||||
HAL_BOOL commit, int16_t *minPower, int16_t *maxPower);
|
||||
static void ar5212CorrectGainDelta(struct ath_hal *, int twiceOfdmCckDelta);
|
||||
static void ar5212GetTargetPowers(struct ath_hal *, HAL_CHANNEL *,
|
||||
const TRGT_POWER_INFO *pPowerInfo, uint16_t numChannels,
|
||||
TRGT_POWER_INFO *pNewPower);
|
||||
const TRGT_POWER_INFO *pPowerInfo, uint16_t numChannels,
|
||||
TRGT_POWER_INFO *pNewPower);
|
||||
static uint16_t ar5212GetMaxEdgePower(uint16_t channel,
|
||||
const RD_EDGES_POWER *pRdEdgesPower);
|
||||
static void ar5212RequestRfgain(struct ath_hal *);
|
||||
static HAL_BOOL ar5212InvalidGainReadback(struct ath_hal *, GAIN_VALUES *);
|
||||
static HAL_BOOL ar5212IsGainAdjustNeeded(struct ath_hal *, const GAIN_VALUES *);
|
||||
static int32_t ar5212AdjustGain(struct ath_hal *, GAIN_VALUES *);
|
||||
const RD_EDGES_POWER *pRdEdgesPower);
|
||||
void ar5212SetRateDurationTable(struct ath_hal *, HAL_CHANNEL *);
|
||||
static uint32_t ar5212GetRfField(uint32_t *rfBuf, uint32_t numBits,
|
||||
uint32_t firstBit, uint32_t column);
|
||||
static void ar5212GetGainFCorrection(struct ath_hal *ah);
|
||||
HAL_BOOL ar5212SetXrMode(struct ath_hal *ah, HAL_OPMODE opmode,HAL_CHANNEL *chan);
|
||||
void ar5212SetIFSTiming(struct ath_hal *, HAL_CHANNEL *);
|
||||
void ar5212SetIFSTiming(struct ath_hal *, HAL_CHANNEL *);
|
||||
|
||||
/* NB: public for RF backend use */
|
||||
void ar5212GetLowerUpperValues(uint16_t value,
|
||||
uint16_t *pList, uint16_t listSize,
|
||||
uint16_t *pLowerValue, uint16_t *pUpperValue);
|
||||
void ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32,
|
||||
uint32_t numBits, uint32_t firstBit, uint32_t column);
|
||||
void ar5212GetLowerUpperValues(uint16_t value,
|
||||
uint16_t *pList, uint16_t listSize,
|
||||
uint16_t *pLowerValue, uint16_t *pUpperValue);
|
||||
void ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32,
|
||||
uint32_t numBits, uint32_t firstBit, uint32_t column);
|
||||
|
||||
static int
|
||||
write_common(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
|
||||
@ -463,8 +454,9 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
|
||||
ar5212SetRateDurationTable(ah, chan);
|
||||
|
||||
/* Set Tx frame start to tx data start delay */
|
||||
if (IS_5112(ah) && (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan) ||
|
||||
IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan))) {
|
||||
if (IS_RAD5112_ANY(ah) &&
|
||||
(IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan) ||
|
||||
IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan))) {
|
||||
txFrm2TxDStart =
|
||||
(IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) ?
|
||||
TX_FRAME_D_START_HALF_RATE:
|
||||
@ -906,7 +898,7 @@ ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
if (chan != AH_NULL) { /* NB: can be null during attach */
|
||||
uint32_t rfMode, phyPLL = 0, curPhyPLL, turbo;
|
||||
|
||||
if (IS_5413(ah)) {
|
||||
if (IS_5413(ah)) { /* NB: =>'s 5424 also */
|
||||
rfMode = AR_PHY_MODE_AR5112;
|
||||
if (IS_CHAN_HALF_RATE(chan))
|
||||
rfMode |= AR_PHY_MODE_HALF;
|
||||
@ -917,33 +909,26 @@ ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
phyPLL = AR_PHY_PLL_CTL_44_5112;
|
||||
else
|
||||
phyPLL = AR_PHY_PLL_CTL_40_5413;
|
||||
}
|
||||
else if (IS_5112(ah) || IS_2413(ah) || IS_2425(ah) || IS_2417(ah)) {
|
||||
rfMode = AR_PHY_MODE_AR5112;
|
||||
if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
|
||||
phyPLL = AR_PHY_PLL_CTL_44_5112;
|
||||
} else {
|
||||
if (IS_CHAN_HALF_RATE(chan)) {
|
||||
phyPLL = AR_PHY_PLL_CTL_40_5112_HALF;
|
||||
} else if (IS_CHAN_QUARTER_RATE(chan)) {
|
||||
phyPLL = AR_PHY_PLL_CTL_40_5112_QUARTER;
|
||||
} else {
|
||||
phyPLL = AR_PHY_PLL_CTL_40_5112;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (IS_RAD5111(ah)) {
|
||||
rfMode = AR_PHY_MODE_AR5111;
|
||||
if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
|
||||
if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
|
||||
phyPLL = AR_PHY_PLL_CTL_44;
|
||||
} else {
|
||||
if (IS_CHAN_HALF_RATE(chan)) {
|
||||
phyPLL = AR_PHY_PLL_CTL_40_HALF;
|
||||
} else if (IS_CHAN_QUARTER_RATE(chan)) {
|
||||
phyPLL = AR_PHY_PLL_CTL_40_QUARTER;
|
||||
} else {
|
||||
phyPLL = AR_PHY_PLL_CTL_40;
|
||||
}
|
||||
}
|
||||
else
|
||||
phyPLL = AR_PHY_PLL_CTL_40;
|
||||
if (IS_CHAN_HALF_RATE(chan))
|
||||
phyPLL = AR_PHY_PLL_CTL_HALF;
|
||||
else if (IS_CHAN_QUARTER_RATE(chan))
|
||||
phyPLL = AR_PHY_PLL_CTL_QUARTER;
|
||||
} else { /* 5112, 2413, 2316, 2317 */
|
||||
rfMode = AR_PHY_MODE_AR5112;
|
||||
if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
|
||||
phyPLL = AR_PHY_PLL_CTL_44_5112;
|
||||
else
|
||||
phyPLL = AR_PHY_PLL_CTL_40_5112;
|
||||
if (IS_CHAN_HALF_RATE(chan))
|
||||
phyPLL |= AR_PHY_PLL_CTL_HALF;
|
||||
else if (IS_CHAN_QUARTER_RATE(chan))
|
||||
phyPLL |= AR_PHY_PLL_CTL_QUARTER;
|
||||
}
|
||||
if (IS_CHAN_OFDM(chan) && (IS_CHAN_CCK(chan) ||
|
||||
IS_CHAN_G(chan)))
|
||||
@ -992,7 +977,8 @@ ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
* changes.
|
||||
*/
|
||||
HAL_BOOL
|
||||
ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
|
||||
HAL_BOOL longCal, HAL_BOOL *isCalDone)
|
||||
{
|
||||
#define IQ_CAL_TRIES 10
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
@ -1004,7 +990,7 @@ ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
HAL_BOOL isBmode = AH_FALSE;
|
||||
|
||||
OS_MARK(ah, AH_MARK_PERCAL, chan->channel);
|
||||
*isIQdone = AH_FALSE;
|
||||
*isCalDone = AH_FALSE;
|
||||
ichan = ath_hal_checkchannel(ah, chan);
|
||||
if (ichan == AH_NULL) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
@ -1015,10 +1001,9 @@ ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
SAVE_CCK(ah, ichan, ichan_isBmode);
|
||||
SAVE_CCK(ah, chan, isBmode);
|
||||
|
||||
/* XXX EAR */
|
||||
if ((ahp->ah_bIQCalibration == IQ_CAL_DONE) ||
|
||||
(ahp->ah_bIQCalibration == IQ_CAL_INACTIVE))
|
||||
*isIQdone = AH_TRUE;
|
||||
if (ahp->ah_bIQCalibration == IQ_CAL_DONE ||
|
||||
ahp->ah_bIQCalibration == IQ_CAL_INACTIVE)
|
||||
*isCalDone = AH_TRUE;
|
||||
|
||||
/* IQ calibration in progress. Check to see if it has finished. */
|
||||
if (ahp->ah_bIQCalibration == IQ_CAL_RUNNING &&
|
||||
@ -1027,7 +1012,7 @@ ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
|
||||
/* IQ Calibration has finished. */
|
||||
ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
|
||||
*isIQdone = AH_TRUE;
|
||||
*isCalDone = AH_TRUE;
|
||||
|
||||
/* workaround for misgated IQ Cal results */
|
||||
i = 0;
|
||||
@ -1097,9 +1082,8 @@ ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
ichan->iCoff = iCoff;
|
||||
ichan->qCoff = qCoff;
|
||||
}
|
||||
} else if (!IS_CHAN_B(chan) &&
|
||||
ahp->ah_bIQCalibration == IQ_CAL_DONE &&
|
||||
!ichan->iqCalValid) {
|
||||
} else if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration == IQ_CAL_DONE &&
|
||||
!ichan->iqCalValid) {
|
||||
/*
|
||||
* Start IQ calibration if configured channel has changed.
|
||||
* Use a magic number of 15 based on default value.
|
||||
@ -1113,22 +1097,21 @@ ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
}
|
||||
/* XXX EAR */
|
||||
|
||||
/* Check noise floor results */
|
||||
ar5212GetNf(ah, ichan);
|
||||
if ((ichan->channelFlags & CHANNEL_CW_INT) == 0) {
|
||||
/* Perform calibration for 5Ghz channels and any OFDM on 5112 */
|
||||
if ((IS_CHAN_5GHZ(chan) ||
|
||||
(IS_5112(ah) && IS_CHAN_OFDM(chan))) &&
|
||||
!(IS_2413(ah) || IS_5413(ah) || IS_2417(ah)))
|
||||
ar5212RequestRfgain(ah);
|
||||
if (longCal) {
|
||||
/* Check noise floor results */
|
||||
ar5212GetNf(ah, ichan);
|
||||
|
||||
/* XXX EAR */
|
||||
} else {
|
||||
/* report up and clear internal state */
|
||||
chan->channelFlags |= CHANNEL_CW_INT;
|
||||
ichan->channelFlags &= ~CHANNEL_CW_INT;
|
||||
if ((ichan->channelFlags & CHANNEL_CW_INT) == 0) {
|
||||
/* Perform cal for 5Ghz channels and any OFDM on 5112 */
|
||||
if (IS_CHAN_5GHZ(chan) ||
|
||||
(IS_RAD5112(ah) && IS_CHAN_OFDM(chan)))
|
||||
ar5212RequestRfgain(ah);
|
||||
} else {
|
||||
/* report up and clear internal state */
|
||||
chan->channelFlags |= CHANNEL_CW_INT;
|
||||
ichan->channelFlags &= ~CHANNEL_CW_INT;
|
||||
}
|
||||
}
|
||||
|
||||
RESTORE_CCK(ah, ichan, ichan_isBmode);
|
||||
RESTORE_CCK(ah, chan, isBmode);
|
||||
|
||||
@ -1136,6 +1119,19 @@ ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
#undef IQ_CAL_TRIES
|
||||
}
|
||||
|
||||
HAL_BOOL
|
||||
ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
{
|
||||
return ar5212PerCalibrationN(ah, chan, 0x1, AH_TRUE, isIQdone);
|
||||
}
|
||||
|
||||
HAL_BOOL
|
||||
ar5212ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
{
|
||||
/* XXX */
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the given reset bit mask into the reset register
|
||||
*/
|
||||
@ -1174,6 +1170,9 @@ ar5212SetResetReg(struct ath_hal *ah, uint32_t resetMask)
|
||||
if (ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
|
||||
(void) OS_REG_READ(ah, AR_ISR_RAC);
|
||||
}
|
||||
|
||||
/* track PHY power state so we don't try to r/w BB registers */
|
||||
AH5212(ah)->ah_phyPowerOn = ((resetMask & AR_RC_BB) == 0);
|
||||
return rt;
|
||||
}
|
||||
|
||||
@ -1383,42 +1382,6 @@ ar5212SetCompRegs(struct ath_hal *ah)
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_ANALOG_START 319 /* XXX */
|
||||
|
||||
/*
|
||||
* Find analog bits of given parameter data and return a reversed value
|
||||
*/
|
||||
static uint32_t
|
||||
ar5212GetRfField(uint32_t *rfBuf, uint32_t numBits, uint32_t firstBit, uint32_t column)
|
||||
{
|
||||
uint32_t reg32 = 0, mask, arrayEntry, lastBit;
|
||||
uint32_t bitPosition, bitsShifted;
|
||||
int32_t bitsLeft;
|
||||
|
||||
HALASSERT(column <= 3);
|
||||
HALASSERT(numBits <= 32);
|
||||
HALASSERT(firstBit + numBits <= MAX_ANALOG_START);
|
||||
|
||||
arrayEntry = (firstBit - 1) / 8;
|
||||
bitPosition = (firstBit - 1) % 8;
|
||||
bitsLeft = numBits;
|
||||
bitsShifted = 0;
|
||||
while (bitsLeft > 0) {
|
||||
lastBit = (bitPosition + bitsLeft > 8) ?
|
||||
(8) : (bitPosition + bitsLeft);
|
||||
mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
|
||||
(column * 8);
|
||||
reg32 |= (((rfBuf[arrayEntry] & mask) >> (column * 8)) >>
|
||||
bitPosition) << bitsShifted;
|
||||
bitsShifted += lastBit - bitPosition;
|
||||
bitsLeft -= (8 - bitPosition);
|
||||
bitPosition = 0;
|
||||
arrayEntry++;
|
||||
}
|
||||
reg32 = ath_hal_reverseBits(reg32, numBits);
|
||||
return reg32;
|
||||
}
|
||||
|
||||
HAL_BOOL
|
||||
ar5212SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
|
||||
const HAL_CHANNEL_INTERNAL *chan)
|
||||
@ -1434,6 +1397,7 @@ ar5212SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
|
||||
HAL_CHANNEL_INTERNAL ichan = *chan;
|
||||
|
||||
HALASSERT(ah->ah_magic == AR5212_MAGIC);
|
||||
HALASSERT(ahp->ah_phyPowerOn);
|
||||
|
||||
SAVE_CCK(ah, &ichan, isBmode);
|
||||
switch (ichan.channelFlags & CHANNEL_ALL_NOTURBO) {
|
||||
@ -1482,13 +1446,15 @@ ar5212SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
|
||||
"%s: Setting fast diversity off.\n", __func__);
|
||||
OS_REG_CLR_BIT(ah,AR_PHY_CCK_DETECT,
|
||||
AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
|
||||
ahp->ah_diversity = AH_FALSE;
|
||||
} else {
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM,
|
||||
"%s: Setting fast diversity on.\n", __func__);
|
||||
OS_REG_SET_BIT(ah,AR_PHY_CCK_DETECT,
|
||||
AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
|
||||
ahp->ah_diversity = AH_TRUE;
|
||||
}
|
||||
ahp->ah_diversityControl = settings;
|
||||
ahp->ah_antControl = settings;
|
||||
|
||||
OS_REG_WRITE(ah, ANT_SWITCH_TABLE1, antSwitchA);
|
||||
OS_REG_WRITE(ah, ANT_SWITCH_TABLE2, antSwitchB);
|
||||
@ -1502,7 +1468,7 @@ HAL_BOOL
|
||||
ar5212IsSpurChannel(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
{
|
||||
uint32_t clockFreq =
|
||||
((IS_5413(ah) || IS_2413(ah) || IS_5112(ah) || IS_2417(ah)) ? 40 : 32);
|
||||
((IS_5413(ah) || IS_RAD5112_ANY(ah) || IS_2417(ah)) ? 40 : 32);
|
||||
return ( ((chan->channel % clockFreq) != 0)
|
||||
&& (((chan->channel % clockFreq) < 10)
|
||||
|| (((chan->channel) % clockFreq) > 22)) );
|
||||
@ -1534,7 +1500,7 @@ ar5212SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
|
||||
case CHANNEL_A:
|
||||
case CHANNEL_T:
|
||||
arrayMode = headerInfo11A;
|
||||
if (!IS_5112(ah) && !IS_2413(ah) && !IS_5413(ah))
|
||||
if (!IS_RAD5112_ANY(ah) && !IS_2413(ah) && !IS_5413(ah))
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
|
||||
AR_PHY_FRAME_CTL_TX_CLIP,
|
||||
ahp->ah_gainValues.currStep->paramVal[GP_TXCLIP]);
|
||||
@ -1556,7 +1522,7 @@ ar5212SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
|
||||
AR_PHY_BIS(ah, 68, 0xFFFFFC06,
|
||||
(ee->ee_antennaControl[0][arrayMode] << 4) | 0x1);
|
||||
|
||||
ar5212SetAntennaSwitchInternal(ah, ahp->ah_diversityControl, chan);
|
||||
ar5212SetAntennaSwitchInternal(ah, ahp->ah_antControl, chan);
|
||||
|
||||
/* Set the Noise Floor Thresh on ar5211 devices */
|
||||
OS_REG_WRITE(ah, AR_PHY(90),
|
||||
@ -2566,278 +2532,16 @@ ar5212GetLowerUpperValues(uint16_t v, uint16_t *lp, uint16_t listSize,
|
||||
HALASSERT(AH_FALSE); /* should not reach here */
|
||||
}
|
||||
|
||||
static const GAIN_OPTIMIZATION_LADDER gainLadder = {
|
||||
9, /* numStepsInLadder */
|
||||
4, /* defaultStepNum */
|
||||
{ { {4, 1, 1, 1}, 6, "FG8"},
|
||||
{ {4, 0, 1, 1}, 4, "FG7"},
|
||||
{ {3, 1, 1, 1}, 3, "FG6"},
|
||||
{ {4, 0, 0, 1}, 1, "FG5"},
|
||||
{ {4, 1, 1, 0}, 0, "FG4"}, /* noJack */
|
||||
{ {4, 0, 1, 0}, -2, "FG3"}, /* halfJack */
|
||||
{ {3, 1, 1, 0}, -3, "FG2"}, /* clip3 */
|
||||
{ {4, 0, 0, 0}, -4, "FG1"}, /* noJack */
|
||||
{ {2, 1, 1, 0}, -6, "FG0"} /* clip2 */
|
||||
}
|
||||
};
|
||||
|
||||
const static GAIN_OPTIMIZATION_LADDER gainLadder5112 = {
|
||||
8, /* numStepsInLadder */
|
||||
1, /* defaultStepNum */
|
||||
{ { {3, 0,0,0, 0,0,0}, 6, "FG7"}, /* most fixed gain */
|
||||
{ {2, 0,0,0, 0,0,0}, 0, "FG6"},
|
||||
{ {1, 0,0,0, 0,0,0}, -3, "FG5"},
|
||||
{ {0, 0,0,0, 0,0,0}, -6, "FG4"},
|
||||
{ {0, 1,1,0, 0,0,0}, -8, "FG3"},
|
||||
{ {0, 1,1,0, 1,1,0}, -10, "FG2"},
|
||||
{ {0, 1,0,1, 1,1,0}, -13, "FG1"},
|
||||
{ {0, 1,0,1, 1,0,1}, -16, "FG0"}, /* least fixed gain */
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the gain structure to good values
|
||||
*/
|
||||
void
|
||||
ar5212InitializeGainValues(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
GAIN_VALUES *gv = &ahp->ah_gainValues;
|
||||
|
||||
/* initialize gain optimization values */
|
||||
if (IS_5112(ah)) {
|
||||
gv->currStepNum = gainLadder5112.defaultStepNum;
|
||||
gv->currStep =
|
||||
&gainLadder5112.optStep[gainLadder5112.defaultStepNum];
|
||||
gv->active = AH_TRUE;
|
||||
gv->loTrig = 20;
|
||||
gv->hiTrig = 85;
|
||||
} else {
|
||||
gv->currStepNum = gainLadder.defaultStepNum;
|
||||
gv->currStep = &gainLadder.optStep[gainLadder.defaultStepNum];
|
||||
gv->active = AH_TRUE;
|
||||
gv->loTrig = 20;
|
||||
gv->hiTrig = 35;
|
||||
}
|
||||
}
|
||||
|
||||
static HAL_BOOL
|
||||
ar5212InvalidGainReadback(struct ath_hal *ah, GAIN_VALUES *gv)
|
||||
{
|
||||
uint32_t gStep, g, mixOvr;
|
||||
uint32_t L1, L2, L3, L4;
|
||||
|
||||
if (IS_5112(ah)) {
|
||||
mixOvr = ar5212GetRfField(ar5212GetRfBank(ah, 7), 1, 36, 0);
|
||||
L1 = 0;
|
||||
L2 = 107;
|
||||
L3 = 0;
|
||||
L4 = 107;
|
||||
if (mixOvr == 1) {
|
||||
L2 = 83;
|
||||
L4 = 83;
|
||||
gv->hiTrig = 55;
|
||||
}
|
||||
} else {
|
||||
gStep = ar5212GetRfField(ar5212GetRfBank(ah, 7), 6, 37, 0);
|
||||
|
||||
L1 = 0;
|
||||
L2 = (gStep == 0x3f) ? 50 : gStep + 4;
|
||||
L3 = (gStep != 0x3f) ? 0x40 : L1;
|
||||
L4 = L3 + 50;
|
||||
|
||||
gv->loTrig = L1 + (gStep == 0x3f ? DYN_ADJ_LO_MARGIN : 0);
|
||||
/* never adjust if != 0x3f */
|
||||
gv->hiTrig = L4 - (gStep == 0x3f ? DYN_ADJ_UP_MARGIN : -5);
|
||||
}
|
||||
g = gv->currGain;
|
||||
|
||||
return !((g >= L1 && g<= L2) || (g >= L3 && g <= L4));
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable the probe gain check on the next packet
|
||||
*/
|
||||
static void
|
||||
ar5212RequestRfgain(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
uint32_t probePowerIndex;
|
||||
|
||||
/* Enable the gain readback probe */
|
||||
probePowerIndex = ahp->ah_ofdmTxPower + ahp->ah_txPowerIndexOffset;
|
||||
OS_REG_WRITE(ah, AR_PHY_PAPD_PROBE,
|
||||
SM(probePowerIndex, AR_PHY_PAPD_PROBE_POWERTX)
|
||||
| AR_PHY_PAPD_PROBE_NEXT_TX);
|
||||
|
||||
ahp->ah_rfgainState = HAL_RFGAIN_READ_REQUESTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exported call to check for a recent gain reading and return
|
||||
* the current state of the thermal calibration gain engine.
|
||||
*/
|
||||
HAL_RFGAIN
|
||||
ar5212GetRfgain(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
GAIN_VALUES *gv = &ahp->ah_gainValues;
|
||||
uint32_t rddata, probeType;
|
||||
|
||||
if (!gv->active)
|
||||
return HAL_RFGAIN_INACTIVE;
|
||||
|
||||
if (ahp->ah_rfgainState == HAL_RFGAIN_READ_REQUESTED) {
|
||||
/* Caller had asked to setup a new reading. Check it. */
|
||||
rddata = OS_REG_READ(ah, AR_PHY_PAPD_PROBE);
|
||||
|
||||
if ((rddata & AR_PHY_PAPD_PROBE_NEXT_TX) == 0) {
|
||||
/* bit got cleared, we have a new reading. */
|
||||
gv->currGain = rddata >> AR_PHY_PAPD_PROBE_GAINF_S;
|
||||
probeType = MS(rddata, AR_PHY_PAPD_PROBE_TYPE);
|
||||
if (probeType == AR_PHY_PAPD_PROBE_TYPE_CCK) {
|
||||
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
|
||||
|
||||
HALASSERT(IS_5112(ah));
|
||||
HALASSERT(ah->ah_magic == AR5212_MAGIC);
|
||||
if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2)
|
||||
gv->currGain += ee->ee_cckOfdmGainDelta;
|
||||
else
|
||||
gv->currGain += PHY_PROBE_CCK_CORRECTION;
|
||||
}
|
||||
if (IS_5112(ah)) {
|
||||
ar5212GetGainFCorrection(ah);
|
||||
if (gv->currGain >= gv->gainFCorrection)
|
||||
gv->currGain -= gv->gainFCorrection;
|
||||
else
|
||||
gv->currGain = 0;
|
||||
}
|
||||
/* inactive by default */
|
||||
ahp->ah_rfgainState = HAL_RFGAIN_INACTIVE;
|
||||
|
||||
if (!ar5212InvalidGainReadback(ah, gv) &&
|
||||
ar5212IsGainAdjustNeeded(ah, gv) &&
|
||||
ar5212AdjustGain(ah, gv) > 0) {
|
||||
/*
|
||||
* Change needed. Copy ladder info
|
||||
* into eeprom info.
|
||||
*/
|
||||
ahp->ah_rfgainState = HAL_RFGAIN_NEED_CHANGE;
|
||||
/* for ap51 */
|
||||
ahp->ah_cwCalRequire = AH_TRUE;
|
||||
/* Request IQ recalibration for temperature chang */
|
||||
ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ahp->ah_rfgainState;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if our readback gain level sits within the linear
|
||||
* region of our current variable attenuation window
|
||||
*/
|
||||
static HAL_BOOL
|
||||
ar5212IsGainAdjustNeeded(struct ath_hal *ah, const GAIN_VALUES *gv)
|
||||
{
|
||||
return (gv->currGain <= gv->loTrig || gv->currGain >= gv->hiTrig);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the rabbit ears in the correct direction.
|
||||
*/
|
||||
static int32_t
|
||||
ar5212AdjustGain(struct ath_hal *ah, GAIN_VALUES *gv)
|
||||
{
|
||||
const GAIN_OPTIMIZATION_LADDER *gl;
|
||||
|
||||
if (IS_5112(ah))
|
||||
gl = &gainLadder5112;
|
||||
else
|
||||
gl = &gainLadder;
|
||||
gv->currStep = &gl->optStep[gv->currStepNum];
|
||||
if (gv->currGain >= gv->hiTrig) {
|
||||
if (gv->currStepNum == 0) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: Max gain limit.\n",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM,
|
||||
"%s: Adding gain: currG=%d [%s] --> ",
|
||||
__func__, gv->currGain, gv->currStep->stepName);
|
||||
gv->targetGain = gv->currGain;
|
||||
while (gv->targetGain >= gv->hiTrig && gv->currStepNum > 0) {
|
||||
gv->targetGain -= 2 * (gl->optStep[--(gv->currStepNum)].stepGain -
|
||||
gv->currStep->stepGain);
|
||||
gv->currStep = &gl->optStep[gv->currStepNum];
|
||||
}
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "targG=%d [%s]\n",
|
||||
gv->targetGain, gv->currStep->stepName);
|
||||
return 1;
|
||||
}
|
||||
if (gv->currGain <= gv->loTrig) {
|
||||
if (gv->currStepNum == gl->numStepsInLadder-1) {
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM,
|
||||
"%s: Min gain limit.\n", __func__);
|
||||
return -2;
|
||||
}
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM,
|
||||
"%s: Deducting gain: currG=%d [%s] --> ",
|
||||
__func__, gv->currGain, gv->currStep->stepName);
|
||||
gv->targetGain = gv->currGain;
|
||||
while (gv->targetGain <= gv->loTrig &&
|
||||
gv->currStepNum < (gl->numStepsInLadder - 1)) {
|
||||
gv->targetGain -= 2 *
|
||||
(gl->optStep[++(gv->currStepNum)].stepGain - gv->currStep->stepGain);
|
||||
gv->currStep = &gl->optStep[gv->currStepNum];
|
||||
}
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "targG=%d [%s]\n",
|
||||
gv->targetGain, gv->currStep->stepName);
|
||||
return 2;
|
||||
}
|
||||
return 0; /* caller didn't call needAdjGain first */
|
||||
}
|
||||
|
||||
/*
|
||||
* Read rf register to determine if gainF needs correction
|
||||
*/
|
||||
static void
|
||||
ar5212GetGainFCorrection(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
GAIN_VALUES *gv = &ahp->ah_gainValues;
|
||||
|
||||
HALASSERT(IS_RADX112_REV2(ah));
|
||||
|
||||
gv->gainFCorrection = 0;
|
||||
if (ar5212GetRfField(ar5212GetRfBank(ah, 7), 1, 36, 0) == 1) {
|
||||
uint32_t mixGain = gv->currStep->paramVal[0];
|
||||
uint32_t gainStep =
|
||||
ar5212GetRfField(ar5212GetRfBank(ah, 7), 4, 32, 0);
|
||||
switch (mixGain) {
|
||||
case 0 :
|
||||
gv->gainFCorrection = 0;
|
||||
break;
|
||||
case 1 :
|
||||
gv->gainFCorrection = gainStep;
|
||||
break;
|
||||
case 2 :
|
||||
gv->gainFCorrection = 2 * gainStep - 5;
|
||||
break;
|
||||
case 3 :
|
||||
gv->gainFCorrection = 2 * gainStep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform analog "swizzling" of parameters into their location
|
||||
*
|
||||
* NB: used by RF backends
|
||||
*/
|
||||
void
|
||||
ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32, uint32_t numBits,
|
||||
uint32_t firstBit, uint32_t column)
|
||||
{
|
||||
#define MAX_ANALOG_START 319 /* XXX */
|
||||
uint32_t tmp32, mask, arrayEntry, lastBit;
|
||||
int32_t bitPosition, bitsLeft;
|
||||
|
||||
@ -2862,6 +2566,7 @@ ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32, uint32_t numBits,
|
||||
bitPosition = 0;
|
||||
arrayEntry++;
|
||||
}
|
||||
#undef MAX_ANALOG_START
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2881,6 +2586,7 @@ ar5212SetRateDurationTable(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
const HAL_RATE_TABLE *rt;
|
||||
int i;
|
||||
|
||||
/* NB: band doesn't matter for 1/2 and 1/4 rate */
|
||||
if (IS_CHAN_HALF_RATE(chan)) {
|
||||
rt = ar5212GetRateTable(ah, HAL_MODE_11A_HALF_RATE);
|
||||
} else if (IS_CHAN_QUARTER_RATE(chan)) {
|
||||
@ -2931,6 +2637,8 @@ ar5212SetIFSTiming(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
{
|
||||
uint32_t txLat, rxLat, usec, slot, refClock, eifs, init_usec;
|
||||
|
||||
HALASSERT(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan));
|
||||
|
||||
refClock = OS_REG_READ(ah, AR_USEC) & AR_USEC_USEC32;
|
||||
if (IS_CHAN_HALF_RATE(chan)) {
|
||||
slot = IFS_SLOT_HALF_RATE;
|
||||
@ -2953,7 +2661,5 @@ ar5212SetIFSTiming(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs);
|
||||
OS_REG_RMW_FIELD(ah, AR_D_GBL_IFS_MISC,
|
||||
AR_D_GBL_IFS_MISC_USEC_DURATION, init_usec);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* AH_SUPPORT_AR5212 */
|
||||
|
333
ar5212/ar5212_rfgain.c
Normal file
333
ar5212/ar5212_rfgain.c
Normal file
@ -0,0 +1,333 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
|
||||
* Copyright (c) 2002-2008 Atheros Communications, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5212_rfgain.c,v 1.2 2008/11/19 21:23:01 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
#ifdef AH_SUPPORT_AR5212
|
||||
|
||||
#include "ah.h"
|
||||
#include "ah_internal.h"
|
||||
#include "ah_devid.h"
|
||||
|
||||
#include "ar5212/ar5212.h"
|
||||
#include "ar5212/ar5212reg.h"
|
||||
#include "ar5212/ar5212phy.h"
|
||||
|
||||
#include "ah_eeprom_v3.h"
|
||||
|
||||
static const GAIN_OPTIMIZATION_LADDER gainLadder = {
|
||||
9, /* numStepsInLadder */
|
||||
4, /* defaultStepNum */
|
||||
{ { {4, 1, 1, 1}, 6, "FG8"},
|
||||
{ {4, 0, 1, 1}, 4, "FG7"},
|
||||
{ {3, 1, 1, 1}, 3, "FG6"},
|
||||
{ {4, 0, 0, 1}, 1, "FG5"},
|
||||
{ {4, 1, 1, 0}, 0, "FG4"}, /* noJack */
|
||||
{ {4, 0, 1, 0}, -2, "FG3"}, /* halfJack */
|
||||
{ {3, 1, 1, 0}, -3, "FG2"}, /* clip3 */
|
||||
{ {4, 0, 0, 0}, -4, "FG1"}, /* noJack */
|
||||
{ {2, 1, 1, 0}, -6, "FG0"} /* clip2 */
|
||||
}
|
||||
};
|
||||
|
||||
static const GAIN_OPTIMIZATION_LADDER gainLadder5112 = {
|
||||
8, /* numStepsInLadder */
|
||||
1, /* defaultStepNum */
|
||||
{ { {3, 0,0,0, 0,0,0}, 6, "FG7"}, /* most fixed gain */
|
||||
{ {2, 0,0,0, 0,0,0}, 0, "FG6"},
|
||||
{ {1, 0,0,0, 0,0,0}, -3, "FG5"},
|
||||
{ {0, 0,0,0, 0,0,0}, -6, "FG4"},
|
||||
{ {0, 1,1,0, 0,0,0}, -8, "FG3"},
|
||||
{ {0, 1,1,0, 1,1,0}, -10, "FG2"},
|
||||
{ {0, 1,0,1, 1,1,0}, -13, "FG1"},
|
||||
{ {0, 1,0,1, 1,0,1}, -16, "FG0"}, /* least fixed gain */
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the gain structure to good values
|
||||
*/
|
||||
void
|
||||
ar5212InitializeGainValues(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
GAIN_VALUES *gv = &ahp->ah_gainValues;
|
||||
|
||||
/* initialize gain optimization values */
|
||||
if (IS_RAD5112_ANY(ah)) {
|
||||
gv->currStepNum = gainLadder5112.defaultStepNum;
|
||||
gv->currStep =
|
||||
&gainLadder5112.optStep[gainLadder5112.defaultStepNum];
|
||||
gv->active = AH_TRUE;
|
||||
gv->loTrig = 20;
|
||||
gv->hiTrig = 85;
|
||||
} else {
|
||||
gv->currStepNum = gainLadder.defaultStepNum;
|
||||
gv->currStep = &gainLadder.optStep[gainLadder.defaultStepNum];
|
||||
gv->active = AH_TRUE;
|
||||
gv->loTrig = 20;
|
||||
gv->hiTrig = 35;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_ANALOG_START 319 /* XXX */
|
||||
|
||||
/*
|
||||
* Find analog bits of given parameter data and return a reversed value
|
||||
*/
|
||||
static uint32_t
|
||||
ar5212GetRfField(uint32_t *rfBuf, uint32_t numBits, uint32_t firstBit, uint32_t column)
|
||||
{
|
||||
uint32_t reg32 = 0, mask, arrayEntry, lastBit;
|
||||
uint32_t bitPosition, bitsShifted;
|
||||
int32_t bitsLeft;
|
||||
|
||||
HALASSERT(column <= 3);
|
||||
HALASSERT(numBits <= 32);
|
||||
HALASSERT(firstBit + numBits <= MAX_ANALOG_START);
|
||||
|
||||
arrayEntry = (firstBit - 1) / 8;
|
||||
bitPosition = (firstBit - 1) % 8;
|
||||
bitsLeft = numBits;
|
||||
bitsShifted = 0;
|
||||
while (bitsLeft > 0) {
|
||||
lastBit = (bitPosition + bitsLeft > 8) ?
|
||||
(8) : (bitPosition + bitsLeft);
|
||||
mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
|
||||
(column * 8);
|
||||
reg32 |= (((rfBuf[arrayEntry] & mask) >> (column * 8)) >>
|
||||
bitPosition) << bitsShifted;
|
||||
bitsShifted += lastBit - bitPosition;
|
||||
bitsLeft -= (8 - bitPosition);
|
||||
bitPosition = 0;
|
||||
arrayEntry++;
|
||||
}
|
||||
reg32 = ath_hal_reverseBits(reg32, numBits);
|
||||
return reg32;
|
||||
}
|
||||
|
||||
static HAL_BOOL
|
||||
ar5212InvalidGainReadback(struct ath_hal *ah, GAIN_VALUES *gv)
|
||||
{
|
||||
uint32_t gStep, g, mixOvr;
|
||||
uint32_t L1, L2, L3, L4;
|
||||
|
||||
if (IS_RAD5112_ANY(ah)) {
|
||||
mixOvr = ar5212GetRfField(ar5212GetRfBank(ah, 7), 1, 36, 0);
|
||||
L1 = 0;
|
||||
L2 = 107;
|
||||
L3 = 0;
|
||||
L4 = 107;
|
||||
if (mixOvr == 1) {
|
||||
L2 = 83;
|
||||
L4 = 83;
|
||||
gv->hiTrig = 55;
|
||||
}
|
||||
} else {
|
||||
gStep = ar5212GetRfField(ar5212GetRfBank(ah, 7), 6, 37, 0);
|
||||
|
||||
L1 = 0;
|
||||
L2 = (gStep == 0x3f) ? 50 : gStep + 4;
|
||||
L3 = (gStep != 0x3f) ? 0x40 : L1;
|
||||
L4 = L3 + 50;
|
||||
|
||||
gv->loTrig = L1 + (gStep == 0x3f ? DYN_ADJ_LO_MARGIN : 0);
|
||||
/* never adjust if != 0x3f */
|
||||
gv->hiTrig = L4 - (gStep == 0x3f ? DYN_ADJ_UP_MARGIN : -5);
|
||||
}
|
||||
g = gv->currGain;
|
||||
|
||||
return !((g >= L1 && g<= L2) || (g >= L3 && g <= L4));
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable the probe gain check on the next packet
|
||||
*/
|
||||
void
|
||||
ar5212RequestRfgain(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
uint32_t probePowerIndex;
|
||||
|
||||
/* Enable the gain readback probe */
|
||||
probePowerIndex = ahp->ah_ofdmTxPower + ahp->ah_txPowerIndexOffset;
|
||||
OS_REG_WRITE(ah, AR_PHY_PAPD_PROBE,
|
||||
SM(probePowerIndex, AR_PHY_PAPD_PROBE_POWERTX)
|
||||
| AR_PHY_PAPD_PROBE_NEXT_TX);
|
||||
|
||||
ahp->ah_rfgainState = HAL_RFGAIN_READ_REQUESTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if our readback gain level sits within the linear
|
||||
* region of our current variable attenuation window
|
||||
*/
|
||||
static HAL_BOOL
|
||||
ar5212IsGainAdjustNeeded(struct ath_hal *ah, const GAIN_VALUES *gv)
|
||||
{
|
||||
return (gv->currGain <= gv->loTrig || gv->currGain >= gv->hiTrig);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the rabbit ears in the correct direction.
|
||||
*/
|
||||
static int32_t
|
||||
ar5212AdjustGain(struct ath_hal *ah, GAIN_VALUES *gv)
|
||||
{
|
||||
const GAIN_OPTIMIZATION_LADDER *gl;
|
||||
|
||||
if (IS_RAD5112_ANY(ah))
|
||||
gl = &gainLadder5112;
|
||||
else
|
||||
gl = &gainLadder;
|
||||
gv->currStep = &gl->optStep[gv->currStepNum];
|
||||
if (gv->currGain >= gv->hiTrig) {
|
||||
if (gv->currStepNum == 0) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: Max gain limit.\n",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM,
|
||||
"%s: Adding gain: currG=%d [%s] --> ",
|
||||
__func__, gv->currGain, gv->currStep->stepName);
|
||||
gv->targetGain = gv->currGain;
|
||||
while (gv->targetGain >= gv->hiTrig && gv->currStepNum > 0) {
|
||||
gv->targetGain -= 2 * (gl->optStep[--(gv->currStepNum)].stepGain -
|
||||
gv->currStep->stepGain);
|
||||
gv->currStep = &gl->optStep[gv->currStepNum];
|
||||
}
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "targG=%d [%s]\n",
|
||||
gv->targetGain, gv->currStep->stepName);
|
||||
return 1;
|
||||
}
|
||||
if (gv->currGain <= gv->loTrig) {
|
||||
if (gv->currStepNum == gl->numStepsInLadder-1) {
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM,
|
||||
"%s: Min gain limit.\n", __func__);
|
||||
return -2;
|
||||
}
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM,
|
||||
"%s: Deducting gain: currG=%d [%s] --> ",
|
||||
__func__, gv->currGain, gv->currStep->stepName);
|
||||
gv->targetGain = gv->currGain;
|
||||
while (gv->targetGain <= gv->loTrig &&
|
||||
gv->currStepNum < (gl->numStepsInLadder - 1)) {
|
||||
gv->targetGain -= 2 *
|
||||
(gl->optStep[++(gv->currStepNum)].stepGain - gv->currStep->stepGain);
|
||||
gv->currStep = &gl->optStep[gv->currStepNum];
|
||||
}
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "targG=%d [%s]\n",
|
||||
gv->targetGain, gv->currStep->stepName);
|
||||
return 2;
|
||||
}
|
||||
return 0; /* caller didn't call needAdjGain first */
|
||||
}
|
||||
|
||||
/*
|
||||
* Read rf register to determine if gainF needs correction
|
||||
*/
|
||||
static void
|
||||
ar5212GetGainFCorrection(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
GAIN_VALUES *gv = &ahp->ah_gainValues;
|
||||
|
||||
HALASSERT(IS_RADX112_REV2(ah));
|
||||
|
||||
gv->gainFCorrection = 0;
|
||||
if (ar5212GetRfField(ar5212GetRfBank(ah, 7), 1, 36, 0) == 1) {
|
||||
uint32_t mixGain = gv->currStep->paramVal[0];
|
||||
uint32_t gainStep =
|
||||
ar5212GetRfField(ar5212GetRfBank(ah, 7), 4, 32, 0);
|
||||
switch (mixGain) {
|
||||
case 0 :
|
||||
gv->gainFCorrection = 0;
|
||||
break;
|
||||
case 1 :
|
||||
gv->gainFCorrection = gainStep;
|
||||
break;
|
||||
case 2 :
|
||||
gv->gainFCorrection = 2 * gainStep - 5;
|
||||
break;
|
||||
case 3 :
|
||||
gv->gainFCorrection = 2 * gainStep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Exported call to check for a recent gain reading and return
|
||||
* the current state of the thermal calibration gain engine.
|
||||
*/
|
||||
HAL_RFGAIN
|
||||
ar5212GetRfgain(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
GAIN_VALUES *gv = &ahp->ah_gainValues;
|
||||
uint32_t rddata, probeType;
|
||||
|
||||
if (!gv->active)
|
||||
return HAL_RFGAIN_INACTIVE;
|
||||
|
||||
if (ahp->ah_rfgainState == HAL_RFGAIN_READ_REQUESTED) {
|
||||
/* Caller had asked to setup a new reading. Check it. */
|
||||
rddata = OS_REG_READ(ah, AR_PHY_PAPD_PROBE);
|
||||
|
||||
if ((rddata & AR_PHY_PAPD_PROBE_NEXT_TX) == 0) {
|
||||
/* bit got cleared, we have a new reading. */
|
||||
gv->currGain = rddata >> AR_PHY_PAPD_PROBE_GAINF_S;
|
||||
probeType = MS(rddata, AR_PHY_PAPD_PROBE_TYPE);
|
||||
if (probeType == AR_PHY_PAPD_PROBE_TYPE_CCK) {
|
||||
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
|
||||
|
||||
HALASSERT(IS_RAD5112_ANY(ah));
|
||||
HALASSERT(ah->ah_magic == AR5212_MAGIC);
|
||||
if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2)
|
||||
gv->currGain += ee->ee_cckOfdmGainDelta;
|
||||
else
|
||||
gv->currGain += PHY_PROBE_CCK_CORRECTION;
|
||||
}
|
||||
if (IS_RADX112_REV2(ah)) {
|
||||
ar5212GetGainFCorrection(ah);
|
||||
if (gv->currGain >= gv->gainFCorrection)
|
||||
gv->currGain -= gv->gainFCorrection;
|
||||
else
|
||||
gv->currGain = 0;
|
||||
}
|
||||
/* inactive by default */
|
||||
ahp->ah_rfgainState = HAL_RFGAIN_INACTIVE;
|
||||
|
||||
if (!ar5212InvalidGainReadback(ah, gv) &&
|
||||
ar5212IsGainAdjustNeeded(ah, gv) &&
|
||||
ar5212AdjustGain(ah, gv) > 0) {
|
||||
/*
|
||||
* Change needed. Copy ladder info
|
||||
* into eeprom info.
|
||||
*/
|
||||
ahp->ah_rfgainState = HAL_RFGAIN_NEED_CHANGE;
|
||||
/* for ap51 */
|
||||
ahp->ah_cwCalRequire = AH_TRUE;
|
||||
/* Request IQ recalibration for temperature chang */
|
||||
ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ahp->ah_rfgainState;
|
||||
}
|
||||
#endif /* AH_SUPPORT_AR5212 */
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5212phy.h,v 1.5 2008/11/04 01:08:40 sam Exp $
|
||||
* $Id: ar5212phy.h,v 1.7 2008/11/19 21:23:01 sam Exp $
|
||||
*/
|
||||
#ifndef _DEV_ATH_AR5212PHY_H_
|
||||
#define _DEV_ATH_AR5212PHY_H_
|
||||
@ -113,6 +113,7 @@
|
||||
#define AR_PHY_AGC_CONTROL_CAL 0x00000001 /* do internal calibration */
|
||||
#define AR_PHY_AGC_CONTROL_NF 0x00000002 /* do noise-floor calculation */
|
||||
#define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000 /* Enable noise floor calibration to happen */
|
||||
#define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000 /* Allow Filter calibration */
|
||||
#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 /* Don't update noise floor automatically */
|
||||
|
||||
#define AR_PHY_SFCORR_LOW 0x986C
|
||||
@ -136,16 +137,14 @@
|
||||
#define AR_PHY_SLEEP_CTR_LIMIT 0x9874
|
||||
#define AR_PHY_SLEEP_SCAL 0x9878
|
||||
|
||||
#define AR_PHY_PLL_CTL 0x987c /* PLL control register */
|
||||
#define AR_PHY_PLL_CTL_40 0xaa /* 40 MHz */
|
||||
#define AR_PHY_PLL_CTL_44 0xab /* 44 MHz for 11b, 11g */
|
||||
#define AR_PHY_PLL_CTL_40_HALF 0x1aa /* 40 MHz for 11a, turbos (Half)*/
|
||||
#define AR_PHY_PLL_CTL_40_QUARTER 0x2aa /* 40 MHz for 11a, turbos (Quarter)*/
|
||||
#define AR_PHY_PLL_CTL_44_5112 0xeb /* 44 MHz for 11b, 11g */
|
||||
#define AR_PHY_PLL_CTL_40_5112 0xea /* 40 MHz for 11a, turbos */
|
||||
#define AR_PHY_PLL_CTL_40_5112_HALF 0x1ea /* 40 MHz for 11a, turbos (Half)*/
|
||||
#define AR_PHY_PLL_CTL_40_5112_QUARTER 0x2ea /* 40 MHz for 11a, turbos (Quarter)*/
|
||||
#define AR_PHY_PLL_CTL_40_5413 0x04 /* 40 MHz for 11a, turbos with 5413 */
|
||||
#define AR_PHY_PLL_CTL 0x987c /* PLL control register */
|
||||
#define AR_PHY_PLL_CTL_40 0xaa /* 40 MHz */
|
||||
#define AR_PHY_PLL_CTL_44 0xab /* 44 MHz for 11b, 11g */
|
||||
#define AR_PHY_PLL_CTL_44_5112 0xeb /* 44 MHz for 11b, 11g */
|
||||
#define AR_PHY_PLL_CTL_40_5112 0xea /* 40 MHz for 11a, turbos */
|
||||
#define AR_PHY_PLL_CTL_40_5413 0x04 /* 40 MHz for 11a, turbos with 5413 */
|
||||
#define AR_PHY_PLL_CTL_HALF 0x100 /* Half clock for 1/2 chan width */
|
||||
#define AR_PHY_PLL_CTL_QUARTER 0x200 /* Quarter clock for 1/4 chan width */
|
||||
|
||||
#define AR_PHY_BIN_MASK_1 0x9900
|
||||
#define AR_PHY_BIN_MASK_2 0x9904
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5212reg.h,v 1.4 2008/10/12 17:07:17 sam Exp $
|
||||
* $Id: ar5212reg.h,v 1.5 2008/11/16 06:45:43 sam Exp $
|
||||
*/
|
||||
#ifndef _DEV_ATH_AR5212REG_H_
|
||||
#define _DEV_ATH_AR5212REG_H_
|
||||
@ -762,9 +762,9 @@
|
||||
#define AR_SREV_CRETE_MS 5 /* FCS metal spin */
|
||||
#define AR_SREV_CRETE_MS23 7 /* 2.3 metal spin (6 skipped) */
|
||||
#define AR_SREV_CRETE_23 8 /* 2.3 full tape out */
|
||||
#define AR_SREV_GRIFFIN_LITE 8
|
||||
#define AR_SREV_HAINAN 9
|
||||
#define AR_SREV_CONDOR 11
|
||||
#define AR_SREV_GRIFFIN_LITE 8
|
||||
#define AR_SREV_HAINAN 9
|
||||
#define AR_SREV_CONDOR 11
|
||||
#define AR_SREV_VERSION 0x000000F0 /* Mask for Chip version */
|
||||
#define AR_SREV_VERSION_CRETE 0
|
||||
#define AR_SREV_VERSION_MAUI_1 1
|
||||
@ -773,38 +773,39 @@
|
||||
#define AR_SREV_VERSION_OAHU 4
|
||||
#define AR_SREV_VERSION_VENICE 5
|
||||
#define AR_SREV_VERSION_GRIFFIN 7
|
||||
#define AR_SREV_VERSION_CONDOR 9
|
||||
#define AR_SREV_VERSION_EAGLE 10
|
||||
#define AR_SREV_VERSION_CONDOR 9
|
||||
#define AR_SREV_VERSION_EAGLE 10
|
||||
#define AR_SREV_VERSION_COBRA 11
|
||||
#define AR_SREV_2413 AR_SREV_VERSION_GRIFFIN
|
||||
#define AR_SREV_5413 AR_SREV_VERSION_EAGLE
|
||||
#define AR_SREV_5413 AR_SREV_VERSION_EAGLE
|
||||
#define AR_SREV_2415 AR_SREV_VERSION_COBRA
|
||||
#define AR_SREV_5424 AR_SREV_VERSION_CONDOR
|
||||
#define AR_SREV_2425 14 /* SWAN */
|
||||
#define AR_SREV_2417 15 /* Nala */
|
||||
#define AR_SREV_5424 AR_SREV_VERSION_CONDOR
|
||||
#define AR_SREV_2425 14 /* SWAN */
|
||||
#define AR_SREV_2417 15 /* Nala */
|
||||
#define AR_SREV_OAHU_ES 0 /* Engineering Sample */
|
||||
#define AR_SREV_OAHU_PROD 2 /* Production */
|
||||
|
||||
#define AR_PHYREV_HAINAN 0x43
|
||||
#define AR_ANALOG5REV_HAINAN 0x46
|
||||
#define AR_PHYREV_HAINAN 0x43
|
||||
#define AR_ANALOG5REV_HAINAN 0x46
|
||||
|
||||
#define AR_RADIO_SREV_MAJOR 0xF0
|
||||
#define AR_RADIO_SREV_MAJOR 0xF0
|
||||
#define AR_RADIO_SREV_MINOR 0x0F
|
||||
#define AR_RAD5111_SREV_MAJOR 0x10 /* All current supported ar5211 5 GHz
|
||||
radios are rev 0x10 */
|
||||
#define AR_RAD5111_SREV_PROD 0x15 /* Current production level radios */
|
||||
#define AR_RAD2111_SREV_MAJOR 0x20 /* All current supported ar5211 2 GHz
|
||||
radios are rev 0x10 */
|
||||
#define AR_RAD5112_SREV_MAJOR 0x30 /* 5112 Major Rev */
|
||||
#define AR_RAD5112_SREV_2_0 0x35 /* AR5112 Revision 2.0 */
|
||||
#define AR_RAD5112_SREV_2_1 0x36 /* AR5112 Revision 2.1 */
|
||||
#define AR_RAD2112_SREV_MAJOR 0x40 /* 2112 Major Rev */
|
||||
#define AR_RAD2112_SREV_2_0 0x45 /* AR2112 Revision 2.0 */
|
||||
#define AR_RAD2112_SREV_2_1 0x46 /* AR2112 Revision 2.1 */
|
||||
#define AR_RAD2413_SREV_MAJOR 0x50 /* 2413 Major Rev */
|
||||
#define AR_RAD5413_SREV_MAJOR 0x60 /* 5413 Major Rev */
|
||||
#define AR_RAD5424_SREV_MAJOR 0xa0 /* Mostly same as 5413 Major Rev */
|
||||
#define AR_RAD2316_SREV_MAJOR 0x70 /* 2316 Major Rev */
|
||||
#define AR_RAD2317_SREV_MAJOR 0x80 /* 2317 Major Rev */
|
||||
#define AR_RAD5112_SREV_2_0 0x35 /* AR5112 Revision 2.0 */
|
||||
#define AR_RAD2112_SREV_2_0 0x45 /* AR2112 Revision 2.0 */
|
||||
#define AR_RAD5112_SREV_2_1 0x36 /* AR5112 Revision 2.1 */
|
||||
#define AR_RAD2112_SREV_2_1 0x46 /* AR2112 Revision 2.1 */
|
||||
#define AR_RAD5424_SREV_MAJOR 0xa0 /* Mostly same as 5413 Major Rev */
|
||||
|
||||
#define AR_PCIE_PMC_ENA_L1 0x01 /* enable PCIe core enter L1 when
|
||||
d2_sleep_en is asserted */
|
||||
|
@ -45,5 +45,6 @@
|
||||
* is controlled
|
||||
*/
|
||||
#define AR5311_D_MISC_SEQ_NUM_CONTROL 0x01000000 /* seq num local or global */
|
||||
#define AR5311_DIAG_USE_ECO 0x00000400 /* "super secret" enable ECO */
|
||||
|
||||
#endif /* _DEV_ATH_AR5311REG_H_ */
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5413.c,v 1.7 2008/11/10 04:08:03 sam Exp $
|
||||
* $Id: ar5413.c,v 1.8 2008/11/15 22:15:46 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -549,8 +549,11 @@ ar5413SetPowerTable(struct ath_hal *ah,
|
||||
int16_t minCalPower5413_t2;
|
||||
uint16_t *pdadcValues = ahp->ah_pcdacTable;
|
||||
uint16_t gainBoundaries[4];
|
||||
uint32_t i, reg32, regoffset, tpcrg1;
|
||||
int numPdGainsUsed;
|
||||
uint32_t reg32, regoffset;
|
||||
int i, numPdGainsUsed;
|
||||
#ifndef AH_USE_INIPDGAIN
|
||||
uint32_t tpcrg1;
|
||||
#endif
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan 0x%x flag 0x%x\n",
|
||||
__func__, chan->channel,chan->channelFlags);
|
||||
@ -572,10 +575,16 @@ ar5413SetPowerTable(struct ath_hal *ah,
|
||||
&minCalPower5413_t2,gainBoundaries, rfXpdGain, pdadcValues);
|
||||
HALASSERT(1 <= numPdGainsUsed && numPdGainsUsed <= 3);
|
||||
|
||||
#if 0
|
||||
#ifdef AH_USE_INIPDGAIN
|
||||
/*
|
||||
* Use pd_gains curve from eeprom; Atheros always uses
|
||||
* the default curve from the ini file but some vendors
|
||||
* (e.g. Zcomax) want to override this curve and not
|
||||
* honoring their settings results in tx power 5dBm low.
|
||||
*/
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
|
||||
(pRawDataset->pDataPerChannel[0].numPdGains - 1));
|
||||
#endif
|
||||
#else
|
||||
tpcrg1 = OS_REG_READ(ah, AR_PHY_TPCRG1);
|
||||
tpcrg1 = (tpcrg1 &~ AR_PHY_TPCRG1_NUM_PD_GAIN)
|
||||
| SM(numPdGainsUsed-1, AR_PHY_TPCRG1_NUM_PD_GAIN);
|
||||
@ -600,6 +609,7 @@ ar5413SetPowerTable(struct ath_hal *ah,
|
||||
__func__, OS_REG_READ(ah, AR_PHY_TPCRG1), tpcrg1);
|
||||
#endif
|
||||
OS_REG_WRITE(ah, AR_PHY_TPCRG1, tpcrg1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note the pdadc table may not start at 0 dBm power, could be
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5312.h,v 1.4 2008/11/10 04:08:04 sam Exp $
|
||||
* $Id: ar5312.h,v 1.5 2008/11/22 07:37:40 sam Exp $
|
||||
*/
|
||||
#ifndef _ATH_AR5312_H_
|
||||
#define _ATH_AR5312_H_
|
||||
@ -30,15 +30,13 @@
|
||||
(((const struct ar531x_config *)((_ah)->ah_st))->radio)
|
||||
|
||||
#define IS_5312_2_X(ah) \
|
||||
(((AH_PRIVATE(ah)->ah_macVersion) == AR_SREV_VERSION_VENICE) && \
|
||||
(((AH_PRIVATE(ah)->ah_macRev) == 2) || ((AH_PRIVATE(ah)->ah_macRev) == 7)))
|
||||
|
||||
(AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE && \
|
||||
(AH_PRIVATE(ah)->ah_macRev == 2 || AH_PRIVATE(ah)->ah_macRev == 7))
|
||||
#define IS_5315(ah) \
|
||||
((AH_PRIVATE(ah)->ah_devid == AR5212_AR2315_REV6) || \
|
||||
(AH_PRIVATE(ah)->ah_devid == AR5212_AR2315_REV7) || \
|
||||
(AH_PRIVATE(ah)->ah_devid == AR5212_AR2317_REV1) || \
|
||||
(AH_PRIVATE(ah)->ah_devid == AR5212_AR2317_REV2))
|
||||
|
||||
(AH_PRIVATE(ah)->ah_devid == AR5212_AR2315_REV6 || \
|
||||
AH_PRIVATE(ah)->ah_devid == AR5212_AR2315_REV7 || \
|
||||
AH_PRIVATE(ah)->ah_devid == AR5212_AR2317_REV1 || \
|
||||
AH_PRIVATE(ah)->ah_devid == AR5212_AR2317_REV2)
|
||||
|
||||
extern struct ath_hal * ar5312Attach(uint16_t devid, HAL_SOFTC sc,
|
||||
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status);
|
||||
@ -76,5 +74,6 @@ extern HAL_BOOL ar5312GetPowerStatus(struct ath_hal *ah);
|
||||
|
||||
/* BSP functions */
|
||||
extern HAL_BOOL ar5312EepromRead(struct ath_hal *, u_int off, uint16_t *data);
|
||||
extern HAL_BOOL ar5312EepromWrite(struct ath_hal *, u_int off, uint16_t data);
|
||||
|
||||
#endif /* _ATH_AR3212_H_ */
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5312_attach.c,v 1.6 2008/11/10 04:08:04 sam Exp $
|
||||
* $Id: ar5312_attach.c,v 1.8 2008/11/27 22:30:03 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -39,13 +39,6 @@
|
||||
#define AH_5212_COMMON
|
||||
#include "ar5212/ar5212.ini"
|
||||
|
||||
/*
|
||||
* These are not valid 2.4 channels, either we change these
|
||||
* or we need to change the coding to accept these
|
||||
*/
|
||||
static const uint16_t channels11b[] = { 2412, 2447, 2484 };
|
||||
static const uint16_t channels11g[] = { 2312, 2412, 2484 };
|
||||
|
||||
static HAL_BOOL ar5312GetMacAddr(struct ath_hal *ah);
|
||||
|
||||
static void
|
||||
@ -217,7 +210,7 @@ ar5312Attach(uint16_t devid, HAL_SOFTC sc,
|
||||
goto bad;
|
||||
}
|
||||
#endif
|
||||
if (IS_5112(ah) && !IS_RADX112_REV2(ah)) {
|
||||
if (IS_RAD5112(ah) && !IS_RADX112_REV2(ah)) {
|
||||
#ifdef AH_DEBUG
|
||||
ath_hal_printf(ah, "%s: 5112 Rev 1 is not supported by this "
|
||||
"driver (analog5GhzRev 0x%x)\n", __func__,
|
||||
@ -293,13 +286,13 @@ ar5312Attach(uint16_t devid, HAL_SOFTC sc,
|
||||
#else
|
||||
ecode = HAL_ENOTSUPP;
|
||||
#endif
|
||||
else if (IS_5112(ah))
|
||||
else if (IS_RAD5112_ANY(ah))
|
||||
#ifdef AH_SUPPORT_5112
|
||||
rfStatus = ar5112RfAttach(ah, &ecode);
|
||||
#else
|
||||
ecode = HAL_ENOTSUPP;
|
||||
#endif
|
||||
else
|
||||
else if (IS_RAD5111(ah))
|
||||
#ifdef AH_SUPPORT_5111
|
||||
rfStatus = ar5111RfAttach(ah, &ecode);
|
||||
#else
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5312_misc.c,v 1.3 2008/11/10 04:08:04 sam Exp $
|
||||
* $Id: ar5312_misc.c,v 1.4 2008/11/22 07:40:15 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -108,7 +108,8 @@ ar5312SetupClock(struct ath_hal *ah, HAL_OPMODE opmode)
|
||||
OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0c);
|
||||
OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x03);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0x05);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKPD, (IS_5112(ah) || IS_2413(ah)) ? 0x14 : 0x18);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
|
||||
IS_RAD5112_ANY(ah) ? 0x14 : 0x18);
|
||||
|
||||
OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32, 1);
|
||||
OS_REG_WRITE(ah, AR_TSF_PARM, 61); /* 32 KHz TSF incr */
|
||||
@ -116,7 +117,7 @@ ar5312SetupClock(struct ath_hal *ah, HAL_OPMODE opmode)
|
||||
} else {
|
||||
OS_REG_WRITE(ah, AR_TSF_PARM, 1); /* 32 MHz TSF incr */
|
||||
OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32,
|
||||
(IS_5112(ah) || IS_2413(ah)) ? 39 : 31);
|
||||
IS_RAD5112_ANY(ah) ? 39 : 31);
|
||||
|
||||
OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f);
|
||||
OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT, 0x7f);
|
||||
@ -128,7 +129,8 @@ ar5312SetupClock(struct ath_hal *ah, HAL_OPMODE opmode)
|
||||
OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
|
||||
OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x0c);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0xff);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKPD, (IS_5112(ah) || IS_2413(ah)) ? 0x14 : 0x18);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
|
||||
IS_RAD5112_ANY(ah) ? 0x14 : 0x18);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -143,7 +145,7 @@ ar5312RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode)
|
||||
/* # Set sleep clock rate back to 32 MHz. */
|
||||
OS_REG_WRITE(ah, AR_TSF_PARM, 1); /* 32 MHz TSF incr */
|
||||
OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32,
|
||||
(IS_5112(ah) || IS_2413(ah)) ? 39 : 31);
|
||||
IS_RAD5112_ANY(ah) ? 39 : 31);
|
||||
|
||||
/*
|
||||
* Restore BB registers to power-on defaults
|
||||
@ -157,7 +159,8 @@ ar5312RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode)
|
||||
OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
|
||||
OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x0c);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0xff);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKPD, (IS_5112(ah) || IS_2413(ah)) ? 0x14 : 0x18);
|
||||
OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
|
||||
IS_RAD5112_ANY(ah) ? 0x14 : 0x18);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5312_reset.c,v 1.9 2008/11/10 04:08:04 sam Exp $
|
||||
* $Id: ar5312_reset.c,v 1.10 2008/11/22 07:41:37 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -173,7 +173,7 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
|
||||
* -channel change requested - so it's not the initial reset.
|
||||
* -it's not a change to the current channel - often called when switching modes
|
||||
* on a channel
|
||||
* -the modes of the previous and requested channel are the same
|
||||
* -the modes of the previous and requested channel are the same - some ugly code for XR
|
||||
*/
|
||||
if (bChannelChange &&
|
||||
(AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
|
||||
@ -406,8 +406,9 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
|
||||
ar5212SetRateDurationTable(ah, chan);
|
||||
|
||||
/* Set Tx frame start to tx data start delay */
|
||||
if (IS_5112(ah) && (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan) ||
|
||||
IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan))) {
|
||||
if (IS_RAD5112_ANY(ah) &&
|
||||
(IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan) ||
|
||||
IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan))) {
|
||||
txFrm2TxDStart =
|
||||
(IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) ?
|
||||
TX_FRAME_D_START_HALF_RATE:
|
||||
@ -679,7 +680,7 @@ ar5312ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
if (chan != AH_NULL) { /* NB: can be null during attach */
|
||||
uint32_t rfMode, phyPLL = 0, curPhyPLL, turbo;
|
||||
|
||||
if (IS_5112(ah) || IS_2413(ah)) {
|
||||
if (IS_RAD5112_ANY(ah)) {
|
||||
rfMode = AR_PHY_MODE_AR5112;
|
||||
if (!IS_5315(ah)) {
|
||||
if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
|
||||
@ -694,31 +695,25 @@ ar5312ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
|
||||
if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
|
||||
phyPLL = AR_PHY_PLL_CTL_44_5112;
|
||||
} else {
|
||||
if (IS_CHAN_HALF_RATE(chan)) {
|
||||
phyPLL = AR_PHY_PLL_CTL_40_5112_HALF;
|
||||
} else if (IS_CHAN_QUARTER_RATE(chan)) {
|
||||
phyPLL = AR_PHY_PLL_CTL_40_5112_QUARTER;
|
||||
} else {
|
||||
phyPLL = AR_PHY_PLL_CTL_40_5112;
|
||||
}
|
||||
}
|
||||
else
|
||||
phyPLL = AR_PHY_PLL_CTL_40_5112;
|
||||
if (IS_CHAN_HALF_RATE(chan))
|
||||
phyPLL |= AR_PHY_PLL_CTL_HALF;
|
||||
else if (IS_CHAN_QUARTER_RATE(chan))
|
||||
phyPLL |= AR_PHY_PLL_CTL_QUARTER;
|
||||
}
|
||||
} else {
|
||||
rfMode = AR_PHY_MODE_AR5111;
|
||||
if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
|
||||
if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
|
||||
phyPLL = AR_PHY_PLL_CTL_44;
|
||||
} else {
|
||||
if (IS_CHAN_HALF_RATE(chan)) {
|
||||
phyPLL = AR_PHY_PLL_CTL_40_HALF;
|
||||
} else if (IS_CHAN_QUARTER_RATE(chan)) {
|
||||
phyPLL = AR_PHY_PLL_CTL_40_QUARTER;
|
||||
} else {
|
||||
phyPLL = AR_PHY_PLL_CTL_40;
|
||||
}
|
||||
}
|
||||
else
|
||||
phyPLL = AR_PHY_PLL_CTL_40;
|
||||
if (IS_CHAN_HALF_RATE(chan))
|
||||
phyPLL = AR_PHY_PLL_CTL_HALF;
|
||||
else if (IS_CHAN_QUARTER_RATE(chan))
|
||||
phyPLL = AR_PHY_PLL_CTL_QUARTER;
|
||||
}
|
||||
if (IS_CHAN_OFDM(chan) && (IS_CHAN_CCK(chan) ||
|
||||
IS_CHAN_G(chan)))
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar2133.c,v 1.10 2008/11/10 04:08:04 sam Exp $
|
||||
* $Id: ar2133.c,v 1.13 2008/11/11 00:11:30 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -330,6 +330,64 @@ ar2133GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan, int16_t *maxP
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[])
|
||||
{
|
||||
struct ath_hal_5416 *ahp = AH5416(ah);
|
||||
int16_t nf;
|
||||
|
||||
switch (ahp->ah_rx_chainmask) {
|
||||
case 0x7:
|
||||
nf = MS(OS_REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
|
||||
if (nf & 0x100)
|
||||
nf = 0 - ((nf ^ 0x1ff) + 1);
|
||||
HALDEBUG(ah, HAL_DEBUG_NFCAL,
|
||||
"NF calibrated [ctl] [chain 2] is %d\n", nf);
|
||||
nfarray[4] = nf;
|
||||
|
||||
nf = MS(OS_REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR);
|
||||
if (nf & 0x100)
|
||||
nf = 0 - ((nf ^ 0x1ff) + 1);
|
||||
HALDEBUG(ah, HAL_DEBUG_NFCAL,
|
||||
"NF calibrated [ext] [chain 2] is %d\n", nf);
|
||||
nfarray[5] = nf;
|
||||
/* fall thru... */
|
||||
case 0x3:
|
||||
case 0x5:
|
||||
nf = MS(OS_REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR);
|
||||
if (nf & 0x100)
|
||||
nf = 0 - ((nf ^ 0x1ff) + 1);
|
||||
HALDEBUG(ah, HAL_DEBUG_NFCAL,
|
||||
"NF calibrated [ctl] [chain 1] is %d\n", nf);
|
||||
nfarray[2] = nf;
|
||||
|
||||
|
||||
nf = MS(OS_REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR);
|
||||
if (nf & 0x100)
|
||||
nf = 0 - ((nf ^ 0x1ff) + 1);
|
||||
HALDEBUG(ah, HAL_DEBUG_NFCAL,
|
||||
"NF calibrated [ext] [chain 1] is %d\n", nf);
|
||||
nfarray[3] = nf;
|
||||
/* fall thru... */
|
||||
case 0x1:
|
||||
nf = MS(OS_REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
|
||||
if (nf & 0x100)
|
||||
nf = 0 - ((nf ^ 0x1ff) + 1);
|
||||
HALDEBUG(ah, HAL_DEBUG_NFCAL,
|
||||
"NF calibrated [ctl] [chain 0] is %d\n", nf);
|
||||
nfarray[0] = nf;
|
||||
|
||||
nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
|
||||
if (nf & 0x100)
|
||||
nf = 0 - ((nf ^ 0x1ff) + 1);
|
||||
HALDEBUG(ah, HAL_DEBUG_NFCAL,
|
||||
"NF calibrated [ext] [chain 0] is %d\n", nf);
|
||||
nfarray[1] = nf;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjust NF based on statistical values for 5GHz frequencies.
|
||||
* Stubbed:Not used by Fowl
|
||||
@ -404,6 +462,7 @@ ar2133RfAttach(struct ath_hal *ah, HAL_STATUS *status)
|
||||
* direct call instead of thunking.
|
||||
*/
|
||||
AH_PRIVATE(ah)->ah_getNfAdjust = priv->base.getNfAdjust;
|
||||
AH_PRIVATE(ah)->ah_getNoiseFloor = ar2133GetNoiseFloor;
|
||||
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
131
ar5416/ar5416.h
131
ar5416/ar5416.h
@ -14,19 +14,20 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416.h,v 1.16 2008/11/10 04:08:04 sam Exp $
|
||||
* $Id: ar5416.h,v 1.19 2008/11/11 21:38:13 sam Exp $
|
||||
*/
|
||||
#ifndef _ATH_AR5416_H_
|
||||
#define _ATH_AR5416_H_
|
||||
|
||||
#include "ar5212/ar5212.h"
|
||||
#include "ar5416_cal.h"
|
||||
|
||||
#define AR5416_MAGIC 0x20065416
|
||||
|
||||
enum {
|
||||
HAL_RESET_POWER_ON,
|
||||
HAL_RESET_WARM,
|
||||
HAL_RESET_COLD,
|
||||
HAL_RESET_POWER_ON,
|
||||
HAL_RESET_WARM,
|
||||
HAL_RESET_COLD,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@ -40,71 +41,10 @@ typedef struct {
|
||||
#define AR5416_MAX_RATE_POWER 63
|
||||
#define AR5416_KEYTABLE_SIZE 128
|
||||
|
||||
#define AR5416_NUM_NF_READINGS 6 /* (3 chains * (ctl + ext) */
|
||||
#define AR5416_CCA_MAX_GOOD_VALUE -85
|
||||
#define AR5416_CCA_MAX_HIGH_VALUE -62
|
||||
#define AR5416_CCA_MIN_BAD_VALUE -140
|
||||
|
||||
#define INIT_CAL(_perCal) do { \
|
||||
(_perCal)->calState = CAL_WAITING; \
|
||||
(_perCal)->calNext = AH_NULL; \
|
||||
} while (0)
|
||||
|
||||
#define INSERT_CAL(_ahp, _perCal) do { \
|
||||
if ((_ahp)->ah_cal_last == AH_NULL) { \
|
||||
(_ahp)->ah_cal_list = (_ahp)->ah_cal_last = (_perCal); \
|
||||
((_ahp)->ah_cal_last)->calNext = (_perCal); \
|
||||
} else { \
|
||||
((_ahp)->ah_cal_last)->calNext = (_perCal); \
|
||||
(_ahp)->ah_cal_last = (_perCal); \
|
||||
(_perCal)->calNext = (_ahp)->ah_cal_list; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
typedef enum cal_types {
|
||||
ADC_DC_INIT_CAL = 0x1,
|
||||
ADC_GAIN_CAL = 0x2,
|
||||
ADC_DC_CAL = 0x4,
|
||||
IQ_MISMATCH_CAL = 0x8
|
||||
} HAL_CAL_TYPE;
|
||||
|
||||
/* Calibrate state */
|
||||
typedef enum cal_state {
|
||||
CAL_INACTIVE,
|
||||
CAL_WAITING,
|
||||
CAL_RUNNING,
|
||||
CAL_DONE
|
||||
} HAL_CAL_STATE;
|
||||
|
||||
typedef union {
|
||||
uint32_t u;
|
||||
int32_t s;
|
||||
} HAL_CAL_SAMPLE;
|
||||
|
||||
#define MIN_CAL_SAMPLES 1
|
||||
#define MAX_CAL_SAMPLES 64
|
||||
#define INIT_LOG_COUNT 5
|
||||
#define PER_MIN_LOG_COUNT 2
|
||||
#define PER_MAX_LOG_COUNT 10
|
||||
|
||||
/* Per Calibration data structure */
|
||||
typedef struct per_cal_data {
|
||||
const char *calName; /* for diagnostics */
|
||||
HAL_CAL_TYPE calType; /* Type of calibration */
|
||||
uint32_t calNumSamples; /* # SW samples to collect */
|
||||
uint32_t calCountMax; /* # HW samples to collect */
|
||||
void (*calCollect)(struct ath_hal *); /* Accumulator function */
|
||||
/* Post-processing function */
|
||||
void (*calPostProc)(struct ath_hal *, uint8_t);
|
||||
} HAL_PERCAL_DATA;
|
||||
|
||||
/* List structure for calibration data */
|
||||
typedef struct cal_list {
|
||||
struct cal_list *calNext;
|
||||
HAL_CAL_STATE calState;
|
||||
const HAL_PERCAL_DATA *calData;
|
||||
} HAL_CAL_LIST;
|
||||
|
||||
struct ath_hal_5416 {
|
||||
struct ath_hal_5212 ah_5212;
|
||||
|
||||
@ -119,7 +59,6 @@ struct ath_hal_5416 {
|
||||
HAL_INI_ARRAY ah_ini_addac;
|
||||
|
||||
u_int ah_globaltxtimeout; /* global tx timeout */
|
||||
int ah_clksel;
|
||||
int ah_hangs; /* h/w hangs state */
|
||||
uint8_t ah_keytype[AR5416_KEYTABLE_SIZE];
|
||||
/*
|
||||
@ -130,43 +69,11 @@ struct ath_hal_5416 {
|
||||
uint32_t ah_extBusy;
|
||||
uint32_t ah_rx_chainmask;
|
||||
uint32_t ah_tx_chainmask;
|
||||
/*
|
||||
* Periodic calibration state.
|
||||
*/
|
||||
HAL_CAL_TYPE ah_suppCals;
|
||||
HAL_CAL_LIST ah_iqCalData;
|
||||
HAL_CAL_LIST ah_adcGainCalData;
|
||||
HAL_CAL_LIST ah_adcDcCalInitData;
|
||||
HAL_CAL_LIST ah_adcDcCalData;
|
||||
HAL_CAL_LIST *ah_cal_list;
|
||||
HAL_CAL_LIST *ah_cal_last;
|
||||
HAL_CAL_LIST *ah_cal_curr;
|
||||
#define AR5416_MAX_CHAINS 3 /* XXX dup's eeprom def */
|
||||
HAL_CAL_SAMPLE ah_caldata[4][AR5416_MAX_CHAINS];
|
||||
int ah_calSamples;
|
||||
/*
|
||||
* Noise floor cal histogram support.
|
||||
* XXX be nice to re-use space in ar5212
|
||||
*/
|
||||
struct ar5212NfCalHist ah_nfCalHist[AR5416_NUM_NF_READINGS];
|
||||
|
||||
struct ar5416PerCal ah_cal; /* periodic calibration state */
|
||||
};
|
||||
#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
|
||||
|
||||
/* IQ Cal aliases */
|
||||
#define ah_totalPowerMeasI(i) ah_caldata[0][i].u
|
||||
#define ah_totalPowerMeasQ(i) ah_caldata[1][i].u
|
||||
#define ah_totalIqCorrMeas(i) ah_caldata[2][i].s
|
||||
/* Adc Gain Cal aliases */
|
||||
#define ah_totalAdcIOddPhase(i) ah_caldata[0][i].u
|
||||
#define ah_totalAdcIEvenPhase(i) ah_caldata[1][i].u
|
||||
#define ah_totalAdcQOddPhase(i) ah_caldata[2][i].u
|
||||
#define ah_totalAdcQEvenPhase(i) ah_caldata[3][i].u
|
||||
/* Adc DC Offset Cal aliases */
|
||||
#define ah_totalAdcDcOffsetIOddPhase(i) ah_caldata[0][i].s
|
||||
#define ah_totalAdcDcOffsetIEvenPhase(i) ah_caldata[1][i].s
|
||||
#define ah_totalAdcDcOffsetQOddPhase(i) ah_caldata[2][i].s
|
||||
#define ah_totalAdcDcOffsetQEvenPhase(i) ah_caldata[3][i].s
|
||||
|
||||
#define IS_5416_PCI(ah) ((AH_PRIVATE(ah)->ah_macVersion) == AR_SREV_VERSION_OWL_PCI)
|
||||
#define IS_5416_PCIE(ah) ((AH_PRIVATE(ah)->ah_macVersion) == AR_SREV_VERSION_OWL_PCIE)
|
||||
#undef IS_PCIE
|
||||
@ -187,8 +94,17 @@ extern HAL_BOOL ar5416FillCapabilityInfo(struct ath_hal *ah);
|
||||
#define IS_5GHZ_FAST_CLOCK_EN(_ah, _c) \
|
||||
(IS_CHAN_5GHZ(_c) && ath_hal_eepromGetFlag(ah, AR_EEP_FSTCLK_5G))
|
||||
|
||||
extern HAL_BOOL ar5416AniAttach(struct ath_hal *ah);
|
||||
extern void ar5416AniDetach(struct ath_hal *ah);
|
||||
extern void ar5416AniAttach(struct ath_hal *, const struct ar5212AniParams *,
|
||||
const struct ar5212AniParams *, HAL_BOOL ena);
|
||||
extern void ar5416AniDetach(struct ath_hal *);
|
||||
extern HAL_BOOL ar5416AniControl(struct ath_hal *, HAL_ANI_CMD cmd, int param);
|
||||
extern HAL_BOOL ar5416AniSetParams(struct ath_hal *,
|
||||
const struct ar5212AniParams *, const struct ar5212AniParams *);
|
||||
extern void ar5416ProcessMibIntr(struct ath_hal *, const HAL_NODE_STATS *);
|
||||
extern void ar5416AniPoll(struct ath_hal *, const HAL_NODE_STATS *,
|
||||
HAL_CHANNEL *);
|
||||
extern void ar5416AniReset(struct ath_hal *, HAL_CHANNEL_INTERNAL *,
|
||||
HAL_OPMODE, int);
|
||||
|
||||
extern void ar5416SetBeaconTimers(struct ath_hal *, const HAL_BEACON_TIMERS *);
|
||||
extern void ar5416BeaconInit(struct ath_hal *ah,
|
||||
@ -250,17 +166,6 @@ extern HAL_RFGAIN ar5416GetRfgain(struct ath_hal *ah);
|
||||
extern HAL_BOOL ar5416Disable(struct ath_hal *ah);
|
||||
extern HAL_BOOL ar5416ChipReset(struct ath_hal *ah, HAL_CHANNEL *);
|
||||
extern HAL_BOOL ar5416SetResetReg(struct ath_hal *, uint32_t type);
|
||||
extern HAL_BOOL ar5416PerCalibration(struct ath_hal *, HAL_CHANNEL *,
|
||||
HAL_BOOL *isIQdone);
|
||||
extern void ar5416ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan,
|
||||
HAL_BOOL *isIQdone);
|
||||
extern void ar5416IQCalCollect(struct ath_hal *ah);
|
||||
extern void ar5416IQCalibration(struct ath_hal *ah, uint8_t numChains);
|
||||
extern void ar5416AdcGainCalCollect(struct ath_hal *ah);
|
||||
extern void ar5416AdcGainCalibration(struct ath_hal *ah, uint8_t numChains);
|
||||
extern void ar5416AdcDcCalCollect(struct ath_hal *ah);
|
||||
extern void ar5416AdcDcCalibration(struct ath_hal *ah, uint8_t numChains);
|
||||
extern void ar5416InitNfHistBuff(struct ar5212NfCalHist *h);
|
||||
extern HAL_BOOL ar5416SetTxPowerLimit(struct ath_hal *ah, uint32_t limit);
|
||||
extern HAL_BOOL ar5416GetChipPowerLimits(struct ath_hal *ah,
|
||||
HAL_CHANNEL *chans, uint32_t nchans);
|
||||
|
888
ar5416/ar5416_ani.c
Normal file
888
ar5416/ar5416_ani.c
Normal file
@ -0,0 +1,888 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
|
||||
* Copyright (c) 2002-2008 Atheros Communications, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416_ani.c,v 1.1 2008/11/11 20:46:06 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
#ifdef AH_SUPPORT_AR5416
|
||||
/*
|
||||
* XXX this is virtually the same code as for 5212; we reuse
|
||||
* storage in the 5212 state block; need to refactor.
|
||||
*/
|
||||
#include "ah.h"
|
||||
#include "ah_internal.h"
|
||||
#include "ah_desc.h"
|
||||
|
||||
#include "ar5416/ar5416.h"
|
||||
#include "ar5416/ar5416reg.h"
|
||||
#include "ar5416/ar5416phy.h"
|
||||
|
||||
/*
|
||||
* Anti noise immunity support. We track phy errors and react
|
||||
* to excessive errors by adjusting the noise immunity parameters.
|
||||
*/
|
||||
|
||||
#define HAL_EP_RND(x, mul) \
|
||||
((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
|
||||
#define BEACON_RSSI(ahp) \
|
||||
HAL_EP_RND(ahp->ah_stats.ast_nodestats.ns_avgbrssi, \
|
||||
HAL_RSSI_EP_MULTIPLIER)
|
||||
|
||||
/*
|
||||
* ANI processing tunes radio parameters according to PHY errors
|
||||
* and related information. This is done for for noise and spur
|
||||
* immunity in all operating modes if the device indicates it's
|
||||
* capable at attach time. In addition, when there is a reference
|
||||
* rssi value (e.g. beacon frames from an ap in station mode)
|
||||
* further tuning is done.
|
||||
*
|
||||
* ANI_ENA indicates whether any ANI processing should be done;
|
||||
* this is specified at attach time.
|
||||
*
|
||||
* ANI_ENA_RSSI indicates whether rssi-based processing should
|
||||
* done, this is enabled based on operating mode and is meaningful
|
||||
* only if ANI_ENA is true.
|
||||
*
|
||||
* ANI parameters are typically controlled only by the hal. The
|
||||
* AniControl interface however permits manual tuning through the
|
||||
* diagnostic api.
|
||||
*/
|
||||
#define ANI_ENA(ah) \
|
||||
(AH5212(ah)->ah_procPhyErr & HAL_ANI_ENA)
|
||||
#define ANI_ENA_RSSI(ah) \
|
||||
(AH5212(ah)->ah_procPhyErr & HAL_RSSI_ANI_ENA)
|
||||
|
||||
#define ah_mibStats ah_stats.ast_mibstats
|
||||
|
||||
static void
|
||||
enableAniMIBCounters(struct ath_hal *ah, const struct ar5212AniParams *params)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: Enable mib counters: "
|
||||
"OfdmPhyErrBase 0x%x cckPhyErrBase 0x%x\n",
|
||||
__func__, params->ofdmPhyErrBase, params->cckPhyErrBase);
|
||||
|
||||
OS_REG_WRITE(ah, AR_FILTOFDM, 0);
|
||||
OS_REG_WRITE(ah, AR_FILTCCK, 0);
|
||||
|
||||
OS_REG_WRITE(ah, AR_PHYCNT1, params->ofdmPhyErrBase);
|
||||
OS_REG_WRITE(ah, AR_PHYCNT2, params->cckPhyErrBase);
|
||||
OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
|
||||
OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
|
||||
|
||||
ar5212UpdateMibCounters(ah, &ahp->ah_mibStats); /* save+clear counters*/
|
||||
ar5212EnableMibCounters(ah); /* enable everything */
|
||||
}
|
||||
|
||||
static void
|
||||
disableAniMIBCounters(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI, "Disable MIB counters\n");
|
||||
|
||||
ar5212UpdateMibCounters(ah, &ahp->ah_mibStats); /* save stats */
|
||||
ar5212DisableMibCounters(ah); /* disable everything */
|
||||
|
||||
OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, 0);
|
||||
OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine returns the index into the aniState array that
|
||||
* corresponds to the channel in *chan. If no match is found and the
|
||||
* array is still not fully utilized, a new entry is created for the
|
||||
* channel. We assume the attach function has already initialized the
|
||||
* ah_ani values and only the channel field needs to be set.
|
||||
*/
|
||||
static int
|
||||
ar5416GetAniChannelIndex(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
|
||||
{
|
||||
#define N(a) (sizeof(a) / sizeof(a[0]))
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < N(ahp->ah_ani); i++) {
|
||||
struct ar5212AniState *asp = &ahp->ah_ani[i];
|
||||
if (asp->c.channel == chan->channel)
|
||||
return i;
|
||||
if (asp->c.channel == 0) {
|
||||
asp->c.channel = chan->channel;
|
||||
asp->c.channelFlags = chan->channelFlags;
|
||||
asp->c.privFlags = chan->privFlags;
|
||||
asp->isSetup = AH_FALSE;
|
||||
if (IS_CHAN_2GHZ(chan))
|
||||
asp->params = &ahp->ah_aniParams24;
|
||||
else
|
||||
asp->params = &ahp->ah_aniParams5;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
/* XXX statistic */
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"No more channel states left. Using channel 0\n");
|
||||
return 0; /* XXX gotta return something valid */
|
||||
#undef N
|
||||
}
|
||||
|
||||
static void
|
||||
setPhyErrBase(struct ath_hal *ah, struct ar5212AniParams *params)
|
||||
{
|
||||
if (params->ofdmTrigHigh >= AR_PHY_COUNTMAX) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"OFDM Trigger %d is too high for hw counters, using max\n",
|
||||
params->ofdmTrigHigh);
|
||||
params->ofdmPhyErrBase = 0;
|
||||
} else
|
||||
params->ofdmPhyErrBase = AR_PHY_COUNTMAX - params->ofdmTrigHigh;
|
||||
if (params->cckTrigHigh >= AR_PHY_COUNTMAX) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"CCK Trigger %d is too high for hw counters, using max\n",
|
||||
params->cckTrigHigh);
|
||||
params->cckPhyErrBase = 0;
|
||||
} else
|
||||
params->cckPhyErrBase = AR_PHY_COUNTMAX - params->cckTrigHigh;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup ANI handling. Sets all thresholds and reset the
|
||||
* channel statistics. Note that ar5416AniReset should be
|
||||
* called by ar5416Reset before anything else happens and
|
||||
* that's where we force initial settings.
|
||||
*/
|
||||
void
|
||||
ar5416AniAttach(struct ath_hal *ah, const struct ar5212AniParams *params24,
|
||||
const struct ar5212AniParams *params5, HAL_BOOL enable)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
|
||||
if (params24 != AH_NULL) {
|
||||
OS_MEMCPY(&ahp->ah_aniParams24, params24, sizeof(*params24));
|
||||
setPhyErrBase(ah, &ahp->ah_aniParams24);
|
||||
}
|
||||
if (params5 != AH_NULL) {
|
||||
OS_MEMCPY(&ahp->ah_aniParams5, params5, sizeof(*params5));
|
||||
setPhyErrBase(ah, &ahp->ah_aniParams5);
|
||||
}
|
||||
|
||||
OS_MEMZERO(ahp->ah_ani, sizeof(ahp->ah_ani));
|
||||
/* Enable MIB Counters */
|
||||
enableAniMIBCounters(ah, &ahp->ah_aniParams24 /*XXX*/);
|
||||
|
||||
if (enable) { /* Enable ani now */
|
||||
HALASSERT(params24 != AH_NULL && params5 != AH_NULL);
|
||||
ahp->ah_procPhyErr |= HAL_ANI_ENA;
|
||||
} else {
|
||||
ahp->ah_procPhyErr &= ~HAL_ANI_ENA;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleanup any ANI state setup.
|
||||
*/
|
||||
void
|
||||
ar5416AniDetach(struct ath_hal *ah)
|
||||
{
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI, "Detaching Ani\n");
|
||||
disableAniMIBCounters(ah);
|
||||
}
|
||||
|
||||
/*
|
||||
* Control Adaptive Noise Immunity Parameters
|
||||
*/
|
||||
HAL_BOOL
|
||||
ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
|
||||
{
|
||||
typedef int TABLE[];
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
struct ar5212AniState *aniState = ahp->ah_curani;
|
||||
const struct ar5212AniParams *params = aniState->params;
|
||||
|
||||
OS_MARK(ah, AH_MARK_ANI_CONTROL, cmd);
|
||||
|
||||
switch (cmd) {
|
||||
case HAL_ANI_NOISE_IMMUNITY_LEVEL: {
|
||||
u_int level = param;
|
||||
|
||||
if (level >= params->maxNoiseImmunityLevel) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: level out of range (%u > %u)\n",
|
||||
__func__, level, params->maxNoiseImmunityLevel);
|
||||
return AH_FALSE;
|
||||
}
|
||||
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
|
||||
AR_PHY_DESIRED_SZ_TOT_DES, params->totalSizeDesired[level]);
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
|
||||
AR_PHY_AGC_CTL1_COARSE_LOW, params->coarseLow[level]);
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
|
||||
AR_PHY_AGC_CTL1_COARSE_HIGH, params->coarseHigh[level]);
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
|
||||
AR_PHY_FIND_SIG_FIRPWR, params->firpwr[level]);
|
||||
|
||||
if (level > aniState->noiseImmunityLevel)
|
||||
ahp->ah_stats.ast_ani_niup++;
|
||||
else if (level < aniState->noiseImmunityLevel)
|
||||
ahp->ah_stats.ast_ani_nidown++;
|
||||
aniState->noiseImmunityLevel = level;
|
||||
break;
|
||||
}
|
||||
case HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION: {
|
||||
static const TABLE m1ThreshLow = { 127, 50 };
|
||||
static const TABLE m2ThreshLow = { 127, 40 };
|
||||
static const TABLE m1Thresh = { 127, 0x4d };
|
||||
static const TABLE m2Thresh = { 127, 0x40 };
|
||||
static const TABLE m2CountThr = { 31, 16 };
|
||||
static const TABLE m2CountThrLow = { 63, 48 };
|
||||
u_int on = param ? 1 : 0;
|
||||
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_M1_THRESH_LOW, m1ThreshLow[on]);
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_M2_THRESH_LOW, m2ThreshLow[on]);
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
AR_PHY_SFCORR_M1_THRESH, m1Thresh[on]);
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
AR_PHY_SFCORR_M2_THRESH, m2Thresh[on]);
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
AR_PHY_SFCORR_M2COUNT_THR, m2CountThr[on]);
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, m2CountThrLow[on]);
|
||||
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLow[on]);
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLow[on]);
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
AR_PHY_SFCORR_EXT_M1_THRESH, m1Thresh[on]);
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
AR_PHY_SFCORR_EXT_M2_THRESH, m2Thresh[on]);
|
||||
|
||||
if (on) {
|
||||
OS_REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
||||
} else {
|
||||
OS_REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
||||
}
|
||||
if (on)
|
||||
ahp->ah_stats.ast_ani_ofdmon++;
|
||||
else
|
||||
ahp->ah_stats.ast_ani_ofdmoff++;
|
||||
aniState->ofdmWeakSigDetectOff = !on;
|
||||
break;
|
||||
}
|
||||
case HAL_ANI_CCK_WEAK_SIGNAL_THR: {
|
||||
static const TABLE weakSigThrCck = { 8, 6 };
|
||||
u_int high = param ? 1 : 0;
|
||||
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
|
||||
AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, weakSigThrCck[high]);
|
||||
if (high)
|
||||
ahp->ah_stats.ast_ani_cckhigh++;
|
||||
else
|
||||
ahp->ah_stats.ast_ani_ccklow++;
|
||||
aniState->cckWeakSigThreshold = high;
|
||||
break;
|
||||
}
|
||||
case HAL_ANI_FIRSTEP_LEVEL: {
|
||||
u_int level = param;
|
||||
|
||||
if (level >= params->maxFirstepLevel) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: level out of range (%u > %u)\n",
|
||||
__func__, level, params->maxFirstepLevel);
|
||||
return AH_FALSE;
|
||||
}
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
|
||||
AR_PHY_FIND_SIG_FIRSTEP, params->firstep[level]);
|
||||
if (level > aniState->firstepLevel)
|
||||
ahp->ah_stats.ast_ani_stepup++;
|
||||
else if (level < aniState->firstepLevel)
|
||||
ahp->ah_stats.ast_ani_stepdown++;
|
||||
aniState->firstepLevel = level;
|
||||
break;
|
||||
}
|
||||
case HAL_ANI_SPUR_IMMUNITY_LEVEL: {
|
||||
u_int level = param;
|
||||
|
||||
if (level >= params->maxSpurImmunityLevel) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: level out of range (%u > %u)\n",
|
||||
__func__, level, params->maxSpurImmunityLevel);
|
||||
return AH_FALSE;
|
||||
}
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5,
|
||||
AR_PHY_TIMING5_CYCPWR_THR1, params->cycPwrThr1[level]);
|
||||
if (level > aniState->spurImmunityLevel)
|
||||
ahp->ah_stats.ast_ani_spurup++;
|
||||
else if (level < aniState->spurImmunityLevel)
|
||||
ahp->ah_stats.ast_ani_spurdown++;
|
||||
aniState->spurImmunityLevel = level;
|
||||
break;
|
||||
}
|
||||
case HAL_ANI_PRESENT:
|
||||
break;
|
||||
case HAL_ANI_MODE:
|
||||
if (param == 0) {
|
||||
ahp->ah_procPhyErr &= ~HAL_ANI_ENA;
|
||||
/* Turn off HW counters if we have them */
|
||||
ar5416AniDetach(ah);
|
||||
ar5212SetRxFilter(ah,
|
||||
ar5212GetRxFilter(ah) &~ HAL_RX_FILTER_PHYERR);
|
||||
} else { /* normal/auto mode */
|
||||
/* don't mess with state if already enabled */
|
||||
if (ahp->ah_procPhyErr & HAL_ANI_ENA)
|
||||
break;
|
||||
ar5212SetRxFilter(ah,
|
||||
ar5212GetRxFilter(ah) &~ HAL_RX_FILTER_PHYERR);
|
||||
/* Enable MIB Counters */
|
||||
enableAniMIBCounters(ah, ahp->ah_curani != AH_NULL ?
|
||||
ahp->ah_curani->params: &ahp->ah_aniParams24 /*XXX*/);
|
||||
ahp->ah_procPhyErr |= HAL_ANI_ENA;
|
||||
}
|
||||
break;
|
||||
#ifdef AH_PRIVATE_DIAG
|
||||
case HAL_ANI_PHYERR_RESET:
|
||||
ahp->ah_stats.ast_ani_ofdmerrs = 0;
|
||||
ahp->ah_stats.ast_ani_cckerrs = 0;
|
||||
break;
|
||||
#endif /* AH_PRIVATE_DIAG */
|
||||
default:
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid cmd %u\n",
|
||||
__func__, cmd);
|
||||
return AH_FALSE;
|
||||
}
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
ar5416AniOfdmErrTrigger(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
|
||||
struct ar5212AniState *aniState;
|
||||
const struct ar5212AniParams *params;
|
||||
|
||||
HALASSERT(chan != AH_NULL);
|
||||
|
||||
if (!ANI_ENA(ah))
|
||||
return;
|
||||
|
||||
aniState = ahp->ah_curani;
|
||||
params = aniState->params;
|
||||
/* First, raise noise immunity level, up to max */
|
||||
if (aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel) {
|
||||
ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
|
||||
aniState->noiseImmunityLevel + 1);
|
||||
return;
|
||||
}
|
||||
/* then, raise spur immunity level, up to max */
|
||||
if (aniState->spurImmunityLevel+1 < params->maxSpurImmunityLevel) {
|
||||
ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
|
||||
aniState->spurImmunityLevel + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ANI_ENA_RSSI(ah)) {
|
||||
int32_t rssi = BEACON_RSSI(ahp);
|
||||
if (rssi > params->rssiThrHigh) {
|
||||
/*
|
||||
* Beacon rssi is high, can turn off ofdm
|
||||
* weak sig detect.
|
||||
*/
|
||||
if (!aniState->ofdmWeakSigDetectOff) {
|
||||
ar5416AniControl(ah,
|
||||
HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
AH_FALSE);
|
||||
ar5416AniControl(ah,
|
||||
HAL_ANI_SPUR_IMMUNITY_LEVEL, 0);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* If weak sig detect is already off, as last resort,
|
||||
* raise firstep level
|
||||
*/
|
||||
if (aniState->firstepLevel+1 < params->maxFirstepLevel) {
|
||||
ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel + 1);
|
||||
return;
|
||||
}
|
||||
} else if (rssi > params->rssiThrLow) {
|
||||
/*
|
||||
* Beacon rssi in mid range, need ofdm weak signal
|
||||
* detect, but we can raise firststepLevel.
|
||||
*/
|
||||
if (aniState->ofdmWeakSigDetectOff)
|
||||
ar5416AniControl(ah,
|
||||
HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
AH_TRUE);
|
||||
if (aniState->firstepLevel+1 < params->maxFirstepLevel)
|
||||
ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel + 1);
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* Beacon rssi is low, if in 11b/g mode, turn off ofdm
|
||||
* weak signal detection and zero firstepLevel to
|
||||
* maximize CCK sensitivity
|
||||
*/
|
||||
/* XXX can optimize */
|
||||
if (IS_CHAN_B(chan) || IS_CHAN_G(chan)) {
|
||||
if (!aniState->ofdmWeakSigDetectOff)
|
||||
ar5416AniControl(ah,
|
||||
HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
AH_FALSE);
|
||||
if (aniState->firstepLevel > 0)
|
||||
ar5416AniControl(ah,
|
||||
HAL_ANI_FIRSTEP_LEVEL, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ar5416AniCckErrTrigger(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
|
||||
struct ar5212AniState *aniState;
|
||||
const struct ar5212AniParams *params;
|
||||
|
||||
HALASSERT(chan != AH_NULL);
|
||||
|
||||
if (!ANI_ENA(ah))
|
||||
return;
|
||||
|
||||
/* first, raise noise immunity level, up to max */
|
||||
aniState = ahp->ah_curani;
|
||||
params = aniState->params;
|
||||
if (aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel) {
|
||||
ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
|
||||
aniState->noiseImmunityLevel + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ANI_ENA_RSSI(ah)) {
|
||||
int32_t rssi = BEACON_RSSI(ahp);
|
||||
if (rssi > params->rssiThrLow) {
|
||||
/*
|
||||
* Beacon signal in mid and high range,
|
||||
* raise firstep level.
|
||||
*/
|
||||
if (aniState->firstepLevel+1 < params->maxFirstepLevel)
|
||||
ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel + 1);
|
||||
} else {
|
||||
/*
|
||||
* Beacon rssi is low, zero firstep level to maximize
|
||||
* CCK sensitivity in 11b/g mode.
|
||||
*/
|
||||
/* XXX can optimize */
|
||||
if (IS_CHAN_B(chan) || IS_CHAN_G(chan)) {
|
||||
if (aniState->firstepLevel > 0)
|
||||
ar5416AniControl(ah,
|
||||
HAL_ANI_FIRSTEP_LEVEL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ar5416AniRestart(struct ath_hal *ah, struct ar5212AniState *aniState)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
const struct ar5212AniParams *params = aniState->params;
|
||||
|
||||
aniState->listenTime = 0;
|
||||
/*
|
||||
* NB: these are written on reset based on the
|
||||
* ini so we must re-write them!
|
||||
*/
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: Writing ofdmbase=%u cckbase=%u\n", __func__,
|
||||
params->ofdmPhyErrBase, params->cckPhyErrBase);
|
||||
OS_REG_WRITE(ah, AR_PHY_ERR_1, params->ofdmPhyErrBase);
|
||||
OS_REG_WRITE(ah, AR_PHY_ERR_2, params->cckPhyErrBase);
|
||||
OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
|
||||
OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_CCK_TIMING);
|
||||
|
||||
/* Clear the mib counters and save them in the stats */
|
||||
ar5212UpdateMibCounters(ah, &ahp->ah_mibStats);
|
||||
aniState->ofdmPhyErrCount = 0;
|
||||
aniState->cckPhyErrCount = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore/reset the ANI parameters and reset the statistics.
|
||||
* This routine must be called for every channel change.
|
||||
*
|
||||
* NOTE: This is where ah_curani is set; other ani code assumes
|
||||
* it is setup to reflect the current channel.
|
||||
*/
|
||||
void
|
||||
ar5416AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
|
||||
HAL_OPMODE opmode, int restore)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
struct ar5212AniState *aniState;
|
||||
uint32_t rxfilter;
|
||||
int index;
|
||||
|
||||
index = ar5416GetAniChannelIndex(ah, chan);
|
||||
aniState = &ahp->ah_ani[index];
|
||||
ahp->ah_curani = aniState;
|
||||
#if 0
|
||||
ath_hal_printf(ah,"%s: chan %u/0x%x restore %d setup %d opmode %u\n",
|
||||
__func__, chan->channel, chan->channelFlags, restore,
|
||||
aniState->isSetup, opmode);
|
||||
#else
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI,
|
||||
"%s: chan %u/0x%x restore %d setup %d opmode %u\n",
|
||||
__func__, chan->channel, chan->channelFlags, restore,
|
||||
aniState->isSetup, opmode);
|
||||
#endif
|
||||
OS_MARK(ah, AH_MARK_ANI_RESET, opmode);
|
||||
|
||||
/*
|
||||
* Turn off PHY error frame delivery while we futz with settings.
|
||||
*/
|
||||
rxfilter = ar5212GetRxFilter(ah);
|
||||
ar5212SetRxFilter(ah, rxfilter &~ HAL_RX_FILTER_PHYERR);
|
||||
/*
|
||||
* Automatic processing is done only in station mode right now.
|
||||
*/
|
||||
if (opmode == HAL_M_STA)
|
||||
ahp->ah_procPhyErr |= HAL_RSSI_ANI_ENA;
|
||||
else
|
||||
ahp->ah_procPhyErr &= ~HAL_RSSI_ANI_ENA;
|
||||
/*
|
||||
* Set all ani parameters. We either set them to initial
|
||||
* values or restore the previous ones for the channel.
|
||||
* XXX if ANI follows hardware, we don't care what mode we're
|
||||
* XXX in, we should keep the ani parameters
|
||||
*/
|
||||
if (restore && aniState->isSetup) {
|
||||
ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
|
||||
aniState->noiseImmunityLevel);
|
||||
ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
|
||||
aniState->spurImmunityLevel);
|
||||
ar5416AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
!aniState->ofdmWeakSigDetectOff);
|
||||
ar5416AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR,
|
||||
aniState->cckWeakSigThreshold);
|
||||
ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel);
|
||||
} else {
|
||||
ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, 0);
|
||||
ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, 0);
|
||||
ar5416AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
AH_TRUE);
|
||||
ar5416AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR, AH_FALSE);
|
||||
ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
|
||||
aniState->isSetup = AH_TRUE;
|
||||
}
|
||||
ar5416AniRestart(ah, aniState);
|
||||
|
||||
/* restore RX filter mask */
|
||||
ar5212SetRxFilter(ah, rxfilter);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a MIB interrupt. We may potentially be invoked because
|
||||
* any of the MIB counters overflow/trigger so don't assume we're
|
||||
* here because a PHY error counter triggered.
|
||||
*/
|
||||
void
|
||||
ar5416ProcessMibIntr(struct ath_hal *ah, const HAL_NODE_STATS *stats)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
uint32_t phyCnt1, phyCnt2;
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: mibc 0x%x phyCnt1 0x%x phyCnt2 0x%x "
|
||||
"filtofdm 0x%x filtcck 0x%x\n",
|
||||
__func__, OS_REG_READ(ah, AR_MIBC),
|
||||
OS_REG_READ(ah, AR_PHYCNT1), OS_REG_READ(ah, AR_PHYCNT2),
|
||||
OS_REG_READ(ah, AR_FILTOFDM), OS_REG_READ(ah, AR_FILTCCK));
|
||||
|
||||
/*
|
||||
* First order of business is to clear whatever caused
|
||||
* the interrupt so we don't keep getting interrupted.
|
||||
* We have the usual mib counters that are reset-on-read
|
||||
* and the additional counters that appeared starting in
|
||||
* Hainan. We collect the mib counters and explicitly
|
||||
* zero additional counters we are not using. Anything
|
||||
* else is reset only if it caused the interrupt.
|
||||
*/
|
||||
/* NB: these are not reset-on-read */
|
||||
phyCnt1 = OS_REG_READ(ah, AR_PHY_ERR_1);
|
||||
phyCnt2 = OS_REG_READ(ah, AR_PHY_ERR_2);
|
||||
/* not used, always reset them in case they are the cause */
|
||||
OS_REG_WRITE(ah, AR_FILTOFDM, 0);
|
||||
OS_REG_WRITE(ah, AR_FILTCCK, 0);
|
||||
if ((OS_REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING) == 0)
|
||||
OS_REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
|
||||
|
||||
/* Clear the mib counters and save them in the stats */
|
||||
ar5212UpdateMibCounters(ah, &ahp->ah_mibStats);
|
||||
ahp->ah_stats.ast_nodestats = *stats;
|
||||
|
||||
/*
|
||||
* Check for an ani stat hitting the trigger threshold.
|
||||
* When this happens we get a MIB interrupt and the top
|
||||
* 2 bits of the counter register will be 0b11, hence
|
||||
* the mask check of phyCnt?.
|
||||
*/
|
||||
if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
|
||||
((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
|
||||
struct ar5212AniState *aniState = ahp->ah_curani;
|
||||
const struct ar5212AniParams *params = aniState->params;
|
||||
uint32_t ofdmPhyErrCnt, cckPhyErrCnt;
|
||||
|
||||
ofdmPhyErrCnt = phyCnt1 - params->ofdmPhyErrBase;
|
||||
ahp->ah_stats.ast_ani_ofdmerrs +=
|
||||
ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
|
||||
aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
|
||||
|
||||
cckPhyErrCnt = phyCnt2 - params->cckPhyErrBase;
|
||||
ahp->ah_stats.ast_ani_cckerrs +=
|
||||
cckPhyErrCnt - aniState->cckPhyErrCount;
|
||||
aniState->cckPhyErrCount = cckPhyErrCnt;
|
||||
|
||||
/*
|
||||
* NB: figure out which counter triggered. If both
|
||||
* trigger we'll only deal with one as the processing
|
||||
* clobbers the error counter so the trigger threshold
|
||||
* check will never be true.
|
||||
*/
|
||||
if (aniState->ofdmPhyErrCount > params->ofdmTrigHigh)
|
||||
ar5416AniOfdmErrTrigger(ah);
|
||||
if (aniState->cckPhyErrCount > params->cckTrigHigh)
|
||||
ar5416AniCckErrTrigger(ah);
|
||||
/* NB: always restart to insure the h/w counters are reset */
|
||||
ar5416AniRestart(ah, aniState);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ar5416AniLowerImmunity(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
struct ar5212AniState *aniState;
|
||||
const struct ar5212AniParams *params;
|
||||
|
||||
HALASSERT(ANI_ENA(ah));
|
||||
|
||||
aniState = ahp->ah_curani;
|
||||
params = aniState->params;
|
||||
if (ANI_ENA_RSSI(ah)) {
|
||||
int32_t rssi = BEACON_RSSI(ahp);
|
||||
if (rssi > params->rssiThrHigh) {
|
||||
/*
|
||||
* Beacon signal is high, leave ofdm weak signal
|
||||
* detection off or it may oscillate. Let it fall
|
||||
* through.
|
||||
*/
|
||||
} else if (rssi > params->rssiThrLow) {
|
||||
/*
|
||||
* Beacon rssi in mid range, turn on ofdm weak signal
|
||||
* detection or lower firstep level.
|
||||
*/
|
||||
if (aniState->ofdmWeakSigDetectOff) {
|
||||
ar5416AniControl(ah,
|
||||
HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
AH_TRUE);
|
||||
return;
|
||||
}
|
||||
if (aniState->firstepLevel > 0) {
|
||||
ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel - 1);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Beacon rssi is low, reduce firstep level.
|
||||
*/
|
||||
if (aniState->firstepLevel > 0) {
|
||||
ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel - 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* then lower spur immunity level, down to zero */
|
||||
if (aniState->spurImmunityLevel > 0) {
|
||||
ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
|
||||
aniState->spurImmunityLevel - 1);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* if all else fails, lower noise immunity level down to a min value
|
||||
* zero for now
|
||||
*/
|
||||
if (aniState->noiseImmunityLevel > 0) {
|
||||
ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
|
||||
aniState->noiseImmunityLevel - 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#define CLOCK_RATE 44000 /* XXX use mac_usec or similar */
|
||||
/* convert HW counter values to ms using 11g clock rate, goo9d enough
|
||||
for 11a and Turbo */
|
||||
|
||||
/*
|
||||
* Return an approximation of the time spent ``listening'' by
|
||||
* deducting the cycles spent tx'ing and rx'ing from the total
|
||||
* cycle count since our last call. A return value <0 indicates
|
||||
* an invalid/inconsistent time.
|
||||
*/
|
||||
static int32_t
|
||||
ar5416AniGetListenTime(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
struct ar5212AniState *aniState;
|
||||
uint32_t txFrameCount, rxFrameCount, cycleCount;
|
||||
int32_t listenTime;
|
||||
|
||||
txFrameCount = OS_REG_READ(ah, AR_TFCNT);
|
||||
rxFrameCount = OS_REG_READ(ah, AR_RFCNT);
|
||||
cycleCount = OS_REG_READ(ah, AR_CCCNT);
|
||||
|
||||
aniState = ahp->ah_curani;
|
||||
if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
|
||||
/*
|
||||
* Cycle counter wrap (or initial call); it's not possible
|
||||
* to accurately calculate a value because the registers
|
||||
* right shift rather than wrap--so punt and return 0.
|
||||
*/
|
||||
listenTime = 0;
|
||||
ahp->ah_stats.ast_ani_lzero++;
|
||||
} else {
|
||||
int32_t ccdelta = cycleCount - aniState->cycleCount;
|
||||
int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
|
||||
int32_t tfdelta = txFrameCount - aniState->txFrameCount;
|
||||
listenTime = (ccdelta - rfdelta - tfdelta) / CLOCK_RATE;
|
||||
}
|
||||
aniState->cycleCount = cycleCount;
|
||||
aniState->txFrameCount = txFrameCount;
|
||||
aniState->rxFrameCount = rxFrameCount;
|
||||
return listenTime;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update ani stats in preparation for listen time processing.
|
||||
*/
|
||||
static void
|
||||
updateMIBStats(struct ath_hal *ah, struct ar5212AniState *aniState)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
const struct ar5212AniParams *params = aniState->params;
|
||||
uint32_t phyCnt1, phyCnt2;
|
||||
int32_t ofdmPhyErrCnt, cckPhyErrCnt;
|
||||
|
||||
/* Clear the mib counters and save them in the stats */
|
||||
ar5212UpdateMibCounters(ah, &ahp->ah_mibStats);
|
||||
|
||||
/* NB: these are not reset-on-read */
|
||||
phyCnt1 = OS_REG_READ(ah, AR_PHY_ERR_1);
|
||||
phyCnt2 = OS_REG_READ(ah, AR_PHY_ERR_2);
|
||||
|
||||
/* NB: these are spec'd to never roll-over */
|
||||
ofdmPhyErrCnt = phyCnt1 - params->ofdmPhyErrBase;
|
||||
if (ofdmPhyErrCnt < 0) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI, "OFDM phyErrCnt %d phyCnt1 0x%x\n",
|
||||
ofdmPhyErrCnt, phyCnt1);
|
||||
ofdmPhyErrCnt = AR_PHY_COUNTMAX;
|
||||
}
|
||||
ahp->ah_stats.ast_ani_ofdmerrs +=
|
||||
ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
|
||||
aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
|
||||
|
||||
cckPhyErrCnt = phyCnt2 - params->cckPhyErrBase;
|
||||
if (cckPhyErrCnt < 0) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANI, "CCK phyErrCnt %d phyCnt2 0x%x\n",
|
||||
cckPhyErrCnt, phyCnt2);
|
||||
cckPhyErrCnt = AR_PHY_COUNTMAX;
|
||||
}
|
||||
ahp->ah_stats.ast_ani_cckerrs +=
|
||||
cckPhyErrCnt - aniState->cckPhyErrCount;
|
||||
aniState->cckPhyErrCount = cckPhyErrCnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do periodic processing. This routine is called from the
|
||||
* driver's rx interrupt handler after processing frames.
|
||||
*/
|
||||
void
|
||||
ar5416AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
|
||||
HAL_CHANNEL *chan)
|
||||
{
|
||||
struct ath_hal_5212 *ahp = AH5212(ah);
|
||||
struct ar5212AniState *aniState = ahp->ah_curani;
|
||||
const struct ar5212AniParams *params;
|
||||
int32_t listenTime;
|
||||
|
||||
ahp->ah_stats.ast_nodestats.ns_avgbrssi = stats->ns_avgbrssi;
|
||||
|
||||
/* XXX can aniState be null? */
|
||||
if (aniState == AH_NULL)
|
||||
return;
|
||||
if (!ANI_ENA(ah))
|
||||
return;
|
||||
|
||||
listenTime = ar5416AniGetListenTime(ah);
|
||||
if (listenTime < 0) {
|
||||
ahp->ah_stats.ast_ani_lneg++;
|
||||
/* restart ANI period if listenTime is invalid */
|
||||
ar5416AniRestart(ah, aniState);
|
||||
}
|
||||
/* XXX beware of overflow? */
|
||||
aniState->listenTime += listenTime;
|
||||
|
||||
OS_MARK(ah, AH_MARK_ANI_POLL, aniState->listenTime);
|
||||
|
||||
params = aniState->params;
|
||||
if (aniState->listenTime > 5*params->period) {
|
||||
/*
|
||||
* Check to see if need to lower immunity if
|
||||
* 5 aniPeriods have passed
|
||||
*/
|
||||
updateMIBStats(ah, aniState);
|
||||
if (aniState->ofdmPhyErrCount <= aniState->listenTime *
|
||||
params->ofdmTrigLow/1000 &&
|
||||
aniState->cckPhyErrCount <= aniState->listenTime *
|
||||
params->cckTrigLow/1000)
|
||||
ar5416AniLowerImmunity(ah);
|
||||
ar5416AniRestart(ah, aniState);
|
||||
} else if (aniState->listenTime > params->period) {
|
||||
updateMIBStats(ah, aniState);
|
||||
/* check to see if need to raise immunity */
|
||||
if (aniState->ofdmPhyErrCount > aniState->listenTime *
|
||||
params->ofdmTrigHigh / 1000) {
|
||||
ar5416AniOfdmErrTrigger(ah);
|
||||
ar5416AniRestart(ah, aniState);
|
||||
} else if (aniState->cckPhyErrCount > aniState->listenTime *
|
||||
params->cckTrigHigh / 1000) {
|
||||
ar5416AniCckErrTrigger(ah);
|
||||
ar5416AniRestart(ah, aniState);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* AH_SUPPORT_AR5416 */
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416_attach.c,v 1.19 2008/11/10 04:08:04 sam Exp $
|
||||
* $Id: ar5416_attach.c,v 1.27 2008/11/27 22:30:07 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -83,6 +83,8 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
|
||||
ah->ah_phyDisable = ar5416PhyDisable;
|
||||
ah->ah_disable = ar5416Disable;
|
||||
ah->ah_perCalibration = ar5416PerCalibration;
|
||||
ah->ah_perCalibrationN = ar5416PerCalibrationN,
|
||||
ah->ah_resetCalValid = ar5416ResetCalValid,
|
||||
ah->ah_setTxPowerLimit = ar5416SetTxPowerLimit;
|
||||
|
||||
/* Transmit functions */
|
||||
@ -97,6 +99,8 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
|
||||
ah->ah_stopPcuReceive = ar5416StopPcuReceive;
|
||||
ah->ah_setupRxDesc = ar5416SetupRxDesc;
|
||||
ah->ah_procRxDesc = ar5416ProcRxDesc;
|
||||
ah->ah_rxMonitor = ar5416AniPoll,
|
||||
ah->ah_procMibEvent = ar5416ProcessMibIntr,
|
||||
|
||||
/* Misc Functions */
|
||||
ah->ah_getDiagState = ar5416GetDiagState;
|
||||
@ -157,24 +161,10 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
|
||||
ahp->ah_priv.ah_getChipPowerLimits = ar5416GetChipPowerLimits;
|
||||
|
||||
/*
|
||||
* XXX - Do we need a board specific chain mask?
|
||||
* Start by setting all Owl devices to 2x2
|
||||
*/
|
||||
AH5416(ah)->ah_rx_chainmask = AR5416_DEFAULT_RXCHAINMASK;
|
||||
AH5416(ah)->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK;
|
||||
AH5416(ah)->ah_clksel = 0; /* XXX */
|
||||
/* NB: ah_keytype is initialized to zero which is ok */
|
||||
#if 0
|
||||
ah->ah_descinfo.rxctl_numwords = RXCTL_NUMWORDS(ah);
|
||||
ah->ah_descinfo.rxctl_offset = RXCTL_OFFSET(ah);
|
||||
ah->ah_descinfo.rxstatus_numwords = RXSTATUS_NUMWORDS(ah);
|
||||
ah->ah_descinfo.rxstatus_offset = RXSTATUS_OFFSET(ah);
|
||||
|
||||
ah->ah_descinfo.txctl_numwords = TXCTL_NUMWORDS(ah);
|
||||
ah->ah_descinfo.txctl_offset = TXCTL_OFFSET(ah);
|
||||
ah->ah_descinfo.txstatus_numwords = TXSTATUS_NUMWORDS(ah);
|
||||
ah->ah_descinfo.txstatus_offset = TXSTATUS_OFFSET(ah);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -330,7 +320,7 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc,
|
||||
* ah_miscMode is populated by ar5416FillCapabilityInfo()
|
||||
* starting from griffin. Set here to make sure that
|
||||
* AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
|
||||
* placed into hardware
|
||||
* placed into hardware.
|
||||
*/
|
||||
if (ahp->ah_miscMode != 0)
|
||||
OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
|
||||
@ -344,9 +334,8 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
ar5212InitializeGainValues(ah); /* gain ladder */
|
||||
ar5416AniSetup(ah); /* Anti Noise Immunity */
|
||||
ar5416InitNfHistBuff(AH5416(ah)->ah_nfCalHist);
|
||||
ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
|
||||
|
||||
@ -367,7 +356,7 @@ ar5416Detach(struct ath_hal *ah)
|
||||
HALASSERT(ah != AH_NULL);
|
||||
HALASSERT(ah->ah_magic == AR5416_MAGIC);
|
||||
|
||||
ar5212AniDetach(ah);
|
||||
ar5416AniDetach(ah);
|
||||
ar5212RfDetach(ah);
|
||||
ah->ah_disable(ah);
|
||||
ar5416SetPowerMode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416_beacon.c,v 1.7 2008/11/10 04:08:04 sam Exp $
|
||||
* $Id: ar5416_beacon.c,v 1.8 2008/11/11 01:03:12 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
/*
|
||||
* Initialize all of the hardware registers used to
|
||||
* send beacons. Note that for station operation the
|
||||
* driver calls ar5212SetStaBeaconTimers instead.
|
||||
* driver calls ar5416SetStaBeaconTimers instead.
|
||||
*/
|
||||
void
|
||||
ar5416SetBeaconTimers(struct ath_hal *ah, const HAL_BEACON_TIMERS *bt)
|
||||
|
669
ar5416/ar5416_cal.c
Normal file
669
ar5416/ar5416_cal.c
Normal file
@ -0,0 +1,669 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
|
||||
* Copyright (c) 2002-2008 Atheros Communications, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416_cal.c,v 1.7 2008/11/11 17:43:23 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
#ifdef AH_SUPPORT_AR5416
|
||||
|
||||
#include "ah.h"
|
||||
#include "ah_internal.h"
|
||||
#include "ah_devid.h"
|
||||
|
||||
#include "ah_eeprom_v14.h"
|
||||
|
||||
#include "ar5416/ar5416.h"
|
||||
#include "ar5416/ar5416reg.h"
|
||||
#include "ar5416/ar5416phy.h"
|
||||
#ifdef AH_SUPPORT_AR9280
|
||||
#include "ar5416/ar9280.h"
|
||||
#endif
|
||||
|
||||
/* Owl specific stuff */
|
||||
#define NUM_NOISEFLOOR_READINGS 6 /* 3 chains * (ctl + ext) */
|
||||
|
||||
static void ar5416StartNFCal(struct ath_hal *ah);
|
||||
static void ar5416LoadNF(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *);
|
||||
static int16_t ar5416GetNf(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
|
||||
|
||||
/*
|
||||
* Determine if calibration is supported by device and channel flags
|
||||
*/
|
||||
static OS_INLINE HAL_BOOL
|
||||
ar5416IsCalSupp(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_CAL_TYPE calType)
|
||||
{
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
|
||||
switch (calType & cal->suppCals) {
|
||||
case IQ_MISMATCH_CAL:
|
||||
/* Run IQ Mismatch for non-CCK only */
|
||||
return !IS_CHAN_B(chan);
|
||||
case ADC_GAIN_CAL:
|
||||
case ADC_DC_CAL:
|
||||
/* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */
|
||||
return !IS_CHAN_B(chan) &&
|
||||
!(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan));
|
||||
}
|
||||
return AH_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup HW to collect samples used for current cal
|
||||
*/
|
||||
static void
|
||||
ar5416SetupMeasurement(struct ath_hal *ah, HAL_CAL_LIST *currCal)
|
||||
{
|
||||
/* Start calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
|
||||
AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
|
||||
currCal->calData->calCountMax);
|
||||
|
||||
/* Select calibration to run */
|
||||
switch (currCal->calData->calType) {
|
||||
case IQ_MISMATCH_CAL:
|
||||
OS_REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"%s: start IQ Mismatch calibration\n", __func__);
|
||||
break;
|
||||
case ADC_GAIN_CAL:
|
||||
OS_REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"%s: start ADC Gain calibration\n", __func__);
|
||||
break;
|
||||
case ADC_DC_CAL:
|
||||
OS_REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"%s: start ADC DC calibration\n", __func__);
|
||||
break;
|
||||
case ADC_DC_INIT_CAL:
|
||||
OS_REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"%s: start Init ADC DC calibration\n", __func__);
|
||||
break;
|
||||
}
|
||||
/* Kick-off cal */
|
||||
OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4, AR_PHY_TIMING_CTRL4_DO_CAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize shared data structures and prepare a cal to be run.
|
||||
*/
|
||||
static void
|
||||
ar5416ResetMeasurement(struct ath_hal *ah, HAL_CAL_LIST *currCal)
|
||||
{
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
|
||||
/* Reset data structures shared between different calibrations */
|
||||
OS_MEMZERO(cal->caldata, sizeof(cal->caldata));
|
||||
cal->calSamples = 0;
|
||||
|
||||
/* Setup HW for new calibration */
|
||||
ar5416SetupMeasurement(ah, currCal);
|
||||
|
||||
/* Change SW state to RUNNING for this calibration */
|
||||
currCal->calState = CAL_RUNNING;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Run non-periodic calibrations.
|
||||
*/
|
||||
static HAL_BOOL
|
||||
ar5416RunInitCals(struct ath_hal *ah, int init_cal_count)
|
||||
{
|
||||
struct ath_hal_5416 *ahp = AH5416(ah);
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
HAL_CHANNEL_INTERNAL ichan; /* XXX bogus */
|
||||
HAL_CAL_LIST *curCal = ahp->ah_cal_curr;
|
||||
HAL_BOOL isCalDone;
|
||||
int i;
|
||||
|
||||
if (curCal == AH_NULL)
|
||||
return AH_FALSE;
|
||||
|
||||
ichan.calValid = 0;
|
||||
for (i = 0; i < init_cal_count; i++) {
|
||||
/* Reset this Cal */
|
||||
ar5416ResetMeasurement(ah, curCal);
|
||||
/* Poll for offset calibration complete */
|
||||
if (!ath_hal_wait(ah, AR_PHY_TIMING_CTRL4, AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: Cal %d failed to finish in 100ms.\n",
|
||||
__func__, curCal->calData->calType);
|
||||
/* Re-initialize list pointers for periodic cals */
|
||||
cal->cal_list = cal->cal_last = cal->cal_curr = AH_NULL;
|
||||
return AH_FALSE;
|
||||
}
|
||||
/* Run this cal */
|
||||
ar5416DoCalibration(ah, &ichan, ahp->ah_rxchainmask,
|
||||
curCal, &isCalDone);
|
||||
if (!isCalDone)
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: init cal %d did not complete.\n",
|
||||
__func__, curCal->calData->calType);
|
||||
if (curCal->calNext != AH_NULL)
|
||||
curCal = curCal->calNext;
|
||||
}
|
||||
|
||||
/* Re-initialize list pointers for periodic cals */
|
||||
cal->cal_list = cal->cal_last = cal->cal_curr = AH_NULL;
|
||||
return AH_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize Calibration infrastructure.
|
||||
*/
|
||||
HAL_BOOL
|
||||
ar5416InitCal(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
{
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
HAL_CHANNEL_INTERNAL *ichan;
|
||||
|
||||
ichan = ath_hal_checkchannel(ah, chan);
|
||||
HALASSERT(ichan != AH_NULL);
|
||||
|
||||
if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
|
||||
/* Enable Rx Filter Cal */
|
||||
OS_REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
|
||||
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
|
||||
AR_PHY_AGC_CONTROL_FLTR_CAL);
|
||||
|
||||
/* Clear the carrier leak cal bit */
|
||||
OS_REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
|
||||
|
||||
/* kick off the cal */
|
||||
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
|
||||
|
||||
/* Poll for offset calibration complete */
|
||||
if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: offset calibration failed to complete in 1ms; "
|
||||
"noisy environment?\n", __func__);
|
||||
return AH_FALSE;
|
||||
}
|
||||
|
||||
/* Set the cl cal bit and rerun the cal a 2nd time */
|
||||
/* Enable Rx Filter Cal */
|
||||
OS_REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
|
||||
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
|
||||
AR_PHY_AGC_CONTROL_FLTR_CAL);
|
||||
|
||||
OS_REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
|
||||
}
|
||||
|
||||
/* Calibrate the AGC */
|
||||
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
|
||||
|
||||
/* Poll for offset calibration complete */
|
||||
if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: offset calibration did not complete in 1ms; "
|
||||
"noisy environment?\n", __func__);
|
||||
return AH_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do NF calibration after DC offset and other CALs.
|
||||
* Per system engineers, noise floor value can sometimes be 20 dB
|
||||
* higher than normal value if DC offset and noise floor cal are
|
||||
* triggered at the same time.
|
||||
*/
|
||||
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
|
||||
|
||||
/* Initialize list pointers */
|
||||
cal->cal_list = cal->cal_last = cal->cal_curr = AH_NULL;
|
||||
|
||||
/*
|
||||
* Enable IQ, ADC Gain, ADC DC Offset Cals
|
||||
*/
|
||||
if (AR_SREV_SOWL_10_OR_LATER(ah)) {
|
||||
/* Setup all non-periodic, init time only calibrations */
|
||||
/* XXX: Init DC Offset not working yet */
|
||||
#if 0
|
||||
if (ar5416IsCalSupp(ah, chan, ADC_DC_INIT_CAL)) {
|
||||
INIT_CAL(&cal->adcDcCalInitData);
|
||||
INSERT_CAL(cal, &cal->adcDcCalInitData);
|
||||
}
|
||||
/* Initialize current pointer to first element in list */
|
||||
cal->cal_curr = cal->cal_list;
|
||||
|
||||
if (cal->ah_cal_curr != AH_NULL && !ar5416RunInitCals(ah, 0))
|
||||
return AH_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If Cals are supported, add them to list via INIT/INSERT_CAL */
|
||||
if (ar5416IsCalSupp(ah, chan, ADC_GAIN_CAL)) {
|
||||
INIT_CAL(&cal->adcGainCalData);
|
||||
INSERT_CAL(cal, &cal->adcGainCalData);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"%s: enable ADC Gain Calibration.\n", __func__);
|
||||
}
|
||||
if (ar5416IsCalSupp(ah, chan, ADC_DC_CAL)) {
|
||||
INIT_CAL(&cal->adcDcCalData);
|
||||
INSERT_CAL(cal, &cal->adcDcCalData);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"%s: enable ADC DC Calibration.\n", __func__);
|
||||
}
|
||||
if (ar5416IsCalSupp(ah, chan, IQ_MISMATCH_CAL)) {
|
||||
INIT_CAL(&cal->iqCalData);
|
||||
INSERT_CAL(cal, &cal->iqCalData);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"%s: enable IQ Calibration.\n", __func__);
|
||||
}
|
||||
/* Initialize current pointer to first element in list */
|
||||
cal->cal_curr = cal->cal_list;
|
||||
|
||||
/* Kick off measurements for the first cal */
|
||||
if (cal->cal_curr != AH_NULL)
|
||||
ar5416ResetMeasurement(ah, cal->cal_curr);
|
||||
|
||||
/* Mark all calibrations on this channel as being invalid */
|
||||
ichan->calValid = 0;
|
||||
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Entry point for upper layers to restart current cal.
|
||||
* Reset the calibration valid bit in channel.
|
||||
*/
|
||||
HAL_BOOL
|
||||
ar5416ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
|
||||
{
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
|
||||
HAL_CAL_LIST *currCal = cal->cal_curr;
|
||||
|
||||
if (!AR_SREV_SOWL_10_OR_LATER(ah))
|
||||
return AH_FALSE;
|
||||
if (currCal == AH_NULL)
|
||||
return AH_FALSE;
|
||||
if (ichan == AH_NULL) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: invalid channel %u/0x%x; no mapping\n",
|
||||
__func__, chan->channel, chan->channelFlags);
|
||||
return AH_FALSE;
|
||||
}
|
||||
/*
|
||||
* Expected that this calibration has run before, post-reset.
|
||||
* Current state should be done
|
||||
*/
|
||||
if (currCal->calState != CAL_DONE) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: Calibration state incorrect, %d\n",
|
||||
__func__, currCal->calState);
|
||||
return AH_FALSE;
|
||||
}
|
||||
|
||||
/* Verify Cal is supported on this channel */
|
||||
if (!ar5416IsCalSupp(ah, chan, currCal->calData->calType))
|
||||
return AH_FALSE;
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"%s: Resetting Cal %d state for channel %u/0x%x\n",
|
||||
__func__, currCal->calData->calType, chan->channel,
|
||||
chan->channelFlags);
|
||||
|
||||
/* Disable cal validity in channel */
|
||||
ichan->calValid &= ~currCal->calData->calType;
|
||||
currCal->calState = CAL_WAITING;
|
||||
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Recalibrate the lower PHY chips to account for temperature/environment
|
||||
* changes.
|
||||
*/
|
||||
static void
|
||||
ar5416DoCalibration(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan,
|
||||
uint8_t rxchainmask, HAL_CAL_LIST *currCal, HAL_BOOL *isCalDone)
|
||||
{
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
|
||||
/* Cal is assumed not done until explicitly set below */
|
||||
*isCalDone = AH_FALSE;
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"%s: %s Calibration, state %d, calValid 0x%x\n",
|
||||
__func__, currCal->calData->calName, currCal->calState,
|
||||
ichan->calValid);
|
||||
|
||||
/* Calibration in progress. */
|
||||
if (currCal->calState == CAL_RUNNING) {
|
||||
/* Check to see if it has finished. */
|
||||
if (!(OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) & AR_PHY_TIMING_CTRL4_DO_CAL)) {
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"%s: sample %d of %d finished\n",
|
||||
__func__, cal->calSamples,
|
||||
currCal->calData->calNumSamples);
|
||||
/*
|
||||
* Collect measurements for active chains.
|
||||
*/
|
||||
currCal->calData->calCollect(ah);
|
||||
if (++cal->calSamples >= currCal->calData->calNumSamples) {
|
||||
int i, numChains = 0;
|
||||
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
|
||||
if (rxchainmask & (1 << i))
|
||||
numChains++;
|
||||
}
|
||||
/*
|
||||
* Process accumulated data
|
||||
*/
|
||||
currCal->calData->calPostProc(ah, numChains);
|
||||
|
||||
/* Calibration has finished. */
|
||||
ichan->calValid |= currCal->calData->calType;
|
||||
currCal->calState = CAL_DONE;
|
||||
*isCalDone = AH_TRUE;
|
||||
} else {
|
||||
/*
|
||||
* Set-up to collect of another sub-sample.
|
||||
*/
|
||||
ar5416SetupMeasurement(ah, currCal);
|
||||
}
|
||||
}
|
||||
} else if (!(ichan->calValid & currCal->calData->calType)) {
|
||||
/* If current cal is marked invalid in channel, kick it off */
|
||||
ar5416ResetMeasurement(ah, currCal);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal interface to schedule periodic calibration work.
|
||||
*/
|
||||
HAL_BOOL
|
||||
ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
|
||||
u_int rxchainmask, HAL_BOOL longcal, HAL_BOOL *isCalDone)
|
||||
{
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
HAL_CAL_LIST *currCal = cal->cal_curr;
|
||||
HAL_CHANNEL_INTERNAL *ichan;
|
||||
|
||||
OS_MARK(ah, AH_MARK_PERCAL, chan->channel);
|
||||
|
||||
*isCalDone = AH_TRUE;
|
||||
|
||||
/* Invalid channel check */
|
||||
ichan = ath_hal_checkchannel(ah, chan);
|
||||
if (ichan == AH_NULL) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: invalid channel %u/0x%x; no mapping\n",
|
||||
__func__, chan->channel, chan->channelFlags);
|
||||
return AH_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* For given calibration:
|
||||
* 1. Call generic cal routine
|
||||
* 2. When this cal is done (isCalDone) if we have more cals waiting
|
||||
* (eg after reset), mask this to upper layers by not propagating
|
||||
* isCalDone if it is set to TRUE.
|
||||
* Instead, change isCalDone to FALSE and setup the waiting cal(s)
|
||||
* to be run.
|
||||
*/
|
||||
if (currCal != AH_NULL &&
|
||||
(currCal->calState == CAL_RUNNING ||
|
||||
currCal->calState == CAL_WAITING)) {
|
||||
ar5416DoCalibration(ah, ichan, rxchainmask, currCal, isCalDone);
|
||||
if (*isCalDone == AH_TRUE) {
|
||||
cal->cal_curr = currCal = currCal->calNext;
|
||||
if (currCal->calState == CAL_WAITING) {
|
||||
*isCalDone = AH_FALSE;
|
||||
ar5416ResetMeasurement(ah, currCal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do NF cal only at longer intervals */
|
||||
if (longcal) {
|
||||
/*
|
||||
* Get the value from the previous NF cal
|
||||
* and update the history buffer.
|
||||
*/
|
||||
ar5416GetNf(ah, ichan);
|
||||
|
||||
/*
|
||||
* Load the NF from history buffer of the current channel.
|
||||
* NF is slow time-variant, so it is OK to use a
|
||||
* historical value.
|
||||
*/
|
||||
ar5416LoadNF(ah, AH_PRIVATE(ah)->ah_curchan);
|
||||
|
||||
/* start NF calibration, without updating BB NF register*/
|
||||
ar5416StartNFCal(ah);
|
||||
|
||||
if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
|
||||
/* report up and clear internal state */
|
||||
chan->channelFlags |= CHANNEL_CW_INT;
|
||||
ichan->channelFlags &= ~CHANNEL_CW_INT;
|
||||
}
|
||||
}
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Recalibrate the lower PHY chips to account for temperature/environment
|
||||
* changes.
|
||||
*/
|
||||
HAL_BOOL
|
||||
ar5416PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
|
||||
{
|
||||
struct ath_hal_5416 *ahp = AH5416(ah);
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
HAL_CAL_LIST *curCal = cal->cal_curr;
|
||||
|
||||
if (curCal != AH_NULL && curCal->calData->calType == IQ_MISMATCH_CAL) {
|
||||
return ar5416PerCalibrationN(ah, chan, ahp->ah_rx_chainmask,
|
||||
AH_TRUE, isIQdone);
|
||||
} else {
|
||||
HAL_BOOL isCalDone;
|
||||
|
||||
*isIQdone = AH_FALSE;
|
||||
return ar5416PerCalibrationN(ah, chan, ahp->ah_rx_chainmask,
|
||||
AH_TRUE, &isCalDone);
|
||||
}
|
||||
}
|
||||
|
||||
static HAL_BOOL
|
||||
ar5416GetEepromNoiseFloorThresh(struct ath_hal *ah,
|
||||
const HAL_CHANNEL_INTERNAL *chan, int16_t *nft)
|
||||
{
|
||||
switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
|
||||
case CHANNEL_A:
|
||||
case CHANNEL_A_HT20:
|
||||
case CHANNEL_A_HT40PLUS:
|
||||
case CHANNEL_A_HT40MINUS:
|
||||
ath_hal_eepromGet(ah, AR_EEP_NFTHRESH_5, nft);
|
||||
break;
|
||||
case CHANNEL_B:
|
||||
case CHANNEL_G:
|
||||
case CHANNEL_G_HT20:
|
||||
case CHANNEL_G_HT40PLUS:
|
||||
case CHANNEL_G_HT40MINUS:
|
||||
ath_hal_eepromGet(ah, AR_EEP_NFTHRESH_2, nft);
|
||||
break;
|
||||
default:
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: invalid channel flags 0x%x\n",
|
||||
__func__, chan->channelFlags);
|
||||
return AH_FALSE;
|
||||
}
|
||||
return AH_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
ar5416StartNFCal(struct ath_hal *ah)
|
||||
{
|
||||
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
|
||||
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
|
||||
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
|
||||
}
|
||||
|
||||
static void
|
||||
ar5416LoadNF(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
|
||||
{
|
||||
static const uint32_t ar5416_cca_regs[] = {
|
||||
AR_PHY_CCA,
|
||||
AR_PHY_CH1_CCA,
|
||||
AR_PHY_CH2_CCA,
|
||||
AR_PHY_EXT_CCA,
|
||||
AR_PHY_CH1_EXT_CCA,
|
||||
AR_PHY_CH2_EXT_CCA
|
||||
};
|
||||
struct ar5212NfCalHist *h;
|
||||
int i, j;
|
||||
int32_t val;
|
||||
uint8_t chainmask;
|
||||
|
||||
/*
|
||||
* Force NF calibration for all chains.
|
||||
*/
|
||||
if (AR_SREV_KITE(ah)) {
|
||||
/* Kite has only one chain */
|
||||
chainmask = 0x9;
|
||||
} else if (AR_SREV_MERLIN(ah)) {
|
||||
/* Merlin has only two chains */
|
||||
chainmask = 0x1B;
|
||||
} else {
|
||||
chainmask = 0x3F;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write filtered NF values into maxCCApwr register parameter
|
||||
* so we can load below.
|
||||
*/
|
||||
h = AH5416(ah)->ah_cal.nfCalHist;
|
||||
for (i = 0; i < AR5416_NUM_NF_READINGS; i ++)
|
||||
if (chainmask & (1 << i)) {
|
||||
val = OS_REG_READ(ah, ar5416_cca_regs[i]);
|
||||
val &= 0xFFFFFE00;
|
||||
val |= (((uint32_t)(h[i].privNF) << 1) & 0x1ff);
|
||||
OS_REG_WRITE(ah, ar5416_cca_regs[i], val);
|
||||
}
|
||||
|
||||
/* Load software filtered NF value into baseband internal minCCApwr variable. */
|
||||
OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
|
||||
OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
|
||||
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
|
||||
|
||||
/* Wait for load to complete, should be fast, a few 10s of us. */
|
||||
for (j = 0; j < 1000; j++) {
|
||||
if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0)
|
||||
break;
|
||||
OS_DELAY(10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore maxCCAPower register parameter again so that we're not capped
|
||||
* by the median we just loaded. This will be initial (and max) value
|
||||
* of next noise floor calibration the baseband does.
|
||||
*/
|
||||
for (i = 0; i < AR5416_NUM_NF_READINGS; i ++)
|
||||
if (chainmask & (1 << i)) {
|
||||
val = OS_REG_READ(ah, ar5416_cca_regs[i]);
|
||||
val &= 0xFFFFFE00;
|
||||
val |= (((uint32_t)(-50) << 1) & 0x1ff);
|
||||
OS_REG_WRITE(ah, ar5416_cca_regs[i], val);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ar5416InitNfHistBuff(struct ar5212NfCalHist *h)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < AR5416_NUM_NF_READINGS; i ++) {
|
||||
h[i].currIndex = 0;
|
||||
h[i].privNF = AR5416_CCA_MAX_GOOD_VALUE;
|
||||
h[i].invalidNFcount = AR512_NF_CAL_HIST_MAX;
|
||||
for (j = 0; j < AR512_NF_CAL_HIST_MAX; j ++)
|
||||
h[i].nfCalBuffer[j] = AR5416_CCA_MAX_GOOD_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the noise floor buffer as a ring buffer
|
||||
*/
|
||||
static void
|
||||
ar5416UpdateNFHistBuff(struct ar5212NfCalHist *h, int16_t *nfarray)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AR5416_NUM_NF_READINGS; i ++) {
|
||||
h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
|
||||
|
||||
if (++h[i].currIndex >= AR512_NF_CAL_HIST_MAX)
|
||||
h[i].currIndex = 0;
|
||||
if (h[i].invalidNFcount > 0) {
|
||||
if (nfarray[i] < AR5416_CCA_MIN_BAD_VALUE ||
|
||||
nfarray[i] > AR5416_CCA_MAX_HIGH_VALUE) {
|
||||
h[i].invalidNFcount = AR512_NF_CAL_HIST_MAX;
|
||||
} else {
|
||||
h[i].invalidNFcount--;
|
||||
h[i].privNF = nfarray[i];
|
||||
}
|
||||
} else {
|
||||
h[i].privNF = ar5212GetNfHistMid(h[i].nfCalBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the NF and check it against the noise floor threshhold
|
||||
*/
|
||||
static int16_t
|
||||
ar5416GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
|
||||
{
|
||||
int16_t nf, nfThresh;
|
||||
|
||||
if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: NF didn't complete in calibration window\n", __func__);
|
||||
nf = 0;
|
||||
} else {
|
||||
/* Finished NF cal, check against threshold */
|
||||
int16_t nfarray[NUM_NOISEFLOOR_READINGS] = { 0 };
|
||||
|
||||
/* TODO - enhance for multiple chains and ext ch */
|
||||
ath_hal_getNoiseFloor(ah, nfarray);
|
||||
nf = nfarray[0];
|
||||
if (ar5416GetEepromNoiseFloorThresh(ah, chan, &nfThresh)) {
|
||||
if (nf > nfThresh) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY,
|
||||
"%s: noise floor failed detected; "
|
||||
"detected %d, threshold %d\n", __func__,
|
||||
nf, nfThresh);
|
||||
/*
|
||||
* NB: Don't discriminate 2.4 vs 5Ghz, if this
|
||||
* happens it indicates a problem regardless
|
||||
* of the band.
|
||||
*/
|
||||
chan->channelFlags |= CHANNEL_CW_INT;
|
||||
nf = 0;
|
||||
}
|
||||
} else {
|
||||
nf = 0;
|
||||
}
|
||||
ar5416UpdateNFHistBuff(AH5416(ah)->ah_cal.nfCalHist, nfarray);
|
||||
chan->rawNoiseFloor = nf;
|
||||
}
|
||||
return nf;
|
||||
}
|
||||
#endif /* AH_SUPPORT_AR5416 */
|
119
ar5416/ar5416_cal.h
Normal file
119
ar5416/ar5416_cal.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
|
||||
* Copyright (c) 2002-2008 Atheros Communications, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416_cal.h,v 1.3 2008/11/11 17:43:23 sam Exp $
|
||||
*/
|
||||
#ifndef _ATH_AR5416_CAL_H_
|
||||
#define _ATH_AR5416_CAL_H_
|
||||
|
||||
typedef enum {
|
||||
ADC_DC_INIT_CAL = 0x1,
|
||||
ADC_GAIN_CAL = 0x2,
|
||||
ADC_DC_CAL = 0x4,
|
||||
IQ_MISMATCH_CAL = 0x8
|
||||
} HAL_CAL_TYPE;
|
||||
|
||||
/* Calibrate state */
|
||||
typedef enum {
|
||||
CAL_INACTIVE,
|
||||
CAL_WAITING,
|
||||
CAL_RUNNING,
|
||||
CAL_DONE
|
||||
} HAL_CAL_STATE;
|
||||
|
||||
typedef union {
|
||||
uint32_t u;
|
||||
int32_t s;
|
||||
} HAL_CAL_SAMPLE;
|
||||
|
||||
#define MIN_CAL_SAMPLES 1
|
||||
#define MAX_CAL_SAMPLES 64
|
||||
#define INIT_LOG_COUNT 5
|
||||
#define PER_MIN_LOG_COUNT 2
|
||||
#define PER_MAX_LOG_COUNT 10
|
||||
|
||||
/* Per Calibration data structure */
|
||||
typedef struct per_cal_data {
|
||||
const char *calName; /* for diagnostics */
|
||||
HAL_CAL_TYPE calType; /* Type of calibration */
|
||||
uint32_t calNumSamples; /* # SW samples to collect */
|
||||
uint32_t calCountMax; /* # HW samples to collect */
|
||||
void (*calCollect)(struct ath_hal *); /* Accumulator function */
|
||||
/* Post-processing function */
|
||||
void (*calPostProc)(struct ath_hal *, uint8_t);
|
||||
} HAL_PERCAL_DATA;
|
||||
|
||||
/* List structure for calibration data */
|
||||
typedef struct cal_list {
|
||||
struct cal_list *calNext;
|
||||
HAL_CAL_STATE calState;
|
||||
const HAL_PERCAL_DATA *calData;
|
||||
} HAL_CAL_LIST;
|
||||
|
||||
struct ar5416PerCal {
|
||||
/*
|
||||
* Periodic calibration state.
|
||||
*/
|
||||
HAL_CAL_TYPE suppCals;
|
||||
HAL_CAL_LIST iqCalData;
|
||||
HAL_CAL_LIST adcGainCalData;
|
||||
HAL_CAL_LIST adcDcCalInitData;
|
||||
HAL_CAL_LIST adcDcCalData;
|
||||
HAL_CAL_LIST *cal_list;
|
||||
HAL_CAL_LIST *cal_last;
|
||||
HAL_CAL_LIST *cal_curr;
|
||||
#define AR5416_MAX_CHAINS 3 /* XXX dup's eeprom def */
|
||||
HAL_CAL_SAMPLE caldata[4][AR5416_MAX_CHAINS];
|
||||
int calSamples;
|
||||
/*
|
||||
* Noise floor cal histogram support.
|
||||
* XXX be nice to re-use space in ar5212
|
||||
*/
|
||||
#define AR5416_NUM_NF_READINGS 6 /* (3 chains * (ctl + ext) */
|
||||
struct ar5212NfCalHist nfCalHist[AR5416_NUM_NF_READINGS];
|
||||
};
|
||||
|
||||
#define INIT_CAL(_perCal) do { \
|
||||
(_perCal)->calState = CAL_WAITING; \
|
||||
(_perCal)->calNext = AH_NULL; \
|
||||
} while (0)
|
||||
|
||||
#define INSERT_CAL(_cal, _perCal) do { \
|
||||
if ((_cal)->cal_last == AH_NULL) { \
|
||||
(_cal)->cal_list = (_cal)->cal_last = (_perCal); \
|
||||
((_cal)->cal_last)->calNext = (_perCal); \
|
||||
} else { \
|
||||
((_cal)->cal_last)->calNext = (_perCal); \
|
||||
(_cal)->cal_last = (_perCal); \
|
||||
(_perCal)->calNext = (_cal)->cal_list; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
HAL_BOOL ar5416InitCal(struct ath_hal *ah, HAL_CHANNEL *chan);
|
||||
HAL_BOOL ar5416PerCalibration(struct ath_hal *, HAL_CHANNEL *,
|
||||
HAL_BOOL *isIQdone);
|
||||
HAL_BOOL ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
|
||||
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
|
||||
HAL_BOOL ar5416ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan);
|
||||
|
||||
void ar5416IQCalCollect(struct ath_hal *ah);
|
||||
void ar5416IQCalibration(struct ath_hal *ah, uint8_t numChains);
|
||||
void ar5416AdcGainCalCollect(struct ath_hal *ah);
|
||||
void ar5416AdcGainCalibration(struct ath_hal *ah, uint8_t numChains);
|
||||
void ar5416AdcDcCalCollect(struct ath_hal *ah);
|
||||
void ar5416AdcDcCalibration(struct ath_hal *ah, uint8_t numChains);
|
||||
void ar5416InitNfHistBuff(struct ar5212NfCalHist *h);
|
||||
#endif /* _ATH_AR5416_CAL_H_ */
|
114
ar5416/ar5416_cal_adcdc.c
Normal file
114
ar5416/ar5416_cal_adcdc.c
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
|
||||
* Copyright (c) 2002-2008 Atheros Communications, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416_cal_adcdc.c,v 1.2 2008/11/11 17:43:23 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
#ifdef AH_SUPPORT_AR5416
|
||||
|
||||
#include "ah.h"
|
||||
#include "ah_internal.h"
|
||||
#include "ah_devid.h"
|
||||
|
||||
#include "ar5416/ar5416.h"
|
||||
#include "ar5416/ar5416reg.h"
|
||||
#include "ar5416/ar5416phy.h"
|
||||
|
||||
/* Adc DC Offset Cal aliases */
|
||||
#define totalAdcDcOffsetIOddPhase(i) caldata[0][i].s
|
||||
#define totalAdcDcOffsetIEvenPhase(i) caldata[1][i].s
|
||||
#define totalAdcDcOffsetQOddPhase(i) caldata[2][i].s
|
||||
#define totalAdcDcOffsetQEvenPhase(i) caldata[3][i].s
|
||||
|
||||
void
|
||||
ar5416AdcDcCalCollect(struct ath_hal *ah)
|
||||
{
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
|
||||
cal->totalAdcDcOffsetIOddPhase(i) += (int32_t)
|
||||
OS_REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
|
||||
cal->totalAdcDcOffsetIEvenPhase(i) += (int32_t)
|
||||
OS_REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
|
||||
cal->totalAdcDcOffsetQOddPhase(i) += (int32_t)
|
||||
OS_REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
|
||||
cal->totalAdcDcOffsetQEvenPhase(i) += (int32_t)
|
||||
OS_REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n",
|
||||
cal->calSamples, i,
|
||||
cal->totalAdcDcOffsetIOddPhase(i),
|
||||
cal->totalAdcDcOffsetIEvenPhase(i),
|
||||
cal->totalAdcDcOffsetQOddPhase(i),
|
||||
cal->totalAdcDcOffsetQEvenPhase(i));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ar5416AdcDcCalibration(struct ath_hal *ah, uint8_t numChains)
|
||||
{
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
const HAL_PERCAL_DATA *calData = cal->cal_curr->calData;
|
||||
uint32_t numSamples;
|
||||
int i;
|
||||
|
||||
numSamples = (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
|
||||
for (i = 0; i < numChains; i++) {
|
||||
uint32_t iOddMeasOffset = cal->totalAdcDcOffsetIOddPhase(i);
|
||||
uint32_t iEvenMeasOffset = cal->totalAdcDcOffsetIEvenPhase(i);
|
||||
int32_t qOddMeasOffset = cal->totalAdcDcOffsetQOddPhase(i);
|
||||
int32_t qEvenMeasOffset = cal->totalAdcDcOffsetQEvenPhase(i);
|
||||
int32_t qDcMismatch, iDcMismatch;
|
||||
uint32_t val;
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"Starting ADC DC Offset Cal for Chain %d\n", i);
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_odd_i = %d\n",
|
||||
iOddMeasOffset);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_even_i = %d\n",
|
||||
iEvenMeasOffset);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_odd_q = %d\n",
|
||||
qOddMeasOffset);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_even_q = %d\n",
|
||||
qEvenMeasOffset);
|
||||
|
||||
HALASSERT(numSamples);
|
||||
|
||||
iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
|
||||
numSamples) & 0x1ff;
|
||||
qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
|
||||
numSamples) & 0x1ff;
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
" dc_offset_mismatch_i = 0x%08x\n", iDcMismatch);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
" dc_offset_mismatch_q = 0x%08x\n", qDcMismatch);
|
||||
|
||||
val = OS_REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
|
||||
val &= 0xc0000fff;
|
||||
val |= (qDcMismatch << 12) | (iDcMismatch << 21);
|
||||
OS_REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"ADC DC Offset Cal done for Chain %d\n", i);
|
||||
}
|
||||
OS_REG_SET_BIT(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
|
||||
AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
|
||||
}
|
||||
#endif /* AH_SUPPORT_AR5416 */
|
119
ar5416/ar5416_cal_adcgain.c
Normal file
119
ar5416/ar5416_cal_adcgain.c
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
|
||||
* Copyright (c) 2002-2008 Atheros Communications, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416_cal_adcgain.c,v 1.2 2008/11/11 17:43:23 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
#ifdef AH_SUPPORT_AR5416
|
||||
|
||||
#include "ah.h"
|
||||
#include "ah_internal.h"
|
||||
#include "ah_devid.h"
|
||||
|
||||
#include "ar5416/ar5416.h"
|
||||
#include "ar5416/ar5416reg.h"
|
||||
#include "ar5416/ar5416phy.h"
|
||||
|
||||
/* Adc Gain Cal aliases */
|
||||
#define totalAdcIOddPhase(i) caldata[0][i].u
|
||||
#define totalAdcIEvenPhase(i) caldata[1][i].u
|
||||
#define totalAdcQOddPhase(i) caldata[2][i].u
|
||||
#define totalAdcQEvenPhase(i) caldata[3][i].u
|
||||
|
||||
/*
|
||||
* Collect data from HW to later perform ADC Gain Calibration
|
||||
*/
|
||||
void
|
||||
ar5416AdcGainCalCollect(struct ath_hal *ah)
|
||||
{
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Accumulate ADC Gain cal measures for active chains
|
||||
*/
|
||||
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
|
||||
cal->totalAdcIOddPhase(i) +=
|
||||
OS_REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
|
||||
cal->totalAdcIEvenPhase(i) +=
|
||||
OS_REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
|
||||
cal->totalAdcQOddPhase(i) +=
|
||||
OS_REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
|
||||
cal->totalAdcQEvenPhase(i) +=
|
||||
OS_REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n",
|
||||
cal->calSamples, i, cal->totalAdcIOddPhase(i),
|
||||
cal->totalAdcIEvenPhase(i), cal->totalAdcQOddPhase(i),
|
||||
cal->totalAdcQEvenPhase(i));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Use HW data to do ADC Gain Calibration
|
||||
*/
|
||||
void
|
||||
ar5416AdcGainCalibration(struct ath_hal *ah, uint8_t numChains)
|
||||
{
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < numChains; i++) {
|
||||
uint32_t iOddMeasOffset = cal->totalAdcIOddPhase(i);
|
||||
uint32_t iEvenMeasOffset = cal->totalAdcIEvenPhase(i);
|
||||
uint32_t qOddMeasOffset = cal->totalAdcQOddPhase(i);
|
||||
uint32_t qEvenMeasOffset = cal->totalAdcQEvenPhase(i);
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"Start ADC Gain Cal for Chain %d\n", i);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
" pwr_meas_odd_i = 0x%08x\n", iOddMeasOffset);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
" pwr_meas_even_i = 0x%08x\n", iEvenMeasOffset);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
" pwr_meas_odd_q = 0x%08x\n", qOddMeasOffset);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
" pwr_meas_even_q = 0x%08x\n", qEvenMeasOffset);
|
||||
|
||||
if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
|
||||
uint32_t iGainMismatch =
|
||||
((iEvenMeasOffset*32)/iOddMeasOffset) & 0x3f;
|
||||
uint32_t qGainMismatch =
|
||||
((qOddMeasOffset*32)/qEvenMeasOffset) & 0x3f;
|
||||
uint32_t val;
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
" gain_mismatch_i = 0x%08x\n",
|
||||
iGainMismatch);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
" gain_mismatch_q = 0x%08x\n",
|
||||
qGainMismatch);
|
||||
|
||||
val = OS_REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
|
||||
val &= 0xfffff000;
|
||||
val |= (qGainMismatch) | (iGainMismatch << 6);
|
||||
OS_REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"ADC Gain Cal done for Chain %d\n", i);
|
||||
}
|
||||
}
|
||||
OS_REG_SET_BIT(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
|
||||
AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
|
||||
}
|
||||
#endif /* AH_SUPPORT_AR5416 */
|
135
ar5416/ar5416_cal_iq.c
Normal file
135
ar5416/ar5416_cal_iq.c
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
|
||||
* Copyright (c) 2002-2008 Atheros Communications, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416_cal_iq.c,v 1.2 2008/11/11 17:43:23 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
#ifdef AH_SUPPORT_AR5416
|
||||
|
||||
#include "ah.h"
|
||||
#include "ah_internal.h"
|
||||
#include "ah_devid.h"
|
||||
|
||||
#include "ar5416/ar5416.h"
|
||||
#include "ar5416/ar5416reg.h"
|
||||
#include "ar5416/ar5416phy.h"
|
||||
|
||||
/* IQ Cal aliases */
|
||||
#define totalPowerMeasI(i) caldata[0][i].u
|
||||
#define totalPowerMeasQ(i) caldata[1][i].u
|
||||
#define totalIqCorrMeas(i) caldata[2][i].s
|
||||
|
||||
/*
|
||||
* Collect data from HW to later perform IQ Mismatch Calibration
|
||||
*/
|
||||
void
|
||||
ar5416IQCalCollect(struct ath_hal *ah)
|
||||
{
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Accumulate IQ cal measures for active chains
|
||||
*/
|
||||
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
|
||||
cal->totalPowerMeasI(i) +=
|
||||
OS_REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
|
||||
cal->totalPowerMeasQ(i) +=
|
||||
OS_REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
|
||||
cal->totalIqCorrMeas(i) += (int32_t)
|
||||
OS_REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
|
||||
cal->calSamples, i, cal->totalPowerMeasI(i),
|
||||
cal->totalPowerMeasQ(i), cal->totalIqCorrMeas(i));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Use HW data to do IQ Mismatch Calibration
|
||||
*/
|
||||
void
|
||||
ar5416IQCalibration(struct ath_hal *ah, uint8_t numChains)
|
||||
{
|
||||
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numChains; i++) {
|
||||
uint32_t powerMeasI = cal->totalPowerMeasI(i);
|
||||
uint32_t powerMeasQ = cal->totalPowerMeasQ(i);
|
||||
uint32_t iqCorrMeas = cal->totalIqCorrMeas(i);
|
||||
uint32_t qCoffDenom, iCoffDenom;
|
||||
int iqCorrNeg;
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"Start IQ Cal and Correction for Chain %d\n", i);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"Orignal: iq_corr_meas = 0x%08x\n", iqCorrMeas);
|
||||
|
||||
iqCorrNeg = 0;
|
||||
/* iqCorrMeas is always negative. */
|
||||
if (iqCorrMeas > 0x80000000) {
|
||||
iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
|
||||
iqCorrNeg = 1;
|
||||
}
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_i = 0x%08x\n",
|
||||
powerMeasI);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL, " pwr_meas_q = 0x%08x\n",
|
||||
powerMeasQ);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL, " iqCorrNeg is 0x%08x\n",
|
||||
iqCorrNeg);
|
||||
|
||||
iCoffDenom = (powerMeasI/2 + powerMeasQ/2)/ 128;
|
||||
qCoffDenom = powerMeasQ / 64;
|
||||
/* Protect against divide-by-0 */
|
||||
if (powerMeasQ != 0) {
|
||||
/* IQ corr_meas is already negated if iqcorr_neg == 1 */
|
||||
int32_t iCoff = iqCorrMeas/iCoffDenom;
|
||||
int32_t qCoff = powerMeasI/qCoffDenom - 64;
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL, " iCoff = 0x%08x\n",
|
||||
iCoff);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL, " qCoff = 0x%08x\n",
|
||||
qCoff);
|
||||
|
||||
/* Negate iCoff if iqCorrNeg == 0 */
|
||||
iCoff = iCoff & 0x3f;
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"New: iCoff = 0x%08x\n", iCoff);
|
||||
|
||||
if (iqCorrNeg == 0x0)
|
||||
iCoff = 0x40 - iCoff;
|
||||
if (qCoff > 15)
|
||||
qCoff = 15;
|
||||
else if (qCoff <= -16)
|
||||
qCoff = 16;
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
" : iCoff = 0x%x qCoff = 0x%x\n", iCoff, qCoff);
|
||||
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4_CHAIN(i),
|
||||
AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, iCoff);
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4_CHAIN(i),
|
||||
AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, qCoff);
|
||||
HALDEBUG(ah, HAL_DEBUG_PERCAL,
|
||||
"IQ Cal and Correction done for Chain %d\n", i);
|
||||
}
|
||||
}
|
||||
OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
|
||||
AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
|
||||
}
|
||||
#endif /* AH_SUPPORT_AR5416 */
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416_misc.c,v 1.9 2008/11/10 04:08:04 sam Exp $
|
||||
* $Id: ar5416_misc.c,v 1.12 2008/11/27 22:30:07 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -277,7 +277,7 @@ ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
|
||||
case HAL_BB_HANG_RIFS:
|
||||
return AR_SREV_SOWL(ah) ? HAL_OK : HAL_ENOTSUPP;
|
||||
case HAL_BB_HANG_DFS:
|
||||
return AR_SREV_SOWL(ah) ? HAL_OK : HAL_ENOTSUPP;
|
||||
return AR_SREV_SOWL(ah) ? HAL_OK : HAL_ENOTSUPP;
|
||||
case HAL_BB_HANG_RX_CLEAR:
|
||||
return AR_SREV_MERLIN(ah) ? HAL_OK : HAL_ENOTSUPP;
|
||||
}
|
||||
@ -285,7 +285,8 @@ ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
|
||||
case HAL_CAP_MAC_HANG:
|
||||
return ((ah->ah_macVersion == AR_XSREV_VERSION_OWL_PCI) ||
|
||||
(ah->ah_macVersion == AR_XSREV_VERSION_OWL_PCIE) ||
|
||||
AR_SREV_SOWL(ah)) ? HAL_OK : HAL_ENOTSUPP;
|
||||
AR_SREV_SOWL(ah)) ?
|
||||
HAL_OK : HAL_ENOTSUPP;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -316,6 +317,7 @@ ar5416GetDiagState(struct ath_hal *ah, int request,
|
||||
ahp->ah_hangs = 0;
|
||||
if (hangs & HAL_BB_HANGS)
|
||||
ahp->ah_hangs |= ar5416DetectBBHang(ah);
|
||||
/* NB: if BB is hung MAC will be hung too so skip check */
|
||||
if (ahp->ah_hangs == 0 && (hangs & HAL_MAC_HANGS))
|
||||
ahp->ah_hangs |= ar5416DetectMacHang(ah);
|
||||
*result = &ahp->ah_hangs;
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416_phy.c,v 1.3 2008/11/10 01:19:39 sam Exp $
|
||||
* $Id: ar5416_phy.c,v 1.4 2008/11/27 22:30:08 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -40,7 +40,7 @@ HAL_RATE_TABLE ar5416_11ng_table = {
|
||||
/* 2 Mb */ { AH_TRUE, CCK, 2000, 0x1a, 0x04, (0x80| 4), 1 },
|
||||
/* 5.5 Mb */ { AH_TRUE, CCK, 5500, 0x19, 0x04, (0x80|11), 2 },
|
||||
/* 11 Mb */ { AH_TRUE, CCK, 11000, 0x18, 0x04, (0x80|22), 3 },
|
||||
/* We remove rates 6, 9 from rate ctrl */
|
||||
/* Remove rates 6, 9 from rate ctrl */
|
||||
/* 6 Mb */ { AH_FALSE, OFDM, 6000, 0x0b, 0x00, 12, 4 },
|
||||
/* 9 Mb */ { AH_FALSE, OFDM, 9000, 0x0f, 0x00, 18, 4 },
|
||||
/* 12 Mb */ { AH_TRUE, OFDM, 12000, 0x0a, 0x00, 24, 6 },
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416_power.c,v 1.5 2008/11/10 04:08:04 sam Exp $
|
||||
* $Id: ar5416_power.c,v 1.6 2008/11/11 00:11:30 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416_recv.c,v 1.5 2008/11/10 04:08:04 sam Exp $
|
||||
* $Id: ar5416_recv.c,v 1.7 2008/11/11 20:46:06 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -36,12 +36,15 @@ ar5416StartPcuReceive(struct ath_hal *ah)
|
||||
{
|
||||
struct ath_hal_private *ahp = AH_PRIVATE(ah);
|
||||
|
||||
OS_REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT);
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_RX, "%s: Start PCU Receive \n", __func__);
|
||||
ar5212EnableMibCounters(ah);
|
||||
/* NB: restore current settings */
|
||||
ar5212AniReset(ah, ahp->ah_curchan, ahp->ah_opmode, AH_TRUE);
|
||||
ar5416AniReset(ah, ahp->ah_curchan, ahp->ah_opmode, AH_TRUE);
|
||||
/*
|
||||
* NB: must do after enabling phy errors to avoid rx
|
||||
* frames w/ corrupted descriptor status.
|
||||
*/
|
||||
OS_REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT);
|
||||
}
|
||||
|
||||
/*
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416_xmit.c,v 1.8 2008/11/10 04:08:05 sam Exp $
|
||||
* $Id: ar5416_xmit.c,v 1.9 2008/11/27 22:30:08 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416desc.h,v 1.6 2008/11/10 04:08:05 sam Exp $
|
||||
* $Id: ar5416desc.h,v 1.7 2008/11/11 00:11:30 sam Exp $
|
||||
*/
|
||||
#ifndef _ATH_AR5416_DESC_H_
|
||||
#define _ATH_AR5416_DESC_H
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416phy.h,v 1.8 2008/11/06 22:08:01 sam Exp $
|
||||
* $Id: ar5416phy.h,v 1.10 2008/11/11 20:46:06 sam Exp $
|
||||
*/
|
||||
#ifndef _DEV_ATH_AR5416PHY_H_
|
||||
#define _DEV_ATH_AR5416PHY_H_
|
||||
@ -218,6 +218,14 @@
|
||||
|
||||
#define AR_PHY_SPUR_REG 0x994c
|
||||
#define AR_PHY_SFCORR_EXT 0x99c0
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000
|
||||
#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000
|
||||
#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
|
||||
#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
|
||||
|
||||
/* enable vit puncture per rate, 8 bits, lsb is low rate */
|
||||
@ -237,4 +245,6 @@
|
||||
#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
|
||||
#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
|
||||
|
||||
#define AR_PHY_CL_CAL_CTL 0xA358 /* carrier leak cal control */
|
||||
#define AR_PHY_CL_CAL_ENABLE 0x00000002
|
||||
#endif /* _DEV_ATH_AR5416PHY_H_ */
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar5416reg.h,v 1.9 2008/11/06 22:07:22 sam Exp $
|
||||
* $Id: ar5416reg.h,v 1.10 2008/11/11 00:11:30 sam Exp $
|
||||
*/
|
||||
#ifndef _DEV_ATH_AR5416REG_H
|
||||
#define _DEV_ATH_AR5416REG_H
|
||||
@ -445,10 +445,6 @@
|
||||
#define IS_5416V2(_ah) ((_ah)->ah_macRev >= AR_SREV_REVISION_OWL_20)
|
||||
#define IS_5416V2_2(_ah) ((_ah)->ah_macRev == AR_SREV_REVISION_OWL_22)
|
||||
|
||||
#define AR_SREV_VERSION_HOWL 0x014
|
||||
#define AR_SREV_HOWL(_ah) \
|
||||
(AH_PRIVATE((_ah))->ah_macVersion == AR_SREV_VERSION_HOWL)
|
||||
|
||||
/* Expanded Mac Silicon Rev (16 bits starting with Sowl) */
|
||||
#define AR_XSREV_ID 0xFFFFFFFF /* Chip ID */
|
||||
#define AR_XSREV_ID_S 0
|
||||
|
@ -14,7 +14,7 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ar9160_attach.c,v 1.10 2008/11/10 04:08:05 sam Exp $
|
||||
* $Id: ar9160_attach.c,v 1.14 2008/11/27 22:30:08 sam Exp $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
|
||||
@ -129,11 +129,11 @@ ar9160Attach(uint16_t devid, HAL_SOFTC sc,
|
||||
/* override 5416 methods for our needs */
|
||||
ah->ah_detach = ar9160Detach;
|
||||
|
||||
AH5416(ah)->ah_iqCalData.calData = &ar9160_iq_cal;
|
||||
AH5416(ah)->ah_adcGainCalData.calData = &ar9160_adc_gain_cal;
|
||||
AH5416(ah)->ah_adcDcCalData.calData = &ar9160_adc_dc_cal;
|
||||
AH5416(ah)->ah_adcDcCalInitData.calData = &ar9160_adc_init_dc_cal;
|
||||
AH5416(ah)->ah_suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
|
||||
AH5416(ah)->ah_cal.iqCalData.calData = &ar9160_iq_cal;
|
||||
AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9160_adc_gain_cal;
|
||||
AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9160_adc_dc_cal;
|
||||
AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9160_adc_init_dc_cal;
|
||||
AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
|
||||
|
||||
if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
|
||||
/* reset chip */
|
||||
@ -255,14 +255,13 @@ ar9160Attach(uint16_t devid, HAL_SOFTC sc,
|
||||
* ah_miscMode is populated by ar5416FillCapabilityInfo()
|
||||
* starting from griffin. Set here to make sure that
|
||||
* AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
|
||||
* placed into hardware
|
||||
* placed into hardware.
|
||||
*/
|
||||
if (ahp->ah_miscMode != 0)
|
||||
OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
|
||||
|
||||
ar5212InitializeGainValues(ah); /* gain ladder */
|
||||
ar9160AniSetup(ah); /* Anti Noise Immunity */
|
||||
ar5416InitNfHistBuff(AH5416(ah)->ah_nfCalHist);
|
||||
ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
|
||||
|
||||
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
|
||||
|
||||
|
@ -14,6 +14,6 @@
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: version.h,v 1.31 2008/11/10 01:05:31 sam Exp $
|
||||
* $Id: version.h,v 1.64 2008/11/27 22:29:27 sam Exp $
|
||||
*/
|
||||
#define ATH_HAL_VERSION "0.11.2.0"
|
||||
#define ATH_HAL_VERSION "0.11.3.7"
|
||||
|
Loading…
Reference in New Issue
Block a user