ath9k: Add new Atheros IEEE 802.11n driver

This adds the new mac80211 11n ath9k Atheros driver. Only STA support
is currently enabled and tested.

Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Jack Howarth <howarth@bromo.msbb.uc.edu>
Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Luis R. Rodriguez 2008-08-04 00:16:41 -07:00 committed by John W. Linville
parent b1a5215004
commit f078f20970
23 changed files with 31694 additions and 0 deletions

View file

@ -720,6 +720,15 @@ L: linux-wireless@vger.kernel.org
L: ath5k-devel@lists.ath5k.org
S: Maintained
ATHEROS ATH9K WIRELESS DRIVER
P: Luis R. Rodriguez
M: lrodriguez@atheros.com
P: Jouni Malinen
M: jmalinen@atheros.com
L: linux-wireless@vger.kernel.org
L: ath9k-devel@lists.ath9k.org
S: Supported
ATI_REMOTE2 DRIVER
P: Ville Syrjala
M: syrjala@sci.fi

View file

@ -695,6 +695,7 @@ config MAC80211_HWSIM
source "drivers/net/wireless/p54/Kconfig"
source "drivers/net/wireless/ath5k/Kconfig"
source "drivers/net/wireless/ath9k/Kconfig"
source "drivers/net/wireless/iwlwifi/Kconfig"
source "drivers/net/wireless/hostap/Kconfig"
source "drivers/net/wireless/b43/Kconfig"

View file

@ -62,5 +62,6 @@ obj-$(CONFIG_RT2X00) += rt2x00/
obj-$(CONFIG_P54_COMMON) += p54/
obj-$(CONFIG_ATH5K) += ath5k/
obj-$(CONFIG_ATH9K) += ath9k/
obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o

View file

@ -0,0 +1,8 @@
config ATH9K
tristate "Atheros 802.11n wireless cards support"
depends on PCI && MAC80211 && WLAN_80211
---help---
This module adds support for wireless adapters based on
Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets.
If you choose to build a module, it'll be called ath9k.

View file

