merged changes from FreeBSD 9.0 for ath driver.

This commit is contained in:
Jérôme Duval
2012-02-23 22:41:37 +01:00
parent 7c4899ed72
commit 74bf05c232
165 changed files with 18675 additions and 5810 deletions
@@ -22,6 +22,10 @@ Depends atheroswifi : atheroswifi_rate.o ;
KernelAddon atheroswifi : KernelAddon atheroswifi :
if_ath.c if_ath.c
if_ath_pci.c if_ath_pci.c
if_ath_keycache.c
if_ath_sysctl.c
if_ath_tx.c
if_ath_tx_ht.c
glue.c glue.c
atheroswifi_hal.o atheroswifi_hal.o
atheroswifi_rate.o atheroswifi_rate.o
@@ -36,11 +40,15 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) dev ath ath_hal ar5211 ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) dev ath ath_hal ar5212 ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) dev ath ath_hal ar5212 ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) dev ath ath_hal ar5312 ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) dev ath ath_hal ar5312 ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) dev ath ath_hal ar5416 ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) dev ath ath_hal ar5416 ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) dev ath ath_hal ar9001 ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) dev ath ath_hal ar9002 ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) dev ath ath_dfs null ] ;
KernelMergeObject atheroswifi_hal.o : KernelMergeObject atheroswifi_hal.o :
ah_osdep.c ah_osdep.c
ah.c ah.c
ah_regdomain.c ah_regdomain.c
ah_eeprom_9287.c
ah_eeprom_v3.c ah_eeprom_v3.c
# AR5210 support # AR5210 support
@@ -112,16 +120,31 @@ KernelMergeObject atheroswifi_hal.o :
ar5416_reset.c ar5416_reset.c
ar5416_xmit.c ar5416_xmit.c
# AR9k support
ar9160_attach.c
ar9280.c
ar9280_attach.c
ar9285.c
ar9285_attach.c
ar9285_reset.c
# RF backend for 5416 and 9160 # RF backend for 5416 and 9160
ar2133.c ar2133.c
# AR9001 and AR9002 support
ar9130_attach.c
ar9130_eeprom.c
ar9130_phy.c
ar9160_attach.c
ar9280_attach.c
ar9280_olc.c
ar9285_attach.c
ar9285_cal.c
ar9285_diversity.c
ar9285_phy.c
ar9285_reset.c
ar9287_attach.c
ar9287_cal.c
ar9287_olc.c
ar9287_reset.c
ar9280.c
ar9285.c
ar9287.c
dfs_null.c
; ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) dev ath ath_rate sample ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) dev ath ath_rate sample ] ;
@@ -71,7 +71,7 @@ extern void ath_hal_assert_failed(const char* filename,
int lineno, const char* msg); int lineno, const char* msg);
#endif #endif
#ifdef AH_DEBUG #ifdef AH_DEBUG
extern void HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...); extern void DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...);
#endif /* AH_DEBUG */ #endif /* AH_DEBUG */
/* NB: put this here instead of the driver to avoid circular references */ /* NB: put this here instead of the driver to avoid circular references */
@@ -79,26 +79,12 @@ SYSCTL_NODE(_hw, OID_AUTO, ath, CTLFLAG_RD, 0, "Atheros driver parameters");
SYSCTL_NODE(_hw_ath, OID_AUTO, hal, CTLFLAG_RD, 0, "Atheros HAL parameters"); SYSCTL_NODE(_hw_ath, OID_AUTO, hal, CTLFLAG_RD, 0, "Atheros HAL parameters");
#ifdef AH_DEBUG #ifdef AH_DEBUG
static int ath_hal_debug = 0; int ath_hal_debug = 0;
SYSCTL_INT(_hw_ath_hal, OID_AUTO, debug, CTLFLAG_RW, &ath_hal_debug, SYSCTL_INT(_hw_ath_hal, OID_AUTO, debug, CTLFLAG_RW, &ath_hal_debug,
0, "Atheros HAL debugging printfs"); 0, "Atheros HAL debugging printfs");
TUNABLE_INT("hw.ath.hal.debug", &ath_hal_debug); TUNABLE_INT("hw.ath.hal.debug", &ath_hal_debug);
#endif /* AH_DEBUG */ #endif /* AH_DEBUG */
/* NB: these are deprecated; they exist for now for compatibility */
int ath_hal_dma_beacon_response_time = 2; /* in TU's */
SYSCTL_INT(_hw_ath_hal, OID_AUTO, dma_brt, CTLFLAG_RW,
&ath_hal_dma_beacon_response_time, 0,
"Atheros HAL DMA beacon response time");
int ath_hal_sw_beacon_response_time = 10; /* in TU's */
SYSCTL_INT(_hw_ath_hal, OID_AUTO, sw_brt, CTLFLAG_RW,
&ath_hal_sw_beacon_response_time, 0,
"Atheros HAL software beacon response time");
int ath_hal_additional_swba_backoff = 0; /* in TU's */
SYSCTL_INT(_hw_ath_hal, OID_AUTO, swba_backoff, CTLFLAG_RW,
&ath_hal_additional_swba_backoff, 0,
"Atheros HAL additional SWBA backoff time");
MALLOC_DEFINE(M_ATH_HAL, "ath_hal", "ath hal data"); MALLOC_DEFINE(M_ATH_HAL, "ath_hal", "ath hal data");
void* void*
@@ -135,16 +121,22 @@ ath_hal_ether_sprintf(const u_int8_t *mac)
} }
#ifdef AH_DEBUG #ifdef AH_DEBUG
/* This must match the definition in ath_hal/ah_debug.h */
#define HAL_DEBUG_UNMASKABLE 0xf0000000
void void
HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...) DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...)
{ {
if (ath_hal_debug & mask) { if ((mask == HAL_DEBUG_UNMASKABLE) ||
(ah->ah_config.ah_debug & mask) ||
(ath_hal_debug & mask)) {
__va_list ap; __va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
ath_hal_vprintf(ah, fmt, ap); ath_hal_vprintf(ah, fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#undef HAL_DEBUG_UNMASKABLE
#endif /* AH_DEBUG */ #endif /* AH_DEBUG */
#ifdef AH_DEBUG_ALQ #ifdef AH_DEBUG_ALQ
@@ -168,7 +160,11 @@ HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...)
static struct alq *ath_hal_alq; static struct alq *ath_hal_alq;
static int ath_hal_alq_emitdev; /* need to emit DEVICE record */ static int ath_hal_alq_emitdev; /* need to emit DEVICE record */
static u_int ath_hal_alq_lost; /* count of lost records */ static u_int ath_hal_alq_lost; /* count of lost records */
static const char *ath_hal_logfile = "/tmp/ath_hal.log"; static char ath_hal_logfile[MAXPATHLEN] = "/tmp/ath_hal.log";
SYSCTL_STRING(_hw_ath_hal, OID_AUTO, alq_logfile, CTLFLAG_RW,
&ath_hal_logfile, sizeof(kernelname), "Name of ALQ logfile");
static u_int ath_hal_alq_qsize = 64*1024; static u_int ath_hal_alq_qsize = 64*1024;
static int static int
@@ -0,0 +1,228 @@
/*-
* Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $FreeBSD$
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* This implements an empty DFS module.
*/
#include "opt_inet.h"
#include "opt_wlan.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/errno.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/bus.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_media.h>
#include <net/if_arp.h>
#include <net/ethernet.h> /* XXX for ether_sprintf */
#include <net80211/ieee80211_var.h>
#include <net/bpf.h>
#ifdef INET
#include <netinet/in.h>
#include <netinet/if_ether.h>
#endif
#include <dev/ath/if_athvar.h>
#include <dev/ath/if_athdfs.h>
#include <dev/ath/ath_hal/ah_desc.h>
/*
* Methods which are required
*/
/*
* Attach DFS to the given interface
*/
int
ath_dfs_attach(struct ath_softc *sc)
{
return 1;
}
/*
* Detach DFS from the given interface
*/
int
ath_dfs_detach(struct ath_softc *sc)
{
return 1;
}
/*
* Enable radar check
*/
void
ath_dfs_radar_enable(struct ath_softc *sc, struct ieee80211_channel *chan)
{
/* Check if the current channel is radar-enabled */
if (! IEEE80211_IS_CHAN_DFS(chan))
return;
}
/*
* Process DFS related PHY errors
*/
void
ath_dfs_process_phy_err(struct ath_softc *sc, const char *buf,
uint64_t tsf, struct ath_rx_status *rxstat)
{
}
/*
* Process the radar events and determine whether a DFS event has occured.
*
* This is designed to run outside of the RX processing path.
* The RX path will call ath_dfs_tasklet_needed() to see whether
* the task/callback running this routine needs to be called.
*/
int
ath_dfs_process_radar_event(struct ath_softc *sc,
struct ieee80211_channel *chan)
{
return 0;
}
/*
* Determine whether the the DFS check task needs to be queued.
*
* This is called in the RX task when the current batch of packets
* have been received. It will return whether there are any radar
* events for ath_dfs_process_radar_event() to handle.
*/
int
ath_dfs_tasklet_needed(struct ath_softc *sc, struct ieee80211_channel *chan)
{
return 0;
}
/*
* Handle ioctl requests from the diagnostic interface.
*
* The initial part of this code resembles ath_ioctl_diag();
* it's likely a good idea to reduce duplication between
* these two routines.
*/
int
ath_ioctl_phyerr(struct ath_softc *sc, struct ath_diag *ad)
{
unsigned int id = ad->ad_id & ATH_DIAG_ID;
void *indata = NULL;
void *outdata = NULL;
u_int32_t insize = ad->ad_in_size;
u_int32_t outsize = ad->ad_out_size;
int error = 0;
HAL_PHYERR_PARAM peout;
HAL_PHYERR_PARAM *pe;
if (ad->ad_id & ATH_DIAG_IN) {
/*
* Copy in data.
*/
indata = malloc(insize, M_TEMP, M_NOWAIT);
if (indata == NULL) {
error = ENOMEM;
goto bad;
}
error = copyin(ad->ad_in_data, indata, insize);
if (error)
goto bad;
}
if (ad->ad_id & ATH_DIAG_DYN) {
/*
* Allocate a buffer for the results (otherwise the HAL
* returns a pointer to a buffer where we can read the
* results). Note that we depend on the HAL leaving this
* pointer for us to use below in reclaiming the buffer;
* may want to be more defensive.
*/
outdata = malloc(outsize, M_TEMP, M_NOWAIT);
if (outdata == NULL) {
error = ENOMEM;
goto bad;
}
}
switch (id) {
case DFS_SET_THRESH:
if (insize < sizeof(HAL_PHYERR_PARAM)) {
error = EINVAL;
break;
}
pe = (HAL_PHYERR_PARAM *) indata;
ath_hal_enabledfs(sc->sc_ah, pe);
break;
case DFS_GET_THRESH:
memset(&peout, 0, sizeof(peout));
outsize = sizeof(HAL_PHYERR_PARAM);
ath_hal_getdfsthresh(sc->sc_ah, &peout);
pe = (HAL_PHYERR_PARAM *) outdata;
memcpy(pe, &peout, sizeof(*pe));
break;
default:
error = EINVAL;
}
if (outsize < ad->ad_out_size)
ad->ad_out_size = outsize;
if (outdata && copyout(outdata, ad->ad_out_data, ad->ad_out_size))
error = EFAULT;
bad:
if ((ad->ad_id & ATH_DIAG_IN) && indata != NULL)
free(indata, M_TEMP);
if ((ad->ad_id & ATH_DIAG_DYN) && outdata != NULL)
free(outdata, M_TEMP);
return error;
}
/*
* Get the current DFS thresholds from the HAL
*/
int
ath_dfs_get_thresholds(struct ath_softc *sc, HAL_PHYERR_PARAM *param)
{
ath_hal_getdfsthresh(sc->sc_ah, param);
return 1;
}
@@ -21,6 +21,7 @@
#include "ah.h" #include "ah.h"
#include "ah_internal.h" #include "ah_internal.h"
#include "ah_devid.h" #include "ah_devid.h"
#include "ah_eeprom.h" /* for 5ghz fast clock flag */
#include "ar5416/ar5416reg.h" /* NB: includes ar5212reg.h */ #include "ar5416/ar5416reg.h" /* NB: includes ar5212reg.h */
@@ -53,7 +54,7 @@ ath_hal_probe(uint16_t vendorid, uint16_t devid)
*/ */
struct ath_hal* struct ath_hal*
ath_hal_attach(uint16_t devid, HAL_SOFTC sc, ath_hal_attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *error) HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, HAL_STATUS *error)
{ {
struct ath_hal_chip * const *pchip; struct ath_hal_chip * const *pchip;
@@ -64,7 +65,7 @@ ath_hal_attach(uint16_t devid, HAL_SOFTC sc,
/* XXX don't have vendorid, assume atheros one works */ /* XXX don't have vendorid, assume atheros one works */
if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL) if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL)
continue; continue;
ah = chip->attach(devid, sc, st, sh, error); ah = chip->attach(devid, sc, st, sh, eepromdata, error);
if (ah != AH_NULL) { if (ah != AH_NULL) {
/* copy back private state to public area */ /* copy back private state to public area */
ah->ah_devid = AH_PRIVATE(ah)->ah_devid; ah->ah_devid = AH_PRIVATE(ah)->ah_devid;
@@ -108,12 +109,16 @@ ath_hal_mac_name(struct ath_hal *ah)
return "5416"; return "5416";
case AR_XSREV_VERSION_OWL_PCIE: case AR_XSREV_VERSION_OWL_PCIE:
return "5418"; return "5418";
case AR_XSREV_VERSION_HOWL:
return "9130";
case AR_XSREV_VERSION_SOWL: case AR_XSREV_VERSION_SOWL:
return "9160"; return "9160";
case AR_XSREV_VERSION_MERLIN: case AR_XSREV_VERSION_MERLIN:
return "9280"; return "9280";
case AR_XSREV_VERSION_KITE: case AR_XSREV_VERSION_KITE:
return "9285"; return "9285";
case AR_XSREV_VERSION_KIWI:
return "9287";
} }
return "????"; return "????";
} }
@@ -197,9 +202,16 @@ HAL_BOOL
ath_hal_wait(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val) ath_hal_wait(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val)
{ {
#define AH_TIMEOUT 1000 #define AH_TIMEOUT 1000
return ath_hal_waitfor(ah, reg, mask, val, AH_TIMEOUT);
#undef AH_TIMEOUT
}
HAL_BOOL
ath_hal_waitfor(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val, uint32_t timeout)
{
int i; int i;
for (i = 0; i < AH_TIMEOUT; i++) { for (i = 0; i < timeout; i++) {
if ((OS_REG_READ(ah, reg) & mask) == val) if ((OS_REG_READ(ah, reg) & mask) == val)
return AH_TRUE; return AH_TRUE;
OS_DELAY(10); OS_DELAY(10);
@@ -208,7 +220,6 @@ ath_hal_wait(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val)
"%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
__func__, reg, OS_REG_READ(ah, reg), mask, val); __func__, reg, OS_REG_READ(ah, reg), mask, val);
return AH_FALSE; return AH_FALSE;
#undef AH_TIMEOUT
} }
/* /*
@@ -228,6 +239,78 @@ ath_hal_reverseBits(uint32_t val, uint32_t n)
return retval; return retval;
} }
/* 802.11n related timing definitions */
#define OFDM_PLCP_BITS 22
#define HT_L_STF 8
#define HT_L_LTF 8
#define HT_L_SIG 4
#define HT_SIG 8
#define HT_STF 4
#define HT_LTF(n) ((n) * 4)
#define HT_RC_2_MCS(_rc) ((_rc) & 0xf)
#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1)
#define IS_HT_RATE(_rc) ( (_rc) & IEEE80211_RATE_MCS)
/*
* Calculate the duration of a packet whether it is 11n or legacy.
*/
uint32_t
ath_hal_pkt_txtime(struct ath_hal *ah, const HAL_RATE_TABLE *rates, uint32_t frameLen,
uint16_t rateix, HAL_BOOL isht40, HAL_BOOL shortPreamble)
{
uint8_t rc;
int numStreams;
rc = rates->info[rateix].rateCode;
/* Legacy rate? Return the old way */
if (! IS_HT_RATE(rc))
return ath_hal_computetxtime(ah, rates, frameLen, rateix, shortPreamble);
/* 11n frame - extract out the number of spatial streams */
numStreams = HT_RC_2_STREAMS(rc);
KASSERT(numStreams == 1 || numStreams == 2, ("number of spatial streams needs to be 1 or 2: MCS rate 0x%x!", rateix));
return ath_computedur_ht(frameLen, rc, numStreams, isht40, shortPreamble);
}
/*
* Calculate the transmit duration of an 11n frame.
* This only works for MCS0->MCS15.
*/
uint32_t
ath_computedur_ht(uint32_t frameLen, uint16_t rate, int streams, HAL_BOOL isht40,
HAL_BOOL isShortGI)
{
static const uint16_t ht20_bps[16] = {
26, 52, 78, 104, 156, 208, 234, 260,
52, 104, 156, 208, 312, 416, 468, 520
};
static const uint16_t ht40_bps[16] = {
54, 108, 162, 216, 324, 432, 486, 540,
108, 216, 324, 432, 648, 864, 972, 1080,
};
uint32_t bitsPerSymbol, numBits, numSymbols, txTime;
KASSERT(rate & IEEE80211_RATE_MCS, ("not mcs %d", rate));
KASSERT((rate &~ IEEE80211_RATE_MCS) < 16, ("bad mcs 0x%x", rate));
if (isht40)
bitsPerSymbol = ht40_bps[rate & 0xf];
else
bitsPerSymbol = ht20_bps[rate & 0xf];
numBits = OFDM_PLCP_BITS + (frameLen << 3);
numSymbols = howmany(numBits, bitsPerSymbol);
if (isShortGI)
txTime = ((numSymbols * 18) + 4) / 5; /* 3.6us */
else
txTime = numSymbols * 4; /* 4us */
return txTime + HT_L_STF + HT_L_LTF +
HT_L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
}
/* /*
* Compute the time to transmit a frame of length frameLen bytes * Compute the time to transmit a frame of length frameLen bytes
* using the specified rate, phy, and short preamble setting. * using the specified rate, phy, and short preamble setting.
@@ -240,6 +323,11 @@ ath_hal_computetxtime(struct ath_hal *ah,
uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime; uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
uint32_t kbps; uint32_t kbps;
/* Warn if this function is called for 11n rates; it should not be! */
if (IS_HT_RATE(rates->info[rateix].rateCode))
ath_hal_printf(ah, "%s: MCS rate? (index %d; hwrate 0x%x)\n",
__func__, rateix, rates->info[rateix].rateCode);
kbps = rates->info[rateix].rateKbps; kbps = rates->info[rateix].rateKbps;
/* /*
* index can be invalid duting dynamic Turbo transitions. * index can be invalid duting dynamic Turbo transitions.
@@ -336,6 +424,8 @@ ath_hal_chan2wmode(struct ath_hal *ah, const struct ieee80211_channel *chan)
/* 11a Turbo 11b 11g 108g */ /* 11a Turbo 11b 11g 108g */
static const uint8_t CLOCK_RATE[] = { 40, 80, 22, 44, 88 }; static const uint8_t CLOCK_RATE[] = { 40, 80, 22, 44, 88 };
#define CLOCK_FAST_RATE_5GHZ_OFDM 44
u_int u_int
ath_hal_mac_clks(struct ath_hal *ah, u_int usecs) ath_hal_mac_clks(struct ath_hal *ah, u_int usecs)
{ {
@@ -343,7 +433,12 @@ ath_hal_mac_clks(struct ath_hal *ah, u_int usecs)
u_int clks; u_int clks;
/* NB: ah_curchan may be null when called attach time */ /* NB: ah_curchan may be null when called attach time */
if (c != AH_NULL) { /* XXX merlin and later specific workaround - 5ghz fast clock is 44 */
if (c != AH_NULL && IS_5GHZ_FAST_CLOCK_EN(ah, c)) {
clks = usecs * CLOCK_FAST_RATE_5GHZ_OFDM;
if (IEEE80211_IS_CHAN_HT40(c))
clks <<= 1;
} else if (c != AH_NULL) {
clks = usecs * CLOCK_RATE[ath_hal_chan2wmode(ah, c)]; clks = usecs * CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
if (IEEE80211_IS_CHAN_HT40(c)) if (IEEE80211_IS_CHAN_HT40(c))
clks <<= 1; clks <<= 1;
@@ -359,7 +454,12 @@ ath_hal_mac_usec(struct ath_hal *ah, u_int clks)
u_int usec; u_int usec;
/* NB: ah_curchan may be null when called attach time */ /* NB: ah_curchan may be null when called attach time */
if (c != AH_NULL) { /* XXX merlin and later specific workaround - 5ghz fast clock is 44 */
if (c != AH_NULL && IS_5GHZ_FAST_CLOCK_EN(ah, c)) {
usec = clks / CLOCK_FAST_RATE_5GHZ_OFDM;
if (IEEE80211_IS_CHAN_HT40(c))
usec >>= 1;
} else if (c != AH_NULL) {
usec = clks / CLOCK_RATE[ath_hal_chan2wmode(ah, c)]; usec = clks / CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
if (IEEE80211_IS_CHAN_HT40(c)) if (IEEE80211_IS_CHAN_HT40(c))
usec >>= 1; usec >>= 1;
@@ -422,6 +522,9 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
case HAL_CAP_REG_DMN: /* regulatory domain */ case HAL_CAP_REG_DMN: /* regulatory domain */
*result = AH_PRIVATE(ah)->ah_currentRD; *result = AH_PRIVATE(ah)->ah_currentRD;
return HAL_OK; return HAL_OK;
case HAL_CAP_DFS_DMN: /* DFS Domain */
*result = AH_PRIVATE(ah)->ah_dfsDomain;
return HAL_OK;
case HAL_CAP_CIPHER: /* cipher handled in hardware */ case HAL_CAP_CIPHER: /* cipher handled in hardware */
case HAL_CAP_TKIP_MIC: /* handle TKIP MIC in hardware */ case HAL_CAP_TKIP_MIC: /* handle TKIP MIC in hardware */
return HAL_ENOTSUPP; return HAL_ENOTSUPP;
@@ -487,24 +590,75 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
return HAL_ENOTSUPP; return HAL_ENOTSUPP;
case HAL_CAP_11D: case HAL_CAP_11D:
return HAL_OK; return HAL_OK;
case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */
return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_HT: case HAL_CAP_HT:
return pCap->halHTSupport ? HAL_OK : HAL_ENOTSUPP; return pCap->halHTSupport ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_GTXTO:
return pCap->halGTTSupport ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_FAST_CC:
return pCap->halFastCCSupport ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_TX_CHAINMASK: /* mask of TX chains supported */ case HAL_CAP_TX_CHAINMASK: /* mask of TX chains supported */
*result = pCap->halTxChainMask; *result = pCap->halTxChainMask;
return HAL_OK; return HAL_OK;
case HAL_CAP_RX_CHAINMASK: /* mask of RX chains supported */ case HAL_CAP_RX_CHAINMASK: /* mask of RX chains supported */
*result = pCap->halRxChainMask; *result = pCap->halRxChainMask;
return HAL_OK; return HAL_OK;
case HAL_CAP_NUM_GPIO_PINS:
*result = pCap->halNumGpioPins;
return HAL_OK;
case HAL_CAP_CST:
return pCap->halCSTSupport ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_RTS_AGGR_LIMIT:
*result = pCap->halRtsAggrLimit;
return HAL_OK;
case HAL_CAP_4ADDR_AGGR:
return pCap->hal4AddrAggrSupport ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_EXT_CHAN_DFS:
return pCap->halExtChanDfsSupport ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_COMBINED_RADAR_RSSI:
return pCap->halUseCombinedRadarRssi ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_AUTO_SLEEP:
return pCap->halAutoSleepSupport ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_MBSSID_AGGR_SUPPORT:
return pCap->halMbssidAggrSupport ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_SPLIT_4KB_TRANS: /* hardware handles descriptors straddling 4k page boundary */
return pCap->hal4kbSplitTransSupport ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_REG_FLAG:
*result = AH_PRIVATE(ah)->ah_currentRDext;
return HAL_OK;
case HAL_CAP_BT_COEX:
return pCap->halBtCoexSupport ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_HT20_SGI:
return pCap->halHTSGI20Support ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_RXTSTAMP_PREC: /* rx desc tstamp precision (bits) */ case HAL_CAP_RXTSTAMP_PREC: /* rx desc tstamp precision (bits) */
*result = pCap->halTstampPrecision; *result = pCap->halTstampPrecision;
return HAL_OK; return HAL_OK;
case HAL_CAP_ENHANCED_DFS_SUPPORT:
return pCap->halEnhancedDfsSupport ? HAL_OK : HAL_ENOTSUPP;
/* FreeBSD-specific entries for now */
case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */
return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_INTRMASK: /* mask of supported interrupts */ case HAL_CAP_INTRMASK: /* mask of supported interrupts */
*result = pCap->halIntrMask; *result = pCap->halIntrMask;
return HAL_OK; return HAL_OK;
case HAL_CAP_BSSIDMATCH: /* hardware has disable bssid match */ case HAL_CAP_BSSIDMATCH: /* hardware has disable bssid match */
return pCap->halBssidMatchSupport ? HAL_OK : HAL_ENOTSUPP; return pCap->halBssidMatchSupport ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_STREAMS: /* number of 11n spatial streams */
switch (capability) {
case 0: /* TX */
*result = pCap->halTxStreams;
return HAL_OK;
case 1: /* RX */
*result = pCap->halRxStreams;
return HAL_OK;
default:
return HAL_ENOTSUPP;
}
case HAL_CAP_RXDESC_SELFLINK: /* hardware supports self-linked final RX descriptors correctly */
return pCap->halHasRxSelfLinkedTail ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_LONG_RXDESC_TSF: /* 32 bit TSF in RX descriptor? */
return pCap->halHasLongRxDescTsf ? HAL_OK : HAL_ENOTSUPP;
default: default:
return HAL_EINVAL; return HAL_EINVAL;
} }
@@ -779,6 +933,80 @@ ath_hal_getChanNoise(struct ath_hal *ah, const struct ieee80211_channel *chan)
return ichan->rawNoiseFloor + ichan->noiseFloorAdjust; return ichan->rawNoiseFloor + ichan->noiseFloorAdjust;
} }
/*
* Fetch the current setup of ctl/ext noise floor values.
*
* If the CHANNEL_MIMO_NF_VALID flag isn't set, the array is simply
* populated with values from NOISE_FLOOR[] + ath_hal_getNfAdjust().
*
* The caller must supply ctl/ext NF arrays which are at least
* AH_MIMO_MAX_CHAINS entries long.
*/
int
ath_hal_get_mimo_chan_noise(struct ath_hal *ah,
const struct ieee80211_channel *chan, int16_t *nf_ctl,
int16_t *nf_ext)
{
#ifdef AH_SUPPORT_AR5416
HAL_CHANNEL_INTERNAL *ichan;
int i;
ichan = ath_hal_checkchannel(ah, chan);
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_NFCAL,
"%s: invalid channel %u/0x%x; no mapping\n",
__func__, chan->ic_freq, chan->ic_flags);
for (i = 0; i < AH_MIMO_MAX_CHAINS; i++) {
nf_ctl[i] = nf_ext[i] = 0;
}
return 0;
}
/* Return 0 if there's no valid MIMO values (yet) */
if (! (ichan->privFlags & CHANNEL_MIMO_NF_VALID)) {
for (i = 0; i < AH_MIMO_MAX_CHAINS; i++) {
nf_ctl[i] = nf_ext[i] = 0;
}
return 0;
}
if (ichan->rawNoiseFloor == 0) {
WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan);
HALASSERT(mode < WIRELESS_MODE_MAX);
/*
* See the comment below - this could cause issues for
* stations which have a very low RSSI, below the
* 'normalised' NF values in NOISE_FLOOR[].
*/
for (i = 0; i < AH_MIMO_MAX_CHAINS; i++) {
nf_ctl[i] = nf_ext[i] = NOISE_FLOOR[mode] +
ath_hal_getNfAdjust(ah, ichan);
}
return 1;
} else {
/*
* The value returned here from a MIMO radio is presumed to be
* "good enough" as a NF calculation. As RSSI values are calculated
* against this, an adjusted NF may be higher than the RSSI value
* returned from a vary weak station, resulting in an obscenely
* high signal strength calculation being returned.
*
* This should be re-evaluated at a later date, along with any
* signal strength calculations which are made. Quite likely the
* RSSI values will need to be adjusted to ensure the calculations
* don't "wrap" when RSSI is less than the "adjusted" NF value.
* ("Adjust" here is via ichan->noiseFloorAdjust.)
*/
for (i = 0; i < AH_MIMO_MAX_CHAINS; i++) {
nf_ctl[i] = ichan->noiseFloorCtl[i] + ath_hal_getNfAdjust(ah, ichan);
nf_ext[i] = ichan->noiseFloorExt[i] + ath_hal_getNfAdjust(ah, ichan);
}
return 1;
}
#else
return 0;
#endif /* AH_SUPPORT_AR5416 */
}
/* /*
* Process all valid raw noise floors into the dBm noise floor values. * Process all valid raw noise floors into the dBm noise floor values.
* Though our device has no reference for a dBm noise floor, we perform * Though our device has no reference for a dBm noise floor, we perform
@@ -852,6 +1080,11 @@ ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
for (r = 0; r < ia->rows; r++) { for (r = 0; r < ia->rows; r++) {
OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0),
HAL_INI_VAL(ia, r, col)); HAL_INI_VAL(ia, r, col));
/* Analog shift register delay seems needed for Merlin - PR kern/154220 */
if (HAL_INI_VAL(ia, r, 0) >= 0x7800 && HAL_INI_VAL(ia, r, 0) < 0x7900)
OS_DELAY(100);
DMA_YIELD(regWr); DMA_YIELD(regWr);
} }
return regWr; return regWr;
@@ -879,3 +1112,149 @@ ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
} }
return regWr; return regWr;
} }
/*
* These are EEPROM board related routines which should likely live in
* a helper library of some sort.
*/
/**************************************************************
* ath_ee_getLowerUppderIndex
*
* Return indices surrounding the value in sorted integer lists.
* Requirement: the input list must be monotonically increasing
* and populated up to the list size
* Returns: match is set if an index in the array matches exactly
* or a the target is before or after the range of the array.
*/
HAL_BOOL
ath_ee_getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize,
uint16_t *indexL, uint16_t *indexR)
{
uint16_t i;
/*
* Check first and last elements for beyond ordered array cases.
*/
if (target <= pList[0]) {
*indexL = *indexR = 0;
return AH_TRUE;
}
if (target >= pList[listSize-1]) {
*indexL = *indexR = (uint16_t)(listSize - 1);
return AH_TRUE;
}
/* look for value being near or between 2 values in list */
for (i = 0; i < listSize - 1; i++) {
/*
* If value is close to the current value of the list
* then target is not between values, it is one of the values
*/
if (pList[i] == target) {
*indexL = *indexR = i;
return AH_TRUE;
}
/*
* Look for value being between current value and next value
* if so return these 2 values
*/
if (target < pList[i + 1]) {
*indexL = i;
*indexR = (uint16_t)(i + 1);
return AH_FALSE;
}
}
HALASSERT(0);
*indexL = *indexR = 0;
return AH_FALSE;
}
/**************************************************************
* ath_ee_FillVpdTable
*
* Fill the Vpdlist for indices Pmax-Pmin
* Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4
*/
HAL_BOOL
ath_ee_FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList,
uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList)
{
uint16_t i, k;
uint8_t currPwr = pwrMin;
uint16_t idxL, idxR;
HALASSERT(pwrMax > pwrMin);
for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
ath_ee_getLowerUpperIndex(currPwr, pPwrList, numIntercepts,
&(idxL), &(idxR));
if (idxR < 1)
idxR = 1; /* extrapolate below */
if (idxL == numIntercepts - 1)
idxL = (uint16_t)(numIntercepts - 2); /* extrapolate above */
if (pPwrList[idxL] == pPwrList[idxR])
k = pVpdList[idxL];
else
k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
(pPwrList[idxR] - pPwrList[idxL]) );
HALASSERT(k < 256);
pRetVpdList[i] = (uint8_t)k;
currPwr += 2; /* half dB steps */
}
return AH_TRUE;
}
/**************************************************************************
* ath_ee_interpolate
*
* Returns signed interpolated or the scaled up interpolated value
*/
int16_t
ath_ee_interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
int16_t targetLeft, int16_t targetRight)
{
int16_t rv;
if (srcRight == srcLeft) {
rv = targetLeft;
} else {
rv = (int16_t)( ((target - srcLeft) * targetRight +
(srcRight - target) * targetLeft) / (srcRight - srcLeft) );
}
return rv;
}
/*
* Adjust the TSF.
*/
void
ath_hal_adjusttsf(struct ath_hal *ah, int32_t tsfdelta)
{
/* XXX handle wrap/overflow */
OS_REG_WRITE(ah, AR_TSF_L32, OS_REG_READ(ah, AR_TSF_L32) + tsfdelta);
}
/*
* Enable or disable CCA.
*/
void
ath_hal_setcca(struct ath_hal *ah, int ena)
{
/*
* NB: fill me in; this is not provided by default because disabling
* CCA in most locales violates regulatory.
*/
}
/*
* Get CCA setting.
*/
int
ath_hal_getcca(struct ath_hal *ah)
{
u_int32_t diag;
if (ath_hal_getcapability(ah, HAL_CAP_DIAG, 0, &diag) != HAL_OK)
return 1;
return ((diag & 0x500000) == 0);
}
@@ -30,6 +30,14 @@
#include "ah_osdep.h" #include "ah_osdep.h"
/*
* The maximum number of TX/RX chains supported.
* This is intended to be used by various statistics gathering operations
* (NF, RSSI, EVM).
*/
#define AH_MIMO_MAX_CHAINS 3
#define AH_MIMO_MAX_EVM_PILOTS 6
/* /*
* __ahdecl is analogous to _cdecl; it defines the calling * __ahdecl is analogous to _cdecl; it defines the calling
* convention used within the HAL. For most systems this * convention used within the HAL. For most systems this
@@ -101,16 +109,46 @@ typedef enum {
HAL_CAP_TPC_ACK = 26, /* ack txpower with per-packet tpc */ HAL_CAP_TPC_ACK = 26, /* ack txpower with per-packet tpc */
HAL_CAP_TPC_CTS = 27, /* cts txpower with per-packet tpc */ HAL_CAP_TPC_CTS = 27, /* cts txpower with per-packet tpc */
HAL_CAP_11D = 28, /* 11d beacon support for changing cc */ HAL_CAP_11D = 28, /* 11d beacon support for changing cc */
HAL_CAP_INTMIT = 29, /* interference mitigation */
HAL_CAP_RXORN_FATAL = 30, /* HAL_INT_RXORN treated as fatal */ HAL_CAP_HT = 30, /* hardware can support HT */
HAL_CAP_HT = 31, /* hardware can support HT */ HAL_CAP_GTXTO = 31, /* hardware supports global tx timeout */
HAL_CAP_TX_CHAINMASK = 32, /* mask of TX chains supported */ HAL_CAP_FAST_CC = 32, /* hardware supports fast channel change */
HAL_CAP_RX_CHAINMASK = 33, /* mask of RX chains supported */ HAL_CAP_TX_CHAINMASK = 33, /* mask of TX chains supported */
HAL_CAP_RXTSTAMP_PREC = 34, /* rx desc tstamp precision (bits) */ HAL_CAP_RX_CHAINMASK = 34, /* mask of RX chains supported */
HAL_CAP_BB_HANG = 35, /* can baseband hang */ HAL_CAP_NUM_GPIO_PINS = 36, /* number of GPIO pins */
HAL_CAP_MAC_HANG = 36, /* can MAC hang */
HAL_CAP_INTRMASK = 37, /* bitmask of supported interrupts */ HAL_CAP_CST = 38, /* hardware supports carrier sense timeout */
HAL_CAP_BSSIDMATCH = 38, /* hardware has disable bssid match */
HAL_CAP_RTS_AGGR_LIMIT = 42, /* aggregation limit with RTS */
HAL_CAP_4ADDR_AGGR = 43, /* hardware is capable of 4addr aggregation */
HAL_CAP_DFS_DMN = 44, /* current DFS domain */
HAL_CAP_EXT_CHAN_DFS = 45, /* DFS support for extension channel */
HAL_CAP_COMBINED_RADAR_RSSI = 46, /* Is combined RSSI for radar accurate */
HAL_CAP_AUTO_SLEEP = 48, /* hardware can go to network sleep
automatically after waking up to receive TIM */
HAL_CAP_MBSSID_AGGR_SUPPORT = 49, /* Support for mBSSID Aggregation */
HAL_CAP_SPLIT_4KB_TRANS = 50, /* hardware supports descriptors straddling a 4k page boundary */
HAL_CAP_REG_FLAG = 51, /* Regulatory domain flags */
HAL_CAP_BT_COEX = 60, /* hardware is capable of bluetooth coexistence */
HAL_CAP_HT20_SGI = 96, /* hardware supports HT20 short GI */
HAL_CAP_RXTSTAMP_PREC = 100, /* rx desc tstamp precision (bits) */
HAL_CAP_ENHANCED_DFS_SUPPORT = 117, /* hardware supports enhanced DFS */
/* The following are private to the FreeBSD HAL (224 onward) */
HAL_CAP_INTMIT = 229, /* interference mitigation */
HAL_CAP_RXORN_FATAL = 230, /* HAL_INT_RXORN treated as fatal */
HAL_CAP_BB_HANG = 235, /* can baseband hang */
HAL_CAP_MAC_HANG = 236, /* can MAC hang */
HAL_CAP_INTRMASK = 237, /* bitmask of supported interrupts */
HAL_CAP_BSSIDMATCH = 238, /* hardware has disable bssid match */
HAL_CAP_STREAMS = 239, /* how many 802.11n spatial streams are available */
HAL_CAP_RXDESC_SELFLINK = 242, /* support a self-linked tail RX descriptor */
HAL_CAP_LONG_RXDESC_TSF = 243, /* hardware supports 32bit TSF in RX descriptor */
} HAL_CAPABILITY_TYPE; } HAL_CAPABILITY_TYPE;
/* /*
@@ -139,6 +177,7 @@ typedef enum {
HAL_TX_QUEUE_BEACON = 2, /* beacon xmit q */ HAL_TX_QUEUE_BEACON = 2, /* beacon xmit q */
HAL_TX_QUEUE_CAB = 3, /* "crap after beacon" xmit q */ HAL_TX_QUEUE_CAB = 3, /* "crap after beacon" xmit q */
HAL_TX_QUEUE_UAPSD = 4, /* u-apsd power save xmit q */ HAL_TX_QUEUE_UAPSD = 4, /* u-apsd power save xmit q */
HAL_TX_QUEUE_PSPOLL = 5, /* power save poll xmit q */
} HAL_TX_QUEUE; } HAL_TX_QUEUE;
#define HAL_NUM_TX_QUEUES 10 /* max possible # of queues */ #define HAL_NUM_TX_QUEUES 10 /* max possible # of queues */
@@ -287,6 +326,10 @@ typedef enum {
/* Rx Filter Frame Types */ /* Rx Filter Frame Types */
typedef enum { typedef enum {
/*
* These bits correspond to AR_RX_FILTER for all chips.
* Not all bits are supported by all chips.
*/
HAL_RX_FILTER_UCAST = 0x00000001, /* Allow unicast frames */ HAL_RX_FILTER_UCAST = 0x00000001, /* Allow unicast frames */
HAL_RX_FILTER_MCAST = 0x00000002, /* Allow multicast frames */ HAL_RX_FILTER_MCAST = 0x00000002, /* Allow multicast frames */
HAL_RX_FILTER_BCAST = 0x00000004, /* Allow broadcast frames */ HAL_RX_FILTER_BCAST = 0x00000004, /* Allow broadcast frames */
@@ -295,9 +338,19 @@ typedef enum {
HAL_RX_FILTER_PROM = 0x00000020, /* Promiscuous mode */ HAL_RX_FILTER_PROM = 0x00000020, /* Promiscuous mode */
HAL_RX_FILTER_PROBEREQ = 0x00000080, /* Allow probe request frames */ HAL_RX_FILTER_PROBEREQ = 0x00000080, /* Allow probe request frames */
HAL_RX_FILTER_PHYERR = 0x00000100, /* Allow phy errors */ HAL_RX_FILTER_PHYERR = 0x00000100, /* Allow phy errors */
HAL_RX_FILTER_PHYRADAR = 0x00000200, /* Allow phy radar errors */
HAL_RX_FILTER_COMPBAR = 0x00000400, /* Allow compressed BAR */ HAL_RX_FILTER_COMPBAR = 0x00000400, /* Allow compressed BAR */
HAL_RX_FILTER_BSSID = 0x00000800, /* Disable BSSID match */ HAL_RX_FILTER_COMP_BA = 0x00000800, /* Allow compressed blockack */
HAL_RX_FILTER_PHYRADAR = 0x00002000, /* Allow phy radar errors */
HAL_RX_FILTER_PSPOLL = 0x00004000, /* Allow PS-POLL frames */
HAL_RX_FILTER_MCAST_BCAST_ALL = 0x00008000,
/* Allow all mcast/bcast frames */
/*
* Magic RX filter flags that aren't targetting hardware bits
* but instead the HAL sets individual bits - eg PHYERR will result
* in OFDM/CCK timing error frames being received.
*/
HAL_RX_FILTER_BSSID = 0x40000000, /* Disable BSSID match */
} HAL_RX_FILTER; } HAL_RX_FILTER;
typedef enum { typedef enum {
@@ -324,6 +377,7 @@ typedef enum {
HAL_INT_RXORN = 0x00000020, HAL_INT_RXORN = 0x00000020,
HAL_INT_TX = 0x00000040, /* Non-common mapping */ HAL_INT_TX = 0x00000040, /* Non-common mapping */
HAL_INT_TXDESC = 0x00000080, HAL_INT_TXDESC = 0x00000080,
HAL_INT_TIM_TIMER= 0x00000100,
HAL_INT_TXURN = 0x00000800, HAL_INT_TXURN = 0x00000800,
HAL_INT_MIB = 0x00001000, HAL_INT_MIB = 0x00001000,
HAL_INT_RXPHY = 0x00004000, HAL_INT_RXPHY = 0x00004000,
@@ -592,6 +646,141 @@ struct ath_tx_status;
struct ath_rx_status; struct ath_rx_status;
struct ieee80211_channel; struct ieee80211_channel;
/*
* This is a channel survey sample entry.
*
* The AR5212 ANI routines fill these samples. The ANI code then uses it
* when calculating listen time; it is also exported via a diagnostic
* API.
*/
typedef struct {
uint32_t seq_num;
uint32_t tx_busy;
uint32_t rx_busy;
uint32_t chan_busy;
uint32_t cycle_count;
} HAL_SURVEY_SAMPLE;
/*
* This provides 3.2 seconds of sample space given an
* ANI time of 1/10th of a second. This may not be enough!
*/
#define CHANNEL_SURVEY_SAMPLE_COUNT 32
typedef struct {
HAL_SURVEY_SAMPLE samples[CHANNEL_SURVEY_SAMPLE_COUNT];
uint32_t cur_sample; /* current sample in sequence */
uint32_t cur_seq; /* current sequence number */
} HAL_CHANNEL_SURVEY;
/*
* ANI commands.
*
* These are used both internally and externally via the diagnostic
* API.
*
* Note that this is NOT the ANI commands being used via the INTMIT
* capability - that has a different mapping for some reason.
*/
typedef enum {
HAL_ANI_PRESENT = 0, /* is ANI support present */
HAL_ANI_NOISE_IMMUNITY_LEVEL = 1, /* set level */
HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION = 2, /* enable/disable */
HAL_ANI_CCK_WEAK_SIGNAL_THR = 3, /* enable/disable */
HAL_ANI_FIRSTEP_LEVEL = 4, /* set level */
HAL_ANI_SPUR_IMMUNITY_LEVEL = 5, /* set level */
HAL_ANI_MODE = 6, /* 0 => manual, 1 => auto (XXX do not change) */
HAL_ANI_PHYERR_RESET = 7, /* reset phy error stats */
} HAL_ANI_CMD;
/*
* This is the layout of the ANI INTMIT capability.
*
* Notice that the command values differ to HAL_ANI_CMD.
*/
typedef enum {
HAL_CAP_INTMIT_PRESENT = 0,
HAL_CAP_INTMIT_ENABLE = 1,
HAL_CAP_INTMIT_NOISE_IMMUNITY_LEVEL = 2,
HAL_CAP_INTMIT_OFDM_WEAK_SIGNAL_LEVEL = 3,
HAL_CAP_INTMIT_CCK_WEAK_SIGNAL_THR = 4,
HAL_CAP_INTMIT_FIRSTEP_LEVEL = 5,
HAL_CAP_INTMIT_SPUR_IMMUNITY_LEVEL = 6
} HAL_CAP_INTMIT_CMD;
typedef struct {
int32_t pe_firpwr; /* FIR pwr out threshold */
int32_t pe_rrssi; /* Radar rssi thresh */
int32_t pe_height; /* Pulse height thresh */
int32_t pe_prssi; /* Pulse rssi thresh */
int32_t pe_inband; /* Inband thresh */
/* The following params are only for AR5413 and later */
u_int32_t pe_relpwr; /* Relative power threshold in 0.5dB steps */
u_int32_t pe_relstep; /* Pulse Relative step threshold in 0.5dB steps */
u_int32_t pe_maxlen; /* Max length of radar sign in 0.8us units */
int32_t pe_usefir128; /* Use the average in-band power measured over 128 cycles */
int32_t pe_blockradar; /*
* Enable to block radar check if pkt detect is done via OFDM
* weak signal detect or pkt is detected immediately after tx
* to rx transition
*/
int32_t pe_enmaxrssi; /*
* Enable to use the max rssi instead of the last rssi during
* fine gain changes for radar detection
*/
int32_t pe_extchannel; /* Enable DFS on ext channel */
int32_t pe_enabled; /* Whether radar detection is enabled */
} HAL_PHYERR_PARAM;
#define HAL_PHYERR_PARAM_NOVAL 65535
#define HAL_PHYERR_PARAM_ENABLE 0x8000 /* Enable/Disable if applicable */
/*
* DFS operating mode flags.
*/
typedef enum {
HAL_DFS_UNINIT_DOMAIN = 0, /* Uninitialized dfs domain */
HAL_DFS_FCC_DOMAIN = 1, /* FCC3 dfs domain */
HAL_DFS_ETSI_DOMAIN = 2, /* ETSI dfs domain */
HAL_DFS_MKK4_DOMAIN = 3, /* Japan dfs domain */
} HAL_DFS_DOMAIN;
/*
* Flag for setting QUIET period
*/
typedef enum {
HAL_QUIET_DISABLE = 0x0,
HAL_QUIET_ENABLE = 0x1,
HAL_QUIET_ADD_CURRENT_TSF = 0x2, /* add current TSF to next_start offset */
HAL_QUIET_ADD_SWBA_RESP_TIME = 0x4, /* add beacon response time to next_start offset */
} HAL_QUIET_FLAG;
#define HAL_DFS_EVENT_PRICH 0x0000001
#define HAL_DFS_EVENT_EXTCH 0x0000002
#define HAL_DFS_EVENT_EXTEARLY 0x0000004
#define HAL_DFS_EVENT_ISDC 0x0000008
struct hal_dfs_event {
uint64_t re_full_ts; /* 64-bit full timestamp from interrupt time */
uint32_t re_ts; /* Original 15 bit recv timestamp */
uint8_t re_rssi; /* rssi of radar event */
uint8_t re_dur; /* duration of radar pulse */
uint32_t re_flags; /* Flags (see above) */
};
typedef struct hal_dfs_event HAL_DFS_EVENT;
typedef struct
{
int ah_debug; /* only used if AH_DEBUG is defined */
int ah_ar5416_biasadj; /* enable AR2133 radio specific bias fiddling */
/* NB: these are deprecated; they exist for now for compatibility */
int ah_dma_beacon_response_time;/* in TU's */
int ah_sw_beacon_response_time; /* in TU's */
int ah_additional_swba_backoff; /* in TU's */
} HAL_OPS_CONFIG;
/* /*
* Hardware Access Layer (HAL) API. * Hardware Access Layer (HAL) API.
* *
@@ -618,6 +807,9 @@ struct ath_hal {
uint16_t ah_analog5GhzRev;/* 5GHz radio revision */ uint16_t ah_analog5GhzRev;/* 5GHz radio revision */
uint16_t ah_analog2GhzRev;/* 2GHz radio revision */ uint16_t ah_analog2GhzRev;/* 2GHz radio revision */
uint16_t *ah_eepromdata; /* eeprom buffer, if needed */
HAL_OPS_CONFIG ah_config;
const HAL_RATE_TABLE *__ahdecl(*ah_getRateTable)(struct ath_hal *, const HAL_RATE_TABLE *__ahdecl(*ah_getRateTable)(struct ath_hal *,
u_int mode); u_int mode);
void __ahdecl(*ah_detach)(struct ath_hal*); void __ahdecl(*ah_detach)(struct ath_hal*);
@@ -679,6 +871,8 @@ struct ath_hal {
struct ath_desc *, struct ath_tx_status *); struct ath_desc *, struct ath_tx_status *);
void __ahdecl(*ah_getTxIntrQueue)(struct ath_hal *, uint32_t *); void __ahdecl(*ah_getTxIntrQueue)(struct ath_hal *, uint32_t *);
void __ahdecl(*ah_reqTxIntrDesc)(struct ath_hal *, struct ath_desc*); void __ahdecl(*ah_reqTxIntrDesc)(struct ath_hal *, struct ath_desc*);
HAL_BOOL __ahdecl(*ah_getTxCompletionRates)(struct ath_hal *,
const struct ath_desc *ds, int *rates, int *tries);
/* Receive Functions */ /* Receive Functions */
uint32_t __ahdecl(*ah_getRxDP)(struct ath_hal*); uint32_t __ahdecl(*ah_getRxDP)(struct ath_hal*);
@@ -704,8 +898,13 @@ struct ath_hal {
void __ahdecl(*ah_rxMonitor)(struct ath_hal *, void __ahdecl(*ah_rxMonitor)(struct ath_hal *,
const HAL_NODE_STATS *, const HAL_NODE_STATS *,
const struct ieee80211_channel *); const struct ieee80211_channel *);
void __ahdecl(*ah_aniPoll)(struct ath_hal *,
const struct ieee80211_channel *);
void __ahdecl(*ah_procMibEvent)(struct ath_hal *, void __ahdecl(*ah_procMibEvent)(struct ath_hal *,
const HAL_NODE_STATS *); const HAL_NODE_STATS *);
void __ahdecl(*ah_rxAntCombDiversity)(struct ath_hal *,
struct ath_rx_status *,
unsigned long, int);
/* Misc Functions */ /* Misc Functions */
HAL_STATUS __ahdecl(*ah_getCapability)(struct ath_hal *, HAL_STATUS __ahdecl(*ah_getCapability)(struct ath_hal *,
@@ -757,6 +956,19 @@ struct ath_hal {
u_int __ahdecl(*ah_getCTSTimeout)(struct ath_hal*); u_int __ahdecl(*ah_getCTSTimeout)(struct ath_hal*);
HAL_BOOL __ahdecl(*ah_setDecompMask)(struct ath_hal*, uint16_t, int); HAL_BOOL __ahdecl(*ah_setDecompMask)(struct ath_hal*, uint16_t, int);
void __ahdecl(*ah_setCoverageClass)(struct ath_hal*, uint8_t, int); void __ahdecl(*ah_setCoverageClass)(struct ath_hal*, uint8_t, int);
HAL_STATUS __ahdecl(*ah_setQuiet)(struct ath_hal *ah, uint32_t period,
uint32_t duration, uint32_t nextStart,
HAL_QUIET_FLAG flag);
/* DFS functions */
void __ahdecl(*ah_enableDfs)(struct ath_hal *ah,
HAL_PHYERR_PARAM *pe);
void __ahdecl(*ah_getDfsThresh)(struct ath_hal *ah,
HAL_PHYERR_PARAM *pe);
HAL_BOOL __ahdecl(*ah_procRadarEvent)(struct ath_hal *ah,
struct ath_rx_status *rxs, uint64_t fulltsf,
const char *buf, HAL_DFS_EVENT *event);
HAL_BOOL __ahdecl(*ah_isFastClockEnabled)(struct ath_hal *ah);
/* Key Cache Functions */ /* Key Cache Functions */
uint32_t __ahdecl(*ah_getKeyCacheSize)(struct ath_hal*); uint32_t __ahdecl(*ah_getKeyCacheSize)(struct ath_hal*);
@@ -785,6 +997,33 @@ struct ath_hal {
void __ahdecl(*ah_setStationBeaconTimers)(struct ath_hal*, void __ahdecl(*ah_setStationBeaconTimers)(struct ath_hal*,
const HAL_BEACON_STATE *); const HAL_BEACON_STATE *);
void __ahdecl(*ah_resetStationBeaconTimers)(struct ath_hal*); void __ahdecl(*ah_resetStationBeaconTimers)(struct ath_hal*);
uint64_t __ahdecl(*ah_getNextTBTT)(struct ath_hal *);
/* 802.11n Functions */
HAL_BOOL __ahdecl(*ah_chainTxDesc)(struct ath_hal *,
struct ath_desc *, u_int, u_int, HAL_PKT_TYPE,
u_int, HAL_CIPHER, uint8_t, u_int, HAL_BOOL,
HAL_BOOL);
HAL_BOOL __ahdecl(*ah_setupFirstTxDesc)(struct ath_hal *,
struct ath_desc *, u_int, u_int, u_int,
u_int, u_int, u_int, u_int, u_int);
HAL_BOOL __ahdecl(*ah_setupLastTxDesc)(struct ath_hal *,
struct ath_desc *, const struct ath_desc *);
void __ahdecl(*ah_set11nRateScenario)(struct ath_hal *,
struct ath_desc *, u_int, u_int,
HAL_11N_RATE_SERIES [], u_int, u_int);
void __ahdecl(*ah_set11nAggrMiddle)(struct ath_hal *,
struct ath_desc *, u_int);
void __ahdecl(*ah_clr11nAggr)(struct ath_hal *,
struct ath_desc *);
void __ahdecl(*ah_set11nBurstDuration)(struct ath_hal *,
struct ath_desc *, u_int);
uint32_t __ahdecl(*ah_get11nExtBusy)(struct ath_hal *);
void __ahdecl(*ah_set11nMac2040)(struct ath_hal *,
HAL_HT_MACMODE);
HAL_HT_RXCLEAR __ahdecl(*ah_get11nRxClear)(struct ath_hal *ah);
void __ahdecl(*ah_set11nRxClear)(struct ath_hal *,
HAL_HT_RXCLEAR);
/* Interrupt functions */ /* Interrupt functions */
HAL_BOOL __ahdecl(*ah_isInterruptPending)(struct ath_hal*); HAL_BOOL __ahdecl(*ah_isInterruptPending)(struct ath_hal*);
@@ -814,7 +1053,7 @@ extern const char *__ahdecl ath_hal_probe(uint16_t vendorid, uint16_t devid);
* be returned if the status parameter is non-zero. * be returned if the status parameter is non-zero.
*/ */
extern struct ath_hal * __ahdecl ath_hal_attach(uint16_t devid, HAL_SOFTC, extern struct ath_hal * __ahdecl ath_hal_attach(uint16_t devid, HAL_SOFTC,
HAL_BUS_TAG, HAL_BUS_HANDLE, HAL_STATUS* status); HAL_BUS_TAG, HAL_BUS_HANDLE, uint16_t *eepromdata, HAL_STATUS* status);
extern const char *ath_hal_mac_name(struct ath_hal *); extern const char *ath_hal_mac_name(struct ath_hal *);
extern const char *ath_hal_rf_name(struct ath_hal *); extern const char *ath_hal_rf_name(struct ath_hal *);
@@ -863,6 +1102,14 @@ extern HAL_STATUS __ahdecl ath_hal_set_channels(struct ath_hal *,
struct ieee80211_channel *chans, int nchans, struct ieee80211_channel *chans, int nchans,
HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn); HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn);
/*
* Fetch the ctl/ext noise floor values reported by a MIMO
* radio. Returns 1 for valid results, 0 for invalid channel.
*/
extern int __ahdecl ath_hal_get_mimo_chan_noise(struct ath_hal *ah,
const struct ieee80211_channel *chan, int16_t *nf_ctl,
int16_t *nf_ext);
/* /*
* Calibrate noise floor data following a channel scan or similar. * Calibrate noise floor data following a channel scan or similar.
* This must be called prior retrieving noise floor data. * This must be called prior retrieving noise floor data.
@@ -875,9 +1122,38 @@ extern void __ahdecl ath_hal_process_noisefloor(struct ath_hal *ah);
extern u_int __ahdecl ath_hal_getwirelessmodes(struct ath_hal*); extern u_int __ahdecl ath_hal_getwirelessmodes(struct ath_hal*);
/* /*
* Calculate the transmit duration of a frame. * Calculate the packet TX time for a legacy or 11n frame
*/
extern uint32_t __ahdecl ath_hal_pkt_txtime(struct ath_hal *ah,
const HAL_RATE_TABLE *rates, uint32_t frameLen,
uint16_t rateix, HAL_BOOL isht40, HAL_BOOL shortPreamble);
/*
* Calculate the duration of an 11n frame.
*/
extern uint32_t __ahdecl ath_computedur_ht(uint32_t frameLen, uint16_t rate,
int streams, HAL_BOOL isht40, HAL_BOOL isShortGI);
/*
* Calculate the transmit duration of a legacy frame.
*/ */
extern uint16_t __ahdecl ath_hal_computetxtime(struct ath_hal *, extern uint16_t __ahdecl ath_hal_computetxtime(struct ath_hal *,
const HAL_RATE_TABLE *rates, uint32_t frameLen, const HAL_RATE_TABLE *rates, uint32_t frameLen,
uint16_t rateix, HAL_BOOL shortPreamble); uint16_t rateix, HAL_BOOL shortPreamble);
/*
* Adjust the TSF.
*/
extern void __ahdecl ath_hal_adjusttsf(struct ath_hal *ah, int32_t tsfdelta);
/*
* Enable or disable CCA.
*/
void __ahdecl ath_hal_setcca(struct ath_hal *ah, int ena);
/*
* Get CCA setting.
*/
int __ahdecl ath_hal_getcca(struct ath_hal *ah);
#endif /* _ATH_AH_H_ */ #endif /* _ATH_AH_H_ */
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ah_debug.h,v 1.1 2008/10/12 16:44:34 sam Exp $ * $FreeBSD$
*/ */
#ifndef _ATH_AH_DEBUG_H_ #ifndef _ATH_AH_DEBUG_H_
#define _ATH_AH_DEBUG_H_ #define _ATH_AH_DEBUG_H_
@@ -42,8 +42,13 @@ enum {
HAL_DEBUG_EEPROM = 0x00008000, HAL_DEBUG_EEPROM = 0x00008000,
HAL_DEBUG_BEACON = 0x00010000, /* beacon setup work */ HAL_DEBUG_BEACON = 0x00010000, /* beacon setup work */
HAL_DEBUG_POWER = 0x00020000, /* power management */ HAL_DEBUG_POWER = 0x00020000, /* power management */
HAL_DEBUG_INTERRUPT = 0x00000080, /* interrupt handling */ HAL_DEBUG_GPIO = 0x00040000, /* GPIO debugging */
HAL_DEBUG_INTERRUPT = 0x00080000, /* interrupt handling */
HAL_DEBUG_DIVERSITY = 0x00100000, /* diversity debugging */
HAL_DEBUG_DFS = 0x00200000, /* DFS debugging */
HAL_DEBUG_HANG = 0x00400000, /* BB/MAC hang debugging */
HAL_DEBUG_UNMASKABLE = 0xf0000000, /* always printed */
HAL_DEBUG_ANY = 0xffffffff HAL_DEBUG_ANY = 0xffffffff
}; };
#endif /* _ATH_AH_DEBUG_H_ */ #endif /* _ATH_AH_DEBUG_H_ */
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ah_decode.h,v 1.4 2008/11/10 04:08:00 sam Exp $ * $FreeBSD$
*/ */
#ifndef _ATH_AH_DECODE_H_ #ifndef _ATH_AH_DECODE_H_
#define _ATH_AH_DECODE_H_ #define _ATH_AH_DECODE_H_
@@ -51,5 +51,15 @@ enum {
AH_MARK_ANI_RESET, /* ar*AniReset, opmode */ AH_MARK_ANI_RESET, /* ar*AniReset, opmode */
AH_MARK_ANI_POLL, /* ar*AniReset, listen time */ AH_MARK_ANI_POLL, /* ar*AniReset, listen time */
AH_MARK_ANI_CONTROL, /* ar*AniReset, cmd */ AH_MARK_ANI_CONTROL, /* ar*AniReset, cmd */
AH_MARK_RX_CTL, /* RX DMA control */
}; };
enum {
AH_MARK_RX_CTL_PCU_START,
AH_MARK_RX_CTL_PCU_STOP,
AH_MARK_RX_CTL_DMA_START,
AH_MARK_RX_CTL_DMA_STOP,
AH_MARK_RX_CTL_DMA_STOP_ERR,
};
#endif /* _ATH_AH_DECODE_H_ */ #endif /* _ATH_AH_DECODE_H_ */
@@ -113,6 +113,8 @@ struct ath_rx_status {
uint32_t rs_evm0; /* evm bytes */ uint32_t rs_evm0; /* evm bytes */
uint32_t rs_evm1; uint32_t rs_evm1;
uint32_t rs_evm2; uint32_t rs_evm2;
uint32_t rs_evm3; /* needed for ar9300 and later */
uint32_t rs_evm4; /* needed for ar9300 and later */
#endif /* AH_SUPPORT_AR5416 */ #endif /* AH_SUPPORT_AR5416 */
}; };
@@ -142,7 +144,7 @@ enum {
HAL_PHYERR_RADAR = 5, /* Radar detect */ HAL_PHYERR_RADAR = 5, /* Radar detect */
HAL_PHYERR_SERVICE = 6, /* Illegal service */ HAL_PHYERR_SERVICE = 6, /* Illegal service */
HAL_PHYERR_TOR = 7, /* Transmit override receive */ HAL_PHYERR_TOR = 7, /* Transmit override receive */
/* NB: these are specific to the 5212 */ /* NB: these are specific to the 5212 and later */
HAL_PHYERR_OFDM_TIMING = 17, /* */ HAL_PHYERR_OFDM_TIMING = 17, /* */
HAL_PHYERR_OFDM_SIGNAL_PARITY = 18, /* */ HAL_PHYERR_OFDM_SIGNAL_PARITY = 18, /* */
HAL_PHYERR_OFDM_RATE_ILLEGAL = 19, /* */ HAL_PHYERR_OFDM_RATE_ILLEGAL = 19, /* */
@@ -150,11 +152,18 @@ enum {
HAL_PHYERR_OFDM_POWER_DROP = 21, /* */ HAL_PHYERR_OFDM_POWER_DROP = 21, /* */
HAL_PHYERR_OFDM_SERVICE = 22, /* */ HAL_PHYERR_OFDM_SERVICE = 22, /* */
HAL_PHYERR_OFDM_RESTART = 23, /* */ HAL_PHYERR_OFDM_RESTART = 23, /* */
HAL_PHYERR_FALSE_RADAR_EXT = 24, /* */
HAL_PHYERR_CCK_TIMING = 25, /* */ HAL_PHYERR_CCK_TIMING = 25, /* */
HAL_PHYERR_CCK_HEADER_CRC = 26, /* */ HAL_PHYERR_CCK_HEADER_CRC = 26, /* */
HAL_PHYERR_CCK_RATE_ILLEGAL = 27, /* */ HAL_PHYERR_CCK_RATE_ILLEGAL = 27, /* */
HAL_PHYERR_CCK_SERVICE = 30, /* */ HAL_PHYERR_CCK_SERVICE = 30, /* */
HAL_PHYERR_CCK_RESTART = 31, /* */ HAL_PHYERR_CCK_RESTART = 31, /* */
HAL_PHYERR_CCK_LENGTH_ILLEGAL = 32, /* */
HAL_PHYERR_CCK_POWER_DROP = 33, /* */
/* AR5416 and later */
HAL_PHYERR_HT_CRC_ERROR = 34, /* */
HAL_PHYERR_HT_LENGTH_ILLEGAL = 35, /* */
HAL_PHYERR_HT_RATE_ILLEGAL = 36, /* */
}; };
/* value found in rs_keyix to mark invalid entries */ /* value found in rs_keyix to mark invalid entries */
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ah_devid.h,v 1.4 2008/10/06 18:32:46 sam Exp $ * $FreeBSD$
*/ */
#ifndef _DEV_ATH_DEVID_H_ #ifndef _DEV_ATH_DEVID_H_
@@ -74,10 +74,14 @@
/* AR5416 compatible devid's */ /* AR5416 compatible devid's */
#define AR5416_DEVID_PCI 0x0023 /* AR5416 PCI (MB/CB) Owl */ #define AR5416_DEVID_PCI 0x0023 /* AR5416 PCI (MB/CB) Owl */
#define AR5416_DEVID_PCIE 0x0024 /* AR5416 PCI-E (XB) Owl */ #define AR5416_DEVID_PCIE 0x0024 /* AR5416 PCI-E (XB) Owl */
#define AR5416_AR9130_DEVID 0x000b /* AR9130 SoC WiMAC */
#define AR9160_DEVID_PCI 0x0027 /* AR9160 PCI Sowl */ #define AR9160_DEVID_PCI 0x0027 /* AR9160 PCI Sowl */
#define AR9280_DEVID_PCI 0x0029 /* AR9280 PCI Merlin */ #define AR9280_DEVID_PCI 0x0029 /* AR9280 PCI Merlin */
#define AR9280_DEVID_PCIE 0x002a /* AR9280 PCI-E Merlin */ #define AR9280_DEVID_PCIE 0x002a /* AR9280 PCI-E Merlin */
#define AR9285_DEVID_PCIE 0x002b /* AR9285 PCI-E Kite */ #define AR9285_DEVID_PCIE 0x002b /* AR9285 PCI-E Kite */
#define AR2427_DEVID_PCIE 0x002c /* AR2427 PCI-E w/ 802.11n bonded out */
#define AR9287_DEVID_PCI 0x002d /* AR9227 PCI Kiwi */
#define AR9287_DEVID_PCIE 0x002e /* AR9287 PCI-E Kiwi */
#define AR_SUBVENDOR_ID_NOG 0x0e11 /* No 11G subvendor ID */ #define AR_SUBVENDOR_ID_NOG 0x0e11 /* No 11G subvendor ID */
#define AR_SUBVENDOR_ID_NEW_A 0x7065 /* Update device to new RD */ #define AR_SUBVENDOR_ID_NEW_A 0x7065 /* Update device to new RD */
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2002-2009 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.
*
* $FreeBSD$
*/
#ifndef _ATH_AH_DIAGCODES_H_
#define _ATH_AH_DIAGCODES_H_
/*
* Atheros Device Hardware Access Layer (HAL).
*
* Internal diagnostic API definitions.
*/
/*
* Diagnostic interface. This is an open-ended interface that
* is opaque to applications. Diagnostic programs use this to
* retrieve internal data structures, etc. There is no guarantee
* that calling conventions for calls other than HAL_DIAG_REVS
* are stable between HAL releases; a diagnostic application must
* use the HAL revision information to deal with ABI/API differences.
*
* NB: do not renumber these, certain codes are publicly used.
*/
enum {
HAL_DIAG_REVS = 0, /* MAC/PHY/Radio revs */
HAL_DIAG_EEPROM = 1, /* EEPROM contents */
HAL_DIAG_EEPROM_EXP_11A = 2, /* EEPROM 5112 power exp for 11a */
HAL_DIAG_EEPROM_EXP_11B = 3, /* EEPROM 5112 power exp for 11b */
HAL_DIAG_EEPROM_EXP_11G = 4, /* EEPROM 5112 power exp for 11g */
HAL_DIAG_ANI_CURRENT = 5, /* ANI current channel state */
HAL_DIAG_ANI_OFDM = 6, /* ANI OFDM timing error stats */
HAL_DIAG_ANI_CCK = 7, /* ANI CCK timing error stats */
HAL_DIAG_ANI_STATS = 8, /* ANI statistics */
HAL_DIAG_RFGAIN = 9, /* RfGain GAIN_VALUES */
HAL_DIAG_RFGAIN_CURSTEP = 10, /* RfGain GAIN_OPTIMIZATION_STEP */
HAL_DIAG_PCDAC = 11, /* PCDAC table */
HAL_DIAG_TXRATES = 12, /* Transmit rate table */
HAL_DIAG_REGS = 13, /* Registers */
HAL_DIAG_ANI_CMD = 14, /* ANI issue command (XXX do not change!) */
HAL_DIAG_SETKEY = 15, /* Set keycache backdoor */
HAL_DIAG_RESETKEY = 16, /* Reset keycache backdoor */
HAL_DIAG_EEREAD = 17, /* Read EEPROM word */
HAL_DIAG_EEWRITE = 18, /* Write EEPROM word */
/* 19-26 removed, do not reuse */
HAL_DIAG_RDWRITE = 27, /* Write regulatory domain */
HAL_DIAG_RDREAD = 28, /* Get regulatory domain */
HAL_DIAG_FATALERR = 29, /* Read cached interrupt state */
HAL_DIAG_11NCOMPAT = 30, /* 11n compatibility tweaks */
HAL_DIAG_ANI_PARAMS = 31, /* ANI noise immunity parameters */
HAL_DIAG_CHECK_HANGS = 32, /* check h/w hangs */
HAL_DIAG_SETREGS = 33, /* write registers */
HAL_DIAG_CHANSURVEY = 34, /* channel survey */
};
#endif /* _ATH_AH_DIAGCODES_H_ */
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ah_eeprom.h,v 1.11 2008/11/27 22:32:48 sam Exp $ * $FreeBSD$
*/ */
#ifndef _ATH_AH_EEPROM_H_ #ifndef _ATH_AH_EEPROM_H_
#define _ATH_AH_EEPROM_H_ #define _ATH_AH_EEPROM_H_
@@ -94,11 +94,17 @@ enum {
AR_EEP_RXMASK, /* uint8_t* */ AR_EEP_RXMASK, /* uint8_t* */
AR_EEP_RXGAIN_TYPE, /* uint8_t* */ AR_EEP_RXGAIN_TYPE, /* uint8_t* */
AR_EEP_TXGAIN_TYPE, /* uint8_t* */ AR_EEP_TXGAIN_TYPE, /* uint8_t* */
AR_EEP_DAC_HPWR_5G, /* uint8_t* */
AR_EEP_OL_PWRCTRL, /* use ath_hal_eepromGetFlag */ AR_EEP_OL_PWRCTRL, /* use ath_hal_eepromGetFlag */
AR_EEP_FSTCLK_5G, /* use ath_hal_eepromGetFlag */ AR_EEP_FSTCLK_5G, /* use ath_hal_eepromGetFlag */
AR_EEP_ANTGAINMAX_5, /* int8_t* */ AR_EEP_ANTGAINMAX_5, /* int8_t* */
AR_EEP_ANTGAINMAX_2, /* int8_t* */ AR_EEP_ANTGAINMAX_2, /* int8_t* */
AR_EEP_WRITEPROTECT, /* use ath_hal_eepromGetFlag */ AR_EEP_WRITEPROTECT, /* use ath_hal_eepromGetFlag */
AR_EEP_PWR_TABLE_OFFSET,/* int8_t* */
AR_EEP_PWDCLKIND, /* uint8_t* */
AR_EEP_TEMPSENSE_SLOPE, /* int8_t* */
AR_EEP_TEMPSENSE_SLOPE_PAL_ON, /* int8_t* */
AR_EEP_FRAC_N_5G, /* uint8_t* */
}; };
typedef struct { typedef struct {
@@ -130,4 +136,5 @@ HAL_STATUS ath_hal_v1EepromAttach(struct ath_hal *ah);
HAL_STATUS ath_hal_legacyEepromAttach(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_v14EepromAttach(struct ath_hal *ah);
HAL_STATUS ath_hal_v4kEepromAttach(struct ath_hal *ah); HAL_STATUS ath_hal_v4kEepromAttach(struct ath_hal *ah);
HAL_STATUS ath_hal_9287EepromAttach(struct ath_hal *ah);
#endif /* _ATH_AH_EEPROM_H_ */ #endif /* _ATH_AH_EEPROM_H_ */
@@ -0,0 +1,408 @@
/*
* Copyright (c) 2008 Sam Leffler, Errno Consulting
* Copyright (c) 2010 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.
*
* $FreeBSD$
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_internal.h"
#include "ah_eeprom_v14.h"
#include "ah_eeprom_9287.h"
static HAL_STATUS
v9287EepromGet(struct ath_hal *ah, int param, void *val)
{
#define CHAN_A_IDX 0
#define CHAN_B_IDX 1
#define IS_VERS(op, v) ((pBase->version & AR5416_EEP_VER_MINOR_MASK) op (v))
HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
const MODAL_EEP_9287_HEADER *pModal = &ee->ee_base.modalHeader;
const BASE_EEP_9287_HEADER *pBase = &ee->ee_base.baseEepHeader;
uint32_t sum;
uint8_t *macaddr;
int i;
switch (param) {
case AR_EEP_NFTHRESH_2:
*(int16_t *)val = pModal->noiseFloorThreshCh[0];
return HAL_OK;
case AR_EEP_MACADDR: /* Get MAC Address */
sum = 0;
macaddr = val;
for (i = 0; i < 6; i++) {
macaddr[i] = pBase->macAddr[i];
sum += pBase->macAddr[i];
}
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:
return pBase->regDmn[0];
case AR_EEP_REGDMN_1:
return pBase->regDmn[1];
case AR_EEP_OPCAP:
return pBase->deviceCap;
case AR_EEP_OPMODE:
return pBase->opCapFlags;
case AR_EEP_RFSILENT:
return pBase->rfSilent;
case AR_EEP_TXMASK:
return pBase->txMask;
case AR_EEP_RXMASK:
return pBase->rxMask;
case AR_EEP_OL_PWRCTRL:
HALASSERT(val == AH_NULL);
return pBase->openLoopPwrCntl ? HAL_OK : HAL_EIO;
case AR_EEP_AMODE:
return HAL_EIO; /* no 5GHz for Kiwi */
case AR_EEP_BMODE:
case AR_EEP_GMODE:
HALASSERT(val == AH_NULL);
return pBase->opCapFlags & AR5416_OPFLAGS_11G ?
HAL_OK : HAL_EIO;
case AR_EEP_32KHZCRYSTAL:
case AR_EEP_COMPRESS:
case AR_EEP_FASTFRAME: /* XXX policy decision, h/w can do it */
case AR_EEP_WRITEPROTECT: /* NB: no write protect bit */
HALASSERT(val == AH_NULL);
/* fall thru... */
case AR_EEP_MAXQCU: /* NB: not in opCapFlags */
case AR_EEP_KCENTRIES: /* NB: not in opCapFlags */
return HAL_EIO;
case AR_EEP_AES:
case AR_EEP_BURST:
case AR_EEP_RFKILL:
case AR_EEP_TURBO5DISABLE:
case AR_EEP_TURBO2DISABLE:
HALASSERT(val == AH_NULL);
return HAL_OK;
case AR_EEP_ANTGAINMAX_2:
*(int8_t *) val = ee->ee_antennaGainMax[1];
return HAL_OK;
case AR_EEP_PWR_TABLE_OFFSET:
*(int8_t *) val = pBase->pwrTableOffset;
return HAL_OK;
case AR_EEP_TEMPSENSE_SLOPE:
if (IS_VERS(>=, AR9287_EEP_MINOR_VER_2))
*(int8_t *)val = pBase->tempSensSlope;
else
*(int8_t *)val = 0;
return HAL_OK;
case AR_EEP_TEMPSENSE_SLOPE_PAL_ON:
if (IS_VERS(>=, AR9287_EEP_MINOR_VER_3))
*(int8_t *)val = pBase->tempSensSlopePalOn;
else
*(int8_t *)val = 0;
return HAL_OK;
default:
HALASSERT(0);
return HAL_EINVAL;
}
#undef IS_VERS
#undef CHAN_A_IDX
#undef CHAN_B_IDX
}
static HAL_STATUS
v9287EepromSet(struct ath_hal *ah, int param, int v)
{
HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
switch (param) {
case AR_EEP_ANTGAINMAX_2:
ee->ee_antennaGainMax[1] = (int8_t) v;
return HAL_OK;
default:
return HAL_EINVAL;
}
}
static HAL_BOOL
v9287EepromDiag(struct ath_hal *ah, int request,
const void *args, uint32_t argsize, void **result, uint32_t *resultsize)
{
HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
switch (request) {
case HAL_DIAG_EEPROM:
*result = ee;
*resultsize = sizeof(HAL_EEPROM_9287);
return AH_TRUE;
}
return AH_FALSE;
}
/* Do structure specific swaps if Eeprom format is non native to host */
static void
eepromSwap(HAL_EEPROM_9287 *ee)
{
uint32_t integer, i;
uint16_t word;
MODAL_EEP_9287_HEADER *pModal;
/* convert Base Eep header */
word = __bswap16(ee->ee_base.baseEepHeader.length);
ee->ee_base.baseEepHeader.length = word;
word = __bswap16(ee->ee_base.baseEepHeader.checksum);
ee->ee_base.baseEepHeader.checksum = word;
word = __bswap16(ee->ee_base.baseEepHeader.version);
ee->ee_base.baseEepHeader.version = word;
word = __bswap16(ee->ee_base.baseEepHeader.regDmn[0]);
ee->ee_base.baseEepHeader.regDmn[0] = word;
word = __bswap16(ee->ee_base.baseEepHeader.regDmn[1]);
ee->ee_base.baseEepHeader.regDmn[1] = word;
word = __bswap16(ee->ee_base.baseEepHeader.rfSilent);
ee->ee_base.baseEepHeader.rfSilent = word;
word = __bswap16(ee->ee_base.baseEepHeader.blueToothOptions);
ee->ee_base.baseEepHeader.blueToothOptions = word;
word = __bswap16(ee->ee_base.baseEepHeader.deviceCap);
ee->ee_base.baseEepHeader.deviceCap = word;
/* convert Modal Eep header */
/* only 2.4ghz here; so only one modal header entry */
pModal = &ee->ee_base.modalHeader;
/* XXX linux/ah_osdep.h only defines __bswap32 for BE */
integer = __bswap32(pModal->antCtrlCommon);
pModal->antCtrlCommon = integer;
for (i = 0; i < AR9287_MAX_CHAINS; i++) {
integer = __bswap32(pModal->antCtrlChain[i]);
pModal->antCtrlChain[i] = integer;
}
for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
word = __bswap16(pModal->spurChans[i].spurChan);
pModal->spurChans[i].spurChan = word;
}
}
static uint16_t
v9287EepromGetSpurChan(struct ath_hal *ah, int ix, HAL_BOOL is2GHz)
{
HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
HALASSERT(is2GHz == AH_TRUE);
if (is2GHz != AH_TRUE)
return 0; /* XXX ? */
HALASSERT(0 <= ix && ix < AR5416_EEPROM_MODAL_SPURS);
return ee->ee_base.modalHeader.spurChans[ix].spurChan;
}
/**************************************************************************
* fbin2freq
*
* Get channel value from binary representation held in eeprom
* RETURNS: the frequency in MHz
*/
static uint16_t
fbin2freq(uint8_t fbin, HAL_BOOL is2GHz)
{
/*
* Reserved value 0xFF provides an empty definition both as
* an fbin and as a frequency - do not convert
*/
if (fbin == AR5416_BCHAN_UNUSED)
return fbin;
return (uint16_t)((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
}
/*
* Copy EEPROM Conformance Testing Limits contents
* into the allocated space
*/
/* USE CTLS from chain zero */
#define CTL_CHAIN 0
static void
v9287EepromReadCTLInfo(struct ath_hal *ah, HAL_EEPROM_9287 *ee)
{
RD_EDGES_POWER *rep = ee->ee_rdEdgesPower;
int i, j;
HALASSERT(AR9287_NUM_CTLS <= sizeof(ee->ee_rdEdgesPower)/NUM_EDGES);
for (i = 0; ee->ee_base.ctlIndex[i] != 0 && i < AR9287_NUM_CTLS; i++) {
for (j = 0; j < NUM_EDGES; j ++) {
/* XXX Confirm this is the right thing to do when an invalid channel is stored */
if (ee->ee_base.ctlData[i].ctlEdges[CTL_CHAIN][j].bChannel == AR5416_BCHAN_UNUSED) {
rep[j].rdEdge = 0;
rep[j].twice_rdEdgePower = 0;
rep[j].flag = 0;
} else {
rep[j].rdEdge = fbin2freq(
ee->ee_base.ctlData[i].ctlEdges[CTL_CHAIN][j].bChannel,
(ee->ee_base.ctlIndex[i] & CTL_MODE_M) != CTL_11A);
rep[j].twice_rdEdgePower = MS(ee->ee_base.ctlData[i].ctlEdges[CTL_CHAIN][j].tPowerFlag, CAL_CTL_EDGES_POWER);
rep[j].flag = MS(ee->ee_base.ctlData[i].ctlEdges[CTL_CHAIN][j].tPowerFlag, CAL_CTL_EDGES_FLAG) != 0;
}
}
rep += NUM_EDGES;
}
ee->ee_numCtls = i;
HALDEBUG(ah, HAL_DEBUG_ATTACH | HAL_DEBUG_EEPROM,
"%s Numctls = %u\n",__func__,i);
}
/*
* Reclaim any EEPROM-related storage.
*/
static void
v9287EepromDetach(struct ath_hal *ah)
{
HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
ath_hal_free(ee);
AH_PRIVATE(ah)->ah_eeprom = AH_NULL;
}
#define owl_get_eep_ver(_ee) \
(((_ee)->ee_base.baseEepHeader.version >> 12) & 0xF)
#define owl_get_eep_rev(_ee) \
(((_ee)->ee_base.baseEepHeader.version) & 0xFFF)
HAL_STATUS
ath_hal_9287EepromAttach(struct ath_hal *ah)
{
#define NW(a) (sizeof(a) / sizeof(uint16_t))
HAL_EEPROM_9287 *ee = AH_PRIVATE(ah)->ah_eeprom;
uint16_t *eep_data, magic;
HAL_BOOL need_swap;
u_int w, off, len;
uint32_t sum;
HALASSERT(ee == AH_NULL);
/*
* Don't check magic if we're supplied with an EEPROM block,
* typically this is from Howl but it may also be from later
* boards w/ an embedded WMAC.
*/
if (ah->ah_eepromdata == NULL) {
if (!ath_hal_eepromRead(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s Error reading Eeprom MAGIC\n", __func__);
return HAL_EEREAD;
}
}
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s Eeprom Magic = 0x%x\n",
__func__, magic);
if (magic != AR5416_EEPROM_MAGIC) {
HALDEBUG(ah, HAL_DEBUG_ANY, "Bad magic number\n");
return HAL_EEMAGIC;
}
ee = ath_hal_malloc(sizeof(HAL_EEPROM_9287));
if (ee == AH_NULL) {
/* XXX message */
return HAL_ENOMEM;
}
eep_data = (uint16_t *) ee;
for (w = 0; w < NW(struct ar9287_eeprom); w++) {
off = AR9287_EEP_START_LOC + w;
if (!ath_hal_eepromRead(ah, off, &eep_data[w])) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s eeprom read error at offset 0x%x\n",
__func__, off);
return HAL_EEREAD;
}
}
/* Convert to eeprom native eeprom endian format */
/*
* XXX this is likely incorrect but will do for now
* XXX to get embedded boards working.
*/
if (ah->ah_eepromdata == NULL && isBigEndian()) {
for (w = 0; w < NW(HAL_EEPROM_9287); w++)
eep_data[w] = __bswap16(eep_data[w]);
}
/*
* At this point, we're in the native eeprom endian format
* Now, determine the eeprom endian by looking at byte 26??
*/
need_swap = ((ee->ee_base.baseEepHeader.eepMisc & AR5416_EEPMISC_BIG_ENDIAN) != 0) ^ isBigEndian();
if (need_swap) {
HALDEBUG(ah, HAL_DEBUG_ATTACH | HAL_DEBUG_EEPROM,
"Byte swap EEPROM contents.\n");
len = __bswap16(ee->ee_base.baseEepHeader.length);
} else {
len = ee->ee_base.baseEepHeader.length;
}
len = AH_MIN(len, sizeof(HAL_EEPROM_9287)) / sizeof(uint16_t);
/* Apply the checksum, done in native eeprom format */
/* XXX - Need to check to make sure checksum calculation is done
* in the correct endian format. Right now, it seems it would
* cast the raw data to host format and do the calculation, which may
* not be correct as the calculation may need to be done in the native
* eeprom format
*/
sum = 0;
for (w = 0; w < len; w++)
sum ^= eep_data[w];
/* Check CRC - Attach should fail on a bad checksum */
if (sum != 0xffff) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"Bad EEPROM checksum 0x%x (Len=%u)\n", sum, len);
return HAL_EEBADSUM;
}
if (need_swap)
eepromSwap(ee); /* byte swap multi-byte data */
/* swap words 0+2 so version is at the front */
magic = eep_data[0];
eep_data[0] = eep_data[2];
eep_data[2] = magic;
HALDEBUG(ah, HAL_DEBUG_ATTACH | HAL_DEBUG_EEPROM,
"%s Eeprom Version %u.%u\n", __func__,
owl_get_eep_ver(ee), owl_get_eep_rev(ee));
/* NB: must be after all byte swapping */
if (owl_get_eep_ver(ee) != AR5416_EEP_VER) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"Bad EEPROM version 0x%x\n", owl_get_eep_ver(ee));
return HAL_EEBADSUM;
}
v9287EepromReadCTLInfo(ah, ee); /* Get CTLs */
AH_PRIVATE(ah)->ah_eeprom = ee;
AH_PRIVATE(ah)->ah_eeversion = ee->ee_base.baseEepHeader.version;
AH_PRIVATE(ah)->ah_eepromDetach = v9287EepromDetach;
AH_PRIVATE(ah)->ah_eepromGet = v9287EepromGet;
AH_PRIVATE(ah)->ah_eepromSet = v9287EepromSet;
AH_PRIVATE(ah)->ah_getSpurChan = v9287EepromGetSpurChan;
AH_PRIVATE(ah)->ah_eepromDiag = v9287EepromDiag;
return HAL_OK;
#undef NW
}
@@ -0,0 +1,168 @@
/*
* Copyright (c) 2008-2009 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.
*
* $FreeBSD$
*/
#ifndef __AH_EEPROM_9287_H__
#define __AH_EEPROM_9287_H__
#define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_11_OR_LATER(ah) && \
ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
#define AR9287_EEP_VER 0xE
#define AR9287_EEP_VER_MINOR_MASK 0xFFF
#define AR9287_EEP_MINOR_VER_1 0x1
#define AR9287_EEP_MINOR_VER_2 0x2
#define AR9287_EEP_MINOR_VER_3 0x3
#define AR9287_EEP_MINOR_VER AR9287_EEP_MINOR_VER_3
#define AR9287_EEP_MINOR_VER_b AR9287_EEP_MINOR_VER
#define AR9287_EEP_NO_BACK_VER AR9287_EEP_MINOR_VER_1
#define AR9287_RDEXT_DEFAULT 0x1F
#define AR9287_EEP_START_LOC 128
#define AR9287_HTC_EEP_START_LOC 256
#define AR9287_NUM_2G_CAL_PIERS 3
#define AR9287_NUM_2G_CCK_TARGET_POWERS 3
#define AR9287_NUM_2G_20_TARGET_POWERS 3
#define AR9287_NUM_2G_40_TARGET_POWERS 3
#define AR9287_NUM_CTLS 12
#define AR9287_NUM_BAND_EDGES 4
#define AR9287_PD_GAIN_ICEPTS 1
#define AR9287_EEPMISC_BIG_ENDIAN 0x01
#define AR9287_EEPMISC_WOW 0x02
#define AR9287_MAX_CHAINS 2
#define AR9287_ANT_16S 32
#define AR9287_DATA_SZ 32
#define AR9287_PWR_TABLE_OFFSET_DB -5
#define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1)
struct base_eep_ar9287_header {
uint16_t version; /* Swapped w/ length; check ah_eeprom_v14.h */
uint16_t checksum;
uint16_t length;
uint8_t opCapFlags;
uint8_t eepMisc;
uint16_t regDmn[2];
uint8_t macAddr[6];
uint8_t rxMask;
uint8_t txMask;
uint16_t rfSilent;
uint16_t blueToothOptions;
uint16_t deviceCap;
uint32_t binBuildNumber;
uint8_t deviceType;
uint8_t openLoopPwrCntl;
int8_t pwrTableOffset;
int8_t tempSensSlope;
int8_t tempSensSlopePalOn;
uint8_t futureBase[29];
} __packed;
struct modal_eep_ar9287_header {
uint32_t antCtrlChain[AR9287_MAX_CHAINS];
uint32_t antCtrlCommon;
int8_t antennaGainCh[AR9287_MAX_CHAINS];
uint8_t switchSettling;
uint8_t txRxAttenCh[AR9287_MAX_CHAINS];
uint8_t rxTxMarginCh[AR9287_MAX_CHAINS];
int8_t adcDesiredSize;
uint8_t txEndToXpaOff;
uint8_t txEndToRxOn;
uint8_t txFrameToXpaOn;
uint8_t thresh62;
int8_t noiseFloorThreshCh[AR9287_MAX_CHAINS];
uint8_t xpdGain;
uint8_t xpd;
int8_t iqCalICh[AR9287_MAX_CHAINS];
int8_t iqCalQCh[AR9287_MAX_CHAINS];
uint8_t pdGainOverlap;
uint8_t xpaBiasLvl;
uint8_t txFrameToDataStart;
uint8_t txFrameToPaOn;
uint8_t ht40PowerIncForPdadc;
uint8_t bswAtten[AR9287_MAX_CHAINS];
uint8_t bswMargin[AR9287_MAX_CHAINS];
uint8_t swSettleHt40;
uint8_t version;
uint8_t db1;
uint8_t db2;
uint8_t ob_cck;
uint8_t ob_psk;
uint8_t ob_qam;
uint8_t ob_pal_off;
uint8_t futureModal[30];
SPUR_CHAN spurChans[AR5416_EEPROM_MODAL_SPURS];
} __packed;
struct cal_data_op_loop_ar9287 {
uint8_t pwrPdg[2][5];
uint8_t vpdPdg[2][5];
uint8_t pcdac[2][5];
uint8_t empty[2][5];
} __packed;
struct cal_data_per_freq_ar9287 {
uint8_t pwrPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
uint8_t vpdPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
} __packed;
union cal_data_per_freq_ar9287_u {
struct cal_data_op_loop_ar9287 calDataOpen;
struct cal_data_per_freq_ar9287 calDataClose;
} __packed;
struct cal_ctl_data_ar9287 {
CAL_CTL_EDGES ctlEdges[AR9287_MAX_CHAINS][AR9287_NUM_BAND_EDGES];
} __packed;
struct ar9287_eeprom {
struct base_eep_ar9287_header baseEepHeader;
uint8_t custData[AR9287_DATA_SZ];
struct modal_eep_ar9287_header modalHeader;
uint8_t calFreqPier2G[AR9287_NUM_2G_CAL_PIERS];
union cal_data_per_freq_ar9287_u
calPierData2G[AR9287_MAX_CHAINS][AR9287_NUM_2G_CAL_PIERS];
CAL_TARGET_POWER_LEG
calTargetPowerCck[AR9287_NUM_2G_CCK_TARGET_POWERS];
CAL_TARGET_POWER_LEG
calTargetPower2G[AR9287_NUM_2G_20_TARGET_POWERS];
CAL_TARGET_POWER_HT
calTargetPower2GHT20[AR9287_NUM_2G_20_TARGET_POWERS];
CAL_TARGET_POWER_HT
calTargetPower2GHT40[AR9287_NUM_2G_40_TARGET_POWERS];
uint8_t ctlIndex[AR9287_NUM_CTLS];
struct cal_ctl_data_ar9287 ctlData[AR9287_NUM_CTLS];
uint8_t padding;
} __packed;
typedef struct {
struct ar9287_eeprom ee_base;
#define NUM_EDGES 8
uint16_t ee_numCtls;
RD_EDGES_POWER ee_rdEdgesPower[NUM_EDGES*AR9287_NUM_CTLS];
/* XXX these are dynamically calculated for use by shared code */
int8_t ee_antennaGainMax[2];
} HAL_EEPROM_9287;
typedef struct modal_eep_ar9287_header MODAL_EEP_9287_HEADER;
typedef struct base_eep_ar9287_header BASE_EEP_9287_HEADER;
#endif /* __AH_EEPROM_9287_H__ */
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * 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 $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -68,7 +68,7 @@ v1EepromGet(struct ath_hal *ah, int param, void *val)
} }
} }
static HAL_BOOL static HAL_STATUS
v1EepromSet(struct ath_hal *ah, int param, int v) v1EepromSet(struct ath_hal *ah, int param, int v)
{ {
return HAL_EINVAL; return HAL_EINVAL;
@@ -112,7 +112,7 @@ ath_hal_v1EepromAttach(struct ath_hal *ah)
{ {
HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom; HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom;
uint16_t athvals[AR_EEPROM_ATHEROS_MAX]; /* XXX off stack */ uint16_t athvals[AR_EEPROM_ATHEROS_MAX]; /* XXX off stack */
uint16_t protect, version, eeval; uint16_t protect, eeprom_version, eeval;
uint32_t sum; uint32_t sum;
int i, loc; int i, loc;
@@ -138,18 +138,18 @@ ath_hal_v1EepromAttach(struct ath_hal *ah)
HALDEBUG(ah, HAL_DEBUG_ATTACH, "EEPROM protect 0x%x\n", protect); HALDEBUG(ah, HAL_DEBUG_ATTACH, "EEPROM protect 0x%x\n", protect);
/* XXX check proper access before continuing */ /* XXX check proper access before continuing */
if (!ath_hal_eepromRead(ah, AR_EEPROM_VERSION, &version)) { if (!ath_hal_eepromRead(ah, AR_EEPROM_VERSION, &eeprom_version)) {
HALDEBUG(ah, HAL_DEBUG_ANY, HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: unable to read EEPROM version\n", __func__); "%s: unable to read EEPROM version\n", __func__);
return HAL_EEREAD; return HAL_EEREAD;
} }
if (((version>>12) & 0xf) != 1) { if (((eeprom_version>>12) & 0xf) != 1) {
/* /*
* This code only groks the version 1 EEPROM layout. * This code only groks the version 1 EEPROM layout.
*/ */
HALDEBUG(ah, HAL_DEBUG_ANY, HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: unsupported EEPROM version 0x%x found\n", "%s: unsupported EEPROM version 0x%x found\n",
__func__, version); __func__, eeprom_version);
return HAL_EEVERSION; return HAL_EEVERSION;
} }
@@ -183,7 +183,7 @@ ath_hal_v1EepromAttach(struct ath_hal *ah)
return HAL_ENOMEM; return HAL_ENOMEM;
} }
ee->ee_version = version; ee->ee_version = eeprom_version;
ee->ee_protect = protect; ee->ee_protect = protect;
ee->ee_antenna = athvals[2]; ee->ee_antenna = athvals[2];
ee->ee_biasCurrents = athvals[3]; ee->ee_biasCurrents = athvals[3];
@@ -243,7 +243,7 @@ ath_hal_v1EepromAttach(struct ath_hal *ah)
} }
AH_PRIVATE(ah)->ah_eeprom = ee; AH_PRIVATE(ah)->ah_eeprom = ee;
AH_PRIVATE(ah)->ah_eeversion = version; AH_PRIVATE(ah)->ah_eeversion = eeprom_version;
AH_PRIVATE(ah)->ah_eepromDetach = v1EepromDetach; AH_PRIVATE(ah)->ah_eepromDetach = v1EepromDetach;
AH_PRIVATE(ah)->ah_eepromGet = v1EepromGet; AH_PRIVATE(ah)->ah_eepromGet = v1EepromGet;
AH_PRIVATE(ah)->ah_eepromSet = v1EepromSet; AH_PRIVATE(ah)->ah_eepromSet = v1EepromSet;
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * 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 $ * $FreeBSD$
*/ */
#ifndef _ATH_AH_EEPROM_V1_H_ #ifndef _ATH_AH_EEPROM_V1_H_
#define _ATH_AH_EEPROM_V1_H_ #define _ATH_AH_EEPROM_V1_H_
@@ -84,11 +84,25 @@ v14EepromGet(struct ath_hal *ah, int param, void *val)
return IS_VERS(>=, AR5416_EEP_MINOR_VER_19) ? return IS_VERS(>=, AR5416_EEP_MINOR_VER_19) ?
pBase->txGainType : AR5416_EEP_TXGAIN_ORIG; pBase->txGainType : AR5416_EEP_TXGAIN_ORIG;
case AR_EEP_FSTCLK_5G: case AR_EEP_FSTCLK_5G:
return IS_VERS(>, AR5416_EEP_MINOR_VER_16) ? /* 5ghz fastclock is always enabled for Merlin minor <= 16 */
pBase->fastClk5g : AH_TRUE; if (IS_VERS(<=, AR5416_EEP_MINOR_VER_16))
return HAL_OK;
return pBase->fastClk5g ? HAL_OK : HAL_EIO;
case AR_EEP_OL_PWRCTRL: case AR_EEP_OL_PWRCTRL:
HALASSERT(val == AH_NULL); HALASSERT(val == AH_NULL);
return pBase->openLoopPwrCntl ? HAL_OK : HAL_EIO; return pBase->openLoopPwrCntl ? HAL_OK : HAL_EIO;
case AR_EEP_DAC_HPWR_5G:
if (IS_VERS(>=, AR5416_EEP_MINOR_VER_20)) {
*(uint8_t *) val = pBase->dacHiPwrMode_5G;
return HAL_OK;
} else
return HAL_EIO;
case AR_EEP_FRAC_N_5G:
if (IS_VERS(>=, AR5416_EEP_MINOR_VER_22)) {
*(uint8_t *) val = pBase->frac_n_5g;
} else
*(uint8_t *) val = 0;
return HAL_OK;
case AR_EEP_AMODE: case AR_EEP_AMODE:
HALASSERT(val == AH_NULL); HALASSERT(val == AH_NULL);
return pBase->opCapFlags & AR5416_OPFLAGS_11A ? return pBase->opCapFlags & AR5416_OPFLAGS_11A ?
@@ -120,6 +134,19 @@ v14EepromGet(struct ath_hal *ah, int param, void *val)
case AR_EEP_ANTGAINMAX_5: case AR_EEP_ANTGAINMAX_5:
*(int8_t *) val = ee->ee_antennaGainMax[0]; *(int8_t *) val = ee->ee_antennaGainMax[0];
return HAL_OK; return HAL_OK;
case AR_EEP_PWR_TABLE_OFFSET:
if (IS_VERS(>=, AR5416_EEP_MINOR_VER_21))
*(int8_t *) val = pBase->pwr_table_offset;
else
*(int8_t *) val = AR5416_PWR_TABLE_OFFSET_DB;
return HAL_OK;
case AR_EEP_PWDCLKIND:
if (IS_VERS(>=, AR5416_EEP_MINOR_VER_10)) {
*(uint8_t *) val = pBase->pwdclkind;
return HAL_OK;
}
return HAL_EIO;
default: default:
HALASSERT(0); HALASSERT(0);
return HAL_EINVAL; return HAL_EINVAL;
@@ -129,7 +156,7 @@ v14EepromGet(struct ath_hal *ah, int param, void *val)
#undef CHAN_B_IDX #undef CHAN_B_IDX
} }
static HAL_BOOL static HAL_STATUS
v14EepromSet(struct ath_hal *ah, int param, int v) v14EepromSet(struct ath_hal *ah, int param, int v)
{ {
HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom; HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom;
@@ -153,8 +180,8 @@ v14EepromDiag(struct ath_hal *ah, int request,
switch (request) { switch (request) {
case HAL_DIAG_EEPROM: case HAL_DIAG_EEPROM:
*result = &ee->ee_base; *result = ee;
*resultsize = sizeof(ee->ee_base); *resultsize = sizeof(HAL_EEPROM_v14);
return AH_TRUE; return AH_TRUE;
} }
return AH_FALSE; return AH_FALSE;
@@ -205,7 +232,10 @@ eepromSwap(struct ar5416eeprom *ee)
integer = __bswap32(pModal->antCtrlChain[i]); integer = __bswap32(pModal->antCtrlChain[i]);
pModal->antCtrlChain[i] = integer; pModal->antCtrlChain[i] = integer;
} }
for (i = 0; i < 3; i++) {
word = __bswap16(pModal->xpaBiasLvlFreq[i]);
pModal->xpaBiasLvlFreq[i] = word;
}
for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
word = __bswap16(pModal->spurChans[i].spurChan); word = __bswap16(pModal->spurChans[i].spurChan);
pModal->spurChans[i].spurChan = word; pModal->spurChans[i].spurChan = word;
@@ -294,6 +324,11 @@ v14EepromDetach(struct ath_hal *ah)
#define owl_get_eep_rev(_ee) \ #define owl_get_eep_rev(_ee) \
(((_ee)->ee_base.baseEepHeader.version) & 0xFFF) (((_ee)->ee_base.baseEepHeader.version) & 0xFFF)
/*
* Howl is (hopefully) a special case where the endian-ness of the EEPROM
* matches the native endian-ness; and that supplied EEPROMs don't have
* a magic value to check.
*/
HAL_STATUS HAL_STATUS
ath_hal_v14EepromAttach(struct ath_hal *ah) ath_hal_v14EepromAttach(struct ath_hal *ah)
{ {
@@ -306,6 +341,12 @@ ath_hal_v14EepromAttach(struct ath_hal *ah)
HALASSERT(ee == AH_NULL); HALASSERT(ee == AH_NULL);
/*
* Don't check magic if we're supplied with an EEPROM block,
* typically this is from Howl but it may also be from later
* boards w/ an embedded Merlin.
*/
if (ah->ah_eepromdata == NULL) {
if (!ath_hal_eepromRead(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { if (!ath_hal_eepromRead(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
HALDEBUG(ah, HAL_DEBUG_ANY, HALDEBUG(ah, HAL_DEBUG_ANY,
"%s Error reading Eeprom MAGIC\n", __func__); "%s Error reading Eeprom MAGIC\n", __func__);
@@ -317,6 +358,7 @@ ath_hal_v14EepromAttach(struct ath_hal *ah)
HALDEBUG(ah, HAL_DEBUG_ANY, "Bad magic number\n"); HALDEBUG(ah, HAL_DEBUG_ANY, "Bad magic number\n");
return HAL_EEMAGIC; return HAL_EEMAGIC;
} }
}
ee = ath_hal_malloc(sizeof(HAL_EEPROM_v14)); ee = ath_hal_malloc(sizeof(HAL_EEPROM_v14));
if (ee == AH_NULL) { if (ee == AH_NULL) {
@@ -335,7 +377,8 @@ ath_hal_v14EepromAttach(struct ath_hal *ah)
} }
} }
/* Convert to eeprom native eeprom endian format */ /* Convert to eeprom native eeprom endian format */
if (isBigEndian()) { /* XXX this is likely incorrect but will do for now to get howl/ap83 working. */
if (ah->ah_eepromdata == NULL && isBigEndian()) {
for (w = 0; w < NW(struct ar5416eeprom); w++) for (w = 0; w < NW(struct ar5416eeprom); w++)
eep_data[w] = __bswap16(eep_data[w]); eep_data[w] = __bswap16(eep_data[w]);
} }
@@ -49,9 +49,13 @@
#define AR5416_EEP_MINOR_VER_3 0x3 #define AR5416_EEP_MINOR_VER_3 0x3
#define AR5416_EEP_MINOR_VER_7 0x7 #define AR5416_EEP_MINOR_VER_7 0x7
#define AR5416_EEP_MINOR_VER_9 0x9 #define AR5416_EEP_MINOR_VER_9 0x9
#define AR5416_EEP_MINOR_VER_10 0xa
#define AR5416_EEP_MINOR_VER_16 0x10 #define AR5416_EEP_MINOR_VER_16 0x10
#define AR5416_EEP_MINOR_VER_17 0x11 #define AR5416_EEP_MINOR_VER_17 0x11
#define AR5416_EEP_MINOR_VER_19 0x13 #define AR5416_EEP_MINOR_VER_19 0x13
#define AR5416_EEP_MINOR_VER_20 0x14
#define AR5416_EEP_MINOR_VER_21 0x15
#define AR5416_EEP_MINOR_VER_22 0x16
// 16-bit offset location start of calibration struct // 16-bit offset location start of calibration struct
#define AR5416_EEP_START_LOC 256 #define AR5416_EEP_START_LOC 256
@@ -91,10 +95,10 @@
#define AR5416_OPFLAGS_11A 0x01 #define AR5416_OPFLAGS_11A 0x01
#define AR5416_OPFLAGS_11G 0x02 #define AR5416_OPFLAGS_11G 0x02
#define AR5416_OPFLAGS_5G_HT40 0x04 #define AR5416_OPFLAGS_N_5G_HT40 0x04 /* If set, disable 5G HT40 */
#define AR5416_OPFLAGS_2G_HT40 0x08 #define AR5416_OPFLAGS_N_2G_HT40 0x08
#define AR5416_OPFLAGS_5G_HT20 0x10 #define AR5416_OPFLAGS_N_5G_HT20 0x10
#define AR5416_OPFLAGS_2G_HT20 0x20 #define AR5416_OPFLAGS_N_2G_HT20 0x20
/* RF silent fields in EEPROM */ /* RF silent fields in EEPROM */
#define EEP_RFSILENT_ENABLED 0x0001 /* enabled/disabled */ #define EEP_RFSILENT_ENABLED 0x0001 /* enabled/disabled */
@@ -138,6 +142,16 @@ typedef struct CalCtlEdges {
#define CAL_CTL_EDGES_FLAG_S 6 #define CAL_CTL_EDGES_FLAG_S 6
} __packed CAL_CTL_EDGES; } __packed CAL_CTL_EDGES;
/*
* These are the secondary regulatory domain flags
* for regDmn[1].
*/
#define AR5416_REGDMN_EN_FCC_MID 0x01 /* 5.47 - 5.7GHz operation */
#define AR5416_REGDMN_EN_JAP_MID 0x02 /* 5.47 - 5.7GHz operation */
#define AR5416_REGDMN_EN_FCC_DFS_HT40 0x04 /* FCC HT40 + DFS operation */
#define AR5416_REGDMN_EN_JAP_HT40 0x08 /* JP HT40 operation */
#define AR5416_REGDMN_EN_JAP_DFS_HT40 0x10 /* JP HT40 + DFS operation */
/* /*
* NB: The format in EEPROM has words 0 and 2 swapped (i.e. version * NB: The format in EEPROM has words 0 and 2 swapped (i.e. version
* and length are swapped). We reverse their position after reading * and length are swapped). We reverse their position after reading
@@ -165,13 +179,19 @@ typedef struct BaseEepHeader {
uint8_t fastClk5g; uint8_t fastClk5g;
uint8_t divChain; uint8_t divChain;
uint8_t rxGainType; uint8_t rxGainType;
uint8_t dacHiPwrMode; /* use the DAC high power mode (MB91) */ uint8_t dacHiPwrMode_5G;/* use the DAC high power mode (MB91) */
uint8_t openLoopPwrCntl;/* 1: use open loop power control, uint8_t openLoopPwrCntl;/* 1: use open loop power control,
0: use closed loop power control */ 0: use closed loop power control */
uint8_t dacLpMode; uint8_t dacLpMode;
uint8_t txGainType; /* high power tx gain table support */ uint8_t txGainType; /* high power tx gain table support */
uint8_t rcChainMask; /* "1" if the card is an HB93 1x2 */ uint8_t rcChainMask; /* "1" if the card is an HB93 1x2 */
uint8_t futureBase[24]; uint8_t desiredScaleCCK;
uint8_t pwr_table_offset;
uint8_t frac_n_5g; /*
* bit 0: indicates that fracN synth
* mode applies to all 5G channels
*/
uint8_t futureBase[21];
} __packed BASE_EEP_HEADER; // 64 B } __packed BASE_EEP_HEADER; // 64 B
typedef struct ModalEepHeader { typedef struct ModalEepHeader {
@@ -210,14 +230,14 @@ typedef struct ModalEepHeader {
uint8_t ob_ch1; // 1 -> ob and db become chain specific from AR9280 uint8_t ob_ch1; // 1 -> ob and db become chain specific from AR9280
uint8_t db_ch1; // 1 uint8_t db_ch1; // 1
uint8_t flagBits; // 1 uint8_t flagBits; // 1
#define AR5416_EEP_FLAG_USEANT1 0x01 /* +1 configured antenna */ #define AR5416_EEP_FLAG_USEANT1 0x80 /* +1 configured antenna */
#define AR5416_EEP_FLAG_FORCEXPAON 0x02 /* force XPA bit for 5G */ #define AR5416_EEP_FLAG_FORCEXPAON 0x40 /* force XPA bit for 5G */
#define AR5416_EEP_FLAG_LOCALBIAS 0x04 /* enable local bias */ #define AR5416_EEP_FLAG_LOCALBIAS 0x20 /* enable local bias */
#define AR5416_EEP_FLAG_FEMBANDSELECT 0x08 /* FEM band select used */ #define AR5416_EEP_FLAG_FEMBANDSELECT 0x10 /* FEM band select used */
#define AR5416_EEP_FLAG_XLNABUFIN 0x10 #define AR5416_EEP_FLAG_XLNABUFIN 0x08
#define AR5416_EEP_FLAG_XLNAISEL 0x60 #define AR5416_EEP_FLAG_XLNAISEL1 0x04
#define AR5416_EEP_FLAG_XLNAISEL_S 5 #define AR5416_EEP_FLAG_XLNAISEL2 0x02
#define AR5416_EEP_FLAG_XLNABUFMODE 0x80 #define AR5416_EEP_FLAG_XLNABUFMODE 0x01
uint8_t miscBits; // [0..1]: bb_tx_dac_scale_cck uint8_t miscBits; // [0..1]: bb_tx_dac_scale_cck
uint16_t xpaBiasLvlFreq[3]; // 3 uint16_t xpaBiasLvlFreq[3]; // 3
uint8_t futureModal[6]; // 6 uint8_t futureModal[6]; // 6
@@ -1665,7 +1665,7 @@ legacyEepromGet(struct ath_hal *ah, int param, void *val)
return HAL_EINVAL; return HAL_EINVAL;
} }
static HAL_BOOL static HAL_STATUS
legacyEepromSet(struct ath_hal *ah, int param, int v) legacyEepromSet(struct ath_hal *ah, int param, int v)
{ {
HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ah_eeprom_v3.h,v 1.2 2008/11/10 04:08:00 sam Exp $ * $FreeBSD$
*/ */
#ifndef _ATH_AH_EEPROM_V3_H_ #ifndef _ATH_AH_EEPROM_V3_H_
#define _ATH_AH_EEPROM_V3_H_ #define _ATH_AH_EEPROM_V3_H_
@@ -38,11 +38,8 @@ v4kEepromGet(struct ath_hal *ah, int param, void *val)
int i; int i;
switch (param) { switch (param) {
case AR_EEP_NFTHRESH_5:
*(int16_t *)val = pModal[0].noiseFloorThreshCh[0];
return HAL_OK;
case AR_EEP_NFTHRESH_2: case AR_EEP_NFTHRESH_2:
*(int16_t *)val = pModal[1].noiseFloorThreshCh[0]; *(int16_t *)val = pModal->noiseFloorThreshCh[0];
return HAL_OK; return HAL_OK;
case AR_EEP_MACADDR: /* Get MAC Address */ case AR_EEP_MACADDR: /* Get MAC Address */
sum = 0; sum = 0;
@@ -67,14 +64,10 @@ v4kEepromGet(struct ath_hal *ah, int param, void *val)
return pBase->opCapFlags; return pBase->opCapFlags;
case AR_EEP_RFSILENT: case AR_EEP_RFSILENT:
return pBase->rfSilent; return pBase->rfSilent;
case AR_EEP_OB_5:
return pModal[CHAN_A_IDX].ob;
case AR_EEP_DB_5:
return pModal[CHAN_A_IDX].db;
case AR_EEP_OB_2: case AR_EEP_OB_2:
return pModal[CHAN_B_IDX].ob; return pModal->ob_0;
case AR_EEP_DB_2: case AR_EEP_DB_2:
return pModal[CHAN_B_IDX].db; return pModal->db1_1;
case AR_EEP_TXMASK: case AR_EEP_TXMASK:
return pBase->txMask; return pBase->txMask;
case AR_EEP_RXMASK: case AR_EEP_RXMASK:
@@ -82,13 +75,10 @@ v4kEepromGet(struct ath_hal *ah, int param, void *val)
case AR_EEP_RXGAIN_TYPE: case AR_EEP_RXGAIN_TYPE:
return AR5416_EEP_RXGAIN_ORIG; return AR5416_EEP_RXGAIN_ORIG;
case AR_EEP_TXGAIN_TYPE: case AR_EEP_TXGAIN_TYPE:
return IS_VERS(>=, AR5416_EEP_MINOR_VER_19) ? return pBase->txGainType;
pBase->txGainType : AR5416_EEP_TXGAIN_ORIG;
#if 0
case AR_EEP_OL_PWRCTRL: case AR_EEP_OL_PWRCTRL:
HALASSERT(val == AH_NULL); HALASSERT(val == AH_NULL);
return pBase->openLoopPwrCntl ? HAL_OK : HAL_EIO; return HAL_EIO;
#endif
case AR_EEP_AMODE: case AR_EEP_AMODE:
HALASSERT(val == AH_NULL); HALASSERT(val == AH_NULL);
return pBase->opCapFlags & AR5416_OPFLAGS_11A ? return pBase->opCapFlags & AR5416_OPFLAGS_11A ?
@@ -110,15 +100,11 @@ v4kEepromGet(struct ath_hal *ah, int param, void *val)
case AR_EEP_AES: case AR_EEP_AES:
case AR_EEP_BURST: case AR_EEP_BURST:
case AR_EEP_RFKILL: case AR_EEP_RFKILL:
case AR_EEP_TURBO5DISABLE:
case AR_EEP_TURBO2DISABLE: case AR_EEP_TURBO2DISABLE:
HALASSERT(val == AH_NULL); HALASSERT(val == AH_NULL);
return HAL_OK; return HAL_OK;
case AR_EEP_ANTGAINMAX_2: case AR_EEP_ANTGAINMAX_2:
*(int8_t *) val = ee->ee_antennaGainMax[1]; *(int8_t *) val = ee->ee_antennaGainMax;
return HAL_OK;
case AR_EEP_ANTGAINMAX_5:
*(int8_t *) val = ee->ee_antennaGainMax[0];
return HAL_OK; return HAL_OK;
default: default:
HALASSERT(0); HALASSERT(0);
@@ -129,17 +115,14 @@ v4kEepromGet(struct ath_hal *ah, int param, void *val)
#undef CHAN_B_IDX #undef CHAN_B_IDX
} }
static HAL_BOOL static HAL_STATUS
v4kEepromSet(struct ath_hal *ah, int param, int v) v4kEepromSet(struct ath_hal *ah, int param, int v)
{ {
HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom; HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom;
switch (param) { switch (param) {
case AR_EEP_ANTGAINMAX_2: case AR_EEP_ANTGAINMAX_2:
ee->ee_antennaGainMax[1] = (int8_t) v; ee->ee_antennaGainMax = (int8_t) v;
return HAL_OK;
case AR_EEP_ANTGAINMAX_5:
ee->ee_antennaGainMax[0] = (int8_t) v;
return HAL_OK; return HAL_OK;
} }
return HAL_EINVAL; return HAL_EINVAL;
@@ -153,8 +136,8 @@ v4kEepromDiag(struct ath_hal *ah, int request,
switch (request) { switch (request) {
case HAL_DIAG_EEPROM: case HAL_DIAG_EEPROM:
*result = &ee->ee_base; *result = ee;
*resultsize = sizeof(ee->ee_base); *resultsize = sizeof(HAL_EEPROM_v4k);
return AH_TRUE; return AH_TRUE;
} }
return AH_FALSE; return AH_FALSE;
@@ -252,7 +235,7 @@ v4kEepromReadCTLInfo(struct ath_hal *ah, HAL_EEPROM_v4k *ee)
RD_EDGES_POWER *rep = ee->ee_rdEdgesPower; RD_EDGES_POWER *rep = ee->ee_rdEdgesPower;
int i, j; int i, j;
HALASSERT(AR5416_NUM_CTLS <= sizeof(ee->ee_rdEdgesPower)/NUM_EDGES); HALASSERT(AR5416_4K_NUM_CTLS <= sizeof(ee->ee_rdEdgesPower)/NUM_EDGES);
for (i = 0; ee->ee_base.ctlIndex[i] != 0 && i < AR5416_4K_NUM_CTLS; i++) { for (i = 0; ee->ee_base.ctlIndex[i] != 0 && i < AR5416_4K_NUM_CTLS; i++) {
for (j = 0; j < NUM_EDGES; j ++) { for (j = 0; j < NUM_EDGES; j ++) {
@@ -304,12 +287,18 @@ ath_hal_v4kEepromAttach(struct ath_hal *ah)
uint32_t sum; uint32_t sum;
HALASSERT(ee == AH_NULL); HALASSERT(ee == AH_NULL);
/*
* Don't check magic if we're supplied with an EEPROM block,
* typically this is from Howl but it may also be from later
* boards w/ an embedded WMAC.
*/
if (ah->ah_eepromdata == NULL) {
if (!ath_hal_eepromRead(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) { if (!ath_hal_eepromRead(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
HALDEBUG(ah, HAL_DEBUG_ANY, HALDEBUG(ah, HAL_DEBUG_ANY,
"%s Error reading Eeprom MAGIC\n", __func__); "%s Error reading Eeprom MAGIC\n", __func__);
return HAL_EEREAD; return HAL_EEREAD;
} }
}
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s Eeprom Magic = 0x%x\n", HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s Eeprom Magic = 0x%x\n",
__func__, magic); __func__, magic);
if (magic != AR5416_EEPROM_MAGIC) { if (magic != AR5416_EEPROM_MAGIC) {
@@ -334,7 +323,11 @@ ath_hal_v4kEepromAttach(struct ath_hal *ah)
} }
} }
/* Convert to eeprom native eeprom endian format */ /* Convert to eeprom native eeprom endian format */
if (isBigEndian()) { /*
* XXX this is likely incorrect but will do for now
* XXX to get embedded boards working.
*/
if (ah->ah_eepromdata == NULL && isBigEndian()) {
for (w = 0; w < NW(struct ar5416eeprom_4k); w++) for (w = 0; w < NW(struct ar5416eeprom_4k); w++)
eep_data[w] = __bswap16(eep_data[w]); eep_data[w] = __bswap16(eep_data[w]);
} }
@@ -23,6 +23,14 @@
#include "ah_eeprom.h" #include "ah_eeprom.h"
#include "ah_eeprom_v14.h" #include "ah_eeprom_v14.h"
#if _BYTE_ORDER == _BIG_ENDIAN
#define __BIG_ENDIAN_BITFIELD
#endif
#define AR9285_RDEXT_DEFAULT 0x1F
#define AR5416_4K_EEP_PD_GAIN_BOUNDARY_DEFAULT 58
#undef owl_eep_start_loc #undef owl_eep_start_loc
#ifdef __LINUX_ARM_ARCH__ /* AP71 */ #ifdef __LINUX_ARM_ARCH__ /* AP71 */
#define owl_eep_start_loc 0 #define owl_eep_start_loc 0
@@ -68,7 +76,7 @@ typedef struct BaseEepHeader4k {
} __packed BASE_EEP4K_HEADER; // 32 B } __packed BASE_EEP4K_HEADER; // 32 B
typedef struct ModalEepHeader4k { typedef struct ModalEepHeader4k {
uint32_t antCtrlChain[AR5416_4K_MAX_CHAINS]; // 12 uint32_t antCtrlChain[AR5416_4K_MAX_CHAINS]; // 4
uint32_t antCtrlCommon; // 4 uint32_t antCtrlCommon; // 4
int8_t antennaGainCh[AR5416_4K_MAX_CHAINS]; // 1 int8_t antennaGainCh[AR5416_4K_MAX_CHAINS]; // 1
uint8_t switchSettling; // 1 uint8_t switchSettling; // 1
@@ -86,14 +94,18 @@ typedef struct ModalEepHeader4k {
uint8_t xpd; // 1 uint8_t xpd; // 1
int8_t iqCalICh[AR5416_4K_MAX_CHAINS]; // 1 int8_t iqCalICh[AR5416_4K_MAX_CHAINS]; // 1
int8_t iqCalQCh[AR5416_4K_MAX_CHAINS]; // 1 int8_t iqCalQCh[AR5416_4K_MAX_CHAINS]; // 1
uint8_t pdGainOverlap; // 1 uint8_t pdGainOverlap; // 1
uint8_t ob; // 1
uint8_t db; // 1 #ifdef __BIG_ENDIAN_BITFIELD
uint8_t xpaBiasLvl; // 1 uint8_t ob_1:4, ob_0:4; // 1
#if 0 uint8_t db1_1:4, db1_0:4; // 1
uint8_t pwrDecreaseFor2Chain; // 1 #else
uint8_t pwrDecreaseFor3Chain; // 1 -> 48 B uint8_t ob_0:4, ob_1:4;
uint8_t db1_0:4, db1_1:4;
#endif #endif
uint8_t xpaBiasLvl; // 1
uint8_t txFrameToDataStart; // 1 uint8_t txFrameToDataStart; // 1
uint8_t txFrameToPaOn; // 1 uint8_t txFrameToPaOn; // 1
uint8_t ht40PowerIncForPdadc; // 1 uint8_t ht40PowerIncForPdadc; // 1
@@ -102,20 +114,35 @@ typedef struct ModalEepHeader4k {
uint8_t swSettleHt40; // 1 uint8_t swSettleHt40; // 1
uint8_t xatten2Db[AR5416_4K_MAX_CHAINS]; // 1 uint8_t xatten2Db[AR5416_4K_MAX_CHAINS]; // 1
uint8_t xatten2Margin[AR5416_4K_MAX_CHAINS]; // 1 uint8_t xatten2Margin[AR5416_4K_MAX_CHAINS]; // 1
uint8_t ob_ch1; // 1 -> ob and db become chain specific from AR9280
uint8_t db_ch1; // 1 #ifdef __BIG_ENDIAN_BITFIELD
uint8_t flagBits; // 1 uint8_t db2_1:4, db2_0:4; // 1
#define AR5416_EEP_FLAG_USEANT1 0x01 /* +1 configured antenna */ #else
#define AR5416_EEP_FLAG_FORCEXPAON 0x02 /* force XPA bit for 5G */ uint8_t db2_0:4, db2_1:4; // 1
#define AR5416_EEP_FLAG_LOCALBIAS 0x04 /* enable local bias */ #endif
#define AR5416_EEP_FLAG_FEMBANDSELECT 0x08 /* FEM band select used */
#define AR5416_EEP_FLAG_XLNABUFIN 0x10 uint8_t version; // 1
#define AR5416_EEP_FLAG_XLNAISEL 0x60
#define AR5416_EEP_FLAG_XLNAISEL_S 5 #ifdef __BIG_ENDIAN_BITFIELD
#define AR5416_EEP_FLAG_XLNABUFMODE 0x80 uint8_t ob_3:4, ob_2:4; // 1
uint8_t miscBits; // [0..1]: bb_tx_dac_scale_cck uint8_t antdiv_ctl1:4, ob_4:4; // 1
uint16_t xpaBiasLvlFreq[3]; // 6 uint8_t db1_3:4, db1_2:4; // 1
uint8_t futureModal[2]; // 2 uint8_t antdiv_ctl2:4, db1_4:4; // 1
uint8_t db2_2:4, db2_3:4; // 1
uint8_t reserved:4, db2_4:4; // 1
#else
uint8_t ob_2:4, ob_3:4;
uint8_t ob_4:4, antdiv_ctl1:4;
uint8_t db1_2:4, db1_3:4;
uint8_t db1_4:4, antdiv_ctl2:4;
uint8_t db2_2:4, db2_3:4;
uint8_t db2_4:4, reserved:4;
#endif
uint8_t tx_diversity;
uint8_t flc_pwr_thresh;
uint8_t bb_scale_smrt_antenna;
#define EEP_4K_BB_DESIRED_SCALE_MASK 0x1f
uint8_t futureModal[1];
SPUR_CHAN spurChans[AR5416_EEPROM_MODAL_SPURS]; // 20 B SPUR_CHAN spurChans[AR5416_EEPROM_MODAL_SPURS]; // 20 B
} __packed MODAL_EEP4K_HEADER; // == 68 B } __packed MODAL_EEP4K_HEADER; // == 68 B
@@ -150,6 +177,6 @@ typedef struct {
uint16_t ee_numCtls; uint16_t ee_numCtls;
RD_EDGES_POWER ee_rdEdgesPower[NUM_EDGES*AR5416_4K_NUM_CTLS]; RD_EDGES_POWER ee_rdEdgesPower[NUM_EDGES*AR5416_4K_NUM_CTLS];
/* XXX these are dynamically calculated for use by shared code */ /* XXX these are dynamically calculated for use by shared code */
int8_t ee_antennaGainMax[2]; int8_t ee_antennaGainMax;
} HAL_EEPROM_v4k; } HAL_EEPROM_v4k;
#endif /* _AH_EEPROM_V4K_H_ */ #endif /* _AH_EEPROM_V4K_H_ */
@@ -28,6 +28,7 @@
#define AH_MAX(a,b) ((a)>(b)?(a):(b)) #define AH_MAX(a,b) ((a)>(b)?(a):(b))
#include <net80211/_ieee80211.h> #include <net80211/_ieee80211.h>
#include "opt_ah.h" /* needed for AH_SUPPORT_AR5416 */
#ifndef NBBY #ifndef NBBY
#define NBBY 8 /* number of bits/byte */ #define NBBY 8 /* number of bits/byte */
@@ -80,7 +81,8 @@ struct ath_hal_chip {
const char *name; const char *name;
const char *(*probe)(uint16_t vendorid, uint16_t devid); const char *(*probe)(uint16_t vendorid, uint16_t devid);
struct ath_hal *(*attach)(uint16_t devid, HAL_SOFTC, struct ath_hal *(*attach)(uint16_t devid, HAL_SOFTC,
HAL_BUS_TAG, HAL_BUS_HANDLE, HAL_STATUS *error); HAL_BUS_TAG, HAL_BUS_HANDLE, uint16_t *eepromdata,
HAL_STATUS *error);
}; };
#ifndef AH_CHIP #ifndef AH_CHIP
#define AH_CHIP(_name, _probe, _attach) \ #define AH_CHIP(_name, _probe, _attach) \
@@ -135,11 +137,16 @@ typedef struct {
#define CHANNEL_IQVALID 0x01 /* IQ calibration valid */ #define CHANNEL_IQVALID 0x01 /* IQ calibration valid */
#define CHANNEL_ANI_INIT 0x02 /* ANI state initialized */ #define CHANNEL_ANI_INIT 0x02 /* ANI state initialized */
#define CHANNEL_ANI_SETUP 0x04 /* ANI state setup */ #define CHANNEL_ANI_SETUP 0x04 /* ANI state setup */
#define CHANNEL_MIMO_NF_VALID 0x04 /* Mimo NF values are valid */
uint8_t calValid; /* bitmask of cal types */ uint8_t calValid; /* bitmask of cal types */
int8_t iCoff; int8_t iCoff;
int8_t qCoff; int8_t qCoff;
int16_t rawNoiseFloor; int16_t rawNoiseFloor;
int16_t noiseFloorAdjust; int16_t noiseFloorAdjust;
#ifdef AH_SUPPORT_AR5416
int16_t noiseFloorCtl[AH_MIMO_MAX_CHAINS];
int16_t noiseFloorExt[AH_MIMO_MAX_CHAINS];
#endif /* AH_SUPPORT_AR5416 */
uint16_t mainSpur; /* cached spur value for this channel */ uint16_t mainSpur; /* cached spur value for this channel */
} HAL_CHANNEL_INTERNAL; } HAL_CHANNEL_INTERNAL;
@@ -177,6 +184,7 @@ typedef struct {
halChanHalfRate : 1, halChanHalfRate : 1,
halChanQuarterRate : 1, halChanQuarterRate : 1,
halHTSupport : 1, halHTSupport : 1,
halHTSGI20Support : 1,
halRfSilentSupport : 1, halRfSilentSupport : 1,
halHwPhyCounterSupport : 1, halHwPhyCounterSupport : 1,
halWowSupport : 1, halWowSupport : 1,
@@ -190,11 +198,18 @@ typedef struct {
halCSTSupport : 1, halCSTSupport : 1,
halRifsRxSupport : 1, halRifsRxSupport : 1,
halRifsTxSupport : 1, halRifsTxSupport : 1,
hal4AddrAggrSupport : 1,
halExtChanDfsSupport : 1, halExtChanDfsSupport : 1,
halUseCombinedRadarRssi : 1,
halForcePpmSupport : 1, halForcePpmSupport : 1,
halEnhancedPmSupport : 1, halEnhancedPmSupport : 1,
halEnhancedDfsSupport : 1,
halMbssidAggrSupport : 1, halMbssidAggrSupport : 1,
halBssidMatchSupport : 1; halBssidMatchSupport : 1,
hal4kbSplitTransSupport : 1,
halHasRxSelfLinkedTail : 1,
halSupportsFastClock5GHz : 1, /* Hardware supports 5ghz fast clock; check eeprom/channel before using */
halHasLongRxDescTsf : 1;
uint32_t halWirelessModes; uint32_t halWirelessModes;
uint16_t halTotalQueues; uint16_t halTotalQueues;
uint16_t halKeyCacheSize; uint16_t halKeyCacheSize;
@@ -208,6 +223,8 @@ typedef struct {
uint8_t halNumAntCfg2GHz; uint8_t halNumAntCfg2GHz;
uint8_t halNumAntCfg5GHz; uint8_t halNumAntCfg5GHz;
uint32_t halIntrMask; uint32_t halIntrMask;
uint8_t halTxStreams;
uint8_t halRxStreams;
} HAL_CAPABILITIES; } HAL_CAPABILITIES;
struct regDomain; struct regDomain;
@@ -255,7 +272,7 @@ struct ath_hal_private {
uint16_t ah_eeversion; /* EEPROM version */ uint16_t ah_eeversion; /* EEPROM version */
void (*ah_eepromDetach)(struct ath_hal *); void (*ah_eepromDetach)(struct ath_hal *);
HAL_STATUS (*ah_eepromGet)(struct ath_hal *, int, void *); HAL_STATUS (*ah_eepromGet)(struct ath_hal *, int, void *);
HAL_BOOL (*ah_eepromSet)(struct ath_hal *, int, int); HAL_STATUS (*ah_eepromSet)(struct ath_hal *, int, int);
uint16_t (*ah_getSpurChan)(struct ath_hal *, int, HAL_BOOL); uint16_t (*ah_getSpurChan)(struct ath_hal *, int, HAL_BOOL);
HAL_BOOL (*ah_eepromDiag)(struct ath_hal *, int request, HAL_BOOL (*ah_eepromDiag)(struct ath_hal *, int request,
const void *args, uint32_t argsize, const void *args, uint32_t argsize,
@@ -286,6 +303,8 @@ struct ath_hal_private {
* State for regulatory domain handling. * State for regulatory domain handling.
*/ */
HAL_REG_DOMAIN ah_currentRD; /* EEPROM regulatory domain */ HAL_REG_DOMAIN ah_currentRD; /* EEPROM regulatory domain */
HAL_REG_DOMAIN ah_currentRDext; /* EEPROM extended regdomain flags */
HAL_DFS_DOMAIN ah_dfsDomain; /* current DFS domain */
HAL_CHANNEL_INTERNAL ah_channels[AH_MAXCHAN]; /* private chan state */ HAL_CHANNEL_INTERNAL ah_channels[AH_MAXCHAN]; /* private chan state */
u_int ah_nchan; /* valid items in ah_channels */ u_int ah_nchan; /* valid items in ah_channels */
const struct regDomain *ah_rd2GHz; /* reg state for 2G band */ const struct regDomain *ah_rd2GHz; /* reg state for 2G band */
@@ -334,6 +353,8 @@ struct ath_hal_private {
(_ah)->ah_configPCIE(_ah, _reset) (_ah)->ah_configPCIE(_ah, _reset)
#define ath_hal_disablePCIE(_ah) \ #define ath_hal_disablePCIE(_ah) \
(_ah)->ah_disablePCIE(_ah) (_ah)->ah_disablePCIE(_ah)
#define ath_hal_setInterrupts(_ah, _mask) \
(_ah)->ah_setInterrupts(_ah, _mask)
#define ath_hal_eepromDetach(_ah) do { \ #define ath_hal_eepromDetach(_ah) do { \
if (AH_PRIVATE(_ah)->ah_eepromDetach != AH_NULL) \ if (AH_PRIVATE(_ah)->ah_eepromDetach != AH_NULL) \
@@ -401,17 +422,6 @@ extern HAL_BOOL ath_hal_setTxQProps(struct ath_hal *ah,
extern HAL_BOOL ath_hal_getTxQProps(struct ath_hal *ah, extern HAL_BOOL ath_hal_getTxQProps(struct ath_hal *ah,
HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi); HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi);
typedef enum {
HAL_ANI_PRESENT, /* is ANI support present */
HAL_ANI_NOISE_IMMUNITY_LEVEL, /* set level */
HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, /* enable/disable */
HAL_ANI_CCK_WEAK_SIGNAL_THR, /* enable/disable */
HAL_ANI_FIRSTEP_LEVEL, /* set level */
HAL_ANI_SPUR_IMMUNITY_LEVEL, /* set level */
HAL_ANI_MODE = 6, /* 0 => manual, 1 => auto (XXX do not change) */
HAL_ANI_PHYERR_RESET, /* reset phy error stats */
} HAL_ANI_CMD;
#define HAL_SPUR_VAL_MASK 0x3FFF #define HAL_SPUR_VAL_MASK 0x3FFF
#define HAL_SPUR_CHAN_WIDTH 87 #define HAL_SPUR_CHAN_WIDTH 87
#define HAL_BIN_WIDTH_BASE_100HZ 3125 #define HAL_BIN_WIDTH_BASE_100HZ 3125
@@ -453,6 +463,8 @@ isBigEndian(void)
*/ */
#define SM(_v, _f) (((_v) << _f##_S) & (_f)) #define SM(_v, _f) (((_v) << _f##_S) & (_f))
#define MS(_v, _f) (((_v) & (_f)) >> _f##_S) #define MS(_v, _f) (((_v) & (_f)) >> _f##_S)
#define OS_REG_RMW(_a, _r, _set, _clr) \
OS_REG_WRITE(_a, _r, (OS_REG_READ(_a, _r) & ~(_clr)) | (_set))
#define OS_REG_RMW_FIELD(_a, _r, _f, _v) \ #define OS_REG_RMW_FIELD(_a, _r, _f, _v) \
OS_REG_WRITE(_a, _r, \ OS_REG_WRITE(_a, _r, \
(OS_REG_READ(_a, _r) &~ (_f)) | (((_v) << _f##_S) & (_f))) (OS_REG_READ(_a, _r) &~ (_f)) | (((_v) << _f##_S) & (_f)))
@@ -461,14 +473,15 @@ isBigEndian(void)
#define OS_REG_CLR_BIT(_a, _r, _f) \ #define OS_REG_CLR_BIT(_a, _r, _f) \
OS_REG_WRITE(_a, _r, OS_REG_READ(_a, _r) &~ (_f)) OS_REG_WRITE(_a, _r, OS_REG_READ(_a, _r) &~ (_f))
/* system-configurable parameters */ /* Analog register writes may require a delay between each one (eg Merlin?) */
extern int ath_hal_dma_beacon_response_time; /* in TU's */ #define OS_A_REG_RMW_FIELD(_a, _r, _f, _v) \
extern int ath_hal_sw_beacon_response_time; /* in TU's */ do { OS_REG_WRITE(_a, _r, (OS_REG_READ(_a, _r) &~ (_f)) | (((_v) << _f##_S) & (_f))) ; OS_DELAY(100); } while (0)
extern int ath_hal_additional_swba_backoff; /* in TU's */
/* wait for the register contents to have the specified value */ /* wait for the register contents to have the specified value */
extern HAL_BOOL ath_hal_wait(struct ath_hal *, u_int reg, extern HAL_BOOL ath_hal_wait(struct ath_hal *, u_int reg,
uint32_t mask, uint32_t val); uint32_t mask, uint32_t val);
extern HAL_BOOL ath_hal_waitfor(struct ath_hal *, u_int reg,
uint32_t mask, uint32_t val, uint32_t timeout);
/* return the first n bits in val reversed */ /* return the first n bits in val reversed */
extern uint32_t ath_hal_reverseBits(uint32_t val, uint32_t n); extern uint32_t ath_hal_reverseBits(uint32_t val, uint32_t n);
@@ -487,11 +500,38 @@ extern void ath_hal_free(void *);
/* common debugging interfaces */ /* common debugging interfaces */
#ifdef AH_DEBUG #ifdef AH_DEBUG
#include "ah_debug.h" #include "ah_debug.h"
extern int ath_hal_debug; extern int ath_hal_debug; /* Global debug flags */
extern void HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...)
/*
* This is used for global debugging, when ahp doesn't yet have the
* related debugging state. For example, during probe/attach.
*/
#define HALDEBUG_G(_ah, __m, ...) \
do { \
if ((__m) == HAL_DEBUG_UNMASKABLE || \
ath_hal_debug & (__m)) { \
DO_HALDEBUG((_ah), (__m), __VA_ARGS__); \
} \
} while (0);
/*
* This is used for local debugging, when ahp isn't NULL and
* thus may have debug flags set.
*/
#define HALDEBUG(_ah, __m, ...) \
do { \
if ((__m) == HAL_DEBUG_UNMASKABLE || \
ath_hal_debug & (__m) || \
(_ah)->ah_config.ah_debug & (__m)) { \
DO_HALDEBUG((_ah), (__m), __VA_ARGS__); \
} \
} while(0);
extern void DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...)
__printflike(3,4); __printflike(3,4);
#else #else
#define HALDEBUG(_ah, __m, _fmt, ...) #define HALDEBUG(_ah, __m, ...)
#define HALDEBUG_G(_ah, __m, ...)
#endif /* AH_DEBUG */ #endif /* AH_DEBUG */
/* /*
@@ -587,45 +627,8 @@ extern HAL_BOOL ath_hal_setcapability(struct ath_hal *ah,
HAL_CAPABILITY_TYPE type, uint32_t capability, HAL_CAPABILITY_TYPE type, uint32_t capability,
uint32_t setting, HAL_STATUS *status); uint32_t setting, HAL_STATUS *status);
/* /* The diagnostic codes used to be internally defined here -adrian */
* Diagnostic interface. This is an open-ended interface that #include "ah_diagcodes.h"
* is opaque to applications. Diagnostic programs use this to
* retrieve internal data structures, etc. There is no guarantee
* that calling conventions for calls other than HAL_DIAG_REVS
* are stable between HAL releases; a diagnostic application must
* use the HAL revision information to deal with ABI/API differences.
*
* NB: do not renumber these, certain codes are publicly used.
*/
enum {
HAL_DIAG_REVS = 0, /* MAC/PHY/Radio revs */
HAL_DIAG_EEPROM = 1, /* EEPROM contents */
HAL_DIAG_EEPROM_EXP_11A = 2, /* EEPROM 5112 power exp for 11a */
HAL_DIAG_EEPROM_EXP_11B = 3, /* EEPROM 5112 power exp for 11b */
HAL_DIAG_EEPROM_EXP_11G = 4, /* EEPROM 5112 power exp for 11g */
HAL_DIAG_ANI_CURRENT = 5, /* ANI current channel state */
HAL_DIAG_ANI_OFDM = 6, /* ANI OFDM timing error stats */
HAL_DIAG_ANI_CCK = 7, /* ANI CCK timing error stats */
HAL_DIAG_ANI_STATS = 8, /* ANI statistics */
HAL_DIAG_RFGAIN = 9, /* RfGain GAIN_VALUES */
HAL_DIAG_RFGAIN_CURSTEP = 10, /* RfGain GAIN_OPTIMIZATION_STEP */
HAL_DIAG_PCDAC = 11, /* PCDAC table */
HAL_DIAG_TXRATES = 12, /* Transmit rate table */
HAL_DIAG_REGS = 13, /* Registers */
HAL_DIAG_ANI_CMD = 14, /* ANI issue command (XXX do not change!) */
HAL_DIAG_SETKEY = 15, /* Set keycache backdoor */
HAL_DIAG_RESETKEY = 16, /* Reset keycache backdoor */
HAL_DIAG_EEREAD = 17, /* Read EEPROM word */
HAL_DIAG_EEWRITE = 18, /* Write EEPROM word */
/* 19-26 removed, do not reuse */
HAL_DIAG_RDWRITE = 27, /* Write regulatory domain */
HAL_DIAG_RDREAD = 28, /* Get regulatory domain */
HAL_DIAG_FATALERR = 29, /* Read cached interrupt state */
HAL_DIAG_11NCOMPAT = 30, /* 11n compatibility tweaks */
HAL_DIAG_ANI_PARAMS = 31, /* ANI noise immunity parameters */
HAL_DIAG_CHECK_HANGS = 32, /* check h/w hangs */
HAL_DIAG_SETREGS = 33, /* write registers */
};
enum { enum {
HAL_BB_HANG_DFS = 0x0001, HAL_BB_HANG_DFS = 0x0001,
@@ -801,4 +804,31 @@ extern int ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
#define TURBO_SYMBOL_TIME 4 #define TURBO_SYMBOL_TIME 4
#define WLAN_CTRL_FRAME_SIZE (2+2+6+4) /* ACK+FCS */ #define WLAN_CTRL_FRAME_SIZE (2+2+6+4) /* ACK+FCS */
/* Generic EEPROM board value functions */
extern HAL_BOOL ath_ee_getLowerUpperIndex(uint8_t target, uint8_t *pList,
uint16_t listSize, uint16_t *indexL, uint16_t *indexR);
extern HAL_BOOL ath_ee_FillVpdTable(uint8_t pwrMin, uint8_t pwrMax,
uint8_t *pPwrList, uint8_t *pVpdList, uint16_t numIntercepts,
uint8_t *pRetVpdList);
extern int16_t ath_ee_interpolate(uint16_t target, uint16_t srcLeft,
uint16_t srcRight, int16_t targetLeft, int16_t targetRight);
/* Whether 5ghz fast clock is needed */
/*
* The chipset (Merlin, AR9300/later) should set the capability flag below;
* this flag simply says that the hardware can do it, not that the EEPROM
* says it can.
*
* Merlin 2.0/2.1 chips with an EEPROM version > 16 do 5ghz fast clock
* if the relevant eeprom flag is set.
* Merlin 2.0/2.1 chips with an EEPROM version <= 16 do 5ghz fast clock
* by default.
*/
#define IS_5GHZ_FAST_CLOCK_EN(_ah, _c) \
(IEEE80211_IS_CHAN_5GHZ(_c) && \
AH_PRIVATE((_ah))->ah_caps.halSupportsFastClock5GHz && \
ath_hal_eepromGetFlag((_ah), AR_EEP_FSTCLK_5G))
#endif /* _ATH_AH_INTERAL_H_ */ #endif /* _ATH_AH_INTERAL_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,163 @@
/*
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2005-2006 Atheros Communications, Inc.
* All rights reserved.
*
* 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.
*
* $FreeBSD$
*/
#ifndef __AH_REGDOMAIN_H__
#define __AH_REGDOMAIN_H__
/*
* BMLEN defines the size of the bitmask used to hold frequency
* band specifications. Note this must agree with the BM macro
* definition that's used to setup initializers. See also further
* comments below.
*/
#define BMLEN 2 /* 2 x 64 bits in each channel bitmask */
typedef uint64_t chanbmask_t[BMLEN];
/*
* The following describe the bit masks for different passive scan
* capability/requirements per regdomain.
*/
#define NO_PSCAN 0x0ULL /* NB: must be zero */
#define PSCAN_FCC 0x0000000000000001ULL
#define PSCAN_FCC_T 0x0000000000000002ULL
#define PSCAN_ETSI 0x0000000000000004ULL
#define PSCAN_MKK1 0x0000000000000008ULL
#define PSCAN_MKK2 0x0000000000000010ULL
#define PSCAN_MKKA 0x0000000000000020ULL
#define PSCAN_MKKA_G 0x0000000000000040ULL
#define PSCAN_ETSIA 0x0000000000000080ULL
#define PSCAN_ETSIB 0x0000000000000100ULL
#define PSCAN_ETSIC 0x0000000000000200ULL
#define PSCAN_WWR 0x0000000000000400ULL
#define PSCAN_MKKA1 0x0000000000000800ULL
#define PSCAN_MKKA1_G 0x0000000000001000ULL
#define PSCAN_MKKA2 0x0000000000002000ULL
#define PSCAN_MKKA2_G 0x0000000000004000ULL
#define PSCAN_MKK3 0x0000000000008000ULL
#define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL
#define IS_ECM_CHAN 0x8000000000000000ULL
/*
* The following are flags for different requirements per reg domain.
* These requirements are either inhereted from the reg domain pair or
* from the unitary reg domain if the reg domain pair flags value is 0
*/
enum {
NO_REQ = 0x00000000, /* NB: must be zero */
DISALLOW_ADHOC_11A = 0x00000001, /* adhoc not allowed in 5GHz */
DISALLOW_ADHOC_11A_TURB = 0x00000002, /* not allowed w/ 5GHz turbo */
NEED_NFC = 0x00000004, /* need noise floor check */
ADHOC_PER_11D = 0x00000008, /* must receive 11d beacon */
LIMIT_FRAME_4MS = 0x00000020, /* 4msec tx burst limit */
NO_HOSTAP = 0x00000040, /* No HOSTAP mode opereation */
};
/* Bit masks for DFS per regdomain */
enum {
NO_DFS = 0x0000000000000000ULL, /* NB: must be zero */
DFS_FCC3 = 0x0000000000000001ULL,
DFS_ETSI = 0x0000000000000002ULL,
DFS_MKK4 = 0x0000000000000004ULL,
};
enum { /* conformance test limits */
FCC = 0x10,
MKK = 0x40,
ETSI = 0x30,
};
/*
* THE following table is the mapping of regdomain pairs specified by
* an 8 bit regdomain value to the individual unitary reg domains
*/
typedef struct regDomainPair {
HAL_REG_DOMAIN regDmnEnum; /* 16 bit reg domain pair */
HAL_REG_DOMAIN regDmn5GHz; /* 5GHz reg domain */
HAL_REG_DOMAIN regDmn2GHz; /* 2GHz reg domain */
uint32_t flags5GHz; /* Requirements flags (AdHoc
disallow, noise floor cal needed,
etc) */
uint32_t flags2GHz; /* Requirements flags (AdHoc
disallow, noise floor cal needed,
etc) */
uint64_t pscanMask; /* Passive Scan flags which
can override unitary domain
passive scan flags. This
value is used as a mask on
the unitary flags*/
uint16_t singleCC; /* Country code of single country if
a one-on-one mapping exists */
} REG_DMN_PAIR_MAPPING;
typedef struct {
HAL_CTRY_CODE countryCode;
HAL_REG_DOMAIN regDmnEnum;
} COUNTRY_CODE_TO_ENUM_RD;
/*
* Frequency band collections are defined using bitmasks. Each bit
* in a mask is the index of an entry in one of the following tables.
* Bitmasks are BMLEN*64 bits so if a table grows beyond that the bit
* vectors must be enlarged or the tables split somehow (e.g. split
* 1/2 and 1/4 rate channels into a separate table).
*
* Beware of ordering; the indices are defined relative to the preceding
* entry so if things get off there will be confusion. A good way to
* check the indices is to collect them in a switch statement in a stub
* function so the compiler checks for duplicates.
*/
typedef struct {
uint16_t lowChannel; /* Low channel center in MHz */
uint16_t highChannel; /* High Channel center in MHz */
uint8_t powerDfs; /* Max power (dBm) for channel
range when using DFS */
uint8_t antennaMax; /* Max allowed antenna gain */
uint8_t channelBW; /* Bandwidth of the channel */
uint8_t channelSep; /* Channel separation within
the band */
uint64_t useDfs; /* Use DFS in the RegDomain
if corresponding bit is set */
uint64_t usePassScan; /* Use Passive Scan in the RegDomain
if corresponding bit is set */
} REG_DMN_FREQ_BAND;
typedef struct regDomain {
uint16_t regDmnEnum; /* value from EnumRd table */
uint8_t conformanceTestLimit;
uint32_t flags; /* Requirement flags (AdHoc disallow,
noise floor cal needed, etc) */
uint64_t dfsMask; /* DFS bitmask for 5Ghz tables */
uint64_t pscan; /* Bitmask for passive scan */
chanbmask_t chan11a; /* 11a channels */
chanbmask_t chan11a_turbo; /* 11a static turbo channels */
chanbmask_t chan11a_dyn_turbo; /* 11a dynamic turbo channels */
chanbmask_t chan11a_half; /* 11a 1/2 width channels */
chanbmask_t chan11a_quarter; /* 11a 1/4 width channels */
chanbmask_t chan11b; /* 11b channels */
chanbmask_t chan11g; /* 11g channels */
chanbmask_t chan11g_turbo; /* 11g dynamic turbo channels */
chanbmask_t chan11g_half; /* 11g 1/2 width channels */
chanbmask_t chan11g_quarter; /* 11g 1/4 width channels */
} REG_DOMAIN;
struct cmode {
u_int mode;
u_int flags;
};
#endif
@@ -0,0 +1,170 @@
/*
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2005-2011 Atheros Communications, Inc.
* All rights reserved.
*
* 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.
*
* $FreeBSD$
*/
#ifndef __AH_REGDOMAIN_CTRY_H__
#define __AH_REGDOMAIN_CTRY_H__
#define DEF_REGDMN FCC1_FCCA
/*
* This table maps country ISO codes from net80211 into regulatory
* domains which the ath regulatory domain code understands.
*/
static COUNTRY_CODE_TO_ENUM_RD allCountries[] = {
{ CTRY_DEBUG, NO_ENUMRD },
{ CTRY_DEFAULT, DEF_REGDMN },
{ CTRY_ALBANIA, NULL1_WORLD },
{ CTRY_ALGERIA, NULL1_WORLD },
{ CTRY_ARGENTINA, APL3_WORLD },
{ CTRY_ARMENIA, ETSI4_WORLD },
{ CTRY_AUSTRALIA, FCC3_WORLD },
{ CTRY_AUSTRIA, ETSI1_WORLD },
{ CTRY_AZERBAIJAN, ETSI4_WORLD },
{ CTRY_BAHRAIN, APL6_WORLD },
{ CTRY_BELARUS, NULL1_WORLD },
{ CTRY_BELGIUM, ETSI1_WORLD },
{ CTRY_BELIZE, APL1_ETSIC },
{ CTRY_BOLIVIA, APL1_ETSIC },
{ CTRY_BRAZIL, FCC3_WORLD },
{ CTRY_BRUNEI_DARUSSALAM,APL1_WORLD },
{ CTRY_BULGARIA, ETSI6_WORLD },
{ CTRY_CANADA, FCC2_FCCA },
{ CTRY_CHILE, APL6_WORLD },
{ CTRY_CHINA, APL1_WORLD },
{ CTRY_COLOMBIA, FCC1_FCCA },
{ CTRY_COSTA_RICA, NULL1_WORLD },
{ CTRY_CROATIA, ETSI3_WORLD },
{ CTRY_CYPRUS, ETSI1_WORLD },
{ CTRY_CZECH, ETSI1_WORLD },
{ CTRY_DENMARK, ETSI1_WORLD },
{ CTRY_DOMINICAN_REPUBLIC,FCC1_FCCA },
{ CTRY_ECUADOR, NULL1_WORLD },
{ CTRY_EGYPT, ETSI3_WORLD },
{ CTRY_EL_SALVADOR, NULL1_WORLD },
{ CTRY_ESTONIA, ETSI1_WORLD },
{ CTRY_FINLAND, ETSI1_WORLD },
{ CTRY_FRANCE, ETSI1_WORLD },
{ CTRY_FRANCE2, ETSI3_WORLD },
{ CTRY_GEORGIA, ETSI4_WORLD },
{ CTRY_GERMANY, ETSI1_WORLD },
{ CTRY_GREECE, ETSI1_WORLD },
{ CTRY_GUATEMALA, FCC1_FCCA },
{ CTRY_HONDURAS, NULL1_WORLD },
{ CTRY_HONG_KONG, FCC2_WORLD },
{ CTRY_HUNGARY, ETSI1_WORLD },
{ CTRY_ICELAND, ETSI1_WORLD },
{ CTRY_INDIA, APL6_WORLD },
{ CTRY_INDONESIA, APL1_WORLD },
{ CTRY_IRAN, APL1_WORLD },
{ CTRY_IRELAND, ETSI1_WORLD },
{ CTRY_ISRAEL, NULL1_WORLD },
{ CTRY_ITALY, ETSI1_WORLD },
{ CTRY_JAPAN, MKK1_MKKA },
{ CTRY_JAPAN1, MKK1_MKKB },
{ CTRY_JAPAN2, MKK1_FCCA },
{ CTRY_JAPAN3, MKK2_MKKA },
{ CTRY_JAPAN4, MKK1_MKKA1 },
{ CTRY_JAPAN5, MKK1_MKKA2 },
{ CTRY_JAPAN6, MKK1_MKKC },
{ CTRY_JAPAN7, MKK3_MKKB },
{ CTRY_JAPAN8, MKK3_MKKA2 },
{ CTRY_JAPAN9, MKK3_MKKC },
{ CTRY_JAPAN10, MKK4_MKKB },
{ CTRY_JAPAN11, MKK4_MKKA2 },
{ CTRY_JAPAN12, MKK4_MKKC },
{ CTRY_JAPAN13, MKK5_MKKB },
{ CTRY_JAPAN14, MKK5_MKKA2 },
{ CTRY_JAPAN15, MKK5_MKKC },
{ CTRY_JAPAN16, MKK6_MKKB },
{ CTRY_JAPAN17, MKK6_MKKA2 },
{ CTRY_JAPAN18, MKK6_MKKC },
{ CTRY_JAPAN19, MKK7_MKKB },
{ CTRY_JAPAN20, MKK7_MKKA2 },
{ CTRY_JAPAN21, MKK7_MKKC },
{ CTRY_JAPAN22, MKK8_MKKB },
{ CTRY_JAPAN23, MKK8_MKKA2 },
{ CTRY_JAPAN24, MKK8_MKKC },
{ CTRY_JORDAN, APL4_WORLD },
{ CTRY_KAZAKHSTAN, NULL1_WORLD },
{ CTRY_KOREA_NORTH, APL2_WORLD },
{ CTRY_KOREA_ROC, APL2_WORLD },
{ CTRY_KOREA_ROC2, APL2_WORLD },
{ CTRY_KOREA_ROC3, APL9_WORLD },
{ CTRY_KUWAIT, NULL1_WORLD },
{ CTRY_LATVIA, ETSI1_WORLD },
{ CTRY_LEBANON, NULL1_WORLD },
{ CTRY_LIECHTENSTEIN,ETSI1_WORLD },
{ CTRY_LITHUANIA, ETSI1_WORLD },
{ CTRY_LUXEMBOURG, ETSI1_WORLD },
{ CTRY_MACAU, FCC2_WORLD },
{ CTRY_MACEDONIA, NULL1_WORLD },
{ CTRY_MALAYSIA, APL8_WORLD },
{ CTRY_MALTA, ETSI1_WORLD },
{ CTRY_MEXICO, FCC1_FCCA },
{ CTRY_MONACO, ETSI4_WORLD },
{ CTRY_MOROCCO, NULL1_WORLD },
{ CTRY_NETHERLANDS, ETSI1_WORLD },
{ CTRY_NEW_ZEALAND, FCC2_ETSIC },
{ CTRY_NORWAY, ETSI1_WORLD },
{ CTRY_OMAN, APL6_WORLD },
{ CTRY_PAKISTAN, NULL1_WORLD },
{ CTRY_PANAMA, FCC1_FCCA },
{ CTRY_PERU, APL1_WORLD },
{ CTRY_PHILIPPINES, FCC3_WORLD },
{ CTRY_POLAND, ETSI1_WORLD },
{ CTRY_PORTUGAL, ETSI1_WORLD },
{ CTRY_PUERTO_RICO, FCC1_FCCA },
{ CTRY_QATAR, NULL1_WORLD },
{ CTRY_ROMANIA, NULL1_WORLD },
{ CTRY_RUSSIA, NULL1_WORLD },
{ CTRY_SAUDI_ARABIA,FCC2_WORLD },
{ CTRY_SINGAPORE, APL6_WORLD },
{ CTRY_SLOVAKIA, ETSI1_WORLD },
{ CTRY_SLOVENIA, ETSI1_WORLD },
{ CTRY_SOUTH_AFRICA,FCC3_WORLD },
{ CTRY_SPAIN, ETSI1_WORLD },
{ CTRY_SWEDEN, ETSI1_WORLD },
{ CTRY_SWITZERLAND, ETSI1_WORLD },
{ CTRY_SYRIA, NULL1_WORLD },
{ CTRY_TAIWAN, APL3_FCCA },
{ CTRY_THAILAND, FCC3_WORLD },
{ CTRY_TRINIDAD_Y_TOBAGO,ETSI4_WORLD },
{ CTRY_TUNISIA, ETSI3_WORLD },
{ CTRY_TURKEY, ETSI3_WORLD },
{ CTRY_UKRAINE, NULL1_WORLD },
{ CTRY_UAE, NULL1_WORLD },
{ CTRY_UNITED_KINGDOM, ETSI1_WORLD },
{ CTRY_UNITED_STATES, FCC1_FCCA },
{ CTRY_UNITED_STATES_FCC49,FCC4_FCCA },
{ CTRY_URUGUAY, FCC1_WORLD },
{ CTRY_UZBEKISTAN, FCC3_FCCA },
{ CTRY_VENEZUELA, APL2_ETSIC },
{ CTRY_VIET_NAM, NULL1_WORLD },
{ CTRY_ZIMBABWE, NULL1_WORLD }
};
#endif
@@ -0,0 +1,749 @@
/*
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2005-2006 Atheros Communications, Inc.
* All rights reserved.
*
* 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.
*
* $FreeBSD$
*/
#ifndef __AH_REGDOMAIN_DOMAINS_H__
#define __AH_REGDOMAIN_DOMAINS_H__
/*
* BMLEN defines the size of the bitmask used to hold frequency
* band specifications. Note this must agree with the BM macro
* definition that's used to setup initializers. See also further
* comments below.
*/
/* BMLEN is now defined in ah_regdomain.h */
#define W0(_a) \
(((_a) >= 0 && (_a) < 64 ? (((uint64_t) 1)<<(_a)) : (uint64_t) 0))
#define W1(_a) \
(((_a) > 63 && (_a) < 128 ? (((uint64_t) 1)<<((_a)-64)) : (uint64_t) 0))
#define BM1(_fa) { W0(_fa), W1(_fa) }
#define BM2(_fa, _fb) { W0(_fa) | W0(_fb), W1(_fa) | W1(_fb) }
#define BM3(_fa, _fb, _fc) \
{ W0(_fa) | W0(_fb) | W0(_fc), W1(_fa) | W1(_fb) | W1(_fc) }
#define BM4(_fa, _fb, _fc, _fd) \
{ W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd), \
W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) }
#define BM5(_fa, _fb, _fc, _fd, _fe) \
{ W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe), \
W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) }
#define BM6(_fa, _fb, _fc, _fd, _fe, _ff) \
{ W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe) | W0(_ff), \
W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) | W1(_ff) }
#define BM7(_fa, _fb, _fc, _fd, _fe, _ff, _fg) \
{ W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe) | W0(_ff) | \
W0(_fg),\
W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) | W1(_ff) | \
W1(_fg) }
#define BM8(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh) \
{ W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe) | W0(_ff) | \
W0(_fg) | W0(_fh) , \
W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) | W1(_ff) | \
W1(_fg) | W1(_fh) }
#define BM9(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi) \
{ W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe) | W0(_ff) | \
W0(_fg) | W0(_fh) | W0(_fi) , \
W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) | W1(_ff) | \
W1(_fg) | W1(_fh) | W1(_fi) }
static REG_DOMAIN regDomains[] = {
{.regDmnEnum = DEBUG_REG_DMN,
.conformanceTestLimit = FCC,
.dfsMask = DFS_FCC3,
.chan11a = BM4(F1_4950_4980,
F1_5120_5240,
F1_5260_5700,
F1_5745_5825),
.chan11a_half = BM4(F1_4945_4985,
F2_5120_5240,
F2_5260_5700,
F7_5745_5825),
.chan11a_quarter = BM4(F1_4942_4987,
F3_5120_5240,
F3_5260_5700,
F8_5745_5825),
.chan11a_turbo = BM8(T1_5130_5210,
T1_5250_5330,
T1_5370_5490,
T1_5530_5650,
T1_5150_5190,
T1_5230_5310,
T1_5350_5470,
T1_5510_5670),
.chan11a_dyn_turbo = BM4(T1_5200_5240,
T1_5280_5280,
T1_5540_5660,
T1_5765_5805),
.chan11b = BM4(F1_2312_2372,
F1_2412_2472,
F1_2484_2484,
F1_2512_2732),
.chan11g = BM3(G1_2312_2372, G1_2412_2472, G1_2512_2732),
.chan11g_turbo = BM3(T1_2312_2372, T1_2437_2437, T1_2512_2732),
.chan11g_half = BM3(G2_2312_2372, G4_2412_2472, G2_2512_2732),
.chan11g_quarter = BM3(G3_2312_2372, G5_2412_2472, G3_2512_2732),
},
{.regDmnEnum = APL1,
.conformanceTestLimit = FCC,
.chan11a = BM1(F4_5745_5825),
},
{.regDmnEnum = APL2,
.conformanceTestLimit = FCC,
.chan11a = BM1(F1_5745_5805),
},
{.regDmnEnum = APL3,
.conformanceTestLimit = FCC,
.chan11a = BM2(F1_5280_5320, F2_5745_5805),
},
{.regDmnEnum = APL4,
.conformanceTestLimit = FCC,
.chan11a = BM2(F4_5180_5240, F3_5745_5825),
},
{.regDmnEnum = APL5,
.conformanceTestLimit = FCC,
.chan11a = BM1(F2_5745_5825),
},
{.regDmnEnum = APL6,
.conformanceTestLimit = ETSI,
.dfsMask = DFS_ETSI,
.pscan = PSCAN_FCC_T | PSCAN_FCC,
.chan11a = BM3(F4_5180_5240, F2_5260_5320, F3_5745_5825),
.chan11a_turbo = BM3(T2_5210_5210, T1_5250_5290, T1_5760_5800),
},
{.regDmnEnum = APL8,
.conformanceTestLimit = ETSI,
.flags = DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB,
.chan11a = BM2(F6_5260_5320, F4_5745_5825),
},
{.regDmnEnum = APL9,
.conformanceTestLimit = ETSI,
.dfsMask = DFS_ETSI,
.pscan = PSCAN_ETSI,
.flags = DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB,
.chan11a = BM3(F1_5180_5320, F1_5500_5620, F3_5745_5805),
},
{.regDmnEnum = ETSI1,
.conformanceTestLimit = ETSI,
.dfsMask = DFS_ETSI,
.pscan = PSCAN_ETSI,
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
.chan11a = BM3(W2_5180_5240, F2_5260_5320, F2_5500_5700),
},
{.regDmnEnum = ETSI2,
.conformanceTestLimit = ETSI,
.dfsMask = DFS_ETSI,
.pscan = PSCAN_ETSI,
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
.chan11a = BM1(F3_5180_5240),
},
{.regDmnEnum = ETSI3,
.conformanceTestLimit = ETSI,
.dfsMask = DFS_ETSI,
.pscan = PSCAN_ETSI,
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
.chan11a = BM2(W2_5180_5240, F2_5260_5320),
},
{.regDmnEnum = ETSI4,
.conformanceTestLimit = ETSI,
.dfsMask = DFS_ETSI,
.pscan = PSCAN_ETSI,
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
.chan11a = BM2(F3_5180_5240, F1_5260_5320),
},
{.regDmnEnum = ETSI5,
.conformanceTestLimit = ETSI,
.dfsMask = DFS_ETSI,
.pscan = PSCAN_ETSI,
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
.chan11a = BM1(F1_5180_5240),
},
{.regDmnEnum = ETSI6,
.conformanceTestLimit = ETSI,
.dfsMask = DFS_ETSI,
.pscan = PSCAN_ETSI,
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
.chan11a = BM3(F5_5180_5240, F1_5260_5280, F3_5500_5700),
},
{.regDmnEnum = FCC1,
.conformanceTestLimit = FCC,
.chan11a = BM3(F2_5180_5240, F4_5260_5320, F5_5745_5825),
.chan11a_turbo = BM3(T1_5210_5210, T2_5250_5290, T2_5760_5800),
.chan11a_dyn_turbo = BM3(T1_5200_5240, T1_5280_5280, T1_5765_5805),
},
{.regDmnEnum = FCC2,
.conformanceTestLimit = FCC,
.chan11a = BM3(F6_5180_5240, F5_5260_5320, F6_5745_5825),
.chan11a_dyn_turbo = BM3(T2_5200_5240, T1_5280_5280, T1_5765_5805),
},
{.regDmnEnum = FCC3,
.conformanceTestLimit = FCC,
.dfsMask = DFS_FCC3,
.pscan = PSCAN_FCC | PSCAN_FCC_T,
.chan11a = BM4(F2_5180_5240,
F3_5260_5320,
F1_5500_5700,
F5_5745_5825),
.chan11a_turbo = BM4(T1_5210_5210,
T1_5250_5250,
T1_5290_5290,
T2_5760_5800),
.chan11a_dyn_turbo = BM3(T1_5200_5240, T2_5280_5280, T1_5540_5660),
},
{.regDmnEnum = FCC4,
.conformanceTestLimit = FCC,
.dfsMask = DFS_FCC3,
.pscan = PSCAN_FCC | PSCAN_FCC_T,
.chan11a = BM1(F1_4950_4980),
.chan11a_half = BM1(F1_4945_4985),
.chan11a_quarter = BM1(F1_4942_4987),
},
/* FCC1 w/ 1/2 and 1/4 width channels */
{.regDmnEnum = FCC5,
.conformanceTestLimit = FCC,
.chan11a = BM3(F2_5180_5240, F4_5260_5320, F5_5745_5825),
.chan11a_turbo = BM3(T1_5210_5210, T2_5250_5290, T2_5760_5800),
.chan11a_dyn_turbo = BM3(T1_5200_5240, T1_5280_5280, T1_5765_5805),
.chan11a_half = BM3(F7_5180_5240, F7_5260_5320, F9_5745_5825),
.chan11a_quarter = BM3(F8_5180_5240, F8_5260_5320,F10_5745_5825),
},
{.regDmnEnum = MKK1,
.conformanceTestLimit = MKK,
.pscan = PSCAN_MKK1,
.flags = DISALLOW_ADHOC_11A_TURB,
.chan11a = BM1(F1_5170_5230),
},
{.regDmnEnum = MKK2,
.conformanceTestLimit = MKK,
.pscan = PSCAN_MKK2,
.flags = DISALLOW_ADHOC_11A_TURB,
.chan11a = BM3(F1_4920_4980, F1_5040_5080, F1_5170_5230),
.chan11a_half = BM4(F1_4915_4925,
F1_4935_4945,
F1_5035_5040,
F1_5055_5055),
},
/* UNI-1 even */
{.regDmnEnum = MKK3,
.conformanceTestLimit = MKK,
.pscan = PSCAN_MKK3,
.flags = DISALLOW_ADHOC_11A_TURB,
.chan11a = BM1(F4_5180_5240),
},
/* UNI-1 even + UNI-2 */
{.regDmnEnum = MKK4,
.conformanceTestLimit = MKK,
.dfsMask = DFS_MKK4,
.pscan = PSCAN_MKK3,
.flags = DISALLOW_ADHOC_11A_TURB,
.chan11a = BM2(F4_5180_5240, F2_5260_5320),
},
/* UNI-1 even + UNI-2 + mid-band */
{.regDmnEnum = MKK5,
.conformanceTestLimit = MKK,
.dfsMask = DFS_MKK4,
.pscan = PSCAN_MKK3,
.flags = DISALLOW_ADHOC_11A_TURB,
.chan11a = BM3(F4_5180_5240, F2_5260_5320, F4_5500_5700),
},
/* UNI-1 odd + even */
{.regDmnEnum = MKK6,
.conformanceTestLimit = MKK,
.pscan = PSCAN_MKK1,
.flags = DISALLOW_ADHOC_11A_TURB,
.chan11a = BM2(F2_5170_5230, F4_5180_5240),
},
/* UNI-1 odd + UNI-1 even + UNI-2 */
{.regDmnEnum = MKK7,
.conformanceTestLimit = MKK,
.dfsMask = DFS_MKK4,
.pscan = PSCAN_MKK1 | PSCAN_MKK3,
.flags = DISALLOW_ADHOC_11A_TURB,
.chan11a = BM3(F1_5170_5230, F4_5180_5240, F2_5260_5320),
},
/* UNI-1 odd + UNI-1 even + UNI-2 + mid-band */
{.regDmnEnum = MKK8,
.conformanceTestLimit = MKK,
.dfsMask = DFS_MKK4,
.pscan = PSCAN_MKK1 | PSCAN_MKK3,
.flags = DISALLOW_ADHOC_11A_TURB,
.chan11a = BM4(F1_5170_5230,
F4_5180_5240,
F2_5260_5320,
F4_5500_5700),
},
/* UNI-1 even + 4.9 GHZ */
{.regDmnEnum = MKK9,
.conformanceTestLimit = MKK,
.pscan = PSCAN_MKK3,
.flags = DISALLOW_ADHOC_11A_TURB,
.chan11a = BM7(F1_4915_4925,
F1_4935_4945,
F1_4920_4980,
F1_5035_5040,
F1_5055_5055,
F1_5040_5080,
F4_5180_5240),
},
/* UNI-1 even + UNI-2 + 4.9 GHZ */
{.regDmnEnum = MKK10,
.conformanceTestLimit = MKK,
.dfsMask = DFS_MKK4,
.pscan = PSCAN_MKK3,
.flags = DISALLOW_ADHOC_11A_TURB,
.chan11a = BM8(F1_4915_4925,
F1_4935_4945,
F1_4920_4980,
F1_5035_5040,
F1_5055_5055,
F1_5040_5080,
F4_5180_5240,
F2_5260_5320),
},
/* Defined here to use when 2G channels are authorised for country K2 */
{.regDmnEnum = APLD,
.conformanceTestLimit = NO_CTL,
.chan11b = BM2(F2_2312_2372,F2_2412_2472),
.chan11g = BM2(G2_2312_2372,G2_2412_2472),
},
{.regDmnEnum = ETSIA,
.conformanceTestLimit = NO_CTL,
.pscan = PSCAN_ETSIA,
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
.chan11b = BM1(F1_2457_2472),
.chan11g = BM1(G1_2457_2472),
.chan11g_turbo = BM1(T2_2437_2437)
},
{.regDmnEnum = ETSIB,
.conformanceTestLimit = ETSI,
.pscan = PSCAN_ETSIB,
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
.chan11b = BM1(F1_2432_2442),
.chan11g = BM1(G1_2432_2442),
.chan11g_turbo = BM1(T2_2437_2437)
},
{.regDmnEnum = ETSIC,
.conformanceTestLimit = ETSI,
.pscan = PSCAN_ETSIC,
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
.chan11b = BM1(F3_2412_2472),
.chan11g = BM1(G3_2412_2472),
.chan11g_turbo = BM1(T2_2437_2437)
},
{.regDmnEnum = FCCA,
.conformanceTestLimit = FCC,
.chan11b = BM1(F1_2412_2462),
.chan11g = BM1(G1_2412_2462),
.chan11g_turbo = BM1(T2_2437_2437),
},
/* FCCA w/ 1/2 and 1/4 width channels */
{.regDmnEnum = FCCB,
.conformanceTestLimit = FCC,
.chan11b = BM1(F1_2412_2462),
.chan11g = BM1(G1_2412_2462),
.chan11g_turbo = BM1(T2_2437_2437),
.chan11g_half = BM1(G3_2412_2462),
.chan11g_quarter = BM1(G4_2412_2462),
},
{.regDmnEnum = MKKA,
.conformanceTestLimit = MKK,
.pscan = PSCAN_MKKA | PSCAN_MKKA_G
| PSCAN_MKKA1 | PSCAN_MKKA1_G
| PSCAN_MKKA2 | PSCAN_MKKA2_G,
.flags = DISALLOW_ADHOC_11A_TURB,
.chan11b = BM3(F2_2412_2462, F1_2467_2472, F2_2484_2484),
.chan11g = BM2(G2_2412_2462, G1_2467_2472),
.chan11g_turbo = BM1(T2_2437_2437)
},
{.regDmnEnum = MKKC,
.conformanceTestLimit = MKK,
.chan11b = BM1(F2_2412_2472),
.chan11g = BM1(G2_2412_2472),
.chan11g_turbo = BM1(T2_2437_2437)
},
{.regDmnEnum = WORLD,
.conformanceTestLimit = ETSI,
.chan11b = BM1(F2_2412_2472),
.chan11g = BM1(G2_2412_2472),
.chan11g_turbo = BM1(T2_2437_2437)
},
{.regDmnEnum = WOR0_WORLD,
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
.flags = ADHOC_PER_11D,
.chan11a = BM5(W1_5260_5320,
W1_5180_5240,
W1_5170_5230,
W1_5745_5825,
W1_5500_5700),
.chan11a_turbo = BM3(WT1_5210_5250,
WT1_5290_5290,
WT1_5760_5800),
.chan11b = BM8(W1_2412_2412,
W1_2437_2442,
W1_2462_2462,
W1_2472_2472,
W1_2417_2432,
W1_2447_2457,
W1_2467_2467,
W1_2484_2484),
.chan11g = BM7(WG1_2412_2412,
WG1_2437_2442,
WG1_2462_2462,
WG1_2472_2472,
WG1_2417_2432,
WG1_2447_2457,
WG1_2467_2467),
.chan11g_turbo = BM1(T3_2437_2437)
},
{.regDmnEnum = WOR01_WORLD,
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
.flags = ADHOC_PER_11D,
.chan11a = BM5(W1_5260_5320,
W1_5180_5240,
W1_5170_5230,
W1_5745_5825,
W1_5500_5700),
.chan11a_turbo = BM3(WT1_5210_5250,
WT1_5290_5290,
WT1_5760_5800),
.chan11b = BM5(W1_2412_2412,
W1_2437_2442,
W1_2462_2462,
W1_2417_2432,
W1_2447_2457),
.chan11g = BM5(WG1_2412_2412,
WG1_2437_2442,
WG1_2462_2462,
WG1_2417_2432,
WG1_2447_2457),
.chan11g_turbo = BM1(T3_2437_2437)},
{.regDmnEnum = WOR02_WORLD,
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
.flags = ADHOC_PER_11D,
.chan11a = BM5(W1_5260_5320,
W1_5180_5240,
W1_5170_5230,
W1_5745_5825,
W1_5500_5700),
.chan11a_turbo = BM3(WT1_5210_5250,
WT1_5290_5290,
WT1_5760_5800),
.chan11b = BM7(W1_2412_2412,
W1_2437_2442,
W1_2462_2462,
W1_2472_2472,
W1_2417_2432,
W1_2447_2457,
W1_2467_2467),
.chan11g = BM7(WG1_2412_2412,
WG1_2437_2442,
WG1_2462_2462,
WG1_2472_2472,
WG1_2417_2432,
WG1_2447_2457,
WG1_2467_2467),
.chan11g_turbo = BM1(T3_2437_2437)},
{.regDmnEnum = EU1_WORLD,
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
.flags = ADHOC_PER_11D,
.chan11a = BM5(W1_5260_5320,
W1_5180_5240,
W1_5170_5230,
W1_5745_5825,
W1_5500_5700),
.chan11a_turbo = BM3(WT1_5210_5250,
WT1_5290_5290,
WT1_5760_5800),
.chan11b = BM7(W1_2412_2412,
W1_2437_2442,
W1_2462_2462,
W2_2472_2472,
W1_2417_2432,
W1_2447_2457,
W2_2467_2467),
.chan11g = BM7(WG1_2412_2412,
WG1_2437_2442,
WG1_2462_2462,
WG2_2472_2472,
WG1_2417_2432,
WG1_2447_2457,
WG2_2467_2467),
.chan11g_turbo = BM1(T3_2437_2437)},
{.regDmnEnum = WOR1_WORLD,
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
.flags = DISALLOW_ADHOC_11A,
.chan11a = BM5(W1_5260_5320,
W1_5180_5240,
W1_5170_5230,
W1_5745_5825,
W1_5500_5700),
.chan11b = BM8(W1_2412_2412,
W1_2437_2442,
W1_2462_2462,
W1_2472_2472,
W1_2417_2432,
W1_2447_2457,
W1_2467_2467,
W1_2484_2484),
.chan11g = BM7(WG1_2412_2412,
WG1_2437_2442,
WG1_2462_2462,
WG1_2472_2472,
WG1_2417_2432,
WG1_2447_2457,
WG1_2467_2467),
.chan11g_turbo = BM1(T3_2437_2437)
},
{.regDmnEnum = WOR2_WORLD,
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
.flags = DISALLOW_ADHOC_11A,
.chan11a = BM5(W1_5260_5320,
W1_5180_5240,
W1_5170_5230,
W1_5745_5825,
W1_5500_5700),
.chan11a_turbo = BM3(WT1_5210_5250,
WT1_5290_5290,
WT1_5760_5800),
.chan11b = BM8(W1_2412_2412,
W1_2437_2442,
W1_2462_2462,
W1_2472_2472,
W1_2417_2432,
W1_2447_2457,
W1_2467_2467,
W1_2484_2484),
.chan11g = BM7(WG1_2412_2412,
WG1_2437_2442,
WG1_2462_2462,
WG1_2472_2472,
WG1_2417_2432,
WG1_2447_2457,
WG1_2467_2467),
.chan11g_turbo = BM1(T3_2437_2437)},
{.regDmnEnum = WOR3_WORLD,
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
.flags = ADHOC_PER_11D,
.chan11a = BM4(W1_5260_5320,
W1_5180_5240,
W1_5170_5230,
W1_5745_5825),
.chan11a_turbo = BM3(WT1_5210_5250,
WT1_5290_5290,
WT1_5760_5800),
.chan11b = BM7(W1_2412_2412,
W1_2437_2442,
W1_2462_2462,
W1_2472_2472,
W1_2417_2432,
W1_2447_2457,
W1_2467_2467),
.chan11g = BM7(WG1_2412_2412,
WG1_2437_2442,
WG1_2462_2462,
WG1_2472_2472,
WG1_2417_2432,
WG1_2447_2457,
WG1_2467_2467),
.chan11g_turbo = BM1(T3_2437_2437)},
{.regDmnEnum = WOR4_WORLD,
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
.flags = DISALLOW_ADHOC_11A,
.chan11a = BM4(W2_5260_5320,
W2_5180_5240,
F2_5745_5805,
W2_5825_5825),
.chan11a_turbo = BM3(WT1_5210_5250,
WT1_5290_5290,
WT1_5760_5800),
.chan11b = BM5(W1_2412_2412,
W1_2437_2442,
W1_2462_2462,
W1_2417_2432,
W1_2447_2457),
.chan11g = BM5(WG1_2412_2412,
WG1_2437_2442,
WG1_2462_2462,
WG1_2417_2432,
WG1_2447_2457),
.chan11g_turbo = BM1(T3_2437_2437)},
{.regDmnEnum = WOR5_ETSIC,
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
.flags = DISALLOW_ADHOC_11A,
.chan11a = BM3(W1_5260_5320, W2_5180_5240, F6_5745_5825),
.chan11b = BM7(W1_2412_2412,
W1_2437_2442,
W1_2462_2462,
W2_2472_2472,
W1_2417_2432,
W1_2447_2457,
W2_2467_2467),
.chan11g = BM7(WG1_2412_2412,
WG1_2437_2442,
WG1_2462_2462,
WG2_2472_2472,
WG1_2417_2432,
WG1_2447_2457,
WG2_2467_2467),
.chan11g_turbo = BM1(T3_2437_2437)},
{.regDmnEnum = WOR9_WORLD,
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
.flags = DISALLOW_ADHOC_11A,
.chan11a = BM4(W1_5260_5320,
W1_5180_5240,
W1_5745_5825,
W1_5500_5700),
.chan11a_turbo = BM3(WT1_5210_5250,
WT1_5290_5290,
WT1_5760_5800),
.chan11b = BM5(W1_2412_2412,
W1_2437_2442,
W1_2462_2462,
W1_2417_2432,
W1_2447_2457),
.chan11g = BM5(WG1_2412_2412,
WG1_2437_2442,
WG1_2462_2462,
WG1_2417_2432,
WG1_2447_2457),
.chan11g_turbo = BM1(T3_2437_2437)},
{.regDmnEnum = WORA_WORLD,
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
.flags = DISALLOW_ADHOC_11A,
.chan11a = BM4(W1_5260_5320,
W1_5180_5240,
W1_5745_5825,
W1_5500_5700),
.chan11b = BM7(W1_2412_2412,
W1_2437_2442,
W1_2462_2462,
W1_2472_2472,
W1_2417_2432,
W1_2447_2457,
W1_2467_2467),
.chan11g = BM7(WG1_2412_2412,
WG1_2437_2442,
WG1_2462_2462,
WG1_2472_2472,
WG1_2417_2432,
WG1_2447_2457,
WG1_2467_2467),
.chan11g_turbo = BM1(T3_2437_2437)},
{.regDmnEnum = WORB_WORLD,
.conformanceTestLimit = NO_CTL,
.dfsMask = DFS_FCC3 | DFS_ETSI,
.pscan = PSCAN_WWR,
.flags = DISALLOW_ADHOC_11A,
.chan11a = BM4(W1_5260_5320,
W1_5180_5240,
W1_5745_5825,
W1_5500_5700),
.chan11b = BM7(W1_2412_2412,
W1_2437_2442,
W1_2462_2462,
W1_2472_2472,
W1_2417_2432,
W1_2447_2457,
W1_2467_2467),
.chan11g = BM7(WG1_2412_2412,
WG1_2437_2442,
WG1_2462_2462,
WG1_2472_2472,
WG1_2417_2432,
WG1_2447_2457,
WG1_2467_2467),
.chan11g_turbo = BM1(T3_2437_2437)},
{.regDmnEnum = NULL1,
.conformanceTestLimit = NO_CTL,
}
};
#endif
@@ -0,0 +1,419 @@
/*
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2005-2006 Atheros Communications, Inc.
* All rights reserved.
*
* 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.
*
* $FreeBSD$
*/
#ifndef __AH_REGDOMAIN_FREQBANDS_H__
#define __AH_REGDOMAIN_FREQBANDS_H__
#define AFTER(x) ((x)+1)
/*
* Frequency band collections are defined using bitmasks. Each bit
* in a mask is the index of an entry in one of the following tables.
* Bitmasks are BMLEN*64 bits so if a table grows beyond that the bit
* vectors must be enlarged or the tables split somehow (e.g. split
* 1/2 and 1/4 rate channels into a separate table).
*
* Beware of ordering; the indices are defined relative to the preceding
* entry so if things get off there will be confusion. A good way to
* check the indices is to collect them in a switch statement in a stub
* function so the compiler checks for duplicates.
*/
/*
* 5GHz 11A channel tags
*/
static REG_DMN_FREQ_BAND regDmn5GhzFreq[] = {
{ 4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2 },
#define F1_4915_4925 0
{ 4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2 },
#define F1_4935_4945 AFTER(F1_4915_4925)
{ 4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2 },
#define F1_4920_4980 AFTER(F1_4935_4945)
{ 4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC },
#define F1_4942_4987 AFTER(F1_4920_4980)
{ 4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC },
#define F1_4945_4985 AFTER(F1_4942_4987)
{ 4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC },
#define F1_4950_4980 AFTER(F1_4945_4985)
{ 5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2 },
#define F1_5035_5040 AFTER(F1_4950_4980)
{ 5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2 },
#define F1_5040_5080 AFTER(F1_5035_5040)
{ 5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2 },
#define F1_5055_5055 AFTER(F1_5040_5080)
{ 5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN },
#define F1_5120_5240 AFTER(F1_5055_5055)
{ 5120, 5240, 5, 6, 10, 10, NO_DFS, NO_PSCAN },
#define F2_5120_5240 AFTER(F1_5120_5240)
{ 5120, 5240, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
#define F3_5120_5240 AFTER(F2_5120_5240)
{ 5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2 },
#define F1_5170_5230 AFTER(F3_5120_5240)
{ 5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2 },
#define F2_5170_5230 AFTER(F1_5170_5230)
{ 5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI },
#define F1_5180_5240 AFTER(F2_5170_5230)
{ 5180, 5240, 17, 6, 20, 20, NO_DFS, PSCAN_FCC },
#define F2_5180_5240 AFTER(F1_5180_5240)
{ 5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI },
#define F3_5180_5240 AFTER(F2_5180_5240)
{ 5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI },
#define F4_5180_5240 AFTER(F3_5180_5240)
{ 5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI },
#define F5_5180_5240 AFTER(F4_5180_5240)
{ 5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC },
#define F6_5180_5240 AFTER(F5_5180_5240)
{ 5180, 5240, 17, 6, 20, 10, NO_DFS, PSCAN_FCC },
#define F7_5180_5240 AFTER(F6_5180_5240)
{ 5180, 5240, 17, 6, 20, 5, NO_DFS, PSCAN_FCC },
#define F8_5180_5240 AFTER(F7_5180_5240)
{ 5180, 5320, 20, 6, 20, 20, DFS_ETSI, PSCAN_ETSI },
#define F1_5180_5320 AFTER(F8_5180_5240)
{ 5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI },
#define F1_5240_5280 AFTER(F1_5180_5320)
{ 5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI },
#define F1_5260_5280 AFTER(F1_5240_5280)
{ 5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI },
#define F1_5260_5320 AFTER(F1_5260_5280)
{ 5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3 },
#define F2_5260_5320 AFTER(F1_5260_5320)
{ 5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F3_5260_5320 AFTER(F2_5260_5320)
{ 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F4_5260_5320 AFTER(F3_5260_5320)
{ 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F5_5260_5320 AFTER(F4_5260_5320)
{ 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN },
#define F6_5260_5320 AFTER(F5_5260_5320)
{ 5260, 5320, 23, 6, 20, 10, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F7_5260_5320 AFTER(F6_5260_5320)
{ 5260, 5320, 23, 6, 20, 5, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F8_5260_5320 AFTER(F7_5260_5320)
{ 5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN },
#define F1_5260_5700 AFTER(F8_5260_5320)
{ 5260, 5700, 5, 6, 10, 10, DFS_FCC3 | DFS_ETSI, NO_PSCAN },
#define F2_5260_5700 AFTER(F1_5260_5700)
{ 5260, 5700, 5, 6, 5, 5, DFS_FCC3 | DFS_ETSI, NO_PSCAN },
#define F3_5260_5700 AFTER(F2_5260_5700)
{ 5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F1_5280_5320 AFTER(F3_5260_5700)
{ 5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI },
#define F1_5500_5620 AFTER(F1_5280_5320)
{ 5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
#define F1_5500_5700 AFTER(F1_5500_5620)
{ 5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI },
#define F2_5500_5700 AFTER(F1_5500_5700)
{ 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI },
#define F3_5500_5700 AFTER(F2_5500_5700)
{ 5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_MKK3 | PSCAN_FCC },
#define F4_5500_5700 AFTER(F3_5500_5700)
{ 5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN },
#define F1_5745_5805 AFTER(F4_5500_5700)
{ 5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN },
#define F2_5745_5805 AFTER(F1_5745_5805)
{ 5745, 5805, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI },
#define F3_5745_5805 AFTER(F2_5745_5805)
{ 5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN },
#define F1_5745_5825 AFTER(F3_5745_5805)
{ 5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN },
#define F2_5745_5825 AFTER(F1_5745_5825)
{ 5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN },
#define F3_5745_5825 AFTER(F2_5745_5825)
{ 5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN },
#define F4_5745_5825 AFTER(F3_5745_5825)
{ 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN },
#define F5_5745_5825 AFTER(F4_5745_5825)
{ 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN },
#define F6_5745_5825 AFTER(F5_5745_5825)
{ 5745, 5825, 5, 6, 10, 10, NO_DFS, NO_PSCAN },
#define F7_5745_5825 AFTER(F6_5745_5825)
{ 5745, 5825, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
#define F8_5745_5825 AFTER(F7_5745_5825)
{ 5745, 5825, 30, 6, 20, 10, NO_DFS, NO_PSCAN },
#define F9_5745_5825 AFTER(F8_5745_5825)
{ 5745, 5825, 30, 6, 20, 5, NO_DFS, NO_PSCAN },
#define F10_5745_5825 AFTER(F9_5745_5825)
/*
* Below are the world roaming channels
* All WWR domains have no power limit, instead use the card's CTL
* or max power settings.
*/
{ 4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR },
#define W1_4920_4980 AFTER(F10_5745_5825)
{ 5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR },
#define W1_5040_5080 AFTER(W1_4920_4980)
{ 5170, 5230, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define W1_5170_5230 AFTER(W1_5040_5080)
{ 5180, 5240, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define W1_5180_5240 AFTER(W1_5170_5230)
{ 5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define W1_5260_5320 AFTER(W1_5180_5240)
{ 5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR },
#define W1_5745_5825 AFTER(W1_5260_5320)
{ 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define W1_5500_5700 AFTER(W1_5745_5825)
{ 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN },
#define W2_5260_5320 AFTER(W1_5500_5700)
{ 5180, 5240, 30, 0, 20, 20, NO_DFS, NO_PSCAN },
#define W2_5180_5240 AFTER(W2_5260_5320)
{ 5825, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR },
#define W2_5825_5825 AFTER(W2_5180_5240)
};
/*
* 5GHz Turbo (dynamic & static) tags
*/
static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[] = {
{ 5130, 5210, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5130_5210 0
{ 5250, 5330, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN },
#define T1_5250_5330 AFTER(T1_5130_5210)
{ 5370, 5490, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5370_5490 AFTER(T1_5250_5330)
{ 5530, 5650, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN },
#define T1_5530_5650 AFTER(T1_5370_5490)
{ 5150, 5190, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5150_5190 AFTER(T1_5530_5650)
{ 5230, 5310, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN },
#define T1_5230_5310 AFTER(T1_5150_5190)
{ 5350, 5470, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5350_5470 AFTER(T1_5230_5310)
{ 5510, 5670, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN },
#define T1_5510_5670 AFTER(T1_5350_5470)
{ 5200, 5240, 17, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5200_5240 AFTER(T1_5510_5670)
{ 5200, 5240, 23, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T2_5200_5240 AFTER(T1_5200_5240)
{ 5210, 5210, 17, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5210_5210 AFTER(T2_5200_5240)
{ 5210, 5210, 23, 0, 40, 40, NO_DFS, NO_PSCAN },
#define T2_5210_5210 AFTER(T1_5210_5210)
{ 5280, 5280, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T1_5280_5280 AFTER(T2_5210_5210)
{ 5280, 5280, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T2_5280_5280 AFTER(T1_5280_5280)
{ 5250, 5250, 17, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T1_5250_5250 AFTER(T2_5280_5280)
{ 5290, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T1_5290_5290 AFTER(T1_5250_5250)
{ 5250, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T1_5250_5290 AFTER(T1_5290_5290)
{ 5250, 5290, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T2_5250_5290 AFTER(T1_5250_5290)
{ 5540, 5660, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T },
#define T1_5540_5660 AFTER(T2_5250_5290)
{ 5760, 5800, 20, 0, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5760_5800 AFTER(T1_5540_5660)
{ 5760, 5800, 30, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T2_5760_5800 AFTER(T1_5760_5800)
{ 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_5765_5805 AFTER(T2_5760_5800)
/*
* Below are the WWR frequencies
*/
{ 5210, 5250, 15, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define WT1_5210_5250 AFTER(T1_5765_5805)
{ 5290, 5290, 18, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define WT1_5290_5290 AFTER(WT1_5210_5250)
{ 5540, 5660, 20, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
#define WT1_5540_5660 AFTER(WT1_5290_5290)
{ 5760, 5800, 20, 0, 40, 40, NO_DFS, PSCAN_WWR },
#define WT1_5760_5800 AFTER(WT1_5540_5660)
};
/*
* 2GHz 11b channel tags
*/
static REG_DMN_FREQ_BAND regDmn2GhzFreq[] = {
{ 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2312_2372 0
{ 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define F2_2312_2372 AFTER(F1_2312_2372)
{ 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2412_2472 AFTER(F2_2312_2372)
{ 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA },
#define F2_2412_2472 AFTER(F1_2412_2472)
{ 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN },
#define F3_2412_2472 AFTER(F2_2412_2472)
{ 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2412_2462 AFTER(F3_2412_2472)
{ 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA },
#define F2_2412_2462 AFTER(F1_2412_2462)
{ 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2432_2442 AFTER(F2_2412_2462)
{ 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2457_2472 AFTER(F1_2432_2442)
{ 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA },
#define F1_2467_2472 AFTER(F1_2457_2472)
{ 2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2484_2484 AFTER(F1_2467_2472)
{ 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2 },
#define F2_2484_2484 AFTER(F1_2484_2484)
{ 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define F1_2512_2732 AFTER(F2_2484_2484)
/*
* WWR have powers opened up to 20dBm.
* Limits should often come from CTL/Max powers
*/
{ 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define W1_2312_2372 AFTER(F1_2512_2732)
{ 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define W1_2412_2412 AFTER(W1_2312_2372)
{ 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define W1_2417_2432 AFTER(W1_2412_2412)
{ 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define W1_2437_2442 AFTER(W1_2417_2432)
{ 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define W1_2447_2457 AFTER(W1_2437_2442)
{ 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define W1_2462_2462 AFTER(W1_2447_2457)
{ 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
#define W1_2467_2467 AFTER(W1_2462_2462)
{ 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
#define W2_2467_2467 AFTER(W1_2467_2467)
{ 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
#define W1_2472_2472 AFTER(W2_2467_2467)
{ 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
#define W2_2472_2472 AFTER(W1_2472_2472)
{ 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
#define W1_2484_2484 AFTER(W2_2472_2472)
{ 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
#define W2_2484_2484 AFTER(W1_2484_2484)
};
/*
* 2GHz 11g channel tags
*/
static REG_DMN_FREQ_BAND regDmn2Ghz11gFreq[] = {
{ 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define G1_2312_2372 0
{ 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define G2_2312_2372 AFTER(G1_2312_2372)
{ 2312, 2372, 5, 6, 10, 5, NO_DFS, NO_PSCAN },
#define G3_2312_2372 AFTER(G2_2312_2372)
{ 2312, 2372, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
#define G4_2312_2372 AFTER(G3_2312_2372)
{ 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define G1_2412_2472 AFTER(G4_2312_2372)
{ 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G },
#define G2_2412_2472 AFTER(G1_2412_2472)
{ 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN },
#define G3_2412_2472 AFTER(G2_2412_2472)
{ 2412, 2472, 5, 6, 10, 5, NO_DFS, NO_PSCAN },
#define G4_2412_2472 AFTER(G3_2412_2472)
{ 2412, 2472, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
#define G5_2412_2472 AFTER(G4_2412_2472)
{ 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN },
#define G1_2412_2462 AFTER(G5_2412_2472)
{ 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G },
#define G2_2412_2462 AFTER(G1_2412_2462)
{ 2412, 2462, 27, 6, 10, 5, NO_DFS, NO_PSCAN },
#define G3_2412_2462 AFTER(G2_2412_2462)
{ 2412, 2462, 27, 6, 5, 5, NO_DFS, NO_PSCAN },
#define G4_2412_2462 AFTER(G3_2412_2462)
{ 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define G1_2432_2442 AFTER(G4_2412_2462)
{ 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define G1_2457_2472 AFTER(G1_2432_2442)
{ 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
#define G1_2512_2732 AFTER(G1_2457_2472)
{ 2512, 2732, 5, 6, 10, 5, NO_DFS, NO_PSCAN },
#define G2_2512_2732 AFTER(G1_2512_2732)
{ 2512, 2732, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
#define G3_2512_2732 AFTER(G2_2512_2732)
{ 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA },
#define G1_2467_2472 AFTER(G3_2512_2732)
/*
* WWR open up the power to 20dBm
*/
{ 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define WG1_2312_2372 AFTER(G1_2467_2472)
{ 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define WG1_2412_2412 AFTER(WG1_2312_2372)
{ 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define WG1_2417_2432 AFTER(WG1_2412_2412)
{ 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define WG1_2437_2442 AFTER(WG1_2417_2432)
{ 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define WG1_2447_2457 AFTER(WG1_2437_2442)
{ 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
#define WG1_2462_2462 AFTER(WG1_2447_2457)
{ 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
#define WG1_2467_2467 AFTER(WG1_2462_2462)
{ 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
#define WG2_2467_2467 AFTER(WG1_2467_2467)
{ 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
#define WG1_2472_2472 AFTER(WG2_2467_2467)
{ 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
#define WG2_2472_2472 AFTER(WG1_2472_2472)
};
/*
* 2GHz Dynamic turbo tags
*/
static REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[] = {
{ 2312, 2372, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_2312_2372 0
{ 2437, 2437, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_2437_2437 AFTER(T1_2312_2372)
{ 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T2_2437_2437 AFTER(T1_2437_2437)
{ 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR },
#define T3_2437_2437 AFTER(T2_2437_2437)
{ 2512, 2732, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
#define T1_2512_2732 AFTER(T3_2437_2437)
};
#endif
@@ -0,0 +1,249 @@
/*
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2005-2011 Atheros Communications, Inc.
* All rights reserved.
*
* 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.
*
* $FreeBSD$
*/
#ifndef __AH_REGDOMAIN_REGENUM_H__
#define __AH_REGDOMAIN_REGENUM_H__
/*
* Enumerated Regulatory Domain Information 8 bit values indicate that
* the regdomain is really a pair of unitary regdomains. 12 bit values
* are the real unitary regdomains and are the only ones which have the
* frequency bitmasks and flags set.
*/
enum {
/*
* The following regulatory domain definitions are
* found in the EEPROM. Each regulatory domain
* can operate in either a 5GHz or 2.4GHz wireless mode or
* both 5GHz and 2.4GHz wireless modes.
* In general, the value holds no special
* meaning and is used to decode into either specific
* 2.4GHz or 5GHz wireless mode for that particular
* regulatory domain.
*/
NO_ENUMRD = 0x00,
NULL1_WORLD = 0x03, /* For 11b-only countries (no 11a allowed) */
NULL1_ETSIB = 0x07, /* Israel */
NULL1_ETSIC = 0x08,
FCC1_FCCA = 0x10, /* USA */
FCC1_WORLD = 0x11, /* Hong Kong */
FCC4_FCCA = 0x12, /* USA - Public Safety */
FCC5_FCCB = 0x13, /* USA w/ 1/2 and 1/4 width channels */
FCC6_FCCA = 0x14, /* Canada for AP only */
FCC2_FCCA = 0x20, /* Canada */
FCC2_WORLD = 0x21, /* Australia & HK */
FCC2_ETSIC = 0x22,
FRANCE_RES = 0x31, /* Legacy France for OEM */
FCC3_FCCA = 0x3A, /* USA & Canada w/5470 band, 11h, DFS enabled */
FCC3_WORLD = 0x3B, /* USA & Canada w/5470 band, 11h, DFS enabled */
ETSI1_WORLD = 0x37,
ETSI3_ETSIA = 0x32, /* France (optional) */
ETSI2_WORLD = 0x35, /* Hungary & others */
ETSI3_WORLD = 0x36, /* France & others */
ETSI4_WORLD = 0x30,
ETSI4_ETSIC = 0x38,
ETSI5_WORLD = 0x39,
ETSI6_WORLD = 0x34, /* Bulgaria */
ETSI8_WORLD = 0x3D, /* Russia */
ETSI9_WORLD = 0x3E, /* Ukraine */
ETSI_RESERVED = 0x33, /* Reserved (Do not used) */
MKK1_MKKA = 0x40, /* Japan (JP1) */
MKK1_MKKB = 0x41, /* Japan (JP0) */
APL4_WORLD = 0x42, /* Singapore */
MKK2_MKKA = 0x43, /* Japan with 4.9G channels */
APL_RESERVED = 0x44, /* Reserved (Do not used) */
APL2_WORLD = 0x45, /* Korea */
APL2_APLC = 0x46,
APL3_WORLD = 0x47,
MKK1_FCCA = 0x48, /* Japan (JP1-1) */
APL2_APLD = 0x49, /* Korea with 2.3G channels */
MKK1_MKKA1 = 0x4A, /* Japan (JE1) */
MKK1_MKKA2 = 0x4B, /* Japan (JE2) */
MKK1_MKKC = 0x4C, /* Japan (MKK1_MKKA,except Ch14) */
APL2_FCCA = 0x4D, /* Mobile customer */
APL3_FCCA = 0x50,
APL1_WORLD = 0x52, /* Latin America */
APL1_FCCA = 0x53,
APL1_APLA = 0x54,
APL1_ETSIC = 0x55,
APL2_ETSIC = 0x56, /* Venezuela */
APL5_WORLD = 0x58, /* Chile */
APL6_WORLD = 0x5B, /* Singapore */
APL7_FCCA = 0x5C, /* Taiwan 5.47 Band */
APL8_WORLD = 0x5D, /* Malaysia 5GHz */
APL9_WORLD = 0x5E, /* Korea 5GHz; before 11/2007; now APs only */
APL10_WORLD = 0x5F, /* Korea 5GHz; After 11/2007; STAs only */
/*
* World mode SKUs
*/
WOR0_WORLD = 0x60, /* World0 (WO0 SKU) */
WOR1_WORLD = 0x61, /* World1 (WO1 SKU) */
WOR2_WORLD = 0x62, /* World2 (WO2 SKU) */
WOR3_WORLD = 0x63, /* World3 (WO3 SKU) */
WOR4_WORLD = 0x64, /* World4 (WO4 SKU) */
WOR5_ETSIC = 0x65, /* World5 (WO5 SKU) */
WOR01_WORLD = 0x66, /* World0-1 (WW0-1 SKU) */
WOR02_WORLD = 0x67, /* World0-2 (WW0-2 SKU) */
EU1_WORLD = 0x68, /* Same as World0-2 (WW0-2 SKU), except active scan ch1-13. No ch14 */
WOR9_WORLD = 0x69, /* World9 (WO9 SKU) */
WORA_WORLD = 0x6A, /* WorldA (WOA SKU) */
WORB_WORLD = 0x6B, /* WorldB (WOB SKU) */
WORC_WORLD = 0x6C, /* WorldC (WOC SKU) */
MKK3_MKKB = 0x80, /* Japan UNI-1 even + MKKB */
MKK3_MKKA2 = 0x81, /* Japan UNI-1 even + MKKA2 */
MKK3_MKKC = 0x82, /* Japan UNI-1 even + MKKC */
MKK4_MKKB = 0x83, /* Japan UNI-1 even + UNI-2 + MKKB */
MKK4_MKKA2 = 0x84, /* Japan UNI-1 even + UNI-2 + MKKA2 */
MKK4_MKKC = 0x85, /* Japan UNI-1 even + UNI-2 + MKKC */
MKK5_MKKB = 0x86, /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */
MKK5_MKKA2 = 0x87, /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */
MKK5_MKKC = 0x88, /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */
MKK6_MKKB = 0x89, /* Japan UNI-1 even + UNI-1 odd MKKB */
MKK6_MKKA2 = 0x8A, /* Japan UNI-1 even + UNI-1 odd + MKKA2 */
MKK6_MKKC = 0x8B, /* Japan UNI-1 even + UNI-1 odd + MKKC */
MKK7_MKKB = 0x8C, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */
MKK7_MKKA2 = 0x8D, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */
MKK7_MKKC = 0x8E, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */
MKK8_MKKB = 0x8F, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */
MKK8_MKKA2 = 0x90, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */
MKK8_MKKC = 0x91, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */
MKK14_MKKA1 = 0x92, /* Japan UNI-1 even + UNI-1 odd + 4.9GHz + MKKA1 */
MKK15_MKKA1 = 0x93, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + 4.9GHz + MKKA1 */
MKK10_FCCA = 0xD0, /* Japan UNI-1 even + UNI-2 + 4.9GHz + FCCA */
MKK10_MKKA1 = 0xD1, /* Japan UNI-1 even + UNI-2 + 4.9GHz + MKKA1 */
MKK10_MKKC = 0xD2, /* Japan UNI-1 even + UNI-2 + 4.9GHz + MKKC */
MKK10_MKKA2 = 0xD3, /* Japan UNI-1 even + UNI-2 + 4.9GHz + MKKA2 */
MKK11_MKKA = 0xD4, /* Japan UNI-1 even + UNI-2 + mid-band + 4.9GHz + MKKA */
MKK11_FCCA = 0xD5, /* Japan UNI-1 even + UNI-2 + mid-band + 4.9GHz + FCCA */
MKK11_MKKA1 = 0xD6, /* Japan UNI-1 even + UNI-2 + mid-band + 4.9GHz + MKKA1 */
MKK11_MKKC = 0xD7, /* Japan UNI-1 even + UNI-2 + mid-band + 4.9GHz + MKKC */
MKK11_MKKA2 = 0xD8, /* Japan UNI-1 even + UNI-2 + mid-band + 4.9GHz + MKKA2 */
MKK12_MKKA = 0xD9, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + 4.9GHz + MKKA */
MKK12_FCCA = 0xDA, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + 4.9GHz + FCCA */
MKK12_MKKA1 = 0xDB, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + 4.9GHz + MKKA1 */
MKK12_MKKC = 0xDC, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + 4.9GHz + MKKC */
MKK12_MKKA2 = 0xDD, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + 4.9GHz + MKKA2 */
MKK13_MKKB = 0xDE, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB + All passive + no adhoc */
/*
* Following definitions are used only by s/w to map old
* Japan SKUs.
*/
MKK3_MKKA = 0xF0, /* Japan UNI-1 even + MKKA */
MKK3_MKKA1 = 0xF1, /* Japan UNI-1 even + MKKA1 */
MKK3_FCCA = 0xF2, /* Japan UNI-1 even + FCCA */
MKK4_MKKA = 0xF3, /* Japan UNI-1 even + UNI-2 + MKKA */
MKK4_MKKA1 = 0xF4, /* Japan UNI-1 even + UNI-2 + MKKA1 */
MKK4_FCCA = 0xF5, /* Japan UNI-1 even + UNI-2 + FCCA */
MKK9_MKKA = 0xF6, /* Japan UNI-1 even + 4.9GHz */
MKK10_MKKA = 0xF7, /* Japan UNI-1 even + UNI-2 + 4.9GHz */
MKK6_MKKA1 = 0xF8, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA1 */
MKK6_FCCA = 0xF9, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + FCCA */
MKK7_MKKA1 = 0xFA, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA1 */
MKK7_FCCA = 0xFB, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + FCCA */
MKK9_FCCA = 0xFC, /* Japan UNI-1 even + 4.9GHz + FCCA */
MKK9_MKKA1 = 0xFD, /* Japan UNI-1 even + 4.9GHz + MKKA1 */
MKK9_MKKC = 0xFE, /* Japan UNI-1 even + 4.9GHz + MKKC */
MKK9_MKKA2 = 0xFF, /* Japan UNI-1 even + 4.9GHz + MKKA2 */
/*
* Regulator domains ending in a number (e.g. APL1,
* MK1, ETSI4, etc) apply to 5GHz channel and power
* information. Regulator domains ending in a letter
* (e.g. APLA, FCCA, etc) apply to 2.4GHz channel and
* power information.
*/
APL1 = 0x0150, /* LAT & Asia */
APL2 = 0x0250, /* LAT & Asia */
APL3 = 0x0350, /* Taiwan */
APL4 = 0x0450, /* Jordan */
APL5 = 0x0550, /* Chile */
APL6 = 0x0650, /* Singapore */
APL7 = 0x0750, /* Taiwan, disable ch52 */
APL8 = 0x0850, /* Malaysia */
APL9 = 0x0950, /* Korea. Before 11/2007. Now used only by APs */
APL10 = 0x1050, /* Korea. After 11/2007. For STAs only */
ETSI1 = 0x0130, /* Europe & others */
ETSI2 = 0x0230, /* Europe & others */
ETSI3 = 0x0330, /* Europe & others */
ETSI4 = 0x0430, /* Europe & others */
ETSI5 = 0x0530, /* Europe & others */
ETSI6 = 0x0630, /* Europe & others */
ETSI8 = 0x0830, /* Russia */
ETSI9 = 0x0930, /* Ukraine */
ETSIA = 0x0A30, /* France */
ETSIB = 0x0B30, /* Israel */
ETSIC = 0x0C30, /* Latin America */
FCC1 = 0x0110, /* US & others */
FCC2 = 0x0120, /* Canada, Australia & New Zealand */
FCC3 = 0x0160, /* US w/new middle band & DFS */
FCC4 = 0x0165, /* US Public Safety */
FCC5 = 0x0166, /* US w/ 1/2 and 1/4 width channels */
FCC6 = 0x0610, /* Canada and Australia */
FCCA = 0x0A10,
FCCB = 0x0A11, /* US w/ 1/2 and 1/4 width channels */
APLD = 0x0D50, /* South Korea */
MKK1 = 0x0140, /* Japan (UNI-1 odd)*/
MKK2 = 0x0240, /* Japan (4.9 GHz + UNI-1 odd) */
MKK3 = 0x0340, /* Japan (UNI-1 even) */
MKK4 = 0x0440, /* Japan (UNI-1 even + UNI-2) */
MKK5 = 0x0540, /* Japan (UNI-1 even + UNI-2 + mid-band) */
MKK6 = 0x0640, /* Japan (UNI-1 odd + UNI-1 even) */
MKK7 = 0x0740, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */
MKK8 = 0x0840, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */
MKK9 = 0x0940, /* Japan (UNI-1 even + 4.9 GHZ) */
MKK10 = 0x0B40, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */
MKK11 = 0x1140, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */
MKK12 = 0x1240, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */
MKK13 = 0x0C40, /* Same as MKK8 but all passive and no adhoc 11a */
MKK14 = 0x1440, /* Japan UNI-1 even + UNI-1 odd + 4.9GHz */
MKK15 = 0x1540, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + 4.9GHz */
MKKA = 0x0A40, /* Japan */
MKKC = 0x0A50,
NULL1 = 0x0198,
WORLD = 0x0199,
DEBUG_REG_DMN = 0x01ff,
};
#endif
@@ -0,0 +1,134 @@
/*
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2005-2006 Atheros Communications, Inc.
* All rights reserved.
*
* 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.
*
* $FreeBSD$
*/
#ifndef __AH_REGDOMAIN_REGMAP_H__
#define __AH_REGDOMAIN_REGMAP_H__
/*
* THE following table is the mapping of regdomain pairs specified by
* an 8 bit regdomain value to the individual unitary reg domains
*/
/* regdomain 5ghz 2ghz 5ghz 2ghz pscan mask single */
/* enum regdomain regdomain flags flags country? */
static REG_DMN_PAIR_MAPPING regDomainPairs[] = {
{NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{FCC4_FCCA, FCC4, FCCA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{FCC5_FCCB, FCC5, FCCB, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{ETSI1_WORLD, ETSI1, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{ETSI2_WORLD, ETSI2, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{ETSI3_WORLD, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{ETSI4_WORLD, ETSI4, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{ETSI5_WORLD, ETSI5, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{ETSI6_WORLD, ETSI6, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{ETSI3_ETSIA, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{MKK1_MKKA, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN },
{MKK1_MKKB, MKK1, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN1 },
{MKK1_FCCA, MKK1, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN2 },
{MKK1_MKKA1, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4 },
{MKK1_MKKA2, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5 },
{MKK1_MKKC, MKK1, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN6 },
/* MKK2 */
{MKK2_MKKA, MKK2, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN3 },
/* MKK3 */
{MKK3_MKKA, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC , PSCAN_MKKA, CTRY_DEFAULT },
{MKK3_MKKB, MKK3, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN7 },
{MKK3_MKKA1, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_DEFAULT },
{MKK3_MKKA2,MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8 },
{MKK3_MKKC, MKK3, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_JAPAN9 },
{MKK3_FCCA, MKK3, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_DEFAULT },
/* MKK4 */
{MKK4_MKKB, MKK4, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN10 },
{MKK4_MKKA1, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_DEFAULT },
{MKK4_MKKA2, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 |PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11 },
{MKK4_MKKC, MKK4, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN12 },
{MKK4_FCCA, MKK4, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_DEFAULT },
/* MKK5 */
{MKK5_MKKB, MKK5, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN13 },
{MKK5_MKKA2,MKK5, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14 },
{MKK5_MKKC, MKK5, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN15 },
/* MKK6 */
{MKK6_MKKB, MKK6, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN16 },
{MKK6_MKKA2, MKK6, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17 },
{MKK6_MKKC, MKK6, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN18 },
/* MKK7 */
{MKK7_MKKB, MKK7, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN19 },
{MKK7_MKKA2, MKK7, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN20 },
{MKK7_MKKC, MKK7, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21 },
/* MKK8 */
{MKK8_MKKB, MKK8, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN22 },
{MKK8_MKKA2,MKK8, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN23 },
{MKK8_MKKC, MKK8, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 , CTRY_JAPAN24 },
{MKK9_MKKA, MKK9, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_DEFAULT },
{MKK10_MKKA, MKK10, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_DEFAULT },
/* These are super domains */
{WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{WOR1_WORLD, WOR1_WORLD, WOR1_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{WOR4_WORLD, WOR4_WORLD, WOR4_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{WOR9_WORLD, WOR9_WORLD, WOR9_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{WORA_WORLD, WORA_WORLD, WORA_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
{WORB_WORLD, WORB_WORLD, WORB_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
};
#endif
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ah_soc.h,v 1.4 2008/11/10 04:08:00 sam Exp $ * $FreeBSD$
*/ */
#ifndef _ATH_AH_SOC_H_ #ifndef _ATH_AH_SOC_H_
#define _ATH_AH_SOC_H_ #define _ATH_AH_SOC_H_
@@ -177,6 +177,8 @@ extern HAL_STATUS ar5210ProcTxDesc(struct ath_hal *,
struct ath_desc *, struct ath_tx_status *); struct ath_desc *, struct ath_tx_status *);
extern void ar5210GetTxIntrQueue(struct ath_hal *ah, uint32_t *); extern void ar5210GetTxIntrQueue(struct ath_hal *ah, uint32_t *);
extern void ar5210IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *); extern void ar5210IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *);
extern HAL_BOOL ar5210GetTxCompletionRates(struct ath_hal *ah,
const struct ath_desc *, int *rates, int *tries);
extern uint32_t ar5210GetRxDP(struct ath_hal *); extern uint32_t ar5210GetRxDP(struct ath_hal *);
extern void ar5210SetRxDP(struct ath_hal *, uint32_t rxdp); extern void ar5210SetRxDP(struct ath_hal *, uint32_t rxdp);
@@ -266,6 +268,7 @@ extern void ar5210BeaconInit(struct ath_hal *, uint32_t, uint32_t);
extern void ar5210SetStaBeaconTimers(struct ath_hal *, extern void ar5210SetStaBeaconTimers(struct ath_hal *,
const HAL_BEACON_STATE *); const HAL_BEACON_STATE *);
extern void ar5210ResetStaBeaconTimers(struct ath_hal *); extern void ar5210ResetStaBeaconTimers(struct ath_hal *);
extern uint64_t ar5210GetNextTBTT(struct ath_hal *);
extern HAL_BOOL ar5210IsInterruptPending(struct ath_hal *); extern HAL_BOOL ar5210IsInterruptPending(struct ath_hal *);
extern HAL_BOOL ar5210GetPendingInterrupts(struct ath_hal *, HAL_INT *); extern HAL_BOOL ar5210GetPendingInterrupts(struct ath_hal *, HAL_INT *);
@@ -275,7 +278,8 @@ extern HAL_INT ar5210SetInterrupts(struct ath_hal *, HAL_INT ints);
extern const HAL_RATE_TABLE *ar5210GetRateTable(struct ath_hal *, u_int mode); extern const HAL_RATE_TABLE *ar5210GetRateTable(struct ath_hal *, u_int mode);
extern HAL_BOOL ar5210AniControl(struct ath_hal *, HAL_ANI_CMD, int ); extern HAL_BOOL ar5210AniControl(struct ath_hal *, HAL_ANI_CMD, int );
extern void ar5210AniPoll(struct ath_hal *, const HAL_NODE_STATS *, extern void ar5210AniPoll(struct ath_hal *, const struct ieee80211_channel *);
extern void ar5210RxMonitor(struct ath_hal *, const HAL_NODE_STATS *,
const struct ieee80211_channel *); const struct ieee80211_channel *);
extern void ar5210MibEvent(struct ath_hal *, const HAL_NODE_STATS *); extern void ar5210MibEvent(struct ath_hal *, const HAL_NODE_STATS *);
#endif /* _ATH_AR5210_H_ */ #endif /* _ATH_AR5210_H_ */
@@ -73,6 +73,7 @@ static const struct ath_hal_private ar5210hal = {{
.ah_procTxDesc = ar5210ProcTxDesc, .ah_procTxDesc = ar5210ProcTxDesc,
.ah_getTxIntrQueue = ar5210GetTxIntrQueue, .ah_getTxIntrQueue = ar5210GetTxIntrQueue,
.ah_reqTxIntrDesc = ar5210IntrReqTxDesc, .ah_reqTxIntrDesc = ar5210IntrReqTxDesc,
.ah_getTxCompletionRates = ar5210GetTxCompletionRates,
/* RX Functions */ /* RX Functions */
.ah_getRxDP = ar5210GetRxDP, .ah_getRxDP = ar5210GetRxDP,
@@ -88,7 +89,8 @@ static const struct ath_hal_private ar5210hal = {{
.ah_setRxFilter = ar5210SetRxFilter, .ah_setRxFilter = ar5210SetRxFilter,
.ah_setupRxDesc = ar5210SetupRxDesc, .ah_setupRxDesc = ar5210SetupRxDesc,
.ah_procRxDesc = ar5210ProcRxDesc, .ah_procRxDesc = ar5210ProcRxDesc,
.ah_rxMonitor = ar5210AniPoll, .ah_rxMonitor = ar5210RxMonitor,
.ah_aniPoll = ar5210AniPoll,
.ah_procMibEvent = ar5210MibEvent, .ah_procMibEvent = ar5210MibEvent,
/* Misc Functions */ /* Misc Functions */
@@ -146,6 +148,7 @@ static const struct ath_hal_private ar5210hal = {{
.ah_beaconInit = ar5210BeaconInit, .ah_beaconInit = ar5210BeaconInit,
.ah_setStationBeaconTimers = ar5210SetStaBeaconTimers, .ah_setStationBeaconTimers = ar5210SetStaBeaconTimers,
.ah_resetStationBeaconTimers = ar5210ResetStaBeaconTimers, .ah_resetStationBeaconTimers = ar5210ResetStaBeaconTimers,
.ah_getNextTBTT = ar5210GetNextTBTT,
/* Interrupt Functions */ /* Interrupt Functions */
.ah_isInterruptPending = ar5210IsInterruptPending, .ah_isInterruptPending = ar5210IsInterruptPending,
@@ -169,7 +172,7 @@ static HAL_BOOL ar5210FillCapabilityInfo(struct ath_hal *ah);
*/ */
static struct ath_hal * static struct ath_hal *
ar5210Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, ar5210Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh,
HAL_STATUS *status) uint16_t *eepromdata, HAL_STATUS *status)
{ {
#define N(a) (sizeof(a)/sizeof(a[0])) #define N(a) (sizeof(a)/sizeof(a[0]))
struct ath_hal_5210 *ahp; struct ath_hal_5210 *ahp;
@@ -179,14 +182,14 @@ ar5210Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh,
HAL_STATUS ecode; HAL_STATUS ecode;
int i; int i;
HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH,
"%s: devid 0x%x sc %p st %p sh %p\n", __func__, devid, "%s: devid 0x%x sc %p st %p sh %p\n", __func__, devid,
sc, (void*) st, (void*) sh); sc, (void*) st, (void*) sh);
/* NB: memory is returned zero'd */ /* NB: memory is returned zero'd */
ahp = ath_hal_malloc(sizeof (struct ath_hal_5210)); ahp = ath_hal_malloc(sizeof (struct ath_hal_5210));
if (ahp == AH_NULL) { if (ahp == AH_NULL) {
HALDEBUG(AH_NULL, HAL_DEBUG_ANY, HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY,
"%s: no memory for state block\n", __func__); "%s: no memory for state block\n", __func__);
ecode = HAL_ENOMEM; ecode = HAL_ENOMEM;
goto bad; goto bad;
@@ -375,6 +378,9 @@ ar5210FillCapabilityInfo(struct ath_hal *ah)
| HAL_INT_FATAL | HAL_INT_FATAL
; ;
pCap->hal4kbSplitTransSupport = AH_TRUE;
pCap->halHasRxSelfLinkedTail = AH_TRUE;
ahpriv->ah_rxornIsFatal = AH_TRUE; ahpriv->ah_rxornIsFatal = AH_TRUE;
return AH_TRUE; return AH_TRUE;
} }
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5210_beacon.c,v 1.4 2008/11/10 04:08:02 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -26,6 +26,17 @@
#include "ar5210/ar5210reg.h" #include "ar5210/ar5210reg.h"
#include "ar5210/ar5210desc.h" #include "ar5210/ar5210desc.h"
/*
* Return the hardware NextTBTT in TSF
*/
uint64_t
ar5210GetNextTBTT(struct ath_hal *ah)
{
#define TU_TO_TSF(_tu) (((uint64_t)(_tu)) << 10)
return TU_TO_TSF(OS_REG_READ(ah, AR_TIMER0));
#undef TU_TO_TSF
}
/* /*
* Initialize all of the hardware registers used to send beacons. * Initialize all of the hardware registers used to send beacons.
*/ */
@@ -56,9 +67,9 @@ ar5210BeaconInit(struct ath_hal *ah,
if (AH_PRIVATE(ah)->ah_opmode != HAL_M_STA) { if (AH_PRIVATE(ah)->ah_opmode != HAL_M_STA) {
bt.bt_nextdba = (next_beacon - bt.bt_nextdba = (next_beacon -
ath_hal_dma_beacon_response_time) << 3; /* 1/8 TU */ ah->ah_config.ah_dma_beacon_response_time) << 3; /* 1/8 TU */
bt.bt_nextswba = (next_beacon - bt.bt_nextswba = (next_beacon -
ath_hal_sw_beacon_response_time) << 3; /* 1/8 TU */ ah->ah_config.ah_sw_beacon_response_time) << 3; /* 1/8 TU */
/* /*
* The SWBA interrupt is not used for beacons in ad hoc mode * The SWBA interrupt is not used for beacons in ad hoc mode
* as we don't yet support ATIMs. So since the beacon never * as we don't yet support ATIMs. So since the beacon never
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5210_keycache.c,v 1.4 2008/11/10 04:08:02 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -561,11 +561,16 @@ ar5210AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
} }
void void
ar5210AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats, ar5210RxMonitor(struct ath_hal *ah, const HAL_NODE_STATS *stats,
const struct ieee80211_channel *chan) const struct ieee80211_channel *chan)
{ {
} }
void
ar5210AniPoll(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
}
void void
ar5210MibEvent(struct ath_hal *ah, const HAL_NODE_STATS *stats) ar5210MibEvent(struct ath_hal *ah, const HAL_NODE_STATS *stats)
{ {
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5210_power.c,v 1.4 2008/11/10 04:08:02 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5210_recv.c,v 1.4 2008/11/10 04:08:02 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -526,9 +526,10 @@ ar5210PerCalibrationN(struct ath_hal *ah,
/* AGC calibration (this was added to make the NF threshold check work) */ /* AGC calibration (this was added to make the NF threshold check work) */
OS_REG_WRITE(ah, AR_PHY_AGCCTL, OS_REG_WRITE(ah, AR_PHY_AGCCTL,
OS_REG_READ(ah, AR_PHY_AGCCTL) | AR_PHY_AGC_CAL); OS_REG_READ(ah, AR_PHY_AGCCTL) | AR_PHY_AGC_CAL);
if (!ath_hal_wait(ah, AR_PHY_AGCCTL, AR_PHY_AGC_CAL, 0)) if (!ath_hal_wait(ah, AR_PHY_AGCCTL, AR_PHY_AGC_CAL, 0)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: AGC calibration timeout\n", HALDEBUG(ah, HAL_DEBUG_ANY, "%s: AGC calibration timeout\n",
__func__); __func__);
}
/* Rewrite our AGC values we stored off earlier (return AGC to normal operation) */ /* Rewrite our AGC values we stored off earlier (return AGC to normal operation) */
OS_REG_WRITE(ah, 0x9858, reg9858); OS_REG_WRITE(ah, 0x9858, reg9858);
@@ -621,3 +621,12 @@ ar5210GetTxIntrQueue(struct ath_hal *ah, uint32_t *txqs)
{ {
return; return;
} }
/*
* Retrieve the rate table from the given TX completion descriptor
*/
HAL_BOOL
ar5210GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries)
{
return AH_FALSE;
}
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5210desc.h,v 1.5 2008/11/10 04:08:02 sam Exp $ * $FreeBSD$
*/ */
#ifndef _DEV_ATH_AR5210DESC_H #ifndef _DEV_ATH_AR5210DESC_H
#define _DEV_ATH_AR5210DESC_H #define _DEV_ATH_AR5210DESC_H
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5210phy.h,v 1.4 2008/11/10 01:19:37 sam Exp $ * $FreeBSD$
*/ */
#ifndef _DEV_ATH_AR5210PHY_H #ifndef _DEV_ATH_AR5210PHY_H
#define _DEV_ATH_AR5210PHY_H #define _DEV_ATH_AR5210PHY_H
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5210reg.h,v 1.4 2008/11/10 01:19:37 sam Exp $ * $FreeBSD$
*/ */
#ifndef _DEV_ATH_AR5210REG_H #ifndef _DEV_ATH_AR5210REG_H
#define _DEV_ATH_AR5210REG_H #define _DEV_ATH_AR5210REG_H
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5k_0007.ini,v 1.2 2008/11/10 01:19:37 sam Exp $ * $FreeBSD$
*/ */
/* crete register init */ /* crete register init */
@@ -202,6 +202,8 @@ extern HAL_STATUS ar5211ProcTxDesc(struct ath_hal *,
struct ath_desc *, struct ath_tx_status *); struct ath_desc *, struct ath_tx_status *);
extern void ar5211GetTxIntrQueue(struct ath_hal *ah, uint32_t *); extern void ar5211GetTxIntrQueue(struct ath_hal *ah, uint32_t *);
extern void ar5211IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *); extern void ar5211IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *);
extern HAL_BOOL ar5211GetTxCompletionRates(struct ath_hal *ah,
const struct ath_desc *ds0, int *rates, int *tries);
extern uint32_t ar5211GetRxDP(struct ath_hal *); extern uint32_t ar5211GetRxDP(struct ath_hal *);
extern void ar5211SetRxDP(struct ath_hal *, uint32_t rxdp); extern void ar5211SetRxDP(struct ath_hal *, uint32_t rxdp);
@@ -294,6 +296,7 @@ extern void ar5211BeaconInit(struct ath_hal *, uint32_t, uint32_t);
extern void ar5211SetStaBeaconTimers(struct ath_hal *, extern void ar5211SetStaBeaconTimers(struct ath_hal *,
const HAL_BEACON_STATE *); const HAL_BEACON_STATE *);
extern void ar5211ResetStaBeaconTimers(struct ath_hal *); extern void ar5211ResetStaBeaconTimers(struct ath_hal *);
extern uint64_t ar5211GetNextTBTT(struct ath_hal *);
extern HAL_BOOL ar5211IsInterruptPending(struct ath_hal *); extern HAL_BOOL ar5211IsInterruptPending(struct ath_hal *);
extern HAL_BOOL ar5211GetPendingInterrupts(struct ath_hal *, HAL_INT *); extern HAL_BOOL ar5211GetPendingInterrupts(struct ath_hal *, HAL_INT *);
@@ -303,7 +306,8 @@ extern HAL_INT ar5211SetInterrupts(struct ath_hal *, HAL_INT ints);
extern const HAL_RATE_TABLE *ar5211GetRateTable(struct ath_hal *, u_int mode); extern const HAL_RATE_TABLE *ar5211GetRateTable(struct ath_hal *, u_int mode);
extern HAL_BOOL ar5211AniControl(struct ath_hal *, HAL_ANI_CMD, int ); extern HAL_BOOL ar5211AniControl(struct ath_hal *, HAL_ANI_CMD, int );
extern void ar5211AniPoll(struct ath_hal *, const HAL_NODE_STATS *, extern void ar5211RxMonitor(struct ath_hal *, const HAL_NODE_STATS *,
const struct ieee80211_channel *); const struct ieee80211_channel *);
extern void ar5211AniPoll(struct ath_hal *, const struct ieee80211_channel *);
extern void ar5211MibEvent(struct ath_hal *, const HAL_NODE_STATS *); extern void ar5211MibEvent(struct ath_hal *, const HAL_NODE_STATS *);
#endif /* _ATH_AR5211_H_ */ #endif /* _ATH_AR5211_H_ */
@@ -73,6 +73,7 @@ static const struct ath_hal_private ar5211hal = {{
.ah_procTxDesc = ar5211ProcTxDesc, .ah_procTxDesc = ar5211ProcTxDesc,
.ah_getTxIntrQueue = ar5211GetTxIntrQueue, .ah_getTxIntrQueue = ar5211GetTxIntrQueue,
.ah_reqTxIntrDesc = ar5211IntrReqTxDesc, .ah_reqTxIntrDesc = ar5211IntrReqTxDesc,
.ah_getTxCompletionRates = ar5211GetTxCompletionRates,
/* RX Functions */ /* RX Functions */
.ah_getRxDP = ar5211GetRxDP, .ah_getRxDP = ar5211GetRxDP,
@@ -88,7 +89,8 @@ static const struct ath_hal_private ar5211hal = {{
.ah_setRxFilter = ar5211SetRxFilter, .ah_setRxFilter = ar5211SetRxFilter,
.ah_setupRxDesc = ar5211SetupRxDesc, .ah_setupRxDesc = ar5211SetupRxDesc,
.ah_procRxDesc = ar5211ProcRxDesc, .ah_procRxDesc = ar5211ProcRxDesc,
.ah_rxMonitor = ar5211AniPoll, .ah_rxMonitor = ar5211RxMonitor,
.ah_aniPoll = ar5211AniPoll,
.ah_procMibEvent = ar5211MibEvent, .ah_procMibEvent = ar5211MibEvent,
/* Misc Functions */ /* Misc Functions */
@@ -146,6 +148,7 @@ static const struct ath_hal_private ar5211hal = {{
.ah_beaconInit = ar5211BeaconInit, .ah_beaconInit = ar5211BeaconInit,
.ah_setStationBeaconTimers = ar5211SetStaBeaconTimers, .ah_setStationBeaconTimers = ar5211SetStaBeaconTimers,
.ah_resetStationBeaconTimers = ar5211ResetStaBeaconTimers, .ah_resetStationBeaconTimers = ar5211ResetStaBeaconTimers,
.ah_getNextTBTT = ar5211GetNextTBTT,
/* Interrupt Functions */ /* Interrupt Functions */
.ah_isInterruptPending = ar5211IsInterruptPending, .ah_isInterruptPending = ar5211IsInterruptPending,
@@ -188,7 +191,8 @@ ar5211GetRadioRev(struct ath_hal *ah)
*/ */
static struct ath_hal * static struct ath_hal *
ar5211Attach(uint16_t devid, HAL_SOFTC sc, ar5211Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_STATUS *status)
{ {
#define N(a) (sizeof(a)/sizeof(a[0])) #define N(a) (sizeof(a)/sizeof(a[0]))
struct ath_hal_5211 *ahp; struct ath_hal_5211 *ahp;
@@ -197,13 +201,13 @@ ar5211Attach(uint16_t devid, HAL_SOFTC sc,
uint16_t eeval; uint16_t eeval;
HAL_STATUS ecode; HAL_STATUS ecode;
HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
__func__, sc, (void*) st, (void*) sh); __func__, sc, (void*) st, (void*) sh);
/* NB: memory is returned zero'd */ /* NB: memory is returned zero'd */
ahp = ath_hal_malloc(sizeof (struct ath_hal_5211)); ahp = ath_hal_malloc(sizeof (struct ath_hal_5211));
if (ahp == AH_NULL) { if (ahp == AH_NULL) {
HALDEBUG(AH_NULL, HAL_DEBUG_ANY, HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY,
"%s: cannot allocate memory for state block\n", __func__); "%s: cannot allocate memory for state block\n", __func__);
ecode = HAL_ENOMEM; ecode = HAL_ENOMEM;
goto bad; goto bad;
@@ -506,6 +510,9 @@ ar5211FillCapabilityInfo(struct ath_hal *ah)
| HAL_INT_TIM | HAL_INT_TIM
; ;
pCap->hal4kbSplitTransSupport = AH_TRUE;
pCap->halHasRxSelfLinkedTail = AH_TRUE;
/* XXX might be ok w/ some chip revs */ /* XXX might be ok w/ some chip revs */
ahpriv->ah_rxornIsFatal = AH_TRUE; ahpriv->ah_rxornIsFatal = AH_TRUE;
return AH_TRUE; return AH_TRUE;
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5211_beacon.c,v 1.4 2008/11/10 04:08:02 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -29,6 +29,17 @@
* Routines used to initialize and generated beacons for the AR5211/AR5311. * Routines used to initialize and generated beacons for the AR5211/AR5311.
*/ */
/*
* Return the hardware NextTBTT in TSF
*/
uint64_t
ar5211GetNextTBTT(struct ath_hal *ah)
{
#define TU_TO_TSF(_tu) (((uint64_t)(_tu)) << 10)
return TU_TO_TSF(OS_REG_READ(ah, AR_TIMER0));
#undef TU_TO_TSF
}
/* /*
* Initialize all of the hardware registers used to send beacons. * Initialize all of the hardware registers used to send beacons.
*/ */
@@ -71,9 +82,9 @@ ar5211BeaconInit(struct ath_hal *ah,
case HAL_M_IBSS: case HAL_M_IBSS:
case HAL_M_HOSTAP: case HAL_M_HOSTAP:
bt.bt_nextdba = (next_beacon - bt.bt_nextdba = (next_beacon -
ath_hal_dma_beacon_response_time) << 3; /* 1/8 TU */ ah->ah_config.ah_dma_beacon_response_time) << 3; /* 1/8 TU */
bt.bt_nextswba = (next_beacon - bt.bt_nextswba = (next_beacon -
ath_hal_sw_beacon_response_time) << 3; /* 1/8 TU */ ah->ah_config.ah_sw_beacon_response_time) << 3; /* 1/8 TU */
break; break;
} }
/* /*
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5211_keycache.c,v 1.4 2008/11/10 04:08:02 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -564,7 +564,12 @@ ar5211AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
} }
void void
ar5211AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats, ar5211AniPoll(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
}
void
ar5211RxMonitor(struct ath_hal *ah, const HAL_NODE_STATS *stats,
const struct ieee80211_channel *chan) const struct ieee80211_channel *chan)
{ {
} }
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5211_power.c,v 1.4 2008/11/10 04:08:02 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5211_recv.c,v 1.4 2008/11/10 04:08:02 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -46,7 +46,7 @@ typedef struct {
} CHAN_INFO_2GHZ; } CHAN_INFO_2GHZ;
#define CI_2GHZ_INDEX_CORRECTION 19 #define CI_2GHZ_INDEX_CORRECTION 19
const static CHAN_INFO_2GHZ chan2GHzData[] = { static const CHAN_INFO_2GHZ chan2GHzData[] = {
{ 1, 0x46, 96 }, /* 2312 -19 */ { 1, 0x46, 96 }, /* 2312 -19 */
{ 1, 0x46, 97 }, /* 2317 -18 */ { 1, 0x46, 97 }, /* 2317 -18 */
{ 1, 0x46, 98 }, /* 2322 -17 */ { 1, 0x46, 98 }, /* 2322 -17 */
@@ -926,9 +926,10 @@ ar5211IsNfGood(struct ath_hal *ah, struct ieee80211_channel *chan)
if (!getNoiseFloorThresh(ah, chan, &nfThresh)) if (!getNoiseFloorThresh(ah, chan, &nfThresh))
return AH_FALSE; return AH_FALSE;
if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
HALDEBUG(ah, HAL_DEBUG_ANY, HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: NF did not complete in calibration window\n", __func__); "%s: NF did not complete in calibration window\n", __func__);
}
nf = ar5211GetNoiseFloor(ah); nf = ar5211GetNoiseFloor(ah);
if (nf > nfThresh) { if (nf > nfThresh) {
HALDEBUG(ah, HAL_DEBUG_ANY, HALDEBUG(ah, HAL_DEBUG_ANY,
@@ -345,8 +345,9 @@ ar5211ResetTxQueue(struct ath_hal *ah, u_int q)
| AR_Q_MISC_CBR_INCR_DIS0 | AR_Q_MISC_RDYTIME_EXP_POLICY); | AR_Q_MISC_CBR_INCR_DIS0 | AR_Q_MISC_RDYTIME_EXP_POLICY);
value = (ahp->ah_beaconInterval value = (ahp->ah_beaconInterval
- (ath_hal_sw_beacon_response_time - ath_hal_dma_beacon_response_time) - (ah->ah_config.ah_sw_beacon_response_time
- ath_hal_additional_swba_backoff) * 1024; - ah->ah_config.ah_dma_beacon_response_time)
- ah->ah_config.ah_additional_swba_backoff) * 1024;
OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), value | AR_Q_RDYTIMECFG_EN); OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), value | AR_Q_RDYTIMECFG_EN);
/* Configure DCU for CAB */ /* Configure DCU for CAB */
@@ -660,3 +661,13 @@ ar5211GetTxIntrQueue(struct ath_hal *ah, uint32_t *txqs)
{ {
return; return;
} }
/*
* Retrieve the rate table from the given TX completion descriptor
*/
HAL_BOOL
ar5211GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries)
{
return AH_FALSE;
}
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5211desc.h,v 1.5 2008/11/10 04:08:03 sam Exp $ * $FreeBSD$
*/ */
#ifndef _DEV_ATH_AR5211DESC_H #ifndef _DEV_ATH_AR5211DESC_H
#define _DEV_ATH_AR5211DESC_H #define _DEV_ATH_AR5211DESC_H
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5211phy.h,v 1.4 2008/11/10 01:19:38 sam Exp $ * $FreeBSD$
*/ */
#ifndef _DEV_ATH_AR5211PHY_H #ifndef _DEV_ATH_AR5211PHY_H
#define _DEV_ATH_AR5211PHY_H #define _DEV_ATH_AR5211PHY_H
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5211reg.h,v 1.4 2008/11/10 01:19:38 sam Exp $ * $FreeBSD$
*/ */
#ifndef _DEV_ATH_AR5211REG_H #ifndef _DEV_ATH_AR5211REG_H
#define _DEV_ATH_AR5211REG_H #define _DEV_ATH_AR5211REG_H
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: boss.ini,v 1.3 2008/11/10 04:08:03 sam Exp $ * $FreeBSD$
*/ */
/* Auto Generated PCI Register Writes. Created: 09/12/02 */ /* Auto Generated PCI Register Writes. Created: 09/12/02 */
@@ -611,7 +611,7 @@ getFullPwrTable(uint16_t numPcdacs, uint16_t *pcdacs, int16_t *power, int16_t ma
uint16_t idxR = 1; uint16_t idxR = 1;
if (numPcdacs < 2) { if (numPcdacs < 2) {
HALDEBUG(AH_NULL, HAL_DEBUG_ANY, HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY,
"%s: at least 2 pcdac values needed [%d]\n", "%s: at least 2 pcdac values needed [%d]\n",
__func__, numPcdacs); __func__, numPcdacs);
return AH_FALSE; return AH_FALSE;
@@ -143,7 +143,7 @@ typedef struct RfHalFuncs {
int16_t *minPower, int16_t *maxPower, int16_t *minPower, int16_t *maxPower,
const struct ieee80211_channel *, uint16_t *rfXpdGain); const struct ieee80211_channel *, uint16_t *rfXpdGain);
HAL_BOOL (*getChannelMaxMinPower)(struct ath_hal *ah, HAL_BOOL (*getChannelMaxMinPower)(struct ath_hal *ah,
const struct ieee80211_channel *, const const struct ieee80211_channel *,
int16_t *maxPow, int16_t *minPow); int16_t *maxPow, int16_t *minPow);
int16_t (*getNfAdjust)(struct ath_hal *, const HAL_CHANNEL_INTERNAL*); int16_t (*getNfAdjust)(struct ath_hal *, const HAL_CHANNEL_INTERNAL*);
} RF_HAL_FUNCS; } RF_HAL_FUNCS;
@@ -320,13 +320,19 @@ struct ath_hal_5212 {
struct ar5212AniState *ah_curani; /* cached last reference */ struct ar5212AniState *ah_curani; /* cached last reference */
struct ar5212AniState ah_ani[AH_MAXCHAN]; /* per-channel state */ struct ar5212AniState ah_ani[AH_MAXCHAN]; /* per-channel state */
/* AR5416 uses some of the AR5212 ANI code; these are the ANI methods */
HAL_BOOL (*ah_aniControl) (struct ath_hal *, HAL_ANI_CMD cmd, int param);
/* /*
* Transmit power state. Note these are maintained * Transmit power state. Note these are maintained
* here so they can be retrieved by diagnostic tools. * here so they can be retrieved by diagnostic tools.
*/ */
uint16_t *ah_pcdacTable; uint16_t *ah_pcdacTable;
u_int ah_pcdacTableSize; u_int ah_pcdacTableSize;
uint16_t ah_ratesArray[16]; uint16_t ah_ratesArray[37];
uint8_t ah_txTrigLev; /* current Tx trigger level */
uint8_t ah_maxTxTrigLev; /* max tx trigger level */
}; };
#define AH5212(_ah) ((struct ath_hal_5212 *)(_ah)) #define AH5212(_ah) ((struct ath_hal_5212 *)(_ah))
@@ -424,6 +430,7 @@ extern void ar5212BeaconInit(struct ath_hal *ah,
extern void ar5212ResetStaBeaconTimers(struct ath_hal *ah); extern void ar5212ResetStaBeaconTimers(struct ath_hal *ah);
extern void ar5212SetStaBeaconTimers(struct ath_hal *ah, extern void ar5212SetStaBeaconTimers(struct ath_hal *ah,
const HAL_BEACON_STATE *); const HAL_BEACON_STATE *);
extern uint64_t ar5212GetNextTBTT(struct ath_hal *);
extern HAL_BOOL ar5212IsInterruptPending(struct ath_hal *ah); extern HAL_BOOL ar5212IsInterruptPending(struct ath_hal *ah);
extern HAL_BOOL ar5212GetPendingInterrupts(struct ath_hal *ah, HAL_INT *); extern HAL_BOOL ar5212GetPendingInterrupts(struct ath_hal *ah, HAL_INT *);
@@ -459,6 +466,7 @@ extern void ar5212WriteAssocid(struct ath_hal *ah, const uint8_t *bssid,
uint16_t assocId); uint16_t assocId);
extern uint32_t ar5212GetTsf32(struct ath_hal *ah); extern uint32_t ar5212GetTsf32(struct ath_hal *ah);
extern uint64_t ar5212GetTsf64(struct ath_hal *ah); extern uint64_t ar5212GetTsf64(struct ath_hal *ah);
extern void ar5212SetTsf64(struct ath_hal *ah, uint64_t tsf64);
extern void ar5212ResetTsf(struct ath_hal *ah); extern void ar5212ResetTsf(struct ath_hal *ah);
extern void ar5212SetBasicRate(struct ath_hal *ah, HAL_RATE_SET *pSet); extern void ar5212SetBasicRate(struct ath_hal *ah, HAL_RATE_SET *pSet);
extern uint32_t ar5212GetRandomSeed(struct ath_hal *ah); extern uint32_t ar5212GetRandomSeed(struct ath_hal *ah);
@@ -499,6 +507,8 @@ extern HAL_BOOL ar5212SetCapability(struct ath_hal *, HAL_CAPABILITY_TYPE,
extern HAL_BOOL ar5212GetDiagState(struct ath_hal *ah, int request, extern HAL_BOOL ar5212GetDiagState(struct ath_hal *ah, int request,
const void *args, uint32_t argsize, const void *args, uint32_t argsize,
void **result, uint32_t *resultsize); void **result, uint32_t *resultsize);
extern HAL_STATUS ar5212SetQuiet(struct ath_hal *ah, uint32_t period,
uint32_t duration, uint32_t nextStart, HAL_QUIET_FLAG flag);
extern HAL_BOOL ar5212SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, extern HAL_BOOL ar5212SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode,
int setChip); int setChip);
@@ -586,6 +596,8 @@ extern HAL_STATUS ar5212ProcTxDesc(struct ath_hal *ah,
struct ath_desc *, struct ath_tx_status *); struct ath_desc *, struct ath_tx_status *);
extern void ar5212GetTxIntrQueue(struct ath_hal *ah, uint32_t *); extern void ar5212GetTxIntrQueue(struct ath_hal *ah, uint32_t *);
extern void ar5212IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *); extern void ar5212IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *);
extern HAL_BOOL ar5212GetTxCompletionRates(struct ath_hal *ah,
const struct ath_desc *ds0, int *rates, int *tries);
extern const HAL_RATE_TABLE *ar5212GetRateTable(struct ath_hal *, u_int mode); extern const HAL_RATE_TABLE *ar5212GetRateTable(struct ath_hal *, u_int mode);
@@ -601,8 +613,19 @@ struct ath_rx_status;
extern void ar5212AniPhyErrReport(struct ath_hal *ah, extern void ar5212AniPhyErrReport(struct ath_hal *ah,
const struct ath_rx_status *rs); const struct ath_rx_status *rs);
extern void ar5212ProcessMibIntr(struct ath_hal *, const HAL_NODE_STATS *); extern void ar5212ProcessMibIntr(struct ath_hal *, const HAL_NODE_STATS *);
extern void ar5212AniPoll(struct ath_hal *, const HAL_NODE_STATS *, extern void ar5212RxMonitor(struct ath_hal *, const HAL_NODE_STATS *,
const struct ieee80211_channel *); const struct ieee80211_channel *);
extern void ar5212AniPoll(struct ath_hal *, const struct ieee80211_channel *);
extern void ar5212AniReset(struct ath_hal *, const struct ieee80211_channel *, extern void ar5212AniReset(struct ath_hal *, const struct ieee80211_channel *,
HAL_OPMODE, int); HAL_OPMODE, int);
extern HAL_BOOL ar5212IsNFCalInProgress(struct ath_hal *ah);
extern HAL_BOOL ar5212WaitNFCalComplete(struct ath_hal *ah, int i);
extern void ar5212EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe);
extern void ar5212GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe);
extern HAL_BOOL ar5212ProcessRadarEvent(struct ath_hal *ah,
struct ath_rx_status *rxs, uint64_t fulltsf, const char *buf,
HAL_DFS_EVENT *event);
extern HAL_BOOL ar5212IsFastClockEnabled(struct ath_hal *ah);
#endif /* _ATH_AR5212_H_ */ #endif /* _ATH_AR5212_H_ */
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5212.ini,v 1.3 2008/11/10 04:08:03 sam Exp $ * $FreeBSD$
*/ */
/* Auto Generated PCI Register Writes. Created: 09/01/04 */ /* Auto Generated PCI Register Writes. Created: 09/01/04 */
@@ -222,7 +222,14 @@ ar5212AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
typedef int TABLE[]; typedef int TABLE[];
struct ath_hal_5212 *ahp = AH5212(ah); struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212AniState *aniState = ahp->ah_curani; struct ar5212AniState *aniState = ahp->ah_curani;
const struct ar5212AniParams *params = aniState->params; const struct ar5212AniParams *params = AH_NULL;
/*
* This function may be called before there's a current
* channel (eg to disable ANI.)
*/
if (aniState != AH_NULL)
params = aniState->params;
OS_MARK(ah, AH_MARK_ANI_CONTROL, cmd); OS_MARK(ah, AH_MARK_ANI_CONTROL, cmd);
@@ -343,8 +350,8 @@ ar5212AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
ahp->ah_procPhyErr &= ~HAL_ANI_ENA; ahp->ah_procPhyErr &= ~HAL_ANI_ENA;
/* Turn off HW counters if we have them */ /* Turn off HW counters if we have them */
ar5212AniDetach(ah); ar5212AniDetach(ah);
ar5212SetRxFilter(ah, ah->ah_setRxFilter(ah,
ar5212GetRxFilter(ah) &~ HAL_RX_FILTER_PHYERR); ah->ah_getRxFilter(ah) &~ HAL_RX_FILTER_PHYERR);
} else { /* normal/auto mode */ } else { /* normal/auto mode */
/* don't mess with state if already enabled */ /* don't mess with state if already enabled */
if (ahp->ah_procPhyErr & HAL_ANI_ENA) if (ahp->ah_procPhyErr & HAL_ANI_ENA)
@@ -358,8 +365,8 @@ ar5212AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
ahp->ah_curani->params: ahp->ah_curani->params:
&ahp->ah_aniParams24 /*XXX*/); &ahp->ah_aniParams24 /*XXX*/);
} else { } else {
ar5212SetRxFilter(ah, ah->ah_setRxFilter(ah,
ar5212GetRxFilter(ah) | HAL_RX_FILTER_PHYERR); ah->ah_getRxFilter(ah) | HAL_RX_FILTER_PHYERR);
} }
ahp->ah_procPhyErr |= HAL_ANI_ENA; ahp->ah_procPhyErr |= HAL_ANI_ENA;
} }
@@ -609,8 +616,20 @@ ar5212AniReset(struct ath_hal *ah, const struct ieee80211_channel *chan,
/* /*
* Turn off PHY error frame delivery while we futz with settings. * Turn off PHY error frame delivery while we futz with settings.
*/ */
rxfilter = ar5212GetRxFilter(ah); rxfilter = ah->ah_getRxFilter(ah);
ar5212SetRxFilter(ah, rxfilter &~ HAL_RX_FILTER_PHYERR); ah->ah_setRxFilter(ah, rxfilter &~ HAL_RX_FILTER_PHYERR);
/*
* If ANI is disabled at this point, don't set the default
* ANI parameter settings - leave the HAL settings there.
* This is (currently) needed for reliable radar detection.
*/
if (! ANI_ENA(ah)) {
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: ANI disabled\n",
__func__);
goto finish;
}
/* /*
* Automatic processing is done only in station mode right now. * Automatic processing is done only in station mode right now.
*/ */
@@ -644,10 +663,15 @@ ar5212AniReset(struct ath_hal *ah, const struct ieee80211_channel *chan,
ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0); ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
ichan->privFlags |= CHANNEL_ANI_SETUP; ichan->privFlags |= CHANNEL_ANI_SETUP;
} }
/*
* In case the counters haven't yet been setup; set them up.
*/
enableAniMIBCounters(ah, ahp->ah_curani->params);
ar5212AniRestart(ah, aniState); ar5212AniRestart(ah, aniState);
finish:
/* restore RX filter mask */ /* restore RX filter mask */
ar5212SetRxFilter(ah, rxfilter); ah->ah_setRxFilter(ah, rxfilter);
} }
/* /*
@@ -912,21 +936,26 @@ updateMIBStats(struct ath_hal *ah, struct ar5212AniState *aniState)
aniState->cckPhyErrCount = cckPhyErrCnt; aniState->cckPhyErrCount = cckPhyErrCnt;
} }
void
ar5212RxMonitor(struct ath_hal *ah, const HAL_NODE_STATS *stats,
const struct ieee80211_channel *chan)
{
struct ath_hal_5212 *ahp = AH5212(ah);
ahp->ah_stats.ast_nodestats.ns_avgbrssi = stats->ns_avgbrssi;
}
/* /*
* Do periodic processing. This routine is called from the * Do periodic processing. This routine is called from the
* driver's rx interrupt handler after processing frames. * driver's rx interrupt handler after processing frames.
*/ */
void void
ar5212AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats, ar5212AniPoll(struct ath_hal *ah, const struct ieee80211_channel *chan)
const struct ieee80211_channel *chan)
{ {
struct ath_hal_5212 *ahp = AH5212(ah); struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212AniState *aniState = ahp->ah_curani; struct ar5212AniState *aniState = ahp->ah_curani;
const struct ar5212AniParams *params; const struct ar5212AniParams *params;
int32_t listenTime; int32_t listenTime;
ahp->ah_stats.ast_nodestats.ns_avgbrssi = stats->ns_avgbrssi;
/* XXX can aniState be null? */ /* XXX can aniState be null? */
if (aniState == AH_NULL) if (aniState == AH_NULL)
return; return;
@@ -69,6 +69,7 @@ static const struct ath_hal_private ar5212hal = {{
.ah_procTxDesc = ar5212ProcTxDesc, .ah_procTxDesc = ar5212ProcTxDesc,
.ah_getTxIntrQueue = ar5212GetTxIntrQueue, .ah_getTxIntrQueue = ar5212GetTxIntrQueue,
.ah_reqTxIntrDesc = ar5212IntrReqTxDesc, .ah_reqTxIntrDesc = ar5212IntrReqTxDesc,
.ah_getTxCompletionRates = ar5212GetTxCompletionRates,
/* RX Functions */ /* RX Functions */
.ah_getRxDP = ar5212GetRxDP, .ah_getRxDP = ar5212GetRxDP,
@@ -84,7 +85,8 @@ static const struct ath_hal_private ar5212hal = {{
.ah_setRxFilter = ar5212SetRxFilter, .ah_setRxFilter = ar5212SetRxFilter,
.ah_setupRxDesc = ar5212SetupRxDesc, .ah_setupRxDesc = ar5212SetupRxDesc,
.ah_procRxDesc = ar5212ProcRxDesc, .ah_procRxDesc = ar5212ProcRxDesc,
.ah_rxMonitor = ar5212AniPoll, .ah_rxMonitor = ar5212RxMonitor,
.ah_aniPoll = ar5212AniPoll,
.ah_procMibEvent = ar5212ProcessMibIntr, .ah_procMibEvent = ar5212ProcessMibIntr,
/* Misc Functions */ /* Misc Functions */
@@ -125,6 +127,13 @@ static const struct ath_hal_private ar5212hal = {{
.ah_getCTSTimeout = ar5212GetCTSTimeout, .ah_getCTSTimeout = ar5212GetCTSTimeout,
.ah_setDecompMask = ar5212SetDecompMask, .ah_setDecompMask = ar5212SetDecompMask,
.ah_setCoverageClass = ar5212SetCoverageClass, .ah_setCoverageClass = ar5212SetCoverageClass,
.ah_setQuiet = ar5212SetQuiet,
/* DFS Functions */
.ah_enableDfs = ar5212EnableDfs,
.ah_getDfsThresh = ar5212GetDfsThresh,
.ah_procRadarEvent = ar5212ProcessRadarEvent,
.ah_isFastClockEnabled = ar5212IsFastClockEnabled,
/* Key Cache Functions */ /* Key Cache Functions */
.ah_getKeyCacheSize = ar5212GetKeyCacheSize, .ah_getKeyCacheSize = ar5212GetKeyCacheSize,
@@ -142,6 +151,7 @@ static const struct ath_hal_private ar5212hal = {{
.ah_beaconInit = ar5212BeaconInit, .ah_beaconInit = ar5212BeaconInit,
.ah_setStationBeaconTimers = ar5212SetStaBeaconTimers, .ah_setStationBeaconTimers = ar5212SetStaBeaconTimers,
.ah_resetStationBeaconTimers = ar5212ResetStaBeaconTimers, .ah_resetStationBeaconTimers = ar5212ResetStaBeaconTimers,
.ah_getNextTBTT = ar5212GetNextTBTT,
/* Interrupt Functions */ /* Interrupt Functions */
.ah_isInterruptPending = ar5212IsInterruptPending, .ah_isInterruptPending = ar5212IsInterruptPending,
@@ -201,6 +211,9 @@ ar5212AniSetup(struct ath_hal *ah)
ar5212AniAttach(ah, &tmp, &tmp, AH_TRUE); ar5212AniAttach(ah, &tmp, &tmp, AH_TRUE);
} else } else
ar5212AniAttach(ah, &aniparams, &aniparams, AH_TRUE); ar5212AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
/* Set overridable ANI methods */
AH5212(ah)->ah_aniControl = ar5212AniControl;
} }
/* /*
@@ -248,6 +261,9 @@ ar5212InitState(struct ath_hal_5212 *ahp, uint16_t devid, HAL_SOFTC sc,
ahp->ah_acktimeout = (u_int) -1; ahp->ah_acktimeout = (u_int) -1;
ahp->ah_ctstimeout = (u_int) -1; ahp->ah_ctstimeout = (u_int) -1;
ahp->ah_sifstime = (u_int) -1; ahp->ah_sifstime = (u_int) -1;
ahp->ah_txTrigLev = INIT_TX_FIFO_THRESHOLD,
ahp->ah_maxTxTrigLev = MAX_TX_FIFO_THRESHOLD,
OS_MEMCPY(&ahp->ah_bssidmask, defbssidmask, IEEE80211_ADDR_LEN); OS_MEMCPY(&ahp->ah_bssidmask, defbssidmask, IEEE80211_ADDR_LEN);
#undef N #undef N
} }
@@ -291,7 +307,8 @@ ar5212IsMacSupported(uint8_t macVersion, uint8_t macRev)
*/ */
static struct ath_hal * static struct ath_hal *
ar5212Attach(uint16_t devid, HAL_SOFTC sc, ar5212Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_STATUS *status)
{ {
#define AH_EEPROM_PROTECT(ah) \ #define AH_EEPROM_PROTECT(ah) \
(AH_PRIVATE(ah)->ah_ispcie)? AR_EEPROM_PROTECT_PCIE : AR_EEPROM_PROTECT) (AH_PRIVATE(ah)->ah_ispcie)? AR_EEPROM_PROTECT_PCIE : AR_EEPROM_PROTECT)
@@ -302,13 +319,13 @@ ar5212Attach(uint16_t devid, HAL_SOFTC sc,
uint16_t eeval; uint16_t eeval;
HAL_STATUS ecode; HAL_STATUS ecode;
HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
__func__, sc, (void*) st, (void*) sh); __func__, sc, (void*) st, (void*) sh);
/* NB: memory is returned zero'd */ /* NB: memory is returned zero'd */
ahp = ath_hal_malloc(sizeof (struct ath_hal_5212)); ahp = ath_hal_malloc(sizeof (struct ath_hal_5212));
if (ahp == AH_NULL) { if (ahp == AH_NULL) {
HALDEBUG(AH_NULL, HAL_DEBUG_ANY, HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY,
"%s: cannot allocate memory for state block\n", __func__); "%s: cannot allocate memory for state block\n", __func__);
*status = HAL_ENOMEM; *status = HAL_ENOMEM;
return AH_NULL; return AH_NULL;
@@ -854,6 +871,9 @@ ar5212FillCapabilityInfo(struct ath_hal *ah)
if (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_GRIFFIN) if (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_GRIFFIN)
pCap->halIntrMask &= ~HAL_INT_TBTT; pCap->halIntrMask &= ~HAL_INT_TBTT;
pCap->hal4kbSplitTransSupport = AH_TRUE;
pCap->halHasRxSelfLinkedTail = AH_TRUE;
return AH_TRUE; return AH_TRUE;
#undef IS_COBRA #undef IS_COBRA
#undef IS_GRIFFIN_LITE #undef IS_GRIFFIN_LITE
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5212_beacon.c,v 1.6 2008/11/10 04:08:03 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -25,6 +25,17 @@
#include "ar5212/ar5212reg.h" #include "ar5212/ar5212reg.h"
#include "ar5212/ar5212desc.h" #include "ar5212/ar5212desc.h"
/*
* Return the hardware NextTBTT in TSF
*/
uint64_t
ar5212GetNextTBTT(struct ath_hal *ah)
{
#define TU_TO_TSF(_tu) (((uint64_t)(_tu)) << 10)
return TU_TO_TSF(OS_REG_READ(ah, AR_TIMER0));
#undef TU_TO_TSF
}
/* /*
* Initialize all of the hardware registers used to * Initialize all of the hardware registers used to
* send beacons. Note that for station operation the * send beacons. Note that for station operation the
@@ -84,9 +95,9 @@ ar5212BeaconInit(struct ath_hal *ah,
case HAL_M_HOSTAP: case HAL_M_HOSTAP:
case HAL_M_IBSS: case HAL_M_IBSS:
bt.bt_nextdba = (next_beacon - bt.bt_nextdba = (next_beacon -
ath_hal_dma_beacon_response_time) << 3; /* 1/8 TU */ ah->ah_config.ah_dma_beacon_response_time) << 3; /* 1/8 TU */
bt.bt_nextswba = (next_beacon - bt.bt_nextswba = (next_beacon -
ath_hal_sw_beacon_response_time) << 3; /* 1/8 TU */ ah->ah_config.ah_sw_beacon_response_time) << 3; /* 1/8 TU */
break; break;
} }
/* /*
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5212_eeprom.c,v 1.6 2008/11/10 04:08:03 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5212_keycache.c,v 1.4 2008/11/10 04:08:03 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -99,11 +99,18 @@ ar5212ResetKeyCacheEntry(struct ath_hal *ah, uint16_t entry)
/* /*
* Sets the mac part of the specified key cache entry (and any * Sets the mac part of the specified key cache entry (and any
* associated MIC entry) and mark them valid. * associated MIC entry) and mark them valid.
*
* Since mac[0] is shifted off and not presented to the hardware,
* it does double duty as a "don't use for unicast, use for multicast
* matching" flag. This interface should later be extended to
* explicitly do that rather than overloading a bit in the MAC
* address.
*/ */
HAL_BOOL HAL_BOOL
ar5212SetKeyCacheEntryMac(struct ath_hal *ah, uint16_t entry, const uint8_t *mac) ar5212SetKeyCacheEntryMac(struct ath_hal *ah, uint16_t entry, const uint8_t *mac)
{ {
uint32_t macHi, macLo; uint32_t macHi, macLo;
uint32_t unicast_flag = AR_KEYTABLE_VALID;
if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) { if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: entry %u out of range\n", HALDEBUG(ah, HAL_DEBUG_ANY, "%s: entry %u out of range\n",
@@ -115,6 +122,16 @@ ar5212SetKeyCacheEntryMac(struct ath_hal *ah, uint16_t entry, const uint8_t *mac
* the 4 MSBs, and MacHi is the 2 LSBs. * the 4 MSBs, and MacHi is the 2 LSBs.
*/ */
if (mac != AH_NULL) { if (mac != AH_NULL) {
/*
* AR_KEYTABLE_VALID indicates that the address is a unicast
* address, which must match the transmitter address for
* decrypting frames.
* Not setting this bit allows the hardware to use the key
* for multicast frame decryption.
*/
if (mac[0] & 0x01)
unicast_flag = 0;
macHi = (mac[5] << 8) | mac[4]; macHi = (mac[5] << 8) | mac[4];
macLo = (mac[3] << 24)| (mac[2] << 16) macLo = (mac[3] << 24)| (mac[2] << 16)
| (mac[1] << 8) | mac[0]; | (mac[1] << 8) | mac[0];
@@ -125,7 +142,7 @@ ar5212SetKeyCacheEntryMac(struct ath_hal *ah, uint16_t entry, const uint8_t *mac
macLo = macHi = 0; macLo = macHi = 0;
} }
OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID); OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
return AH_TRUE; return AH_TRUE;
} }
@@ -21,9 +21,7 @@
#include "ah.h" #include "ah.h"
#include "ah_internal.h" #include "ah_internal.h"
#include "ah_devid.h" #include "ah_devid.h"
#ifdef AH_DEBUG
#include "ah_desc.h" /* NB: for HAL_PHYERR* */ #include "ah_desc.h" /* NB: for HAL_PHYERR* */
#endif
#include "ar5212/ar5212.h" #include "ar5212/ar5212.h"
#include "ar5212/ar5212reg.h" #include "ar5212/ar5212reg.h"
@@ -264,6 +262,13 @@ ar5212GetTsf32(struct ath_hal *ah)
return OS_REG_READ(ah, AR_TSF_L32); return OS_REG_READ(ah, AR_TSF_L32);
} }
void
ar5212SetTsf64(struct ath_hal *ah, uint64_t tsf64)
{
OS_REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
OS_REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
}
/* /*
* Reset the current hardware tsf for stamlme. * Reset the current hardware tsf for stamlme.
*/ */
@@ -451,7 +456,7 @@ ar5212SetSifsTime(struct ath_hal *ah, u_int us)
} else { } else {
/* convert to system clocks */ /* convert to system clocks */
OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, ath_hal_mac_clks(ah, us-2)); OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, ath_hal_mac_clks(ah, us-2));
ahp->ah_slottime = us; ahp->ah_sifstime = us;
return AH_TRUE; return AH_TRUE;
} }
} }
@@ -627,6 +632,20 @@ ar5212SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
} }
} }
HAL_STATUS
ar5212SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration,
uint32_t nextStart, HAL_QUIET_FLAG flag)
{
OS_REG_WRITE(ah, AR_QUIET2, period | (duration << AR_QUIET2_QUIET_DUR_S));
if (flag & HAL_QUIET_ENABLE) {
OS_REG_WRITE(ah, AR_QUIET1, nextStart | (1 << 16));
}
else {
OS_REG_WRITE(ah, AR_QUIET1, nextStart);
}
return HAL_OK;
}
void void
ar5212SetPCUConfig(struct ath_hal *ah) ar5212SetPCUConfig(struct ath_hal *ah)
{ {
@@ -850,7 +869,7 @@ ar5212GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
case HAL_CAP_MCAST_KEYSRCH: /* multicast frame keycache search */ case HAL_CAP_MCAST_KEYSRCH: /* multicast frame keycache search */
switch (capability) { switch (capability) {
case 0: /* hardware capability */ case 0: /* hardware capability */
return HAL_OK; return pCap->halMcastKeySrchSupport ? HAL_OK : HAL_ENXIO;
case 1: case 1:
return (ahp->ah_staId1Defaults & return (ahp->ah_staId1Defaults &
AR_STA_ID1_MCAST_KSRCH) ? HAL_OK : HAL_ENXIO; AR_STA_ID1_MCAST_KSRCH) ? HAL_OK : HAL_ENXIO;
@@ -873,16 +892,16 @@ ar5212GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
return HAL_OK; return HAL_OK;
case HAL_CAP_INTMIT: /* interference mitigation */ case HAL_CAP_INTMIT: /* interference mitigation */
switch (capability) { switch (capability) {
case 0: /* hardware capability */ case HAL_CAP_INTMIT_PRESENT: /* hardware capability */
return HAL_OK; return HAL_OK;
case 1: case HAL_CAP_INTMIT_ENABLE:
return (ahp->ah_procPhyErr & HAL_ANI_ENA) ? return (ahp->ah_procPhyErr & HAL_ANI_ENA) ?
HAL_OK : HAL_ENXIO; HAL_OK : HAL_ENXIO;
case 2: /* HAL_ANI_NOISE_IMMUNITY_LEVEL */ case HAL_CAP_INTMIT_NOISE_IMMUNITY_LEVEL:
case 3: /* HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION */ case HAL_CAP_INTMIT_OFDM_WEAK_SIGNAL_LEVEL:
case 4: /* HAL_ANI_CCK_WEAK_SIGNAL_THR */ case HAL_CAP_INTMIT_CCK_WEAK_SIGNAL_THR:
case 5: /* HAL_ANI_FIRSTEP_LEVEL */ case HAL_CAP_INTMIT_FIRSTEP_LEVEL:
case 6: /* HAL_ANI_SPUR_IMMUNITY_LEVEL */ case HAL_CAP_INTMIT_SPUR_IMMUNITY_LEVEL:
ani = ar5212AniGetCurrentState(ah); ani = ar5212AniGetCurrentState(ah);
if (ani == AH_NULL) if (ani == AH_NULL)
return HAL_ENXIO; return HAL_ENXIO;
@@ -927,7 +946,7 @@ ar5212SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
else else
ahp->ah_miscMode |= AR_MISC_MODE_MIC_NEW_LOC_ENABLE; ahp->ah_miscMode |= AR_MISC_MODE_MIC_NEW_LOC_ENABLE;
/* NB: write here so keys can be setup w/o a reset */ /* NB: write here so keys can be setup w/o a reset */
OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode);
return AH_TRUE; return AH_TRUE;
case HAL_CAP_DIVERSITY: case HAL_CAP_DIVERSITY:
if (ahp->ah_phyPowerOn) { if (ahp->ah_phyPowerOn) {
@@ -973,6 +992,8 @@ ar5212SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
OS_REG_WRITE(ah, AR_TPC, ahp->ah_macTPC); OS_REG_WRITE(ah, AR_TPC, ahp->ah_macTPC);
return AH_TRUE; return AH_TRUE;
case HAL_CAP_INTMIT: { /* interference mitigation */ case HAL_CAP_INTMIT: { /* interference mitigation */
/* This maps the public ANI commands to the internal ANI commands */
/* Private: HAL_ANI_CMD; Public: HAL_CAP_INTMIT_CMD */
static const HAL_ANI_CMD cmds[] = { static const HAL_ANI_CMD cmds[] = {
HAL_ANI_PRESENT, HAL_ANI_PRESENT,
HAL_ANI_MODE, HAL_ANI_MODE,
@@ -983,7 +1004,7 @@ ar5212SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
HAL_ANI_SPUR_IMMUNITY_LEVEL, HAL_ANI_SPUR_IMMUNITY_LEVEL,
}; };
return capability < N(cmds) ? return capability < N(cmds) ?
ar5212AniControl(ah, cmds[capability], setting) : AH5212(ah)->ah_aniControl(ah, cmds[capability], setting) :
AH_FALSE; AH_FALSE;
} }
case HAL_CAP_TSF_ADJUST: /* hardware has beacon tsf adjust */ case HAL_CAP_TSF_ADJUST: /* hardware has beacon tsf adjust */
@@ -1046,7 +1067,7 @@ ar5212GetDiagState(struct ath_hal *ah, int request,
case HAL_DIAG_ANI_CMD: case HAL_DIAG_ANI_CMD:
if (argsize != 2*sizeof(uint32_t)) if (argsize != 2*sizeof(uint32_t))
return AH_FALSE; return AH_FALSE;
ar5212AniControl(ah, ((const uint32_t *)args)[0], AH5212(ah)->ah_aniControl(ah, ((const uint32_t *)args)[0],
((const uint32_t *)args)[1]); ((const uint32_t *)args)[1]);
return AH_TRUE; return AH_TRUE;
case HAL_DIAG_ANI_PARAMS: case HAL_DIAG_ANI_PARAMS:
@@ -1071,3 +1092,143 @@ ar5212GetDiagState(struct ath_hal *ah, int request,
} }
return AH_FALSE; return AH_FALSE;
} }
/*
* Check whether there's an in-progress NF completion.
*
* Returns AH_TRUE if there's a in-progress NF calibration, AH_FALSE
* otherwise.
*/
HAL_BOOL
ar5212IsNFCalInProgress(struct ath_hal *ah)
{
if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF)
return AH_TRUE;
return AH_FALSE;
}
/*
* Wait for an in-progress NF calibration to complete.
*
* The completion function waits "i" times 10uS.
* It returns AH_TRUE if the NF calibration completed (or was never
* in progress); AH_FALSE if it was still in progress after "i" checks.
*/
HAL_BOOL
ar5212WaitNFCalComplete(struct ath_hal *ah, int i)
{
int j;
if (i <= 0)
i = 1; /* it should run at least once */
for (j = 0; j < i; j++) {
if (! ar5212IsNFCalInProgress(ah))
return AH_TRUE;
OS_DELAY(10);
}
return AH_FALSE;
}
void
ar5212EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
{
uint32_t val;
val = OS_REG_READ(ah, AR_PHY_RADAR_0);
if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_FIRPWR;
val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR);
}
if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_RRSSI;
val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI);
}
if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_HEIGHT;
val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT);
}
if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_PRSSI;
val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
}
if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_INBAND;
val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND);
}
OS_REG_WRITE(ah, AR_PHY_RADAR_0, val | AR_PHY_RADAR_0_ENA);
}
void
ar5212GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
{
uint32_t val,temp;
val = OS_REG_READ(ah, AR_PHY_RADAR_0);
temp = MS(val,AR_PHY_RADAR_0_FIRPWR);
temp |= 0xFFFFFF80;
pe->pe_firpwr = temp;
pe->pe_rrssi = MS(val, AR_PHY_RADAR_0_RRSSI);
pe->pe_height = MS(val, AR_PHY_RADAR_0_HEIGHT);
pe->pe_prssi = MS(val, AR_PHY_RADAR_0_PRSSI);
pe->pe_inband = MS(val, AR_PHY_RADAR_0_INBAND);
pe->pe_relpwr = 0;
pe->pe_relstep = 0;
pe->pe_maxlen = 0;
pe->pe_extchannel = AH_FALSE;
}
/*
* Process the radar phy error and extract the pulse duration.
*/
HAL_BOOL
ar5212ProcessRadarEvent(struct ath_hal *ah, struct ath_rx_status *rxs,
uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event)
{
uint8_t dur;
uint8_t rssi;
/* Check whether the given phy error is a radar event */
if ((rxs->rs_phyerr != HAL_PHYERR_RADAR) &&
(rxs->rs_phyerr != HAL_PHYERR_FALSE_RADAR_EXT))
return AH_FALSE;
/*
* The first byte is the pulse width - if there's
* no data, simply set the duration to 0
*/
if (rxs->rs_datalen >= 1)
/* The pulse width is byte 0 of the data */
dur = ((uint8_t) buf[0]) & 0xff;
else
dur = 0;
/* Pulse RSSI is the normal reported RSSI */
rssi = (uint8_t) rxs->rs_rssi;
/* 0 duration/rssi is not a valid radar event */
if (dur == 0 && rssi == 0)
return AH_FALSE;
HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, dur=%d\n",
__func__, rssi, dur);
/* Record the event */
event->re_full_ts = fulltsf;
event->re_ts = rxs->rs_tstamp;
event->re_rssi = rssi;
event->re_dur = dur;
event->re_flags = HAL_DFS_EVENT_PRICH;
return AH_TRUE;
}
/*
* Return whether 5GHz fast-clock (44MHz) is enabled.
* It's always disabled for AR5212 series NICs.
*/
HAL_BOOL
ar5212IsFastClockEnabled(struct ath_hal *ah)
{
return AH_FALSE;
}
@@ -59,8 +59,10 @@ ar5212EnableReceive(struct ath_hal *ah)
HAL_BOOL HAL_BOOL
ar5212StopDmaReceive(struct ath_hal *ah) ar5212StopDmaReceive(struct ath_hal *ah)
{ {
OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_DMA_STOP);
OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); /* Set receive disable bit */ OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); /* Set receive disable bit */
if (!ath_hal_wait(ah, AR_CR, AR_CR_RXE, 0)) { if (!ath_hal_wait(ah, AR_CR, AR_CR_RXE, 0)) {
OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_DMA_STOP_ERR);
#ifdef AH_DEBUG #ifdef AH_DEBUG
ath_hal_printf(ah, "%s: dma failed to stop in 10ms\n" ath_hal_printf(ah, "%s: dma failed to stop in 10ms\n"
"AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n", "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
@@ -82,6 +84,7 @@ ar5212StartPcuReceive(struct ath_hal *ah)
{ {
struct ath_hal_private *ahp = AH_PRIVATE(ah); struct ath_hal_private *ahp = AH_PRIVATE(ah);
OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_PCU_START);
OS_REG_WRITE(ah, AR_DIAG_SW, OS_REG_WRITE(ah, AR_DIAG_SW,
OS_REG_READ(ah, AR_DIAG_SW) &~ AR_DIAG_RX_DIS); OS_REG_READ(ah, AR_DIAG_SW) &~ AR_DIAG_RX_DIS);
ar5212EnableMibCounters(ah); ar5212EnableMibCounters(ah);
@@ -95,6 +98,7 @@ ar5212StartPcuReceive(struct ath_hal *ah)
void void
ar5212StopPcuReceive(struct ath_hal *ah) ar5212StopPcuReceive(struct ath_hal *ah)
{ {
OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_PCU_STOP);
OS_REG_WRITE(ah, AR_DIAG_SW, OS_REG_WRITE(ah, AR_DIAG_SW,
OS_REG_READ(ah, AR_DIAG_SW) | AR_DIAG_RX_DIS); OS_REG_READ(ah, AR_DIAG_SW) | AR_DIAG_RX_DIS);
ar5212DisableMibCounters(ah); ar5212DisableMibCounters(ah);
@@ -199,7 +203,7 @@ ar5212SetRxFilter(struct ath_hal *ah, uint32_t bits)
ahp->ah_miscMode |= AR_MISC_MODE_BSSID_MATCH_FORCE; ahp->ah_miscMode |= AR_MISC_MODE_BSSID_MATCH_FORCE;
else else
ahp->ah_miscMode &= ~AR_MISC_MODE_BSSID_MATCH_FORCE; ahp->ah_miscMode &= ~AR_MISC_MODE_BSSID_MATCH_FORCE;
OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode);
} }
} }
@@ -283,6 +283,14 @@ ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 0); regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 0);
regWrites = write_common(ah, &ahp->ah_ini_common, bChannelChange, regWrites = write_common(ah, &ahp->ah_ini_common, bChannelChange,
regWrites); regWrites);
#ifdef AH_RXCFG_SDMAMW_4BYTES
/*
* Nala doesn't work with 128 byte bursts on pb42(hydra) (ar71xx),
* use 4 instead. Enabling it on all platforms would hurt performance,
* so we only enable it on the ones that are affected by it.
*/
OS_REG_WRITE(ah, AR_RXCFG, 0);
#endif
ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites); ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites);
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
@@ -48,16 +48,19 @@ ar5212UpdateTxTrigLevel(struct ath_hal *ah, HAL_BOOL bIncTrigLevel)
uint32_t txcfg, curLevel, newLevel; uint32_t txcfg, curLevel, newLevel;
HAL_INT omask; HAL_INT omask;
if (ahp->ah_txTrigLev >= ahp->ah_maxTxTrigLev)
return AH_FALSE;
/* /*
* Disable interrupts while futzing with the fifo level. * Disable interrupts while futzing with the fifo level.
*/ */
omask = ar5212SetInterrupts(ah, ahp->ah_maskReg &~ HAL_INT_GLOBAL); omask = ath_hal_setInterrupts(ah, ahp->ah_maskReg &~ HAL_INT_GLOBAL);
txcfg = OS_REG_READ(ah, AR_TXCFG); txcfg = OS_REG_READ(ah, AR_TXCFG);
curLevel = MS(txcfg, AR_FTRIG); curLevel = MS(txcfg, AR_FTRIG);
newLevel = curLevel; newLevel = curLevel;
if (bIncTrigLevel) { /* increase the trigger level */ if (bIncTrigLevel) { /* increase the trigger level */
if (curLevel < MAX_TX_FIFO_THRESHOLD) if (curLevel < ahp->ah_maxTxTrigLev)
newLevel++; newLevel++;
} else if (curLevel > MIN_TX_FIFO_THRESHOLD) } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
newLevel--; newLevel--;
@@ -66,8 +69,10 @@ ar5212UpdateTxTrigLevel(struct ath_hal *ah, HAL_BOOL bIncTrigLevel)
OS_REG_WRITE(ah, AR_TXCFG, OS_REG_WRITE(ah, AR_TXCFG,
(txcfg &~ AR_FTRIG) | SM(newLevel, AR_FTRIG)); (txcfg &~ AR_FTRIG) | SM(newLevel, AR_FTRIG));
ahp->ah_txTrigLev = newLevel;
/* re-enable chip interrupts */ /* re-enable chip interrupts */
ar5212SetInterrupts(ah, omask); ath_hal_setInterrupts(ah, omask);
return (newLevel != curLevel); return (newLevel != curLevel);
} }
@@ -411,9 +416,9 @@ ar5212ResetTxQueue(struct ath_hal *ah, u_int q)
* here solely for backwards compatibility. * here solely for backwards compatibility.
*/ */
value = (ahp->ah_beaconInterval value = (ahp->ah_beaconInterval
- (ath_hal_sw_beacon_response_time - - (ah->ah_config.ah_sw_beacon_response_time -
ath_hal_dma_beacon_response_time) ah->ah_config.ah_dma_beacon_response_time)
- ath_hal_additional_swba_backoff) * 1024; - ah->ah_config.ah_additional_swba_backoff) * 1024;
OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), value | AR_Q_RDYTIMECFG_ENA); OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), value | AR_Q_RDYTIMECFG_ENA);
} }
dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
@@ -913,3 +918,24 @@ ar5212GetTxIntrQueue(struct ath_hal *ah, uint32_t *txqs)
*txqs &= ahp->ah_intrTxqs; *txqs &= ahp->ah_intrTxqs;
ahp->ah_intrTxqs &= ~(*txqs); ahp->ah_intrTxqs &= ~(*txqs);
} }
/*
* Retrieve the rate table from the given TX completion descriptor
*/
HAL_BOOL
ar5212GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries)
{
const struct ar5212_desc *ads = AR5212DESC_CONST(ds0);
rates[0] = MS(ads->ds_ctl3, AR_XmitRate0);
rates[1] = MS(ads->ds_ctl3, AR_XmitRate1);
rates[2] = MS(ads->ds_ctl3, AR_XmitRate2);
rates[3] = MS(ads->ds_ctl3, AR_XmitRate3);
tries[0] = MS(ads->ds_ctl2, AR_XmitDataTries0);
tries[1] = MS(ads->ds_ctl2, AR_XmitDataTries1);
tries[2] = MS(ads->ds_ctl2, AR_XmitDataTries2);
tries[3] = MS(ads->ds_ctl2, AR_XmitDataTries3);
return AH_TRUE;
}
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5212desc.h,v 1.4 2008/11/10 04:08:03 sam Exp $ * $FreeBSD$
*/ */
#ifndef _ATH_AR5212_DESC_H_ #ifndef _ATH_AR5212_DESC_H_
#define _ATH_AR5212_DESC_H_ #define _ATH_AR5212_DESC_H_
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5212phy.h,v 1.7 2008/11/19 21:23:01 sam Exp $ * $FreeBSD$
*/ */
#ifndef _DEV_ATH_AR5212PHY_H_ #ifndef _DEV_ATH_AR5212PHY_H_
#define _DEV_ATH_AR5212PHY_H_ #define _DEV_ATH_AR5212PHY_H_
@@ -300,6 +300,7 @@
#define AR_QUIET1_NEXT_QUIET 0xffff #define AR_QUIET1_NEXT_QUIET 0xffff
#define AR_QUIET1_QUIET_ENABLE 0x10000 /* Enable Quiet time operation */ #define AR_QUIET1_QUIET_ENABLE 0x10000 /* Enable Quiet time operation */
#define AR_QUIET1_QUIET_ACK_CTS_ENABLE 0x20000 /* Do we ack/cts during quiet period */ #define AR_QUIET1_QUIET_ACK_CTS_ENABLE 0x20000 /* Do we ack/cts during quiet period */
#define AR_QUIET1_QUIET_ACK_CTS_ENABLE_S 17
#define AR_QUIET2 0x8100 /* More Quiet time programming */ #define AR_QUIET2 0x8100 /* More Quiet time programming */
#define AR_QUIET2_QUIET_PER_S 0 /* Periodicity of quiet period (TU) */ #define AR_QUIET2_QUIET_PER_S 0 /* Periodicity of quiet period (TU) */
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5311reg.h,v 1.3 2008/10/06 18:32:50 sam Exp $ * $FreeBSD$
*/ */
#ifndef _DEV_ATH_AR5311REG_H_ #ifndef _DEV_ATH_AR5311REG_H_
#define _DEV_ATH_AR5311REG_H_ #define _DEV_ATH_AR5311REG_H_
@@ -61,7 +61,8 @@ ar5312AniSetup(struct ath_hal *ah)
*/ */
static struct ath_hal * static struct ath_hal *
ar5312Attach(uint16_t devid, HAL_SOFTC sc, ar5312Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_STATUS *status)
{ {
struct ath_hal_5212 *ahp = AH_NULL; struct ath_hal_5212 *ahp = AH_NULL;
struct ath_hal *ah; struct ath_hal *ah;
@@ -70,13 +71,13 @@ ar5312Attach(uint16_t devid, HAL_SOFTC sc,
uint16_t eeval; uint16_t eeval;
HAL_STATUS ecode; HAL_STATUS ecode;
HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
__func__, sc, st, (void*) sh); __func__, sc, st, (void*) sh);
/* NB: memory is returned zero'd */ /* NB: memory is returned zero'd */
ahp = ath_hal_malloc(sizeof (struct ath_hal_5212)); ahp = ath_hal_malloc(sizeof (struct ath_hal_5212));
if (ahp == AH_NULL) { if (ahp == AH_NULL) {
HALDEBUG(AH_NULL, HAL_DEBUG_ANY, HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY,
"%s: cannot allocate memory for state block\n", __func__); "%s: cannot allocate memory for state block\n", __func__);
*status = HAL_ENOMEM; *status = HAL_ENOMEM;
return AH_NULL; return AH_NULL;
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5312_eeprom.c,v 1.4 2008/11/10 04:08:04 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5312_interrupts.c,v 1.2 2008/11/10 01:19:39 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5312_misc.c,v 1.4 2008/11/22 07:40:15 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5312_power.c,v 1.4 2008/11/10 04:08:04 sam Exp $ * $FreeBSD$
*/ */
#include "opt_ah.h" #include "opt_ah.h"
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5312phy.h,v 1.3 2008/10/06 18:32:50 sam Exp $ * $FreeBSD$
*/ */
#ifndef _DEV_ATH_AR5312PHY_H_ #ifndef _DEV_ATH_AR5312PHY_H_
#define _DEV_ATH_AR5312PHY_H_ #define _DEV_ATH_AR5312PHY_H_
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $Id: ar5312reg.h,v 1.4 2008/11/10 04:08:04 sam Exp $ * $FreeBSD$
*/ */
#ifndef _DEV_ATH_AR5312REG_H_ #ifndef _DEV_ATH_AR5312REG_H_
#define _DEV_ATH_AR5312REG_H_ #define _DEV_ATH_AR5312REG_H_
@@ -57,6 +57,65 @@ ar2133WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
freqIndex, writes); freqIndex, writes);
} }
/*
* Fix on 2.4 GHz band for orientation sensitivity issue by increasing
* rf_pwd_icsyndiv.
*
* Theoretical Rules:
* if 2 GHz band
* if forceBiasAuto
* if synth_freq < 2412
* bias = 0
* else if 2412 <= synth_freq <= 2422
* bias = 1
* else // synth_freq > 2422
* bias = 2
* else if forceBias > 0
* bias = forceBias & 7
* else
* no change, use value from ini file
* else
* no change, invalid band
*
* 1st Mod:
* 2422 also uses value of 2
* <approved>
*
* 2nd Mod:
* Less than 2412 uses value of 0, 2412 and above uses value of 2
*/
static void
ar2133ForceBias(struct ath_hal *ah, uint16_t synth_freq)
{
uint32_t tmp_reg;
int reg_writes = 0;
uint32_t new_bias = 0;
struct ar2133State *priv = AR2133(ah);
/* XXX this is a bit of a silly check for 2.4ghz channels -adrian */
if (synth_freq >= 3000)
return;
if (synth_freq < 2412)
new_bias = 0;
else if (synth_freq < 2422)
new_bias = 1;
else
new_bias = 2;
/* pre-reverse this field */
tmp_reg = ath_hal_reverseBits(new_bias, 3);
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: Force rf_pwd_icsyndiv to %1d on %4d\n",
__func__, new_bias, synth_freq);
/* swizzle rf_pwd_icsyndiv */
ar5416ModifyRfBuffer(priv->Bank6Data, tmp_reg, 3, 181, 3);
/* write Bank 6 with new params */
ath_hal_ini_bank_write(ah, &AH5416(ah)->ah_ini_bank6, priv->Bank6Data, reg_writes);
}
/* /*
* Take the MHz channel value and set the Channel value * Take the MHz channel value and set the Channel value
* *
@@ -106,13 +165,13 @@ ar2133SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
} }
} else if ((freq % 20) == 0 && freq >= 5120) { } else if ((freq % 20) == 0 && freq >= 5120) {
channelSel = ath_hal_reverseBits(((freq - 4800) / 20 << 2), 8); channelSel = ath_hal_reverseBits(((freq - 4800) / 20 << 2), 8);
if (AR_SREV_SOWL_10_OR_LATER(ah)) if (AR_SREV_HOWL(ah) || AR_SREV_SOWL_10_OR_LATER(ah))
aModeRefSel = ath_hal_reverseBits(3, 2); aModeRefSel = ath_hal_reverseBits(3, 2);
else else
aModeRefSel = ath_hal_reverseBits(1, 2); aModeRefSel = ath_hal_reverseBits(1, 2);
} else if ((freq % 10) == 0) { } else if ((freq % 10) == 0) {
channelSel = ath_hal_reverseBits(((freq - 4800) / 10 << 1), 8); channelSel = ath_hal_reverseBits(((freq - 4800) / 10 << 1), 8);
if (AR_SREV_SOWL_10_OR_LATER(ah)) if (AR_SREV_HOWL(ah) || AR_SREV_SOWL_10_OR_LATER(ah))
aModeRefSel = ath_hal_reverseBits(2, 2); aModeRefSel = ath_hal_reverseBits(2, 2);
else else
aModeRefSel = ath_hal_reverseBits(1, 2); aModeRefSel = ath_hal_reverseBits(1, 2);
@@ -125,6 +184,10 @@ ar2133SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
return AH_FALSE; return AH_FALSE;
} }
/* Workaround for hw bug - AR5416 specific */
if (AR_SREV_OWL(ah) && ah->ah_config.ah_ar5416_biasadj)
ar2133ForceBias(ah, freq);
reg32 = (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) | reg32 = (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
(1 << 5) | 0x1; (1 << 5) | 0x1;
@@ -188,11 +251,19 @@ ar2133SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan,
/* Only the 5 or 2 GHz OB/DB need to be set for a mode */ /* Only the 5 or 2 GHz OB/DB need to be set for a mode */
if (IEEE80211_IS_CHAN_2GHZ(chan)) { if (IEEE80211_IS_CHAN_2GHZ(chan)) {
HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: 2ghz: OB_2:%d, DB_2:%d\n",
__func__,
ath_hal_eepromGet(ah, AR_EEP_OB_2, AH_NULL),
ath_hal_eepromGet(ah, AR_EEP_DB_2, AH_NULL));
ar5416ModifyRfBuffer(priv->Bank6Data, ar5416ModifyRfBuffer(priv->Bank6Data,
ath_hal_eepromGet(ah, AR_EEP_OB_2, AH_NULL), 3, 197, 0); ath_hal_eepromGet(ah, AR_EEP_OB_2, AH_NULL), 3, 197, 0);
ar5416ModifyRfBuffer(priv->Bank6Data, ar5416ModifyRfBuffer(priv->Bank6Data,
ath_hal_eepromGet(ah, AR_EEP_DB_2, AH_NULL), 3, 194, 0); ath_hal_eepromGet(ah, AR_EEP_DB_2, AH_NULL), 3, 194, 0);
} else { } else {
HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: 5ghz: OB_5:%d, DB_5:%d\n",
__func__,
ath_hal_eepromGet(ah, AR_EEP_OB_5, AH_NULL),
ath_hal_eepromGet(ah, AR_EEP_DB_5, AH_NULL));
ar5416ModifyRfBuffer(priv->Bank6Data, ar5416ModifyRfBuffer(priv->Bank6Data,
ath_hal_eepromGet(ah, AR_EEP_OB_5, AH_NULL), 3, 203, 0); ath_hal_eepromGet(ah, AR_EEP_OB_5, AH_NULL), 3, 203, 0);
ar5416ModifyRfBuffer(priv->Bank6Data, ar5416ModifyRfBuffer(priv->Bank6Data,
@@ -323,12 +394,29 @@ ar2133GetChannelMaxMinPower(struct ath_hal *ah,
#endif #endif
} }
/*
* The ordering of nfarray is thus:
*
* nfarray[0]: Chain 0 ctl
* nfarray[1]: Chain 1 ctl
* nfarray[2]: Chain 2 ctl
* nfarray[3]: Chain 0 ext
* nfarray[4]: Chain 1 ext
* nfarray[5]: Chain 2 ext
*/
static void static void
ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[]) ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[])
{ {
struct ath_hal_5416 *ahp = AH5416(ah); struct ath_hal_5416 *ahp = AH5416(ah);
int16_t nf; int16_t nf;
/*
* Blank nf array - some chips may only
* have one or two RX chainmasks enabled.
*/
nfarray[0] = nfarray[1] = nfarray[2] = 0;
nfarray[3] = nfarray[4] = nfarray[5] = 0;
switch (ahp->ah_rx_chainmask) { switch (ahp->ah_rx_chainmask) {
case 0x7: case 0x7:
nf = MS(OS_REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR); nf = MS(OS_REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
@@ -336,7 +424,7 @@ ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[])
nf = 0 - ((nf ^ 0x1ff) + 1); nf = 0 - ((nf ^ 0x1ff) + 1);
HALDEBUG(ah, HAL_DEBUG_NFCAL, HALDEBUG(ah, HAL_DEBUG_NFCAL,
"NF calibrated [ctl] [chain 2] is %d\n", nf); "NF calibrated [ctl] [chain 2] is %d\n", nf);
nfarray[4] = nf; nfarray[2] = nf;
nf = MS(OS_REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR); nf = MS(OS_REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR);
if (nf & 0x100) if (nf & 0x100)
@@ -352,7 +440,7 @@ ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[])
nf = 0 - ((nf ^ 0x1ff) + 1); nf = 0 - ((nf ^ 0x1ff) + 1);
HALDEBUG(ah, HAL_DEBUG_NFCAL, HALDEBUG(ah, HAL_DEBUG_NFCAL,
"NF calibrated [ctl] [chain 1] is %d\n", nf); "NF calibrated [ctl] [chain 1] is %d\n", nf);
nfarray[2] = nf; nfarray[1] = nf;
nf = MS(OS_REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR); nf = MS(OS_REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR);
@@ -360,7 +448,7 @@ ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[])
nf = 0 - ((nf ^ 0x1ff) + 1); nf = 0 - ((nf ^ 0x1ff) + 1);
HALDEBUG(ah, HAL_DEBUG_NFCAL, HALDEBUG(ah, HAL_DEBUG_NFCAL,
"NF calibrated [ext] [chain 1] is %d\n", nf); "NF calibrated [ext] [chain 1] is %d\n", nf);
nfarray[3] = nf; nfarray[4] = nf;
/* fall thru... */ /* fall thru... */
case 0x1: case 0x1:
nf = MS(OS_REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); nf = MS(OS_REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
@@ -375,7 +463,7 @@ ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[])
nf = 0 - ((nf ^ 0x1ff) + 1); nf = 0 - ((nf ^ 0x1ff) + 1);
HALDEBUG(ah, HAL_DEBUG_NFCAL, HALDEBUG(ah, HAL_DEBUG_NFCAL,
"NF calibrated [ext] [chain 0] is %d\n", nf); "NF calibrated [ext] [chain 0] is %d\n", nf);
nfarray[1] = nf; nfarray[3] = nf;
break; break;
} }
@@ -37,6 +37,19 @@ typedef struct {
uint16_t ext_center; uint16_t ext_center;
} CHAN_CENTERS; } CHAN_CENTERS;
typedef enum Ar5416_Rates {
rate6mb, rate9mb, rate12mb, rate18mb,
rate24mb, rate36mb, rate48mb, rate54mb,
rate1l, rate2l, rate2s, rate5_5l,
rate5_5s, rate11l, rate11s, rateXr,
rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
Ar5416RateSize
} AR5416_RATES;
#define AR5416_DEFAULT_RXCHAINMASK 7 #define AR5416_DEFAULT_RXCHAINMASK 7
#define AR5416_DEFAULT_TXCHAINMASK 1 #define AR5416_DEFAULT_TXCHAINMASK 1
#define AR5416_MAX_RATE_POWER 63 #define AR5416_MAX_RATE_POWER 63
@@ -49,6 +62,12 @@ typedef struct {
#define AR5416_SPUR_RSSI_THRESH 40 #define AR5416_SPUR_RSSI_THRESH 40
struct ar5416NfLimits {
int16_t max;
int16_t min;
int16_t nominal;
};
struct ath_hal_5416 { struct ath_hal_5416 {
struct ath_hal_5212 ah_5212; struct ath_hal_5212 ah_5212;
@@ -68,6 +87,26 @@ struct ath_hal_5416 {
void (*ah_spurMitigate)(struct ath_hal *, void (*ah_spurMitigate)(struct ath_hal *,
const struct ieee80211_channel *); const struct ieee80211_channel *);
/* calibration ops */
HAL_BOOL (*ah_cal_initcal)(struct ath_hal *,
const struct ieee80211_channel *);
void (*ah_cal_pacal)(struct ath_hal *,
HAL_BOOL is_reset);
/* optional open-loop tx power control related methods */
void (*ah_olcInit)(struct ath_hal *);
void (*ah_olcTempCompensation)(struct ath_hal *);
/* tx power control */
HAL_BOOL (*ah_setPowerCalTable) (struct ath_hal *ah,
struct ar5416eeprom *pEepData,
const struct ieee80211_channel *chan,
int16_t *pTxPowerIndexOffset);
/* baseband operations */
void (*ah_initPLL) (struct ath_hal *ah,
const struct ieee80211_channel *chan);
u_int ah_globaltxtimeout; /* global tx timeout */ u_int ah_globaltxtimeout; /* global tx timeout */
u_int ah_gpioMask; u_int ah_gpioMask;
int ah_hangs; /* h/w hangs state */ int ah_hangs; /* h/w hangs state */
@@ -81,7 +120,16 @@ struct ath_hal_5416 {
uint32_t ah_rx_chainmask; uint32_t ah_rx_chainmask;
uint32_t ah_tx_chainmask; uint32_t ah_tx_chainmask;
HAL_ANI_CMD ah_ani_function;
struct ar5416PerCal ah_cal; /* periodic calibration state */ struct ar5416PerCal ah_cal; /* periodic calibration state */
struct ar5416NfLimits nf_2g;
struct ar5416NfLimits nf_5g;
int initPDADC;
int ah_need_an_top2_fixup; /* merlin or later chips that may need this workaround */
}; };
#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah)) #define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
@@ -102,10 +150,6 @@ extern void ar5416Detach(struct ath_hal *ah);
extern void ar5416AttachPCIE(struct ath_hal *ah); extern void ar5416AttachPCIE(struct ath_hal *ah);
extern HAL_BOOL ar5416FillCapabilityInfo(struct ath_hal *ah); extern HAL_BOOL ar5416FillCapabilityInfo(struct ath_hal *ah);
#define IS_5GHZ_FAST_CLOCK_EN(_ah, _c) \
(IEEE80211_IS_CHAN_5GHZ(_c) && \
ath_hal_eepromGetFlag(ah, AR_EEP_FSTCLK_5G))
extern void ar5416AniAttach(struct ath_hal *, const struct ar5212AniParams *, extern void ar5416AniAttach(struct ath_hal *, const struct ar5212AniParams *,
const struct ar5212AniParams *, HAL_BOOL ena); const struct ar5212AniParams *, HAL_BOOL ena);
extern void ar5416AniDetach(struct ath_hal *); extern void ar5416AniDetach(struct ath_hal *);
@@ -113,8 +157,9 @@ extern HAL_BOOL ar5416AniControl(struct ath_hal *, HAL_ANI_CMD cmd, int param);
extern HAL_BOOL ar5416AniSetParams(struct ath_hal *, extern HAL_BOOL ar5416AniSetParams(struct ath_hal *,
const struct ar5212AniParams *, const struct ar5212AniParams *); const struct ar5212AniParams *, const struct ar5212AniParams *);
extern void ar5416ProcessMibIntr(struct ath_hal *, const HAL_NODE_STATS *); extern void ar5416ProcessMibIntr(struct ath_hal *, const HAL_NODE_STATS *);
extern void ar5416AniPoll(struct ath_hal *, const HAL_NODE_STATS *, extern void ar5416RxMonitor(struct ath_hal *, const HAL_NODE_STATS *,
const struct ieee80211_channel *); const struct ieee80211_channel *);
extern void ar5416AniPoll(struct ath_hal *, const struct ieee80211_channel *);
extern void ar5416AniReset(struct ath_hal *, const struct ieee80211_channel *, extern void ar5416AniReset(struct ath_hal *, const struct ieee80211_channel *,
HAL_OPMODE, int); HAL_OPMODE, int);
@@ -124,6 +169,7 @@ extern void ar5416BeaconInit(struct ath_hal *ah,
extern void ar5416ResetStaBeaconTimers(struct ath_hal *ah); extern void ar5416ResetStaBeaconTimers(struct ath_hal *ah);
extern void ar5416SetStaBeaconTimers(struct ath_hal *ah, extern void ar5416SetStaBeaconTimers(struct ath_hal *ah,
const HAL_BEACON_STATE *); const HAL_BEACON_STATE *);
extern uint64_t ar5416GetNextTBTT(struct ath_hal *);
extern HAL_BOOL ar5416EepromRead(struct ath_hal *, u_int off, uint16_t *data); extern HAL_BOOL ar5416EepromRead(struct ath_hal *, u_int off, uint16_t *data);
extern HAL_BOOL ar5416EepromWrite(struct ath_hal *, u_int off, uint16_t data); extern HAL_BOOL ar5416EepromWrite(struct ath_hal *, u_int off, uint16_t data);
@@ -141,6 +187,8 @@ extern void ar5416GpioSetIntr(struct ath_hal *ah, u_int, uint32_t ilevel);
extern u_int ar5416GetWirelessModes(struct ath_hal *ah); extern u_int ar5416GetWirelessModes(struct ath_hal *ah);
extern void ar5416SetLedState(struct ath_hal *ah, HAL_LED_STATE state); extern void ar5416SetLedState(struct ath_hal *ah, HAL_LED_STATE state);
extern uint64_t ar5416GetTsf64(struct ath_hal *ah);
extern void ar5416SetTsf64(struct ath_hal *ah, uint64_t tsf64);
extern void ar5416ResetTsf(struct ath_hal *ah); extern void ar5416ResetTsf(struct ath_hal *ah);
extern HAL_BOOL ar5416SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING); extern HAL_BOOL ar5416SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING);
extern HAL_BOOL ar5416SetDecompMask(struct ath_hal *, uint16_t, int); extern HAL_BOOL ar5416SetDecompMask(struct ath_hal *, uint16_t, int);
@@ -149,11 +197,21 @@ extern uint32_t ar5416Get11nExtBusy(struct ath_hal *ah);
extern void ar5416Set11nMac2040(struct ath_hal *ah, HAL_HT_MACMODE mode); extern void ar5416Set11nMac2040(struct ath_hal *ah, HAL_HT_MACMODE mode);
extern HAL_HT_RXCLEAR ar5416Get11nRxClear(struct ath_hal *ah); extern HAL_HT_RXCLEAR ar5416Get11nRxClear(struct ath_hal *ah);
extern void ar5416Set11nRxClear(struct ath_hal *ah, HAL_HT_RXCLEAR rxclear); extern void ar5416Set11nRxClear(struct ath_hal *ah, HAL_HT_RXCLEAR rxclear);
extern HAL_STATUS ar5416SetQuiet(struct ath_hal *ah, uint32_t period,
uint32_t duration, uint32_t nextStart, HAL_QUIET_FLAG flag);
extern HAL_STATUS ar5416GetCapability(struct ath_hal *ah, extern HAL_STATUS ar5416GetCapability(struct ath_hal *ah,
HAL_CAPABILITY_TYPE type, uint32_t capability, uint32_t *result); HAL_CAPABILITY_TYPE type, uint32_t capability, uint32_t *result);
extern HAL_BOOL ar5416GetDiagState(struct ath_hal *ah, int request, extern HAL_BOOL ar5416GetDiagState(struct ath_hal *ah, int request,
const void *args, uint32_t argsize, const void *args, uint32_t argsize,
void **result, uint32_t *resultsize); void **result, uint32_t *resultsize);
extern HAL_BOOL ar5416SetRifsDelay(struct ath_hal *ah,
const struct ieee80211_channel *chan, HAL_BOOL enable);
extern void ar5416EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe);
extern void ar5416GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe);
extern HAL_BOOL ar5416ProcessRadarEvent(struct ath_hal *ah,
struct ath_rx_status *rxs, uint64_t fulltsf, const char *buf,
HAL_DFS_EVENT *event);
extern HAL_BOOL ar5416IsFastClockEnabled(struct ath_hal *ah);
extern HAL_BOOL ar5416SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, extern HAL_BOOL ar5416SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode,
int setChip); int setChip);
@@ -164,6 +222,8 @@ extern HAL_BOOL ar5416ResetKeyCacheEntry(struct ath_hal *ah, uint16_t entry);
extern HAL_BOOL ar5416SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry, extern HAL_BOOL ar5416SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry,
const HAL_KEYVAL *k, const uint8_t *mac, int xorKey); const HAL_KEYVAL *k, const uint8_t *mac, int xorKey);
extern uint32_t ar5416GetRxFilter(struct ath_hal *ah);
extern void ar5416SetRxFilter(struct ath_hal *ah, uint32_t bits);
extern void ar5416StartPcuReceive(struct ath_hal *ah); extern void ar5416StartPcuReceive(struct ath_hal *ah);
extern void ar5416StopPcuReceive(struct ath_hal *ah); extern void ar5416StopPcuReceive(struct ath_hal *ah);
extern HAL_BOOL ar5416SetupRxDesc(struct ath_hal *, extern HAL_BOOL ar5416SetupRxDesc(struct ath_hal *,
@@ -180,6 +240,7 @@ extern HAL_RFGAIN ar5416GetRfgain(struct ath_hal *ah);
extern HAL_BOOL ar5416Disable(struct ath_hal *ah); extern HAL_BOOL ar5416Disable(struct ath_hal *ah);
extern HAL_BOOL ar5416ChipReset(struct ath_hal *ah, extern HAL_BOOL ar5416ChipReset(struct ath_hal *ah,
const struct ieee80211_channel *); const struct ieee80211_channel *);
extern int ar5416GetRegChainOffset(struct ath_hal *ah, int i);
extern HAL_BOOL ar5416SetBoardValues(struct ath_hal *, extern HAL_BOOL ar5416SetBoardValues(struct ath_hal *,
const struct ieee80211_channel *); const struct ieee80211_channel *);
extern HAL_BOOL ar5416SetResetReg(struct ath_hal *, uint32_t type); extern HAL_BOOL ar5416SetResetReg(struct ath_hal *, uint32_t type);
@@ -190,6 +251,15 @@ extern HAL_BOOL ar5416GetChipPowerLimits(struct ath_hal *ah,
struct ieee80211_channel *chan); struct ieee80211_channel *chan);
extern void ar5416GetChannelCenters(struct ath_hal *, extern void ar5416GetChannelCenters(struct ath_hal *,
const struct ieee80211_channel *chan, CHAN_CENTERS *centers); const struct ieee80211_channel *chan, CHAN_CENTERS *centers);
extern void ar5416SetRatesArrayFromTargetPower(struct ath_hal *ah,
const struct ieee80211_channel *chan,
int16_t *ratesArray,
const CAL_TARGET_POWER_LEG *targetPowerCck,
const CAL_TARGET_POWER_LEG *targetPowerCckExt,
const CAL_TARGET_POWER_LEG *targetPowerOfdm,
const CAL_TARGET_POWER_LEG *targetPowerOfdmExt,
const CAL_TARGET_POWER_HT *targetPowerHt20,
const CAL_TARGET_POWER_HT *targetPowerHt40);
extern void ar5416GetTargetPowers(struct ath_hal *ah, extern void ar5416GetTargetPowers(struct ath_hal *ah,
const struct ieee80211_channel *chan, const struct ieee80211_channel *chan,
CAL_TARGET_POWER_HT *powInfo, CAL_TARGET_POWER_HT *powInfo,
@@ -200,7 +270,36 @@ extern void ar5416GetTargetPowersLeg(struct ath_hal *ah,
CAL_TARGET_POWER_LEG *powInfo, CAL_TARGET_POWER_LEG *powInfo,
uint16_t numChannels, CAL_TARGET_POWER_LEG *pNewPower, uint16_t numChannels, CAL_TARGET_POWER_LEG *pNewPower,
uint16_t numRates, HAL_BOOL isExtTarget); uint16_t numRates, HAL_BOOL isExtTarget);
extern void ar5416InitChainMasks(struct ath_hal *ah);
extern void ar5416RestoreChainMask(struct ath_hal *ah);
extern void ar5416EepromSetAddac(struct ath_hal *ah,
const struct ieee80211_channel *chan);
extern uint16_t ar5416GetMaxEdgePower(uint16_t freq,
CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz);
extern void ar5416InitPLL(struct ath_hal *ah,
const struct ieee80211_channel *chan);
/* TX power setup related routines in ar5416_reset.c */
extern void ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,
const struct ieee80211_channel *chan, CAL_DATA_PER_FREQ *pRawDataSet,
uint8_t * bChans, uint16_t availPiers,
uint16_t tPdGainOverlap, int16_t *pMinCalPower,
uint16_t * pPdGainBoundaries, uint8_t * pPDADCValues,
uint16_t numXpdGains);
extern void ar5416SetGainBoundariesClosedLoop(struct ath_hal *ah,
int i, uint16_t pdGainOverlap_t2,
uint16_t gainBoundaries[]);
extern uint16_t ar5416GetXpdGainValues(struct ath_hal *ah, uint16_t xpdMask,
uint16_t xpdGainValues[]);
extern void ar5416WriteDetectorGainBiases(struct ath_hal *ah,
uint16_t numXpdGain, uint16_t xpdGainValues[]);
extern void ar5416WritePdadcValues(struct ath_hal *ah, int i,
uint8_t pdadcValues[]);
extern HAL_BOOL ar5416SetPowerCalTable(struct ath_hal *ah,
struct ar5416eeprom *pEepData, const struct ieee80211_channel *chan,
int16_t *pTxPowerIndexOffset);
extern void ar5416WriteTxPowerRateRegisters(struct ath_hal *ah,
const struct ieee80211_channel *chan, const int16_t ratesArray[]);
extern HAL_BOOL ar5416StopTxDma(struct ath_hal *ah, u_int q); extern HAL_BOOL ar5416StopTxDma(struct ath_hal *ah, u_int q);
extern HAL_BOOL ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds, extern HAL_BOOL ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
@@ -218,6 +317,30 @@ extern HAL_BOOL ar5416FillTxDesc(struct ath_hal *ah, struct ath_desc *ds,
const struct ath_desc *ds0); const struct ath_desc *ds0);
extern HAL_STATUS ar5416ProcTxDesc(struct ath_hal *ah, extern HAL_STATUS ar5416ProcTxDesc(struct ath_hal *ah,
struct ath_desc *, struct ath_tx_status *); struct ath_desc *, struct ath_tx_status *);
extern HAL_BOOL ar5416GetTxCompletionRates(struct ath_hal *ah,
const struct ath_desc *ds0, int *rates, int *tries);
extern HAL_BOOL ar5416ResetTxQueue(struct ath_hal *ah, u_int q);
extern int ar5416SetupTxQueue(struct ath_hal *ah, HAL_TX_QUEUE type,
const HAL_TXQ_INFO *qInfo);
extern HAL_BOOL ar5416ChainTxDesc(struct ath_hal *ah, struct ath_desc *ds,
u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int keyIx,
HAL_CIPHER cipher, uint8_t delims, u_int segLen, HAL_BOOL firstSeg,
HAL_BOOL lastSeg);
extern HAL_BOOL ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds,
u_int aggrLen, u_int flags, u_int txPower, u_int txRate0, u_int txTries0,
u_int antMode, u_int rtsctsRate, u_int rtsctsDuration);
extern HAL_BOOL ar5416SetupLastTxDesc(struct ath_hal *ah, struct ath_desc *ds,
const struct ath_desc *ds0);
extern HAL_BOOL ar5416SetGlobalTxTimeout(struct ath_hal *ah, u_int tu);
extern u_int ar5416GetGlobalTxTimeout(struct ath_hal *ah);
extern void ar5416Set11nRateScenario(struct ath_hal *ah, struct ath_desc *ds,
u_int durUpdateEn, u_int rtsctsRate, HAL_11N_RATE_SERIES series[],
u_int nseries, u_int flags);
extern void ar5416Set11nAggrMiddle(struct ath_hal *ah, struct ath_desc *ds, u_int numDelims);
extern void ar5416Clr11nAggr(struct ath_hal *ah, struct ath_desc *ds);
extern void ar5416Set11nBurstDuration(struct ath_hal *ah, struct ath_desc *ds, u_int burstDuration);
extern const HAL_RATE_TABLE *ar5416GetRateTable(struct ath_hal *, u_int mode); extern const HAL_RATE_TABLE *ar5416GetRateTable(struct ath_hal *, u_int mode);
#endif /* _ATH_AR5416_H_ */ #endif /* _ATH_AR5416_H_ */
@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc. * Copyright (c) 2008-2009 Atheros Communications Inc.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -24,29 +24,31 @@ static const uint32_t ar5416Modes[][6] = {
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
{ 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
{ 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801080, 0x08400840, 0x06e006e0 }, { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
{ 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf }, { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
{ 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
{ 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
{ 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
{ 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
{ 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
{ 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
{ 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
{ 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
{ 0x00009844, 0x1372161e, 0x13721c1e, 0x13721c30, 0x137216a4, 0x13721c25 }, { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
{ 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
{ 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
{ 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
{ 0x00009850, 0x6c28b4e0, 0x6c28b4e0, 0x6d68b0de, 0x6d68b0de, 0x6c28b0de }, { 0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de },
{ 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e }, { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
{ 0x0000985c, 0x313a5d5e, 0x313a5d5e, 0x313a605e, 0x313a605e, 0x313a5d5e }, { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e },
{ 0x00009860, 0x00049d10, 0x00049d10, 0x00049d20, 0x00049d20, 0x00049d10 }, { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
{ 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
{ 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 }, { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
{ 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 }, { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
{ 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 }, { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
{ 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000370 }, { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 },
{ 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a19, 0xd0058a13, 0xd0058a0b }, { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b },
{ 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 }, { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
#ifdef TB243 #ifdef TB243
{ 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
{ 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
@@ -63,14 +65,16 @@ static const uint32_t ar5416Modes[][6] = {
#endif #endif
#endif #endif
{ 0x0000c9bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 }, { 0x0000c9bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
{ 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
{ 0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
{ 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be }, { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
{ 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c }, { 0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c },
{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x0000a204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, 0x00000440 }, { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
{ 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 }, { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
{ 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
{ 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
@@ -219,7 +223,6 @@ static const uint32_t ar5416Common[][2] = {
{ 0x00008110, 0x00000168 }, { 0x00008110, 0x00000168 },
{ 0x00008118, 0x000100aa }, { 0x00008118, 0x000100aa },
{ 0x0000811c, 0x00003210 }, { 0x0000811c, 0x00003210 },
{ 0x00008120, 0x08f04800 },
{ 0x00008124, 0x00000000 }, { 0x00008124, 0x00000000 },
{ 0x00008128, 0x00000000 }, { 0x00008128, 0x00000000 },
{ 0x0000812c, 0x00000000 }, { 0x0000812c, 0x00000000 },
@@ -227,7 +230,7 @@ static const uint32_t ar5416Common[][2] = {
{ 0x00008134, 0x00000000 }, { 0x00008134, 0x00000000 },
{ 0x00008138, 0x00000000 }, { 0x00008138, 0x00000000 },
{ 0x0000813c, 0x00000000 }, { 0x0000813c, 0x00000000 },
{ 0x00008144, 0x00000000 }, { 0x00008144, 0xffffffff },
{ 0x00008168, 0x00000000 }, { 0x00008168, 0x00000000 },
{ 0x0000816c, 0x00000000 }, { 0x0000816c, 0x00000000 },
{ 0x00008170, 0x32143320 }, { 0x00008170, 0x32143320 },
@@ -235,7 +238,6 @@ static const uint32_t ar5416Common[][2] = {
{ 0x00008178, 0x00000100 }, { 0x00008178, 0x00000100 },
{ 0x0000817c, 0x00000000 }, { 0x0000817c, 0x00000000 },
{ 0x000081c4, 0x00000000 }, { 0x000081c4, 0x00000000 },
{ 0x000081d0, 0x00003210 },
{ 0x000081ec, 0x00000000 }, { 0x000081ec, 0x00000000 },
{ 0x000081f0, 0x00000000 }, { 0x000081f0, 0x00000000 },
{ 0x000081f4, 0x00000000 }, { 0x000081f4, 0x00000000 },
@@ -266,6 +268,7 @@ static const uint32_t ar5416Common[][2] = {
{ 0x00008258, 0x00000000 }, { 0x00008258, 0x00000000 },
{ 0x0000825c, 0x400000ff }, { 0x0000825c, 0x400000ff },
{ 0x00008260, 0x00080922 }, { 0x00008260, 0x00080922 },
{ 0x00008264, 0xa8000010 },
{ 0x00008270, 0x00000000 }, { 0x00008270, 0x00000000 },
{ 0x00008274, 0x40000000 }, { 0x00008274, 0x40000000 },
{ 0x00008278, 0x003e4180 }, { 0x00008278, 0x003e4180 },
@@ -286,7 +289,7 @@ static const uint32_t ar5416Common[][2] = {
{ 0x0000832c, 0x00000007 }, { 0x0000832c, 0x00000007 },
{ 0x00008330, 0x00000302 }, { 0x00008330, 0x00000302 },
{ 0x00008334, 0x00000e00 }, { 0x00008334, 0x00000e00 },
{ 0x00008338, 0x00000000 }, { 0x00008338, 0x00070000 },
{ 0x0000833c, 0x00000000 }, { 0x0000833c, 0x00000000 },
{ 0x00008340, 0x000107ff }, { 0x00008340, 0x000107ff },
{ 0x00009808, 0x00000000 }, { 0x00009808, 0x00000000 },
@@ -297,7 +300,7 @@ static const uint32_t ar5416Common[][2] = {
{ 0x0000982c, 0x0000a000 }, { 0x0000982c, 0x0000a000 },
{ 0x00009830, 0x00000000 }, { 0x00009830, 0x00000000 },
{ 0x0000983c, 0x00200400 }, { 0x0000983c, 0x00200400 },
{ 0x00009840, 0x206a016e }, { 0x00009840, 0x206a002e },
{ 0x0000984c, 0x1284233c }, { 0x0000984c, 0x1284233c },
{ 0x00009854, 0x00000859 }, { 0x00009854, 0x00000859 },
{ 0x00009900, 0x00000000 }, { 0x00009900, 0x00000000 },
@@ -319,7 +322,7 @@ static const uint32_t ar5416Common[][2] = {
{ 0x00009958, 0x00081fff }, { 0x00009958, 0x00081fff },
{ 0x0000c95c, 0x004b6a8e }, { 0x0000c95c, 0x004b6a8e },
{ 0x0000c968, 0x000003ce }, { 0x0000c968, 0x000003ce },
{ 0x00009970, 0x190c0514 }, { 0x00009970, 0x190fb515 },
{ 0x00009974, 0x00000000 }, { 0x00009974, 0x00000000 },
{ 0x00009978, 0x00000001 }, { 0x00009978, 0x00000001 },
{ 0x0000997c, 0x00000000 }, { 0x0000997c, 0x00000000 },
@@ -334,7 +337,7 @@ static const uint32_t ar5416Common[][2] = {
{ 0x000099a0, 0x00000000 }, { 0x000099a0, 0x00000000 },
{ 0x000099a4, 0x00000001 }, { 0x000099a4, 0x00000001 },
{ 0x000099a8, 0x001fff00 }, { 0x000099a8, 0x001fff00 },
{ 0x000099ac, 0x000000c4 }, { 0x000099ac, 0x00000000 },
{ 0x000099b0, 0x03051000 }, { 0x000099b0, 0x03051000 },
{ 0x000099dc, 0x00000000 }, { 0x000099dc, 0x00000000 },
{ 0x000099e0, 0x00000200 }, { 0x000099e0, 0x00000200 },
@@ -426,9 +429,9 @@ static const uint32_t ar5416Common[][2] = {
{ 0x0000a25c, 0x0f0f0f01 }, { 0x0000a25c, 0x0f0f0f01 },
{ 0x0000a260, 0xdfa91f01 }, { 0x0000a260, 0xdfa91f01 },
{ 0x0000a268, 0x00000000 }, { 0x0000a268, 0x00000000 },
{ 0x0000a26c, 0x0ebae9c6 }, { 0x0000a26c, 0x0e79e5c6 },
{ 0x0000b26c, 0x0ebae9c6 }, { 0x0000b26c, 0x0e79e5c6 },
{ 0x0000c26c, 0x0ebae9c6 }, { 0x0000c26c, 0x0e79e5c6 },
{ 0x0000d270, 0x00820820 }, { 0x0000d270, 0x00820820 },
{ 0x0000a278, 0x1ce739ce }, { 0x0000a278, 0x1ce739ce },
{ 0x0000a27c, 0x051701ce }, { 0x0000a27c, 0x051701ce },
@@ -441,15 +444,15 @@ static const uint32_t ar5416Common[][2] = {
{ 0x0000a350, 0x3fffffff }, { 0x0000a350, 0x3fffffff },
{ 0x0000a354, 0x0003ffff }, { 0x0000a354, 0x0003ffff },
{ 0x0000a358, 0x79a8aa1f }, { 0x0000a358, 0x79a8aa1f },
{ 0x0000d35c, 0x066c420f }, { 0x0000d35c, 0x07ffffef },
{ 0x0000d360, 0x0f282207 }, { 0x0000d360, 0x0fffffe7 },
{ 0x0000d364, 0x17601685 }, { 0x0000d364, 0x17ffffe5 },
{ 0x0000d368, 0x1f801104 }, { 0x0000d368, 0x1fffffe4 },
{ 0x0000d36c, 0x37a00c03 }, { 0x0000d36c, 0x37ffffe3 },
{ 0x0000d370, 0x3fc40883 }, { 0x0000d370, 0x3fffffe3 },
{ 0x0000d374, 0x57c00803 }, { 0x0000d374, 0x57ffffe3 },
{ 0x0000d378, 0x5fd80682 }, { 0x0000d378, 0x5fffffe2 },
{ 0x0000d37c, 0x7fe00482 }, { 0x0000d37c, 0x7fffffe2 },
{ 0x0000d380, 0x7f3c7bba }, { 0x0000d380, 0x7f3c7bba },
{ 0x0000d384, 0xf3307ff0 }, { 0x0000d384, 0xf3307ff0 },
{ 0x0000a388, 0x08000000 }, { 0x0000a388, 0x08000000 },
@@ -625,8 +628,8 @@ static const uint32_t ar5416Bank6[][3] = {
{ 0x0000989c, 0x00dc0000, 0x00dc0000 }, { 0x0000989c, 0x00dc0000, 0x00dc0000 },
{ 0x0000989c, 0x00110000, 0x00110000 }, { 0x0000989c, 0x00110000, 0x00110000 },
{ 0x0000989c, 0x006100a8, 0x006100a8 }, { 0x0000989c, 0x006100a8, 0x006100a8 },
{ 0x0000989c, 0x00421022, 0x00421022 }, { 0x0000989c, 0x00423022, 0x00423022 },
{ 0x0000989c, 0x001400df, 0x001400df }, { 0x0000989c, 0x201400df, 0x201400df },
{ 0x0000989c, 0x00c40002, 0x00c40002 }, { 0x0000989c, 0x00c40002, 0x00c40002 },
{ 0x0000989c, 0x003000f2, 0x003000f2 }, { 0x0000989c, 0x003000f2, 0x003000f2 },
{ 0x0000989c, 0x00440016, 0x00440016 }, { 0x0000989c, 0x00440016, 0x00440016 },
@@ -634,7 +637,7 @@ static const uint32_t ar5416Bank6[][3] = {
{ 0x0000989c, 0x0001805e, 0x0001805e }, { 0x0000989c, 0x0001805e, 0x0001805e },
{ 0x0000989c, 0x0000c0ab, 0x0000c0ab }, { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
{ 0x0000989c, 0x000000e1, 0x000000e1 }, { 0x0000989c, 0x000000e1, 0x000000e1 },
{ 0x0000989c, 0x00002081, 0x00002081 }, { 0x0000989c, 0x00007081, 0x00007081 },
{ 0x0000989c, 0x000000d4, 0x000000d4 }, { 0x0000989c, 0x000000d4, 0x000000d4 },
{ 0x000098d0, 0x0000000f, 0x0010000f }, { 0x000098d0, 0x0000000f, 0x0010000f },
}; };
@@ -648,43 +651,43 @@ static const uint32_t ar5416Bank7[][2] = {
}; };
static const uint32_t ar5416Addac[][2] = { static const uint32_t ar5416Addac[][2] = {
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000003 }, {0x0000989c, 0x00000003 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x0000000c }, {0x0000989c, 0x0000000c },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000030 }, {0x0000989c, 0x00000030 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000060 }, {0x0000989c, 0x00000060 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000058 }, {0x0000989c, 0x00000058 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x0989c, 0x00000000 }, {0x0000989c, 0x00000000 },
{0x098c4, 0x00000000 }, {0x000098c4, 0x00000000 },
}; };
/* hand-crafted from code that does explicit register writes */ /* hand-crafted from code that does explicit register writes */
@@ -156,6 +156,8 @@ ar5416AniAttach(struct ath_hal *ah, const struct ar5212AniParams *params24,
/* /*
* Cleanup any ANI state setup. * Cleanup any ANI state setup.
*
* This doesn't restore registers to their default settings!
*/ */
void void
ar5416AniDetach(struct ath_hal *ah) ar5416AniDetach(struct ath_hal *ah)
@@ -173,16 +175,60 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
typedef int TABLE[]; typedef int TABLE[];
struct ath_hal_5212 *ahp = AH5212(ah); struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212AniState *aniState = ahp->ah_curani; struct ar5212AniState *aniState = ahp->ah_curani;
const struct ar5212AniParams *params = aniState->params; const struct ar5212AniParams *params = AH_NULL;
/*
* This function may be called before there's a current
* channel (eg to disable ANI.)
*/
if (aniState != AH_NULL)
params = aniState->params;
OS_MARK(ah, AH_MARK_ANI_CONTROL, cmd); OS_MARK(ah, AH_MARK_ANI_CONTROL, cmd);
/* These commands can't be disabled */
if (cmd == HAL_ANI_PRESENT)
return AH_TRUE;
if (cmd == HAL_ANI_MODE) {
if (param == 0) {
ahp->ah_procPhyErr &= ~HAL_ANI_ENA;
/* Turn off HW counters if we have them */
ar5416AniDetach(ah);
} else { /* normal/auto mode */
/* don't mess with state if already enabled */
if (! (ahp->ah_procPhyErr & HAL_ANI_ENA)) {
/* Enable MIB Counters */
/*
* XXX use 2.4ghz params if no channel is
* available
*/
enableAniMIBCounters(ah,
ahp->ah_curani != AH_NULL ?
ahp->ah_curani->params:
&ahp->ah_aniParams24);
ahp->ah_procPhyErr |= HAL_ANI_ENA;
}
}
return AH_TRUE;
}
/* Check whether the particular function is enabled */
if (((1 << cmd) & AH5416(ah)->ah_ani_function) == 0) {
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: command %d disabled\n",
__func__, cmd);
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: cmd %d; mask %x\n", __func__, cmd, AH5416(ah)->ah_ani_function);
return AH_FALSE;
}
switch (cmd) { switch (cmd) {
case HAL_ANI_NOISE_IMMUNITY_LEVEL: { case HAL_ANI_NOISE_IMMUNITY_LEVEL: {
u_int level = param; u_int level = param;
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: HAL_ANI_NOISE_IMMUNITY_LEVEL: set level = %d\n", __func__, level);
if (level >= params->maxNoiseImmunityLevel) { if (level >= params->maxNoiseImmunityLevel) {
HALDEBUG(ah, HAL_DEBUG_ANY, HALDEBUG(ah, HAL_DEBUG_ANI,
"%s: immunity level out of range (%u > %u)\n", "%s: immunity level out of range (%u > %u)\n",
__func__, level, params->maxNoiseImmunityLevel); __func__, level, params->maxNoiseImmunityLevel);
return AH_FALSE; return AH_FALSE;
@@ -213,6 +259,7 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
static const TABLE m2CountThrLow = { 63, 48 }; static const TABLE m2CountThrLow = { 63, 48 };
u_int on = param ? 1 : 0; u_int on = param ? 1 : 0;
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION: %s\n", __func__, on ? "enabled" : "disabled");
OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
AR_PHY_SFCORR_LOW_M1_THRESH_LOW, m1ThreshLow[on]); AR_PHY_SFCORR_LOW_M1_THRESH_LOW, m1ThreshLow[on]);
OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
@@ -253,6 +300,7 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
static const TABLE weakSigThrCck = { 8, 6 }; static const TABLE weakSigThrCck = { 8, 6 };
u_int high = param ? 1 : 0; u_int high = param ? 1 : 0;
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: HAL_ANI_CCK_WEAK_SIGNAL_THR: %s\n", __func__, high ? "high" : "low");
OS_REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, OS_REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, weakSigThrCck[high]); AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, weakSigThrCck[high]);
if (high) if (high)
@@ -265,8 +313,9 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
case HAL_ANI_FIRSTEP_LEVEL: { case HAL_ANI_FIRSTEP_LEVEL: {
u_int level = param; u_int level = param;
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: HAL_ANI_FIRSTEP_LEVEL: level = %d\n", __func__, level);
if (level >= params->maxFirstepLevel) { if (level >= params->maxFirstepLevel) {
HALDEBUG(ah, HAL_DEBUG_ANY, HALDEBUG(ah, HAL_DEBUG_ANI,
"%s: firstep level out of range (%u > %u)\n", "%s: firstep level out of range (%u > %u)\n",
__func__, level, params->maxFirstepLevel); __func__, level, params->maxFirstepLevel);
return AH_FALSE; return AH_FALSE;
@@ -283,14 +332,21 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
case HAL_ANI_SPUR_IMMUNITY_LEVEL: { case HAL_ANI_SPUR_IMMUNITY_LEVEL: {
u_int level = param; u_int level = param;
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: HAL_ANI_SPUR_IMMUNITY_LEVEL: level = %d\n", __func__, level);
if (level >= params->maxSpurImmunityLevel) { if (level >= params->maxSpurImmunityLevel) {
HALDEBUG(ah, HAL_DEBUG_ANY, HALDEBUG(ah, HAL_DEBUG_ANI,
"%s: spur immunity level out of range (%u > %u)\n", "%s: spur immunity level out of range (%u > %u)\n",
__func__, level, params->maxSpurImmunityLevel); __func__, level, params->maxSpurImmunityLevel);
return AH_FALSE; return AH_FALSE;
} }
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5, OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5,
AR_PHY_TIMING5_CYCPWR_THR1, params->cycPwrThr1[level]); AR_PHY_TIMING5_CYCPWR_THR1, params->cycPwrThr1[level]);
/* Only set the ext channel cycpwr_thr1 field for ht/40 */
if (IEEE80211_IS_CHAN_HT40(AH_PRIVATE(ah)->ah_curchan))
OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
AR_PHY_EXT_TIMING5_CYCPWR_THR1, params->cycPwrThr1[level]);
if (level > aniState->spurImmunityLevel) if (level > aniState->spurImmunityLevel)
ahp->ah_stats.ast_ani_spurup++; ahp->ah_stats.ast_ani_spurup++;
else if (level < aniState->spurImmunityLevel) else if (level < aniState->spurImmunityLevel)
@@ -298,27 +354,6 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
aniState->spurImmunityLevel = level; aniState->spurImmunityLevel = level;
break; 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 #ifdef AH_PRIVATE_DIAG
case HAL_ANI_PHYERR_RESET: case HAL_ANI_PHYERR_RESET:
ahp->ah_stats.ast_ani_ofdmerrs = 0; ahp->ah_stats.ast_ani_ofdmerrs = 0;
@@ -326,7 +361,7 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
break; break;
#endif /* AH_PRIVATE_DIAG */ #endif /* AH_PRIVATE_DIAG */
default: default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid cmd %u\n", HALDEBUG(ah, HAL_DEBUG_ANI, "%s: invalid cmd %u\n",
__func__, cmd); __func__, cmd);
return AH_FALSE; return AH_FALSE;
} }
@@ -349,13 +384,15 @@ ar5416AniOfdmErrTrigger(struct ath_hal *ah)
aniState = ahp->ah_curani; aniState = ahp->ah_curani;
params = aniState->params; params = aniState->params;
/* First, raise noise immunity level, up to max */ /* First, raise noise immunity level, up to max */
if (aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel) { if ((AH5416(ah)->ah_ani_function & (1 << HAL_ANI_NOISE_IMMUNITY_LEVEL)) &&
(aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel)) {
ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
aniState->noiseImmunityLevel + 1); aniState->noiseImmunityLevel + 1);
return; return;
} }
/* then, raise spur immunity level, up to max */ /* then, raise spur immunity level, up to max */
if (aniState->spurImmunityLevel+1 < params->maxSpurImmunityLevel) { if ((AH5416(ah)->ah_ani_function & (1 << HAL_ANI_SPUR_IMMUNITY_LEVEL)) &&
(aniState->spurImmunityLevel+1 < params->maxSpurImmunityLevel)) {
ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
aniState->spurImmunityLevel + 1); aniState->spurImmunityLevel + 1);
return; return;
@@ -434,7 +471,8 @@ ar5416AniCckErrTrigger(struct ath_hal *ah)
/* first, raise noise immunity level, up to max */ /* first, raise noise immunity level, up to max */
aniState = ahp->ah_curani; aniState = ahp->ah_curani;
params = aniState->params; params = aniState->params;
if (aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel) { if ((AH5416(ah)->ah_ani_function & (1 << HAL_ANI_NOISE_IMMUNITY_LEVEL) &&
aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel)) {
ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
aniState->noiseImmunityLevel + 1); aniState->noiseImmunityLevel + 1);
return; return;
@@ -481,7 +519,7 @@ ar5416AniRestart(struct ath_hal *ah, struct ar5212AniState *aniState)
OS_REG_WRITE(ah, AR_PHY_ERR_1, params->ofdmPhyErrBase); 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_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_OFDM_TIMING);
OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_CCK_TIMING); OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
/* Clear the mib counters and save them in the stats */ /* Clear the mib counters and save them in the stats */
ar5212UpdateMibCounters(ah, &ahp->ah_mibStats); ar5212UpdateMibCounters(ah, &ahp->ah_mibStats);
@@ -530,8 +568,21 @@ ar5416AniReset(struct ath_hal *ah, const struct ieee80211_channel *chan,
/* /*
* Turn off PHY error frame delivery while we futz with settings. * Turn off PHY error frame delivery while we futz with settings.
*/ */
rxfilter = ar5212GetRxFilter(ah); rxfilter = ah->ah_getRxFilter(ah);
ar5212SetRxFilter(ah, rxfilter &~ HAL_RX_FILTER_PHYERR); ah->ah_setRxFilter(ah, rxfilter &~ HAL_RX_FILTER_PHYERR);
/*
* If ANI is disabled at this point, don't set the default
* ANI parameter settings - leave the HAL settings there.
* This is (currently) needed for reliable radar detection.
*/
if (! ANI_ENA(ah)) {
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: ANI disabled\n",
__func__);
goto finish;
}
/* /*
* Automatic processing is done only in station mode right now. * Automatic processing is done only in station mode right now.
*/ */
@@ -565,10 +616,16 @@ ar5416AniReset(struct ath_hal *ah, const struct ieee80211_channel *chan,
ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0); ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
ichan->privFlags |= CHANNEL_ANI_SETUP; ichan->privFlags |= CHANNEL_ANI_SETUP;
} }
/*
* In case the counters haven't yet been setup; set them up.
*/
enableAniMIBCounters(ah, aniState->params);
ar5416AniRestart(ah, aniState); ar5416AniRestart(ah, aniState);
finish:
/* restore RX filter mask */ /* restore RX filter mask */
ar5212SetRxFilter(ah, rxfilter); ah->ah_setRxFilter(ah, rxfilter);
} }
/* /*
@@ -793,21 +850,26 @@ updateMIBStats(struct ath_hal *ah, struct ar5212AniState *aniState)
aniState->cckPhyErrCount = cckPhyErrCnt; aniState->cckPhyErrCount = cckPhyErrCnt;
} }
void
ar5416RxMonitor(struct ath_hal *ah, const HAL_NODE_STATS *stats,
const struct ieee80211_channel *chan)
{
struct ath_hal_5212 *ahp = AH5212(ah);
ahp->ah_stats.ast_nodestats.ns_avgbrssi = stats->ns_avgbrssi;
}
/* /*
* Do periodic processing. This routine is called from the * Do periodic processing. This routine is called from the
* driver's rx interrupt handler after processing frames. * driver's rx interrupt handler after processing frames.
*/ */
void void
ar5416AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats, ar5416AniPoll(struct ath_hal *ah, const struct ieee80211_channel *chan)
const struct ieee80211_channel *chan)
{ {
struct ath_hal_5212 *ahp = AH5212(ah); struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212AniState *aniState = ahp->ah_curani; struct ar5212AniState *aniState = ahp->ah_curani;
const struct ar5212AniParams *params; const struct ar5212AniParams *params;
int32_t listenTime; int32_t listenTime;
ahp->ah_stats.ast_nodestats.ns_avgbrssi = stats->ns_avgbrssi;
/* XXX can aniState be null? */ /* XXX can aniState be null? */
if (aniState == AH_NULL) if (aniState == AH_NULL)
return; return;
@@ -843,10 +905,16 @@ ar5416AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
/* check to see if need to raise immunity */ /* check to see if need to raise immunity */
if (aniState->ofdmPhyErrCount > aniState->listenTime * if (aniState->ofdmPhyErrCount > aniState->listenTime *
params->ofdmTrigHigh / 1000) { params->ofdmTrigHigh / 1000) {
HALDEBUG(ah, HAL_DEBUG_ANI,
"%s: OFDM err %u listenTime %u\n", __func__,
aniState->ofdmPhyErrCount, aniState->listenTime);
ar5416AniOfdmErrTrigger(ah); ar5416AniOfdmErrTrigger(ah);
ar5416AniRestart(ah, aniState); ar5416AniRestart(ah, aniState);
} else if (aniState->cckPhyErrCount > aniState->listenTime * } else if (aniState->cckPhyErrCount > aniState->listenTime *
params->cckTrigHigh / 1000) { params->cckTrigHigh / 1000) {
HALDEBUG(ah, HAL_DEBUG_ANI,
"%s: CCK err %u listenTime %u\n", __func__,
aniState->ofdmPhyErrCount, aniState->listenTime);
ar5416AniCckErrTrigger(ah); ar5416AniCckErrTrigger(ah);
ar5416AniRestart(ah, aniState); ar5416AniRestart(ah, aniState);
} }
@@ -57,8 +57,22 @@ ar5416AniSetup(struct ath_hal *ah)
.rssiThrLow = 7, .rssiThrLow = 7,
.period = 100, .period = 100,
}; };
/* NB: ANI is not enabled yet */ /* NB: disable ANI noise immmunity for reliable RIFS rx */
ar5212AniAttach(ah, &aniparams, &aniparams, AH_FALSE); AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL);
ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
}
/*
* AR5416 doesn't do OLC or temperature compensation.
*/
static void
ar5416olcInit(struct ath_hal *ah)
{
}
static void
ar5416olcTempCompensation(struct ath_hal *ah)
{
} }
/* /*
@@ -98,16 +112,23 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
ah->ah_setupXTxDesc = ar5416SetupXTxDesc; ah->ah_setupXTxDesc = ar5416SetupXTxDesc;
ah->ah_fillTxDesc = ar5416FillTxDesc; ah->ah_fillTxDesc = ar5416FillTxDesc;
ah->ah_procTxDesc = ar5416ProcTxDesc; ah->ah_procTxDesc = ar5416ProcTxDesc;
ah->ah_getTxCompletionRates = ar5416GetTxCompletionRates;
ah->ah_setupTxQueue = ar5416SetupTxQueue;
ah->ah_resetTxQueue = ar5416ResetTxQueue;
/* Receive Functions */ /* Receive Functions */
ah->ah_getRxFilter = ar5416GetRxFilter;
ah->ah_setRxFilter = ar5416SetRxFilter;
ah->ah_startPcuReceive = ar5416StartPcuReceive; ah->ah_startPcuReceive = ar5416StartPcuReceive;
ah->ah_stopPcuReceive = ar5416StopPcuReceive; ah->ah_stopPcuReceive = ar5416StopPcuReceive;
ah->ah_setupRxDesc = ar5416SetupRxDesc; ah->ah_setupRxDesc = ar5416SetupRxDesc;
ah->ah_procRxDesc = ar5416ProcRxDesc; ah->ah_procRxDesc = ar5416ProcRxDesc;
ah->ah_rxMonitor = ar5416AniPoll, ah->ah_rxMonitor = ar5416RxMonitor;
ah->ah_procMibEvent = ar5416ProcessMibIntr, ah->ah_aniPoll = ar5416AniPoll;
ah->ah_procMibEvent = ar5416ProcessMibIntr;
/* Misc Functions */ /* Misc Functions */
ah->ah_getCapability = ar5416GetCapability;
ah->ah_getDiagState = ar5416GetDiagState; ah->ah_getDiagState = ar5416GetDiagState;
ah->ah_setLedState = ar5416SetLedState; ah->ah_setLedState = ar5416SetLedState;
ah->ah_gpioCfgOutput = ar5416GpioCfgOutput; ah->ah_gpioCfgOutput = ar5416GpioCfgOutput;
@@ -115,15 +136,23 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
ah->ah_gpioGet = ar5416GpioGet; ah->ah_gpioGet = ar5416GpioGet;
ah->ah_gpioSet = ar5416GpioSet; ah->ah_gpioSet = ar5416GpioSet;
ah->ah_gpioSetIntr = ar5416GpioSetIntr; ah->ah_gpioSetIntr = ar5416GpioSetIntr;
ah->ah_getTsf64 = ar5416GetTsf64;
ah->ah_resetTsf = ar5416ResetTsf; ah->ah_resetTsf = ar5416ResetTsf;
ah->ah_getRfGain = ar5416GetRfgain; ah->ah_getRfGain = ar5416GetRfgain;
ah->ah_setAntennaSwitch = ar5416SetAntennaSwitch; ah->ah_setAntennaSwitch = ar5416SetAntennaSwitch;
ah->ah_setDecompMask = ar5416SetDecompMask; ah->ah_setDecompMask = ar5416SetDecompMask;
ah->ah_setCoverageClass = ar5416SetCoverageClass; ah->ah_setCoverageClass = ar5416SetCoverageClass;
ah->ah_setQuiet = ar5416SetQuiet;
ah->ah_resetKeyCacheEntry = ar5416ResetKeyCacheEntry; ah->ah_resetKeyCacheEntry = ar5416ResetKeyCacheEntry;
ah->ah_setKeyCacheEntry = ar5416SetKeyCacheEntry; ah->ah_setKeyCacheEntry = ar5416SetKeyCacheEntry;
/* DFS Functions */
ah->ah_enableDfs = ar5416EnableDfs;
ah->ah_getDfsThresh = ar5416GetDfsThresh;
ah->ah_procRadarEvent = ar5416ProcessRadarEvent;
ah->ah_isFastClockEnabled = ar5416IsFastClockEnabled;
/* Power Management Functions */ /* Power Management Functions */
ah->ah_setPowerMode = ar5416SetPowerMode; ah->ah_setPowerMode = ar5416SetPowerMode;
@@ -132,9 +161,9 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
ah->ah_beaconInit = ar5416BeaconInit; ah->ah_beaconInit = ar5416BeaconInit;
ah->ah_setStationBeaconTimers = ar5416SetStaBeaconTimers; ah->ah_setStationBeaconTimers = ar5416SetStaBeaconTimers;
ah->ah_resetStationBeaconTimers = ar5416ResetStaBeaconTimers; ah->ah_resetStationBeaconTimers = ar5416ResetStaBeaconTimers;
ah->ah_getNextTBTT = ar5416GetNextTBTT;
/* XXX 802.11n Functions */ /* 802.11n Functions */
#if 0
ah->ah_chainTxDesc = ar5416ChainTxDesc; ah->ah_chainTxDesc = ar5416ChainTxDesc;
ah->ah_setupFirstTxDesc = ar5416SetupFirstTxDesc; ah->ah_setupFirstTxDesc = ar5416SetupFirstTxDesc;
ah->ah_setupLastTxDesc = ar5416SetupLastTxDesc; ah->ah_setupLastTxDesc = ar5416SetupLastTxDesc;
@@ -146,7 +175,6 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
ah->ah_set11nMac2040 = ar5416Set11nMac2040; ah->ah_set11nMac2040 = ar5416Set11nMac2040;
ah->ah_get11nRxClear = ar5416Get11nRxClear; ah->ah_get11nRxClear = ar5416Get11nRxClear;
ah->ah_set11nRxClear = ar5416Set11nRxClear; ah->ah_set11nRxClear = ar5416Set11nRxClear;
#endif
/* Interrupt functions */ /* Interrupt functions */
ah->ah_isInterruptPending = ar5416IsInterruptPending; ah->ah_isInterruptPending = ar5416IsInterruptPending;
@@ -160,13 +188,32 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
#endif #endif
ahp->ah_priv.ah_getChipPowerLimits = ar5416GetChipPowerLimits; ahp->ah_priv.ah_getChipPowerLimits = ar5416GetChipPowerLimits;
/* Internal ops */
AH5416(ah)->ah_writeIni = ar5416WriteIni; AH5416(ah)->ah_writeIni = ar5416WriteIni;
AH5416(ah)->ah_spurMitigate = ar5416SpurMitigate; AH5416(ah)->ah_spurMitigate = ar5416SpurMitigate;
/* Internal baseband ops */
AH5416(ah)->ah_initPLL = ar5416InitPLL;
/* Internal calibration ops */
AH5416(ah)->ah_cal_initcal = ar5416InitCalHardware;
/* Internal TX power control related operations */
AH5416(ah)->ah_olcInit = ar5416olcInit;
AH5416(ah)->ah_olcTempCompensation = ar5416olcTempCompensation;
AH5416(ah)->ah_setPowerCalTable = ar5416SetPowerCalTable;
/* /*
* Start by setting all Owl devices to 2x2 * Start by setting all Owl devices to 2x2
*/ */
AH5416(ah)->ah_rx_chainmask = AR5416_DEFAULT_RXCHAINMASK; AH5416(ah)->ah_rx_chainmask = AR5416_DEFAULT_RXCHAINMASK;
AH5416(ah)->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK; AH5416(ah)->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK;
/* Enable all ANI functions to begin with */
AH5416(ah)->ah_ani_function = 0xffffffff;
/* Set overridable ANI methods */
AH5212(ah)->ah_aniControl = ar5416AniControl;
} }
uint32_t uint32_t
@@ -189,7 +236,8 @@ ar5416GetRadioRev(struct ath_hal *ah)
*/ */
static struct ath_hal * static struct ath_hal *
ar5416Attach(uint16_t devid, HAL_SOFTC sc, ar5416Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_STATUS *status)
{ {
struct ath_hal_5416 *ahp5416; struct ath_hal_5416 *ahp5416;
struct ath_hal_5212 *ahp; struct ath_hal_5212 *ahp;
@@ -198,7 +246,7 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc,
HAL_STATUS ecode; HAL_STATUS ecode;
HAL_BOOL rfStatus; HAL_BOOL rfStatus;
HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
__func__, sc, (void*) st, (void*) sh); __func__, sc, (void*) st, (void*) sh);
/* NB: memory is returned zero'd */ /* NB: memory is returned zero'd */
@@ -207,7 +255,7 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc,
sizeof(ar5416Addac) sizeof(ar5416Addac)
); );
if (ahp5416 == AH_NULL) { if (ahp5416 == AH_NULL) {
HALDEBUG(AH_NULL, HAL_DEBUG_ANY, HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY,
"%s: cannot allocate memory for state block\n", __func__); "%s: cannot allocate memory for state block\n", __func__);
*status = HAL_ENOMEM; *status = HAL_ENOMEM;
return AH_NULL; return AH_NULL;
@@ -248,6 +296,7 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc,
HAL_INI_INIT(&AH5416(ah)->ah_ini_addac, ar5416Addac, 2); HAL_INI_INIT(&AH5416(ah)->ah_ini_addac, ar5416Addac, 2);
if (! IS_5416V2_2(ah)) { /* Owl 2.1/2.0 */ if (! IS_5416V2_2(ah)) { /* Owl 2.1/2.0 */
ath_hal_printf(ah, "[ath] Enabling CLKDRV workaround for AR5416 < v2.2\n");
struct ini { struct ini {
uint32_t *data; /* NB: !const */ uint32_t *data; /* NB: !const */
int rows, cols; int rows, cols;
@@ -336,6 +385,8 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc,
/* Read Reg Domain */ /* Read Reg Domain */
AH_PRIVATE(ah)->ah_currentRD = AH_PRIVATE(ah)->ah_currentRD =
ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
AH_PRIVATE(ah)->ah_currentRDext =
ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL);
/* /*
* ah_miscMode is populated by ar5416FillCapabilityInfo() * ah_miscMode is populated by ar5416FillCapabilityInfo()
@@ -344,7 +395,7 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc,
* placed into hardware. * placed into hardware.
*/ */
if (ahp->ah_miscMode != 0) if (ahp->ah_miscMode != 0)
OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode);
rfStatus = ar2133RfAttach(ah, &ecode); rfStatus = ar2133RfAttach(ah, &ecode);
if (!rfStatus) { if (!rfStatus) {
@@ -354,6 +405,14 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc,
} }
ar5416AniSetup(ah); /* Anti Noise Immunity */ ar5416AniSetup(ah); /* Anti Noise Immunity */
AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ;
AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ;
AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ;
AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ;
AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ;
AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;
ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist); ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__); HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
@@ -375,6 +434,12 @@ ar5416Detach(struct ath_hal *ah)
HALASSERT(ah != AH_NULL); HALASSERT(ah != AH_NULL);
HALASSERT(ah->ah_magic == AR5416_MAGIC); HALASSERT(ah->ah_magic == AR5416_MAGIC);
/* Make sure that chip is awake before writing to it */
if (! ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
"%s: failed to wake up chip\n",
__func__);
ar5416AniDetach(ah); ar5416AniDetach(ah);
ar5212RfDetach(ah); ar5212RfDetach(ah);
ah->ah_disable(ah); ah->ah_disable(ah);
@@ -435,10 +500,11 @@ ar5416WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
* Write addac shifts * Write addac shifts
*/ */
OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
#if 0
/* NB: only required for Sowl */ /* NB: only required for Sowl */
if (AR_SREV_SOWL(ah))
ar5416EepromSetAddac(ah, chan); ar5416EepromSetAddac(ah, chan);
#endif
regWrites = ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_addac, 1, regWrites = ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_addac, 1,
regWrites); regWrites);
OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
@@ -764,8 +830,9 @@ ar5416FillCapabilityInfo(struct ath_hal *ah)
pCap->halPSPollBroken = AH_TRUE; /* XXX fixed in later revs? */ pCap->halPSPollBroken = AH_TRUE; /* XXX fixed in later revs? */
pCap->halVEOLSupport = AH_TRUE; pCap->halVEOLSupport = AH_TRUE;
pCap->halBssIdMaskSupport = AH_TRUE; pCap->halBssIdMaskSupport = AH_TRUE;
pCap->halMcastKeySrchSupport = AH_FALSE; pCap->halMcastKeySrchSupport = AH_TRUE; /* Works on AR5416 and later */
pCap->halTsfAddSupport = AH_TRUE; pCap->halTsfAddSupport = AH_TRUE;
pCap->hal4AddrAggrSupport = AH_FALSE; /* Broken in Owl */
if (ath_hal_eepromGet(ah, AR_EEP_MAXQCU, &val) == HAL_OK) if (ath_hal_eepromGet(ah, AR_EEP_MAXQCU, &val) == HAL_OK)
pCap->halTotalQueues = val; pCap->halTotalQueues = val;
@@ -801,6 +868,9 @@ ar5416FillCapabilityInfo(struct ath_hal *ah)
pCap->halWowMatchPatternExact = AH_FALSE; pCap->halWowMatchPatternExact = AH_FALSE;
pCap->halBtCoexSupport = AH_FALSE; /* XXX need support */ pCap->halBtCoexSupport = AH_FALSE; /* XXX need support */
pCap->halAutoSleepSupport = AH_FALSE; pCap->halAutoSleepSupport = AH_FALSE;
pCap->hal4kbSplitTransSupport = AH_TRUE;
/* Disable this so Block-ACK works correctly */
pCap->halHasRxSelfLinkedTail = AH_FALSE;
#if 0 /* XXX not yet */ #if 0 /* XXX not yet */
pCap->halNumAntCfg2GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_2GHZ); pCap->halNumAntCfg2GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_2GHZ);
pCap->halNumAntCfg5GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_5GHZ); pCap->halNumAntCfg5GHz = ar5416GetNumAntConfig(ahp, HAL_FREQ_BAND_5GHZ);
@@ -809,11 +879,19 @@ ar5416FillCapabilityInfo(struct ath_hal *ah)
pCap->halTxChainMask = ath_hal_eepromGet(ah, AR_EEP_TXMASK, AH_NULL); pCap->halTxChainMask = ath_hal_eepromGet(ah, AR_EEP_TXMASK, AH_NULL);
/* XXX CB71 uses GPIO 0 to indicate 3 rx chains */ /* XXX CB71 uses GPIO 0 to indicate 3 rx chains */
pCap->halRxChainMask = ath_hal_eepromGet(ah, AR_EEP_RXMASK, AH_NULL); pCap->halRxChainMask = ath_hal_eepromGet(ah, AR_EEP_RXMASK, AH_NULL);
/* AR5416 may have 3 antennas but is a 2x2 stream device */
pCap->halTxStreams = 2;
pCap->halRxStreams = 2;
pCap->halRtsAggrLimit = 8*1024; /* Owl 2.0 limit */ pCap->halRtsAggrLimit = 8*1024; /* Owl 2.0 limit */
pCap->halMbssidAggrSupport = AH_TRUE; pCap->halMbssidAggrSupport = AH_FALSE; /* Broken on Owl */
pCap->halForcePpmSupport = AH_TRUE; pCap->halForcePpmSupport = AH_TRUE;
pCap->halEnhancedPmSupport = AH_TRUE; pCap->halEnhancedPmSupport = AH_TRUE;
pCap->halBssidMatchSupport = AH_TRUE; pCap->halBssidMatchSupport = AH_TRUE;
pCap->halGTTSupport = AH_TRUE;
pCap->halCSTSupport = AH_TRUE;
pCap->halEnhancedDfsSupport = AH_FALSE;
/* Hardware supports 32 bit TSF values in the RX descriptor */
pCap->halHasLongRxDescTsf = AH_TRUE;
if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL) && if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL) &&
ath_hal_eepromGet(ah, AR_EEP_RFSILENT, &ahpriv->ah_rfsilent) == HAL_OK) { ath_hal_eepromGet(ah, AR_EEP_RFSILENT, &ahpriv->ah_rfsilent) == HAL_OK) {
@@ -26,6 +26,16 @@
#include "ar5416/ar5416phy.h" #include "ar5416/ar5416phy.h"
#define TU_TO_USEC(_tu) ((_tu) << 10) #define TU_TO_USEC(_tu) ((_tu) << 10)
#define ONE_EIGHTH_TU_TO_USEC(_tu8) ((_tu8) << 7)
/*
* Return the hardware NextTBTT in TSF
*/
uint64_t
ar5416GetNextTBTT(struct ath_hal *ah)
{
return OS_REG_READ(ah, AR_NEXT_TBTT);
}
/* /*
* Initialize all of the hardware registers used to * Initialize all of the hardware registers used to
@@ -38,8 +48,8 @@ ar5416SetBeaconTimers(struct ath_hal *ah, const HAL_BEACON_TIMERS *bt)
uint32_t bperiod; uint32_t bperiod;
OS_REG_WRITE(ah, AR_NEXT_TBTT, TU_TO_USEC(bt->bt_nexttbtt)); OS_REG_WRITE(ah, AR_NEXT_TBTT, TU_TO_USEC(bt->bt_nexttbtt));
OS_REG_WRITE(ah, AR_NEXT_DBA, TU_TO_USEC(bt->bt_nextdba) >> 3); OS_REG_WRITE(ah, AR_NEXT_DBA, ONE_EIGHTH_TU_TO_USEC(bt->bt_nextdba));
OS_REG_WRITE(ah, AR_NEXT_SWBA, TU_TO_USEC(bt->bt_nextswba) >> 3); OS_REG_WRITE(ah, AR_NEXT_SWBA, ONE_EIGHTH_TU_TO_USEC(bt->bt_nextswba));
OS_REG_WRITE(ah, AR_NEXT_NDP, TU_TO_USEC(bt->bt_nextatim)); OS_REG_WRITE(ah, AR_NEXT_NDP, TU_TO_USEC(bt->bt_nextatim));
bperiod = TU_TO_USEC(bt->bt_intval & HAL_BEACON_PERIOD); bperiod = TU_TO_USEC(bt->bt_intval & HAL_BEACON_PERIOD);
@@ -93,9 +103,9 @@ ar5416BeaconInit(struct ath_hal *ah,
/* fall thru... */ /* fall thru... */
case HAL_M_HOSTAP: case HAL_M_HOSTAP:
bt.bt_nextdba = (next_beacon - bt.bt_nextdba = (next_beacon -
ath_hal_dma_beacon_response_time) << 3; /* 1/8 TU */ ah->ah_config.ah_dma_beacon_response_time) << 3; /* 1/8 TU */
bt.bt_nextswba = (next_beacon - bt.bt_nextswba = (next_beacon -
ath_hal_sw_beacon_response_time) << 3; /* 1/8 TU */ ah->ah_config.ah_sw_beacon_response_time) << 3; /* 1/8 TU */
bt.bt_flags |= AR_TIMER_MODE_TBTT bt.bt_flags |= AR_TIMER_MODE_TBTT
| AR_TIMER_MODE_DBA | AR_TIMER_MODE_DBA
| AR_TIMER_MODE_SWBA; | AR_TIMER_MODE_SWBA;
@@ -144,7 +154,7 @@ ar5416SetStaBeaconTimers(struct ath_hal *ah, const HAL_BEACON_STATE *bs)
/* NB: no cfp setting since h/w automatically takes care */ /* NB: no cfp setting since h/w automatically takes care */
OS_REG_WRITE(ah, AR_NEXT_TBTT, bs->bs_nexttbtt); OS_REG_WRITE(ah, AR_NEXT_TBTT, TU_TO_USEC(bs->bs_nexttbtt));
/* /*
* Start the beacon timers by setting the BEACON register * Start the beacon timers by setting the BEACON register
@@ -221,15 +231,19 @@ ar5416SetStaBeaconTimers(struct ath_hal *ah, const HAL_BEACON_STATE *bs)
OS_REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP)); OS_REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
/* cab timeout is now in 1/8 TU */ /* cab timeout is now in 1/8 TU */
OS_REG_WRITE(ah, AR_SLEEP1, OS_REG_WRITE(ah, AR5416_SLEEP1,
SM((CAB_TIMEOUT_VAL << 3), AR5416_SLEEP1_CAB_TIMEOUT) SM((CAB_TIMEOUT_VAL << 3), AR5416_SLEEP1_CAB_TIMEOUT)
| AR_SLEEP1_ASSUME_DTIM); | AR5416_SLEEP1_ASSUME_DTIM);
/* XXX autosleep? Use min beacon timeout; check ath9k -adrian */
/* beacon timeout is now in 1/8 TU */ /* beacon timeout is now in 1/8 TU */
OS_REG_WRITE(ah, AR_SLEEP2, OS_REG_WRITE(ah, AR5416_SLEEP2,
SM((BEACON_TIMEOUT_VAL << 3), AR5416_SLEEP2_BEACON_TIMEOUT)); SM((BEACON_TIMEOUT_VAL << 3), AR5416_SLEEP2_BEACON_TIMEOUT));
OS_REG_WRITE(ah, AR_TIM_PERIOD, beaconintval); /* TIM_PERIOD and DTIM_PERIOD are now in uS. */
OS_REG_WRITE(ah, AR_DTIM_PERIOD, dtimperiod); OS_REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
OS_REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
OS_REG_SET_BIT(ah, AR_TIMER_MODE, OS_REG_SET_BIT(ah, AR_TIMER_MODE,
AR_TIMER_MODE_TBTT | AR_TIMER_MODE_TIM | AR_TIMER_MODE_DTIM); AR_TIMER_MODE_TBTT | AR_TIMER_MODE_TIM | AR_TIMER_MODE_DTIM);
HALDEBUG(ah, HAL_DEBUG_BEACON, "%s: next DTIM %d\n", HALDEBUG(ah, HAL_DEBUG_BEACON, "%s: next DTIM %d\n",
@@ -24,6 +24,8 @@
#include "ah_eeprom_v14.h" #include "ah_eeprom_v14.h"
#include "ar5212/ar5212.h" /* for NF cal related declarations */
#include "ar5416/ar5416.h" #include "ar5416/ar5416.h"
#include "ar5416/ar5416reg.h" #include "ar5416/ar5416reg.h"
#include "ar5416/ar5416phy.h" #include "ar5416/ar5416phy.h"
@@ -35,9 +37,29 @@ static void ar5416StartNFCal(struct ath_hal *ah);
static void ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *); static void ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *);
static int16_t ar5416GetNf(struct ath_hal *, struct ieee80211_channel *); static int16_t ar5416GetNf(struct ath_hal *, struct ieee80211_channel *);
static uint16_t ar5416GetDefaultNF(struct ath_hal *ah, const struct ieee80211_channel *chan);
static void ar5416SanitizeNF(struct ath_hal *ah, int16_t *nf);
/* /*
* Determine if calibration is supported by device and channel flags * Determine if calibration is supported by device and channel flags
*/ */
/*
* ADC GAIN/DC offset calibration is for calibrating two ADCs that
* are acting as one by interleaving incoming symbols. This isn't
* relevant for 2.4GHz 20MHz wide modes because, as far as I can tell,
* the secondary ADC is never enabled. It is enabled however for
* 5GHz modes.
*
* It hasn't been confirmed whether doing this calibration is needed
* at all in the above modes and/or whether it's actually harmful.
* So for now, let's leave it enabled and just remember to get
* confirmation that it needs to be clarified.
*
* See US Patent No: US 7,541,952 B1:
* " Method and Apparatus for Offset and Gain Compensation for
* Analog-to-Digital Converters."
*/
static OS_INLINE HAL_BOOL static OS_INLINE HAL_BOOL
ar5416IsCalSupp(struct ath_hal *ah, const struct ieee80211_channel *chan, ar5416IsCalSupp(struct ath_hal *ah, const struct ieee80211_channel *chan,
HAL_CAL_TYPE calType) HAL_CAL_TYPE calType)
@@ -50,9 +72,20 @@ ar5416IsCalSupp(struct ath_hal *ah, const struct ieee80211_channel *chan,
return !IEEE80211_IS_CHAN_B(chan); return !IEEE80211_IS_CHAN_B(chan);
case ADC_GAIN_CAL: case ADC_GAIN_CAL:
case ADC_DC_CAL: case ADC_DC_CAL:
/* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */ /*
return !IEEE80211_IS_CHAN_B(chan) && * Run ADC Gain Cal for either 5ghz any or 2ghz HT40.
!(IEEE80211_IS_CHAN_2GHZ(chan) && IEEE80211_IS_CHAN_HT20(chan)); *
* Don't run ADC calibrations for 5ghz fast clock mode
* in HT20 - only one ADC is used.
*/
if (IEEE80211_IS_CHAN_HT20(chan) &&
(IS_5GHZ_FAST_CLOCK_EN(ah, chan)))
return AH_FALSE;
if (IEEE80211_IS_CHAN_5GHZ(chan))
return AH_TRUE;
if (IEEE80211_IS_CHAN_HT40(chan))
return AH_TRUE;
return AH_FALSE;
} }
return AH_FALSE; return AH_FALSE;
} }
@@ -161,45 +194,22 @@ ar5416RunInitCals(struct ath_hal *ah, int init_cal_count)
} }
#endif #endif
/* /*
* Initialize Calibration infrastructure. * AGC calibration for the AR5416, AR9130, AR9160, AR9280.
*/ */
HAL_BOOL HAL_BOOL
ar5416InitCal(struct ath_hal *ah, const struct ieee80211_channel *chan) ar5416InitCalHardware(struct ath_hal *ah, const struct ieee80211_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)) { if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
/* Disable ADC */
OS_REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
AR_PHY_ADC_CTL_OFF_PWDADC);
/* Enable Rx Filter Cal */ /* 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, OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_FLTR_CAL); 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 */ /* Calibrate the AGC */
@@ -213,6 +223,44 @@ ar5416InitCal(struct ath_hal *ah, const struct ieee80211_channel *chan)
return AH_FALSE; return AH_FALSE;
} }
if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
/* Enable ADC */
OS_REG_SET_BIT(ah, AR_PHY_ADC_CTL,
AR_PHY_ADC_CTL_OFF_PWDADC);
/* Disable Rx Filter Cal */
OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_FLTR_CAL);
}
return AH_TRUE;
}
/*
* Initialize Calibration infrastructure.
*/
#define MAX_CAL_CHECK 32
HAL_BOOL
ar5416InitCal(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
HAL_CHANNEL_INTERNAL *ichan;
ichan = ath_hal_checkchannel(ah, chan);
HALASSERT(ichan != AH_NULL);
/* Do initial chipset-specific calibration */
if (! AH5416(ah)->ah_cal_initcal(ah, chan)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: initial chipset calibration did "
"not complete in time; noisy environment?\n", __func__);
return AH_FALSE;
}
/* If there's PA Cal, do it */
if (AH5416(ah)->ah_cal_pacal)
AH5416(ah)->ah_cal_pacal(ah, AH_TRUE);
/* /*
* Do NF calibration after DC offset and other CALs. * Do NF calibration after DC offset and other CALs.
* Per system engineers, noise floor value can sometimes be 20 dB * Per system engineers, noise floor value can sometimes be 20 dB
@@ -221,13 +269,20 @@ ar5416InitCal(struct ath_hal *ah, const struct ieee80211_channel *chan)
*/ */
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
/*
* This may take a while to run; make sure subsequent
* calibration routines check that this has completed
* before reading the value and triggering a subsequent
* calibration.
*/
/* Initialize list pointers */ /* Initialize list pointers */
cal->cal_list = cal->cal_last = cal->cal_curr = AH_NULL; cal->cal_list = cal->cal_last = cal->cal_curr = AH_NULL;
/* /*
* Enable IQ, ADC Gain, ADC DC Offset Cals * Enable IQ, ADC Gain, ADC DC Offset Cals
*/ */
if (AR_SREV_SOWL_10_OR_LATER(ah)) { if (AR_SREV_HOWL(ah) || AR_SREV_SOWL_10_OR_LATER(ah)) {
/* Setup all non-periodic, init time only calibrations */ /* Setup all non-periodic, init time only calibrations */
/* XXX: Init DC Offset not working yet */ /* XXX: Init DC Offset not working yet */
#if 0 #if 0
@@ -273,6 +328,7 @@ ar5416InitCal(struct ath_hal *ah, const struct ieee80211_channel *chan)
ichan->calValid = 0; ichan->calValid = 0;
return AH_TRUE; return AH_TRUE;
#undef MAX_CAL_CHECK
} }
/* /*
@@ -391,11 +447,19 @@ ar5416PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal; struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
HAL_CAL_LIST *currCal = cal->cal_curr; HAL_CAL_LIST *currCal = cal->cal_curr;
HAL_CHANNEL_INTERNAL *ichan; HAL_CHANNEL_INTERNAL *ichan;
int r;
OS_MARK(ah, AH_MARK_PERCAL, chan->ic_freq); OS_MARK(ah, AH_MARK_PERCAL, chan->ic_freq);
*isCalDone = AH_TRUE; *isCalDone = AH_TRUE;
/*
* Since ath_hal calls the PerCal method with rxchainmask=0x1;
* override it with the current chainmask. The upper levels currently
* doesn't know about the chainmask.
*/
rxchainmask = AH5416(ah)->ah_rx_chainmask;
/* Invalid channel check */ /* Invalid channel check */
ichan = ath_hal_checkchannel(ah, chan); ichan = ath_hal_checkchannel(ah, chan);
if (ichan == AH_NULL) { if (ichan == AH_NULL) {
@@ -429,13 +493,27 @@ ar5416PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
/* Do NF cal only at longer intervals */ /* Do NF cal only at longer intervals */
if (longcal) { if (longcal) {
/* Do PA calibration if the chipset supports */
if (AH5416(ah)->ah_cal_pacal)
AH5416(ah)->ah_cal_pacal(ah, AH_FALSE);
/* Do open-loop temperature compensation if the chipset needs it */
if (ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL))
AH5416(ah)->ah_olcTempCompensation(ah);
/* /*
* Get the value from the previous NF cal * Get the value from the previous NF cal
* and update the history buffer. * and update the history buffer.
*/ */
ar5416GetNf(ah, chan); r = ar5416GetNf(ah, chan);
if (r == 0 || r == -1) {
/* NF calibration result isn't valid */
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "%s: NF calibration"
" didn't finish; delaying CCA\n", __func__);
} else {
/* /*
* NF calibration result is valid.
*
* Load the NF from history buffer of the current channel. * Load the NF from history buffer of the current channel.
* NF is slow time-variant, so it is OK to use a * NF is slow time-variant, so it is OK to use a
* historical value. * historical value.
@@ -445,6 +523,7 @@ ar5416PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
/* start NF calibration, without updating BB NF register*/ /* start NF calibration, without updating BB NF register*/
ar5416StartNFCal(ah); ar5416StartNFCal(ah);
} }
}
return AH_TRUE; return AH_TRUE;
} }
@@ -509,9 +588,10 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
AR_PHY_CH2_EXT_CCA AR_PHY_CH2_EXT_CCA
}; };
struct ar5212NfCalHist *h; struct ar5212NfCalHist *h;
int i, j; int i;
int32_t val; int32_t val;
uint8_t chainmask; uint8_t chainmask;
int16_t default_nf = ar5416GetDefaultNF(ah, chan);
/* /*
* Force NF calibration for all chains. * Force NF calibration for all chains.
@@ -519,8 +599,8 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
if (AR_SREV_KITE(ah)) { if (AR_SREV_KITE(ah)) {
/* Kite has only one chain */ /* Kite has only one chain */
chainmask = 0x9; chainmask = 0x9;
} else if (AR_SREV_MERLIN(ah)) { } else if (AR_SREV_MERLIN(ah) || AR_SREV_KIWI(ah)) {
/* Merlin has only two chains */ /* Merlin/Kiwi has only two chains */
chainmask = 0x1B; chainmask = 0x1B;
} else { } else {
chainmask = 0x3F; chainmask = 0x3F;
@@ -531,13 +611,30 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
* so we can load below. * so we can load below.
*/ */
h = AH5416(ah)->ah_cal.nfCalHist; h = AH5416(ah)->ah_cal.nfCalHist;
for (i = 0; i < AR5416_NUM_NF_READINGS; i ++) HALDEBUG(ah, HAL_DEBUG_NFCAL, "CCA: ");
for (i = 0; i < AR5416_NUM_NF_READINGS; i ++) {
/* Don't write to EXT radio CCA registers unless in HT/40 mode */
/* XXX this check should really be cleaner! */
if (i > 2 && !IEEE80211_IS_CHAN_HT40(chan))
continue;
if (chainmask & (1 << i)) { if (chainmask & (1 << i)) {
int16_t nf_val;
if (h)
nf_val = h[i].privNF;
else
nf_val = default_nf;
val = OS_REG_READ(ah, ar5416_cca_regs[i]); val = OS_REG_READ(ah, ar5416_cca_regs[i]);
val &= 0xFFFFFE00; val &= 0xFFFFFE00;
val |= (((uint32_t)(h[i].privNF) << 1) & 0x1ff); val |= (((uint32_t) nf_val << 1) & 0x1ff);
HALDEBUG(ah, HAL_DEBUG_NFCAL, "[%d: %d]", i, nf_val);
OS_REG_WRITE(ah, ar5416_cca_regs[i], val); OS_REG_WRITE(ah, ar5416_cca_regs[i], val);
} }
}
HALDEBUG(ah, HAL_DEBUG_NFCAL, "\n");
/* Load software filtered NF value into baseband internal minCCApwr variable. */ /* 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_ENABLE_NF);
@@ -545,10 +642,20 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_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. */ /* Wait for load to complete, should be fast, a few 10s of us. */
for (j = 0; j < 1000; j++) { if (! ar5212WaitNFCalComplete(ah, 1000)) {
if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) /*
break; * We timed out waiting for the noisefloor to load, probably due to an
OS_DELAY(10); * in-progress rx. Simply return here and allow the load plenty of time
* to complete before the next calibration interval. We need to avoid
* trying to load -50 (which happens below) while the previous load is
* still in progress as this can cause rx deafness. Instead by returning
* here, the baseband nf cal will just be capped by our present
* noisefloor until the next calibration timer.
*/
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "Timeout while waiting for "
"nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
OS_REG_READ(ah, AR_PHY_AGC_CONTROL));
return;
} }
/* /*
@@ -557,6 +664,12 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
* of next noise floor calibration the baseband does. * of next noise floor calibration the baseband does.
*/ */
for (i = 0; i < AR5416_NUM_NF_READINGS; i ++) for (i = 0; i < AR5416_NUM_NF_READINGS; i ++)
/* Don't write to EXT radio CCA registers unless in HT/40 mode */
/* XXX this check should really be cleaner! */
if (i > 2 && !IEEE80211_IS_CHAN_HT40(chan))
continue;
if (chainmask & (1 << i)) { if (chainmask & (1 << i)) {
val = OS_REG_READ(ah, ar5416_cca_regs[i]); val = OS_REG_READ(ah, ar5416_cca_regs[i]);
val &= 0xFFFFFE00; val &= 0xFFFFFE00;
@@ -565,6 +678,11 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
} }
} }
/*
* This just initialises the "good" values for AR5416 which
* may not be right; it'lll be overridden by ar5416SanitizeNF()
* to nominal values.
*/
void void
ar5416InitNfHistBuff(struct ar5212NfCalHist *h) ar5416InitNfHistBuff(struct ar5212NfCalHist *h)
{ {
@@ -583,10 +701,12 @@ ar5416InitNfHistBuff(struct ar5212NfCalHist *h)
* Update the noise floor buffer as a ring buffer * Update the noise floor buffer as a ring buffer
*/ */
static void static void
ar5416UpdateNFHistBuff(struct ar5212NfCalHist *h, int16_t *nfarray) ar5416UpdateNFHistBuff(struct ath_hal *ah, struct ar5212NfCalHist *h,
int16_t *nfarray)
{ {
int i; int i;
/* XXX TODO: don't record nfarray[] entries for inactive chains */
for (i = 0; i < AR5416_NUM_NF_READINGS; i ++) { for (i = 0; i < AR5416_NUM_NF_READINGS; i ++) {
h[i].nfCalBuffer[h[i].currIndex] = nfarray[i]; h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
@@ -606,18 +726,68 @@ ar5416UpdateNFHistBuff(struct ar5212NfCalHist *h, int16_t *nfarray)
} }
} }
static uint16_t
ar5416GetDefaultNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
struct ar5416NfLimits *limit;
if (!chan || IEEE80211_IS_CHAN_2GHZ(chan))
limit = &AH5416(ah)->nf_2g;
else
limit = &AH5416(ah)->nf_5g;
return limit->nominal;
}
static void
ar5416SanitizeNF(struct ath_hal *ah, int16_t *nf)
{
struct ar5416NfLimits *limit;
int i;
if (IEEE80211_IS_CHAN_2GHZ(AH_PRIVATE(ah)->ah_curchan))
limit = &AH5416(ah)->nf_2g;
else
limit = &AH5416(ah)->nf_5g;
for (i = 0; i < AR5416_NUM_NF_READINGS; i++) {
if (!nf[i])
continue;
if (nf[i] > limit->max) {
HALDEBUG(ah, HAL_DEBUG_NFCAL,
"NF[%d] (%d) > MAX (%d), correcting to MAX\n",
i, nf[i], limit->max);
nf[i] = limit->max;
} else if (nf[i] < limit->min) {
HALDEBUG(ah, HAL_DEBUG_NFCAL,
"NF[%d] (%d) < MIN (%d), correcting to NOM\n",
i, nf[i], limit->min);
nf[i] = limit->nominal;
}
}
}
/* /*
* Read the NF and check it against the noise floor threshhold * Read the NF and check it against the noise floor threshhold
*
* Return 0 if the NF calibration hadn't finished, 0 if it was
* invalid, or > 0 for a valid NF reading.
*/ */
static int16_t static int16_t
ar5416GetNf(struct ath_hal *ah, struct ieee80211_channel *chan) ar5416GetNf(struct ath_hal *ah, struct ieee80211_channel *chan)
{ {
int16_t nf, nfThresh; int16_t nf, nfThresh;
int i;
int retval = 0;
if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { if (ar5212IsNFCalInProgress(ah)) {
HALDEBUG(ah, HAL_DEBUG_ANY, HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: NF didn't complete in calibration window\n", __func__); "%s: NF didn't complete in calibration window\n", __func__);
nf = 0; nf = 0;
retval = -1; /* NF didn't finish */
} else { } else {
/* Finished NF cal, check against threshold */ /* Finished NF cal, check against threshold */
int16_t nfarray[NUM_NOISEFLOOR_READINGS] = { 0 }; int16_t nfarray[NUM_NOISEFLOOR_READINGS] = { 0 };
@@ -626,9 +796,10 @@ ar5416GetNf(struct ath_hal *ah, struct ieee80211_channel *chan)
/* TODO - enhance for multiple chains and ext ch */ /* TODO - enhance for multiple chains and ext ch */
ath_hal_getNoiseFloor(ah, nfarray); ath_hal_getNoiseFloor(ah, nfarray);
nf = nfarray[0]; nf = nfarray[0];
ar5416SanitizeNF(ah, nfarray);
if (ar5416GetEepromNoiseFloorThresh(ah, chan, &nfThresh)) { if (ar5416GetEepromNoiseFloorThresh(ah, chan, &nfThresh)) {
if (nf > nfThresh) { if (nf > nfThresh) {
HALDEBUG(ah, HAL_DEBUG_ANY, HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
"%s: noise floor failed detected; " "%s: noise floor failed detected; "
"detected %d, threshold %d\n", __func__, "detected %d, threshold %d\n", __func__,
nf, nfThresh); nf, nfThresh);
@@ -639,12 +810,22 @@ ar5416GetNf(struct ath_hal *ah, struct ieee80211_channel *chan)
*/ */
chan->ic_state |= IEEE80211_CHANSTATE_CWINT; chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
nf = 0; nf = 0;
retval = 0;
} }
} else { } else {
nf = 0; nf = 0;
retval = 0;
} }
ar5416UpdateNFHistBuff(AH5416(ah)->ah_cal.nfCalHist, nfarray); /* Update MIMO channel statistics, regardless of validity or not (for now) */
for (i = 0; i < 3; i++) {
ichan->noiseFloorCtl[i] = nfarray[i];
ichan->noiseFloorExt[i] = nfarray[i + 3];
}
ichan->privFlags |= CHANNEL_MIMO_NF_VALID;
ar5416UpdateNFHistBuff(ah, AH5416(ah)->ah_cal.nfCalHist, nfarray);
ichan->rawNoiseFloor = nf; ichan->rawNoiseFloor = nf;
retval = nf;
} }
return nf; return retval;
} }
@@ -102,6 +102,7 @@ struct ar5416PerCal {
} \ } \
} while (0) } while (0)
HAL_BOOL ar5416InitCalHardware(struct ath_hal *ah, const struct ieee80211_channel *chan);
HAL_BOOL ar5416InitCal(struct ath_hal *, const struct ieee80211_channel *); HAL_BOOL ar5416InitCal(struct ath_hal *, const struct ieee80211_channel *);
HAL_BOOL ar5416PerCalibration(struct ath_hal *, struct ieee80211_channel *, HAL_BOOL ar5416PerCalibration(struct ath_hal *, struct ieee80211_channel *,
HAL_BOOL *isIQdone); HAL_BOOL *isIQdone);
@@ -115,7 +115,7 @@ ar5416IQCalibration(struct ath_hal *ah, uint8_t numChains)
if (qCoff > 15) if (qCoff > 15)
qCoff = 15; qCoff = 15;
else if (qCoff <= -16) else if (qCoff <= -16)
qCoff = 16; qCoff = -16;
HALDEBUG(ah, HAL_DEBUG_PERCAL, HALDEBUG(ah, HAL_DEBUG_PERCAL,
" : iCoff = 0x%x qCoff = 0x%x\n", iCoff, qCoff); " : iCoff = 0x%x qCoff = 0x%x\n", iCoff, qCoff);
@@ -34,6 +34,10 @@ HAL_BOOL
ar5416IsInterruptPending(struct ath_hal *ah) ar5416IsInterruptPending(struct ath_hal *ah)
{ {
uint32_t isr; uint32_t isr;
if (AR_SREV_HOWL(ah))
return AH_TRUE;
/* /*
* Some platforms trigger our ISR before applying power to * Some platforms trigger our ISR before applying power to
* the card, so make sure the INTPEND is really 1, not 0xffffffff. * the card, so make sure the INTPEND is really 1, not 0xffffffff.
@@ -55,17 +59,23 @@ ar5416IsInterruptPending(struct ath_hal *ah)
* values. The value returned is mapped to abstract the hw-specific bit * values. The value returned is mapped to abstract the hw-specific bit
* locations in the Interrupt Status Register. * locations in the Interrupt Status Register.
* *
* (*masked) is cleared on initial call.
*
* Returns: A hardware-abstracted bitmap of all non-masked-out * Returns: A hardware-abstracted bitmap of all non-masked-out
* interrupts pending, as well as an unmasked value * interrupts pending, as well as an unmasked value
*/ */
HAL_BOOL HAL_BOOL
ar5416GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked) ar5416GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked)
{ {
uint32_t isr, isr0, isr1, sync_cause; uint32_t isr, isr0, isr1, sync_cause = 0;
/* /*
* Verify there's a mac interrupt and the RTC is on. * Verify there's a mac interrupt and the RTC is on.
*/ */
if (AR_SREV_HOWL(ah)) {
*masked = 0;
isr = OS_REG_READ(ah, AR_ISR);
} else {
if ((OS_REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) && if ((OS_REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) &&
(OS_REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) == AR_RTC_STATUS_ON) (OS_REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) == AR_RTC_STATUS_ON)
isr = OS_REG_READ(ah, AR_ISR); isr = OS_REG_READ(ah, AR_ISR);
@@ -73,8 +83,9 @@ ar5416GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked)
isr = 0; isr = 0;
sync_cause = OS_REG_READ(ah, AR_INTR_SYNC_CAUSE); sync_cause = OS_REG_READ(ah, AR_INTR_SYNC_CAUSE);
sync_cause &= AR_INTR_SYNC_DEFAULT; sync_cause &= AR_INTR_SYNC_DEFAULT;
if (isr == 0 && sync_cause == 0) {
*masked = 0; *masked = 0;
if (isr == 0 && sync_cause == 0)
return AH_FALSE; return AH_FALSE;
} }
@@ -120,8 +131,15 @@ ar5416GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked)
ahp->ah_intrTxqs |= MS(isr1, AR_ISR_S1_QCU_TXEOL); ahp->ah_intrTxqs |= MS(isr1, AR_ISR_S1_QCU_TXEOL);
} }
if (AR_SREV_MERLIN(ah) || AR_SREV_KITE(ah)) {
uint32_t isr5;
isr5 = OS_REG_READ(ah, AR_ISR_S5_S);
if (isr5 & AR_ISR_S5_TIM_TIMER)
*masked |= HAL_INT_TIM_TIMER;
}
/* Interrupt Mitigation on AR5416 */ /* Interrupt Mitigation on AR5416 */
#ifdef AR5416_INT_MITIGATION #ifdef AH_AR5416_INTERRUPT_MITIGATION
if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
*masked |= HAL_INT_RX; *masked |= HAL_INT_RX;
if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM)) if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
@@ -129,6 +147,10 @@ ar5416GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked)
#endif #endif
*masked |= mask2; *masked |= mask2;
} }
if (AR_SREV_HOWL(ah))
return AH_TRUE;
if (sync_cause != 0) { if (sync_cause != 0) {
if (sync_cause & (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) { if (sync_cause & (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) {
*masked |= HAL_INT_FATAL; *masked |= HAL_INT_FATAL;
@@ -177,16 +199,35 @@ ar5416SetInterrupts(struct ath_hal *ah, HAL_INT ints)
OS_REG_WRITE(ah, AR_IER, AR_IER_DISABLE); OS_REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
(void) OS_REG_READ(ah, AR_IER); (void) OS_REG_READ(ah, AR_IER);
if (! AR_SREV_HOWL(ah)) {
OS_REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0); OS_REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
(void) OS_REG_READ(ah, AR_INTR_ASYNC_ENABLE); (void) OS_REG_READ(ah, AR_INTR_ASYNC_ENABLE);
OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
(void) OS_REG_READ(ah, AR_INTR_SYNC_ENABLE); (void) OS_REG_READ(ah, AR_INTR_SYNC_ENABLE);
} }
}
mask = ints & HAL_INT_COMMON; mask = ints & HAL_INT_COMMON;
mask2 = 0; mask2 = 0;
#ifdef AH_AR5416_INTERRUPT_MITIGATION
/*
* Overwrite default mask if Interrupt mitigation
* is specified for AR5416
*/
mask = ints & HAL_INT_COMMON;
if (ints & HAL_INT_TX)
mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
if (ints & HAL_INT_RX)
mask |= AR_IMR_RXERR | AR_IMR_RXMINTR | AR_IMR_RXINTM;
if (ints & HAL_INT_TX) {
if (ahp->ah_txErrInterruptMask)
mask |= AR_IMR_TXERR;
if (ahp->ah_txEolInterruptMask)
mask |= AR_IMR_TXEOL;
}
#else
if (ints & HAL_INT_TX) { if (ints & HAL_INT_TX) {
if (ahp->ah_txOkInterruptMask) if (ahp->ah_txOkInterruptMask)
mask |= AR_IMR_TXOK; mask |= AR_IMR_TXOK;
@@ -199,16 +240,6 @@ ar5416SetInterrupts(struct ath_hal *ah, HAL_INT ints)
} }
if (ints & HAL_INT_RX) if (ints & HAL_INT_RX)
mask |= AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXDESC; mask |= AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXDESC;
#ifdef AR5416_INT_MITIGATION
/*
* Overwrite default mask if Interrupt mitigation
* is specified for AR5416
*/
mask = ints & HAL_INT_COMMON;
if (ints & HAL_INT_TX)
mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
if (ints & HAL_INT_RX)
mask |= AR_IMR_RXERR | AR_IMR_RXMINTR | AR_IMR_RXINTM;
#endif #endif
if (ints & (HAL_INT_BMISC)) { if (ints & (HAL_INT_BMISC)) {
mask |= AR_IMR_BCNMISC; mask |= AR_IMR_BCNMISC;
@@ -220,14 +251,20 @@ ar5416SetInterrupts(struct ath_hal *ah, HAL_INT ints)
mask2 |= AR_IMR_S2_DTIMSYNC; mask2 |= AR_IMR_S2_DTIMSYNC;
if (ints & HAL_INT_CABEND) if (ints & HAL_INT_CABEND)
mask2 |= (AR_IMR_S2_CABEND ); mask2 |= (AR_IMR_S2_CABEND );
if (ints & HAL_INT_GTT)
mask2 |= AR_IMR_S2_GTT;
if (ints & HAL_INT_CST) if (ints & HAL_INT_CST)
mask2 |= AR_IMR_S2_CST; mask2 |= AR_IMR_S2_CST;
if (ints & HAL_INT_TSFOOR) if (ints & HAL_INT_TSFOOR)
mask2 |= AR_IMR_S2_TSFOOR; mask2 |= AR_IMR_S2_TSFOOR;
} }
if (ints & (HAL_INT_GTT | HAL_INT_CST)) {
mask |= AR_IMR_BCNMISC;
if (ints & HAL_INT_GTT)
mask2 |= AR_IMR_S2_GTT;
if (ints & HAL_INT_CST)
mask2 |= AR_IMR_S2_CST;
}
/* Write the new IMR and store off our SW copy. */ /* Write the new IMR and store off our SW copy. */
HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: new IMR 0x%x\n", __func__, mask); HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: new IMR 0x%x\n", __func__, mask);
OS_REG_WRITE(ah, AR_IMR, mask); OS_REG_WRITE(ah, AR_IMR, mask);
@@ -248,6 +285,7 @@ ar5416SetInterrupts(struct ath_hal *ah, HAL_INT ints)
HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: enable IER\n", __func__); HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: enable IER\n", __func__);
OS_REG_WRITE(ah, AR_IER, AR_IER_ENABLE); OS_REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
if (! AR_SREV_HOWL(ah)) {
mask = AR_INTR_MAC_IRQ; mask = AR_INTR_MAC_IRQ;
if (ints & HAL_INT_GPIO) if (ints & HAL_INT_GPIO)
mask |= SM(AH5416(ah)->ah_gpioMask, mask |= SM(AH5416(ah)->ah_gpioMask,
@@ -262,6 +300,7 @@ ar5416SetInterrupts(struct ath_hal *ah, HAL_INT ints)
OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, mask); OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, mask);
OS_REG_WRITE(ah, AR_INTR_SYNC_MASK, mask); OS_REG_WRITE(ah, AR_INTR_SYNC_MASK, mask);
} }
}
return omask; return omask;
} }
@@ -40,14 +40,18 @@ u_int
ar5416GetWirelessModes(struct ath_hal *ah) ar5416GetWirelessModes(struct ath_hal *ah)
{ {
u_int mode; u_int mode;
struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;
mode = ar5212GetWirelessModes(ah); mode = ar5212GetWirelessModes(ah);
if (mode & HAL_MODE_11A)
/* Only enable HT modes if the NIC supports HT */
if (pCap->halHTSupport == AH_TRUE && (mode & HAL_MODE_11A))
mode |= HAL_MODE_11NA_HT20 mode |= HAL_MODE_11NA_HT20
| HAL_MODE_11NA_HT40PLUS | HAL_MODE_11NA_HT40PLUS
| HAL_MODE_11NA_HT40MINUS | HAL_MODE_11NA_HT40MINUS
; ;
if (mode & HAL_MODE_11G) if (pCap->halHTSupport == AH_TRUE && (mode & HAL_MODE_11G))
mode |= HAL_MODE_11NG_HT20 mode |= HAL_MODE_11NG_HT20
| HAL_MODE_11NG_HT40PLUS | HAL_MODE_11NG_HT40PLUS
| HAL_MODE_11NG_HT40MINUS | HAL_MODE_11NG_HT40MINUS
@@ -73,6 +77,9 @@ ar5416SetLedState(struct ath_hal *ah, HAL_LED_STATE state)
}; };
uint32_t bits; uint32_t bits;
if (AR_SREV_HOWL(ah))
return;
bits = OS_REG_READ(ah, AR_MAC_LED); bits = OS_REG_READ(ah, AR_MAC_LED);
bits = (bits &~ AR_MAC_LED_MODE) bits = (bits &~ AR_MAC_LED_MODE)
| SM(AR_MAC_LED_MODE_POWON, AR_MAC_LED_MODE) | SM(AR_MAC_LED_MODE_POWON, AR_MAC_LED_MODE)
@@ -85,6 +92,41 @@ ar5416SetLedState(struct ath_hal *ah, HAL_LED_STATE state)
OS_REG_WRITE(ah, AR_MAC_LED, bits); OS_REG_WRITE(ah, AR_MAC_LED, bits);
} }
/*
* Get the current hardware tsf for stamlme
*/
uint64_t
ar5416GetTsf64(struct ath_hal *ah)
{
uint32_t low1, low2, u32;
/* sync multi-word read */
low1 = OS_REG_READ(ah, AR_TSF_L32);
u32 = OS_REG_READ(ah, AR_TSF_U32);
low2 = OS_REG_READ(ah, AR_TSF_L32);
if (low2 < low1) { /* roll over */
/*
* If we are not preempted this will work. If we are
* 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.
*/
u32++;
}
return (((uint64_t) u32) << 32) | ((uint64_t) low2);
}
void
ar5416SetTsf64(struct ath_hal *ah, uint64_t tsf64)
{
OS_REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
OS_REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
}
/* /*
* Reset the current hardware tsf for stamlme. * Reset the current hardware tsf for stamlme.
*/ */
@@ -120,6 +162,7 @@ ar5416SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en)
void void
ar5416SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now) ar5416SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
{ {
AH_PRIVATE(ah)->ah_coverageClass = coverageclass;
} }
/* /*
@@ -265,6 +308,35 @@ ar5416Set11nRxClear(struct ath_hal *ah, HAL_HT_RXCLEAR rxclear)
} }
} }
/* XXX shouldn't be here! */
#define TU_TO_USEC(_tu) ((_tu) << 10)
HAL_STATUS
ar5416SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration,
uint32_t nextStart, HAL_QUIET_FLAG flag)
{
uint32_t period_us = TU_TO_USEC(period); /* convert to us unit */
uint32_t nextStart_us = TU_TO_USEC(nextStart); /* convert to us unit */
if (flag & HAL_QUIET_ENABLE) {
if ((!nextStart) || (flag & HAL_QUIET_ADD_CURRENT_TSF)) {
/* Add the nextStart offset to the current TSF */
nextStart_us += OS_REG_READ(ah, AR_TSF_L32);
}
if (flag & HAL_QUIET_ADD_SWBA_RESP_TIME) {
nextStart_us += ah->ah_config.ah_sw_beacon_response_time;
}
OS_REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
OS_REG_WRITE(ah, AR_QUIET2, SM(duration, AR_QUIET2_QUIET_DUR));
OS_REG_WRITE(ah, AR_QUIET_PERIOD, period_us);
OS_REG_WRITE(ah, AR_NEXT_QUIET, nextStart_us);
OS_REG_SET_BIT(ah, AR_TIMER_MODE, AR_TIMER_MODE_QUIET);
} else {
OS_REG_CLR_BIT(ah, AR_TIMER_MODE, AR_TIMER_MODE_QUIET);
}
return HAL_OK;
}
#undef TU_TO_USEC
HAL_STATUS HAL_STATUS
ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
uint32_t capability, uint32_t *result) uint32_t capability, uint32_t *result)
@@ -273,9 +345,9 @@ ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
case HAL_CAP_BB_HANG: case HAL_CAP_BB_HANG:
switch (capability) { switch (capability) {
case HAL_BB_HANG_RIFS: case HAL_BB_HANG_RIFS:
return AR_SREV_SOWL(ah) ? HAL_OK : HAL_ENOTSUPP; return (AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) ? HAL_OK : HAL_ENOTSUPP;
case HAL_BB_HANG_DFS: case HAL_BB_HANG_DFS:
return AR_SREV_SOWL(ah) ? HAL_OK : HAL_ENOTSUPP; return (AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) ? HAL_OK : HAL_ENOTSUPP;
case HAL_BB_HANG_RX_CLEAR: case HAL_BB_HANG_RX_CLEAR:
return AR_SREV_MERLIN(ah) ? HAL_OK : HAL_ENOTSUPP; return AR_SREV_MERLIN(ah) ? HAL_OK : HAL_ENOTSUPP;
} }
@@ -283,8 +355,10 @@ ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
case HAL_CAP_MAC_HANG: case HAL_CAP_MAC_HANG:
return ((ah->ah_macVersion == AR_XSREV_VERSION_OWL_PCI) || return ((ah->ah_macVersion == AR_XSREV_VERSION_OWL_PCI) ||
(ah->ah_macVersion == AR_XSREV_VERSION_OWL_PCIE) || (ah->ah_macVersion == AR_XSREV_VERSION_OWL_PCIE) ||
AR_SREV_SOWL(ah)) ? AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) ?
HAL_OK : HAL_ENOTSUPP; HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_DIVERSITY: /* disable classic fast diversity */
return HAL_ENXIO;
default: default:
break; break;
} }
@@ -356,6 +430,59 @@ typedef struct {
uint8_t qcu_complete_state; uint8_t qcu_complete_state;
} hal_mac_hang_check_t; } hal_mac_hang_check_t;
HAL_BOOL
ar5416SetRifsDelay(struct ath_hal *ah, const struct ieee80211_channel *chan,
HAL_BOOL enable)
{
uint32_t val;
HAL_BOOL is_chan_2g = AH_FALSE;
HAL_BOOL is_ht40 = AH_FALSE;
if (chan)
is_chan_2g = IEEE80211_IS_CHAN_2GHZ(chan);
if (chan)
is_ht40 = IEEE80211_IS_CHAN_HT40(chan);
/* Only support disabling RIFS delay for now */
HALASSERT(enable == AH_FALSE);
if (enable == AH_TRUE)
return AH_FALSE;
/* Change RIFS init delay to 0 */
val = OS_REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS);
val &= ~AR_PHY_RIFS_INIT_DELAY;
OS_REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val);
/*
* For Owl, RIFS RX parameters are controlled differently;
* it isn't enabled in the inivals by default.
*
* For Sowl/Howl, RIFS RX is enabled in the inivals by default;
* the following code sets them back to non-RIFS values.
*
* For > Sowl/Howl, RIFS RX can be left on by default and so
* this function shouldn't be called.
*/
if ((! AR_SREV_SOWL(ah)) && (! AR_SREV_HOWL(ah)))
return AH_TRUE;
/* Reset search delay to default values */
if (is_chan_2g)
if (is_ht40)
OS_REG_WRITE(ah, AR_PHY_SEARCH_START_DELAY, 0x268);
else
OS_REG_WRITE(ah, AR_PHY_SEARCH_START_DELAY, 0x134);
else
if (is_ht40)
OS_REG_WRITE(ah, AR_PHY_SEARCH_START_DELAY, 0x370);
else
OS_REG_WRITE(ah, AR_PHY_SEARCH_START_DELAY, 0x1b8);
return AH_TRUE;
}
static HAL_BOOL static HAL_BOOL
ar5416CompareDbgHang(struct ath_hal *ah, const mac_dbg_regs_t *regs, ar5416CompareDbgHang(struct ath_hal *ah, const mac_dbg_regs_t *regs,
const hal_mac_hang_check_t *check) const hal_mac_hang_check_t *check)
@@ -435,12 +562,12 @@ ar5416DetectMacHang(struct ath_hal *ah)
if (ar5416CompareDbgHang(ah, &mac_dbg, &hang_sig2)) if (ar5416CompareDbgHang(ah, &mac_dbg, &hang_sig2))
return HAL_MAC_HANG_SIG2; return HAL_MAC_HANG_SIG2;
HALDEBUG(ah, HAL_DEBUG_ANY, "%s Found an unknown MAC hang signature " HALDEBUG(ah, HAL_DEBUG_HANG, "%s Found an unknown MAC hang signature "
"DMADBG_3=0x%x DMADBG_4=0x%x DMADBG_5=0x%x DMADBG_6=0x%x\n", "DMADBG_3=0x%x DMADBG_4=0x%x DMADBG_5=0x%x DMADBG_6=0x%x\n",
__func__, mac_dbg.dma_dbg_3, mac_dbg.dma_dbg_4, mac_dbg.dma_dbg_5, __func__, mac_dbg.dma_dbg_3, mac_dbg.dma_dbg_4, mac_dbg.dma_dbg_5,
mac_dbg.dma_dbg_6); mac_dbg.dma_dbg_6);
return HAL_MAC_HANG_UNKNOWN; return 0;
} }
/* /*
@@ -484,16 +611,170 @@ ar5416DetectBBHang(struct ath_hal *ah)
} }
for (i = 0; i < N(hang_list); i++) for (i = 0; i < N(hang_list); i++)
if ((hang_sig & hang_list[i].mask) == hang_list[i].val) { if ((hang_sig & hang_list[i].mask) == hang_list[i].val) {
HALDEBUG(ah, HAL_DEBUG_ANY, HALDEBUG(ah, HAL_DEBUG_HANG,
"%s BB hang, signature 0x%x, code 0x%x\n", "%s BB hang, signature 0x%x, code 0x%x\n",
__func__, hang_sig, hang_list[i].code); __func__, hang_sig, hang_list[i].code);
return hang_list[i].code; return hang_list[i].code;
} }
HALDEBUG(ah, HAL_DEBUG_ANY, "%s Found an unknown BB hang signature! " HALDEBUG(ah, HAL_DEBUG_HANG, "%s Found an unknown BB hang signature! "
"<0x806c>=0x%x\n", __func__, hang_sig); "<0x806c>=0x%x\n", __func__, hang_sig);
return HAL_BB_HANG_UNKNOWN; return 0;
#undef N #undef N
} }
#undef NUM_STATUS_READS #undef NUM_STATUS_READS
/*
* Get the radar parameter values and return them in the pe
* structure
*/
void
ar5416GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
{
uint32_t val, temp;
val = OS_REG_READ(ah, AR_PHY_RADAR_0);
temp = MS(val,AR_PHY_RADAR_0_FIRPWR);
temp |= 0xFFFFFF80;
pe->pe_firpwr = temp;
pe->pe_rrssi = MS(val, AR_PHY_RADAR_0_RRSSI);
pe->pe_height = MS(val, AR_PHY_RADAR_0_HEIGHT);
pe->pe_prssi = MS(val, AR_PHY_RADAR_0_PRSSI);
pe->pe_inband = MS(val, AR_PHY_RADAR_0_INBAND);
val = OS_REG_READ(ah, AR_PHY_RADAR_1);
temp = val & AR_PHY_RADAR_1_RELPWR_ENA;
pe->pe_relpwr = MS(val, AR_PHY_RADAR_1_RELPWR_THRESH);
if (temp)
pe->pe_relpwr |= HAL_PHYERR_PARAM_ENABLE;
temp = val & AR_PHY_RADAR_1_RELSTEP_CHECK;
pe->pe_relstep = MS(val, AR_PHY_RADAR_1_RELSTEP_THRESH);
if (temp)
pe->pe_enabled = 1;
else
pe->pe_enabled = 0;
pe->pe_maxlen = MS(val, AR_PHY_RADAR_1_MAXLEN);
pe->pe_extchannel = !! (OS_REG_READ(ah, AR_PHY_RADAR_EXT) &
AR_PHY_RADAR_EXT_ENA);
pe->pe_usefir128 = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) &
AR_PHY_RADAR_1_USE_FIR128);
pe->pe_blockradar = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) &
AR_PHY_RADAR_1_BLOCK_CHECK);
pe->pe_enmaxrssi = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) &
AR_PHY_RADAR_1_MAX_RRSSI);
}
/*
* Enable radar detection and set the radar parameters per the
* values in pe
*/
void
ar5416EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
{
uint32_t val;
val = OS_REG_READ(ah, AR_PHY_RADAR_0);
if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_FIRPWR;
val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR);
}
if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_RRSSI;
val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI);
}
if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_HEIGHT;
val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT);
}
if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_PRSSI;
val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
}
if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) {
val &= ~AR_PHY_RADAR_0_INBAND;
val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND);
}
/*Enable FFT data*/
val |= AR_PHY_RADAR_0_FFT_ENA;
OS_REG_WRITE(ah, AR_PHY_RADAR_0, val | AR_PHY_RADAR_0_ENA);
if (pe->pe_usefir128 == 1)
OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_USE_FIR128);
else if (pe->pe_usefir128 == 0)
OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_USE_FIR128);
if (pe->pe_enmaxrssi == 1)
OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_MAX_RRSSI);
else if (pe->pe_enmaxrssi == 0)
OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_MAX_RRSSI);
if (pe->pe_blockradar == 1)
OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_BLOCK_CHECK);
else if (pe->pe_blockradar == 0)
OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_BLOCK_CHECK);
if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL) {
val = OS_REG_READ(ah, AR_PHY_RADAR_1);
val &= ~AR_PHY_RADAR_1_MAXLEN;
val |= SM(pe->pe_maxlen, AR_PHY_RADAR_1_MAXLEN);
OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
}
/*
* Enable HT/40 if the upper layer asks;
* it should check the channel is HT/40 and HAL_CAP_EXT_CHAN_DFS
* is available.
*/
if (pe->pe_extchannel == 1)
OS_REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
else if (pe->pe_extchannel == 0)
OS_REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL) {
val = OS_REG_READ(ah, AR_PHY_RADAR_1);
val &= ~AR_PHY_RADAR_1_RELSTEP_THRESH;
val |= SM(pe->pe_relstep, AR_PHY_RADAR_1_RELSTEP_THRESH);
OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
}
if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL) {
val = OS_REG_READ(ah, AR_PHY_RADAR_1);
val &= ~AR_PHY_RADAR_1_RELPWR_THRESH;
val |= SM(pe->pe_relpwr, AR_PHY_RADAR_1_RELPWR_THRESH);
OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
}
}
/*
* Extract the radar event information from the given phy error.
*
* Returns AH_TRUE if the phy error was actually a phy error,
* AH_FALSE if the phy error wasn't a phy error.
*/
HAL_BOOL
ar5416ProcessRadarEvent(struct ath_hal *ah, struct ath_rx_status *rxs,
uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event)
{
/*
* For now, this isn't implemented.
*/
return AH_FALSE;
}
/*
* Return whether fast-clock is currently enabled for this
* channel.
*/
HAL_BOOL
ar5416IsFastClockEnabled(struct ath_hal *ah)
{
struct ath_hal_private *ahp = AH_PRIVATE(ah);
return IS_5GHZ_FAST_CLOCK_EN(ah, ahp->ah_curchan);
}
@@ -77,25 +77,25 @@ static HAL_RATE_TABLE ar5416_11na_table = {
/* 12 Mb */ { AH_TRUE, OFDM, 12000, 0x0a, 0x00, (0x80|24), 2 }, /* 12 Mb */ { AH_TRUE, OFDM, 12000, 0x0a, 0x00, (0x80|24), 2 },
/* 18 Mb */ { AH_TRUE, OFDM, 18000, 0x0e, 0x00, 36, 2 }, /* 18 Mb */ { AH_TRUE, OFDM, 18000, 0x0e, 0x00, 36, 2 },
/* 24 Mb */ { AH_TRUE, OFDM, 24000, 0x09, 0x00, (0x80|48), 4 }, /* 24 Mb */ { AH_TRUE, OFDM, 24000, 0x09, 0x00, (0x80|48), 4 },
/* 36 Mb */ { AH_TRUE, OFDM, 36000, 0x0d, 0x00, 72, 8 }, /* 36 Mb */ { AH_TRUE, OFDM, 36000, 0x0d, 0x00, 72, 4 },
/* 48 Mb */ { AH_TRUE, OFDM, 48000, 0x08, 0x00, 96, 8 }, /* 48 Mb */ { AH_TRUE, OFDM, 48000, 0x08, 0x00, 96, 4 },
/* 54 Mb */ { AH_TRUE, OFDM, 54000, 0x0c, 0x00, 108, 8 }, /* 54 Mb */ { AH_TRUE, OFDM, 54000, 0x0c, 0x00, 108, 4 },
/* 6.5 Mb */ { AH_TRUE, HT, 6500, 0x80, 0x00, 0, 8 }, /* 6.5 Mb */ { AH_TRUE, HT, 6500, 0x80, 0x00, 0, 4 },
/* 13 Mb */ { AH_TRUE, HT, 13000, 0x81, 0x00, 1, 8 }, /* 13 Mb */ { AH_TRUE, HT, 13000, 0x81, 0x00, 1, 4 },
/*19.5 Mb */ { AH_TRUE, HT, 19500, 0x82, 0x00, 2, 8 }, /*19.5 Mb */ { AH_TRUE, HT, 19500, 0x82, 0x00, 2, 4 },
/* 26 Mb */ { AH_TRUE, HT, 26000, 0x83, 0x00, 3, 8 }, /* 26 Mb */ { AH_TRUE, HT, 26000, 0x83, 0x00, 3, 4 },
/* 39 Mb */ { AH_TRUE, HT, 39000, 0x84, 0x00, 4, 8 }, /* 39 Mb */ { AH_TRUE, HT, 39000, 0x84, 0x00, 4, 4 },
/* 52 Mb */ { AH_TRUE, HT, 52000, 0x85, 0x00, 5, 8 }, /* 52 Mb */ { AH_TRUE, HT, 52000, 0x85, 0x00, 5, 4 },
/*58.5 Mb */ { AH_TRUE, HT, 58500, 0x86, 0x00, 6, 8 }, /*58.5 Mb */ { AH_TRUE, HT, 58500, 0x86, 0x00, 6, 4 },
/* 65 Mb */ { AH_TRUE, HT, 65000, 0x87, 0x00, 7, 8 }, /* 65 Mb */ { AH_TRUE, HT, 65000, 0x87, 0x00, 7, 4 },
/* 13 Mb */ { AH_TRUE, HT, 13000, 0x88, 0x00, 8, 8 }, /* 13 Mb */ { AH_TRUE, HT, 13000, 0x88, 0x00, 8, 4 },
/* 26 Mb */ { AH_TRUE, HT, 26000, 0x89, 0x00, 9, 8 }, /* 26 Mb */ { AH_TRUE, HT, 26000, 0x89, 0x00, 9, 4 },
/* 39 Mb */ { AH_TRUE, HT, 39000, 0x8a, 0x00, 10, 8 }, /* 39 Mb */ { AH_TRUE, HT, 39000, 0x8a, 0x00, 10, 4 },
/* 52 Mb */ { AH_TRUE, HT, 52000, 0x8b, 0x00, 11, 8 }, /* 52 Mb */ { AH_TRUE, HT, 52000, 0x8b, 0x00, 11, 4 },
/* 78 Mb */ { AH_TRUE, HT, 78000, 0x8c, 0x00, 12, 8 }, /* 78 Mb */ { AH_TRUE, HT, 78000, 0x8c, 0x00, 12, 4 },
/* 104 Mb */ { AH_TRUE, HT, 104000, 0x8d, 0x00, 13, 8 }, /* 104 Mb */ { AH_TRUE, HT, 104000, 0x8d, 0x00, 13, 4 },
/* 117 Mb */ { AH_TRUE, HT, 117000, 0x8e, 0x00, 14, 8 }, /* 117 Mb */ { AH_TRUE, HT, 117000, 0x8e, 0x00, 14, 4 },
/* 130 Mb */ { AH_TRUE, HT, 130000, 0x8f, 0x00, 15, 8 }, /* 130 Mb */ { AH_TRUE, HT, 130000, 0x8f, 0x00, 15, 4 },
}, },
}; };
@@ -52,7 +52,13 @@ ar5416SetPowerModeAwake(struct ath_hal *ah, int setChip)
goto bad; goto bad;
} }
if (AR_SREV_HOWL(ah))
OS_REG_SET_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN);
OS_REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); OS_REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN);
if (AR_SREV_HOWL(ah))
OS_DELAY(10000);
else
OS_DELAY(50); /* Give chip the chance to awake */ OS_DELAY(50); /* Give chip the chance to awake */
for (i = POWER_UP_TIME / 50; i != 0; i--) { for (i = POWER_UP_TIME / 50; i != 0; i--) {
@@ -88,8 +94,10 @@ ar5416SetPowerModeSleep(struct ath_hal *ah, int setChip)
if (setChip) { if (setChip) {
/* Clear the RTC force wake bit to allow the mac to sleep */ /* Clear the RTC force wake bit to allow the mac to sleep */
OS_REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); OS_REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN);
if (! AR_SREV_HOWL(ah))
OS_REG_WRITE(ah, AR_RC, AR_RC_AHB|AR_RC_HOSTIF); OS_REG_WRITE(ah, AR_RC, AR_RC_AHB|AR_RC_HOSTIF);
/* Shutdown chip. Active low */ /* Shutdown chip. Active low */
if (! AR_SREV_OWL(ah))
OS_REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); OS_REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN);
} }
} }
@@ -26,6 +26,46 @@
#include "ar5416/ar5416reg.h" #include "ar5416/ar5416reg.h"
#include "ar5416/ar5416desc.h" #include "ar5416/ar5416desc.h"
/*
* Get the receive filter.
*/
uint32_t
ar5416GetRxFilter(struct ath_hal *ah)
{
uint32_t bits = OS_REG_READ(ah, AR_RX_FILTER);
uint32_t phybits = OS_REG_READ(ah, AR_PHY_ERR);
if (phybits & AR_PHY_ERR_RADAR)
bits |= HAL_RX_FILTER_PHYRADAR;
if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
bits |= HAL_RX_FILTER_PHYERR;
return bits;
}
/*
* Set the receive filter.
*/
void
ar5416SetRxFilter(struct ath_hal *ah, u_int32_t bits)
{
uint32_t phybits;
OS_REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff));
phybits = 0;
if (bits & HAL_RX_FILTER_PHYRADAR)
phybits |= AR_PHY_ERR_RADAR;
if (bits & HAL_RX_FILTER_PHYERR)
phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
OS_REG_WRITE(ah, AR_PHY_ERR, phybits);
if (phybits) {
OS_REG_WRITE(ah, AR_RXCFG,
OS_REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
} else {
OS_REG_WRITE(ah, AR_RXCFG,
OS_REG_READ(ah, AR_RXCFG) &~ AR_RXCFG_ZLFDMA);
}
}
/* /*
* Start receive at the PCU engine * Start receive at the PCU engine
*/ */
@@ -67,6 +107,7 @@ ar5416SetupRxDesc(struct ath_hal *ah, struct ath_desc *ds,
uint32_t size, u_int flags) uint32_t size, u_int flags)
{ {
struct ar5416_desc *ads = AR5416DESC(ds); struct ar5416_desc *ads = AR5416DESC(ds);
HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
HALASSERT((size &~ AR_BufLen) == 0); HALASSERT((size &~ AR_BufLen) == 0);
@@ -77,6 +118,10 @@ ar5416SetupRxDesc(struct ath_hal *ah, struct ath_desc *ds,
/* this should be enough */ /* this should be enough */
ads->ds_rxstatus8 &= ~AR_RxDone; ads->ds_rxstatus8 &= ~AR_RxDone;
/* clear the rest of the status fields */
if (! pCap->halAutoSleepSupport)
OS_MEMZERO(&(ads->u), sizeof(ads->u));
return AH_TRUE; return AH_TRUE;
} }
@@ -94,18 +139,9 @@ ar5416ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds,
struct ath_rx_status *rs) struct ath_rx_status *rs)
{ {
struct ar5416_desc *ads = AR5416DESC(ds); struct ar5416_desc *ads = AR5416DESC(ds);
struct ar5416_desc *ands = AR5416DESC(nds);
if ((ads->ds_rxstatus8 & AR_RxDone) == 0) if ((ads->ds_rxstatus8 & AR_RxDone) == 0)
return HAL_EINPROGRESS; return HAL_EINPROGRESS;
/*
* Given the use of a self-linked tail be very sure that the hw is
* done with this descriptor; the hw may have done this descriptor
* once and picked it up again...make sure the hw has moved on.
*/
if ((ands->ds_rxstatus8 & AR_RxDone) == 0
&& OS_REG_READ(ah, AR_RXDP) == pa)
return HAL_EINPROGRESS;
rs->rs_status = 0; rs->rs_status = 0;
rs->rs_flags = 0; rs->rs_flags = 0;
@@ -149,8 +149,10 @@ ar5416StopTxDma(struct ath_hal *ah, u_int q)
#define VALID_TX_RATES \ #define VALID_TX_RATES \
((1<<0x0b)|(1<<0x0f)|(1<<0x0a)|(1<<0x0e)|(1<<0x09)|(1<<0x0d)|\ ((1<<0x0b)|(1<<0x0f)|(1<<0x0a)|(1<<0x0e)|(1<<0x09)|(1<<0x0d)|\
(1<<0x08)|(1<<0x0c)|(1<<0x1b)|(1<<0x1a)|(1<<0x1e)|(1<<0x19)|\ (1<<0x08)|(1<<0x0c)|(1<<0x1b)|(1<<0x1a)|(1<<0x1e)|(1<<0x19)|\
(1<<0x1d)|(1<<0x18)|(1<<0x1c)) (1<<0x1d)|(1<<0x18)|(1<<0x1c)|(1<<0x01)|(1<<0x02)|(1<<0x03)|\
#define isValidTxRate(_r) ((1<<(_r)) & VALID_TX_RATES) (1<<0x04)|(1<<0x05)|(1<<0x06)|(1<<0x07)|(1<<0x00))
/* NB: accept HT rates */
#define isValidTxRate(_r) ((1<<((_r) & 0x7f)) & VALID_TX_RATES)
HAL_BOOL HAL_BOOL
ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds, ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
@@ -206,10 +208,11 @@ ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
| SM(ahp->ah_tx_chainmask, AR_ChainSel2) | SM(ahp->ah_tx_chainmask, AR_ChainSel2)
| SM(ahp->ah_tx_chainmask, AR_ChainSel3) | SM(ahp->ah_tx_chainmask, AR_ChainSel3)
; ;
ads->ds_ctl8 = 0; ads->ds_ctl8 = SM(0, AR_AntCtl0);
ads->ds_ctl9 = (txPower << 24); /* XXX? */ ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(txPower, AR_XmitPower1);
ads->ds_ctl10 = (txPower << 24); /* XXX? */ ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(txPower, AR_XmitPower2);
ads->ds_ctl11 = (txPower << 24); /* XXX? */ ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(txPower, AR_XmitPower3);
if (keyIx != HAL_TXKEYIX_INVALID) { if (keyIx != HAL_TXKEYIX_INVALID) {
/* XXX validate key index */ /* XXX validate key index */
ads->ds_ctl1 |= SM(keyIx, AR_DestIdx); ads->ds_ctl1 |= SM(keyIx, AR_DestIdx);
@@ -227,9 +230,20 @@ ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0) ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0)
| (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0) | (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0)
; ;
ads->ds_ctl2 |= SM(rtsctsDuration, AR_BurstDur);
ads->ds_ctl7 |= (rtsctsRate << AR_RTSCTSRate_S); ads->ds_ctl7 |= (rtsctsRate << AR_RTSCTSRate_S);
} }
/*
* Set the TX antenna to 0 for Kite
* To preserve existing behaviour, also set the TPC bits to 0;
* when TPC is enabled these should be filled in appropriately.
*/
if (AR_SREV_KITE(ah)) {
ads->ds_ctl8 = SM(0, AR_AntCtl0);
ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(0, AR_XmitPower1);
ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(0, AR_XmitPower2);
ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(0, AR_XmitPower3);
}
return AH_TRUE; return AH_TRUE;
#undef RTSCTS #undef RTSCTS
} }
@@ -304,8 +318,6 @@ ar5416FillTxDesc(struct ath_hal *ah, struct ath_desc *ds,
return AH_TRUE; return AH_TRUE;
} }
#if 0
HAL_BOOL HAL_BOOL
ar5416ChainTxDesc(struct ath_hal *ah, struct ath_desc *ds, ar5416ChainTxDesc(struct ath_hal *ah, struct ath_desc *ds,
u_int pktLen, u_int pktLen,
@@ -320,6 +332,7 @@ ar5416ChainTxDesc(struct ath_hal *ah, struct ath_desc *ds,
{ {
struct ar5416_desc *ads = AR5416DESC(ds); struct ar5416_desc *ads = AR5416DESC(ds);
uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads); uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads);
struct ath_hal_5416 *ahp = AH5416(ah);
int isaggr = 0; int isaggr = 0;
@@ -335,7 +348,7 @@ ar5416ChainTxDesc(struct ath_hal *ah, struct ath_desc *ds,
} }
if (!firstSeg) { if (!firstSeg) {
ath_hal_memzero(ds->ds_hw, AR5416_DESC_TX_CTL_SZ); OS_MEMZERO(ds->ds_hw, AR5416_DESC_TX_CTL_SZ);
} }
ads->ds_ctl0 = (pktLen & AR_FrameLen); ads->ds_ctl0 = (pktLen & AR_FrameLen);
@@ -349,7 +362,7 @@ ar5416ChainTxDesc(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl0 |= AR_DestIdxValid; ads->ds_ctl0 |= AR_DestIdxValid;
} }
ads->ds_ctl6 = SM(keyType[cipher], AR_EncrType); ads->ds_ctl6 = SM(ahp->ah_keytype[cipher], AR_EncrType);
if (isaggr) { if (isaggr) {
ads->ds_ctl6 |= SM(delims, AR_PadDelim); ads->ds_ctl6 |= SM(delims, AR_PadDelim);
} }
@@ -403,10 +416,10 @@ ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds,
| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel3); | SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel3);
/* NB: no V1 WAR */ /* NB: no V1 WAR */
ads->ds_ctl8 = 0; ads->ds_ctl8 = SM(0, AR_AntCtl0);
ads->ds_ctl9 = (txPower << 24); ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(txPower, AR_XmitPower1);
ads->ds_ctl10 = (txPower << 24); ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(txPower, AR_XmitPower2);
ads->ds_ctl11 = (txPower << 24); ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(txPower, AR_XmitPower3);
ads->ds_ctl6 &= ~(0xffff); ads->ds_ctl6 &= ~(0xffff);
ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen); ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
@@ -415,7 +428,18 @@ ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds,
/* XXX validate rtsctsDuration */ /* XXX validate rtsctsDuration */
ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0) ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0)
| (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0); | (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0);
ads->ds_ctl2 |= SM(rtsctsDuration, AR_BurstDur); }
/*
* Set the TX antenna to 0 for Kite
* To preserve existing behaviour, also set the TPC bits to 0;
* when TPC is enabled these should be filled in appropriately.
*/
if (AR_SREV_KITE(ah)) {
ads->ds_ctl8 = SM(0, AR_AntCtl0);
ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(0, AR_XmitPower1);
ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(0, AR_XmitPower2);
ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(0, AR_XmitPower3);
} }
return AH_TRUE; return AH_TRUE;
@@ -442,7 +466,6 @@ ar5416SetupLastTxDesc(struct ath_hal *ah, struct ath_desc *ds,
return AH_TRUE; return AH_TRUE;
} }
#endif /* 0 */
#ifdef AH_NEED_DESC_SWAP #ifdef AH_NEED_DESC_SWAP
/* Swap transmit descriptor */ /* Swap transmit descriptor */
@@ -574,7 +597,6 @@ ar5416ProcTxDesc(struct ath_hal *ah,
return HAL_OK; return HAL_OK;
} }
#if 0
HAL_BOOL HAL_BOOL
ar5416SetGlobalTxTimeout(struct ath_hal *ah, u_int tu) ar5416SetGlobalTxTimeout(struct ath_hal *ah, u_int tu)
{ {
@@ -601,13 +623,49 @@ ar5416GetGlobalTxTimeout(struct ath_hal *ah)
void void
ar5416Set11nRateScenario(struct ath_hal *ah, struct ath_desc *ds, ar5416Set11nRateScenario(struct ath_hal *ah, struct ath_desc *ds,
u_int durUpdateEn, u_int rtsctsRate, u_int durUpdateEn, u_int rtsctsRate,
HAL_11N_RATE_SERIES series[], u_int nseries) HAL_11N_RATE_SERIES series[], u_int nseries, u_int flags)
{ {
struct ar5416_desc *ads = AR5416DESC(ds); struct ar5416_desc *ads = AR5416DESC(ds);
uint32_t ds_ctl0;
HALASSERT(nseries == 4); HALASSERT(nseries == 4);
(void)nseries; (void)nseries;
/*
* XXX since the upper layers doesn't know the current chainmask
* XXX setup, just override its decisions here.
* XXX The upper layers need to be taught this!
*/
if (series[0].Tries != 0)
series[0].ChSel = AH5416(ah)->ah_tx_chainmask;
if (series[1].Tries != 0)
series[1].ChSel = AH5416(ah)->ah_tx_chainmask;
if (series[2].Tries != 0)
series[2].ChSel = AH5416(ah)->ah_tx_chainmask;
if (series[3].Tries != 0)
series[3].ChSel = AH5416(ah)->ah_tx_chainmask;
/*
* Only one of RTS and CTS enable must be set.
* If a frame has both set, just do RTS protection -
* that's enough to satisfy legacy protection.
*/
if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
ds_ctl0 = ads->ds_ctl0;
if (flags & HAL_TXDESC_RTSENA) {
ds_ctl0 &= ~AR_CTSEnable;
ds_ctl0 |= AR_RTSEnable;
} else {
ds_ctl0 &= ~AR_RTSEnable;
ds_ctl0 |= AR_CTSEnable;
}
ads->ds_ctl0 = ds_ctl0;
} else {
ads->ds_ctl0 =
(ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
}
ads->ds_ctl2 = set11nTries(series, 0) ads->ds_ctl2 = set11nTries(series, 0)
| set11nTries(series, 1) | set11nTries(series, 1)
@@ -631,27 +689,6 @@ ar5416Set11nRateScenario(struct ath_hal *ah, struct ath_desc *ds,
| set11nRateFlags(series, 2) | set11nRateFlags(series, 2)
| set11nRateFlags(series, 3) | set11nRateFlags(series, 3)
| SM(rtsctsRate, AR_RTSCTSRate); | SM(rtsctsRate, AR_RTSCTSRate);
/*
* Enable RTSCTS if any of the series is flagged for RTSCTS,
* but only if CTS is not enabled.
*/
/*
* FIXME : the entire RTS/CTS handling should be moved to this
* function (by passing the global RTS/CTS flags to this function).
* currently it is split between this function and the
* setupFiirstDescriptor. with this current implementation there
* is an implicit assumption that setupFirstDescriptor is called
* before this function.
*/
if (((series[0].RateFlags & HAL_RATESERIES_RTS_CTS) ||
(series[1].RateFlags & HAL_RATESERIES_RTS_CTS) ||
(series[2].RateFlags & HAL_RATESERIES_RTS_CTS) ||
(series[3].RateFlags & HAL_RATESERIES_RTS_CTS) ) &&
(ads->ds_ctl0 & AR_CTSEnable) == 0) {
ads->ds_ctl0 |= AR_RTSEnable;
ads->ds_ctl0 &= ~AR_CTSEnable;
}
} }
void void
@@ -692,4 +729,380 @@ ar5416Set11nBurstDuration(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl2 &= ~AR_BurstDur; ads->ds_ctl2 &= ~AR_BurstDur;
ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur); ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
} }
#endif
/*
* Retrieve the rate table from the given TX completion descriptor
*/
HAL_BOOL
ar5416GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries)
{
const struct ar5416_desc *ads = AR5416DESC_CONST(ds0);
rates[0] = MS(ads->ds_ctl3, AR_XmitRate0);
rates[1] = MS(ads->ds_ctl3, AR_XmitRate1);
rates[2] = MS(ads->ds_ctl3, AR_XmitRate2);
rates[3] = MS(ads->ds_ctl3, AR_XmitRate3);
tries[0] = MS(ads->ds_ctl2, AR_XmitDataTries0);
tries[1] = MS(ads->ds_ctl2, AR_XmitDataTries1);
tries[2] = MS(ads->ds_ctl2, AR_XmitDataTries2);
tries[3] = MS(ads->ds_ctl2, AR_XmitDataTries3);
return AH_TRUE;
}
/*
* TX queue management routines - AR5416 and later chipsets
*/
/*
* Allocate and initialize a tx DCU/QCU combination.
*/
int
ar5416SetupTxQueue(struct ath_hal *ah, HAL_TX_QUEUE type,
const HAL_TXQ_INFO *qInfo)
{
struct ath_hal_5212 *ahp = AH5212(ah);
HAL_TX_QUEUE_INFO *qi;
HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
int q, defqflags;
/* by default enable OK+ERR+DESC+URN interrupts */
defqflags = HAL_TXQ_TXOKINT_ENABLE
| HAL_TXQ_TXERRINT_ENABLE
| HAL_TXQ_TXDESCINT_ENABLE
| HAL_TXQ_TXURNINT_ENABLE;
/* XXX move queue assignment to driver */
switch (type) {
case HAL_TX_QUEUE_BEACON:
q = pCap->halTotalQueues-1; /* highest priority */
defqflags |= HAL_TXQ_DBA_GATED
| HAL_TXQ_CBR_DIS_QEMPTY
| HAL_TXQ_ARB_LOCKOUT_GLOBAL
| HAL_TXQ_BACKOFF_DISABLE;
break;
case HAL_TX_QUEUE_CAB:
q = pCap->halTotalQueues-2; /* next highest priority */
defqflags |= HAL_TXQ_DBA_GATED
| HAL_TXQ_CBR_DIS_QEMPTY
| HAL_TXQ_CBR_DIS_BEMPTY
| HAL_TXQ_ARB_LOCKOUT_GLOBAL
| HAL_TXQ_BACKOFF_DISABLE;
break;
case HAL_TX_QUEUE_PSPOLL:
q = 1; /* lowest priority */
defqflags |= HAL_TXQ_DBA_GATED
| HAL_TXQ_CBR_DIS_QEMPTY
| HAL_TXQ_CBR_DIS_BEMPTY
| HAL_TXQ_ARB_LOCKOUT_GLOBAL
| HAL_TXQ_BACKOFF_DISABLE;
break;
case HAL_TX_QUEUE_UAPSD:
q = pCap->halTotalQueues-3; /* nextest highest priority */
if (ahp->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: no available UAPSD tx queue\n", __func__);
return -1;
}
break;
case HAL_TX_QUEUE_DATA:
for (q = 0; q < pCap->halTotalQueues; q++)
if (ahp->ah_txq[q].tqi_type == HAL_TX_QUEUE_INACTIVE)
break;
if (q == pCap->halTotalQueues) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: no available tx queue\n", __func__);
return -1;
}
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: bad tx queue type %u\n", __func__, type);
return -1;
}
HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: queue %u\n", __func__, q);
qi = &ahp->ah_txq[q];
if (qi->tqi_type != HAL_TX_QUEUE_INACTIVE) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: tx queue %u already active\n",
__func__, q);
return -1;
}
OS_MEMZERO(qi, sizeof(HAL_TX_QUEUE_INFO));
qi->tqi_type = type;
if (qInfo == AH_NULL) {
qi->tqi_qflags = defqflags;
qi->tqi_aifs = INIT_AIFS;
qi->tqi_cwmin = HAL_TXQ_USEDEFAULT; /* NB: do at reset */
qi->tqi_cwmax = INIT_CWMAX;
qi->tqi_shretry = INIT_SH_RETRY;
qi->tqi_lgretry = INIT_LG_RETRY;
qi->tqi_physCompBuf = 0;
} else {
qi->tqi_physCompBuf = qInfo->tqi_compBuf;
(void) ar5212SetTxQueueProps(ah, q, qInfo);
}
/* NB: must be followed by ar5212ResetTxQueue */
return q;
}
/*
* Update the h/w interrupt registers to reflect a tx q's configuration.
*/
static void
setTxQInterrupts(struct ath_hal *ah, HAL_TX_QUEUE_INFO *qi)
{
struct ath_hal_5212 *ahp = AH5212(ah);
HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
"%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", __func__,
ahp->ah_txOkInterruptMask, ahp->ah_txErrInterruptMask,
ahp->ah_txDescInterruptMask, ahp->ah_txEolInterruptMask,
ahp->ah_txUrnInterruptMask);
OS_REG_WRITE(ah, AR_IMR_S0,
SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
| SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC)
);
OS_REG_WRITE(ah, AR_IMR_S1,
SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
| SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL)
);
OS_REG_RMW_FIELD(ah, AR_IMR_S2,
AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
}
/*
* Set the retry, aifs, cwmin/max, readyTime regs for specified queue
* Assumes:
* phwChannel has been set to point to the current channel
*/
HAL_BOOL
ar5416ResetTxQueue(struct ath_hal *ah, u_int q)
{
struct ath_hal_5212 *ahp = AH5212(ah);
HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
HAL_TX_QUEUE_INFO *qi;
uint32_t cwMin, chanCwMin, value, qmisc, dmisc;
if (q >= pCap->halTotalQueues) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n",
__func__, q);
return AH_FALSE;
}
qi = &ahp->ah_txq[q];
if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: inactive queue %u\n",
__func__, q);
return AH_TRUE; /* XXX??? */
}
HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: reset queue %u\n", __func__, q);
if (qi->tqi_cwmin == HAL_TXQ_USEDEFAULT) {
/*
* Select cwmin according to channel type.
* NB: chan can be NULL during attach
*/
if (chan && IEEE80211_IS_CHAN_B(chan))
chanCwMin = INIT_CWMIN_11B;
else
chanCwMin = INIT_CWMIN;
/* make sure that the CWmin is of the form (2^n - 1) */
for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1)
;
} else
cwMin = qi->tqi_cwmin;
/* set cwMin/Max and AIFS values */
OS_REG_WRITE(ah, AR_DLCL_IFS(q),
SM(cwMin, AR_D_LCL_IFS_CWMIN)
| SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
| SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
/* Set retry limit values */
OS_REG_WRITE(ah, AR_DRETRY_LIMIT(q),
SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
| SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
| SM(qi->tqi_lgretry, AR_D_RETRY_LIMIT_FR_LG)
| SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
);
/* NB: always enable early termination on the QCU */
qmisc = AR_Q_MISC_DCU_EARLY_TERM_REQ
| SM(AR_Q_MISC_FSP_ASAP, AR_Q_MISC_FSP);
/* NB: always enable DCU to wait for next fragment from QCU */
dmisc = AR_D_MISC_FRAG_WAIT_EN;
/* Enable exponential backoff window */
dmisc |= AR_D_MISC_BKOFF_PERSISTENCE;
/*
* The chip reset default is to use a DCU backoff threshold of 0x2.
* Restore this when programming the DCU MISC register.
*/
dmisc |= 0x2;
/* multiqueue support */
if (qi->tqi_cbrPeriod) {
OS_REG_WRITE(ah, AR_QCBRCFG(q),
SM(qi->tqi_cbrPeriod,AR_Q_CBRCFG_CBR_INTERVAL)
| SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_CBR_OVF_THRESH));
qmisc = (qmisc &~ AR_Q_MISC_FSP) | AR_Q_MISC_FSP_CBR;
if (qi->tqi_cbrOverflowLimit)
qmisc |= AR_Q_MISC_CBR_EXP_CNTR_LIMIT;
}
if (qi->tqi_readyTime) {
OS_REG_WRITE(ah, AR_QRDYTIMECFG(q),
SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_INT)
| AR_Q_RDYTIMECFG_ENA);
}
OS_REG_WRITE(ah, AR_DCHNTIME(q),
SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR)
| (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
if (qi->tqi_readyTime &&
(qi->tqi_qflags & HAL_TXQ_RDYTIME_EXP_POLICY_ENABLE))
qmisc |= AR_Q_MISC_RDYTIME_EXP_POLICY;
if (qi->tqi_qflags & HAL_TXQ_DBA_GATED)
qmisc = (qmisc &~ AR_Q_MISC_FSP) | AR_Q_MISC_FSP_DBA_GATED;
if (MS(qmisc, AR_Q_MISC_FSP) != AR_Q_MISC_FSP_ASAP) {
/*
* These are meangingful only when not scheduled asap.
*/
if (qi->tqi_qflags & HAL_TXQ_CBR_DIS_BEMPTY)
qmisc |= AR_Q_MISC_CBR_INCR_DIS0;
else
qmisc &= ~AR_Q_MISC_CBR_INCR_DIS0;
if (qi->tqi_qflags & HAL_TXQ_CBR_DIS_QEMPTY)
qmisc |= AR_Q_MISC_CBR_INCR_DIS1;
else
qmisc &= ~AR_Q_MISC_CBR_INCR_DIS1;
}
if (qi->tqi_qflags & HAL_TXQ_BACKOFF_DISABLE)
dmisc |= AR_D_MISC_POST_FR_BKOFF_DIS;
if (qi->tqi_qflags & HAL_TXQ_FRAG_BURST_BACKOFF_ENABLE)
dmisc |= AR_D_MISC_FRAG_BKOFF_EN;
if (qi->tqi_qflags & HAL_TXQ_ARB_LOCKOUT_GLOBAL)
dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
AR_D_MISC_ARB_LOCKOUT_CNTRL);
else if (qi->tqi_qflags & HAL_TXQ_ARB_LOCKOUT_INTRA)
dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR,
AR_D_MISC_ARB_LOCKOUT_CNTRL);
if (qi->tqi_qflags & HAL_TXQ_IGNORE_VIRTCOL)
dmisc |= SM(AR_D_MISC_VIR_COL_HANDLING_IGNORE,
AR_D_MISC_VIR_COL_HANDLING);
if (qi->tqi_qflags & HAL_TXQ_SEQNUM_INC_DIS)
dmisc |= AR_D_MISC_SEQ_NUM_INCR_DIS;
/*
* Fillin type-dependent bits. Most of this can be
* removed by specifying the queue parameters in the
* driver; it's here for backwards compatibility.
*/
switch (qi->tqi_type) {
case HAL_TX_QUEUE_BEACON: /* beacon frames */
qmisc |= AR_Q_MISC_FSP_DBA_GATED
| AR_Q_MISC_BEACON_USE
| AR_Q_MISC_CBR_INCR_DIS1;
dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
AR_D_MISC_ARB_LOCKOUT_CNTRL)
| AR_D_MISC_BEACON_USE
| AR_D_MISC_POST_FR_BKOFF_DIS;
break;
case HAL_TX_QUEUE_CAB: /* CAB frames */
/*
* No longer Enable AR_Q_MISC_RDYTIME_EXP_POLICY,
* There is an issue with the CAB Queue
* not properly refreshing the Tx descriptor if
* the TXE clear setting is used.
*/
qmisc |= AR_Q_MISC_FSP_DBA_GATED
| AR_Q_MISC_CBR_INCR_DIS1
| AR_Q_MISC_CBR_INCR_DIS0;
if (!qi->tqi_readyTime) {
/*
* NB: don't set default ready time if driver
* has explicitly specified something. This is
* here solely for backwards compatibility.
*/
value = (ahp->ah_beaconInterval
- (ah->ah_config.ah_sw_beacon_response_time -
ah->ah_config.ah_dma_beacon_response_time)
- ah->ah_config.ah_additional_swba_backoff) * 1024;
OS_REG_WRITE(ah, AR_QRDYTIMECFG(q), value | AR_Q_RDYTIMECFG_ENA);
}
dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
AR_D_MISC_ARB_LOCKOUT_CNTRL);
break;
case HAL_TX_QUEUE_PSPOLL:
qmisc |= AR_Q_MISC_CBR_INCR_DIS1;
break;
case HAL_TX_QUEUE_UAPSD:
dmisc |= AR_D_MISC_POST_FR_BKOFF_DIS;
break;
default: /* NB: silence compiler */
break;
}
OS_REG_WRITE(ah, AR_QMISC(q), qmisc);
OS_REG_WRITE(ah, AR_DMISC(q), dmisc);
/* Setup compression scratchpad buffer */
/*
* XXX: calling this asynchronously to queue operation can
* cause unexpected behavior!!!
*/
if (qi->tqi_physCompBuf) {
HALASSERT(qi->tqi_type == HAL_TX_QUEUE_DATA ||
qi->tqi_type == HAL_TX_QUEUE_UAPSD);
OS_REG_WRITE(ah, AR_Q_CBBS, (80 + 2*q));
OS_REG_WRITE(ah, AR_Q_CBBA, qi->tqi_physCompBuf);
OS_REG_WRITE(ah, AR_Q_CBC, HAL_COMP_BUF_MAX_SIZE/1024);
OS_REG_WRITE(ah, AR_Q0_MISC + 4*q,
OS_REG_READ(ah, AR_Q0_MISC + 4*q)
| AR_Q_MISC_QCU_COMP_EN);
}
/*
* Always update the secondary interrupt mask registers - this
* could be a new queue getting enabled in a running system or
* hw getting re-initialized during a reset!
*
* Since we don't differentiate between tx interrupts corresponding
* to individual queues - secondary tx mask regs are always unmasked;
* tx interrupts are enabled/disabled for all queues collectively
* using the primary mask reg
*/
if (qi->tqi_qflags & HAL_TXQ_TXOKINT_ENABLE)
ahp->ah_txOkInterruptMask |= 1 << q;
else
ahp->ah_txOkInterruptMask &= ~(1 << q);
if (qi->tqi_qflags & HAL_TXQ_TXERRINT_ENABLE)
ahp->ah_txErrInterruptMask |= 1 << q;
else
ahp->ah_txErrInterruptMask &= ~(1 << q);
if (qi->tqi_qflags & HAL_TXQ_TXDESCINT_ENABLE)
ahp->ah_txDescInterruptMask |= 1 << q;
else
ahp->ah_txDescInterruptMask &= ~(1 << q);
if (qi->tqi_qflags & HAL_TXQ_TXEOLINT_ENABLE)
ahp->ah_txEolInterruptMask |= 1 << q;
else
ahp->ah_txEolInterruptMask &= ~(1 << q);
if (qi->tqi_qflags & HAL_TXQ_TXURNINT_ENABLE)
ahp->ah_txUrnInterruptMask |= 1 << q;
else
ahp->ah_txUrnInterruptMask &= ~(1 << q);
setTxQInterrupts(ah, qi);
return AH_TRUE;
}
@@ -205,6 +205,29 @@ struct ar5416_desc {
#define AR_STBC2 0x40000000 #define AR_STBC2 0x40000000
#define AR_STBC3 0x80000000 #define AR_STBC3 0x80000000
/* ds_ctl8 */
#define AR_AntCtl0 0x00ffffff
#define AR_AntCtl0_S 0
/* Xmit 0 TPC is AR_XmitPower in ctl0 */
/* ds_ctl9 */
#define AR_AntCtl1 0x00ffffff
#define AR_AntCtl1_S 0
#define AR_XmitPower1 0xff000000
#define AR_XmitPower1_S 24
/* ds_ctl10 */
#define AR_AntCtl2 0x00ffffff
#define AR_AntCtl2_S 0
#define AR_XmitPower2 0xff000000
#define AR_XmitPower2_S 24
/* ds_ctl11 */
#define AR_AntCtl3 0x00ffffff
#define AR_AntCtl3_S 0
#define AR_XmitPower3 0xff000000
#define AR_XmitPower3_S 24
/************* /*************
* TX Status * * TX Status *
*************/ *************/
@@ -387,11 +410,11 @@ struct ar5416_desc {
#define RXSTATUS_OFFSET(ah) 4 #define RXSTATUS_OFFSET(ah) 4
#define RXSTATUS_NUMWORDS(ah) 9 #define RXSTATUS_NUMWORDS(ah) 9
#define RXSTATUS_RATE(ah, ads) \ #define RXSTATUS_RATE(ah, ads) \
(AR_SREV_OWL_20_OR_LATER(ah) ? \ (AR_SREV_5416_V20_OR_LATER(ah) ? \
MS((ads)->ds_rxstatus0, AR_RxRate) : \ MS((ads)->ds_rxstatus0, AR_RxRate) : \
((ads)->ds_rxstatus3 >> 2) & 0xFF) ((ads)->ds_rxstatus3 >> 2) & 0xFF)
#define RXSTATUS_DUPLICATE(ah, ads) \ #define RXSTATUS_DUPLICATE(ah, ads) \
(AR_SREV_OWL_20_OR_LATER(ah) ? \ (AR_SREV_5416_V20_OR_LATER(ah) ? \
MS((ads)->ds_rxstatus3, AR_Parallel40) : \ MS((ads)->ds_rxstatus3, AR_Parallel40) : \
((ads)->ds_rxstatus3 >> 10) & 0x1) ((ads)->ds_rxstatus3 >> 10) & 0x1)
#endif /* _ATH_AR5416_DESC_H_ */ #endif /* _ATH_AR5416_DESC_H_ */
@@ -21,6 +21,25 @@
#include "ar5212/ar5212phy.h" #include "ar5212/ar5212phy.h"
/* For AR_PHY_RADAR0 */
#define AR_PHY_RADAR_0_FFT_ENA 0x80000000
#define AR_PHY_RADAR_EXT 0x9940
#define AR_PHY_RADAR_EXT_ENA 0x00004000
#define AR_PHY_RADAR_1 0x9958
#define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000
#define AR_PHY_RADAR_1_USE_FIR128 0x00400000
#define AR_PHY_RADAR_1_RELPWR_THRESH 0x003F0000
#define AR_PHY_RADAR_1_RELPWR_THRESH_S 16
#define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000
#define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000
#define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000
#define AR_PHY_RADAR_1_RELSTEP_THRESH 0x00001F00
#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
#define AR_PHY_RADAR_1_MAXLEN 0x000000FF
#define AR_PHY_RADAR_1_MAXLEN_S 0
#define AR_PHY_CHIP_ID_REV_0 0x80 /* 5416 Rev 0 (owl 1.0) BB */ #define AR_PHY_CHIP_ID_REV_0 0x80 /* 5416 Rev 0 (owl 1.0) BB */
#define AR_PHY_CHIP_ID_REV_1 0x81 /* 5416 Rev 1 (owl 2.0) BB */ #define AR_PHY_CHIP_ID_REV_1 0x81 /* 5416 Rev 1 (owl 2.0) BB */
@@ -93,6 +112,8 @@
#define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000 #define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000
#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14 #define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
#define AR_PHY_SEARCH_START_DELAY 0x9918 /* search start delay */
#define AR_PHY_EXT_CCA 0x99bc #define AR_PHY_EXT_CCA 0x99bc
#define AR_PHY_EXT_CCA_CYCPWR_THR1 0x0000FE00 #define AR_PHY_EXT_CCA_CYCPWR_THR1 0x0000FE00
#define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9 #define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9
@@ -100,6 +121,13 @@
#define AR_PHY_EXT_MINCCA_PWR_S 23 #define AR_PHY_EXT_MINCCA_PWR_S 23
#define AR_PHY_EXT_CCA_THRESH62 0x007F0000 #define AR_PHY_EXT_CCA_THRESH62 0x007F0000
#define AR_PHY_EXT_CCA_THRESH62_S 16 #define AR_PHY_EXT_CCA_THRESH62_S 16
/*
* This duplicates AR_PHY_EXT_CCA_CYCPWR_THR1; it reads more like
* an ANI register this way.
*/
#define AR_PHY_EXT_TIMING5_CYCPWR_THR1 0x0000FE00
#define AR_PHY_EXT_TIMING5_CYCPWR_THR1_S 9
#define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000 #define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000
#define AR9280_PHY_EXT_MINCCA_PWR_S 16 #define AR9280_PHY_EXT_MINCCA_PWR_S 16
@@ -111,6 +139,9 @@
#define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0 #define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0
#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS 0x99ec
#define AR_PHY_RIFS_INIT_DELAY 0x03ff0000
#define AR_PHY_M_SLEEP 0x99f0 /* sleep control registers */ #define AR_PHY_M_SLEEP 0x99f0 /* sleep control registers */
#define AR_PHY_REFCLKDLY 0x99f4 #define AR_PHY_REFCLKDLY 0x99f4
#define AR_PHY_REFCLKPD 0x99f8 #define AR_PHY_REFCLKPD 0x99f8
@@ -266,4 +297,29 @@
#define AR_PHY_CL_CAL_CTL 0xA358 /* carrier leak cal control */ #define AR_PHY_CL_CAL_CTL 0xA358 /* carrier leak cal control */
#define AR_PHY_CL_CAL_ENABLE 0x00000002 #define AR_PHY_CL_CAL_ENABLE 0x00000002
#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001 #define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001
/* empirically determined "good" CCA value ranges from atheros */
#define AR_PHY_CCA_NOM_VAL_5416_2GHZ -90
#define AR_PHY_CCA_NOM_VAL_5416_5GHZ -100
#define AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ -100
#define AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ -110
#define AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ -80
#define AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ -90
/* ar9280 specific? */
#define AR_PHY_XPA_CFG 0xA3D8
#define AR_PHY_FORCE_XPA_CFG 0x000000001
#define AR_PHY_FORCE_XPA_CFG_S 0
#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000C
#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2
#define AR_PHY_TX_PWRCTRL9 0xa27C
#define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00
#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10
#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000
#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
#define AR_PHY_MODE_ASYNCFIFO 0x80 /* Enable async fifo */
#endif /* _DEV_ATH_AR5416PHY_H_ */ #endif /* _DEV_ATH_AR5416PHY_H_ */
@@ -40,6 +40,7 @@
#define AR_INTR_ASYNC_MASK 0x4030 /* asynchronous interrupt mask */ #define AR_INTR_ASYNC_MASK 0x4030 /* asynchronous interrupt mask */
#define AR_INTR_SYNC_MASK 0x4034 /* synchronous interrupt mask */ #define AR_INTR_SYNC_MASK 0x4034 /* synchronous interrupt mask */
#define AR_INTR_ASYNC_CAUSE 0x4038 /* check pending interrupts */ #define AR_INTR_ASYNC_CAUSE 0x4038 /* check pending interrupts */
#define AR_INTR_ASYNC_CAUSE_CLR 0x4038 /* clear pending interrupts */
#define AR_INTR_ASYNC_ENABLE 0x403c /* enable interrupts */ #define AR_INTR_ASYNC_ENABLE 0x403c /* enable interrupts */
#define AR5416_PCIE_SERDES 0x4040 #define AR5416_PCIE_SERDES 0x4040
#define AR5416_PCIE_SERDES2 0x4044 #define AR5416_PCIE_SERDES2 0x4044
@@ -54,37 +55,38 @@
#define AR_GPIO_OUTPUT_MUX3 0x4068 #define AR_GPIO_OUTPUT_MUX3 0x4068
#define AR_EEPROM_STATUS_DATA 0x407c #define AR_EEPROM_STATUS_DATA 0x407c
#define AR_OBS 0x4080 #define AR_OBS 0x4080
#define AR_RTC_RC 0x7000 /* reset control */
#define AR_RTC_PLL_CONTROL 0x7014 #ifdef AH_SUPPORT_AR9130
#define AR_RTC_RESET 0x7040 /* RTC reset register */ #define AR_RTC_BASE 0x20000
#define AR_RTC_STATUS 0x7044 /* system sleep status */ #else
#define AR_RTC_SLEEP_CLK 0x7048 #define AR_RTC_BASE 0x7000
#define AR_RTC_FORCE_WAKE 0x704c /* control MAC force wake */ #endif /* AH_SUPPORT_AR9130 */
#define AR_RTC_INTR_CAUSE 0x7050 /* RTC interrupt cause/clear */
#define AR_RTC_INTR_ENABLE 0x7054 /* RTC interrupt enable */ #define AR_RTC_RC AR_RTC_BASE + 0x00 /* reset control */
#define AR_RTC_INTR_MASK 0x7058 /* RTC interrupt mask */ #define AR_RTC_PLL_CONTROL AR_RTC_BASE + 0x14
/* AR9280: rf long shift registers */ #define AR_RTC_RESET AR_RTC_BASE + 0x40 /* RTC reset register */
#define AR_AN_RF2G1_CH0 0x7810 #define AR_RTC_STATUS AR_RTC_BASE + 0x44 /* system sleep status */
#define AR_AN_RF5G1_CH0 0x7818 #define AR_RTC_SLEEP_CLK AR_RTC_BASE + 0x48
#define AR_AN_RF2G1_CH1 0x7834 #define AR_RTC_FORCE_WAKE AR_RTC_BASE + 0x4c /* control MAC force wake */
#define AR_AN_RF5G1_CH1 0x783C #define AR_RTC_INTR_CAUSE AR_RTC_BASE + 0x50 /* RTC interrupt cause/clear */
#define AR_AN_TOP2 0x7894 #define AR_RTC_INTR_ENABLE AR_RTC_BASE + 0x54 /* RTC interrupt enable */
#define AR_AN_SYNTH9 0x7868 #define AR_RTC_INTR_MASK AR_RTC_BASE + 0x58 /* RTC interrupt mask */
#define AR9285_AN_RF2G1 0x7820
#define AR9285_AN_RF2G2 0x7824 #ifdef AH_SUPPORT_AR9130
#define AR9285_AN_RF2G3 0x7828 /* RTC_DERIVED_* - only for AR9130 */
#define AR9285_AN_RF2G4 0x782C #define AR_RTC_DERIVED_CLK (AR_RTC_BASE + 0x0038)
#define AR9285_AN_RF2G6 0x7834 #define AR_RTC_DERIVED_CLK_PERIOD 0x0000fffe
#define AR9285_AN_RF2G7 0x7838 #define AR_RTC_DERIVED_CLK_PERIOD_S 1
#define AR9285_AN_RF2G8 0x783C #endif /* AH_SUPPORT_AR9130 */
#define AR9285_AN_RF2G9 0x7840
#define AR9285_AN_RXTXBB1 0x7854
#define AR9285_AN_TOP2 0x7868
#define AR9285_AN_TOP3 0x786c
#define AR9285_AN_TOP4 0x7870
#define AR9285_AN_TOP4_DEFAULT 0x10142c00
#define AR_RESET_TSF 0x8020 #define AR_RESET_TSF 0x8020
/*
* AR_SLEEP1 / AR_SLEEP2 are in the same place as in
* AR5212, however the fields have changed.
*/
#define AR5416_SLEEP1 0x80d4
#define AR5416_SLEEP2 0x80d8
#define AR_RXFIFO_CFG 0x8114 #define AR_RXFIFO_CFG 0x8114
#define AR_PHY_ERR_1 0x812c #define AR_PHY_ERR_1 0x812c
#define AR_PHY_ERR_MASK_1 0x8130 /* mask for AR_PHY_ERR_1 */ #define AR_PHY_ERR_MASK_1 0x8130 /* mask for AR_PHY_ERR_1 */
@@ -127,6 +129,7 @@
#define AR_EXTRCCNT 0x8328 /* extension channel rx clear count */ #define AR_EXTRCCNT 0x8328 /* extension channel rx clear count */
#define AR_SELFGEN_MASK 0x832c /* rx and cal chain masks */ #define AR_SELFGEN_MASK 0x832c /* rx and cal chain masks */
#define AR_PCU_TXBUF_CTRL 0x8340 #define AR_PCU_TXBUF_CTRL 0x8340
#define AR_PCU_MISC_MODE2 0x8344
/* DMA & PCI Registers in PCI space (usable during sleep)*/ /* DMA & PCI Registers in PCI space (usable during sleep)*/
#define AR_RC_AHB 0x00000001 /* AHB reset */ #define AR_RC_AHB 0x00000001 /* AHB reset */
@@ -183,6 +186,12 @@
#define AR_RXCFG_DMASZ_512B 7 #define AR_RXCFG_DMASZ_512B 7
/* MAC Led registers */ /* MAC Led registers */
#define AR_CFG_SCLK_RATE_IND 0x00000003 /* sleep clock indication */
#define AR_CFG_SCLK_RATE_IND_S 0
#define AR_CFG_SCLK_32MHZ 0x00000000 /* Sleep clock rate */
#define AR_CFG_SCLK_4MHZ 0x00000001 /* Sleep clock rate */
#define AR_CFG_SCLK_1MHZ 0x00000002 /* Sleep clock rate */
#define AR_CFG_SCLK_32KHZ 0x00000003 /* Sleep clock rate */
#define AR_MAC_LED_BLINK_SLOW 0x00000008 /* LED slowest blink rate mode */ #define AR_MAC_LED_BLINK_SLOW 0x00000008 /* LED slowest blink rate mode */
#define AR_MAC_LED_BLINK_THRESH_SEL 0x00000070 /* LED blink threshold select */ #define AR_MAC_LED_BLINK_THRESH_SEL 0x00000070 /* LED blink threshold select */
#define AR_MAC_LED_MODE 0x00000380 /* LED mode select */ #define AR_MAC_LED_MODE 0x00000380 /* LED mode select */
@@ -218,6 +227,10 @@
#define AR_AHB_PAGE_SIZE_1K 0x00000000 /* set page-size as 1k */ #define AR_AHB_PAGE_SIZE_1K 0x00000000 /* set page-size as 1k */
#define AR_AHB_PAGE_SIZE_2K 0x00000008 /* set page-size as 2k */ #define AR_AHB_PAGE_SIZE_2K 0x00000008 /* set page-size as 2k */
#define AR_AHB_PAGE_SIZE_4K 0x00000010 /* set page-size as 4k */ #define AR_AHB_PAGE_SIZE_4K 0x00000010 /* set page-size as 4k */
/* Kiwi */
#define AR_AHB_CUSTOM_BURST_EN 0x000000C0 /* set Custom Burst Mode */
#define AR_AHB_CUSTOM_BURST_EN_S 6 /* set Custom Burst Mode */
#define AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL 3 /* set both bits in Async FIFO mode */
/* MAC PCU Registers */ /* MAC PCU Registers */
#define AR_STA_ID1_PRESERVE_SEQNUM 0x20000000 /* Don't replace seq num */ #define AR_STA_ID1_PRESERVE_SEQNUM 0x20000000 /* Don't replace seq num */
@@ -244,6 +257,10 @@
#define AR_ISR_S2_GTT 0x00800000 /* Global transmit timeout */ #define AR_ISR_S2_GTT 0x00800000 /* Global transmit timeout */
#define AR_ISR_S2_TSFOOR 0x40000000 /* RX TSF out of range */ #define AR_ISR_S2_TSFOOR 0x40000000 /* RX TSF out of range */
#define AR_ISR_S5 0x0098
#define AR_ISR_S5_S 0x00d8
#define AR_ISR_S5_TIM_TIMER 0x00000010
#define AR_INTR_SPURIOUS 0xffffffff #define AR_INTR_SPURIOUS 0xffffffff
#define AR_INTR_RTC_IRQ 0x00000001 /* rtc in shutdown state */ #define AR_INTR_RTC_IRQ 0x00000001 /* rtc in shutdown state */
#define AR_INTR_MAC_IRQ 0x00000002 /* pending mac interrupt */ #define AR_INTR_MAC_IRQ 0x00000002 /* pending mac interrupt */
@@ -308,6 +325,10 @@
#define AR_RTC_RC_M 0x00000003 #define AR_RTC_RC_M 0x00000003
#define AR_RTC_RC_MAC_WARM 0x00000001 #define AR_RTC_RC_MAC_WARM 0x00000001
#define AR_RTC_RC_MAC_COLD 0x00000002 #define AR_RTC_RC_MAC_COLD 0x00000002
#ifdef AH_SUPPORT_AR9130
#define AR_RTC_RC_COLD_RESET 0x00000004
#define AR_RTC_RC_WARM_RESET 0x00000008
#endif /* AH_SUPPORT_AR9130 */
#define AR_RTC_PLL_DIV 0x0000001f #define AR_RTC_PLL_DIV 0x0000001f
#define AR_RTC_PLL_DIV_S 0 #define AR_RTC_PLL_DIV_S 0
#define AR_RTC_PLL_DIV2 0x00000020 #define AR_RTC_PLL_DIV2 0x00000020
@@ -323,7 +344,11 @@
#define AR_RTC_RESET_EN 0x00000001 /* Reset RTC bit */ #define AR_RTC_RESET_EN 0x00000001 /* Reset RTC bit */
#define AR_RTC_PM_STATUS_M 0x0000000f /* Pwr Mgmt Status */ #define AR_RTC_PM_STATUS_M 0x0000000f /* Pwr Mgmt Status */
#ifdef AH_SUPPORT_AR9130
#define AR_RTC_STATUS_M 0x0000000f /* RTC Status */
#else
#define AR_RTC_STATUS_M 0x0000003f /* RTC Status */ #define AR_RTC_STATUS_M 0x0000003f /* RTC Status */
#endif /* AH_SUPPORT_AR9130 */
#define AR_RTC_STATUS_SHUTDOWN 0x00000001 #define AR_RTC_STATUS_SHUTDOWN 0x00000001
#define AR_RTC_STATUS_ON 0x00000002 #define AR_RTC_STATUS_ON 0x00000002
#define AR_RTC_STATUS_SLEEP 0x00000004 #define AR_RTC_STATUS_SLEEP 0x00000004
@@ -340,6 +365,13 @@
#define AR_RTC_PLL_CLKSEL_S 8 #define AR_RTC_PLL_CLKSEL_S 8
/* AR9280: rf long shift registers */ /* AR9280: rf long shift registers */
#define AR_AN_RF2G1_CH0 0x7810
#define AR_AN_RF5G1_CH0 0x7818
#define AR_AN_RF2G1_CH1 0x7834
#define AR_AN_RF5G1_CH1 0x783C
#define AR_AN_TOP2 0x7894
#define AR_AN_SYNTH9 0x7868
#define AR_AN_RF2G1_CH0_OB 0x03800000 #define AR_AN_RF2G1_CH0_OB 0x03800000
#define AR_AN_RF2G1_CH0_OB_S 23 #define AR_AN_RF2G1_CH0_OB_S 23
#define AR_AN_RF2G1_CH0_DB 0x1C000000 #define AR_AN_RF2G1_CH0_DB 0x1C000000
@@ -360,6 +392,10 @@
#define AR_AN_RF5G1_CH1_DB5 0x00380000 #define AR_AN_RF5G1_CH1_DB5 0x00380000
#define AR_AN_RF5G1_CH1_DB5_S 19 #define AR_AN_RF5G1_CH1_DB5_S 19
#define AR_AN_TOP1 0x7890
#define AR_AN_TOP1_DACIPMODE 0x00040000
#define AR_AN_TOP1_DACIPMODE_S 18
#define AR_AN_TOP2_XPABIAS_LVL 0xC0000000 #define AR_AN_TOP2_XPABIAS_LVL 0xC0000000
#define AR_AN_TOP2_XPABIAS_LVL_S 30 #define AR_AN_TOP2_XPABIAS_LVL_S 30
#define AR_AN_TOP2_LOCALBIAS 0x00200000 #define AR_AN_TOP2_LOCALBIAS 0x00200000
@@ -370,86 +406,11 @@
#define AR_AN_SYNTH9_REFDIVA 0xf8000000 #define AR_AN_SYNTH9_REFDIVA 0xf8000000
#define AR_AN_SYNTH9_REFDIVA_S 27 #define AR_AN_SYNTH9_REFDIVA_S 27
/* AR9285 Analog registers */
#define AR9285_AN_RF2G1_ENPACAL 0x00000800
#define AR9285_AN_RF2G1_ENPACAL_S 11
#define AR9285_AN_RF2G1_PDPADRV1 0x02000000
#define AR9285_AN_RF2G1_PDPADRV1_S 25
#define AR9285_AN_RF2G1_PDPADRV2 0x01000000
#define AR9285_AN_RF2G1_PDPADRV2_S 24
#define AR9285_AN_RF2G1_PDPAOUT 0x00800000
#define AR9285_AN_RF2G1_PDPAOUT_S 23
#define AR9285_AN_RF2G2_OFFCAL 0x00001000
#define AR9285_AN_RF2G2_OFFCAL_S 12
#define AR9285_AN_RF2G3_PDVCCOMP 0x02000000
#define AR9285_AN_RF2G3_PDVCCOMP_S 25
#define AR9285_AN_RF2G3_OB_0 0x00E00000
#define AR9285_AN_RF2G3_OB_0_S 21
#define AR9285_AN_RF2G3_OB_1 0x001C0000
#define AR9285_AN_RF2G3_OB_1_S 18
#define AR9285_AN_RF2G3_OB_2 0x00038000
#define AR9285_AN_RF2G3_OB_2_S 15
#define AR9285_AN_RF2G3_OB_3 0x00007000
#define AR9285_AN_RF2G3_OB_3_S 12
#define AR9285_AN_RF2G3_OB_4 0x00000E00
#define AR9285_AN_RF2G3_OB_4_S 9
#define AR9285_AN_RF2G3_DB1_0 0x000001C0
#define AR9285_AN_RF2G3_DB1_0_S 6
#define AR9285_AN_RF2G3_DB1_1 0x00000038
#define AR9285_AN_RF2G3_DB1_1_S 3
#define AR9285_AN_RF2G3_DB1_2 0x00000007
#define AR9285_AN_RF2G3_DB1_2_S 0
#define AR9285_AN_RF2G4_DB1_3 0xE0000000
#define AR9285_AN_RF2G4_DB1_3_S 29
#define AR9285_AN_RF2G4_DB1_4 0x1C000000
#define AR9285_AN_RF2G4_DB1_4_S 26
#define AR9285_AN_RF2G4_DB2_0 0x03800000
#define AR9285_AN_RF2G4_DB2_0_S 23
#define AR9285_AN_RF2G4_DB2_1 0x00700000
#define AR9285_AN_RF2G4_DB2_1_S 20
#define AR9285_AN_RF2G4_DB2_2 0x000E0000
#define AR9285_AN_RF2G4_DB2_2_S 17
#define AR9285_AN_RF2G4_DB2_3 0x0001C000
#define AR9285_AN_RF2G4_DB2_3_S 14
#define AR9285_AN_RF2G4_DB2_4 0x00003800
#define AR9285_AN_RF2G4_DB2_4_S 11
#define AR9285_AN_RF2G6_CCOMP 0x00007800
#define AR9285_AN_RF2G6_CCOMP_S 11
#define AR9285_AN_RF2G6_OFFS 0x03f00000
#define AR9285_AN_RF2G6_OFFS_S 20
#define AR9271_AN_RF2G6_OFFS 0x07f00000 #define AR9271_AN_RF2G6_OFFS 0x07f00000
#define AR9271_AN_RF2G6_OFFS_S 20 #define AR9271_AN_RF2G6_OFFS_S 20
#define AR9285_AN_RF2G7_PWDDB 0x00000002
#define AR9285_AN_RF2G7_PWDDB_S 1
#define AR9285_AN_RF2G7_PADRVGN2TAB0 0xE0000000
#define AR9285_AN_RF2G7_PADRVGN2TAB0_S 29
#define AR9285_AN_RF2G8_PADRVGN2TAB0 0x0001C000
#define AR9285_AN_RF2G8_PADRVGN2TAB0_S 14
#define AR9285_AN_RXTXBB1_PDRXTXBB1 0x00000020
#define AR9285_AN_RXTXBB1_PDRXTXBB1_S 5
#define AR9285_AN_RXTXBB1_PDV2I 0x00000080
#define AR9285_AN_RXTXBB1_PDV2I_S 7
#define AR9285_AN_RXTXBB1_PDDACIF 0x00000100
#define AR9285_AN_RXTXBB1_PDDACIF_S 8
#define AR9285_AN_RXTXBB1_SPARE9 0x00000001
#define AR9285_AN_RXTXBB1_SPARE9_S 0
#define AR9285_AN_TOP3_XPABIAS_LVL 0x0000000C
#define AR9285_AN_TOP3_XPABIAS_LVL_S 2
#define AR9285_AN_TOP3_PWDDAC 0x00800000
#define AR9285_AN_TOP3_PWDDAC_S 23
/* Sleep control */ /* Sleep control */
#define AR5416_SLEEP1_ASSUME_DTIM 0x00080000
#define AR5416_SLEEP1_CAB_TIMEOUT 0xFFE00000 /* Cab timeout (TU) */ #define AR5416_SLEEP1_CAB_TIMEOUT 0xFFE00000 /* Cab timeout (TU) */
#define AR5416_SLEEP1_CAB_TIMEOUT_S 22 #define AR5416_SLEEP1_CAB_TIMEOUT_S 22
@@ -495,6 +456,31 @@
#define AR_PCU_CLEAR_VMF 0x01000000 /* clear vmf mode (fast cc)*/ #define AR_PCU_CLEAR_VMF 0x01000000 /* clear vmf mode (fast cc)*/
#define AR_PCU_CLEAR_BA_VALID 0x04000000 /* clear ba state */ #define AR_PCU_CLEAR_BA_VALID 0x04000000 /* clear ba state */
#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE 0x00000002
#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT 0x00000004
/*
* This bit enables the Multicast search based on both MAC Address and Key ID.
* If bit is 0, then Multicast search is based on MAC address only.
* For Merlin and above only.
*/
#define AR_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE 0x00000040
#define AR_PCU_MISC_MODE2_ENABLE_AGGWEP 0x00020000 /* Kiwi or later? */
#define AR_PCU_MISC_MODE2_HWWAR1 0x00100000
#define AR_PCU_MISC_MODE2_HWWAR2 0x02000000
/* For Kiwi */
#define AR_MAC_PCU_ASYNC_FIFO_REG3 0x8358
#define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL 0x00000400
#define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000
/* TSF2. For Kiwi only */
#define AR_TSF2_L32 0x8390
#define AR_TSF2_U32 0x8394
/* MAC Direct Connect Control. For Kiwi only */
#define AR_DIRECT_CONNECT 0x83A0
#define AR_DC_AP_STA_EN 0x00000001
/* GPIO Interrupt */ /* GPIO Interrupt */
#define AR_INTR_GPIO 0x3FF00000 /* gpio interrupted */ #define AR_INTR_GPIO 0x3FF00000 /* gpio interrupted */
#define AR_INTR_GPIO_S 20 #define AR_INTR_GPIO_S 20
@@ -521,12 +507,25 @@
#define AR_GPIO_INTR_POL_VAL 0x1FFF #define AR_GPIO_INTR_POL_VAL 0x1FFF
#define AR_GPIO_INTR_POL_VAL_S 0 #define AR_GPIO_INTR_POL_VAL_S 0
#define AR_GPIO_JTAG_DISABLE 0x00020000
#define AR_2040_JOINED_RX_CLEAR 0x00000001 /* use ctl + ext rx_clear for cca */ #define AR_2040_JOINED_RX_CLEAR 0x00000001 /* use ctl + ext rx_clear for cca */
#define AR_PCU_TXBUF_CTRL_SIZE_MASK 0x7FF #define AR_PCU_TXBUF_CTRL_SIZE_MASK 0x7FF
#define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700 #define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700
#define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380 #define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380
/* IFS, SIFS, slot, etc for Async FIFO mode (Kiwi) */
#define AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR 0x000003AB
#define AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR 0x16001D56
#define AR_USEC_ASYNC_FIFO_DUR 0x12e00074
#define AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR 0x00000420
#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR 0x0000A5EB
/* Used by Kiwi Async FIFO */
#define AR_MAC_PCU_LOGIC_ANALYZER 0x8264
#define AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768 0x20000000
/* Eeprom defines */ /* Eeprom defines */
#define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff #define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff
#define AR_EEPROM_STATUS_DATA_VAL_S 0 #define AR_EEPROM_STATUS_DATA_VAL_S 0
@@ -535,6 +534,17 @@
#define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 #define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000
#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000
/*
* AR5212 defines the MAC revision mask as 0xF, but both ath9k and
* the Atheros HAL define it as 0x7.
*
* What this means however is AR5416 silicon revisions have
* changed. The below macros are for what is contained in the
* lower four bits; if the lower three bits are taken into account
* the revisions become 1.0 => 0x0, 2.0 => 0x1, 2.2 => 0x2.
*/
/* These are the legacy revisions, with a four bit AR_SREV_REVISION mask */
#define AR_SREV_REVISION_OWL_10 0x08 #define AR_SREV_REVISION_OWL_10 0x08
#define AR_SREV_REVISION_OWL_20 0x09 #define AR_SREV_REVISION_OWL_20 0x09
#define AR_SREV_REVISION_OWL_22 0x0a #define AR_SREV_REVISION_OWL_22 0x0a
@@ -545,9 +555,13 @@
#define AR_RAD2122_SREV_MAJOR 0xf0 /* Fowl: 2+5G/2x2 */ #define AR_RAD2122_SREV_MAJOR 0xf0 /* Fowl: 2+5G/2x2 */
/* Test macro for owl 1.0 */ /* Test macro for owl 1.0 */
#define IS_5416V1(_ah) ((_ah)->ah_macRev == AR_SREV_REVISION_OWL_10) #define IS_5416V1(_ah) (AR_SREV_OWL((_ah)) && AH_PRIVATE((_ah))->ah_macRev == AR_SREV_REVISION_OWL_10)
#define IS_5416V2(_ah) ((_ah)->ah_macRev >= AR_SREV_REVISION_OWL_20) #define IS_5416V2(_ah) (AR_SREV_OWL((_ah)) && AH_PRIVATE((_ah))->ah_macRev >= AR_SREV_REVISION_OWL_20)
#define IS_5416V2_2(_ah) ((_ah)->ah_macRev == AR_SREV_REVISION_OWL_22) #define IS_5416V2_2(_ah) (AR_SREV_OWL((_ah)) && AH_PRIVATE((_ah))->ah_macRev == AR_SREV_REVISION_OWL_22)
/* Misc; compatibility with Atheros HAL */
#define AR_SREV_5416_V20_OR_LATER(_ah) (AR_SREV_HOWL((_ah)) || AR_SREV_OWL_20_OR_LATER(_ah))
#define AR_SREV_5416_V22_OR_LATER(_ah) (AR_SREV_HOWL((_ah)) || AR_SREV_OWL_22_OR_LATER(_ah))
/* Expanded Mac Silicon Rev (16 bits starting with Sowl) */ /* Expanded Mac Silicon Rev (16 bits starting with Sowl) */
#define AR_XSREV_ID 0xFFFFFFFF /* Chip ID */ #define AR_XSREV_ID 0xFFFFFFFF /* Chip ID */
@@ -564,10 +578,22 @@
#define AR_XSREV_VERSION_OWL_PCI 0x0D #define AR_XSREV_VERSION_OWL_PCI 0x0D
#define AR_XSREV_VERSION_OWL_PCIE 0x0C #define AR_XSREV_VERSION_OWL_PCIE 0x0C
/*
* These are from ath9k/Atheros and assume an AR_SREV version mask
* of 0x07, rather than 0x0F which is being used in the FreeBSD HAL.
* Thus, don't use these values as they're incorrect here; use
* AR_SREV_REVISION_OWL_{10,20,22}.
*/
#if 0
#define AR_XSREV_REVISION_OWL_10 0 /* Owl 1.0 */ #define AR_XSREV_REVISION_OWL_10 0 /* Owl 1.0 */
#define AR_XSREV_REVISION_OWL_20 1 /* Owl 2.0/2.1 */ #define AR_XSREV_REVISION_OWL_20 1 /* Owl 2.0/2.1 */
#define AR_XSREV_REVISION_OWL_22 2 /* Owl 2.2 */ #define AR_XSREV_REVISION_OWL_22 2 /* Owl 2.2 */
#define AR_XSREV_VERSION_SOWL 0x40 #endif
#define AR_XSREV_VERSION_HOWL 0x14 /* Howl (AR9130) */
#define AR_XSREV_VERSION_SOWL 0x40 /* Sowl (AR9160) */
#define AR_XSREV_REVISION_SOWL_10 0 /* Sowl 1.0 */ #define AR_XSREV_REVISION_SOWL_10 0 /* Sowl 1.0 */
#define AR_XSREV_REVISION_SOWL_11 1 /* Sowl 1.1 */ #define AR_XSREV_REVISION_SOWL_11 1 /* Sowl 1.1 */
#define AR_XSREV_VERSION_MERLIN 0x80 /* Merlin Version */ #define AR_XSREV_VERSION_MERLIN 0x80 /* Merlin Version */
@@ -578,47 +604,118 @@
#define AR_XSREV_REVISION_KITE_10 0 /* Kite 1.0 */ #define AR_XSREV_REVISION_KITE_10 0 /* Kite 1.0 */
#define AR_XSREV_REVISION_KITE_11 1 /* Kite 1.1 */ #define AR_XSREV_REVISION_KITE_11 1 /* Kite 1.1 */
#define AR_XSREV_REVISION_KITE_12 2 /* Kite 1.2 */ #define AR_XSREV_REVISION_KITE_12 2 /* Kite 1.2 */
#define AR_XSREV_VERSION_KIWI 0x180 /* Kiwi (AR9287) */
#define AR_XSREV_REVISION_KIWI_10 0
#define AR_XSREV_REVISION_KIWI_11 1
#define AR_XSREV_REVISION_KIWI_12 2
#define AR_XSREV_REVISION_KIWI_13 3
/* Owl (AR5416) */
#define AR_SREV_OWL(_ah) \
((AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_OWL_PCI) || \
(AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_OWL_PCIE))
#define AR_SREV_OWL_20_OR_LATER(_ah) \ #define AR_SREV_OWL_20_OR_LATER(_ah) \
(AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_SOWL || \ ((AR_SREV_OWL(_ah) && \
AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_OWL_20) AH_PRIVATE((_ah))->ah_macRev >= AR_SREV_REVISION_OWL_20) || \
AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_HOWL)
#define AR_SREV_OWL_22_OR_LATER(_ah) \ #define AR_SREV_OWL_22_OR_LATER(_ah) \
(AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_SOWL || \ ((AR_SREV_OWL(_ah) && \
AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_OWL_22) AH_PRIVATE((_ah))->ah_macRev >= AR_SREV_REVISION_OWL_22) || \
AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_HOWL)
/* Howl (AR9130) */
#define AR_SREV_HOWL(_ah) \
(AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_HOWL)
#define AR_SREV_9100(_ah) AR_SREV_HOWL(_ah)
/* Sowl (AR9160) */
#define AR_SREV_SOWL(_ah) \ #define AR_SREV_SOWL(_ah) \
(AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_SOWL) (AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_SOWL)
#define AR_SREV_SOWL_10_OR_LATER(_ah) \ #define AR_SREV_SOWL_10_OR_LATER(_ah) \
(AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_SOWL) (AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_SOWL)
#define AR_SREV_SOWL_11(_ah) \ #define AR_SREV_SOWL_11(_ah) \
(AR_SREV_SOWL(_ah) && \ (AR_SREV_SOWL(_ah) && \
AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_SOWL_11) AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_SOWL_11)
/* Merlin (AR9280) */
#define AR_SREV_MERLIN(_ah) \ #define AR_SREV_MERLIN(_ah) \
(AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_MERLIN) (AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_MERLIN)
#define AR_SREV_MERLIN_10_OR_LATER(_ah) \ #define AR_SREV_MERLIN_10_OR_LATER(_ah) \
(AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_MERLIN) (AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_MERLIN)
#define AR_SREV_MERLIN_20(_ah) \ #define AR_SREV_MERLIN_20(_ah) \
(AR_SREV_MERLIN(_ah) && \ (AR_SREV_MERLIN(_ah) && \
AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_MERLIN_20) AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_MERLIN_20)
#define AR_SREV_MERLIN_20_OR_LATER(_ah) \ #define AR_SREV_MERLIN_20_OR_LATER(_ah) \
(AR_SREV_MERLIN_20(_ah) || \ ((AH_PRIVATE((_ah))->ah_macVersion > AR_XSREV_VERSION_MERLIN) || \
AH_PRIVATE((_ah))->ah_macVersion > AR_XSREV_VERSION_MERLIN) (AR_SREV_MERLIN((_ah)) && \
AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_MERLIN_20))
/* Kite (AR9285) */
#define AR_SREV_KITE(_ah) \ #define AR_SREV_KITE(_ah) \
(AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_KITE) (AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_KITE)
#define AR_SREV_KITE_10_OR_LATER(_ah) \ #define AR_SREV_KITE_10_OR_LATER(_ah) \
(AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_KITE) (AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_KITE)
#define AR_SREV_KITE_11(_ah) \ #define AR_SREV_KITE_11(_ah) \
(AR_SREV_KITE(ah) && \ (AR_SREV_KITE(ah) && \
AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_KITE_11) AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_KITE_11)
#define AR_SREV_KITE_11_OR_LATER(_ah) \ #define AR_SREV_KITE_11_OR_LATER(_ah) \
(AR_SREV_KITE_11(_ah) || \ ((AH_PRIVATE((_ah))->ah_macVersion > AR_XSREV_VERSION_KITE) || \
AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KITE_11) (AR_SREV_KITE((_ah)) && \
AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KITE_11))
#define AR_SREV_KITE_12(_ah) \ #define AR_SREV_KITE_12(_ah) \
(AR_SREV_KITE(ah) && \ (AR_SREV_KITE(ah) && \
AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_KITE_12) AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_KITE_12)
#define AR_SREV_KITE_12_OR_LATER(_ah) \ #define AR_SREV_KITE_12_OR_LATER(_ah) \
(AR_SREV_KITE_12(_ah) || \ ((AH_PRIVATE((_ah))->ah_macVersion > AR_XSREV_VERSION_KITE) || \
AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KITE_12) (AR_SREV_KITE((_ah)) && \
AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KITE_12))
#define AR_SREV_9285E_20(_ah) \
(AR_SREV_KITE_12_OR_LATER(_ah) && \
((OS_REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
#define AR_SREV_KIWI(_ah) \
(AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_KIWI)
#define AR_SREV_KIWI_11_OR_LATER(_ah) \
(AR_SREV_KIWI(_ah) && \
AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KIWI_11)
#define AR_SREV_KIWI_11(_ah) \
(AR_SREV_KIWI(_ah) && \
AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_KIWI_11)
#define AR_SREV_KIWI_12(_ah) \
(AR_SREV_KIWI(_ah) && \
AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_KIWI_12)
#define AR_SREV_KIWI_12_OR_LATER(_ah) \
(AR_SREV_KIWI(_ah) && \
AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KIWI_12)
#define AR_SREV_KIWI_13_OR_LATER(_ah) \
(AR_SREV_KIWI(_ah) && \
AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_KIWI_13)
/* Not yet implemented chips */
#define AR_SREV_9271(_ah) 0
#endif /* _DEV_ATH_AR5416REG_H */ #endif /* _DEV_ATH_AR5416REG_H */
@@ -0,0 +1,669 @@
/*
* Copyright (c) 2010 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.
*
* $FreeBSD$
*/
static const uint32_t ar5416Modes_9100[][6] = {
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
{ 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
{ 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
{ 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
{ 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
{ 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
{ 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
{ 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
{ 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
{ 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
{ 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
{ 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
{ 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
{ 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
{ 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
{ 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
{ 0x00009850, 0x6c48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6c48b0e2, 0x6c48b0e2 },
{ 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
{ 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e },
{ 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
{ 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
{ 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
{ 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
{ 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
{ 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
{ 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
{ 0x00009940, 0x00750604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 },
{ 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
{ 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e },
{ 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff },
{ 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
{ 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
{ 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
{ 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
{ 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 },
{ 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
{ 0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
{ 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
{ 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
{ 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
{ 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
{ 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
{ 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
{ 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
{ 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
{ 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
{ 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
{ 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
{ 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
{ 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
{ 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
{ 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
{ 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
{ 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
};
static const uint32_t ar5416Common_9100[][2] = {
/* Addr allmodes */
{ 0x0000000c, 0x00000000 },
{ 0x00000030, 0x00020015 },
{ 0x00000034, 0x00000005 },
{ 0x00000040, 0x00000000 },
{ 0x00000044, 0x00000008 },
{ 0x00000048, 0x00000008 },
{ 0x0000004c, 0x00000010 },
{ 0x00000050, 0x00000000 },
{ 0x00000054, 0x0000001f },
{ 0x00000800, 0x00000000 },
{ 0x00000804, 0x00000000 },
{ 0x00000808, 0x00000000 },
{ 0x0000080c, 0x00000000 },
{ 0x00000810, 0x00000000 },
{ 0x00000814, 0x00000000 },
{ 0x00000818, 0x00000000 },
{ 0x0000081c, 0x00000000 },
{ 0x00000820, 0x00000000 },
{ 0x00000824, 0x00000000 },
{ 0x00001040, 0x002ffc0f },
{ 0x00001044, 0x002ffc0f },
{ 0x00001048, 0x002ffc0f },
{ 0x0000104c, 0x002ffc0f },
{ 0x00001050, 0x002ffc0f },
{ 0x00001054, 0x002ffc0f },
{ 0x00001058, 0x002ffc0f },
{ 0x0000105c, 0x002ffc0f },
{ 0x00001060, 0x002ffc0f },
{ 0x00001064, 0x002ffc0f },
{ 0x00001230, 0x00000000 },
{ 0x00001270, 0x00000000 },
{ 0x00001038, 0x00000000 },
{ 0x00001078, 0x00000000 },
{ 0x000010b8, 0x00000000 },
{ 0x000010f8, 0x00000000 },
{ 0x00001138, 0x00000000 },
{ 0x00001178, 0x00000000 },
{ 0x000011b8, 0x00000000 },
{ 0x000011f8, 0x00000000 },
{ 0x00001238, 0x00000000 },
{ 0x00001278, 0x00000000 },
{ 0x000012b8, 0x00000000 },
{ 0x000012f8, 0x00000000 },
{ 0x00001338, 0x00000000 },
{ 0x00001378, 0x00000000 },
{ 0x000013b8, 0x00000000 },
{ 0x000013f8, 0x00000000 },
{ 0x00001438, 0x00000000 },
{ 0x00001478, 0x00000000 },
{ 0x000014b8, 0x00000000 },
{ 0x000014f8, 0x00000000 },
{ 0x00001538, 0x00000000 },
{ 0x00001578, 0x00000000 },
{ 0x000015b8, 0x00000000 },
{ 0x000015f8, 0x00000000 },
{ 0x00001638, 0x00000000 },
{ 0x00001678, 0x00000000 },
{ 0x000016b8, 0x00000000 },
{ 0x000016f8, 0x00000000 },
{ 0x00001738, 0x00000000 },
{ 0x00001778, 0x00000000 },
{ 0x000017b8, 0x00000000 },
{ 0x000017f8, 0x00000000 },
{ 0x0000103c, 0x00000000 },
{ 0x0000107c, 0x00000000 },
{ 0x000010bc, 0x00000000 },
{ 0x000010fc, 0x00000000 },
{ 0x0000113c, 0x00000000 },
{ 0x0000117c, 0x00000000 },
{ 0x000011bc, 0x00000000 },
{ 0x000011fc, 0x00000000 },
{ 0x0000123c, 0x00000000 },
{ 0x0000127c, 0x00000000 },
{ 0x000012bc, 0x00000000 },
{ 0x000012fc, 0x00000000 },
{ 0x0000133c, 0x00000000 },
{ 0x0000137c, 0x00000000 },
{ 0x000013bc, 0x00000000 },
{ 0x000013fc, 0x00000000 },
{ 0x0000143c, 0x00000000 },
{ 0x0000147c, 0x00000000 },
{ 0x00020010, 0x00000003 },
{ 0x00020038, 0x000004c2 },
{ 0x00008004, 0x00000000 },
{ 0x00008008, 0x00000000 },
{ 0x0000800c, 0x00000000 },
{ 0x00008018, 0x00000700 },
{ 0x00008020, 0x00000000 },
{ 0x00008038, 0x00000000 },
{ 0x0000803c, 0x00000000 },
{ 0x00008048, 0x40000000 },
{ 0x00008054, 0x00004000 },
{ 0x00008058, 0x00000000 },
{ 0x0000805c, 0x000fc78f },
{ 0x00008060, 0x0000000f },
{ 0x00008064, 0x00000000 },
{ 0x000080c0, 0x2a82301a },
{ 0x000080c4, 0x05dc01e0 },
{ 0x000080c8, 0x1f402710 },
{ 0x000080cc, 0x01f40000 },
{ 0x000080d0, 0x00001e00 },
{ 0x000080d4, 0x00000000 },
{ 0x000080d8, 0x00400000 },
{ 0x000080e0, 0xffffffff },
{ 0x000080e4, 0x0000ffff },
{ 0x000080e8, 0x003f3f3f },
{ 0x000080ec, 0x00000000 },
{ 0x000080f0, 0x00000000 },
{ 0x000080f4, 0x00000000 },
{ 0x000080f8, 0x00000000 },
{ 0x000080fc, 0x00020000 },
{ 0x00008100, 0x00020000 },
{ 0x00008104, 0x00000001 },
{ 0x00008108, 0x00000052 },
{ 0x0000810c, 0x00000000 },
{ 0x00008110, 0x00000168 },
{ 0x00008118, 0x000100aa },
{ 0x0000811c, 0x00003210 },
{ 0x00008120, 0x08f04800 },
{ 0x00008124, 0x00000000 },
{ 0x00008128, 0x00000000 },
{ 0x0000812c, 0x00000000 },
{ 0x00008130, 0x00000000 },
{ 0x00008134, 0x00000000 },
{ 0x00008138, 0x00000000 },
{ 0x0000813c, 0x00000000 },
{ 0x00008144, 0x00000000 },
{ 0x00008168, 0x00000000 },
{ 0x0000816c, 0x00000000 },
{ 0x00008170, 0x32143320 },
{ 0x00008174, 0xfaa4fa50 },
{ 0x00008178, 0x00000100 },
{ 0x0000817c, 0x00000000 },
{ 0x000081c4, 0x00000000 },
{ 0x000081d0, 0x00003210 },
{ 0x000081ec, 0x00000000 },
{ 0x000081f0, 0x00000000 },
{ 0x000081f4, 0x00000000 },
{ 0x000081f8, 0x00000000 },
{ 0x000081fc, 0x00000000 },
{ 0x00008200, 0x00000000 },
{ 0x00008204, 0x00000000 },
{ 0x00008208, 0x00000000 },
{ 0x0000820c, 0x00000000 },
{ 0x00008210, 0x00000000 },
{ 0x00008214, 0x00000000 },
{ 0x00008218, 0x00000000 },
{ 0x0000821c, 0x00000000 },
{ 0x00008220, 0x00000000 },
{ 0x00008224, 0x00000000 },
{ 0x00008228, 0x00000000 },
{ 0x0000822c, 0x00000000 },
{ 0x00008230, 0x00000000 },
{ 0x00008234, 0x00000000 },
{ 0x00008238, 0x00000000 },
{ 0x0000823c, 0x00000000 },
{ 0x00008240, 0x00100000 },
{ 0x00008244, 0x0010f400 },
{ 0x00008248, 0x00000100 },
{ 0x0000824c, 0x0001e800 },
{ 0x00008250, 0x00000000 },
{ 0x00008254, 0x00000000 },
{ 0x00008258, 0x00000000 },
{ 0x0000825c, 0x400000ff },
{ 0x00008260, 0x00080922 },
{ 0x00008270, 0x00000000 },
{ 0x00008274, 0x40000000 },
{ 0x00008278, 0x003e4180 },
{ 0x0000827c, 0x00000000 },
{ 0x00008284, 0x0000002c },
{ 0x00008288, 0x0000002c },
{ 0x0000828c, 0x00000000 },
{ 0x00008294, 0x00000000 },
{ 0x00008298, 0x00000000 },
{ 0x00008300, 0x00000000 },
{ 0x00008304, 0x00000000 },
{ 0x00008308, 0x00000000 },
{ 0x0000830c, 0x00000000 },
{ 0x00008310, 0x00000000 },
{ 0x00008314, 0x00000000 },
{ 0x00008318, 0x00000000 },
{ 0x00008328, 0x00000000 },
{ 0x0000832c, 0x00000007 },
{ 0x00008330, 0x00000302 },
{ 0x00008334, 0x00000e00 },
{ 0x00008338, 0x00000000 },
{ 0x0000833c, 0x00000000 },
{ 0x00008340, 0x000107ff },
{ 0x00009808, 0x00000000 },
{ 0x0000980c, 0xad848e19 },
{ 0x00009810, 0x7d14e000 },
{ 0x00009814, 0x9c0a9f6b },
{ 0x0000981c, 0x00000000 },
{ 0x0000982c, 0x0000a000 },
{ 0x00009830, 0x00000000 },
{ 0x0000983c, 0x00200400 },
{ 0x00009840, 0x206a01ae },
{ 0x0000984c, 0x1284233c },
{ 0x00009854, 0x00000859 },
{ 0x00009900, 0x00000000 },
{ 0x00009904, 0x00000000 },
{ 0x00009908, 0x00000000 },
{ 0x0000990c, 0x00000000 },
{ 0x0000991c, 0x10000fff },
{ 0x00009920, 0x05100000 },
{ 0x0000a920, 0x05100000 },
{ 0x0000b920, 0x05100000 },
{ 0x00009928, 0x00000001 },
{ 0x0000992c, 0x00000004 },
{ 0x00009934, 0x1e1f2022 },
{ 0x00009938, 0x0a0b0c0d },
{ 0x0000993c, 0x00000000 },
{ 0x00009948, 0x9280b212 },
{ 0x0000994c, 0x00020028 },
{ 0x0000c95c, 0x004b6a8e },
{ 0x0000c968, 0x000003ce },
{ 0x00009970, 0x190fb515 },
{ 0x00009974, 0x00000000 },
{ 0x00009978, 0x00000001 },
{ 0x0000997c, 0x00000000 },
{ 0x00009980, 0x00000000 },
{ 0x00009984, 0x00000000 },
{ 0x00009988, 0x00000000 },
{ 0x0000998c, 0x00000000 },
{ 0x00009990, 0x00000000 },
{ 0x00009994, 0x00000000 },
{ 0x00009998, 0x00000000 },
{ 0x0000999c, 0x00000000 },
{ 0x000099a0, 0x00000000 },
{ 0x000099a4, 0x00000001 },
{ 0x000099a8, 0x201fff00 },
{ 0x000099ac, 0x006f0000 },
{ 0x000099b0, 0x03051000 },
{ 0x000099dc, 0x00000000 },
{ 0x000099e0, 0x00000200 },
{ 0x000099e4, 0xaaaaaaaa },
{ 0x000099e8, 0x3c466478 },
{ 0x000099ec, 0x0cc80caa },
{ 0x000099fc, 0x00001042 },
{ 0x00009b00, 0x00000000 },
{ 0x00009b04, 0x00000001 },
{ 0x00009b08, 0x00000002 },
{ 0x00009b0c, 0x00000003 },
{ 0x00009b10, 0x00000004 },
{ 0x00009b14, 0x00000005 },
{ 0x00009b18, 0x00000008 },
{ 0x00009b1c, 0x00000009 },
{ 0x00009b20, 0x0000000a },
{ 0x00009b24, 0x0000000b },
{ 0x00009b28, 0x0000000c },
{ 0x00009b2c, 0x0000000d },
{ 0x00009b30, 0x00000010 },
{ 0x00009b34, 0x00000011 },
{ 0x00009b38, 0x00000012 },
{ 0x00009b3c, 0x00000013 },
{ 0x00009b40, 0x00000014 },
{ 0x00009b44, 0x00000015 },
{ 0x00009b48, 0x00000018 },
{ 0x00009b4c, 0x00000019 },
{ 0x00009b50, 0x0000001a },
{ 0x00009b54, 0x0000001b },
{ 0x00009b58, 0x0000001c },
{ 0x00009b5c, 0x0000001d },
{ 0x00009b60, 0x00000020 },
{ 0x00009b64, 0x00000021 },
{ 0x00009b68, 0x00000022 },
{ 0x00009b6c, 0x00000023 },
{ 0x00009b70, 0x00000024 },
{ 0x00009b74, 0x00000025 },
{ 0x00009b78, 0x00000028 },
{ 0x00009b7c, 0x00000029 },
{ 0x00009b80, 0x0000002a },
{ 0x00009b84, 0x0000002b },
{ 0x00009b88, 0x0000002c },
{ 0x00009b8c, 0x0000002d },
{ 0x00009b90, 0x00000030 },
{ 0x00009b94, 0x00000031 },
{ 0x00009b98, 0x00000032 },
{ 0x00009b9c, 0x00000033 },
{ 0x00009ba0, 0x00000034 },
{ 0x00009ba4, 0x00000035 },
{ 0x00009ba8, 0x00000035 },
{ 0x00009bac, 0x00000035 },
{ 0x00009bb0, 0x00000035 },
{ 0x00009bb4, 0x00000035 },
{ 0x00009bb8, 0x00000035 },
{ 0x00009bbc, 0x00000035 },
{ 0x00009bc0, 0x00000035 },
{ 0x00009bc4, 0x00000035 },
{ 0x00009bc8, 0x00000035 },
{ 0x00009bcc, 0x00000035 },
{ 0x00009bd0, 0x00000035 },
{ 0x00009bd4, 0x00000035 },
{ 0x00009bd8, 0x00000035 },
{ 0x00009bdc, 0x00000035 },
{ 0x00009be0, 0x00000035 },
{ 0x00009be4, 0x00000035 },
{ 0x00009be8, 0x00000035 },
{ 0x00009bec, 0x00000035 },
{ 0x00009bf0, 0x00000035 },
{ 0x00009bf4, 0x00000035 },
{ 0x00009bf8, 0x00000010 },
{ 0x00009bfc, 0x0000001a },
{ 0x0000a210, 0x40806333 },
{ 0x0000a214, 0x00106c10 },
{ 0x0000a218, 0x009c4060 },
{ 0x0000a220, 0x018830c6 },
{ 0x0000a224, 0x00000400 },
{ 0x0000a228, 0x001a0bb5 },
{ 0x0000a22c, 0x00000000 },
{ 0x0000a234, 0x20202020 },
{ 0x0000a238, 0x20202020 },
{ 0x0000a23c, 0x13c889af },
{ 0x0000a240, 0x38490a20 },
{ 0x0000a244, 0x00007bb6 },
{ 0x0000a248, 0x0fff3ffc },
{ 0x0000a24c, 0x00000001 },
{ 0x0000a250, 0x0000e000 },
{ 0x0000a254, 0x00000000 },
{ 0x0000a258, 0x0cc75380 },
{ 0x0000a25c, 0x0f0f0f01 },
{ 0x0000a260, 0xdfa91f01 },
{ 0x0000a268, 0x00000001 },
{ 0x0000a26c, 0x0ebae9c6 },
{ 0x0000b26c, 0x0ebae9c6 },
{ 0x0000c26c, 0x0ebae9c6 },
{ 0x0000d270, 0x00820820 },
{ 0x0000a278, 0x1ce739ce },
{ 0x0000a27c, 0x050701ce },
{ 0x0000a338, 0x00000000 },
{ 0x0000a33c, 0x00000000 },
{ 0x0000a340, 0x00000000 },
{ 0x0000a344, 0x00000000 },
{ 0x0000a348, 0x3fffffff },
{ 0x0000a34c, 0x3fffffff },
{ 0x0000a350, 0x3fffffff },
{ 0x0000a354, 0x0003ffff },
{ 0x0000a358, 0x79a8aa33 },
{ 0x0000d35c, 0x07ffffef },
{ 0x0000d360, 0x0fffffe7 },
{ 0x0000d364, 0x17ffffe5 },
{ 0x0000d368, 0x1fffffe4 },
{ 0x0000d36c, 0x37ffffe3 },
{ 0x0000d370, 0x3fffffe3 },
{ 0x0000d374, 0x57ffffe3 },
{ 0x0000d378, 0x5fffffe2 },
{ 0x0000d37c, 0x7fffffe2 },
{ 0x0000d380, 0x7f3c7bba },
{ 0x0000d384, 0xf3307ff0 },
{ 0x0000a388, 0x0c000000 },
{ 0x0000a38c, 0x20202020 },
{ 0x0000a390, 0x20202020 },
{ 0x0000a394, 0x1ce739ce },
{ 0x0000a398, 0x000001ce },
{ 0x0000a39c, 0x00000001 },
{ 0x0000a3a0, 0x00000000 },
{ 0x0000a3a4, 0x00000000 },
{ 0x0000a3a8, 0x00000000 },
{ 0x0000a3ac, 0x00000000 },
{ 0x0000a3b0, 0x00000000 },
{ 0x0000a3b4, 0x00000000 },
{ 0x0000a3b8, 0x00000000 },
{ 0x0000a3bc, 0x00000000 },
{ 0x0000a3c0, 0x00000000 },
{ 0x0000a3c4, 0x00000000 },
{ 0x0000a3c8, 0x00000246 },
{ 0x0000a3cc, 0x20202020 },
{ 0x0000a3d0, 0x20202020 },
{ 0x0000a3d4, 0x20202020 },
{ 0x0000a3dc, 0x1ce739ce },
{ 0x0000a3e0, 0x000001ce },
};
static const uint32_t ar5416Bank0_9100[][2] = {
/* Addr allmodes */
{ 0x000098b0, 0x1e5795e5 },
{ 0x000098e0, 0x02008020 },
};
static const uint32_t ar5416BB_RfGain_9100[][3] = {
/* Addr 5G_HT20 5G_HT40 */
{ 0x00009a00, 0x00000000, 0x00000000 },
{ 0x00009a04, 0x00000040, 0x00000040 },
{ 0x00009a08, 0x00000080, 0x00000080 },
{ 0x00009a0c, 0x000001a1, 0x00000141 },
{ 0x00009a10, 0x000001e1, 0x00000181 },
{ 0x00009a14, 0x00000021, 0x000001c1 },
{ 0x00009a18, 0x00000061, 0x00000001 },
{ 0x00009a1c, 0x00000168, 0x00000041 },
{ 0x00009a20, 0x000001a8, 0x000001a8 },
{ 0x00009a24, 0x000001e8, 0x000001e8 },
{ 0x00009a28, 0x00000028, 0x00000028 },
{ 0x00009a2c, 0x00000068, 0x00000068 },
{ 0x00009a30, 0x00000189, 0x000000a8 },
{ 0x00009a34, 0x000001c9, 0x00000169 },
{ 0x00009a38, 0x00000009, 0x000001a9 },
{ 0x00009a3c, 0x00000049, 0x000001e9 },
{ 0x00009a40, 0x00000089, 0x00000029 },
{ 0x00009a44, 0x00000170, 0x00000069 },
{ 0x00009a48, 0x000001b0, 0x00000190 },
{ 0x00009a4c, 0x000001f0, 0x000001d0 },
{ 0x00009a50, 0x00000030, 0x00000010 },
{ 0x00009a54, 0x00000070, 0x00000050 },
{ 0x00009a58, 0x00000191, 0x00000090 },
{ 0x00009a5c, 0x000001d1, 0x00000151 },
{ 0x00009a60, 0x00000011, 0x00000191 },
{ 0x00009a64, 0x00000051, 0x000001d1 },
{ 0x00009a68, 0x00000091, 0x00000011 },
{ 0x00009a6c, 0x000001b8, 0x00000051 },
{ 0x00009a70, 0x000001f8, 0x00000198 },
{ 0x00009a74, 0x00000038, 0x000001d8 },
{ 0x00009a78, 0x00000078, 0x00000018 },
{ 0x00009a7c, 0x00000199, 0x00000058 },
{ 0x00009a80, 0x000001d9, 0x00000098 },
{ 0x00009a84, 0x00000019, 0x00000159 },
{ 0x00009a88, 0x00000059, 0x00000199 },
{ 0x00009a8c, 0x00000099, 0x000001d9 },
{ 0x00009a90, 0x000000d9, 0x00000019 },
{ 0x00009a94, 0x000000f9, 0x00000059 },
{ 0x00009a98, 0x000000f9, 0x00000099 },
{ 0x00009a9c, 0x000000f9, 0x000000d9 },
{ 0x00009aa0, 0x000000f9, 0x000000f9 },
{ 0x00009aa4, 0x000000f9, 0x000000f9 },
{ 0x00009aa8, 0x000000f9, 0x000000f9 },
{ 0x00009aac, 0x000000f9, 0x000000f9 },
{ 0x00009ab0, 0x000000f9, 0x000000f9 },
{ 0x00009ab4, 0x000000f9, 0x000000f9 },
{ 0x00009ab8, 0x000000f9, 0x000000f9 },
{ 0x00009abc, 0x000000f9, 0x000000f9 },
{ 0x00009ac0, 0x000000f9, 0x000000f9 },
{ 0x00009ac4, 0x000000f9, 0x000000f9 },
{ 0x00009ac8, 0x000000f9, 0x000000f9 },
{ 0x00009acc, 0x000000f9, 0x000000f9 },
{ 0x00009ad0, 0x000000f9, 0x000000f9 },
{ 0x00009ad4, 0x000000f9, 0x000000f9 },
{ 0x00009ad8, 0x000000f9, 0x000000f9 },
{ 0x00009adc, 0x000000f9, 0x000000f9 },
{ 0x00009ae0, 0x000000f9, 0x000000f9 },
{ 0x00009ae4, 0x000000f9, 0x000000f9 },
{ 0x00009ae8, 0x000000f9, 0x000000f9 },
{ 0x00009aec, 0x000000f9, 0x000000f9 },
{ 0x00009af0, 0x000000f9, 0x000000f9 },
{ 0x00009af4, 0x000000f9, 0x000000f9 },
{ 0x00009af8, 0x000000f9, 0x000000f9 },
{ 0x00009afc, 0x000000f9, 0x000000f9 },
};
static const uint32_t ar5416Bank1_9100[][2] = {
/* Addr allmodes */
{ 0x000098b0, 0x02108421 },
{ 0x000098ec, 0x00000008 },
};
static const uint32_t ar5416Bank2_9100[][2] = {
/* Addr allmodes */
{ 0x000098b0, 0x0e73ff17 },
{ 0x000098e0, 0x00000420 },
};
static const uint32_t ar5416Bank3_9100[][3] = {
/* Addr 5G_HT20 5G_HT40 */
{ 0x000098f0, 0x01400018, 0x01c00018 },
};
static const uint32_t ar5416Bank6_9100[][3] = {
/* Addr 5G_HT20 5G_HT40 */
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00e00000, 0x00e00000 },
{ 0x0000989c, 0x005e0000, 0x005e0000 },
{ 0x0000989c, 0x00120000, 0x00120000 },
{ 0x0000989c, 0x00620000, 0x00620000 },
{ 0x0000989c, 0x00020000, 0x00020000 },
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
{ 0x0000989c, 0x005f0000, 0x005f0000 },
{ 0x0000989c, 0x00870000, 0x00870000 },
{ 0x0000989c, 0x00f90000, 0x00f90000 },
{ 0x0000989c, 0x007b0000, 0x007b0000 },
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
{ 0x0000989c, 0x00f50000, 0x00f50000 },
{ 0x0000989c, 0x00dc0000, 0x00dc0000 },
{ 0x0000989c, 0x00110000, 0x00110000 },
{ 0x0000989c, 0x006100a8, 0x006100a8 },
{ 0x0000989c, 0x004210a2, 0x004210a2 },
{ 0x0000989c, 0x0014000f, 0x0014000f },
{ 0x0000989c, 0x00c40002, 0x00c40002 },
{ 0x0000989c, 0x003000f2, 0x003000f2 },
{ 0x0000989c, 0x00440016, 0x00440016 },
{ 0x0000989c, 0x00410040, 0x00410040 },
{ 0x0000989c, 0x000180d6, 0x000180d6 },
{ 0x0000989c, 0x0000c0aa, 0x0000c0aa },
{ 0x0000989c, 0x000000b1, 0x000000b1 },
{ 0x0000989c, 0x00002000, 0x00002000 },
{ 0x0000989c, 0x000000d4, 0x000000d4 },
{ 0x000098d0, 0x0000000f, 0x0010000f },
};
static const uint32_t ar5416Bank6TPC_9100[][3] = {
/* Addr 5G_HT20 5G_HT40 */
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00e00000, 0x00e00000 },
{ 0x0000989c, 0x005e0000, 0x005e0000 },
{ 0x0000989c, 0x00120000, 0x00120000 },
{ 0x0000989c, 0x00620000, 0x00620000 },
{ 0x0000989c, 0x00020000, 0x00020000 },
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
{ 0x0000989c, 0x40ff0000, 0x40ff0000 },
{ 0x0000989c, 0x005f0000, 0x005f0000 },
{ 0x0000989c, 0x00870000, 0x00870000 },
{ 0x0000989c, 0x00f90000, 0x00f90000 },
{ 0x0000989c, 0x007b0000, 0x007b0000 },
{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
{ 0x0000989c, 0x00f50000, 0x00f50000 },
{ 0x0000989c, 0x00dc0000, 0x00dc0000 },
{ 0x0000989c, 0x00110000, 0x00110000 },
{ 0x0000989c, 0x006100a8, 0x006100a8 },
{ 0x0000989c, 0x00423022, 0x00423022 },
{ 0x0000989c, 0x2014008f, 0x2014008f },
{ 0x0000989c, 0x00c40002, 0x00c40002 },
{ 0x0000989c, 0x003000f2, 0x003000f2 },
{ 0x0000989c, 0x00440016, 0x00440016 },
{ 0x0000989c, 0x00410040, 0x00410040 },
{ 0x0000989c, 0x0001805e, 0x0001805e },
{ 0x0000989c, 0x0000c0ab, 0x0000c0ab },
{ 0x0000989c, 0x000000e1, 0x000000e1 },
{ 0x0000989c, 0x00007080, 0x00007080 },
{ 0x0000989c, 0x000000d4, 0x000000d4 },
{ 0x000098d0, 0x0000000f, 0x0010000f },
};
static const uint32_t ar5416Bank7_9100[][2] = {
/* Addr allmodes */
{ 0x0000989c, 0x00000500 },
{ 0x0000989c, 0x00000800 },
{ 0x000098cc, 0x0000000e },
};
static const uint32_t ar5416Addac_9100[][2] = {
/* Addr allmodes */
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000010 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x000000c0 },
{ 0x0000989c, 0x00000015 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x0000989c, 0x00000000 },
{ 0x000098cc, 0x00000000 },
};
@@ -0,0 +1,312 @@
/*
* Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd
* 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.
*
* $FreeBSD$
*/
#include "opt_ah.h"
#include "ah.h"
#include "ah_internal.h"
#include "ah_devid.h"
#include "ar5416/ar5416.h"
#include "ar5416/ar5416reg.h"
#include "ar5416/ar5416phy.h"
#include "ar9001/ar9130reg.h"
#include "ar9001/ar9130_phy.h"
#include "ar9001/ar9130_eeprom.h"
#include "ar9001/ar9130.ini"
static const HAL_PERCAL_DATA ar9130_iq_cal = { /* multi sample */
.calName = "IQ", .calType = IQ_MISMATCH_CAL,
.calNumSamples = MAX_CAL_SAMPLES,
.calCountMax = PER_MIN_LOG_COUNT,
.calCollect = ar5416IQCalCollect,
.calPostProc = ar5416IQCalibration
};
static const HAL_PERCAL_DATA ar9130_adc_gain_cal = { /* multi sample */
.calName = "ADC Gain", .calType = ADC_GAIN_CAL,
.calNumSamples = MAX_CAL_SAMPLES,
.calCountMax = PER_MIN_LOG_COUNT,
.calCollect = ar5416AdcGainCalCollect,
.calPostProc = ar5416AdcGainCalibration
};
static const HAL_PERCAL_DATA ar9130_adc_dc_cal = { /* multi sample */
.calName = "ADC DC", .calType = ADC_DC_CAL,
.calNumSamples = MAX_CAL_SAMPLES,
.calCountMax = PER_MIN_LOG_COUNT,
.calCollect = ar5416AdcDcCalCollect,
.calPostProc = ar5416AdcDcCalibration
};
static const HAL_PERCAL_DATA ar9130_adc_init_dc_cal = {
.calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL,
.calNumSamples = MIN_CAL_SAMPLES,
.calCountMax = INIT_LOG_COUNT,
.calCollect = ar5416AdcDcCalCollect,
.calPostProc = ar5416AdcDcCalibration
};
static HAL_BOOL ar9130FillCapabilityInfo(struct ath_hal *ah);
/*
* Attach for an AR9130 part.
*/
static struct ath_hal *
ar9130Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, HAL_STATUS *status)
{
struct ath_hal_5416 *ahp5416;
struct ath_hal_5212 *ahp;
struct ath_hal *ah;
uint32_t val;
HAL_STATUS ecode;
HAL_BOOL rfStatus;
HALDEBUG_G(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
__func__, sc, (void*) st, (void*) sh);
/* NB: memory is returned zero'd */
ahp5416 = ath_hal_malloc(sizeof (struct ath_hal_5416));
if (ahp5416 == AH_NULL) {
HALDEBUG_G(AH_NULL, HAL_DEBUG_ANY,
"%s: cannot allocate memory for state block\n", __func__);
*status = HAL_ENOMEM;
return AH_NULL;
}
ar5416InitState(ahp5416, devid, sc, st, sh, status);
ahp = &ahp5416->ah_5212;
ah = &ahp->ah_priv.h;
/* XXX override with 9100 specific state */
AH5416(ah)->ah_initPLL = ar9130InitPLL;
/* XXX should force chainmasks to 0x7, as per ath9k calibration bugs */
/* override 5416 methods for our needs */
AH5416(ah)->ah_cal.iqCalData.calData = &ar9130_iq_cal;
AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9130_adc_gain_cal;
AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9130_adc_dc_cal;
AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9130_adc_init_dc_cal;
AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
/*
* This was hard-set because the initial ath9k port of this
* code kept their runtime conditional register #defines.
* AR_SREV and the RTC registers have shifted for Howl;
* they detected this and changed the values at runtime.
* The current port doesn't yet do this; it may do at a
* later stage, so this is set early so any routines which
* manipulate the registers have ah_macVersion set to base
* the above decision upon.
*/
AH_PRIVATE((ah))->ah_macVersion = AR_XSREV_VERSION_HOWL;
/*
* Use the "local" EEPROM data given to us by the higher layers.
* This is a private copy out of system flash. The Linux ath9k
* commit for the initial AR9130 support mentions MMIO flash
* access is "unreliable." -adrian
*/
AH_PRIVATE((ah))->ah_eepromRead = ar9130EepromRead;
AH_PRIVATE((ah))->ah_eepromWrite = NULL;
ah->ah_eepromdata = eepromdata;
if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
/* reset chip */
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n",
__func__);
ecode = HAL_EIO;
goto bad;
}
if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
__func__);
ecode = HAL_EIO;
goto bad;
}
/* Read Revisions from Chips before taking out of reset */
val = OS_REG_READ(ah, AR_SREV_CHIP_HOWL) & AR_SREV_CHIP_HOWL_ID;
/* XXX are these values even valid for the mac/radio revision? -adrian */
HALDEBUG(ah, HAL_DEBUG_ATTACH,
"%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
__func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION),
MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION));
AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION);
AH_PRIVATE(ah)->ah_ispcie = 0;
/* setup common ini data; rf backends handle remainder */
HAL_INI_INIT(&ahp->ah_ini_modes, ar5416Modes_9100, 6);
HAL_INI_INIT(&ahp->ah_ini_common, ar5416Common_9100, 2);
HAL_INI_INIT(&AH5416(ah)->ah_ini_bb_rfgain, ar5416BB_RfGain_9100, 3);
HAL_INI_INIT(&AH5416(ah)->ah_ini_bank0, ar5416Bank0_9100, 2);
HAL_INI_INIT(&AH5416(ah)->ah_ini_bank1, ar5416Bank1_9100, 2);
HAL_INI_INIT(&AH5416(ah)->ah_ini_bank2, ar5416Bank2_9100, 2);
HAL_INI_INIT(&AH5416(ah)->ah_ini_bank3, ar5416Bank3_9100, 3);
HAL_INI_INIT(&AH5416(ah)->ah_ini_bank6, ar5416Bank6TPC_9100, 3);
HAL_INI_INIT(&AH5416(ah)->ah_ini_bank7, ar5416Bank7_9100, 2);
HAL_INI_INIT(&AH5416(ah)->ah_ini_addac, ar5416Addac_9100, 2);
ecode = ath_hal_v14EepromAttach(ah);
if (ecode != HAL_OK)
goto bad;
if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
ecode = HAL_EIO;
goto bad;
}
AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);
if (!ar5212ChipTest(ah)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
__func__);
ecode = HAL_ESELFTEST;
goto bad;
}
/*
* Set correct Baseband to analog shift
* setting to access analog chips.
*/
OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
/* Read Radio Chip Rev Extract */
AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah);
switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
case AR_RAD2133_SREV_MAJOR: /* Sowl: 2G/3x3 */
case AR_RAD5133_SREV_MAJOR: /* Sowl: 2+5G/3x3 */
break;
default:
if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
AH_PRIVATE(ah)->ah_analog5GhzRev =
AR_RAD5133_SREV_MAJOR;
break;
}
#ifdef AH_DEBUG
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: 5G Radio Chip Rev 0x%02X is not supported by "
"this driver\n", __func__,
AH_PRIVATE(ah)->ah_analog5GhzRev);
ecode = HAL_ENOTSUPP;
goto bad;
#endif
}
rfStatus = ar2133RfAttach(ah, &ecode);
if (!rfStatus) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
__func__, ecode);
goto bad;
}
/*
* Got everything we need now to setup the capabilities.
*/
if (!ar9130FillCapabilityInfo(ah)) {
ecode = HAL_EEREAD;
goto bad;
}
ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
if (ecode != HAL_OK) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: error getting mac address from EEPROM\n", __func__);
goto bad;
}
/* XXX How about the serial number ? */
/* Read Reg Domain */
AH_PRIVATE(ah)->ah_currentRD =
ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
AH_PRIVATE(ah)->ah_currentRDext =
ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL);
/*
* 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.
*/
if (ahp->ah_miscMode != 0)
OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
/* XXX no ANI for AR9130 */
AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ;
AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ;
AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ;
AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ;
AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ;
AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;
ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
return ah;
bad:
if (ahp)
ar5416Detach((struct ath_hal *) ahp);
if (status)
*status = ecode;
return AH_NULL;
}
/*
* Fill all software cached or static hardware state information.
* Return failure if capabilities are to come from EEPROM and
* cannot be read.
*/
static HAL_BOOL
ar9130FillCapabilityInfo(struct ath_hal *ah)
{
HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: begin\n", __func__);
if (!ar5416FillCapabilityInfo(ah))
return AH_FALSE;
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: fill'ed; now setting\n", __func__);
pCap->halCSTSupport = AH_TRUE;
pCap->halRifsRxSupport = AH_TRUE;
pCap->halRifsTxSupport = AH_TRUE;
pCap->halRtsAggrLimit = 64*1024; /* 802.11n max */
pCap->halExtChanDfsSupport = AH_TRUE;
pCap->halUseCombinedRadarRssi = AH_TRUE;
pCap->halAutoSleepSupport = AH_FALSE; /* XXX? */
/*
* MBSSID aggregation is broken in Howl v1.1, v1.2, v1.3
* and works fine in v1.4.
* XXX todo, enable it for v1.4.
*/
pCap->halMbssidAggrSupport = AH_FALSE;
pCap->hal4AddrAggrSupport = AH_TRUE;
return AH_TRUE;
}
static const char*
ar9130Probe(uint16_t vendorid, uint16_t devid)
{
if (vendorid == ATHEROS_VENDOR_ID && devid == AR5416_AR9130_DEVID)
return "Atheros 9130";
return AH_NULL;
}
AH_CHIP(AR9130, ar9130Probe, ar9130Attach);

Some files were not shown because too many files have changed in this diff Show More