@ -0,0 +1,11 @@
ath9k-y += hw.o \
phy.o \
regd.o \
beacon.o \
main.o \
recv.o \
xmit.o \
rc.o \
core.o
obj-$(CONFIG_ATH9K) += ath9k.o

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,977 @@
/*
* 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.
*/
/* Implementation of beacon processing. */
#include <asm/unaligned.h>
#include "core.h"
/*
* Configure parameters for the beacon queue
*
* This function will modify certain transmit queue properties depending on
* the operating mode of the station (AP or AdHoc). Parameters are AIFS
* settings and channel width min/max
*/
static int ath_beaconq_config(struct ath_softc *sc)
{
struct ath_hal *ah = sc->sc_ah;
struct ath9k_txq_info qi;
ath9k_hw_gettxqueueprops(ah, sc->sc_bhalq, &qi);
if (sc->sc_opmode == ATH9K_M_HOSTAP) {
/* Always burst out beacon and CAB traffic. */
qi.tqi_aifs = 1;
qi.tqi_cwmin = 0;
qi.tqi_cwmax = 0;
} else {
/* Adhoc mode; important thing is to use 2x cwmin. */
qi.tqi_aifs = sc->sc_beacon_qi.tqi_aifs;
qi.tqi_cwmin = 2*sc->sc_beacon_qi.tqi_cwmin;
qi.tqi_cwmax = sc->sc_beacon_qi.tqi_cwmax;
}
if (!ath9k_hw_settxqueueprops(ah, sc->sc_bhalq, &qi)) {
DPRINTF(sc, ATH_DBG_FATAL,
"%s: unable to update h/w beacon queue parameters\n",
__func__);
return 0;
} else {
ath9k_hw_resettxqueue(ah, sc->sc_bhalq); /* push to h/w */
return 1;
}
}
/*
* Setup the beacon frame for transmit.
*
* Associates the beacon frame buffer with a transmit descriptor. Will set
* up all required antenna switch parameters, rate codes, and channel flags.
* Beacons are always sent out at the lowest rate, and are not retried.
*/
static void ath_beacon_setup(struct ath_softc *sc,
struct ath_vap *avp, struct ath_buf *bf)
{
struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
struct ath_hal *ah = sc->sc_ah;
struct ath_desc *ds;
int flags, antenna;
const struct ath9k_rate_table *rt;
u8 rix, rate;
int ctsrate = 0;
int ctsduration = 0;
struct ath9k_11n_rate_series series[4];
DPRINTF(sc, ATH_DBG_BEACON, "%s: m %p len %u\n",
__func__, skb, skb->len);
/* setup descriptors */
ds = bf->bf_desc;
flags = ATH9K_TXDESC_NOACK;
if (sc->sc_opmode == ATH9K_M_IBSS && ah->ah_caps.halVEOLSupport) {
ds->ds_link = bf->bf_daddr; /* self-linked */
flags |= ATH9K_TXDESC_VEOL;
/* Let hardware handle antenna switching. */
antenna = 0;
} else {
ds->ds_link = 0;
/*
* Switch antenna every beacon.
* Should only switch every beacon period, not for every
* SWBA's
* XXX assumes two antenna
*/
antenna = ((sc->ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1);
}
ds->ds_data = bf->bf_buf_addr;
/*
* Calculate rate code.
* XXX everything at min xmit rate
*/
rix = sc->sc_minrateix;
rt = sc->sc_currates;
rate = rt->info[rix].rateCode;
if (sc->sc_flags & ATH_PREAMBLE_SHORT)
rate |= rt->info[rix].shortPreamble;
ath9k_hw_set11n_txdesc(ah, ds
, skb->len + FCS_LEN /* frame length */
, ATH9K_PKT_TYPE_BEACON /* Atheros packet type */
, avp->av_btxctl.txpower /* txpower XXX */
, ATH9K_TXKEYIX_INVALID /* no encryption */
, ATH9K_KEY_TYPE_CLEAR /* no encryption */
, flags /* no ack, veol for beacons */
);
/* NB: beacon's BufLen must be a multiple of 4 bytes */
ath9k_hw_filltxdesc(ah, ds
, roundup(skb->len, 4) /* buffer length */
, true /* first segment */
, true /* last segment */
, ds /* first descriptor */
);
memzero(series, sizeof(struct ath9k_11n_rate_series) * 4);
series[0].Tries = 1;
series[0].Rate = rate;
series[0].ChSel = sc->sc_tx_chainmask;
series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
ath9k_hw_set11n_ratescenario(ah, ds, ds, 0,
ctsrate, ctsduration, series, 4, 0);
}
/* Move everything from the vap's mcast queue to the hardware cab queue.
* Caller must hold mcasq lock and cabq lock
* XXX MORE_DATA bit?
*/
static void empty_mcastq_into_cabq(struct ath_hal *ah,
struct ath_txq *mcastq, struct ath_txq *cabq)
{
struct ath_buf *bfmcast;
BUG_ON(list_empty(&mcastq->axq_q));
bfmcast = list_first_entry(&mcastq->axq_q, struct ath_buf, list);
/* link the descriptors */
if (!cabq->axq_link)
ath9k_hw_puttxbuf(ah, cabq->axq_qnum, bfmcast->bf_daddr);
else
*cabq->axq_link = bfmcast->bf_daddr;
/* append the private vap mcast list to the cabq */
cabq->axq_depth += mcastq->axq_depth;
cabq->axq_totalqueued += mcastq->axq_totalqueued;
cabq->axq_linkbuf = mcastq->axq_linkbuf;
cabq->axq_link = mcastq->axq_link;
list_splice_tail_init(&mcastq->axq_q, &cabq->axq_q);
mcastq->axq_depth = 0;
mcastq->axq_totalqueued = 0;
mcastq->axq_linkbuf = NULL;
mcastq->axq_link = NULL;
}
/* This is only run at DTIM. We move everything from the vap's mcast queue
* to the hardware cab queue. Caller must hold the mcastq lock. */
static void trigger_mcastq(struct ath_hal *ah,
struct ath_txq *mcastq, struct ath_txq *cabq)
{
spin_lock_bh(&cabq->axq_lock);
if (!list_empty(&mcastq->axq_q))
empty_mcastq_into_cabq(ah, mcastq, cabq);
/* cabq is gated by beacon so it is safe to start here */
if (!list_empty(&cabq->axq_q))
ath9k_hw_txstart(ah, cabq->axq_qnum);
spin_unlock_bh(&cabq->axq_lock);
}
/*
* Generate beacon frame and queue cab data for a vap.
*
* Updates the contents of the beacon frame. It is assumed that the buffer for
* the beacon frame has been allocated in the ATH object, and simply needs to
* be filled for this cycle. Also, any CAB (crap after beacon?) traffic will
* be added to the beacon frame at this point.
*/
static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
{
struct ath_hal *ah = sc->sc_ah;
struct ath_buf *bf;
struct ath_vap *avp;
struct sk_buff *skb;
int cabq_depth;
int mcastq_depth;
int is_beacon_dtim = 0;
unsigned int curlen;
struct ath_txq *cabq;
struct ath_txq *mcastq;
avp = sc->sc_vaps[if_id];
mcastq = &avp->av_mcastq;
cabq = sc->sc_cabq;
ASSERT(avp);
if (avp->av_bcbuf == NULL) {
DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
__func__, avp, avp->av_bcbuf);
return NULL;
}
bf = avp->av_bcbuf;
skb = (struct sk_buff *) bf->bf_mpdu;
/*
* Update dynamic beacon contents. If this returns
* non-zero then we need to remap the memory because
* the beacon frame changed size (probably because
* of the TIM bitmap).
*/
curlen = skb->len;
/* XXX: spin_lock_bh should not be used here, but sparse bitches
* otherwise. We should fix sparse :) */
spin_lock_bh(&mcastq->axq_lock);
mcastq_depth = avp->av_mcastq.axq_depth;
if (ath_update_beacon(sc, if_id, &avp->av_boff, skb, mcastq_depth) ==
1) {
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
} else {
pci_dma_sync_single_for_cpu(sc->pdev,
bf->bf_buf_addr,
skb_tailroom(skb),
PCI_DMA_TODEVICE);
}
/*
* if the CABQ traffic from previous DTIM is pending and the current
* beacon is also a DTIM.
* 1) if there is only one vap let the cab traffic continue.
* 2) if there are more than one vap and we are using staggered
* beacons, then drain the cabq by dropping all the frames in
* the cabq so that the current vaps cab traffic can be scheduled.
*/
spin_lock_bh(&cabq->axq_lock);
cabq_depth = cabq->axq_depth;
spin_unlock_bh(&cabq->axq_lock);
is_beacon_dtim = avp->av_boff.bo_tim[4] & 1;
if (mcastq_depth && is_beacon_dtim && cabq_depth) {
/*
* Unlock the cabq lock as ath_tx_draintxq acquires
* the lock again which is a common function and that
* acquires txq lock inside.
*/
if (sc->sc_nvaps > 1) {
ath_tx_draintxq(sc, cabq, false);
DPRINTF(sc, ATH_DBG_BEACON,
"%s: flush previous cabq traffic\n", __func__);
}
}
/* Construct tx descriptor. */
ath_beacon_setup(sc, avp, bf);
/*
* Enable the CAB queue before the beacon queue to
* insure cab frames are triggered by this beacon.
*/
if (is_beacon_dtim)
trigger_mcastq(ah, mcastq, cabq);
spin_unlock_bh(&mcastq->axq_lock);
return bf;
}
/*
* Startup beacon transmission for adhoc mode when they are sent entirely
* by the hardware using the self-linked descriptor + veol trick.
*/
static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
{
struct ath_hal *ah = sc->sc_ah;
struct ath_buf *bf;
struct ath_vap *avp;
struct sk_buff *skb;
avp = sc->sc_vaps[if_id];
ASSERT(avp);
if (avp->av_bcbuf == NULL) {
DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
__func__, avp, avp != NULL ? avp->av_bcbuf : NULL);
return;
}
bf = avp->av_bcbuf;
skb = (struct sk_buff *) bf->bf_mpdu;
/* Construct tx descriptor. */
ath_beacon_setup(sc, avp, bf);
/* NB: caller is known to have already stopped tx dma */
ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr);
ath9k_hw_txstart(ah, sc->sc_bhalq);
DPRINTF(sc, ATH_DBG_BEACON, "%s: TXDP%u = %llx (%p)\n", __func__,
sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc);
}
/*
* Setup a h/w transmit queue for beacons.
*
* This function allocates an information structure (struct ath9k_txq_info)
* on the stack, sets some specific parameters (zero out channel width
* min/max, and enable aifs). The info structure does not need to be
* persistant.
*/
int ath_beaconq_setup(struct ath_hal *ah)
{
struct ath9k_txq_info qi;
memzero(&qi, sizeof(qi));
qi.tqi_aifs = 1;
qi.tqi_cwmin = 0;
qi.tqi_cwmax = 0;
/* NB: don't enable any interrupts */
return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
}
/*
* Allocate and setup an initial beacon frame.
*
* Allocate a beacon state variable for a specific VAP instance created on
* the ATH interface. This routine also calculates the beacon "slot" for
* staggared beacons in the mBSSID case.
*/
int ath_beacon_alloc(struct ath_softc *sc, int if_id)
{
struct ath_vap *avp;
struct ieee80211_hdr *wh;
struct ath_buf *bf;
struct sk_buff *skb;
avp = sc->sc_vaps[if_id];
ASSERT(avp);
/* Allocate a beacon descriptor if we haven't done so. */
if (!avp->av_bcbuf) {
/*
* Allocate beacon state for hostap/ibss. We know
* a buffer is available.
*/
avp->av_bcbuf = list_first_entry(&sc->sc_bbuf,
struct ath_buf, list);
list_del(&avp->av_bcbuf->list);
if (sc->sc_opmode == ATH9K_M_HOSTAP ||
!sc->sc_ah->ah_caps.halVEOLSupport) {
int slot;
/*
* Assign the vap to a beacon xmit slot. As
* above, this cannot fail to find one.
*/
avp->av_bslot = 0;
for (slot = 0; slot < ATH_BCBUF; slot++)
if (sc->sc_bslot[slot] == ATH_IF_ID_ANY) {
/*
* XXX hack, space out slots to better
* deal with misses
*/
if (slot+1 < ATH_BCBUF &&
sc->sc_bslot[slot+1] ==
ATH_IF_ID_ANY) {
avp->av_bslot = slot+1;
break;
}
avp->av_bslot = slot;
/* NB: keep looking for a double slot */
}
BUG_ON(sc->sc_bslot[avp->av_bslot] != ATH_IF_ID_ANY);
sc->sc_bslot[avp->av_bslot] = if_id;
sc->sc_nbcnvaps++;
}
}
/* release the previous beacon frame , if it already exists. */
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
skb = (struct sk_buff *)bf->bf_mpdu;
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
}
/*
* NB: the beacon data buffer must be 32-bit aligned;
* we assume the wbuf routines will return us something
* with this alignment (perhaps should assert).
* FIXME: Fill avp->av_boff.bo_tim,avp->av_btxctl.txpower and
* avp->av_btxctl.shortPreamble
*/
skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);
if (skb == NULL) {
DPRINTF(sc, ATH_DBG_BEACON, "%s: cannot get skb\n",
__func__);
return -ENOMEM;
}
/*
* Calculate a TSF adjustment factor required for
* staggered beacons. Note that we assume the format
* of the beacon frame leaves the tstamp field immediately
* following the header.
*/
if (avp->av_bslot > 0) {
u64 tsfadjust;
__le64 val;
int intval;
/* FIXME: Use default value for now: Sujith */
intval = ATH_DEFAULT_BINTVAL;
/*
* The beacon interval is in TU's; the TSF in usecs.
* We figure out how many TU's to add to align the
* timestamp then convert to TSF units and handle
* byte swapping before writing it in the frame.
* The hardware will then add this each time a beacon
* frame is sent. Note that we align vap's 1..N
* and leave vap 0 untouched. This means vap 0
* has a timestamp in one beacon interval while the
* others get a timestamp aligned to the next interval.
*/
tsfadjust = (intval * (ATH_BCBUF - avp->av_bslot)) / ATH_BCBUF;
val = cpu_to_le64(tsfadjust << 10); /* TU->TSF */
DPRINTF(sc, ATH_DBG_BEACON,
"%s: %s beacons, bslot %d intval %u tsfadjust %llu\n",
__func__, "stagger",
avp->av_bslot, intval, (unsigned long long)tsfadjust);
wh = (struct ieee80211_hdr *)skb->data;
memcpy(&wh[1], &val, sizeof(val));
}
bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
bf->bf_mpdu = skb;
return 0;
}
/*
* Reclaim beacon resources and return buffer to the pool.
*
* Checks the VAP to put the beacon frame buffer back to the ATH object
* queue, and de-allocates any wbuf frames that were sent as CAB traffic.
*/
void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
{
if (avp->av_bcbuf != NULL) {
struct ath_buf *bf;
if (avp->av_bslot != -1) {
sc->sc_bslot[avp->av_bslot] = ATH_IF_ID_ANY;
sc->sc_nbcnvaps--;
}
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
}
list_add_tail(&bf->list, &sc->sc_bbuf);
avp->av_bcbuf = NULL;
}
}
/*
* Reclaim beacon resources and return buffer to the pool.
*
* This function will free any wbuf frames that are still attached to the
* beacon buffers in the ATH object. Note that this does not de-allocate
* any wbuf objects that are in the transmit queue and have not yet returned
* to the ATH object.
*/
void ath_beacon_free(struct ath_softc *sc)
{
struct ath_buf *bf;
list_for_each_entry(bf, &sc->sc_bbuf, list) {
if (bf->bf_mpdu != NULL) {
struct sk_buff *skb = (struct sk_buff *) bf->bf_mpdu;
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
}
}
}
/*
* Tasklet for Sending Beacons
*
* Transmit one or more beacon frames at SWBA. Dynamic updates to the frame
* contents are done as needed and the slot time is also adjusted based on
* current state.
*
* This tasklet is not scheduled, it's called in ISR context.
*/
void ath9k_beacon_tasklet(unsigned long data)
{
#define TSF_TO_TU(_h,_l) \
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
struct ath_softc *sc = (struct ath_softc *)data;
struct ath_hal *ah = sc->sc_ah;
struct ath_buf *bf = NULL;
int slot, if_id;
u32 bfaddr;
u32 rx_clear = 0, rx_frame = 0, tx_frame = 0;
u32 show_cycles = 0;
u32 bc = 0; /* beacon count */
u64 tsf;
u32 tsftu;
u16 intval;
if (sc->sc_noreset) {
show_cycles = ath9k_hw_GetMibCycleCountsPct(ah,
&rx_clear,
&rx_frame,
&tx_frame);
}
/*
* Check if the previous beacon has gone out. If
* not don't try to post another, skip this period
* and wait for the next. Missed beacons indicate
* a problem and should not occur. If we miss too
* many consecutive beacons reset the device.
*/
if (ath9k_hw_numtxpending(ah, sc->sc_bhalq) != 0) {
sc->sc_bmisscount++;
/* XXX: doth needs the chanchange IE countdown decremented.
* We should consider adding a mac80211 call to indicate
* a beacon miss so appropriate action could be taken
* (in that layer).
*/
if (sc->sc_bmisscount < BSTUCK_THRESH) {
if (sc->sc_noreset) {
DPRINTF(sc, ATH_DBG_BEACON,
"%s: missed %u consecutive beacons\n",
__func__, sc->sc_bmisscount);
if (show_cycles) {
/*
* Display cycle counter stats
* from HW to aide in debug of
* stickiness.
*/
DPRINTF(sc,
ATH_DBG_BEACON,
"%s: busy times: rx_clear=%d, "
"rx_frame=%d, tx_frame=%d\n",
__func__, rx_clear, rx_frame,
tx_frame);
} else {
DPRINTF(sc,
ATH_DBG_BEACON,
"%s: unable to obtain "
"busy times\n", __func__);
}
} else {
DPRINTF(sc, ATH_DBG_BEACON,
"%s: missed %u consecutive beacons\n",
__func__, sc->sc_bmisscount);
}
} else if (sc->sc_bmisscount >= BSTUCK_THRESH) {
if (sc->sc_noreset) {
if (sc->sc_bmisscount == BSTUCK_THRESH) {
DPRINTF(sc,
ATH_DBG_BEACON,
"%s: beacon is officially "
"stuck\n", __func__);
ath9k_hw_dmaRegDump(ah);
}
} else {
DPRINTF(sc, ATH_DBG_BEACON,
"%s: beacon is officially stuck\n",
__func__);
ath_bstuck_process(sc);
}
}
return;
}
if (sc->sc_bmisscount != 0) {
if (sc->sc_noreset) {
DPRINTF(sc,
ATH_DBG_BEACON,
"%s: resume beacon xmit after %u misses\n",
__func__, sc->sc_bmisscount);
} else {
DPRINTF(sc, ATH_DBG_BEACON,
"%s: resume beacon xmit after %u misses\n",
__func__, sc->sc_bmisscount);
}
sc->sc_bmisscount = 0;
}
/*
* Generate beacon frames. we are sending frames
* staggered so calculate the slot for this frame based
* on the tsf to safeguard against missing an swba.
*/
/* FIXME: Use default value for now - Sujith */
intval = ATH_DEFAULT_BINTVAL;
tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf>>32, tsf);
slot = ((tsftu % intval) * ATH_BCBUF) / intval;
if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF];
DPRINTF(sc, ATH_DBG_BEACON,
"%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
__func__, slot, (unsigned long long) tsf, tsftu,
intval, if_id);
bfaddr = 0;
if (if_id != ATH_IF_ID_ANY) {
bf = ath_beacon_generate(sc, if_id);
if (bf != NULL) {
bfaddr = bf->bf_daddr;
bc = 1;
}
}
/*
* Handle slot time change when a non-ERP station joins/leaves
* an 11g network. The 802.11 layer notifies us via callback,
* we mark updateslot, then wait one beacon before effecting
* the change. This gives associated stations at least one
* beacon interval to note the state change.
*
* NB: The slot time change state machine is clocked according
* to whether we are bursting or staggering beacons. We
* recognize the request to update and record the current
* slot then don't transition until that slot is reached
* again. If we miss a beacon for that slot then we'll be
* slow to transition but we'll be sure at least one beacon
* interval has passed. When bursting slot is always left
* set to ATH_BCBUF so this check is a noop.
*/
/* XXX locking */
if (sc->sc_updateslot == UPDATE) {
sc->sc_updateslot = COMMIT; /* commit next beacon */
sc->sc_slotupdate = slot;
} else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot)
ath_setslottime(sc); /* commit change to hardware */
if (bfaddr != 0) {
/*
* Stop any current dma and put the new frame(s) on the queue.
* This should never fail since we check above that no frames
* are still pending on the queue.
*/
if (!ath9k_hw_stoptxdma(ah, sc->sc_bhalq)) {
DPRINTF(sc, ATH_DBG_FATAL,
"%s: beacon queue %u did not stop?\n",
__func__, sc->sc_bhalq);
/* NB: the HAL still stops DMA, so proceed */
}
/* NB: cabq traffic should already be queued and primed */
ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bfaddr);
ath9k_hw_txstart(ah, sc->sc_bhalq);
sc->ast_be_xmit += bc; /* XXX per-vap? */
}
#undef TSF_TO_TU
}
/*
* Tasklet for Beacon Stuck processing
*
* Processing for Beacon Stuck.
* Basically calls the ath_internal_reset function to reset the chip.
*/
void ath_bstuck_process(struct ath_softc *sc)
{
DPRINTF(sc, ATH_DBG_BEACON,
"%s: stuck beacon; resetting (bmiss count %u)\n",
__func__, sc->sc_bmisscount);
ath_internal_reset(sc);
}
/*
* Configure the beacon and sleep timers.
*
* When operating as an AP this resets the TSF and sets
* up the hardware to notify us when we need to issue beacons.
*
* When operating in station mode this sets up the beacon
* timers according to the timestamp of the last received
* beacon and the current TSF, configures PCF and DTIM
* handling, programs the sleep registers so the hardware
* will wakeup in time to receive beacons, and configures
* the beacon miss handling so we'll receive a BMISS
* interrupt when we stop seeing beacons from the AP
* we've associated with.
*/
void ath_beacon_config(struct ath_softc *sc, int if_id)
{
#define TSF_TO_TU(_h,_l) \
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
struct ath_hal *ah = sc->sc_ah;
u32 nexttbtt, intval;
struct ath_beacon_config conf;
enum ath9k_opmode av_opmode;
if (if_id != ATH_IF_ID_ANY)
av_opmode = sc->sc_vaps[if_id]->av_opmode;
else
av_opmode = sc->sc_opmode;
memzero(&conf, sizeof(struct ath_beacon_config));
/* FIXME: Use default values for now - Sujith */
/* Query beacon configuration first */
/*
* Protocol stack doesn't support dynamic beacon configuration,
* use default configurations.
*/
conf.beacon_interval = ATH_DEFAULT_BINTVAL;
conf.listen_interval = 1;
conf.dtim_period = conf.beacon_interval;
conf.dtim_count = 1;
conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
/* extract tstamp from last beacon and convert to TU */
nexttbtt = TSF_TO_TU(get_unaligned_le32(conf.u.last_tstamp + 4),
get_unaligned_le32(conf.u.last_tstamp));
/* XXX conditionalize multi-bss support? */
if (sc->sc_opmode == ATH9K_M_HOSTAP) {
/*
* For multi-bss ap support beacons are either staggered
* evenly over N slots or burst together. For the former
* arrange for the SWBA to be delivered for each slot.
* Slots that are not occupied will generate nothing.
*/
/* NB: the beacon interval is kept internally in TU's */
intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
intval /= ATH_BCBUF; /* for staggered beacons */
} else {
intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
}
if (nexttbtt == 0) /* e.g. for ap mode */
nexttbtt = intval;
else if (intval) /* NB: can be 0 for monitor mode */
nexttbtt = roundup(nexttbtt, intval);
DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
__func__, nexttbtt, intval, conf.beacon_interval);
/* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */
if (sc->sc_opmode == ATH9K_M_STA) {
struct ath9k_beacon_state bs;
u64 tsf;
u32 tsftu;
int dtimperiod, dtimcount, sleepduration;
int cfpperiod, cfpcount;
/*
* Setup dtim and cfp parameters according to
* last beacon we received (which may be none).
*/
dtimperiod = conf.dtim_period;
if (dtimperiod <= 0) /* NB: 0 if not known */
dtimperiod = 1;
dtimcount = conf.dtim_count;
if (dtimcount >= dtimperiod) /* NB: sanity check */
dtimcount = 0; /* XXX? */
cfpperiod = 1; /* NB: no PCF support yet */
cfpcount = 0;
sleepduration = conf.listen_interval * intval;
if (sleepduration <= 0)
sleepduration = intval;
#define FUDGE 2
/*
* Pull nexttbtt forward to reflect the current
* TSF and calculate dtim+cfp state for the result.
*/
tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
do {
nexttbtt += intval;
if (--dtimcount < 0) {
dtimcount = dtimperiod - 1;
if (--cfpcount < 0)
cfpcount = cfpperiod - 1;
}
} while (nexttbtt < tsftu);
#undef FUDGE
memzero(&bs, sizeof(bs));
bs.bs_intval = intval;
bs.bs_nexttbtt = nexttbtt;
bs.bs_dtimperiod = dtimperiod*intval;
bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
bs.bs_cfpmaxduration = 0;
/*
* Calculate the number of consecutive beacons to miss
* before taking a BMISS interrupt. The configuration
* is specified in TU so we only need calculate based
* on the beacon interval. Note that we clamp the
* result to at most 15 beacons.
*/
if (sleepduration > intval) {
bs.bs_bmissthreshold =
conf.listen_interval *
ATH_DEFAULT_BMISS_LIMIT / 2;
} else {
bs.bs_bmissthreshold =
DIV_ROUND_UP(conf.bmiss_timeout, intval);
if (bs.bs_bmissthreshold > 15)
bs.bs_bmissthreshold = 15;
else if (bs.bs_bmissthreshold <= 0)
bs.bs_bmissthreshold = 1;
}
/*
* Calculate sleep duration. The configuration is
* given in ms. We insure a multiple of the beacon
* period is used. Also, if the sleep duration is
* greater than the DTIM period then it makes senses
* to make it a multiple of that.
*
* XXX fixed at 100ms
*/
bs.bs_sleepduration =
roundup(IEEE80211_MS_TO_TU(100), sleepduration);
if (bs.bs_sleepduration > bs.bs_dtimperiod)
bs.bs_sleepduration = bs.bs_dtimperiod;
DPRINTF(sc, ATH_DBG_BEACON,
"%s: tsf %llu "
"tsf:tu %u "
"intval %u "
"nexttbtt %u "
"dtim %u "
"nextdtim %u "
"bmiss %u "
"sleep %u "
"cfp:period %u "
"maxdur %u "
"next %u "
"timoffset %u\n"
, __func__
, (unsigned long long)tsf, tsftu
, bs.bs_intval
, bs.bs_nexttbtt
, bs.bs_dtimperiod
, bs.bs_nextdtim
, bs.bs_bmissthreshold
, bs.bs_sleepduration
, bs.bs_cfpperiod
, bs.bs_cfpmaxduration
, bs.bs_cfpnext
, bs.bs_timoffset
);
ath9k_hw_set_interrupts(ah, 0);
ath9k_hw_set_sta_beacon_timers(ah, &bs);
sc->sc_imask |= ATH9K_INT_BMISS;
ath9k_hw_set_interrupts(ah, sc->sc_imask);
} else {
u64 tsf;
u32 tsftu;
ath9k_hw_set_interrupts(ah, 0);
if (nexttbtt == intval)
intval |= ATH9K_BEACON_RESET_TSF;
if (sc->sc_opmode == ATH9K_M_IBSS) {
/*
* Pull nexttbtt forward to reflect the current
* TSF .
*/
#define FUDGE 2
if (!(intval & ATH9K_BEACON_RESET_TSF)) {
tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU((u32)(tsf>>32),
(u32)tsf) + FUDGE;
do {
nexttbtt += intval;
} while (nexttbtt < tsftu);
}
#undef FUDGE
DPRINTF(sc, ATH_DBG_BEACON,
"%s: IBSS nexttbtt %u intval %u (%u)\n",
__func__, nexttbtt,
intval & ~ATH9K_BEACON_RESET_TSF,
conf.beacon_interval);
/*
* In IBSS mode enable the beacon timers but only
* enable SWBA interrupts if we need to manually
* prepare beacon frames. Otherwise we use a
* self-linked tx descriptor and let the hardware
* deal with things.
*/
intval |= ATH9K_BEACON_ENA;
if (!ah->ah_caps.halVEOLSupport)
sc->sc_imask |= ATH9K_INT_SWBA;
ath_beaconq_config(sc);
} else if (sc->sc_opmode == ATH9K_M_HOSTAP) {
/*
* In AP mode we enable the beacon timers and
* SWBA interrupts to prepare beacon frames.
*/
intval |= ATH9K_BEACON_ENA;
sc->sc_imask |= ATH9K_INT_SWBA; /* beacon prepare */
ath_beaconq_config(sc);
}
ath9k_hw_beaconinit(ah, nexttbtt, intval);
sc->sc_bmisscount = 0;
ath9k_hw_set_interrupts(ah, sc->sc_imask);
/*
* When using a self-linked beacon descriptor in
* ibss mode load it once here.
*/
if (sc->sc_opmode == ATH9K_M_IBSS && ah->ah_caps.halVEOLSupport)
ath_beacon_start_adhoc(sc, 0);
}
#undef TSF_TO_TU
}
/* Function to collect beacon rssi data and resync beacon if necessary */
void ath_beacon_sync(struct ath_softc *sc, int if_id)
{
/*
* Resync beacon timers using the tsf of the
* beacon frame we just received.
*/
ath_beacon_config(sc, if_id);
sc->sc_beacons = 1;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,969 @@
/*
* 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.
*/
#ifndef HW_H
#define HW_H
#include <linux/if_ether.h>
#include <linux/delay.h>
struct ar5416_desc {
u32 ds_link;
u32 ds_data;
u32 ds_ctl0;
u32 ds_ctl1;
union {
struct {
u32 ctl2;
u32 ctl3;
u32 ctl4;
u32 ctl5;
u32 ctl6;
u32 ctl7;
u32 ctl8;
u32 ctl9;
u32 ctl10;
u32 ctl11;
u32 status0;
u32 status1;
u32 status2;
u32 status3;
u32 status4;
u32 status5;
u32 status6;
u32 status7;
u32 status8;
u32 status9;
} tx;
struct {
u32 status0;
u32 status1;
u32 status2;
u32 status3;
u32 status4;
u32 status5;
u32 status6;
u32 status7;
u32 status8;
} rx;
} u;
} __packed;
#define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds))
#define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds))
#define ds_ctl2 u.tx.ctl2
#define ds_ctl3 u.tx.ctl3
#define ds_ctl4 u.tx.ctl4
#define ds_ctl5 u.tx.ctl5
#define ds_ctl6 u.tx.ctl6
#define ds_ctl7 u.tx.ctl7
#define ds_ctl8 u.tx.ctl8
#define ds_ctl9 u.tx.ctl9
#define ds_ctl10 u.tx.ctl10
#define ds_ctl11 u.tx.ctl11
#define ds_txstatus0 u.tx.status0
#define ds_txstatus1 u.tx.status1
#define ds_txstatus2 u.tx.status2
#define ds_txstatus3 u.tx.status3
#define ds_txstatus4 u.tx.status4
#define ds_txstatus5 u.tx.status5
#define ds_txstatus6 u.tx.status6
#define ds_txstatus7 u.tx.status7
#define ds_txstatus8 u.tx.status8
#define ds_txstatus9 u.tx.status9
#define ds_rxstatus0 u.rx.status0
#define ds_rxstatus1 u.rx.status1
#define ds_rxstatus2 u.rx.status2
#define ds_rxstatus3 u.rx.status3
#define ds_rxstatus4 u.rx.status4
#define ds_rxstatus5 u.rx.status5
#define ds_rxstatus6 u.rx.status6
#define ds_rxstatus7 u.rx.status7
#define ds_rxstatus8 u.rx.status8
#define AR_FrameLen 0x00000fff
#define AR_VirtMoreFrag 0x00001000
#define AR_TxCtlRsvd00 0x0000e000
#define AR_XmitPower 0x003f0000
#define AR_XmitPower_S 16
#define AR_RTSEnable 0x00400000
#define AR_VEOL 0x00800000
#define AR_ClrDestMask 0x01000000
#define AR_TxCtlRsvd01 0x1e000000
#define AR_TxIntrReq 0x20000000
#define AR_DestIdxValid 0x40000000
#define AR_CTSEnable 0x80000000
#define AR_BufLen 0x00000fff
#define AR_TxMore 0x00001000
#define AR_DestIdx 0x000fe000
#define AR_DestIdx_S 13
#define AR_FrameType 0x00f00000
#define AR_FrameType_S 20
#define AR_NoAck 0x01000000
#define AR_InsertTS 0x02000000
#define AR_CorruptFCS 0x04000000
#define AR_ExtOnly 0x08000000
#define AR_ExtAndCtl 0x10000000
#define AR_MoreAggr 0x20000000
#define AR_IsAggr 0x40000000
#define AR_BurstDur 0x00007fff
#define AR_BurstDur_S 0
#define AR_DurUpdateEna 0x00008000
#define AR_XmitDataTries0 0x000f0000
#define AR_XmitDataTries0_S 16
#define AR_XmitDataTries1 0x00f00000
#define AR_XmitDataTries1_S 20
#define AR_XmitDataTries2 0x0f000000
#define AR_XmitDataTries2_S 24
#define AR_XmitDataTries3 0xf0000000
#define AR_XmitDataTries3_S 28
#define AR_XmitRate0 0x000000ff
#define AR_XmitRate0_S 0
#define AR_XmitRate1 0x0000ff00
#define AR_XmitRate1_S 8
#define AR_XmitRate2 0x00ff0000
#define AR_XmitRate2_S 16
#define AR_XmitRate3 0xff000000
#define AR_XmitRate3_S 24
#define AR_PacketDur0 0x00007fff
#define AR_PacketDur0_S 0
#define AR_RTSCTSQual0 0x00008000
#define AR_PacketDur1 0x7fff0000
#define AR_PacketDur1_S 16
#define AR_RTSCTSQual1 0x80000000
#define AR_PacketDur2 0x00007fff
#define AR_PacketDur2_S 0
#define AR_RTSCTSQual2 0x00008000
#define AR_PacketDur3 0x7fff0000
#define AR_PacketDur3_S 16
#define AR_RTSCTSQual3 0x80000000
#define AR_AggrLen 0x0000ffff
#define AR_AggrLen_S 0
#define AR_TxCtlRsvd60 0x00030000
#define AR_PadDelim 0x03fc0000
#define AR_PadDelim_S 18
#define AR_EncrType 0x0c000000
#define AR_EncrType_S 26
#define AR_TxCtlRsvd61 0xf0000000
#define AR_2040_0 0x00000001
#define AR_GI0 0x00000002
#define AR_ChainSel0 0x0000001c
#define AR_ChainSel0_S 2
#define AR_2040_1 0x00000020
#define AR_GI1 0x00000040
#define AR_ChainSel1 0x00000380
#define AR_ChainSel1_S 7
#define AR_2040_2 0x00000400
#define AR_GI2 0x00000800
#define AR_ChainSel2 0x00007000
#define AR_ChainSel2_S 12
#define AR_2040_3 0x00008000
#define AR_GI3 0x00010000
#define AR_ChainSel3 0x000e0000
#define AR_ChainSel3_S 17
#define AR_RTSCTSRate 0x0ff00000
#define AR_RTSCTSRate_S 20
#define AR_TxCtlRsvd70 0xf0000000
#define AR_TxRSSIAnt00 0x000000ff
#define AR_TxRSSIAnt00_S 0
#define AR_TxRSSIAnt01 0x0000ff00
#define AR_TxRSSIAnt01_S 8
#define AR_TxRSSIAnt02 0x00ff0000
#define AR_TxRSSIAnt02_S 16
#define AR_TxStatusRsvd00 0x3f000000
#define AR_TxBaStatus 0x40000000
#define AR_TxStatusRsvd01 0x80000000
#define AR_FrmXmitOK 0x00000001
#define AR_ExcessiveRetries 0x00000002
#define AR_FIFOUnderrun 0x00000004
#define AR_Filtered 0x00000008
#define AR_RTSFailCnt 0x000000f0
#define AR_RTSFailCnt_S 4
#define AR_DataFailCnt 0x00000f00
#define AR_DataFailCnt_S 8
#define AR_VirtRetryCnt 0x0000f000
#define AR_VirtRetryCnt_S 12
#define AR_TxDelimUnderrun 0x00010000
#define AR_TxDataUnderrun 0x00020000
#define AR_DescCfgErr 0x00040000
#define AR_TxTimerExpired 0x00080000
#define AR_TxStatusRsvd10 0xfff00000
#define AR_SendTimestamp ds_txstatus2
#define AR_BaBitmapLow ds_txstatus3
#define AR_BaBitmapHigh ds_txstatus4
#define AR_TxRSSIAnt10 0x000000ff
#define AR_TxRSSIAnt10_S 0
#define AR_TxRSSIAnt11 0x0000ff00
#define AR_TxRSSIAnt11_S 8
#define AR_TxRSSIAnt12 0x00ff0000
#define AR_TxRSSIAnt12_S 16
#define AR_TxRSSICombined 0xff000000
#define AR_TxRSSICombined_S 24
#define AR_TxEVM0 ds_txstatus5
#define AR_TxEVM1 ds_txstatus6
#define AR_TxEVM2 ds_txstatus7
#define AR_TxDone 0x00000001
#define AR_SeqNum 0x00001ffe
#define AR_SeqNum_S 1
#define AR_TxStatusRsvd80 0x0001e000
#define AR_TxOpExceeded 0x00020000
#define AR_TxStatusRsvd81 0x001c0000
#define AR_FinalTxIdx 0x00600000
#define AR_FinalTxIdx_S 21
#define AR_TxStatusRsvd82 0x01800000
#define AR_PowerMgmt 0x02000000
#define AR_TxStatusRsvd83 0xfc000000
#define AR_RxCTLRsvd00 0xffffffff
#define AR_BufLen 0x00000fff
#define AR_RxCtlRsvd00 0x00001000
#define AR_RxIntrReq 0x00002000
#define AR_RxCtlRsvd01 0xffffc000
#define AR_RxRSSIAnt00 0x000000ff
#define AR_RxRSSIAnt00_S 0
#define AR_RxRSSIAnt01 0x0000ff00
#define AR_RxRSSIAnt01_S 8
#define AR_RxRSSIAnt02 0x00ff0000
#define AR_RxRSSIAnt02_S 16
#define AR_RxRate 0xff000000
#define AR_RxRate_S 24
#define AR_RxStatusRsvd00 0xff000000
#define AR_DataLen 0x00000fff
#define AR_RxMore 0x00001000
#define AR_NumDelim 0x003fc000
#define AR_NumDelim_S 14
#define AR_RxStatusRsvd10 0xff800000
#define AR_RcvTimestamp ds_rxstatus2
#define AR_GI 0x00000001
#define AR_2040 0x00000002
#define AR_Parallel40 0x00000004
#define AR_Parallel40_S 2
#define AR_RxStatusRsvd30 0x000000f8
#define AR_RxAntenna 0xffffff00
#define AR_RxAntenna_S 8
#define AR_RxRSSIAnt10 0x000000ff
#define AR_RxRSSIAnt10_S 0
#define AR_RxRSSIAnt11 0x0000ff00
#define AR_RxRSSIAnt11_S 8
#define AR_RxRSSIAnt12 0x00ff0000
#define AR_RxRSSIAnt12_S 16
#define AR_RxRSSICombined 0xff000000
#define AR_RxRSSICombined_S 24
#define AR_RxEVM0 ds_rxstatus4
#define AR_RxEVM1 ds_rxstatus5
#define AR_RxEVM2 ds_rxstatus6
#define AR_RxDone 0x00000001
#define AR_RxFrameOK 0x00000002
#define AR_CRCErr 0x00000004
#define AR_DecryptCRCErr 0x00000008
#define AR_PHYErr 0x00000010
#define AR_MichaelErr 0x00000020
#define AR_PreDelimCRCErr 0x00000040
#define AR_RxStatusRsvd70 0x00000080
#define AR_RxKeyIdxValid 0x00000100
#define AR_KeyIdx 0x0000fe00
#define AR_KeyIdx_S 9
#define AR_PHYErrCode 0x0000ff00
#define AR_PHYErrCode_S 8
#define AR_RxMoreAggr 0x00010000
#define AR_RxAggr 0x00020000
#define AR_PostDelimCRCErr 0x00040000
#define AR_RxStatusRsvd71 0x3ff80000
#define AR_DecryptBusyErr 0x40000000
#define AR_KeyMiss 0x80000000
#define AR5416_MAGIC 0x19641014
#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
MS(ads->ds_rxstatus0, AR_RxRate) : \
(ads->ds_rxstatus3 >> 2) & 0xFF)
#define RXSTATUS_DUPLICATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
MS(ads->ds_rxstatus3, AR_Parallel40) : \
(ads->ds_rxstatus3 >> 10) & 0x1)
#define set11nTries(_series, _index) \
(SM((_series)[_index].Tries, AR_XmitDataTries##_index))
#define set11nRate(_series, _index) \
(SM((_series)[_index].Rate, AR_XmitRate##_index))
#define set11nPktDurRTSCTS(_series, _index) \
(SM((_series)[_index].PktDuration, AR_PacketDur##_index) | \
((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS ? \
AR_RTSCTSQual##_index : 0))
#define set11nRateFlags(_series, _index) \
(((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \
AR_2040_##_index : 0) \
|((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \
AR_GI##_index : 0) \
|SM((_series)[_index].ChSel, AR_ChainSel##_index))
#define AR_SREV_9100(ah) ((ah->ah_macVersion) == AR_SREV_VERSION_9100)
#define INIT_CONFIG_STATUS 0x00000000
#define INIT_RSSI_THR 0x00000700
#define INIT_BCON_CNTRL_REG 0x00000000
#define MIN_TX_FIFO_THRESHOLD 0x1
#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1)
#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD
#define NUM_CORNER_FIX_BITS_2133 7
#define CCK_OFDM_GAIN_DELTA 15
struct ar5416AniState {
struct ath9k_channel c;
u8 noiseImmunityLevel;
u8 spurImmunityLevel;
u8 firstepLevel;
u8 ofdmWeakSigDetectOff;
u8 cckWeakSigThreshold;
u32 listenTime;
u32 ofdmTrigHigh;
u32 ofdmTrigLow;
int32_t cckTrigHigh;
int32_t cckTrigLow;
int32_t rssiThrLow;
int32_t rssiThrHigh;
u32 noiseFloor;
u32 txFrameCount;
u32 rxFrameCount;
u32 cycleCount;
u32 ofdmPhyErrCount;
u32 cckPhyErrCount;
u32 ofdmPhyErrBase;
u32 cckPhyErrBase;
int16_t pktRssi[2];
int16_t ofdmErrRssi[2];
int16_t cckErrRssi[2];
};
#define HAL_PROCESS_ANI 0x00000001
#define HAL_RADAR_EN 0x80000000
#define HAL_AR_EN 0x40000000
#define DO_ANI(ah) \
((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI))
struct ar5416Stats {
u32 ast_ani_niup;
u32 ast_ani_nidown;
u32 ast_ani_spurup;
u32 ast_ani_spurdown;
u32 ast_ani_ofdmon;
u32 ast_ani_ofdmoff;
u32 ast_ani_cckhigh;
u32 ast_ani_ccklow;
u32 ast_ani_stepup;
u32 ast_ani_stepdown;
u32 ast_ani_ofdmerrs;
u32 ast_ani_cckerrs;
u32 ast_ani_reset;
u32 ast_ani_lzero;
u32 ast_ani_lneg;
struct ath9k_mib_stats ast_mibstats;
struct ath9k_node_stats ast_nodestats;
};
#define AR5416_OPFLAGS_11A 0x01
#define AR5416_OPFLAGS_11G 0x02
#define AR5416_OPFLAGS_N_5G_HT40 0x04
#define AR5416_OPFLAGS_N_2G_HT40 0x08
#define AR5416_OPFLAGS_N_5G_HT20 0x10
#define AR5416_OPFLAGS_N_2G_HT20 0x20
#define EEP_RFSILENT_ENABLED 0x0001
#define EEP_RFSILENT_ENABLED_S 0
#define EEP_RFSILENT_POLARITY 0x0002
#define EEP_RFSILENT_POLARITY_S 1
#define EEP_RFSILENT_GPIO_SEL 0x001c
#define EEP_RFSILENT_GPIO_SEL_S 2
#define AR5416_EEP_NO_BACK_VER 0x1
#define AR5416_EEP_VER 0xE
#define AR5416_EEP_VER_MINOR_MASK 0x0FFF
#define AR5416_EEP_MINOR_VER_2 0x2
#define AR5416_EEP_MINOR_VER_3 0x3
#define AR5416_EEP_MINOR_VER_7 0x7
#define AR5416_EEP_MINOR_VER_9 0x9
#define AR5416_EEP_START_LOC 256
#define AR5416_NUM_5G_CAL_PIERS 8
#define AR5416_NUM_2G_CAL_PIERS 4
#define AR5416_NUM_5G_20_TARGET_POWERS 8
#define AR5416_NUM_5G_40_TARGET_POWERS 8
#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
#define AR5416_NUM_2G_20_TARGET_POWERS 4
#define AR5416_NUM_2G_40_TARGET_POWERS 4
#define AR5416_NUM_CTLS 24
#define AR5416_NUM_BAND_EDGES 8
#define AR5416_NUM_PD_GAINS 4
#define AR5416_PD_GAINS_IN_MASK 4
#define AR5416_PD_GAIN_ICEPTS 5
#define AR5416_EEPROM_MODAL_SPURS 5
#define AR5416_MAX_RATE_POWER 63
#define AR5416_NUM_PDADC_VALUES 128
#define AR5416_NUM_RATES 16
#define AR5416_BCHAN_UNUSED 0xFF
#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
#define AR5416_EEPMISC_BIG_ENDIAN 0x01
#define AR5416_MAX_CHAINS 3
#define AR5416_ANT_16S 25
#define AR5416_NUM_ANT_CHAIN_FIELDS 7
#define AR5416_NUM_ANT_COMMON_FIELDS 4
#define AR5416_SIZE_ANT_CHAIN_FIELD 3
#define AR5416_SIZE_ANT_COMMON_FIELD 4
#define AR5416_ANT_CHAIN_MASK 0x7
#define AR5416_ANT_COMMON_MASK 0xf
#define AR5416_CHAIN_0_IDX 0
#define AR5416_CHAIN_1_IDX 1
#define AR5416_CHAIN_2_IDX 2
#define AR5416_PWR_TABLE_OFFSET -5
#define AR5416_LEGACY_CHAINMASK 1
enum eeprom_param {
EEP_NFTHRESH_5,
EEP_NFTHRESH_2,
EEP_MAC_MSW,
EEP_MAC_MID,
EEP_MAC_LSW,
EEP_REG_0,
EEP_REG_1,
EEP_OP_CAP,
EEP_OP_MODE,
EEP_RF_SILENT,
EEP_OB_5,
EEP_DB_5,
EEP_OB_2,
EEP_DB_2,
EEP_MINOR_REV,
EEP_TX_MASK,
EEP_RX_MASK,
};
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
};
struct base_eep_header {
u16 length;
u16 checksum;
u16 version;
u8 opCapFlags;
u8 eepMisc;
u16 regDmn[2];
u8 macAddr[6];
u8 rxMask;
u8 txMask;
u16 rfSilent;
u16 blueToothOptions;
u16 deviceCap;
u32 binBuildNumber;
u8 deviceType;
u8 pwdclkind;
u8 futureBase[32];
} __packed;
struct spur_chan {
u16 spurChan;
u8 spurRangeLow;
u8 spurRangeHigh;
} __packed;
struct modal_eep_header {
u32 antCtrlChain[AR5416_MAX_CHAINS];
u32 antCtrlCommon;
u8 antennaGainCh[AR5416_MAX_CHAINS];
u8 switchSettling;
u8 txRxAttenCh[AR5416_MAX_CHAINS];
u8 rxTxMarginCh[AR5416_MAX_CHAINS];
u8 adcDesiredSize;
u8 pgaDesiredSize;
u8 xlnaGainCh[AR5416_MAX_CHAINS];
u8 txEndToXpaOff;
u8 txEndToRxOn;
u8 txFrameToXpaOn;
u8 thresh62;
u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
u8 xpdGain;
u8 xpd;
u8 iqCalICh[AR5416_MAX_CHAINS];
u8 iqCalQCh[AR5416_MAX_CHAINS];
u8 pdGainOverlap;
u8 ob;
u8 db;
u8 xpaBiasLvl;
u8 pwrDecreaseFor2Chain;
u8 pwrDecreaseFor3Chain;
u8 txFrameToDataStart;
u8 txFrameToPaOn;
u8 ht40PowerIncForPdadc;
u8 bswAtten[AR5416_MAX_CHAINS];
u8 bswMargin[AR5416_MAX_CHAINS];
u8 swSettleHt40;
u8 xatten2Db[AR5416_MAX_CHAINS];
u8 xatten2Margin[AR5416_MAX_CHAINS];
u8 ob_ch1;
u8 db_ch1;
u8 useAnt1:1,
force_xpaon:1,
local_bias:1,
femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
u8 futureModalar9280;
u16 xpaBiasLvlFreq[3];
u8 futureModal[6];
struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
} __packed;
struct cal_data_per_freq {
u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
} __packed;
struct cal_target_power_leg {
u8 bChannel;
u8 tPow2x[4];
} __packed;
struct cal_target_power_ht {
u8 bChannel;
u8 tPow2x[8];
} __packed;
#ifdef __BIG_ENDIAN_BITFIELD
struct cal_ctl_edges {
u8 bChannel;
u8 flag:2, tPower:6;
} __packed;
#else
struct cal_ctl_edges {
u8 bChannel;
u8 tPower:6, flag:2;
} __packed;
#endif
struct cal_ctl_data {
struct cal_ctl_edges
ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
} __packed;
struct ar5416_eeprom {
struct base_eep_header baseEepHeader;
u8 custData[64];
struct modal_eep_header modalHeader[2];
u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
struct cal_data_per_freq
calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
struct cal_data_per_freq
calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
struct cal_target_power_leg
calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
struct cal_target_power_ht
calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
struct cal_target_power_ht
calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
struct cal_target_power_leg
calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
struct cal_target_power_leg
calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
struct cal_target_power_ht
calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
struct cal_target_power_ht
calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
u8 ctlIndex[AR5416_NUM_CTLS];
struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
u8 padding;
} __packed;
struct ar5416IniArray {
u32 *ia_array;
u32 ia_rows;
u32 ia_columns;
};
#define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \
(iniarray)->ia_array = (u32 *)(array); \
(iniarray)->ia_rows = (rows); \
(iniarray)->ia_columns = (columns); \
} while (0)
#define INI_RA(iniarray, row, column) \
(((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)])
#define INIT_CAL(_perCal) do { \
(_perCal)->calState = CAL_WAITING; \
(_perCal)->calNext = NULL; \
} while (0)
#define INSERT_CAL(_ahp, _perCal) \
do { \
if ((_ahp)->ah_cal_list_last == NULL) { \
(_ahp)->ah_cal_list = \
(_ahp)->ah_cal_list_last = (_perCal); \
((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
} else { \
((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
(_ahp)->ah_cal_list_last = (_perCal); \
(_perCal)->calNext = (_ahp)->ah_cal_list; \
} \
} while (0)
enum hal_cal_types {
ADC_DC_INIT_CAL = 0x1,
ADC_GAIN_CAL = 0x2,
ADC_DC_CAL = 0x4,
IQ_MISMATCH_CAL = 0x8
};
enum hal_cal_state {
CAL_INACTIVE,
CAL_WAITING,
CAL_RUNNING,
CAL_DONE
};
#define MIN_CAL_SAMPLES 1
#define MAX_CAL_SAMPLES 64
#define INIT_LOG_COUNT 5
#define PER_MIN_LOG_COUNT 2
#define PER_MAX_LOG_COUNT 10
struct hal_percal_data {
enum hal_cal_types calType;
u32 calNumSamples;
u32 calCountMax;
void (*calCollect) (struct ath_hal *);
void (*calPostProc) (struct ath_hal *, u8);
};
struct hal_cal_list {
const struct hal_percal_data *calData;
enum hal_cal_state calState;
struct hal_cal_list *calNext;
};
struct ath_hal_5416 {
struct ath_hal ah;
struct ar5416_eeprom ah_eeprom;
u8 ah_macaddr[ETH_ALEN];
u8 ah_bssid[ETH_ALEN];
u8 ah_bssidmask[ETH_ALEN];
u16 ah_assocId;
int16_t ah_curchanRadIndex;
u32 ah_maskReg;
struct ar5416Stats ah_stats;
u32 ah_txDescMask;
u32 ah_txOkInterruptMask;
u32 ah_txErrInterruptMask;
u32 ah_txDescInterruptMask;
u32 ah_txEolInterruptMask;
u32 ah_txUrnInterruptMask;
struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
enum ath9k_power_mode ah_powerMode;
bool ah_chipFullSleep;
u32 ah_atimWindow;
enum ath9k_ant_setting ah_diversityControl;
u16 ah_antennaSwitchSwap;
enum hal_cal_types ah_suppCals;
struct hal_cal_list ah_iqCalData;
struct hal_cal_list ah_adcGainCalData;
struct hal_cal_list ah_adcDcCalInitData;
struct hal_cal_list ah_adcDcCalData;
struct hal_cal_list *ah_cal_list;
struct hal_cal_list *ah_cal_list_last;
struct hal_cal_list *ah_cal_list_curr;
#define ah_totalPowerMeasI ah_Meas0.unsign
#define ah_totalPowerMeasQ ah_Meas1.unsign
#define ah_totalIqCorrMeas ah_Meas2.sign
#define ah_totalAdcIOddPhase ah_Meas0.unsign
#define ah_totalAdcIEvenPhase ah_Meas1.unsign
#define ah_totalAdcQOddPhase ah_Meas2.unsign
#define ah_totalAdcQEvenPhase ah_Meas3.unsign
#define ah_totalAdcDcOffsetIOddPhase ah_Meas0.sign
#define ah_totalAdcDcOffsetIEvenPhase ah_Meas1.sign
#define ah_totalAdcDcOffsetQOddPhase ah_Meas2.sign
#define ah_totalAdcDcOffsetQEvenPhase ah_Meas3.sign
union {
u32 unsign[AR5416_MAX_CHAINS];
int32_t sign[AR5416_MAX_CHAINS];
} ah_Meas0;
union {
u32 unsign[AR5416_MAX_CHAINS];
int32_t sign[AR5416_MAX_CHAINS];
} ah_Meas1;
union {
u32 unsign[AR5416_MAX_CHAINS];
int32_t sign[AR5416_MAX_CHAINS];
} ah_Meas2;
union {
u32 unsign[AR5416_MAX_CHAINS];
int32_t sign[AR5416_MAX_CHAINS];
} ah_Meas3;
u16 ah_CalSamples;
u32 ah_tx6PowerInHalfDbm;
u32 ah_staId1Defaults;
u32 ah_miscMode;
bool ah_tpcEnabled;
u32 ah_beaconInterval;
enum {
AUTO_32KHZ,
USE_32KHZ,
DONT_USE_32KHZ,
} ah_enable32kHzClock;
u32 *ah_analogBank0Data;
u32 *ah_analogBank1Data;
u32 *ah_analogBank2Data;
u32 *ah_analogBank3Data;
u32 *ah_analogBank6Data;
u32 *ah_analogBank6TPCData;
u32 *ah_analogBank7Data;
u32 *ah_addac5416_21;
u32 *ah_bank6Temp;
u32 ah_ofdmTxPower;
int16_t ah_txPowerIndexOffset;
u32 ah_slottime;
u32 ah_acktimeout;
u32 ah_ctstimeout;
u32 ah_globaltxtimeout;
u8 ah_gBeaconRate;
u32 ah_gpioSelect;
u32 ah_polarity;
u32 ah_gpioBit;
bool ah_eepEnabled;
u32 ah_procPhyErr;
bool ah_hasHwPhyCounters;
u32 ah_aniPeriod;
struct ar5416AniState *ah_curani;
struct ar5416AniState ah_ani[255];
int ah_totalSizeDesired[5];
int ah_coarseHigh[5];
int ah_coarseLow[5];
int ah_firpwr[5];
u16 ah_ratesArray[16];
u32 ah_intrTxqs;
bool ah_intrMitigation;
u32 ah_cycleCount;
u32 ah_ctlBusy;
u32 ah_extBusy;
enum ath9k_ht_extprotspacing ah_extprotspacing;
u8 ah_txchainmask;
u8 ah_rxchainmask;
int ah_hwp;
void __iomem *ah_cal_mem;
enum ath9k_ani_cmd ah_ani_function;
struct ar5416IniArray ah_iniModes;
struct ar5416IniArray ah_iniCommon;
struct ar5416IniArray ah_iniBank0;
struct ar5416IniArray ah_iniBB_RfGain;
struct ar5416IniArray ah_iniBank1;
struct ar5416IniArray ah_iniBank2;
struct ar5416IniArray ah_iniBank3;
struct ar5416IniArray ah_iniBank6;
struct ar5416IniArray ah_iniBank6TPC;
struct ar5416IniArray ah_iniBank7;
struct ar5416IniArray ah_iniAddac;
struct ar5416IniArray ah_iniPcieSerdes;
struct ar5416IniArray ah_iniModesAdditional;
};
#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
#define IS_5416_EMU(ah) \
((ah->ah_devid == AR5416_DEVID_EMU) || \
(ah->ah_devid == AR5416_DEVID_EMU_PCIE))
#define ar5416RfDetach(ah) do { \
if (AH5416(ah)->ah_rfHal.rfDetach != NULL) \
AH5416(ah)->ah_rfHal.rfDetach(ah); \
} while (0)
#define ath9k_hw_use_flash(_ah) \
(!(_ah->ah_flags & AH_USE_EEPROM))
#define DO_DELAY(x) do { \
if ((++(x) % 64) == 0) \
udelay(1); \
} while (0)
#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
int r; \
for (r = 0; r < ((iniarray)->ia_rows); r++) { \
REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
INI_RA((iniarray), r, (column))); \
DO_DELAY(regWr); \
} \
} while (0)
#define BASE_ACTIVATE_DELAY 100
#define RTC_PLL_SETTLE_DELAY 1000
#define COEF_SCALE_S 24
#define HT40_CHANNEL_CENTER_SHIFT 10
#define ar5416CheckOpMode(_opmode) \
((_opmode == ATH9K_M_STA) || (_opmode == ATH9K_M_IBSS) || \
(_opmode == ATH9K_M_HOSTAP) || (_opmode == ATH9K_M_MONITOR))
#define AR5416_EEPROM_MAGIC_OFFSET 0x0
#define AR5416_EEPROM_S 2
#define AR5416_EEPROM_OFFSET 0x2000
#define AR5416_EEPROM_START_ADDR \
(AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
#define AR5416_EEPROM_MAX 0xae0
#define ar5416_get_eep_ver(_ahp) \
(((_ahp)->ah_eeprom.baseEepHeader.version >> 12) & 0xF)
#define ar5416_get_eep_rev(_ahp) \
(((_ahp)->ah_eeprom.baseEepHeader.version) & 0xFFF)
#define ar5416_get_ntxchains(_txchainmask) \
(((_txchainmask >> 2) & 1) + \
((_txchainmask >> 1) & 1) + (_txchainmask & 1))
#define IS_EEP_MINOR_V3(_ahp) \
(ath9k_hw_get_eeprom((_ahp), EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_3)
#define FIXED_CCA_THRESHOLD 15
#ifdef __BIG_ENDIAN
#define AR5416_EEPROM_MAGIC 0x5aa5
#else
#define AR5416_EEPROM_MAGIC 0xa55a
#endif
#define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
#define ATH9K_ANTENNA0_CHAINMASK 0x1
#define ATH9K_ANTENNA1_CHAINMASK 0x2
#define ATH9K_NUM_DMA_DEBUG_REGS 8
#define ATH9K_NUM_QUEUES 10
#define HAL_NOISE_IMMUNE_MAX 4
#define HAL_SPUR_IMMUNE_MAX 7
#define HAL_FIRST_STEP_MAX 2
#define ATH9K_ANI_OFDM_TRIG_HIGH 500
#define ATH9K_ANI_OFDM_TRIG_LOW 200
#define ATH9K_ANI_CCK_TRIG_HIGH 200
#define ATH9K_ANI_CCK_TRIG_LOW 100
#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
#define ATH9K_ANI_CCK_WEAK_SIG_THR false
#define ATH9K_ANI_SPUR_IMMUNE_LVL 7
#define ATH9K_ANI_FIRSTEP_LVL 0
#define ATH9K_ANI_RSSI_THR_HIGH 40
#define ATH9K_ANI_RSSI_THR_LOW 7
#define ATH9K_ANI_PERIOD 100
#define AR_GPIOD_MASK 0x00001FFF
#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
#define MAX_ANALOG_START 319
#define HAL_EP_RND(x, mul) \
((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
#define BEACON_RSSI(ahp) \
HAL_EP_RND(ahp->ah_stats.ast_nodestats.ns_avgbrssi, \
ATH9K_RSSI_EP_MULTIPLIER)
#define ah_mibStats ah_stats.ast_mibstats
#define AH_TIMEOUT 100000
#define AH_TIME_QUANTUM 10
#define IS(_c, _f) (((_c)->channelFlags & _f) || 0)
#define AR_KEYTABLE_SIZE 128
#define POWER_UP_TIME 200000
#define EXT_ADDITIVE (0x8000)
#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
#define SUB_NUM_CTL_MODES_AT_5G_40 2
#define SUB_NUM_CTL_MODES_AT_2G_40 3
#define SPUR_RSSI_THRESH 40
#define TU_TO_USEC(_tu) ((_tu) << 10)
#define CAB_TIMEOUT_VAL 10
#define BEACON_TIMEOUT_VAL 10
#define MIN_BEACON_TIMEOUT_VAL 1
#define SLEEP_SLOP 3
#define CCK_SIFS_TIME 10
#define CCK_PREAMBLE_BITS 144
#define CCK_PLCP_BITS 48
#define OFDM_SIFS_TIME 16
#define OFDM_PREAMBLE_TIME 20
#define OFDM_PLCP_BITS 22
#define OFDM_SYMBOL_TIME 4
#define OFDM_SIFS_TIME_HALF 32
#define OFDM_PREAMBLE_TIME_HALF 40
#define OFDM_PLCP_BITS_HALF 22
#define OFDM_SYMBOL_TIME_HALF 8
#define OFDM_SIFS_TIME_QUARTER 64
#define OFDM_PREAMBLE_TIME_QUARTER 80
#define OFDM_PLCP_BITS_QUARTER 22
#define OFDM_SYMBOL_TIME_QUARTER 16
u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
enum eeprom_param param);
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,436 @@
/*
* 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.
*/
#include "core.h"
#include "hw.h"
#include "reg.h"
#include "phy.h"
void
ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex, u32 freqIndex,
int regWrites)
{
struct ath_hal_5416 *ahp = AH5416(ah);
REG_WRITE_ARRAY(&ahp->ah_iniBB_RfGain, freqIndex, regWrites);
}
bool
ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan)
{
u32 channelSel = 0;
u32 bModeSynth = 0;
u32 aModeRefSel = 0;
u32 reg32 = 0;
u16 freq;
struct chan_centers centers;
ath9k_hw_get_channel_centers(ah, chan, &centers);
freq = centers.synth_center;
if (freq < 4800) {
u32 txctl;
if (((freq - 2192) % 5) == 0) {
channelSel = ((freq - 672) * 2 - 3040) / 10;
bModeSynth = 0;
} else if (((freq - 2224) % 5) == 0) {
channelSel = ((freq - 704) * 2 - 3040) / 10;
bModeSynth = 1;
} else {
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"%s: invalid channel %u MHz\n", __func__,
freq);
return false;
}
channelSel = (channelSel << 2) & 0xff;
channelSel = ath9k_hw_reverse_bits(channelSel, 8);
txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
if (freq == 2484) {
REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
} else {
REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
}
} else if ((freq % 20) == 0 && freq >= 5120) {
channelSel =
ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
aModeRefSel = ath9k_hw_reverse_bits(1, 2);
} else if ((freq % 10) == 0) {
channelSel =
ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
aModeRefSel = ath9k_hw_reverse_bits(2, 2);
else
aModeRefSel = ath9k_hw_reverse_bits(1, 2);
} else if ((freq % 5) == 0) {
channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
aModeRefSel = ath9k_hw_reverse_bits(1, 2);
} else {
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"%s: invalid channel %u MHz\n", __func__, freq);
return false;
}
reg32 =
(channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
(1 << 5) | 0x1;
REG_WRITE(ah, AR_PHY(0x37), reg32);
ah->ah_curchan = chan;
AH5416(ah)->ah_curchanRadIndex = -1;
return true;
}
bool
ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
struct ath9k_channel *chan)
{
u16 bMode, fracMode, aModeRefSel = 0;
u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
struct chan_centers centers;
u32 refDivA = 24;
ath9k_hw_get_channel_centers(ah, chan, &centers);
freq = centers.synth_center;
reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
reg32 &= 0xc0000000;
if (freq < 4800) {
u32 txctl;
bMode = 1;
fracMode = 1;
aModeRefSel = 0;
channelSel = (freq * 0x10000) / 15;
txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
if (freq == 2484) {
REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
} else {
REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
}
} else {
bMode = 0;
fracMode = 0;
if ((freq % 20) == 0) {
aModeRefSel = 3;
} else if ((freq % 10) == 0) {
aModeRefSel = 2;
} else {
aModeRefSel = 0;
fracMode = 1;
refDivA = 1;
channelSel = (freq * 0x8000) / 15;
REG_RMW_FIELD(ah, AR_AN_SYNTH9,
AR_AN_SYNTH9_REFDIVA, refDivA);
}
if (!fracMode) {
ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
channelSel = ndiv & 0x1ff;
channelFrac = (ndiv & 0xfffffe00) * 2;
channelSel = (channelSel << 17) | channelFrac;
}
}
reg32 = reg32 |
(bMode << 29) |
(fracMode << 28) | (aModeRefSel << 26) | (channelSel);
REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
ah->ah_curchan = chan;
AH5416(ah)->ah_curchanRadIndex = -1;
return true;
}
static void
ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
u32 numBits, u32 firstBit,
u32 column)
{
u32 tmp32, mask, arrayEntry, lastBit;
int32_t bitPosition, bitsLeft;
tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
arrayEntry = (firstBit - 1) / 8;
bitPosition = (firstBit - 1) % 8;
bitsLeft = numBits;
while (bitsLeft > 0) {
lastBit = (bitPosition + bitsLeft > 8) ?
8 : bitPosition + bitsLeft;
mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
(column * 8);
rfBuf[arrayEntry] &= ~mask;
rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
(column * 8)) & mask;
bitsLeft -= 8 - bitPosition;
tmp32 = tmp32 >> (8 - bitPosition);
bitPosition = 0;
arrayEntry++;
}
}
bool
ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan,
u16 modesIndex)
{
struct ath_hal_5416 *ahp = AH5416(ah);
u32 eepMinorRev;
u32 ob5GHz = 0, db5GHz = 0;
u32 ob2GHz = 0, db2GHz = 0;
int regWrites = 0;
if (AR_SREV_9280_10_OR_LATER(ah))
return true;
eepMinorRev = ath9k_hw_get_eeprom(ahp, EEP_MINOR_REV);
RF_BANK_SETUP(ahp->ah_analogBank0Data, &ahp->ah_iniBank0, 1);
RF_BANK_SETUP(ahp->ah_analogBank1Data, &ahp->ah_iniBank1, 1);
RF_BANK_SETUP(ahp->ah_analogBank2Data, &ahp->ah_iniBank2, 1);
RF_BANK_SETUP(ahp->ah_analogBank3Data, &ahp->ah_iniBank3,
modesIndex);
{
int i;
for (i = 0; i < ahp->ah_iniBank6TPC.ia_rows; i++) {
ahp->ah_analogBank6Data[i] =
INI_RA(&ahp->ah_iniBank6TPC, i, modesIndex);
}
}
if (eepMinorRev >= 2) {
if (IS_CHAN_2GHZ(chan)) {
ob2GHz = ath9k_hw_get_eeprom(ahp, EEP_OB_2);
db2GHz = ath9k_hw_get_eeprom(ahp, EEP_DB_2);
ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
ob2GHz, 3, 197, 0);
ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
db2GHz, 3, 194, 0);
} else {
ob5GHz = ath9k_hw_get_eeprom(ahp, EEP_OB_5);
db5GHz = ath9k_hw_get_eeprom(ahp, EEP_DB_5);
ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
ob5GHz, 3, 203, 0);
ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
db5GHz, 3, 200, 0);
}
}
RF_BANK_SETUP(ahp->ah_analogBank7Data, &ahp->ah_iniBank7, 1);
REG_WRITE_RF_ARRAY(&ahp->ah_iniBank0, ahp->ah_analogBank0Data,
regWrites);
REG_WRITE_RF_ARRAY(&ahp->ah_iniBank1, ahp->ah_analogBank1Data,
regWrites);
REG_WRITE_RF_ARRAY(&ahp->ah_iniBank2, ahp->ah_analogBank2Data,
regWrites);
REG_WRITE_RF_ARRAY(&ahp->ah_iniBank3, ahp->ah_analogBank3Data,
regWrites);
REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6TPC, ahp->ah_analogBank6Data,
regWrites);
REG_WRITE_RF_ARRAY(&ahp->ah_iniBank7, ahp->ah_analogBank7Data,
regWrites);
return true;
}
void
ath9k_hw_rfdetach(struct ath_hal *ah)
{
struct ath_hal_5416 *ahp = AH5416(ah);
if (ahp->ah_analogBank0Data != NULL) {
kfree(ahp->ah_analogBank0Data);
ahp->ah_analogBank0Data = NULL;
}
if (ahp->ah_analogBank1Data != NULL) {
kfree(ahp->ah_analogBank1Data);
ahp->ah_analogBank1Data = NULL;
}
if (ahp->ah_analogBank2Data != NULL) {
kfree(ahp->ah_analogBank2Data);
ahp->ah_analogBank2Data = NULL;
}
if (ahp->ah_analogBank3Data != NULL) {
kfree(ahp->ah_analogBank3Data);
ahp->ah_analogBank3Data = NULL;
}
if (ahp->ah_analogBank6Data != NULL) {
kfree(ahp->ah_analogBank6Data);
ahp->ah_analogBank6Data = NULL;
}
if (ahp->ah_analogBank6TPCData != NULL) {
kfree(ahp->ah_analogBank6TPCData);
ahp->ah_analogBank6TPCData = NULL;
}
if (ahp->ah_analogBank7Data != NULL) {
kfree(ahp->ah_analogBank7Data);
ahp->ah_analogBank7Data = NULL;
}
if (ahp->ah_addac5416_21 != NULL) {
kfree(ahp->ah_addac5416_21);
ahp->ah_addac5416_21 = NULL;
}
if (ahp->ah_bank6Temp != NULL) {
kfree(ahp->ah_bank6Temp);
ahp->ah_bank6Temp = NULL;
}
}
bool ath9k_hw_init_rf(struct ath_hal *ah, int *status)
{
struct ath_hal_5416 *ahp = AH5416(ah);
if (!AR_SREV_9280_10_OR_LATER(ah)) {
ahp->ah_analogBank0Data =
kzalloc((sizeof(u32) *
ahp->ah_iniBank0.ia_rows), GFP_KERNEL);
ahp->ah_analogBank1Data =
kzalloc((sizeof(u32) *
ahp->ah_iniBank1.ia_rows), GFP_KERNEL);
ahp->ah_analogBank2Data =
kzalloc((sizeof(u32) *
ahp->ah_iniBank2.ia_rows), GFP_KERNEL);
ahp->ah_analogBank3Data =
kzalloc((sizeof(u32) *
ahp->ah_iniBank3.ia_rows), GFP_KERNEL);
ahp->ah_analogBank6Data =
kzalloc((sizeof(u32) *
ahp->ah_iniBank6.ia_rows), GFP_KERNEL);
ahp->ah_analogBank6TPCData =
kzalloc((sizeof(u32) *
ahp->ah_iniBank6TPC.ia_rows), GFP_KERNEL);
ahp->ah_analogBank7Data =
kzalloc((sizeof(u32) *
ahp->ah_iniBank7.ia_rows), GFP_KERNEL);
if (ahp->ah_analogBank0Data == NULL
|| ahp->ah_analogBank1Data == NULL
|| ahp->ah_analogBank2Data == NULL
|| ahp->ah_analogBank3Data == NULL
|| ahp->ah_analogBank6Data == NULL
|| ahp->ah_analogBank6TPCData == NULL
|| ahp->ah_analogBank7Data == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"%s: cannot allocate RF banks\n",
__func__);
*status = -ENOMEM;
return false;
}
ahp->ah_addac5416_21 =
kzalloc((sizeof(u32) *
ahp->ah_iniAddac.ia_rows *
ahp->ah_iniAddac.ia_columns), GFP_KERNEL);
if (ahp->ah_addac5416_21 == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"%s: cannot allocate ah_addac5416_21\n",
__func__);
*status = -ENOMEM;
return false;
}
ahp->ah_bank6Temp =
kzalloc((sizeof(u32) *
ahp->ah_iniBank6.ia_rows), GFP_KERNEL);
if (ahp->ah_bank6Temp == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"%s: cannot allocate ah_bank6Temp\n",
__func__);
*status = -ENOMEM;
return false;
}
}
return true;
}
void
ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
{
int i, regWrites = 0;
struct ath_hal_5416 *ahp = AH5416(ah);
u32 bank6SelMask;
u32 *bank6Temp = ahp->ah_bank6Temp;
switch (ahp->ah_diversityControl) {
case ATH9K_ANT_FIXED_A:
bank6SelMask =
(ahp->
ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
REDUCE_CHAIN_1;
break;
case ATH9K_ANT_FIXED_B:
bank6SelMask =
(ahp->
ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
REDUCE_CHAIN_0;
break;
case ATH9K_ANT_VARIABLE:
return;
break;
default:
return;
break;
}
for (i = 0; i < ahp->ah_iniBank6.ia_rows; i++)
bank6Temp[i] = ahp->ah_analogBank6Data[i];
REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0);
ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0);
ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0);
ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 192, 0);
ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 193, 0);
ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 222, 0);
ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 245, 0);
ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6, bank6Temp, regWrites);
REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
#ifdef ALTER_SWITCH
REG_WRITE(ah, PHY_SWITCH_CHAIN_0,
(REG_READ(ah, PHY_SWITCH_CHAIN_0) & ~0x38)
| ((REG_READ(ah, PHY_SWITCH_CHAIN_0) >> 3) & 0x38));
#endif
}

View file

@ -0,0 +1,543 @@
/*
* 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.
*/
#ifndef PHY_H
#define PHY_H
bool ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
struct ath9k_channel
*chan);
bool ath9k_hw_set_channel(struct ath_hal *ah,
struct ath9k_channel *chan);
void ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex,
u32 freqIndex, int regWrites);
bool ath9k_hw_set_rf_regs(struct ath_hal *ah,
struct ath9k_channel *chan,
u16 modesIndex);
void ath9k_hw_decrease_chain_power(struct ath_hal *ah,
struct ath9k_channel *chan);
bool ath9k_hw_init_rf(struct ath_hal *ah,
int *status);
#define AR_PHY_BASE 0x9800
#define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2))
#define AR_PHY_TEST 0x9800
#define PHY_AGC_CLR 0x10000000
#define RFSILENT_BB 0x00002000
#define AR_PHY_TURBO 0x9804
#define AR_PHY_FC_TURBO_MODE 0x00000001
#define AR_PHY_FC_TURBO_SHORT 0x00000002
#define AR_PHY_FC_DYN2040_EN 0x00000004
#define AR_PHY_FC_DYN2040_PRI_ONLY 0x00000008
#define AR_PHY_FC_DYN2040_PRI_CH 0x00000010
#define AR_PHY_FC_DYN2040_EXT_CH 0x00000020
#define AR_PHY_FC_HT_EN 0x00000040
#define AR_PHY_FC_SHORT_GI_40 0x00000080
#define AR_PHY_FC_WALSH 0x00000100
#define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200
#define AR_PHY_TIMING2 0x9810
#define AR_PHY_TIMING3 0x9814
#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000
#define AR_PHY_TIMING3_DSC_MAN_S 17
#define AR_PHY_TIMING3_DSC_EXP 0x0001E000
#define AR_PHY_TIMING3_DSC_EXP_S 13
#define AR_PHY_CHIP_ID 0x9818
#define AR_PHY_CHIP_ID_REV_0 0x80
#define AR_PHY_CHIP_ID_REV_1 0x81
#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
#define AR_PHY_ACTIVE 0x981C
#define AR_PHY_ACTIVE_EN 0x00000001
#define AR_PHY_ACTIVE_DIS 0x00000000
#define AR_PHY_RF_CTL2 0x9824
#define AR_PHY_TX_END_DATA_START 0x000000FF
#define AR_PHY_TX_END_DATA_START_S 0
#define AR_PHY_TX_END_PA_ON 0x0000FF00
#define AR_PHY_TX_END_PA_ON_S 8
#define AR_PHY_RF_CTL3 0x9828
#define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000
#define AR_PHY_TX_END_TO_A2_RX_ON_S 16
#define AR_PHY_ADC_CTL 0x982C
#define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003
#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S 0
#define AR_PHY_ADC_CTL_OFF_PWDDAC 0x00002000
#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000
#define AR_PHY_ADC_CTL_OFF_PWDADC 0x00008000
#define AR_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000
#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S 16
#define AR_PHY_ADC_SERIAL_CTL 0x9830
#define AR_PHY_SEL_INTERNAL_ADDAC 0x00000000
#define AR_PHY_SEL_EXTERNAL_RADIO 0x00000001
#define AR_PHY_RF_CTL4 0x9834
#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF 0xFF000000
#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24
#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00FF0000
#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16
#define AR_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000FF00
#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S 8
#define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF
#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0
#define AR_PHY_SETTLING 0x9844
#define AR_PHY_SETTLING_SWITCH 0x00003F80
#define AR_PHY_SETTLING_SWITCH_S 7
#define AR_PHY_RXGAIN 0x9848
#define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000
#define AR_PHY_RXGAIN_TXRX_ATTEN_S 12
#define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000
#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18
#define AR9280_PHY_RXGAIN_TXRX_ATTEN 0x00003F80
#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7
#define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000
#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
#define AR_PHY_DESIRED_SZ 0x9850
#define AR_PHY_DESIRED_SZ_ADC 0x000000FF
#define AR_PHY_DESIRED_SZ_ADC_S 0
#define AR_PHY_DESIRED_SZ_PGA 0x0000FF00
#define AR_PHY_DESIRED_SZ_PGA_S 8
#define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000
#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
#define AR_PHY_FIND_SIG 0x9858
#define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000
#define AR_PHY_FIND_SIG_FIRSTEP_S 12
#define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000
#define AR_PHY_FIND_SIG_FIRPWR_S 18
#define AR_PHY_AGC_CTL1 0x985C
#define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80
#define AR_PHY_AGC_CTL1_COARSE_LOW_S 7
#define AR_PHY_AGC_CTL1_COARSE_HIGH 0x003F8000
#define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15
#define AR_PHY_AGC_CONTROL 0x9860
#define AR_PHY_AGC_CONTROL_CAL 0x00000001
#define AR_PHY_AGC_CONTROL_NF 0x00000002
#define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000
#define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000
#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000
#define AR_PHY_CCA 0x9864
#define AR_PHY_MINCCA_PWR 0x0FF80000
#define AR_PHY_MINCCA_PWR_S 19
#define AR_PHY_CCA_THRESH62 0x0007F000
#define AR_PHY_CCA_THRESH62_S 12
#define AR9280_PHY_MINCCA_PWR 0x1FF00000
#define AR9280_PHY_MINCCA_PWR_S 20
#define AR9280_PHY_CCA_THRESH62 0x000FF000
#define AR9280_PHY_CCA_THRESH62_S 12
#define AR_PHY_SFCORR_LOW 0x986C
#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00
#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8
#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000
#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14
#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000
#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21
#define AR_PHY_SFCORR 0x9868
#define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F
#define AR_PHY_SFCORR_M2COUNT_THR_S 0
#define AR_PHY_SFCORR_M1_THRESH 0x00FE0000
#define AR_PHY_SFCORR_M1_THRESH_S 17
#define AR_PHY_SFCORR_M2_THRESH 0x7F000000
#define AR_PHY_SFCORR_M2_THRESH_S 24
#define AR_PHY_SLEEP_CTR_CONTROL 0x9870
#define AR_PHY_SLEEP_CTR_LIMIT 0x9874
#define AR_PHY_SYNTH_CONTROL 0x9874
#define AR_PHY_SLEEP_SCAL 0x9878
#define AR_PHY_PLL_CTL 0x987c
#define AR_PHY_PLL_CTL_40 0xaa
#define AR_PHY_PLL_CTL_40_5413 0x04
#define AR_PHY_PLL_CTL_44 0xab
#define AR_PHY_PLL_CTL_44_2133 0xeb
#define AR_PHY_PLL_CTL_40_2133 0xea
#define AR_PHY_RX_DELAY 0x9914
#define AR_PHY_SEARCH_START_DELAY 0x9918
#define AR_PHY_RX_DELAY_DELAY 0x00003FFF
#define AR_PHY_TIMING_CTRL4(_i) (0x9920 + ((_i) << 12))
#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0
#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5
#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800
#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12
#define AR_PHY_TIMING_CTRL4_DO_CAL 0x10000
#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000
#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000
#define AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000
#define AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000
#define AR_PHY_TIMING5 0x9924
#define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE
#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
#define AR_PHY_POWER_TX_RATE1 0x9934
#define AR_PHY_POWER_TX_RATE2 0x9938
#define AR_PHY_POWER_TX_RATE_MAX 0x993c
#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
#define AR_PHY_FRAME_CTL 0x9944
#define AR_PHY_FRAME_CTL_TX_CLIP 0x00000038
#define AR_PHY_FRAME_CTL_TX_CLIP_S 3
#define AR_PHY_TXPWRADJ 0x994C
#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA 0x00000FC0
#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S 6
#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX 0x00FC0000
#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
#define AR_PHY_RADAR_EXT 0x9940
#define AR_PHY_RADAR_EXT_ENA 0x00004000
#define AR_PHY_RADAR_0 0x9954
#define AR_PHY_RADAR_0_ENA 0x00000001
#define AR_PHY_RADAR_0_FFT_ENA 0x80000000
#define AR_PHY_RADAR_0_INBAND 0x0000003e
#define AR_PHY_RADAR_0_INBAND_S 1
#define AR_PHY_RADAR_0_PRSSI 0x00000FC0
#define AR_PHY_RADAR_0_PRSSI_S 6
#define AR_PHY_RADAR_0_HEIGHT 0x0003F000
#define AR_PHY_RADAR_0_HEIGHT_S 12
#define AR_PHY_RADAR_0_RRSSI 0x00FC0000
#define AR_PHY_RADAR_0_RRSSI_S 18
#define AR_PHY_RADAR_0_FIRPWR 0x7F000000
#define AR_PHY_RADAR_0_FIRPWR_S 24
#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_SWITCH_CHAIN_0 0x9960
#define AR_PHY_SWITCH_COM 0x9964
#define AR_PHY_SIGMA_DELTA 0x996C
#define AR_PHY_SIGMA_DELTA_ADC_SEL 0x00000003
#define AR_PHY_SIGMA_DELTA_ADC_SEL_S 0
#define AR_PHY_SIGMA_DELTA_FILT2 0x000000F8
#define AR_PHY_SIGMA_DELTA_FILT2_S 3
#define AR_PHY_SIGMA_DELTA_FILT1 0x00001F00
#define AR_PHY_SIGMA_DELTA_FILT1_S 8
#define AR_PHY_SIGMA_DELTA_ADC_CLIP 0x01FFE000
#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
#define AR_PHY_RESTART 0x9970
#define AR_PHY_RESTART_DIV_GC 0x001C0000
#define AR_PHY_RESTART_DIV_GC_S 18
#define AR_PHY_RFBUS_REQ 0x997C
#define AR_PHY_RFBUS_REQ_EN 0x00000001
#define AR_PHY_TIMING7 0x9980
#define AR_PHY_TIMING8 0x9984
#define AR_PHY_TIMING8_PILOT_MASK_2 0x000FFFFF
#define AR_PHY_TIMING8_PILOT_MASK_2_S 0
#define AR_PHY_BIN_MASK2_1 0x9988
#define AR_PHY_BIN_MASK2_2 0x998c
#define AR_PHY_BIN_MASK2_3 0x9990
#define AR_PHY_BIN_MASK2_4 0x9994
#define AR_PHY_BIN_MASK_1 0x9900
#define AR_PHY_BIN_MASK_2 0x9904
#define AR_PHY_BIN_MASK_3 0x9908
#define AR_PHY_MASK_CTL 0x990c
#define AR_PHY_BIN_MASK2_4_MASK_4 0x00003FFF
#define AR_PHY_BIN_MASK2_4_MASK_4_S 0
#define AR_PHY_TIMING9 0x9998
#define AR_PHY_TIMING10 0x999c
#define AR_PHY_TIMING10_PILOT_MASK_2 0x000FFFFF
#define AR_PHY_TIMING10_PILOT_MASK_2_S 0
#define AR_PHY_TIMING11 0x99a0
#define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF
#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
#define AR_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000
#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000
#define AR_PHY_RX_CHAINMASK 0x99a4
#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac
#define AR_PHY_EXT_CCA0 0x99b8
#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF
#define AR_PHY_EXT_CCA0_THRESH62_S 0
#define AR_PHY_EXT_CCA 0x99bc
#define AR_PHY_EXT_CCA_CYCPWR_THR1 0x0000FE00
#define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9
#define AR_PHY_EXT_CCA_THRESH62 0x007F0000
#define AR_PHY_EXT_CCA_THRESH62_S 16
#define AR_PHY_EXT_MINCCA_PWR 0xFF800000
#define AR_PHY_EXT_MINCCA_PWR_S 23
#define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000
#define AR9280_PHY_EXT_MINCCA_PWR_S 16
#define AR_PHY_SFCORR_EXT 0x99c0
#define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F
#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0
#define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80
#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7
#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000
#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000
#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
#define AR_PHY_HALFGI 0x99D0
#define AR_PHY_HALFGI_DSC_MAN 0x0007FFF0
#define AR_PHY_HALFGI_DSC_MAN_S 4
#define AR_PHY_HALFGI_DSC_EXP 0x0000000F
#define AR_PHY_HALFGI_DSC_EXP_S 0
#define AR_PHY_CHAN_INFO_MEMORY 0x99DC
#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001
#define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0
#define AR_PHY_M_SLEEP 0x99f0
#define AR_PHY_REFCLKDLY 0x99f4
#define AR_PHY_REFCLKPD 0x99f8
#define AR_PHY_CALMODE 0x99f0
#define AR_PHY_CALMODE_IQ 0x00000000
#define AR_PHY_CALMODE_ADC_GAIN 0x00000001
#define AR_PHY_CALMODE_ADC_DC_PER 0x00000002
#define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003
#define AR_PHY_CAL_MEAS_0(_i) (0x9c10 + ((_i) << 12))
#define AR_PHY_CAL_MEAS_1(_i) (0x9c14 + ((_i) << 12))
#define AR_PHY_CAL_MEAS_2(_i) (0x9c18 + ((_i) << 12))
#define AR_PHY_CAL_MEAS_3(_i) (0x9c1c + ((_i) << 12))
#define AR_PHY_CURRENT_RSSI 0x9c1c
#define AR9280_PHY_CURRENT_RSSI 0x9c3c
#define AR_PHY_RFBUS_GRANT 0x9C20
#define AR_PHY_RFBUS_GRANT_EN 0x00000001
#define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4
#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
#define AR_PHY_CHAN_INFO_GAIN 0x9CFC
#define AR_PHY_MODE 0xA200
#define AR_PHY_MODE_AR2133 0x08
#define AR_PHY_MODE_AR5111 0x00
#define AR_PHY_MODE_AR5112 0x08
#define AR_PHY_MODE_DYNAMIC 0x04
#define AR_PHY_MODE_RF2GHZ 0x02
#define AR_PHY_MODE_RF5GHZ 0x00
#define AR_PHY_MODE_CCK 0x01
#define AR_PHY_MODE_OFDM 0x00
#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
#define AR_PHY_CCK_TX_CTRL 0xA204
#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
#define AR_PHY_CCK_DETECT 0xA208
#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F
#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
/* [12:6] settling time for antenna switch */
#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0
#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
#define AR_PHY_GAIN_2GHZ 0xA20C
#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000
#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18
#define AR_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003C00
#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S 10
#define AR_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001F
#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S 0
#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003E0000
#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17
#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001F000
#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12
#define AR_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000FC0
#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S 6
#define AR_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003F
#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S 0
#define AR_PHY_CCK_RXCTRL4 0xA21C
#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01F80000
#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
#define AR_PHY_DAG_CTRLCCK 0xA228
#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200
#define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00
#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10
#define AR_PHY_FORCE_CLKEN_CCK 0xA22C
#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX 0x00000040
#define AR_PHY_POWER_TX_RATE3 0xA234
#define AR_PHY_POWER_TX_RATE4 0xA238
#define AR_PHY_SCRM_SEQ_XR 0xA23C
#define AR_PHY_HEADER_DETECT_XR 0xA240
#define AR_PHY_CHIRP_DETECTED_XR 0xA244
#define AR_PHY_BLUETOOTH 0xA254
#define AR_PHY_TPCRG1 0xA258
#define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000
#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
#define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000
#define AR_PHY_TPCRG1_PD_GAIN_1_S 16
#define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000
#define AR_PHY_TPCRG1_PD_GAIN_2_S 18
#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000
#define AR_PHY_TPCRG1_PD_GAIN_3_S 20
#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
#define AR_PHY_MASK2_M_31_45 0xa3a4
#define AR_PHY_MASK2_M_16_30 0xa3a8
#define AR_PHY_MASK2_M_00_15 0xa3ac
#define AR_PHY_MASK2_P_15_01 0xa3b8
#define AR_PHY_MASK2_P_30_16 0xa3bc
#define AR_PHY_MASK2_P_45_31 0xa3c0
#define AR_PHY_MASK2_P_61_45 0xa3c4
#define AR_PHY_SPUR_REG 0x994c
#define AR_PHY_SPUR_REG_MASK_RATE_CNTL (0xFF << 18)
#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18
#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000
#define AR_PHY_SPUR_REG_MASK_RATE_SELECT (0xFF << 9)
#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S 9
#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7F
#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
#define AR_PHY_PILOT_MASK_01_30 0xa3b0
#define AR_PHY_PILOT_MASK_31_60 0xa3b4
#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
#define AR_PHY_ANALOG_SWAP 0xa268
#define AR_PHY_SWAP_ALT_CHAIN 0x00000040
#define AR_PHY_TPCRG5 0xA26C
#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F
#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
#define AR_PHY_POWER_TX_RATE5 0xA38C
#define AR_PHY_POWER_TX_RATE6 0xA390
#define AR_PHY_CAL_CHAINMASK 0xA39C
#define AR_PHY_POWER_TX_SUB 0xA3C8
#define AR_PHY_POWER_TX_RATE7 0xA3CC
#define AR_PHY_POWER_TX_RATE8 0xA3D0
#define AR_PHY_POWER_TX_RATE9 0xA3D4
#define AR_PHY_XPA_CFG 0xA3D8
#define AR_PHY_FORCE_XPA_CFG 0x000000001
#define AR_PHY_FORCE_XPA_CFG_S 0
#define AR_PHY_CH1_CCA 0xa864
#define AR_PHY_CH1_MINCCA_PWR 0x0FF80000
#define AR_PHY_CH1_MINCCA_PWR_S 19
#define AR9280_PHY_CH1_MINCCA_PWR 0x1FF00000
#define AR9280_PHY_CH1_MINCCA_PWR_S 20
#define AR_PHY_CH2_CCA 0xb864
#define AR_PHY_CH2_MINCCA_PWR 0x0FF80000
#define AR_PHY_CH2_MINCCA_PWR_S 19
#define AR_PHY_CH1_EXT_CCA 0xa9bc
#define AR_PHY_CH1_EXT_MINCCA_PWR 0xFF800000
#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
#define AR9280_PHY_CH1_EXT_MINCCA_PWR 0x01FF0000
#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
#define AR_PHY_CH2_EXT_CCA 0xb9bc
#define AR_PHY_CH2_EXT_MINCCA_PWR 0xFF800000
#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \
int r; \
for (r = 0; r < ((iniarray)->ia_rows); r++) { \
REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, \
"RF 0x%x V 0x%x\n", \
INI_RA((iniarray), r, 0), (regData)[r]); \
DO_DELAY(regWr); \
} \
} while (0)
#define ATH9K_KEY_XOR 0xaa
#define ATH9K_IS_MIC_ENABLED(ah) \
(AH5416(ah)->ah_staId1Defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
#define ANTSWAP_AB 0x0001
#define REDUCE_CHAIN_0 0x00000050
#define REDUCE_CHAIN_1 0x00000051
#define RF_BANK_SETUP(_bank, _iniarray, _col) do { \
int i; \
for (i = 0; i < (_iniarray)->ia_rows; i++) \
(_bank)[i] = INI_RA((_iniarray), i, _col);; \
} while (0)
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,316 @@
/*
* Copyright (c) 2004 Sam Leffler, Errno Consulting
* Copyright (c) 2004 Video54 Technologies, Inc.
* 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.
*/
#ifndef RC_H
#define RC_H
#include "ath9k.h"
/*
* Interface definitions for transmit rate control modules for the
* Atheros driver.
*
* A rate control module is responsible for choosing the transmit rate
* for each data frame. Management+control frames are always sent at
* a fixed rate.
*
* Only one module may be present at a time; the driver references
* rate control interfaces by symbol name. If multiple modules are
* to be supported we'll need to switch to a registration-based scheme
* as is currently done, for example, for authentication modules.
*
* An instance of the rate control module is attached to each device
* at attach time and detached when the device is destroyed. The module
* may associate data with each device and each node (station). Both
* sets of storage are opaque except for the size of the per-node storage
* which must be provided when the module is attached.
*
* The rate control module is notified for each state transition and
* station association/reassociation. Otherwise it is queried for a
* rate for each outgoing frame and provided status from each transmitted
* frame. Any ancillary processing is the responsibility of the module
* (e.g. if periodic processing is required then the module should setup
* it's own timer).
*
* In addition to the transmit rate for each frame the module must also
* indicate the number of attempts to make at the specified rate. If this
* number is != ATH_TXMAXTRY then an additional callback is made to setup
* additional transmit state. The rate control code is assumed to write
* this additional data directly to the transmit descriptor.
*/
struct ath_softc;
#define TRUE 1
#define FALSE 0
#define ATH_RATE_MAX 30
#define MCS_SET_SIZE 128
enum ieee80211_fixed_rate_mode {
IEEE80211_FIXED_RATE_NONE = 0,
IEEE80211_FIXED_RATE_MCS = 1 /* HT rates */
};
/*
* Use the hal os glue code to get ms time
*/
#define IEEE80211_RATE_IDX_ENTRY(val, idx) (((val&(0xff<<(idx*8)))>>(idx*8)))
#define SHORT_PRE 1
#define LONG_PRE 0
#define WLAN_PHY_HT_20_SS WLAN_RC_PHY_HT_20_SS
#define WLAN_PHY_HT_20_DS WLAN_RC_PHY_HT_20_DS
#define WLAN_PHY_HT_20_DS_HGI WLAN_RC_PHY_HT_20_DS_HGI
#define WLAN_PHY_HT_40_SS WLAN_RC_PHY_HT_40_SS
#define WLAN_PHY_HT_40_SS_HGI WLAN_RC_PHY_HT_40_SS_HGI
#define WLAN_PHY_HT_40_DS WLAN_RC_PHY_HT_40_DS
#define WLAN_PHY_HT_40_DS_HGI WLAN_RC_PHY_HT_40_DS_HGI
#define WLAN_PHY_OFDM PHY_OFDM
#define WLAN_PHY_CCK PHY_CCK
#define TRUE_20 0x2
#define TRUE_40 0x4
#define TRUE_2040 (TRUE_20|TRUE_40)
#define TRUE_ALL (TRUE_2040|TRUE)
enum {
WLAN_RC_PHY_HT_20_SS = 4,
WLAN_RC_PHY_HT_20_DS,
WLAN_RC_PHY_HT_40_SS,
WLAN_RC_PHY_HT_40_DS,
WLAN_RC_PHY_HT_20_SS_HGI,
WLAN_RC_PHY_HT_20_DS_HGI,
WLAN_RC_PHY_HT_40_SS_HGI,
WLAN_RC_PHY_HT_40_DS_HGI,
WLAN_RC_PHY_MAX
};
#define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \
|| (_phy == WLAN_RC_PHY_HT_40_DS) \
|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
#define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \
|| (_phy == WLAN_RC_PHY_HT_40_DS) \
|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
#define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
#define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS)
/* Returns the capflag mode */
#define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ? \
(capflag & WLAN_RC_40_FLAG) ? TRUE_40 : TRUE_20 : TRUE))
/* Return TRUE if flag supports HT20 && client supports HT20 or
* return TRUE if flag supports HT40 && client supports HT40.
* This is used becos some rates overlap between HT20/HT40.
*/
#define WLAN_RC_PHY_HT_VALID(flag, capflag) (((flag & TRUE_20) && !(capflag \
& WLAN_RC_40_FLAG)) || ((flag & TRUE_40) && \
(capflag & WLAN_RC_40_FLAG)))
#define WLAN_RC_DS_FLAG (0x01)
#define WLAN_RC_40_FLAG (0x02)
#define WLAN_RC_SGI_FLAG (0x04)
#define WLAN_RC_HT_FLAG (0x08)
/* Index into the rate table */
#define INIT_RATE_MAX_20 23
#define INIT_RATE_MAX_40 40
#define RATE_TABLE_SIZE 64
/* XXX: Convert to kdoc */
struct ath_rate_table {
int rate_cnt;
struct {
int valid; /* Valid for use in rate control */
int valid_single_stream;/* Valid for use in rate control
for single stream operation */
u8 phy; /* CCK/OFDM/TURBO/XR */
u32 ratekbps; /* Rate in Kbits per second */
u32 user_ratekbps; /* User rate in KBits per second */
u8 ratecode; /* rate that goes into
hw descriptors */
u8 short_preamble; /* Mask for enabling short preamble
in rate code for CCK */
u8 dot11rate; /* Value that goes into supported
rates info element of MLME */
u8 ctrl_rate; /* Index of next lower basic rate,
used for duration computation */
int8_t rssi_ack_validmin; /* Rate control related */
int8_t rssi_ack_deltamin; /* Rate control related */
u8 base_index; /* base rate index */
u8 cw40index; /* 40cap rate index */
u8 sgi_index; /* shortgi rate index */
u8 ht_index; /* shortgi rate index */
u32 max_4ms_framelen; /* Maximum frame length(bytes)
for 4ms tx duration */
} info[RATE_TABLE_SIZE];
u32 probe_interval; /* interval for ratectrl to
probe for other rates */
u32 rssi_reduce_interval; /* interval for ratectrl
to reduce RSSI */
u8 initial_ratemax; /* the initial ratemax value used
in ath_rc_sib_update() */
};
#define ATH_RC_PROBE_ALLOWED 0x00000001
#define ATH_RC_MINRATE_LASTRATE 0x00000002
#define ATH_RC_SHORT_PREAMBLE 0x00000004
struct ath_rc_series {
u8 rix;
u8 tries;
u8 flags;
u32 max_4ms_framelen;
};
/* rcs_flags definition */
#define ATH_RC_DS_FLAG 0x01
#define ATH_RC_CW40_FLAG 0x02 /* CW 40 */
#define ATH_RC_SGI_FLAG 0x04 /* Short Guard Interval */
#define ATH_RC_HT_FLAG 0x08 /* HT */
#define ATH_RC_RTSCTS_FLAG 0x10 /* RTS-CTS */
/*
* State structures for new rate adaptation code
*/
#define MAX_TX_RATE_TBL 64
#define MAX_TX_RATE_PHY 48
struct ath_tx_ratectrl_state {
int8_t rssi_thres; /* required rssi for this rate (dB) */
u8 per; /* recent estimate of packet error rate (%) */
};
struct ath_tx_ratectrl {
struct ath_tx_ratectrl_state state[MAX_TX_RATE_TBL]; /* state */
int8_t rssi_last; /* last ack rssi */
int8_t rssi_last_lookup; /* last ack rssi used for lookup */
int8_t rssi_last_prev; /* previous last ack rssi */
int8_t rssi_last_prev2; /* 2nd previous last ack rssi */
int32_t rssi_sum_cnt; /* count of rssi_sum for averaging */
int32_t rssi_sum_rate; /* rate that we are averaging */
int32_t rssi_sum; /* running sum of rssi for averaging */
u32 valid_txrate_mask; /* mask of valid rates */
u8 rate_table_size; /* rate table size */
u8 rate_max; /* max rate that has recently worked */
u8 probe_rate; /* rate we are probing at */
u32 rssi_time; /* msec timestamp for last ack rssi */
u32 rssi_down_time; /* msec timestamp for last down step */
u32 probe_time; /* msec timestamp for last probe */
u8 hw_maxretry_pktcnt; /* num packets since we got
HW max retry error */
u8 max_valid_rate; /* maximum number of valid rate */
u8 valid_rate_index[MAX_TX_RATE_TBL]; /* valid rate index */
u32 per_down_time; /* msec timstamp for last
PER down step */
/* 11n state */
u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX]; /* valid rate count */
u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][MAX_TX_RATE_TBL];
u8 rc_phy_mode;
u8 rate_max_phy; /* Phy index for the max rate */
u32 rate_max_lastused; /* msec timstamp of when we
last used rateMaxPhy */
u32 probe_interval; /* interval for ratectrl to probe
for other rates */
};
struct ath_rateset {
u8 rs_nrates;
u8 rs_rates[ATH_RATE_MAX];
};
/* per-device state */
struct ath_rate_softc {
/* phy tables that contain rate control data */
const void *hw_rate_table[WIRELESS_MODE_MAX];
int fixedrix; /* -1 or index of fixed rate */
};
/* per-node state */
struct ath_rate_node {
struct ath_tx_ratectrl tx_ratectrl; /* rate control state proper */
u32 prev_data_rix; /* rate idx of last data frame */
/* map of rate ix -> negotiated rate set ix */
u8 rixmap[MAX_TX_RATE_TBL];
/* map of ht rate ix -> negotiated rate set ix */
u8 ht_rixmap[MAX_TX_RATE_TBL];
u8 ht_cap; /* ht capabilities */
u8 ant_tx; /* current transmit antenna */
u8 single_stream; /* When TRUE, only single
stream Tx possible */
struct ath_rateset neg_rates; /* Negotiated rates */
struct ath_rateset neg_ht_rates; /* Negotiated HT rates */
struct ath_rate_softc *asc; /* back pointer to atheros softc */
struct ath_vap *avp; /* back pointer to vap */
};
/* Driver data of ieee80211_tx_info */
struct ath_tx_info_priv {
struct ath_rc_series rcs[4];
struct ath_tx_status tx;
int n_frames;
int n_bad_frames;
u8 min_rate;
};
/*
* Attach/detach a rate control module.
*/
struct ath_rate_softc *ath_rate_attach(struct ath_hal *ah);
void ath_rate_detach(struct ath_rate_softc *asc);
/*
* Update/reset rate control state for 802.11 state transitions.
* Important mostly as the analog to ath_rate_newassoc when operating
* in station mode.
*/
void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv);
void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp);
/*
* Return the tx rate series.
*/
void ath_rate_findrate(struct ath_softc *sc, struct ath_rate_node *ath_rc_priv,
int num_tries, int num_rates,
unsigned int rcflag, struct ath_rc_series[],
int *is_probe, int isretry);
/*
* Return rate index for given Dot11 Rate.
*/
u8 ath_rate_findrateix(struct ath_softc *sc,
u8 dot11_rate);
/* Routines to register/unregister rate control algorithm */
int ath_rate_control_register(void);
void ath_rate_control_unregister(void);
#endif /* RC_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,412 @@
/*
* 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.
*/
#ifndef REGD_H
#define REGD_H
#include "ath9k.h"
#define BMLEN 2
#define BMZERO {(u64) 0, (u64) 0}
#define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \
{((((_fa >= 0) && (_fa < 64)) ? \
(((u64) 1) << _fa) : (u64) 0) | \
(((_fb >= 0) && (_fb < 64)) ? \
(((u64) 1) << _fb) : (u64) 0) | \
(((_fc >= 0) && (_fc < 64)) ? \
(((u64) 1) << _fc) : (u64) 0) | \
(((_fd >= 0) && (_fd < 64)) ? \
(((u64) 1) << _fd) : (u64) 0) | \
(((_fe >= 0) && (_fe < 64)) ? \
(((u64) 1) << _fe) : (u64) 0) | \
(((_ff >= 0) && (_ff < 64)) ? \
(((u64) 1) << _ff) : (u64) 0) | \
(((_fg >= 0) && (_fg < 64)) ? \
(((u64) 1) << _fg) : (u64) 0) | \
(((_fh >= 0) && (_fh < 64)) ? \
(((u64) 1) << _fh) : (u64) 0) | \
(((_fi >= 0) && (_fi < 64)) ? \
(((u64) 1) << _fi) : (u64) 0) | \
(((_fj >= 0) && (_fj < 64)) ? \
(((u64) 1) << _fj) : (u64) 0) | \
(((_fk >= 0) && (_fk < 64)) ? \
(((u64) 1) << _fk) : (u64) 0) | \
(((_fl >= 0) && (_fl < 64)) ? \
(((u64) 1) << _fl) : (u64) 0) | \
((((_fa > 63) && (_fa < 128)) ? \
(((u64) 1) << (_fa - 64)) : (u64) 0) | \
(((_fb > 63) && (_fb < 128)) ? \
(((u64) 1) << (_fb - 64)) : (u64) 0) | \
(((_fc > 63) && (_fc < 128)) ? \
(((u64) 1) << (_fc - 64)) : (u64) 0) | \
(((_fd > 63) && (_fd < 128)) ? \
(((u64) 1) << (_fd - 64)) : (u64) 0) | \
(((_fe > 63) && (_fe < 128)) ? \
(((u64) 1) << (_fe - 64)) : (u64) 0) | \
(((_ff > 63) && (_ff < 128)) ? \
(((u64) 1) << (_ff - 64)) : (u64) 0) | \
(((_fg > 63) && (_fg < 128)) ? \
(((u64) 1) << (_fg - 64)) : (u64) 0) | \
(((_fh > 63) && (_fh < 128)) ? \
(((u64) 1) << (_fh - 64)) : (u64) 0) | \
(((_fi > 63) && (_fi < 128)) ? \
(((u64) 1) << (_fi - 64)) : (u64) 0) | \
(((_fj > 63) && (_fj < 128)) ? \
(((u64) 1) << (_fj - 64)) : (u64) 0) | \
(((_fk > 63) && (_fk < 128)) ? \
(((u64) 1) << (_fk - 64)) : (u64) 0) | \
(((_fl > 63) && (_fl < 128)) ? \
(((u64) 1) << (_fl - 64)) : (u64) 0)))}
#define DEF_REGDMN FCC1_FCCA
#define DEF_DMN_5 FCC1
#define DEF_DMN_2 FCCA
#define COUNTRY_ERD_FLAG 0x8000
#define WORLDWIDE_ROAMING_FLAG 0x4000
#define SUPER_DOMAIN_MASK 0x0fff
#define COUNTRY_CODE_MASK 0x3fff
#define CF_INTERFERENCE (CHANNEL_CW_INT | CHANNEL_RADAR_INT)
#define CHANNEL_14 (2484)
#define IS_11G_CH14(_ch,_cf) \
(((_ch) == CHANNEL_14) && ((_cf) == CHANNEL_G))
#define NO_PSCAN 0x0ULL
#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
#define isWwrSKU(_ah) \
(((ath9k_regd_get_eepromRD((_ah)) & WORLD_SKU_MASK) == \
WORLD_SKU_PREFIX) || \
(ath9k_regd_get_eepromRD(_ah) == WORLD))
#define isWwrSKU_NoMidband(_ah) \
((ath9k_regd_get_eepromRD((_ah)) == WOR3_WORLD) || \
(ath9k_regd_get_eepromRD(_ah) == WOR4_WORLD) || \
(ath9k_regd_get_eepromRD(_ah) == WOR5_ETSIC))
#define isUNII1OddChan(ch) \
((ch == 5170) || (ch == 5190) || (ch == 5210) || (ch == 5230))
#define IS_HT40_MODE(_mode) \
(((_mode == ATH9K_MODE_SEL_11NA_HT40PLUS || \
_mode == ATH9K_MODE_SEL_11NG_HT40PLUS || \
_mode == ATH9K_MODE_SEL_11NA_HT40MINUS || \
_mode == ATH9K_MODE_SEL_11NG_HT40MINUS) ? true : false))
#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
#define swap(_a, _b, _size) { \
u8 *s = _b; \
int i = _size; \
do { \
u8 tmp = *_a; \
*_a++ = *s; \
*s++ = tmp; \
} while (--i); \
_a -= _size; \
}
#define HALF_MAXCHANBW 10
#define MULTI_DOMAIN_MASK 0xFF00
#define WORLD_SKU_MASK 0x00F0
#define WORLD_SKU_PREFIX 0x0060
#define CHANNEL_HALF_BW 10
#define CHANNEL_QUARTER_BW 5
typedef int ath_hal_cmp_t(const void *, const void *);
struct reg_dmn_pair_mapping {
u16 regDmnEnum;
u16 regDmn5GHz;
u16 regDmn2GHz;
u32 flags5GHz;
u32 flags2GHz;
u64 pscanMask;
u16 singleCC;
};
struct ccmap {
char isoName[3];
u16 countryCode;
};
struct country_code_to_enum_rd {
u16 countryCode;
u16 regDmnEnum;
const char *isoName;
const char *name;
bool allow11g;
bool allow11aTurbo;
bool allow11gTurbo;
bool allow11ng20;
bool allow11ng40;
bool allow11na20;
bool allow11na40;
u16 outdoorChanStart;
};
struct RegDmnFreqBand {
u16 lowChannel;
u16 highChannel;
u8 powerDfs;
u8 antennaMax;
u8 channelBW;
u8 channelSep;
u64 useDfs;
u64 usePassScan;
u8 regClassId;
};
struct regDomain {
u16 regDmnEnum;
u8 conformanceTestLimit;
u64 dfsMask;
u64 pscan;
u32 flags;
u64 chan11a[BMLEN];
u64 chan11a_turbo[BMLEN];
u64 chan11a_dyn_turbo[BMLEN];
u64 chan11b[BMLEN];
u64 chan11g[BMLEN];
u64 chan11g_turbo[BMLEN];
};
struct cmode {
u32 mode;
u32 flags;
};
#define YES true
#define NO false
struct japan_bandcheck {
u16 freqbandbit;
u32 eepromflagtocheck;
};
struct common_mode_power {
u16 lchan;
u16 hchan;
u8 pwrlvl;
};
enum CountryCode {
CTRY_ALBANIA = 8,
CTRY_ALGERIA = 12,
CTRY_ARGENTINA = 32,
CTRY_ARMENIA = 51,
CTRY_AUSTRALIA = 36,
CTRY_AUSTRIA = 40,
CTRY_AZERBAIJAN = 31,
CTRY_BAHRAIN = 48,
CTRY_BELARUS = 112,
CTRY_BELGIUM = 56,
CTRY_BELIZE = 84,
CTRY_BOLIVIA = 68,
CTRY_BOSNIA_HERZ = 70,
CTRY_BRAZIL = 76,
CTRY_BRUNEI_DARUSSALAM = 96,
CTRY_BULGARIA = 100,
CTRY_CANADA = 124,
CTRY_CHILE = 152,
CTRY_CHINA = 156,
CTRY_COLOMBIA = 170,
CTRY_COSTA_RICA = 188,
CTRY_CROATIA = 191,
CTRY_CYPRUS = 196,
CTRY_CZECH = 203,
CTRY_DENMARK = 208,
CTRY_DOMINICAN_REPUBLIC = 214,
CTRY_ECUADOR = 218,
CTRY_EGYPT = 818,
CTRY_EL_SALVADOR = 222,
CTRY_ESTONIA = 233,
CTRY_FAEROE_ISLANDS = 234,
CTRY_FINLAND = 246,
CTRY_FRANCE = 250,
CTRY_GEORGIA = 268,
CTRY_GERMANY = 276,
CTRY_GREECE = 300,
CTRY_GUATEMALA = 320,
CTRY_HONDURAS = 340,
CTRY_HONG_KONG = 344,
CTRY_HUNGARY = 348,
CTRY_ICELAND = 352,
CTRY_INDIA = 356,
CTRY_INDONESIA = 360,
CTRY_IRAN = 364,
CTRY_IRAQ = 368,
CTRY_IRELAND = 372,
CTRY_ISRAEL = 376,
CTRY_ITALY = 380,
CTRY_JAMAICA = 388,
CTRY_JAPAN = 392,
CTRY_JORDAN = 400,
CTRY_KAZAKHSTAN = 398,
CTRY_KENYA = 404,
CTRY_KOREA_NORTH = 408,
CTRY_KOREA_ROC = 410,
CTRY_KOREA_ROC2 = 411,
CTRY_KOREA_ROC3 = 412,
CTRY_KUWAIT = 414,
CTRY_LATVIA = 428,
CTRY_LEBANON = 422,
CTRY_LIBYA = 434,
CTRY_LIECHTENSTEIN = 438,
CTRY_LITHUANIA = 440,
CTRY_LUXEMBOURG = 442,
CTRY_MACAU = 446,
CTRY_MACEDONIA = 807,
CTRY_MALAYSIA = 458,
CTRY_MALTA = 470,
CTRY_MEXICO = 484,
CTRY_MONACO = 492,
CTRY_MOROCCO = 504,
CTRY_NEPAL = 524,
CTRY_NETHERLANDS = 528,
CTRY_NETHERLANDS_ANTILLES = 530,
CTRY_NEW_ZEALAND = 554,
CTRY_NICARAGUA = 558,
CTRY_NORWAY = 578,
CTRY_OMAN = 512,
CTRY_PAKISTAN = 586,
CTRY_PANAMA = 591,
CTRY_PAPUA_NEW_GUINEA = 598,
CTRY_PARAGUAY = 600,
CTRY_PERU = 604,
CTRY_PHILIPPINES = 608,
CTRY_POLAND = 616,
CTRY_PORTUGAL = 620,
CTRY_PUERTO_RICO = 630,
CTRY_QATAR = 634,
CTRY_ROMANIA = 642,
CTRY_RUSSIA = 643,
CTRY_SAUDI_ARABIA = 682,
CTRY_SERBIA_MONTENEGRO = 891,
CTRY_SINGAPORE = 702,
CTRY_SLOVAKIA = 703,
CTRY_SLOVENIA = 705,
CTRY_SOUTH_AFRICA = 710,
CTRY_SPAIN = 724,
CTRY_SRI_LANKA = 144,
CTRY_SWEDEN = 752,
CTRY_SWITZERLAND = 756,
CTRY_SYRIA = 760,
CTRY_TAIWAN = 158,
CTRY_THAILAND = 764,
CTRY_TRINIDAD_Y_TOBAGO = 780,
CTRY_TUNISIA = 788,
CTRY_TURKEY = 792,
CTRY_UAE = 784,
CTRY_UKRAINE = 804,
CTRY_UNITED_KINGDOM = 826,
CTRY_UNITED_STATES = 840,
CTRY_UNITED_STATES_FCC49 = 842,
CTRY_URUGUAY = 858,
CTRY_UZBEKISTAN = 860,
CTRY_VENEZUELA = 862,
CTRY_VIET_NAM = 704,
CTRY_YEMEN = 887,
CTRY_ZIMBABWE = 716,
CTRY_JAPAN1 = 393,
CTRY_JAPAN2 = 394,
CTRY_JAPAN3 = 395,
CTRY_JAPAN4 = 396,
CTRY_JAPAN5 = 397,
CTRY_JAPAN6 = 4006,
CTRY_JAPAN7 = 4007,
CTRY_JAPAN8 = 4008,
CTRY_JAPAN9 = 4009,
CTRY_JAPAN10 = 4010,
CTRY_JAPAN11 = 4011,
CTRY_JAPAN12 = 4012,
CTRY_JAPAN13 = 4013,
CTRY_JAPAN14 = 4014,
CTRY_JAPAN15 = 4015,
CTRY_JAPAN16 = 4016,
CTRY_JAPAN17 = 4017,
CTRY_JAPAN18 = 4018,
CTRY_JAPAN19 = 4019,
CTRY_JAPAN20 = 4020,
CTRY_JAPAN21 = 4021,
CTRY_JAPAN22 = 4022,
CTRY_JAPAN23 = 4023,
CTRY_JAPAN24 = 4024,
CTRY_JAPAN25 = 4025,
CTRY_JAPAN26 = 4026,
CTRY_JAPAN27 = 4027,
CTRY_JAPAN28 = 4028,
CTRY_JAPAN29 = 4029,
CTRY_JAPAN30 = 4030,
CTRY_JAPAN31 = 4031,
CTRY_JAPAN32 = 4032,
CTRY_JAPAN33 = 4033,
CTRY_JAPAN34 = 4034,
CTRY_JAPAN35 = 4035,
CTRY_JAPAN36 = 4036,
CTRY_JAPAN37 = 4037,
CTRY_JAPAN38 = 4038,
CTRY_JAPAN39 = 4039,
CTRY_JAPAN40 = 4040,
CTRY_JAPAN41 = 4041,
CTRY_JAPAN42 = 4042,
CTRY_JAPAN43 = 4043,
CTRY_JAPAN44 = 4044,
CTRY_JAPAN45 = 4045,
CTRY_JAPAN46 = 4046,
CTRY_JAPAN47 = 4047,
CTRY_JAPAN48 = 4048,
CTRY_JAPAN49 = 4049,
CTRY_JAPAN50 = 4050,
CTRY_JAPAN51 = 4051,
CTRY_JAPAN52 = 4052,
CTRY_JAPAN53 = 4053,
CTRY_JAPAN54 = 4054,
CTRY_JAPAN55 = 4055,
CTRY_JAPAN56 = 4056,
CTRY_JAPAN57 = 4057,
CTRY_JAPAN58 = 4058,
CTRY_JAPAN59 = 4059,
CTRY_AUSTRALIA2 = 5000,
CTRY_CANADA2 = 5001,
CTRY_BELGIUM2 = 5002
};
void ath9k_regd_get_current_country(struct ath_hal *ah,
struct ath9k_country_entry *ctry);
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff