Overhaul regulatory support:

o remove HAL_CHANNEL; convert the hal to use net80211 channels; this
  mostly involves mechanical changes to variable names and channel
  attribute macros
o gut HAL_CHANNEL_PRIVATE as most of the contents are now redundant
  with the net80211 channel available
o change api for ath_hal_init_channels: no more reglass id's, no more outdoor
  indication (was a noop), anM contents
o add ath_hal_getchannels to have the hal construct a channel list without
  altering runtime state; this is used to retrieve the calibration list for
  the device in ath_getradiocaps
o add ath_hal_set_channels to take a channel list and regulatory data from
  above and construct internal state to match (maps frequencies for 900MHz
  cards, setup for CTL lookups, etc)
o compact the private channel table: we keep one private channel
  per frequency instead of one per HAL_CHANNEL; this gives a big
  space savings and potentially improves ani and calibration by
  sharing state (to be seen; didn't see anything in testing); a new config
  option AH_MAXCHAN controls the table size (default to 96 which
  was chosen to be ~3x the largest expected size)
o shrink ani state and change to mirror private channel table (one entry per
  frequency indexed by ic_devdata)
o move ani state flags to private channel state
o remove country codes; use net80211 definitions instead
o remove GSM regulatory support; it's no longer needed now that we
  pass in channel lists from above
o consolidate ADHOC_NO_11A attribute with DISALLOW_ADHOC_11A
o simplify initial channel list construction based on the EEPROM contents;
  we preserve country code support for now but may want to just fallback
  to a WWR sku and dispatch the discovered country code up to user space
  so the channel list can be constructed using the master regdomain tables
o defer to net80211 for max antenna gain
o eliminate sorting of internal channel table; now that we use ic_devdata
  as an index, table lookups are O(1)
o remove internal copy of the country code; the public one is sufficient
o remove AH_SUPPORT_11D conditional compilation; we always support 11d
o remove ath_hal_ispublicsafetysku; not needed any more
o remove ath_hal_isgsmsku; no more GSM stuff
o move Conformance Test Limit (CTL) state from private channel to a lookup
  using per-band pointers cached in the private state block
o remove regulatory class id support; was unused and belongs in net80211
o fix channel list construction to set IEEE80211_CHAN_NOADHOC,
  IEEE80211_CHAN_NOHOSTAP, and IEEE80211_CHAN_4MSXMIT
o remove private channel flags CHANNEL_DFS and CHANNEL_4MS_LIMIT; these are
  now set in the constructed net80211 channel
o store CHANNEL_NFCREQUIRED (Noise Floor Required) channel attribute in one
  of the driver-private flag bits of the net80211 channel
o move 900MHz frequency mapping into the hal; the mapped frequency is stored
  in the private channel and used throughout the hal (no more mapping in the
  driver and/or net80211)
o remove ath_hal_mhz2ieee; it's no longer needed as net80211 does the
  calculation and available in the net80211 channel
o change noise floor calibration logic to work with compacted private channel
  table setup; this may require revisiting as we no longer can distinguish
  channel attributes (e.g. 11b vs 11g vs turbo) but since the data is used
  only to calculate status data we can live with it for now
o change ah_getChipPowerLimits internal method to operate on a single channel
  instead of all channels in the private channel table
o add ath_hal_gethwchannel to map a net80211 channel to a h/w frequency
  (always the same except for 900MHz channels)
o add HAL_EEBADREG and HAL_EEBADCC status codes to better identify regulatory
  problems
o remove CTRY_DEBUG and CTRY_DEFAULT enum's; these come from net80211 now
o change ath_hal_getwirelessmodes to really return wireless modes supported
  by the hardware (was previously applying regulatory constraints)
o return channel interference status with IEEE80211_CHANSTATE_CWINT (should
  change to a callback so hal api's can take const pointers)
o remove some #define's no longer needed with the inclusion of
  <net80211/_ieee80211.h>

Sponsored by:   Carlson Wireless
This commit is contained in:
Sam Leffler 2009-01-28 18:00:22 +00:00
parent a4611ab612
commit 59efa8b517
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=187831
39 changed files with 2423 additions and 3435 deletions

View File

@ -762,7 +762,7 @@ AH_WRITE_EEPROM opt_ah.h
AH_PRIVATE_DIAG opt_ah.h
AH_NEED_DESC_SWAP opt_ah.h
AH_USE_INIPDGAIN opt_ah.h
AH_SUPPORT_11D opt_ah.h
AH_MAXCHAN opt_ah.h
# options for the Marvell 8335 wireless driver
MALO_DEBUG opt_malo.h

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -78,6 +78,15 @@ ath_hal_attach(uint16_t devid, HAL_SOFTC sc,
return AH_NULL;
}
/*
* Return the mask of available modes based on the hardware capabilities.
*/
u_int
ath_hal_getwirelessmodes(struct ath_hal*ah)
{
return ath_hal_getWirelessModes(ah);
}
/* linker set of registered RF backends */
OS_SET_DECLARE(ah_rfs, struct ath_hal_rf);
@ -152,8 +161,10 @@ ath_hal_computetxtime(struct ath_hal *ah,
kbps = rates->info[rateix].rateKbps;
/*
* index can be invalid duting dynamic Turbo transitions.
* XXX
*/
if(kbps == 0) return 0;
if (kbps == 0)
return 0;
switch (rates->info[rateix].phy) {
case IEEE80211_T_CCK:
@ -187,8 +198,8 @@ ath_hal_computetxtime(struct ath_hal *ah,
#define OFDM_PLCP_BITS_QUARTER 22
#define OFDM_SYMBOL_TIME_QUARTER 16
if (AH_PRIVATE(ah)->ah_curchan &&
IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {
if (AH_PRIVATE(ah)->ah_curchan != AH_NULL &&
IEEE80211_IS_CHAN_QUARTER(AH_PRIVATE(ah)->ah_curchan)) {
bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
HALASSERT(bitsPerSymbol != 0);
@ -197,8 +208,8 @@ ath_hal_computetxtime(struct ath_hal *ah,
txTime = OFDM_SIFS_TIME_QUARTER
+ OFDM_PREAMBLE_TIME_QUARTER
+ (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
} else if (AH_PRIVATE(ah)->ah_curchan &&
IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {
} else if (AH_PRIVATE(ah)->ah_curchan != AH_NULL &&
IEEE80211_IS_CHAN_HALF(AH_PRIVATE(ah)->ah_curchan)) {
bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
HALASSERT(bitsPerSymbol != 0);
@ -252,71 +263,6 @@ ath_hal_computetxtime(struct ath_hal *ah,
return txTime;
}
static __inline int
mapgsm(u_int freq, u_int flags)
{
freq *= 10;
if (flags & CHANNEL_QUARTER)
freq += 5;
else if (flags & CHANNEL_HALF)
freq += 10;
else
freq += 20;
return (freq - 24220) / 5;
}
static __inline int
mappsb(u_int freq, u_int flags)
{
return ((freq * 10) + (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
}
/*
* Convert GHz frequency to IEEE channel number.
*/
int
ath_hal_mhz2ieee(struct ath_hal *ah, u_int freq, u_int flags)
{
if (flags & CHANNEL_2GHZ) { /* 2GHz band */
if (freq == 2484)
return 14;
if (freq < 2484) {
if (ath_hal_isgsmsku(ah))
return mapgsm(freq, flags);
return ((int)freq - 2407) / 5;
} else
return 15 + ((freq - 2512) / 20);
} else if (flags & CHANNEL_5GHZ) {/* 5Ghz band */
if (ath_hal_ispublicsafetysku(ah) &&
IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
return mappsb(freq, flags);
} else if ((flags & CHANNEL_A) && (freq <= 5000)) {
return (freq - 4000) / 5;
} else {
return (freq - 5000) / 5;
}
} else { /* either, guess */
if (freq == 2484)
return 14;
if (freq < 2484) {
if (ath_hal_isgsmsku(ah))
return mapgsm(freq, flags);
return ((int)freq - 2407) / 5;
}
if (freq < 5000) {
if (ath_hal_ispublicsafetysku(ah) &&
IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
return mappsb(freq, flags);
} else if (freq > 4900) {
return (freq - 4000) / 5;
} else {
return 15 + ((freq - 2512) / 20);
}
}
return (freq - 5000) / 5;
}
}
typedef enum {
WIRELESS_MODE_11a = 0,
WIRELESS_MODE_TURBO = 1,
@ -328,15 +274,15 @@ typedef enum {
} WIRELESS_MODE;
static WIRELESS_MODE
ath_hal_chan2wmode(struct ath_hal *ah, const HAL_CHANNEL *chan)
ath_hal_chan2wmode(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
if (IS_CHAN_CCK(chan))
if (IEEE80211_IS_CHAN_B(chan))
return WIRELESS_MODE_11b;
if (IS_CHAN_G(chan))
if (IEEE80211_IS_CHAN_G(chan))
return WIRELESS_MODE_11g;
if (IS_CHAN_108G(chan))
if (IEEE80211_IS_CHAN_108G(chan))
return WIRELESS_MODE_108g;
if (IS_CHAN_TURBO(chan))
if (IEEE80211_IS_CHAN_TURBO(chan))
return WIRELESS_MODE_TURBO;
return WIRELESS_MODE_11a;
}
@ -350,17 +296,17 @@ static const uint8_t CLOCK_RATE[] = { 40, 80, 22, 44, 88 };
u_int
ath_hal_mac_clks(struct ath_hal *ah, u_int usecs)
{
const HAL_CHANNEL *c = (const HAL_CHANNEL *) AH_PRIVATE(ah)->ah_curchan;
const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan;
u_int clks;
/* NB: ah_curchan may be null when called attach time */
if (c != AH_NULL) {
clks = usecs * CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
if (IS_CHAN_HT40(c))
if (IEEE80211_IS_CHAN_HT40(c))
clks <<= 1;
else if (IS_CHAN_HALF_RATE(c))
else if (IEEE80211_IS_CHAN_HALF(c))
clks >>= 1;
else if (IS_CHAN_QUARTER_RATE(c))
else if (IEEE80211_IS_CHAN_QUARTER(c))
clks >>= 2;
} else
clks = usecs * CLOCK_RATE[WIRELESS_MODE_11b];
@ -370,17 +316,17 @@ ath_hal_mac_clks(struct ath_hal *ah, u_int usecs)
u_int
ath_hal_mac_usec(struct ath_hal *ah, u_int clks)
{
const HAL_CHANNEL *c = (const HAL_CHANNEL *) AH_PRIVATE(ah)->ah_curchan;
const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan;
u_int usec;
/* NB: ah_curchan may be null when called attach time */
if (c != AH_NULL) {
usec = clks / CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
if (IS_CHAN_HT40(c))
if (IEEE80211_IS_CHAN_HT40(c))
usec >>= 1;
else if (IS_CHAN_HALF_RATE(c))
else if (IEEE80211_IS_CHAN_HALF(c))
usec <<= 1;
else if (IS_CHAN_QUARTER_RATE(c))
else if (IEEE80211_IS_CHAN_QUARTER(c))
usec <<= 2;
} else
usec = clks / CLOCK_RATE[WIRELESS_MODE_11b];
@ -505,11 +451,7 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
}
return HAL_ENOTSUPP;
case HAL_CAP_11D:
#ifdef AH_SUPPORT_11D
return HAL_OK;
#else
return HAL_ENOTSUPP;
#endif
case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */
return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_HT:
@ -764,7 +706,7 @@ static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93 };
* implement the ah_getChanNoise method.
*/
int16_t
ath_hal_getChanNoise(struct ath_hal *ah, HAL_CHANNEL *chan)
ath_hal_getChanNoise(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
HAL_CHANNEL_INTERNAL *ichan;
@ -772,7 +714,7 @@ ath_hal_getChanNoise(struct ath_hal *ah, HAL_CHANNEL *chan)
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_NFCAL,
"%s: invalid channel %u/0x%x; no mapping\n",
__func__, chan->channel, chan->channelFlags);
__func__, chan->ic_freq, chan->ic_flags);
return 0;
}
if (ichan->rawNoiseFloor == 0) {
@ -811,8 +753,8 @@ ath_hal_process_noisefloor(struct ath_hal *ah)
c = &AH_PRIVATE(ah)->ah_channels[i];
if (c->rawNoiseFloor >= 0)
continue;
mode = ath_hal_chan2wmode(ah, (HAL_CHANNEL *) c);
HALASSERT(mode < WIRELESS_MODE_MAX);
/* XXX can't identify proper mode */
mode = IS_CHAN_5GHZ(c) ? WIRELESS_MODE_11a : WIRELESS_MODE_11g;
nf = c->rawNoiseFloor + NOISE_FLOOR[mode] +
ath_hal_getNfAdjust(ah, c);
if (IS_CHAN_5GHZ(c)) {
@ -838,9 +780,8 @@ ath_hal_process_noisefloor(struct ath_hal *ah)
/* Apply correction factor */
c->noiseFloorAdjust = ath_hal_getNfAdjust(ah, c) +
(IS_CHAN_5GHZ(c) ? correct5 : correct2);
HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u/0x%x raw nf %d adjust %d\n",
c->channel, c->channelFlags, c->rawNoiseFloor,
c->noiseFloorAdjust);
HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u raw nf %d adjust %d\n",
c->channel, c->rawNoiseFloor, c->noiseFloorAdjust);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ah.h,v 1.15 2008/11/15 03:43:50 sam Exp $
* $FreeBSD$
*/
#ifndef _ATH_AH_H_
@ -63,6 +63,8 @@ typedef enum {
HAL_ENOTSUPP = 13, /* Hardware revision not supported */
HAL_ESELFTEST = 14, /* Hardware self-test failed */
HAL_EINPROGRESS = 15, /* Operation incomplete */
HAL_EEBADREG = 16, /* EEPROM invalid regulatory contents */
HAL_EEBADCC = 17, /* EEPROM invalid country code */
} HAL_STATUS;
typedef enum {
@ -362,64 +364,8 @@ typedef enum {
HAL_RFGAIN_NEED_CHANGE = 2
} HAL_RFGAIN;
/*
* Channels are specified by frequency.
*/
typedef struct {
uint32_t channelFlags; /* see below */
uint16_t channel; /* setting in Mhz */
uint8_t privFlags;
int8_t maxRegTxPower; /* max regulatory tx power in dBm */
int8_t maxTxPower; /* max true tx power in 0.5 dBm */
int8_t minTxPower; /* min true tx power in 0.5 dBm */
} HAL_CHANNEL;
/* channelFlags */
#define CHANNEL_CW_INT 0x00002 /* CW interference detected on channel */
#define CHANNEL_TURBO 0x00010 /* Turbo Channel */
#define CHANNEL_CCK 0x00020 /* CCK channel */
#define CHANNEL_OFDM 0x00040 /* OFDM channel */
#define CHANNEL_2GHZ 0x00080 /* 2 GHz spectrum channel */
#define CHANNEL_5GHZ 0x00100 /* 5 GHz spectrum channel */
#define CHANNEL_PASSIVE 0x00200 /* Only passive scan allowed in the channel */
#define CHANNEL_DYN 0x00400 /* dynamic CCK-OFDM channel */
#define CHANNEL_STURBO 0x02000 /* Static turbo, no 11a-only usage */
#define CHANNEL_HALF 0x04000 /* Half rate channel */
#define CHANNEL_QUARTER 0x08000 /* Quarter rate channel */
#define CHANNEL_HT20 0x10000 /* 11n 20MHZ channel */
#define CHANNEL_HT40PLUS 0x20000 /* 11n 40MHZ channel w/ ext chan above */
#define CHANNEL_HT40MINUS 0x40000 /* 11n 40MHZ channel w/ ext chan below */
/* privFlags */
#define CHANNEL_INTERFERENCE 0x01 /* Software use: channel interference
used for as AR as well as RADAR
interference detection */
#define CHANNEL_DFS 0x02 /* DFS required on channel */
#define CHANNEL_4MS_LIMIT 0x04 /* 4msec packet limit on this channel */
#define CHANNEL_DFS_CLEAR 0x08 /* if channel has been checked for DFS */
#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
#define CHANNEL_PUREG (CHANNEL_2GHZ|CHANNEL_OFDM)
#ifdef notdef
#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_DYN)
#else
#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
#endif
#define CHANNEL_T (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
#define CHANNEL_ST (CHANNEL_T|CHANNEL_STURBO)
#define CHANNEL_108G (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
#define CHANNEL_108A CHANNEL_T
#define CHANNEL_G_HT20 (CHANNEL_G|CHANNEL_HT20)
#define CHANNEL_A_HT20 (CHANNEL_A|CHANNEL_HT20)
#define CHANNEL_G_HT40PLUS (CHANNEL_G|CHANNEL_HT40PLUS)
#define CHANNEL_G_HT40MINUS (CHANNEL_G|CHANNEL_HT40MINUS)
#define CHANNEL_A_HT40PLUS (CHANNEL_A|CHANNEL_HT40PLUS)
#define CHANNEL_A_HT40MINUS (CHANNEL_A|CHANNEL_HT40MINUS)
#define CHANNEL_ALL \
(CHANNEL_OFDM | CHANNEL_CCK| CHANNEL_2GHZ | CHANNEL_5GHZ | \
CHANNEL_TURBO | CHANNEL_HT20 | CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)
#define CHANNEL_ALL_NOTURBO (CHANNEL_ALL &~ CHANNEL_TURBO)
typedef uint16_t HAL_CTRY_CODE; /* country code */
typedef uint16_t HAL_REG_DOMAIN; /* regulatory domain code */
#define HAL_ANTENNA_MIN_MODE 0
#define HAL_ANTENNA_FIXED_A 1
@ -434,14 +380,6 @@ typedef struct {
uint32_t beacons;
} HAL_MIB_STATS;
typedef uint16_t HAL_CTRY_CODE; /* country code */
typedef uint16_t HAL_REG_DOMAIN; /* regulatory domain code */
enum {
CTRY_DEBUG = 0x1ff, /* debug country code */
CTRY_DEFAULT = 0 /* default country code */
};
enum {
HAL_MODE_11A = 0x001, /* 11a channels */
HAL_MODE_TURBO = 0x002, /* 11a turbo-only channels */
@ -630,6 +568,7 @@ typedef struct {
struct ath_desc;
struct ath_tx_status;
struct ath_rx_status;
struct ieee80211_channel;
/*
* Hardware Access Layer (HAL) API.
@ -665,16 +604,18 @@ struct ath_hal {
/* Reset functions */
HAL_BOOL __ahdecl(*ah_reset)(struct ath_hal *, HAL_OPMODE,
HAL_CHANNEL *, HAL_BOOL bChannelChange,
HAL_STATUS *status);
struct ieee80211_channel *,
HAL_BOOL bChannelChange, HAL_STATUS *status);
HAL_BOOL __ahdecl(*ah_phyDisable)(struct ath_hal *);
HAL_BOOL __ahdecl(*ah_disable)(struct ath_hal *);
void __ahdecl(*ah_setPCUConfig)(struct ath_hal *);
HAL_BOOL __ahdecl(*ah_perCalibration)(struct ath_hal*, HAL_CHANNEL *,
HAL_BOOL *);
HAL_BOOL __ahdecl(*ah_perCalibrationN)(struct ath_hal *, HAL_CHANNEL *,
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
HAL_BOOL __ahdecl(*ah_resetCalValid)(struct ath_hal *, HAL_CHANNEL *);
HAL_BOOL __ahdecl(*ah_perCalibration)(struct ath_hal*,
struct ieee80211_channel *, HAL_BOOL *);
HAL_BOOL __ahdecl(*ah_perCalibrationN)(struct ath_hal *,
struct ieee80211_channel *, u_int chainMask,
HAL_BOOL longCal, HAL_BOOL *isCalDone);
HAL_BOOL __ahdecl(*ah_resetCalValid)(struct ath_hal *,
const struct ieee80211_channel *);
HAL_BOOL __ahdecl(*ah_setTxPowerLimit)(struct ath_hal *, uint32_t);
/* Transmit functions */
@ -735,7 +676,8 @@ struct ath_hal {
struct ath_desc *next, uint64_t tsf,
struct ath_rx_status *);
void __ahdecl(*ah_rxMonitor)(struct ath_hal *,
const HAL_NODE_STATS *, HAL_CHANNEL *);
const HAL_NODE_STATS *,
const struct ieee80211_channel *);
void __ahdecl(*ah_procMibEvent)(struct ath_hal *,
const HAL_NODE_STATS *);
@ -804,7 +746,8 @@ struct ath_hal {
HAL_BOOL __ahdecl(*ah_setPowerMode)(struct ath_hal*,
HAL_POWER_MODE mode, int setChip);
HAL_POWER_MODE __ahdecl(*ah_getPowerMode)(struct ath_hal*);
int16_t __ahdecl(*ah_getChanNoise)(struct ath_hal *, HAL_CHANNEL *);
int16_t __ahdecl(*ah_getChanNoise)(struct ath_hal *,
const struct ieee80211_channel *);
/* Beacon Management Functions */
void __ahdecl(*ah_setBeaconTimers)(struct ath_hal*,
@ -847,21 +790,48 @@ extern struct ath_hal * __ahdecl ath_hal_attach(uint16_t devid, HAL_SOFTC,
HAL_BUS_TAG, HAL_BUS_HANDLE, HAL_STATUS* status);
/*
* Return a list of channels available for use with the hardware.
* The list is based on what the hardware is capable of, the specified
* country code, the modeSelect mask, and whether or not outdoor
* channels are to be permitted.
* Regulatory interfaces. Drivers should use ath_hal_init_channels to
* request a set of channels for a particular country code and/or
* regulatory domain. If CTRY_DEFAULT and SKU_NONE are specified then
* this list is constructed according to the contents of the EEPROM.
* ath_hal_getchannels acts similarly but does not alter the operating
* state; this can be used to collect information for a particular
* regulatory configuration. Finally ath_hal_set_channels installs a
* channel list constructed outside the driver. The HAL will adopt the
* channel list and setup internal state according to the specified
* regulatory configuration (e.g. conformance test limits).
*
* The channel list is returned in the supplied array. maxchans
* defines the maximum size of this array. nchans contains the actual
* number of channels returned. If a problem occurred or there were
* no channels that met the criteria then AH_FALSE is returned.
* For all interfaces the channel list is returned in the supplied array.
* maxchans defines the maximum size of this array. nchans contains the
* actual number of channels returned. If a problem occurred then a
* status code != HAL_OK is returned.
*/
extern HAL_BOOL __ahdecl ath_hal_init_channels(struct ath_hal *,
HAL_CHANNEL *chans, u_int maxchans, u_int *nchans,
uint8_t *regclassids, u_int maxregids, u_int *nregids,
HAL_CTRY_CODE cc, u_int modeSelect,
HAL_BOOL enableOutdoor, HAL_BOOL enableExtendedChannels);
struct ieee80211_channel;
/*
* Return a list of channels according to the specified regulatory.
*/
extern HAL_STATUS __ahdecl ath_hal_getchannels(struct ath_hal *,
struct ieee80211_channel *chans, u_int maxchans, int *nchans,
u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn,
HAL_BOOL enableExtendedChannels);
/*
* Return a list of channels and install it as the current operating
* regulatory list.
*/
extern HAL_STATUS __ahdecl ath_hal_init_channels(struct ath_hal *,
struct ieee80211_channel *chans, u_int maxchans, int *nchans,
u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN rd,
HAL_BOOL enableExtendedChannels);
/*
* Install the list of channels as the current operating regulatory
* and setup related state according to the country code and sku.
*/
extern HAL_STATUS __ahdecl ath_hal_set_channels(struct ath_hal *,
struct ieee80211_channel *chans, int nchans,
HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn);
/*
* Calibrate noise floor data following a channel scan or similar.
@ -872,7 +842,7 @@ extern void __ahdecl ath_hal_process_noisefloor(struct ath_hal *ah);
/*
* Return bit mask of wireless modes supported by the hardware.
*/
extern u_int __ahdecl ath_hal_getwirelessmodes(struct ath_hal*, HAL_CTRY_CODE);
extern u_int __ahdecl ath_hal_getwirelessmodes(struct ath_hal*);
/*
* Calculate the transmit duration of a frame.
@ -880,20 +850,4 @@ extern u_int __ahdecl ath_hal_getwirelessmodes(struct ath_hal*, HAL_CTRY_CODE);
extern uint16_t __ahdecl ath_hal_computetxtime(struct ath_hal *,
const HAL_RATE_TABLE *rates, uint32_t frameLen,
uint16_t rateix, HAL_BOOL shortPreamble);
/*
* Return if device is public safety.
*/
extern HAL_BOOL __ahdecl ath_hal_ispublicsafetysku(struct ath_hal *);
/*
* Return if device is operating in 900 MHz band.
*/
extern HAL_BOOL ath_hal_isgsmsku(struct ath_hal *);
/*
* Convert between IEEE channel number and channel frequency
* using the specified channel flags; e.g. CHANNEL_2GHZ.
*/
extern int __ahdecl ath_hal_mhz2ieee(struct ath_hal *, u_int mhz, u_int flags);
#endif /* _ATH_AH_H_ */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -27,6 +27,8 @@
#define AH_MIN(a,b) ((a)<(b)?(a):(b))
#define AH_MAX(a,b) ((a)>(b)?(a):(b))
#include <net80211/_ieee80211.h>
#ifndef NBBY
#define NBBY 8 /* number of bits/byte */
#endif
@ -108,32 +110,44 @@ OS_DATA_SET(ah_rfs, _name##_rf)
struct ath_hal_rf *ath_hal_rfprobe(struct ath_hal *ah, HAL_STATUS *ecode);
/*
* Internal form of a HAL_CHANNEL. Note that the structure
* must be defined such that you can cast references to a
* HAL_CHANNEL so don't shuffle the first two members.
* Maximum number of internal channels. Entries are per unique
* frequency so this might be need to be increased to handle all
* usage cases; typically no more than 32 are really needed but
* dynamically allocating the data structures is a bit painful
* right now.
*/
#ifndef AH_MAXCHAN
#define AH_MAXCHAN 96
#endif
/*
* Internal per-channel state. These are found
* using ic_devdata in the ieee80211_channel.
*/
typedef struct {
uint32_t channelFlags;
uint16_t channel; /* NB: must be first for casting */
uint16_t channel; /* h/w frequency, NB: may be mapped */
uint8_t privFlags;
int8_t maxRegTxPower;
int8_t maxTxPower;
int8_t minTxPower; /* as above... */
HAL_BOOL bssSendHere;
uint8_t gainI;
HAL_BOOL iqCalValid;
uint8_t calValid; /* bitmask of cal types */
#define CHANNEL_IQVALID 0x01 /* IQ calibration valid */
#define CHANNEL_ANI_INIT 0x02 /* ANI state initialized */
#define CHANNEL_ANI_SETUP 0x04 /* ANI state setup */
uint8_t calValid; /* bitmask of cal types */
int8_t iCoff;
int8_t qCoff;
int16_t rawNoiseFloor;
int16_t noiseFloorAdjust;
int8_t antennaMax;
uint32_t regDmnFlags; /* Flags for channel use in reg */
uint32_t conformanceTestLimit; /* conformance test limit from reg domain */
uint16_t mainSpur; /* cached spur value for this cahnnel */
uint16_t mainSpur; /* cached spur value for this channel */
} HAL_CHANNEL_INTERNAL;
/* channel requires noise floor check */
#define CHANNEL_NFCREQUIRED IEEE80211_CHAN_PRIV0
/* all full-width channels */
#define IEEE80211_CHAN_ALLFULL \
(IEEE80211_CHAN_ALL - (IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER))
#define IEEE80211_CHAN_ALLTURBOFULL \
(IEEE80211_CHAN_ALLTURBO - \
(IEEE80211_CHAN_HALF | IEEE80211_CHAN_QUARTER))
typedef struct {
uint32_t halChanSpreadSupport : 1,
halSleepAfterBeaconBroken : 1,
@ -189,6 +203,8 @@ typedef struct {
uint8_t halNumAntCfg5GHz;
} HAL_CAPABILITIES;
struct regDomain;
/*
* The ``private area'' follows immediately after the ``public area''
* in the data structure returned by ath_hal_attach. Private data are
@ -228,7 +244,7 @@ struct ath_hal_private {
uint32_t gpio, uint32_t val);
void (*ah_gpioSetIntr)(struct ath_hal*, u_int, uint32_t);
HAL_BOOL (*ah_getChipPowerLimits)(struct ath_hal *,
HAL_CHANNEL *, uint32_t);
struct ieee80211_channel *);
int16_t (*ah_getNfAdjust)(struct ath_hal *,
const HAL_CHANNEL_INTERNAL*);
void (*ah_getNoiseFloor)(struct ath_hal *,
@ -255,8 +271,8 @@ struct ath_hal_private {
uint16_t ah_analog5GhzRev; /* 2GHz radio revision */
uint16_t ah_analog2GhzRev; /* 5GHz radio revision */
HAL_OPMODE ah_opmode; /* operating mode from reset */
const struct ieee80211_channel *ah_curchan;/* operating channel */
HAL_CAPABILITIES ah_caps; /* device capabilities */
uint32_t ah_diagreg; /* user-specified AR_DIAG_SW */
int16_t ah_powerLimit; /* tx power cap */
@ -267,14 +283,13 @@ struct ath_hal_private {
/*
* State for regulatory domain handling.
*/
HAL_REG_DOMAIN ah_currentRD; /* Current regulatory domain */
HAL_CTRY_CODE ah_countryCode; /* current country code */
HAL_CHANNEL_INTERNAL ah_channels[256]; /* calculated channel list */
u_int ah_nchan; /* valid channels in list */
HAL_CHANNEL_INTERNAL *ah_curchan; /* current channel */
HAL_REG_DOMAIN ah_currentRD; /* EEPROM regulatory domain */
HAL_CHANNEL_INTERNAL ah_channels[AH_MAXCHAN]; /* private chan state */
u_int ah_nchan; /* valid items in ah_channels */
const struct regDomain *ah_rd2GHz; /* reg state for 2G band */
const struct regDomain *ah_rd5GHz; /* reg state for 5G band */
uint8_t ah_coverageClass; /* coverage class */
HAL_BOOL ah_regdomainUpdate; /* regdomain is updated? */
/*
* RF Silent handling; setup according to the EEPROM.
*/
@ -307,8 +322,8 @@ struct ath_hal_private {
AH_PRIVATE(_ah)->ah_gpioGet(_ah, _gpio, _val)
#define ath_hal_gpioSetIntr(_ah, _gpio, _ilevel) \
AH_PRIVATE(_ah)->ah_gpioSetIntr(_ah, _gpio, _ilevel)
#define ath_hal_getpowerlimits(_ah, _chans, _nchan) \
AH_PRIVATE(_ah)->ah_getChipPowerLimits(_ah, _chans, _nchan)
#define ath_hal_getpowerlimits(_ah, _chan) \
AH_PRIVATE(_ah)->ah_getChipPowerLimits(_ah, _chan)
#define ath_hal_getNfAdjust(_ah, _c) \
AH_PRIVATE(_ah)->ah_getNfAdjust(_ah, _c)
#define ath_hal_getNoiseFloor(_ah, _nfArray) \
@ -327,38 +342,22 @@ struct ath_hal_private {
#define ath_hal_eepromDiag(_ah, _request, _a, _asize, _r, _rsize) \
AH_PRIVATE(_ah)->ah_eepromDiag(_ah, _request, _a, _asize, _r, _rsize)
#if !defined(_NET_IF_IEEE80211_H_) && !defined(_NET80211__IEEE80211_H_)
#ifndef _NET_IF_IEEE80211_H_
/*
* Stuff that would naturally come from _ieee80211.h
*/
#define IEEE80211_ADDR_LEN 6
#define IEEE80211_WEP_KEYLEN 5 /* 40bit */
#define IEEE80211_WEP_IVLEN 3 /* 24bit */
#define IEEE80211_WEP_KIDLEN 1 /* 1 octet */
#define IEEE80211_WEP_CRCLEN 4 /* CRC-32 */
#define IEEE80211_CRC_LEN 4
#define IEEE80211_MTU 1500
#define IEEE80211_MAX_LEN (2300 + IEEE80211_CRC_LEN + \
(IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN))
enum {
IEEE80211_T_DS, /* direct sequence spread spectrum */
IEEE80211_T_FH, /* frequency hopping */
IEEE80211_T_OFDM, /* frequency division multiplexing */
IEEE80211_T_TURBO, /* high rate DS */
IEEE80211_T_HT, /* HT - full GI */
};
#define IEEE80211_T_CCK IEEE80211_T_DS /* more common nomenclatur */
#endif /* _NET_IF_IEEE80211_H_ */
/* NB: these are defined privately until XR support is announced */
enum {
ATHEROS_T_XR = IEEE80211_T_HT+1, /* extended range */
};
#define HAL_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
#define INIT_AIFS 2
@ -411,43 +410,11 @@ typedef enum {
#define HAL_BIN_WIDTH_TURBO_100HZ 6250
#define HAL_MAX_BINS_ALLOWED 28
/*
* A = 5GHZ|OFDM
* T = 5GHZ|OFDM|TURBO
*
* IS_CHAN_A(T) will return TRUE. This is probably
* not the default behavior we want. We should migrate to a better mask --
* perhaps CHANNEL_ALL.
*
* For now, IS_CHAN_G() masks itself with CHANNEL_108G.
*
*/
#define IS_CHAN_A(_c) (((_c)->channelFlags & CHANNEL_A) == CHANNEL_A)
#define IS_CHAN_B(_c) (((_c)->channelFlags & CHANNEL_B) == CHANNEL_B)
#define IS_CHAN_G(_c) (((_c)->channelFlags & (CHANNEL_108G|CHANNEL_G)) == CHANNEL_G)
#define IS_CHAN_108G(_c)(((_c)->channelFlags & CHANNEL_108G) == CHANNEL_108G)
#define IS_CHAN_T(_c) (((_c)->channelFlags & CHANNEL_T) == CHANNEL_T)
#define IS_CHAN_PUREG(_c) \
(((_c)->channelFlags & CHANNEL_PUREG) == CHANNEL_PUREG)
#define IS_CHAN_TURBO(_c) (((_c)->channelFlags & CHANNEL_TURBO) != 0)
#define IS_CHAN_CCK(_c) (((_c)->channelFlags & CHANNEL_CCK) != 0)
#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
#define IS_CHAN_5GHZ(_c) ((_c)->channel > 4900)
#define IS_CHAN_2GHZ(_c) (!IS_CHAN_5GHZ(_c))
#define IS_CHAN_IN_PUBLIC_SAFETY_BAND(_c) ((_c) > 4940 && (_c) < 4990)
#define CHANNEL_HT40 (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)
#define CHANNEL_HT (CHANNEL_HT20 | CHANNEL_HT40)
#define IS_CHAN_HT(_c) (((_c)->channelFlags & CHANNEL_HT) != 0)
#define IS_CHAN_HT20(_c) (((_c)->channelFlags & CHANNEL_HT) == CHANNEL_HT20)
#define IS_CHAN_HT40(_c) (((_c)->channelFlags & CHANNEL_HT40) != 0)
/*
* Deduce if the host cpu has big- or litt-endian byte order.
*/
@ -486,37 +453,6 @@ isBigEndian(void)
#define OS_REG_CLR_BIT(_a, _r, _f) \
OS_REG_WRITE(_a, _r, OS_REG_READ(_a, _r) &~ (_f))
/*
* Regulatory domain support.
*/
/*
* Return the max allowed antenna gain based on the current
* regulatory domain.
*/
extern u_int ath_hal_getantennareduction(struct ath_hal *,
HAL_CHANNEL *, u_int twiceGain);
/*
* Return the test group for the specific channel based on
* the current regulator domain.
*/
extern u_int ath_hal_getctl(struct ath_hal *, HAL_CHANNEL *);
/*
* Return whether or not a noise floor check is required
* based on the current regulatory domain for the specified
* channel.
*/
extern u_int ath_hal_getnfcheckrequired(struct ath_hal *, HAL_CHANNEL *);
/*
* Map a public channel definition to the corresponding
* internal data structure. This implicitly specifies
* whether or not the specified channel is ok to use
* based on the current regulatory domain constraints.
*/
extern HAL_CHANNEL_INTERNAL *ath_hal_checkchannel(struct ath_hal *,
const HAL_CHANNEL *);
/* system-configurable parameters */
extern int ath_hal_dma_beacon_response_time; /* in TU's */
extern int ath_hal_sw_beacon_response_time; /* in TU's */
@ -575,6 +511,57 @@ extern void ath_hal_assert_failed(const char* filename,
#define HALASSERT(_x)
#endif /* AH_ASSERT */
/*
* Regulatory domain support.
*/
/*
* Return the max allowed antenna gain and apply any regulatory
* domain specific changes.
*/
u_int ath_hal_getantennareduction(struct ath_hal *ah,
const struct ieee80211_channel *chan, u_int twiceGain);
/*
* Return the test group for the specific channel based on
* the current regulatory setup.
*/
u_int ath_hal_getctl(struct ath_hal *, const struct ieee80211_channel *);
/*
* Map a public channel definition to the corresponding
* internal data structure. This implicitly specifies
* whether or not the specified channel is ok to use
* based on the current regulatory domain constraints.
*/
#ifndef AH_DEBUG
static OS_INLINE HAL_CHANNEL_INTERNAL *
ath_hal_checkchannel(struct ath_hal *ah, const struct ieee80211_channel *c)
{
HAL_CHANNEL_INTERNAL *cc;
HALASSERT(c->ic_devdata < AH_PRIVATE(ah)->ah_nchan);
cc = &AH_PRIVATE(ah)->ah_channels[c->ic_devdata];
HALASSERT(c->ic_freq == cc->channel || IEEE80211_IS_CHAN_GSM(c));
return cc;
}
#else
/* NB: non-inline version that checks state */
HAL_CHANNEL_INTERNAL *ath_hal_checkchannel(struct ath_hal *,
const struct ieee80211_channel *);
#endif /* AH_DEBUG */
/*
* Return the h/w frequency for a channel. This may be
* different from ic_freq if this is a GSM device that
* takes 2.4GHz frequencies and down-converts them.
*/
static OS_INLINE uint16_t
ath_hal_gethwchannel(struct ath_hal *ah, const struct ieee80211_channel *c)
{
return ath_hal_checkchannel(ah, c)->channel;
}
/*
* Convert between microseconds and core system clocks.
*/
@ -733,7 +720,7 @@ extern void ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt);
/*
* Common routine for implementing getChanNoise api.
*/
extern int16_t ath_hal_getChanNoise(struct ath_hal *ah, HAL_CHANNEL *chan);
int16_t ath_hal_getChanNoise(struct ath_hal *, const struct ieee80211_channel *);
/*
* Initialization support.

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2004 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5210.h,v 1.8 2008/11/11 02:40:13 sam Exp $
* $FreeBSD$
*/
#ifndef _ATH_AR5210_H_
#define _ATH_AR5210_H_
@ -128,20 +128,21 @@ struct ath_hal;
extern void ar5210Detach(struct ath_hal *ah);
extern HAL_BOOL ar5210Reset(struct ath_hal *, HAL_OPMODE,
HAL_CHANNEL *, HAL_BOOL bChannelChange, HAL_STATUS *);
struct ieee80211_channel *, HAL_BOOL bChannelChange, HAL_STATUS *);
extern void ar5210SetPCUConfig(struct ath_hal *);
extern HAL_BOOL ar5210PhyDisable(struct ath_hal *);
extern HAL_BOOL ar5210Disable(struct ath_hal *);
extern HAL_BOOL ar5210ChipReset(struct ath_hal *, HAL_CHANNEL *);
extern HAL_BOOL ar5210PerCalibration(struct ath_hal *, HAL_CHANNEL *, HAL_BOOL *);
extern HAL_BOOL ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
extern HAL_BOOL ar5210ChipReset(struct ath_hal *, struct ieee80211_channel *);
extern HAL_BOOL ar5210PerCalibration(struct ath_hal *, struct ieee80211_channel *, HAL_BOOL *);
extern HAL_BOOL ar5210PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
extern HAL_BOOL ar5210ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan);
extern HAL_BOOL ar5210ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *);
extern int16_t ar5210GetNoiseFloor(struct ath_hal *);
extern int16_t ar5210GetNfAdjust(struct ath_hal *,
const HAL_CHANNEL_INTERNAL *);
extern HAL_BOOL ar5210SetTxPowerLimit(struct ath_hal *, uint32_t limit);
extern HAL_BOOL ar5210SetTransmitPower(struct ath_hal *, HAL_CHANNEL *);
extern HAL_BOOL ar5210SetTransmitPower(struct ath_hal *,
const struct ieee80211_channel *);
extern HAL_BOOL ar5210CalNoiseFloor(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
extern HAL_BOOL ar5210ResetDma(struct ath_hal *, HAL_OPMODE);
@ -273,6 +274,7 @@ extern HAL_INT ar5210SetInterrupts(struct ath_hal *, HAL_INT ints);
extern const HAL_RATE_TABLE *ar5210GetRateTable(struct ath_hal *, u_int mode);
extern HAL_BOOL ar5210AniControl(struct ath_hal *, HAL_ANI_CMD, int );
extern void ar5210AniPoll(struct ath_hal *, const HAL_NODE_STATS *, HAL_CHANNEL *);
extern void ar5210AniPoll(struct ath_hal *, const HAL_NODE_STATS *,
const struct ieee80211_channel *);
extern void ar5210MibEvent(struct ath_hal *, const HAL_NODE_STATS *);
#endif /* _ATH_AR5210_H_ */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2004 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5210_attach.c,v 1.9 2008/11/11 02:40:13 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -31,12 +31,11 @@
static HAL_BOOL ar5210GetChannelEdges(struct ath_hal *,
uint16_t flags, uint16_t *low, uint16_t *high);
static HAL_BOOL ar5210GetChipPowerLimits(struct ath_hal *ah,
HAL_CHANNEL *chans, uint32_t nchans);
struct ieee80211_channel *chan);
static const struct ath_hal_private ar5210hal = {{
.ah_magic = AR5210_MAGIC,
.ah_abi = HAL_ABI_VERSION,
.ah_countryCode = CTRY_DEFAULT,
.ah_getRateTable = ar5210GetRateTable,
.ah_detach = ar5210Detach,
@ -303,7 +302,7 @@ static HAL_BOOL
ar5210GetChannelEdges(struct ath_hal *ah,
uint16_t flags, uint16_t *low, uint16_t *high)
{
if (flags & CHANNEL_5GHZ) {
if (flags & IEEE80211_CHAN_5GHZ) {
*low = 5120;
*high = 5430;
return AH_TRUE;
@ -313,20 +312,14 @@ ar5210GetChannelEdges(struct ath_hal *ah,
}
static HAL_BOOL
ar5210GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans)
ar5210GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan)
{
HAL_CHANNEL *chan;
int i;
/* XXX fill in, this is just a placeholder */
for (i = 0; i < nchans; i++) {
chan = &chans[i];
HALDEBUG(ah, HAL_DEBUG_ATTACH,
"%s: no min/max power for %u/0x%x\n",
__func__, chan->channel, chan->channelFlags);
chan->maxTxPower = AR5210_MAX_RATE_POWER;
chan->minTxPower = 0;
}
HALDEBUG(ah, HAL_DEBUG_ATTACH,
"%s: no min/max power for %u/0x%x\n",
__func__, chan->ic_freq, chan->ic_flags);
chan->ic_maxpower = AR5210_MAX_RATE_POWER;
chan->ic_minpower = 0;
return AH_TRUE;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2004 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5210_misc.c,v 1.6 2008/11/27 22:29:37 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -561,7 +561,8 @@ ar5210AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
}
void
ar5210AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats, HAL_CHANNEL *chan)
ar5210AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
const struct ieee80211_channel *chan)
{
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2004 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -55,7 +55,7 @@ static const uint8_t ar5k0007_pwrSettings[17] = {
static HAL_BOOL ar5210SetResetReg(struct ath_hal *,
uint32_t resetMask, u_int delay);
static HAL_BOOL ar5210SetChannel(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
static HAL_BOOL ar5210SetChannel(struct ath_hal *, struct ieee80211_channel *);
static void ar5210SetOperatingMode(struct ath_hal *, int opmode);
/*
@ -68,7 +68,8 @@ static void ar5210SetOperatingMode(struct ath_hal *, int opmode);
*/
HAL_BOOL
ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status)
struct ieee80211_channel *chan, HAL_BOOL bChannelChange,
HAL_STATUS *status)
{
#define N(a) (sizeof (a) /sizeof (a[0]))
#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
@ -81,10 +82,10 @@ ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
HALDEBUG(ah, HAL_DEBUG_RESET,
"%s: opmode %u channel %u/0x%x %s channel\n", __func__,
opmode, chan->channel, chan->channelFlags,
opmode, chan->ic_freq, chan->ic_flags,
bChannelChange ? "change" : "same");
if ((chan->channelFlags & CHANNEL_5GHZ) == 0) {
if (!IEEE80211_IS_CHAN_5GHZ(chan)) {
/* Only 11a mode */
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: channel not 5Ghz\n", __func__);
FAIL(HAL_EINVAL);
@ -96,7 +97,7 @@ ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; no mapping\n",
__func__, chan->channel, chan->channelFlags);
__func__, chan->ic_freq, chan->ic_flags);
FAIL(HAL_EINVAL);
}
switch (opmode) {
@ -232,17 +233,13 @@ ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
(OS_REG_READ(ah, AR_PHY(68)) & 0xFFFFFFFC) |
(ee->ee_antenna & 0x3));
if (!ar5210SetChannel(ah, ichan)) {
if (!ar5210SetChannel(ah, chan)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set channel\n",
__func__);
FAIL(HAL_EIO);
}
if (bChannelChange) {
if (!(ichan->privFlags & CHANNEL_DFS))
ichan->privFlags &= ~CHANNEL_INTERFERENCE;
chan->channelFlags = ichan->channelFlags;
chan->privFlags = ichan->privFlags;
}
if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan))
chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
/* Activate the PHY */
OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ENABLE);
@ -256,7 +253,7 @@ ar5210Reset(struct ath_hal *ah, HAL_OPMODE opmode,
/* Perform noise floor calibration and set status */
if (!ar5210CalNoiseFloor(ah, ichan)) {
chan->channelFlags |= CHANNEL_CW_INT;
chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: noise floor calibration failed\n", __func__);
FAIL(HAL_EIO);
@ -385,19 +382,20 @@ ar5210Disable(struct ath_hal *ah)
* Places the hardware into reset and then pulls it out of reset
*/
HAL_BOOL
ar5210ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
ar5210ChipReset(struct ath_hal *ah, struct ieee80211_channel *chan)
{
#define AR_RC_HW (AR_RC_RPCU | AR_RC_RDMA | AR_RC_RPHY | AR_RC_RMAC)
HALDEBUG(ah, HAL_DEBUG_RESET, "%s turbo %s\n", __func__,
chan && IS_CHAN_TURBO(chan) ? "enabled" : "disabled");
chan && IEEE80211_IS_CHAN_TURBO(chan) ?
"enabled" : "disabled");
if (!ar5210SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
return AH_FALSE;
/* Place chip in turbo before reset to cleanly reset clocks */
OS_REG_WRITE(ah, AR_PHY_FRCTL,
chan && IS_CHAN_TURBO(chan) ? AR_PHY_TURBO_MODE : 0);
chan && IEEE80211_IS_CHAN_TURBO(chan) ? AR_PHY_TURBO_MODE : 0);
/*
* Reset the HW.
@ -444,7 +442,8 @@ enum {
* changes.
*/
HAL_BOOL
ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
ar5210PerCalibrationN(struct ath_hal *ah,
struct ieee80211_channel *chan, u_int chainMask,
HAL_BOOL longCal, HAL_BOOL *isCalDone)
{
uint32_t regBeacon;
@ -452,12 +451,8 @@ ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
HAL_CHANNEL_INTERNAL *ichan;
ichan = ath_hal_checkchannel(ah, chan);
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; no mapping\n",
__func__, chan->channel, chan->channelFlags);
if (ichan == AH_NULL)
return AH_FALSE;
}
/* Disable tx and rx */
OS_REG_WRITE(ah, AR_DIAG_SW,
OS_REG_READ(ah, AR_DIAG_SW) | (AR_DIAG_SW_DIS_TX | AR_DIAG_SW_DIS_RX));
@ -475,7 +470,7 @@ ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
OS_DELAY(10);
/* Change Channel to relock synth */
if (!ar5210SetChannel(ah, ichan))
if (!ar5210SetChannel(ah, chan))
return AH_FALSE;
/* wait for the synthesizer lock to stabilize */
@ -551,7 +546,7 @@ ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
"%s: Performing 2nd Noise Cal\n", __func__);
OS_DELAY(5000);
if (!ar5210CalNoiseFloor(ah, ichan))
chan->channelFlags |= CHANNEL_CW_INT;
chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
}
/* Clear tx and rx disable bit */
@ -567,13 +562,14 @@ ar5210PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
}
HAL_BOOL
ar5210PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
ar5210PerCalibration(struct ath_hal *ah, struct ieee80211_channel *chan,
HAL_BOOL *isIQdone)
{
return ar5210PerCalibrationN(ah, chan, 0x1, AH_TRUE, isIQdone);
}
HAL_BOOL
ar5210ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
ar5210ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
return AH_TRUE;
}
@ -729,8 +725,10 @@ ar5210SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
* Get TXPower values and set them in the radio
*/
static HAL_BOOL
setupPowerSettings(struct ath_hal *ah, HAL_CHANNEL *chan, uint8_t cp[17])
setupPowerSettings(struct ath_hal *ah, const struct ieee80211_channel *chan,
uint8_t cp[17])
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
const HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom;
uint8_t gainFRD, gainF36, gainF48, gainF54;
uint8_t dBmRD, dBm36, dBm48, dBm54, dontcare;
@ -741,9 +739,9 @@ setupPowerSettings(struct ath_hal *ah, HAL_CHANNEL *chan, uint8_t cp[17])
cp[15] = (ee->ee_biasCurrents >> 4) & 0x7;
cp[16] = ee->ee_biasCurrents & 0x7;
if (chan->channel < 5170 || chan->channel > 5320) {
if (freq < 5170 || freq > 5320) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u\n",
__func__, chan->channel);
__func__, freq);
return AH_FALSE;
}
@ -763,7 +761,7 @@ setupPowerSettings(struct ath_hal *ah, HAL_CHANNEL *chan, uint8_t cp[17])
#endif
return AH_FALSE;
}
group = ((chan->channel - 5170) / 10);
group = ((freq - 5170) / 10);
if (group > 11) {
/* Pull 5.29 into the 5.27 group */
@ -829,7 +827,7 @@ setupPowerSettings(struct ath_hal *ah, HAL_CHANNEL *chan, uint8_t cp[17])
* vectors (as determined by the mode), and station configuration
*/
HAL_BOOL
ar5210SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan)
ar5210SetTransmitPower(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
#define N(a) (sizeof (a) / sizeof (a[0]))
static const uint32_t pwr_regs_start[17] = {
@ -917,12 +915,13 @@ ar5210SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan)
* or by disabling the AGC.
*/
static HAL_BOOL
ar5210SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar5210SetChannel(struct ath_hal *ah, struct ieee80211_channel *chan)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t data;
/* Set the Channel */
data = ath_hal_reverseBits((chan->channel - 5120)/10, 5);
data = ath_hal_reverseBits((freq - 5120)/10, 5);
data = (data << 1) | 0x41;
OS_REG_WRITE(ah, AR_PHY(0x27), data);
OS_REG_WRITE(ah, AR_PHY(0x30), 0);
@ -949,7 +948,7 @@ ar5210GetNoiseFloor(struct ath_hal *ah)
* Returns: TRUE for a successful noise floor calibration; else FALSE
*/
HAL_BOOL
ar5210CalNoiseFloor(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar5210CalNoiseFloor(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
{
int32_t nf, nfLoops;
@ -980,10 +979,10 @@ ar5210CalNoiseFloor(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
if (nf > NORMAL_NF_THRESH) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: Bad noise cal %d\n",
__func__, nf);
chan->rawNoiseFloor = 0;
ichan->rawNoiseFloor = 0;
return AH_FALSE;
}
chan->rawNoiseFloor = nf;
ichan->rawNoiseFloor = nf;
return AH_TRUE;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2004 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5210_xmit.c,v 1.5 2008/11/10 04:08:02 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -154,7 +154,7 @@ HAL_BOOL
ar5210ResetTxQueue(struct ath_hal *ah, u_int q)
{
struct ath_hal_5210 *ahp = AH5210(ah);
HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
HAL_TX_QUEUE_INFO *qi;
uint32_t cwMin;
@ -177,7 +177,7 @@ ar5210ResetTxQueue(struct ath_hal *ah, u_int q)
return AH_TRUE;
/* Set turbo mode / base mode parameters on or off */
if (IS_CHAN_TURBO(chan)) {
if (IEEE80211_IS_CHAN_TURBO(chan)) {
OS_REG_WRITE(ah, AR_SLOT_TIME, INIT_SLOT_TIME_TURBO);
OS_REG_WRITE(ah, AR_TIME_OUT, INIT_ACK_CTS_TIMEOUT_TURBO);
OS_REG_WRITE(ah, AR_USEC, INIT_TRANSMIT_LATENCY_TURBO);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2006 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5211.h,v 1.8 2008/11/10 22:08:47 sam Exp $
* $FreeBSD$
*/
#ifndef _ATH_AR5211_H_
#define _ATH_AR5211_H_
@ -123,7 +123,6 @@ struct ath_hal_5211 {
HAL_ANT_SETTING ah_diversityControl; /* antenna setting */
uint32_t ah_calibrationTime;
HAL_BOOL ah_bIQCalibration;
HAL_CHANNEL ah_curchan; /* XXX */
int ah_rfgainState;
uint32_t ah_tx6PowerInHalfDbm; /* power output for 6Mb tx */
uint32_t ah_staId1Defaults; /* STA_ID1 default settings */
@ -150,19 +149,21 @@ extern struct ath_hal *ar5211Attach(uint16_t, HAL_SOFTC,
extern void ar5211Detach(struct ath_hal *);
extern HAL_BOOL ar5211Reset(struct ath_hal *, HAL_OPMODE,
HAL_CHANNEL *, HAL_BOOL bChannelChange, HAL_STATUS *);
struct ieee80211_channel *, HAL_BOOL bChannelChange,
HAL_STATUS *);
extern HAL_BOOL ar5211PhyDisable(struct ath_hal *);
extern HAL_BOOL ar5211Disable(struct ath_hal *);
extern HAL_BOOL ar5211ChipReset(struct ath_hal *, uint16_t);
extern HAL_BOOL ar5211PerCalibration(struct ath_hal *, HAL_CHANNEL *, HAL_BOOL *);
extern HAL_BOOL ar5211PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
extern HAL_BOOL ar5211ChipReset(struct ath_hal *,
const struct ieee80211_channel *);
extern HAL_BOOL ar5211PerCalibration(struct ath_hal *, struct ieee80211_channel *, HAL_BOOL *);
extern HAL_BOOL ar5211PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
extern HAL_BOOL ar5211ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan);
extern HAL_BOOL ar5211ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *);
extern HAL_BOOL ar5211SetTxPowerLimit(struct ath_hal *, uint32_t limit);
extern HAL_BOOL ar5211SetTransmitPower(struct ath_hal *, HAL_CHANNEL *);
extern HAL_BOOL ar5211CalNoiseFloor(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
extern HAL_BOOL ar5211CalNoiseFloor(struct ath_hal *,
const struct ieee80211_channel *);
extern HAL_BOOL ar5211SetAntennaSwitchInternal(struct ath_hal *,
HAL_ANT_SETTING, const HAL_CHANNEL *);
HAL_ANT_SETTING, const struct ieee80211_channel *);
extern int16_t ar5211GetNfAdjust(struct ath_hal *,
const HAL_CHANNEL_INTERNAL *);
extern HAL_BOOL ar5211ResetDma(struct ath_hal *, HAL_OPMODE);
@ -303,6 +304,7 @@ extern HAL_INT ar5211SetInterrupts(struct ath_hal *, HAL_INT ints);
extern const HAL_RATE_TABLE *ar5211GetRateTable(struct ath_hal *, u_int mode);
extern HAL_BOOL ar5211AniControl(struct ath_hal *, HAL_ANI_CMD, int );
extern void ar5211AniPoll(struct ath_hal *, const HAL_NODE_STATS *, HAL_CHANNEL *);
extern void ar5211AniPoll(struct ath_hal *, const HAL_NODE_STATS *,
const struct ieee80211_channel *);
extern void ar5211MibEvent(struct ath_hal *, const HAL_NODE_STATS *);
#endif /* _ATH_AR5211_H_ */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2006 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5211_attach.c,v 1.11 2008/11/27 22:29:52 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -31,12 +31,11 @@
static HAL_BOOL ar5211GetChannelEdges(struct ath_hal *ah,
uint16_t flags, uint16_t *low, uint16_t *high);
static HAL_BOOL ar5211GetChipPowerLimits(struct ath_hal *ah,
HAL_CHANNEL *chans, uint32_t nchans);
struct ieee80211_channel *chan);
static const struct ath_hal_private ar5211hal = {{
.ah_magic = AR5211_MAGIC,
.ah_abi = HAL_ABI_VERSION,
.ah_countryCode = CTRY_DEFAULT,
.ah_getRateTable = ar5211GetRateTable,
.ah_detach = ar5211Detach,
@ -232,7 +231,7 @@ ar5211Attach(uint16_t devid, HAL_SOFTC sc,
ahp->ah_acktimeout = (u_int) -1;
ahp->ah_ctstimeout = (u_int) -1;
if (!ar5211ChipReset(ah, AH_FALSE)) { /* reset chip */
if (!ar5211ChipReset(ah, AH_NULL)) { /* reset chip */
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
ecode = HAL_EIO;
goto bad;
@ -420,12 +419,13 @@ static HAL_BOOL
ar5211GetChannelEdges(struct ath_hal *ah,
uint16_t flags, uint16_t *low, uint16_t *high)
{
if (flags & CHANNEL_5GHZ) {
if (flags & IEEE80211_CHAN_5GHZ) {
*low = 4920;
*high = 6100;
return AH_TRUE;
}
if (flags & CHANNEL_2GHZ && ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) {
if (flags & IEEE80211_CHAN_2GHZ &&
ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) {
*low = 2312;
*high = 2732;
return AH_TRUE;
@ -434,20 +434,14 @@ ar5211GetChannelEdges(struct ath_hal *ah,
}
static HAL_BOOL
ar5211GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans)
ar5211GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan)
{
HAL_CHANNEL *chan;
int i;
/* XXX fill in, this is just a placeholder */
for (i = 0; i < nchans; i++) {
chan = &chans[i];
HALDEBUG(ah, HAL_DEBUG_ATTACH,
"%s: no min/max power for %u/0x%x\n",
__func__, chan->channel, chan->channelFlags);
chan->maxTxPower = MAX_RATE_POWER;
chan->minTxPower = 0;
}
HALDEBUG(ah, HAL_DEBUG_ATTACH,
"%s: no min/max power for %u/0x%x\n",
__func__, chan->ic_freq, chan->ic_flags);
chan->ic_maxpower = MAX_RATE_POWER;
chan->ic_minpower = 0;
return AH_TRUE;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2006 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -432,7 +432,7 @@ ar5211SetSifsTime(struct ath_hal *ah, u_int us)
} else {
/* convert to system clocks */
OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, ath_hal_mac_clks(ah, us));
ahp->ah_sifstime = us;
ahp->ah_slottime = us;
return AH_TRUE;
}
}
@ -564,7 +564,8 @@ ar5211AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
}
void
ar5211AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats, HAL_CHANNEL *chan)
ar5211AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
const struct ieee80211_channel *chan)
{
}
@ -603,8 +604,7 @@ ar5211GetAntennaSwitch(struct ath_hal *ah)
HAL_BOOL
ar5211SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
{
const HAL_CHANNEL *chan =
(const HAL_CHANNEL *) AH_PRIVATE(ah)->ah_curchan;
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
if (chan == AH_NULL) {
AH5211(ah)->ah_diversityControl = settings;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2006 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -105,17 +105,23 @@ const static CHAN_INFO_2GHZ chan2GHzData[] = {
#define NUM_RATES 8
static HAL_BOOL ar5211SetResetReg(struct ath_hal *ah, uint32_t resetMask);
static HAL_BOOL ar5211SetChannel(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
static HAL_BOOL ar5211SetChannel(struct ath_hal *,
const struct ieee80211_channel *);
static int16_t ar5211RunNoiseFloor(struct ath_hal *,
uint8_t runTime, int16_t startingNF);
static HAL_BOOL ar5211IsNfGood(struct ath_hal *, HAL_CHANNEL_INTERNAL *chan);
static HAL_BOOL ar5211SetRf6and7(struct ath_hal *, HAL_CHANNEL *chan);
static HAL_BOOL ar5211SetBoardValues(struct ath_hal *, HAL_CHANNEL *chan);
static HAL_BOOL ar5211IsNfGood(struct ath_hal *,
struct ieee80211_channel *chan);
static HAL_BOOL ar5211SetRf6and7(struct ath_hal *,
const struct ieee80211_channel *chan);
static HAL_BOOL ar5211SetBoardValues(struct ath_hal *,
const struct ieee80211_channel *chan);
static void ar5211SetPowerTable(struct ath_hal *,
PCDACS_EEPROM *pSrcStruct, uint16_t channel);
static HAL_BOOL ar5211SetTransmitPower(struct ath_hal *,
const struct ieee80211_channel *);
static void ar5211SetRateTable(struct ath_hal *,
RD_EDGES_POWER *pRdEdgesPower, TRGT_POWER_INFO *pPowerInfo,
uint16_t numChannels, HAL_CHANNEL *chan);
uint16_t numChannels, const struct ieee80211_channel *chan);
static uint16_t ar5211GetScaledPower(uint16_t channel, uint16_t pcdacValue,
const PCDACS_EEPROM *pSrcStruct);
static HAL_BOOL ar5211FindValueInList(uint16_t channel, uint16_t pcdacValue,
@ -147,7 +153,8 @@ static void ar5211SetOperatingMode(struct ath_hal *, int opmode);
*/
HAL_BOOL
ar5211Reset(struct ath_hal *ah, HAL_OPMODE opmode,
HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status)
struct ieee80211_channel *chan, HAL_BOOL bChannelChange,
HAL_STATUS *status)
{
uint32_t softLedCfg, softLedState;
#define N(a) (sizeof (a) /sizeof (a[0]))
@ -167,34 +174,16 @@ uint32_t softLedCfg, softLedState;
HALDEBUG(ah, HAL_DEBUG_RESET,
"%s: opmode %u channel %u/0x%x %s channel\n",
__func__, opmode, chan->channel, chan->channelFlags,
__func__, opmode, chan->ic_freq, chan->ic_flags,
bChannelChange ? "change" : "same");
OS_MARK(ah, AH_MARK_RESET, bChannelChange);
#define IS(_c,_f) (((_c)->channelFlags & _f) || 0)
if ((IS(chan, CHANNEL_2GHZ) ^ IS(chan,CHANNEL_5GHZ)) == 0) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
__func__, chan->channel, chan->channelFlags);
FAIL(HAL_EINVAL);
}
if ((IS(chan, CHANNEL_OFDM) ^ IS(chan, CHANNEL_CCK)) == 0) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; not marked as OFDM or CCK\n",
__func__, chan->channel, chan->channelFlags);
FAIL(HAL_EINVAL);
}
#undef IS
/*
* Map public channel to private.
*/
ichan = ath_hal_checkchannel(ah, chan);
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; no mapping\n",
__func__, chan->channel, chan->channelFlags);
if (ichan == AH_NULL)
FAIL(HAL_EINVAL);
}
switch (opmode) {
case HAL_M_STA:
case HAL_M_IBSS:
@ -236,10 +225,8 @@ uint32_t softLedCfg, softLedState;
for (i = 0; i < AR_NUM_DCU; i++)
saveFrameSeqCount[i] = OS_REG_READ(ah, AR_DSEQNUM(i));
}
if (!(ichan->privFlags & CHANNEL_DFS))
ichan->privFlags &= ~CHANNEL_INTERFERENCE;
chan->channelFlags = ichan->channelFlags;
chan->privFlags = ichan->privFlags;
if (!IEEE80211_IS_CHAN_DFS(chan))
chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
}
/*
@ -259,33 +246,36 @@ uint32_t softLedCfg, softLedState;
softLedCfg = OS_REG_READ(ah, AR_GPIOCR);
softLedState = OS_REG_READ(ah, AR_GPIODO);
if (!ar5211ChipReset(ah, chan->channelFlags)) {
if (!ar5211ChipReset(ah, chan)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
FAIL(HAL_EIO);
}
/* Setup the indices for the next set of register array writes */
switch (chan->channelFlags & CHANNEL_ALL) {
case CHANNEL_A:
modesIndex = 1;
freqIndex = 1;
break;
case CHANNEL_T:
modesIndex = 2;
freqIndex = 1;
break;
case CHANNEL_B:
modesIndex = 3;
freqIndex = 2;
break;
case CHANNEL_PUREG:
modesIndex = 4;
freqIndex = 2;
break;
default:
/* Ah, a new wireless mode */
HALASSERT(0);
break;
if (IEEE80211_IS_CHAN_5GHZ(chan)) {
freqIndex = 1;
if (IEEE80211_IS_CHAN_TURBO(chan))
modesIndex = 2;
else if (IEEE80211_IS_CHAN_A(chan))
modesIndex = 1;
else {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x\n",
__func__, chan->ic_freq, chan->ic_flags);
FAIL(HAL_EINVAL);
}
} else {
freqIndex = 2;
if (IEEE80211_IS_CHAN_B(chan))
modesIndex = 3;
else if (IEEE80211_IS_CHAN_PUREG(chan))
modesIndex = 4;
else {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x\n",
__func__, chan->ic_freq, chan->ic_flags);
FAIL(HAL_EINVAL);
}
}
/* Set correct Baseband to analog shift setting to access analog chips. */
@ -297,12 +287,12 @@ uint32_t softLedCfg, softLedState;
/* Write parameters specific to AR5211 */
if (AH_PRIVATE(ah)->ah_macVersion >= AR_SREV_VERSION_OAHU) {
if (IS_CHAN_2GHZ(chan) &&
if (IEEE80211_IS_CHAN_2GHZ(chan) &&
AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER3_1) {
HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
uint32_t ob2GHz, db2GHz;
if (IS_CHAN_CCK(chan)) {
if (IEEE80211_IS_CHAN_CCK(chan)) {
ob2GHz = ee->ee_ob2GHz[0];
db2GHz = ee->ee_db2GHz[0];
} else {
@ -437,14 +427,15 @@ uint32_t softLedCfg, softLedState;
/* Setup board specific options for EEPROM version 3 */
ar5211SetBoardValues(ah, chan);
if (!ar5211SetChannel(ah, ichan)) {
if (!ar5211SetChannel(ah, chan)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set channel\n",
__func__);
FAIL(HAL_EIO);
}
/* Activate the PHY */
if (AH_PRIVATE(ah)->ah_devid == AR5211_FPGA11B && IS_CHAN_2GHZ(chan))
if (AH_PRIVATE(ah)->ah_devid == AR5211_FPGA11B &&
IEEE80211_IS_CHAN_2GHZ(chan))
OS_REG_WRITE(ah, 0xd808, 0x502); /* required for FPGA */
OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
@ -454,7 +445,7 @@ uint32_t softLedCfg, softLedState;
* Value is in 100ns increments.
*/
data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_M;
if (IS_CHAN_CCK(chan)) {
if (IEEE80211_IS_CHAN_CCK(chan)) {
synthDelay = (4 * data) / 22;
} else {
synthDelay = data / 10;
@ -473,9 +464,9 @@ uint32_t softLedCfg, softLedState;
(void) ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0);
/* Perform noise floor and set status */
if (!ar5211CalNoiseFloor(ah, ichan)) {
if (!IS_CHAN_CCK(chan))
chan->channelFlags |= CHANNEL_CW_INT;
if (!ar5211CalNoiseFloor(ah, chan)) {
if (!IEEE80211_IS_CHAN_CCK(chan))
chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: noise floor calibration failed\n", __func__);
FAIL(HAL_EIO);
@ -599,49 +590,31 @@ ar5211Disable(struct ath_hal *ah)
* us in the correct mode and we cannot check the hwchannel flags.
*/
HAL_BOOL
ar5211ChipReset(struct ath_hal *ah, uint16_t channelFlags)
ar5211ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
if (!ar5211SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
return AH_FALSE;
/* Set CCK and Turbo modes correctly */
switch (channelFlags & CHANNEL_ALL) {
case CHANNEL_2GHZ|CHANNEL_CCK:
case CHANNEL_2GHZ|CHANNEL_CCK|CHANNEL_TURBO:
OS_REG_WRITE(ah, AR_PHY_TURBO, 0);
OS_REG_WRITE(ah, AR5211_PHY_MODE,
AR5211_PHY_MODE_CCK | AR5211_PHY_MODE_RF2GHZ);
OS_REG_WRITE(ah, AR_PHY_PLL_CTL, AR_PHY_PLL_CTL_44);
/* Wait for the PLL to settle */
OS_DELAY(DELAY_PLL_SETTLE);
break;
case CHANNEL_2GHZ|CHANNEL_OFDM:
case CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO:
OS_REG_WRITE(ah, AR_PHY_TURBO, 0);
if (AH_PRIVATE(ah)->ah_devid == AR5211_DEVID) {
/* NB: called from attach with chan null */
if (chan != AH_NULL) {
/* Set CCK and Turbo modes correctly */
OS_REG_WRITE(ah, AR_PHY_TURBO, IEEE80211_IS_CHAN_TURBO(chan) ?
AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT : 0);
if (IEEE80211_IS_CHAN_B(chan)) {
OS_REG_WRITE(ah, AR5211_PHY_MODE,
AR5211_PHY_MODE_CCK | AR5211_PHY_MODE_RF2GHZ);
OS_REG_WRITE(ah, AR_PHY_PLL_CTL, AR_PHY_PLL_CTL_44);
/* Wait for the PLL to settle */
OS_DELAY(DELAY_PLL_SETTLE);
} else if (AH_PRIVATE(ah)->ah_devid == AR5211_DEVID) {
OS_REG_WRITE(ah, AR_PHY_PLL_CTL, AR_PHY_PLL_CTL_40);
OS_DELAY(DELAY_PLL_SETTLE);
OS_REG_WRITE(ah, AR5211_PHY_MODE,
AR5211_PHY_MODE_OFDM | AR5211_PHY_MODE_RF2GHZ);
AR5211_PHY_MODE_OFDM | (IEEE80211_IS_CHAN_2GHZ(chan) ?
AR5211_PHY_MODE_RF2GHZ :
AR5211_PHY_MODE_RF5GHZ));
}
break;
case CHANNEL_A:
case CHANNEL_T:
if (channelFlags & CHANNEL_TURBO) {
OS_REG_WRITE(ah, AR_PHY_TURBO,
AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT);
} else { /* 5 GHZ OFDM Mode */
OS_REG_WRITE(ah, AR_PHY_TURBO, 0);
}
if (AH_PRIVATE(ah)->ah_devid == AR5211_DEVID) {
OS_REG_WRITE(ah, AR_PHY_PLL_CTL, AR_PHY_PLL_CTL_40);
OS_DELAY(DELAY_PLL_SETTLE);
OS_REG_WRITE(ah, AR5211_PHY_MODE,
AR5211_PHY_MODE_OFDM | AR5211_PHY_MODE_RF5GHZ);
}
break;
}
/* NB: else no flags set - must be attach calling - do nothing */
/*
* Reset the HW - PCI must be reset after the rest of the
@ -664,8 +637,8 @@ ar5211ChipReset(struct ath_hal *ah, uint16_t channelFlags)
* changes.
*/
HAL_BOOL
ar5211PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
HAL_BOOL longCal, HAL_BOOL *isCalDone)
ar5211PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone)
{
struct ath_hal_5211 *ahp = AH5211(ah);
HAL_CHANNEL_INTERNAL *ichan;
@ -679,7 +652,7 @@ ar5211PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; no mapping\n",
__func__, chan->channel, chan->channelFlags);
__func__, chan->ic_freq, chan->ic_flags);
return AH_FALSE;
}
/* IQ calibration in progress. Check to see if it has finished. */
@ -733,22 +706,21 @@ ar5211PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
if (longCal) {
/* Perform noise floor and set status */
if (!ar5211IsNfGood(ah, ichan)) {
if (!ar5211IsNfGood(ah, chan)) {
/* report up and clear internal state */
chan->channelFlags |= CHANNEL_CW_INT;
ichan->channelFlags &= ~CHANNEL_CW_INT;
chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
return AH_FALSE;
}
if (!ar5211CalNoiseFloor(ah, ichan)) {
if (!ar5211CalNoiseFloor(ah, chan)) {
/*
* Delay 5ms before retrying the noise floor
* just to make sure, as we are in an error
* condition here.
*/
OS_DELAY(5000);
if (!ar5211CalNoiseFloor(ah, ichan)) {
if (!IS_CHAN_CCK(chan))
chan->channelFlags |= CHANNEL_CW_INT;
if (!ar5211CalNoiseFloor(ah, chan)) {
if (!IEEE80211_IS_CHAN_CCK(chan))
chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
return AH_FALSE;
}
}
@ -758,13 +730,14 @@ ar5211PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
}
HAL_BOOL
ar5211PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
ar5211PerCalibration(struct ath_hal *ah, struct ieee80211_channel *chan,
HAL_BOOL *isIQdone)
{
return ar5211PerCalibrationN(ah, chan, 0x1, AH_TRUE, isIQdone);
}
HAL_BOOL
ar5211ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
ar5211ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
/* XXX */
return AH_TRUE;
@ -810,13 +783,13 @@ ar5211SetResetReg(struct ath_hal *ah, uint32_t resetMask)
* or by disabling the AGC.
*/
static HAL_BOOL
ar5211SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar5211SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint32_t refClk, reg32, data2111;
int16_t chan5111, chanIEEE;
chanIEEE = ath_hal_mhz2ieee(ah, chan->channel, chan->channelFlags);
if (IS_CHAN_2GHZ(chan)) {
chanIEEE = chan->ic_ieee;
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
const CHAN_INFO_2GHZ* ci =
&chan2GHzData[chanIEEE + CI_2GHZ_INDEX_CORRECTION];
@ -903,7 +876,7 @@ ar5211RunNoiseFloor(struct ath_hal *ah, uint8_t runTime, int16_t startingNF)
if (i >= 60) {
HALDEBUG(ah, HAL_DEBUG_NFCAL,
"NF with runTime %d failed to end on channel %d\n",
runTime, AH_PRIVATE(ah)->ah_curchan->channel);
runTime, AH_PRIVATE(ah)->ah_curchan->ic_freq);
HALDEBUG(ah, HAL_DEBUG_NFCAL,
" PHY NF Reg state: 0x%x\n",
OS_REG_READ(ah, AR_PHY_AGC_CONTROL));
@ -917,23 +890,24 @@ ar5211RunNoiseFloor(struct ath_hal *ah, uint8_t runTime, int16_t startingNF)
}
static HAL_BOOL
getNoiseFloorThresh(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, int16_t *nft)
getNoiseFloorThresh(struct ath_hal *ah, const struct ieee80211_channel *chan,
int16_t *nft)
{
HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
case CHANNEL_A:
switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
case IEEE80211_CHAN_A:
*nft = ee->ee_noiseFloorThresh[0];
break;
case CHANNEL_CCK|CHANNEL_2GHZ:
case IEEE80211_CHAN_B:
*nft = ee->ee_noiseFloorThresh[1];
break;
case CHANNEL_OFDM|CHANNEL_2GHZ:
case IEEE80211_CHAN_PUREG:
*nft = ee->ee_noiseFloorThresh[2];
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
__func__, chan->ic_flags);
return AH_FALSE;
}
return AH_TRUE;
@ -945,8 +919,9 @@ getNoiseFloorThresh(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, int16_t *nft
* Returns: TRUE if the NF is good
*/
static HAL_BOOL
ar5211IsNfGood(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar5211IsNfGood(struct ath_hal *ah, struct ieee80211_channel *chan)
{
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
int16_t nf, nfThresh;
if (!getNoiseFloorThresh(ah, chan, &nfThresh))
@ -964,9 +939,9 @@ ar5211IsNfGood(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* happens it indicates a problem regardless
* of the band.
*/
chan->channelFlags |= CHANNEL_CW_INT;
chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
}
chan->rawNoiseFloor = nf;
ichan->rawNoiseFloor = nf;
return (nf <= nfThresh);
}
@ -980,13 +955,14 @@ ar5211IsNfGood(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* Returns: TRUE for a successful noise floor calibration; else FALSE
*/
HAL_BOOL
ar5211CalNoiseFloor(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar5211CalNoiseFloor(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
#define N(a) (sizeof (a) / sizeof (a[0]))
/* Check for Carrier Wave interference in MKK regulatory zone */
if (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_OAHU &&
ath_hal_getnfcheckrequired(ah, (HAL_CHANNEL *) chan)) {
(chan->ic_flags & CHANNEL_NFCREQUIRED)) {
static const uint8_t runtime[3] = { 0, 2, 7 };
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
int16_t nf, nfThresh;
int i;
@ -1003,9 +979,9 @@ ar5211CalNoiseFloor(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
"%s: run failed with %u > threshold %u "
"(runtime %u)\n", __func__,
nf, nfThresh, runtime[i]);
chan->rawNoiseFloor = 0;
ichan->rawNoiseFloor = 0;
} else
chan->rawNoiseFloor = nf;
ichan->rawNoiseFloor = nf;
}
return (i <= N(runtime));
} else {
@ -1054,9 +1030,10 @@ ar5211GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c)
* REQUIRES: Access to the analog device
*/
static HAL_BOOL
ar5211SetRf6and7(struct ath_hal *ah, HAL_CHANNEL *chan)
ar5211SetRf6and7(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
#define N(a) (sizeof (a) / sizeof (a[0]))
uint16_t freq = ath_hal_gethwchannel(ah, chan);
HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
struct ath_hal_5211 *ahp = AH5211(ah);
uint16_t rfXpdGain, rfPloSel, rfPwdXpd;
@ -1064,25 +1041,25 @@ ar5211SetRf6and7(struct ath_hal *ah, HAL_CHANNEL *chan)
uint16_t freqIndex;
int i;
freqIndex = (chan->channelFlags & CHANNEL_2GHZ) ? 2 : 1;
freqIndex = IEEE80211_IS_CHAN_2GHZ(chan) ? 2 : 1;
/*
* TODO: This array mode correspondes with the index used
* during the read.
* For readability, this should be changed to an enum or #define
*/
switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
case CHANNEL_A:
if (chan->channel > 4000 && chan->channel < 5260) {
switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
case IEEE80211_CHAN_A:
if (freq > 4000 && freq < 5260) {
tempOB = ee->ee_ob1;
tempDB = ee->ee_db1;
} else if (chan->channel >= 5260 && chan->channel < 5500) {
} else if (freq >= 5260 && freq < 5500) {
tempOB = ee->ee_ob2;
tempDB = ee->ee_db2;
} else if (chan->channel >= 5500 && chan->channel < 5725) {
} else if (freq >= 5500 && freq < 5725) {
tempOB = ee->ee_ob3;
tempDB = ee->ee_db3;
} else if (chan->channel >= 5725) {
} else if (freq >= 5725) {
tempOB = ee->ee_ob4;
tempDB = ee->ee_db4;
} else {
@ -1104,14 +1081,14 @@ ar5211SetRf6and7(struct ath_hal *ah, HAL_CHANNEL *chan)
(ar5211Rf6n7[21][freqIndex] & ~0x08) |
(ee->ee_cornerCal.gSel << 3);
break;
case CHANNEL_CCK|CHANNEL_2GHZ:
case IEEE80211_CHAN_B:
tempOB = ee->ee_obFor24;
tempDB = ee->ee_dbFor24;
rfXpdGain = ee->ee_xgain[1];
rfPloSel = ee->ee_xpd[1];
rfPwdXpd = !ee->ee_xpd[1];
break;
case CHANNEL_OFDM|CHANNEL_2GHZ:
case IEEE80211_CHAN_PUREG:
tempOB = ee->ee_obFor24g;
tempDB = ee->ee_dbFor24g;
rfXpdGain = ee->ee_xgain[2];
@ -1120,7 +1097,7 @@ ar5211SetRf6and7(struct ath_hal *ah, HAL_CHANNEL *chan)
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
__func__, chan->ic_flags);
return AH_FALSE;
}
@ -1160,7 +1137,7 @@ ar5211SetRf6and7(struct ath_hal *ah, HAL_CHANNEL *chan)
HAL_BOOL
ar5211SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
const HAL_CHANNEL *chan)
const struct ieee80211_channel *chan)
{
#define ANT_SWITCH_TABLE1 0x9960
#define ANT_SWITCH_TABLE2 0x9964
@ -1169,13 +1146,13 @@ ar5211SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
uint32_t antSwitchA, antSwitchB;
int ix;
switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
case CHANNEL_A: ix = 0; break;
case CHANNEL_B: ix = 1; break;
case CHANNEL_PUREG: ix = 2; break;
switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
case IEEE80211_CHAN_A: ix = 0; break;
case IEEE80211_CHAN_B: ix = 1; break;
case IEEE80211_CHAN_PUREG: ix = 2; break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
__func__, chan->ic_flags);
return AH_FALSE;
}
@ -1223,27 +1200,27 @@ ar5211SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
* given the channel value
*/
static HAL_BOOL
ar5211SetBoardValues(struct ath_hal *ah, HAL_CHANNEL *chan)
ar5211SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
struct ath_hal_5211 *ahp = AH5211(ah);
int arrayMode, falseDectectBackoff;
switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
case CHANNEL_A:
switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
case IEEE80211_CHAN_A:
arrayMode = 0;
OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
AR_PHY_FRAME_CTL_TX_CLIP, ee->ee_cornerCal.clip);
break;
case CHANNEL_CCK|CHANNEL_2GHZ:
case IEEE80211_CHAN_B:
arrayMode = 1;
break;
case CHANNEL_OFDM|CHANNEL_2GHZ:
case IEEE80211_CHAN_PUREG:
arrayMode = 2;
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
__func__, chan->ic_flags);
return AH_FALSE;
}
@ -1295,10 +1272,11 @@ ar5211SetBoardValues(struct ath_hal *ah, HAL_CHANNEL *chan)
falseDectectBackoff = NO_FALSE_DETECT_BACKOFF;
if (AH_PRIVATE(ah)->ah_eeversion < AR_EEPROM_VER3_3) {
if (AH_PRIVATE(ah)->ah_subvendorid == 0x1022 &&
IS_CHAN_OFDM(chan))
IEEE80211_IS_CHAN_OFDM(chan))
falseDectectBackoff += CB22_FALSE_DETECT_BACKOFF;
} else {
uint32_t remainder = chan->channel % 32;
uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t remainder = freq % 32;
if (remainder && (remainder < 10 || remainder > 22))
falseDectectBackoff += ee->ee_falseDetectBackoff[arrayMode];
@ -1331,9 +1309,10 @@ ar5211SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
* Sets the transmit power in the baseband for the given
* operating channel and mode.
*/
HAL_BOOL
ar5211SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan)
static HAL_BOOL
ar5211SetTransmitPower(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
TRGT_POWER_INFO *pi;
RD_EDGES_POWER *rep;
@ -1342,22 +1321,22 @@ ar5211SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan)
int i;
/* setup the pcdac struct to point to the correct info, based on mode */
switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
case CHANNEL_A:
switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
case IEEE80211_CHAN_A:
eepromPcdacs.numChannels = ee->ee_numChannels11a;
eepromPcdacs.pChannelList= ee->ee_channels11a;
eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11a;
nchan = ee->ee_numTargetPwr_11a;
pi = ee->ee_trgtPwr_11a;
break;
case CHANNEL_OFDM|CHANNEL_2GHZ:
case IEEE80211_CHAN_PUREG:
eepromPcdacs.numChannels = ee->ee_numChannels2_4;
eepromPcdacs.pChannelList= ee->ee_channels11g;
eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11g;
nchan = ee->ee_numTargetPwr_11g;
pi = ee->ee_trgtPwr_11g;
break;
case CHANNEL_CCK|CHANNEL_2GHZ:
case IEEE80211_CHAN_B:
eepromPcdacs.numChannels = ee->ee_numChannels2_4;
eepromPcdacs.pChannelList= ee->ee_channels11b;
eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11b;
@ -1366,11 +1345,11 @@ ar5211SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan)
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
__func__, chan->ic_flags);
return AH_FALSE;
}
ar5211SetPowerTable(ah, &eepromPcdacs, chan->channel);
ar5211SetPowerTable(ah, &eepromPcdacs, freq);
rep = AH_NULL;
/* Match CTL to EEPROM value */
@ -1392,7 +1371,8 @@ ar5211SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan)
* table for writing into the hardware.
*/
void
ar5211SetPowerTable(struct ath_hal *ah, PCDACS_EEPROM *pSrcStruct, uint16_t channel)
ar5211SetPowerTable(struct ath_hal *ah, PCDACS_EEPROM *pSrcStruct,
uint16_t channel)
{
static FULL_PCDAC_STRUCT pcdacStruct;
static uint16_t pcdacTable[PWR_TABLE_SIZE];
@ -1509,11 +1489,12 @@ ar5211SetPowerTable(struct ath_hal *ah, PCDACS_EEPROM *pSrcStruct, uint16_t chan
* Set the transmit power in the baseband for the given
* operating channel and mode.
*/
void
static void
ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
TRGT_POWER_INFO *pPowerInfo, uint16_t numChannels,
HAL_CHANNEL *chan)
const struct ieee80211_channel *chan)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
struct ath_hal_5211 *ahp = AH5211(ah);
static uint16_t ratesArray[NUM_RATES];
@ -1534,9 +1515,9 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
int8_t twiceAntennaGain, twiceAntennaReduction = 0;
pRatesPower = ratesArray;
twiceMaxRDPower = chan->maxRegTxPower * 2;
twiceMaxRDPower = chan->ic_maxregpower * 2;
if (IS_CHAN_5GHZ(chan)) {
if (IEEE80211_IS_CHAN_5GHZ(chan)) {
twiceAntennaGain = ee->ee_antennaGainMax[0];
} else {
twiceAntennaGain = ee->ee_antennaGainMax[1];
@ -1553,7 +1534,7 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
}
numEdges = i;
ar5211GetLowerUpperValues(chan->channel, tempChannelList,
ar5211GetLowerUpperValues(freq, tempChannelList,
numEdges, &lowerChannel, &upperChannel);
/* Get the index for this channel */
for (i = 0; i < numEdges; i++)
@ -1562,7 +1543,7 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
HALASSERT(i != numEdges);
if ((lowerChannel == upperChannel &&
lowerChannel == chan->channel) ||
lowerChannel == freq) ||
pRdEdgesPower[i].flag) {
twiceMaxEdgePower = pRdEdgesPower[i].twice_rdEdgePower;
HALASSERT(twiceMaxEdgePower > 0);
@ -1573,7 +1554,7 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
for (i = 0; i < numChannels; i++)
tempChannelList[i] = pPowerInfo[i].testChannel;
ar5211GetLowerUpperValues(chan->channel, tempChannelList,
ar5211GetLowerUpperValues(freq, tempChannelList,
numChannels, &lowerChannel, &upperChannel);
/* get the index for the channel */
@ -1587,7 +1568,7 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
}
for (i = 0; i < NUM_RATES; i++) {
if (IS_CHAN_OFDM(chan)) {
if (IEEE80211_IS_CHAN_OFDM(chan)) {
/* power for rates 6,9,12,18,24 is all the same */
if (i < 5) {
lowerPower = pPowerInfo[lowerIndex].twicePwr6_24;
@ -1627,7 +1608,7 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
}
}
twicePower = ar5211GetInterpolatedValue(chan->channel,
twicePower = ar5211GetInterpolatedValue(freq,
lowerChannel, upperChannel, lowerPower, upperPower, 0);
/* Reduce power by band edge restrictions */
@ -1639,7 +1620,7 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
* this unless specially configured. Then we limit
* power only for non-AP operation.
*/
if (IS_CHAN_TURBO(chan) &&
if (IEEE80211_IS_CHAN_TURBO(chan) &&
AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER3_1
#ifdef AH_ENABLE_AP_SUPPORT
&& AH_PRIVATE(ah)->ah_opmode != HAL_M_HOSTAP
@ -1669,14 +1650,14 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
#ifdef AH_DEBUG
HALDEBUG(ah, HAL_DEBUG_RESET,
"%s: final output power setting %d MHz:\n",
__func__, chan->channel);
__func__, chan->ic_freq);
HALDEBUG(ah, HAL_DEBUG_RESET,
"6 Mb %d dBm, MaxRD: %d dBm, MaxEdge %d dBm\n",
scaledPower / 2, twiceMaxRDPower / 2, twiceMaxEdgePower / 2);
HALDEBUG(ah, HAL_DEBUG_RESET, "TPC Scale %d dBm - Ant Red %d dBm\n",
tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale] * 2,
twiceAntennaReduction / 2);
if (IS_CHAN_TURBO(chan) &&
if (IEEE80211_IS_CHAN_TURBO(chan) &&
AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER3_1)
HALDEBUG(ah, HAL_DEBUG_RESET, "Max Turbo %d dBm\n",
ee->ee_turbo2WMaxPower5);
@ -1709,7 +1690,8 @@ ar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower,
* Get or interpolate the pcdac value from the calibrated data
*/
uint16_t
ar5211GetScaledPower(uint16_t channel, uint16_t pcdacValue, const PCDACS_EEPROM *pSrcStruct)
ar5211GetScaledPower(uint16_t channel, uint16_t pcdacValue,
const PCDACS_EEPROM *pSrcStruct)
{
uint16_t powerValue;
uint16_t lFreq, rFreq; /* left and right frequency values */
@ -1940,11 +1922,11 @@ ar5211InitializeGainValues(struct ath_hal *ah)
static HAL_BOOL
ar5211InvalidGainReadback(struct ath_hal *ah, GAIN_VALUES *gv)
{
HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
uint32_t gStep, g;
uint32_t L1, L2, L3, L4;
if (IS_CHAN_CCK(chan)) {
if (IEEE80211_IS_CHAN_CCK(chan)) {
gStep = 0x18;
L1 = 0;
L2 = gStep + 4;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2006 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5211_xmit.c,v 1.6 2008/11/10 04:08:03 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -233,7 +233,7 @@ HAL_BOOL
ar5211ResetTxQueue(struct ath_hal *ah, u_int q)
{
struct ath_hal_5211 *ahp = AH5211(ah);
HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
HAL_TX_QUEUE_INFO *qi;
uint32_t cwMin, chanCwMin, value;
@ -254,7 +254,7 @@ ar5211ResetTxQueue(struct ath_hal *ah, u_int q)
* Select cwmin according to channel type.
* NB: chan can be NULL during attach
*/
if (chan && IS_CHAN_B(chan))
if (chan && IEEE80211_IS_CHAN_B(chan))
chanCwMin = INIT_CWMIN_11B;
else
chanCwMin = INIT_CWMIN;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar2316.c,v 1.9 2008/11/15 22:15:46 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -88,28 +88,29 @@ ar2316WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
ar2316SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar2316SetChannel(struct ath_hal *ah, struct ieee80211_channel *chan)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
uint32_t aModeRefSel = 0;
uint32_t reg32 = 0;
OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
if (chan->channel < 4800) {
if (freq < 4800) {
uint32_t txctl;
if (((chan->channel - 2192) % 5) == 0) {
channelSel = ((chan->channel - 672) * 2 - 3040)/10;
if (((freq - 2192) % 5) == 0) {
channelSel = ((freq - 672) * 2 - 3040)/10;
bModeSynth = 0;
} else if (((chan->channel - 2224) % 5) == 0) {
channelSel = ((chan->channel - 704) * 2 - 3040) / 10;
} else if (((freq - 2224) % 5) == 0) {
channelSel = ((freq - 704) * 2 - 3040) / 10;
bModeSynth = 1;
} else {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u MHz\n",
__func__, chan->channel);
__func__, freq);
return AH_FALSE;
}
@ -117,7 +118,7 @@ ar2316SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
channelSel = ath_hal_reverseBits(channelSel, 8);
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
if (chan->channel == 2484) {
if (freq == 2484) {
/* Enable channel spreading for channel 14 */
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@ -125,21 +126,21 @@ ar2316SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
}
} else if ((chan->channel % 20) == 0 && chan->channel >= 5120) {
} else if ((freq % 20) == 0 && freq >= 5120) {
channelSel = ath_hal_reverseBits(
((chan->channel - 4800) / 20 << 2), 8);
((freq - 4800) / 20 << 2), 8);
aModeRefSel = ath_hal_reverseBits(3, 2);
} else if ((chan->channel % 10) == 0) {
} else if ((freq % 10) == 0) {
channelSel = ath_hal_reverseBits(
((chan->channel - 4800) / 10 << 1), 8);
((freq - 4800) / 10 << 1), 8);
aModeRefSel = ath_hal_reverseBits(2, 2);
} else if ((chan->channel % 5) == 0) {
} else if ((freq % 5) == 0) {
channelSel = ath_hal_reverseBits(
(chan->channel - 4800) / 5, 8);
(freq - 4800) / 5, 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",
__func__, chan->channel);
__func__, freq);
return AH_FALSE;
}
@ -161,7 +162,8 @@ ar2316SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
ar2316SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIndex, uint16_t *rfXpdGain)
ar2316SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan,
uint16_t modesIndex, uint16_t *rfXpdGain)
{
#define RF_BANK_SETUP(_priv, _ix, _col) do { \
int i; \
@ -174,27 +176,18 @@ ar2316SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
struct ar2316State *priv = AR2316(ah);
int regWrites = 0;
HALDEBUG(ah, HAL_DEBUG_RFPARAM,
"%s: chan 0x%x flag 0x%x modesIndex 0x%x\n",
__func__, chan->channel, chan->channelFlags, modesIndex);
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
__func__, chan->ic_freq, chan->ic_flags, modesIndex);
HALASSERT(priv != AH_NULL);
/* Setup rf parameters */
switch (chan->channelFlags & CHANNEL_ALL) {
case CHANNEL_B:
if (IEEE80211_IS_CHAN_B(chan)) {
ob2GHz = ee->ee_obFor24;
db2GHz = ee->ee_dbFor24;
break;
case CHANNEL_G:
case CHANNEL_108G:
} else {
ob2GHz = ee->ee_obFor24g;
db2GHz = ee->ee_dbFor24g;
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
return AH_FALSE;
}
/* Bank 1 Write */
@ -507,7 +500,8 @@ ar2316getGainBoundariesAndPdadcsForPowers(struct ath_hal *ah, uint16_t channel,
static HAL_BOOL
ar2316SetPowerTable(struct ath_hal *ah,
int16_t *minPower, int16_t *maxPower, HAL_CHANNEL_INTERNAL *chan,
int16_t *minPower, int16_t *maxPower,
const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
struct ath_hal_5212 *ahp = AH5212(ah);
@ -524,11 +518,11 @@ ar2316SetPowerTable(struct ath_hal *ah,
#endif
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan 0x%x flag 0x%x\n",
__func__, chan->channel,chan->channelFlags);
__func__, chan->ic_freq, chan->ic_flags);
if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
else if (IS_CHAN_B(chan))
else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: illegal mode\n", __func__);
@ -646,9 +640,11 @@ ar2316GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2316 *data)
}
static HAL_BOOL
ar2316GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
ar2316GetChannelMaxMinPower(struct ath_hal *ah,
const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
uint16_t freq = chan->ic_freq; /* NB: never mapped */
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2316 *pRawDataset = AH_NULL;
const RAW_DATA_PER_CHANNEL_2316 *data=AH_NULL;
@ -657,9 +653,9 @@ ar2316GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
*maxPow = 0;
if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
else if (IS_CHAN_B(chan))
else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else
return(AH_FALSE);
@ -673,9 +669,9 @@ ar2316GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
if (numChannels < 1)
return(AH_FALSE);
if ((chan->channel < data[0].channelValue) ||
(chan->channel > data[numChannels-1].channelValue)) {
if (chan->channel < data[0].channelValue) {
if ((freq < data[0].channelValue) ||
(freq > data[numChannels-1].channelValue)) {
if (freq < data[0].channelValue) {
*maxPow = ar2316GetMaxPower(ah, &data[0]);
*minPow = ar2316GetMinPower(ah, &data[0]);
return(AH_TRUE);
@ -687,19 +683,19 @@ ar2316GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
}
/* Linearly interpolate the power value now */
for (last=0,i=0; (i<numChannels) && (chan->channel > data[i].channelValue);
for (last=0,i=0; (i<numChannels) && (freq > data[i].channelValue);
last = i++);
totalD = data[i].channelValue - data[last].channelValue;
if (totalD > 0) {
totalF = ar2316GetMaxPower(ah, &data[i]) - ar2316GetMaxPower(ah, &data[last]);
*maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) +
*maxPow = (int8_t) ((totalF*(freq-data[last].channelValue) +
ar2316GetMaxPower(ah, &data[last])*totalD)/totalD);
totalMin = ar2316GetMinPower(ah, &data[i]) - ar2316GetMinPower(ah, &data[last]);
*minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) +
*minPow = (int8_t) ((totalMin*(freq-data[last].channelValue) +
ar2316GetMinPower(ah, &data[last])*totalD)/totalD);
return(AH_TRUE);
} else {
if (chan->channel == data[i].channelValue) {
if (freq == data[i].channelValue) {
*maxPow = ar2316GetMaxPower(ah, &data[i]);
*minPow = ar2316GetMinPower(ah, &data[i]);
return(AH_TRUE);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar2317.c,v 1.8 2008/11/15 22:15:46 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -79,22 +79,23 @@ ar2317WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
ar2317SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar2317SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
uint32_t aModeRefSel = 0;
uint32_t reg32 = 0;
OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
if (chan->channel < 4800) {
if (freq < 4800) {
uint32_t txctl;
channelSel = chan->channel - 2272 ;
channelSel = freq - 2272 ;
channelSel = ath_hal_reverseBits(channelSel, 8);
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
if (chan->channel == 2484) {
if (freq == 2484) {
/* Enable channel spreading for channel 14 */
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@ -102,21 +103,21 @@ ar2317SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
}
} else if ((chan->channel % 20) == 0 && chan->channel >= 5120) {
} else if ((freq % 20) == 0 && freq >= 5120) {
channelSel = ath_hal_reverseBits(
((chan->channel - 4800) / 20 << 2), 8);
((freq - 4800) / 20 << 2), 8);
aModeRefSel = ath_hal_reverseBits(3, 2);
} else if ((chan->channel % 10) == 0) {
} else if ((freq % 10) == 0) {
channelSel = ath_hal_reverseBits(
((chan->channel - 4800) / 10 << 1), 8);
((freq - 4800) / 10 << 1), 8);
aModeRefSel = ath_hal_reverseBits(2, 2);
} else if ((chan->channel % 5) == 0) {
} else if ((freq % 5) == 0) {
channelSel = ath_hal_reverseBits(
(chan->channel - 4800) / 5, 8);
(freq - 4800) / 5, 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",
__func__, chan->channel);
__func__, freq);
return AH_FALSE;
}
@ -138,7 +139,9 @@ ar2317SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
ar2317SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIndex, uint16_t *rfXpdGain)
ar2317SetRfRegs(struct ath_hal *ah,
const struct ieee80211_channel *chan,
uint16_t modesIndex, uint16_t *rfXpdGain)
{
#define RF_BANK_SETUP(_priv, _ix, _col) do { \
int i; \
@ -151,27 +154,18 @@ ar2317SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
struct ar2317State *priv = AR2317(ah);
int regWrites = 0;
HALDEBUG(ah, HAL_DEBUG_RFPARAM,
"%s: chan 0x%x flag 0x%x modesIndex 0x%x\n",
__func__, chan->channel, chan->channelFlags, modesIndex);
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
__func__, chan->ic_freq, chan->ic_flags, modesIndex);
HALASSERT(priv);
/* Setup rf parameters */
switch (chan->channelFlags & CHANNEL_ALL) {
case CHANNEL_B:
if (IEEE80211_IS_CHAN_B(chan)) {
ob2GHz = ee->ee_obFor24;
db2GHz = ee->ee_dbFor24;
break;
case CHANNEL_G:
case CHANNEL_108G:
} else {
ob2GHz = ee->ee_obFor24g;
db2GHz = ee->ee_dbFor24g;
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
return AH_FALSE;
}
/* Bank 1 Write */
@ -484,7 +478,8 @@ ar2317getGainBoundariesAndPdadcsForPowers(struct ath_hal *ah, uint16_t channel,
static HAL_BOOL
ar2317SetPowerTable(struct ath_hal *ah,
int16_t *minPower, int16_t *maxPower, HAL_CHANNEL_INTERNAL *chan,
int16_t *minPower, int16_t *maxPower,
const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
struct ath_hal_5212 *ahp = AH5212(ah);
@ -501,11 +496,11 @@ ar2317SetPowerTable(struct ath_hal *ah,
#endif
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan 0x%x flag 0x%x\n",
__func__, chan->channel,chan->channelFlags);
__func__, chan->ic_freq, chan->ic_flags);
if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
else if (IS_CHAN_B(chan))
else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: illegal mode\n", __func__);
@ -625,9 +620,11 @@ ar2317GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2317 *data)
}
static HAL_BOOL
ar2317GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
ar2317GetChannelMaxMinPower(struct ath_hal *ah,
const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
uint16_t freq = chan->ic_freq; /* NB: never mapped */
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2317 *pRawDataset = AH_NULL;
const RAW_DATA_PER_CHANNEL_2317 *data=AH_NULL;
@ -636,9 +633,9 @@ ar2317GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
*maxPow = 0;
if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
else if (IS_CHAN_B(chan))
else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else
return(AH_FALSE);
@ -652,9 +649,9 @@ ar2317GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
if (numChannels < 1)
return(AH_FALSE);
if ((chan->channel < data[0].channelValue) ||
(chan->channel > data[numChannels-1].channelValue)) {
if (chan->channel < data[0].channelValue) {
if ((freq < data[0].channelValue) ||
(freq > data[numChannels-1].channelValue)) {
if (freq < data[0].channelValue) {
*maxPow = ar2317GetMaxPower(ah, &data[0]);
*minPow = ar2317GetMinPower(ah, &data[0]);
return(AH_TRUE);
@ -666,19 +663,19 @@ ar2317GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
}
/* Linearly interpolate the power value now */
for (last=0,i=0; (i<numChannels) && (chan->channel > data[i].channelValue);
for (last=0,i=0; (i<numChannels) && (freq > data[i].channelValue);
last = i++);
totalD = data[i].channelValue - data[last].channelValue;
if (totalD > 0) {
totalF = ar2317GetMaxPower(ah, &data[i]) - ar2317GetMaxPower(ah, &data[last]);
*maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) +
*maxPow = (int8_t) ((totalF*(freq-data[last].channelValue) +
ar2317GetMaxPower(ah, &data[last])*totalD)/totalD);
totalMin = ar2317GetMinPower(ah, &data[i]) - ar2317GetMinPower(ah, &data[last]);
*minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) +
*minPow = (int8_t) ((totalMin*(freq-data[last].channelValue) +
ar2317GetMinPower(ah, &data[last])*totalD)/totalD);
return(AH_TRUE);
} else {
if (chan->channel == data[i].channelValue) {
if (freq == data[i].channelValue) {
*maxPow = ar2317GetMaxPower(ah, &data[i]);
*minPow = ar2317GetMinPower(ah, &data[i]);
return(AH_TRUE);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar2413.c,v 1.8 2008/11/15 22:15:46 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -75,29 +75,29 @@ ar2413WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
ar2413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar2413SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
uint32_t aModeRefSel = 0;
uint32_t reg32 = 0;
uint16_t freq;
OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
if (chan->channel < 4800) {
if (freq < 4800) {
uint32_t txctl;
if (((chan->channel - 2192) % 5) == 0) {
channelSel = ((chan->channel - 672) * 2 - 3040)/10;
if (((freq - 2192) % 5) == 0) {
channelSel = ((freq - 672) * 2 - 3040)/10;
bModeSynth = 0;
} else if (((chan->channel - 2224) % 5) == 0) {
channelSel = ((chan->channel - 704) * 2 - 3040) / 10;
} else if (((freq - 2224) % 5) == 0) {
channelSel = ((freq - 704) * 2 - 3040) / 10;
bModeSynth = 1;
} else {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u MHz\n",
__func__, chan->channel);
__func__, freq);
return AH_FALSE;
}
@ -105,7 +105,7 @@ ar2413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
channelSel = ath_hal_reverseBits(channelSel, 8);
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
if (chan->channel == 2484) {
if (freq == 2484) {
/* Enable channel spreading for channel 14 */
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@ -113,26 +113,26 @@ ar2413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
}
} else if (((chan->channel % 5) == 2) && (chan->channel <= 5435)) {
freq = chan->channel - 2; /* Align to even 5MHz raster */
} else if (((freq % 5) == 2) && (freq <= 5435)) {
freq = freq - 2; /* Align to even 5MHz raster */
channelSel = ath_hal_reverseBits(
(uint32_t)(((freq - 4800)*10)/25 + 1), 8);
aModeRefSel = ath_hal_reverseBits(0, 2);
} else if ((chan->channel % 20) == 0 && chan->channel >= 5120) {
} else if ((freq % 20) == 0 && freq >= 5120) {
channelSel = ath_hal_reverseBits(
((chan->channel - 4800) / 20 << 2), 8);
((freq - 4800) / 20 << 2), 8);
aModeRefSel = ath_hal_reverseBits(3, 2);
} else if ((chan->channel % 10) == 0) {
} else if ((freq % 10) == 0) {
channelSel = ath_hal_reverseBits(
((chan->channel - 4800) / 10 << 1), 8);
((freq - 4800) / 10 << 1), 8);
aModeRefSel = ath_hal_reverseBits(2, 2);
} else if ((chan->channel % 5) == 0) {
} else if ((freq % 5) == 0) {
channelSel = ath_hal_reverseBits(
(chan->channel - 4800) / 5, 8);
(freq - 4800) / 5, 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",
__func__, chan->channel);
__func__, freq);
return AH_FALSE;
}
@ -155,7 +155,9 @@ ar2413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
ar2413SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIndex, uint16_t *rfXpdGain)
ar2413SetRfRegs(struct ath_hal *ah,
const struct ieee80211_channel *chan,
uint16_t modesIndex, uint16_t *rfXpdGain)
{
#define RF_BANK_SETUP(_priv, _ix, _col) do { \
int i; \
@ -168,27 +170,18 @@ ar2413SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
struct ar2413State *priv = AR2413(ah);
int regWrites = 0;
HALDEBUG(ah, HAL_DEBUG_RFPARAM,
"%s: chan 0x%x flag 0x%x modesIndex 0x%x\n",
__func__, chan->channel, chan->channelFlags, modesIndex);
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
__func__, chan->ic_freq, chan->ic_flags, modesIndex);
HALASSERT(priv);
/* Setup rf parameters */
switch (chan->channelFlags & CHANNEL_ALL) {
case CHANNEL_B:
if (IEEE80211_IS_CHAN_B(chan)) {
ob2GHz = ee->ee_obFor24;
db2GHz = ee->ee_dbFor24;
break;
case CHANNEL_G:
case CHANNEL_108G:
} else {
ob2GHz = ee->ee_obFor24g;
db2GHz = ee->ee_dbFor24g;
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
return AH_FALSE;
}
/* Bank 1 Write */
@ -501,9 +494,11 @@ ar2413getGainBoundariesAndPdadcsForPowers(struct ath_hal *ah, uint16_t channel,
static HAL_BOOL
ar2413SetPowerTable(struct ath_hal *ah,
int16_t *minPower, int16_t *maxPower, HAL_CHANNEL_INTERNAL *chan,
int16_t *minPower, int16_t *maxPower,
const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2413 *pRawDataset = AH_NULL;
@ -518,11 +513,11 @@ ar2413SetPowerTable(struct ath_hal *ah,
#endif
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan 0x%x flag 0x%x\n",
__func__, chan->channel,chan->channelFlags);
__func__, freq, chan->ic_flags);
if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
else if (IS_CHAN_B(chan))
else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: illegal mode\n", __func__);
@ -533,7 +528,7 @@ ar2413SetPowerTable(struct ath_hal *ah,
AR_PHY_TPCRG5_PD_GAIN_OVERLAP);
numPdGainsUsed = ar2413getGainBoundariesAndPdadcsForPowers(ah,
chan->channel, pRawDataset, pdGainOverlap_t2,
freq, pRawDataset, pdGainOverlap_t2,
&minCalPower2413_t2,gainBoundaries, rfXpdGain, pdadcValues);
HALASSERT(1 <= numPdGainsUsed && numPdGainsUsed <= 3);
@ -640,9 +635,11 @@ ar2413GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2413 *data)
}
static HAL_BOOL
ar2413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
ar2413GetChannelMaxMinPower(struct ath_hal *ah,
const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
uint16_t freq = chan->ic_freq; /* NB: never mapped */
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2413 *pRawDataset = AH_NULL;
const RAW_DATA_PER_CHANNEL_2413 *data = AH_NULL;
@ -651,9 +648,9 @@ ar2413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
*maxPow = 0;
if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
else if (IS_CHAN_B(chan))
else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else
return(AH_FALSE);
@ -667,9 +664,9 @@ ar2413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
if (numChannels < 1)
return(AH_FALSE);
if ((chan->channel < data[0].channelValue) ||
(chan->channel > data[numChannels-1].channelValue)) {
if (chan->channel < data[0].channelValue) {
if ((freq < data[0].channelValue) ||
(freq > data[numChannels-1].channelValue)) {
if (freq < data[0].channelValue) {
*maxPow = ar2413GetMaxPower(ah, &data[0]);
*minPow = ar2413GetMinPower(ah, &data[0]);
return(AH_TRUE);
@ -681,19 +678,19 @@ ar2413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
}
/* Linearly interpolate the power value now */
for (last=0,i=0; (i<numChannels) && (chan->channel > data[i].channelValue);
for (last=0,i=0; (i<numChannels) && (freq > data[i].channelValue);
last = i++);
totalD = data[i].channelValue - data[last].channelValue;
if (totalD > 0) {
totalF = ar2413GetMaxPower(ah, &data[i]) - ar2413GetMaxPower(ah, &data[last]);
*maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) +
*maxPow = (int8_t) ((totalF*(freq-data[last].channelValue) +
ar2413GetMaxPower(ah, &data[last])*totalD)/totalD);
totalMin = ar2413GetMinPower(ah, &data[i]) - ar2413GetMinPower(ah, &data[last]);
*minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) +
*minPow = (int8_t) ((totalMin*(freq-data[last].channelValue) +
ar2413GetMinPower(ah, &data[last])*totalD)/totalD);
return(AH_TRUE);
} else {
if (chan->channel == data[i].channelValue) {
if (freq == data[i].channelValue) {
*maxPow = ar2413GetMaxPower(ah, &data[i]);
*minPow = ar2413GetMinPower(ah, &data[i]);
return(AH_TRUE);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar2425.c,v 1.8 2008/11/16 21:33:05 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -82,24 +82,24 @@ ar2425WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
ar2425SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar2425SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
uint32_t aModeRefSel = 0;
uint32_t reg32 = 0;
uint16_t freq;
OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
if (chan->channel < 4800) {
if (freq < 4800) {
uint32_t txctl;
channelSel = chan->channel - 2272;
channelSel = freq - 2272;
channelSel = ath_hal_reverseBits(channelSel, 8);
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
if (chan->channel == 2484) {
if (freq == 2484) {
// Enable channel spreading for channel 14
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@ -108,26 +108,26 @@ ar2425SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
}
} else if (((chan->channel % 5) == 2) && (chan->channel <= 5435)) {
freq = chan->channel - 2; /* Align to even 5MHz raster */
} else if (((freq % 5) == 2) && (freq <= 5435)) {
freq = freq - 2; /* Align to even 5MHz raster */
channelSel = ath_hal_reverseBits(
(uint32_t)(((freq - 4800)*10)/25 + 1), 8);
aModeRefSel = ath_hal_reverseBits(0, 2);
} else if ((chan->channel % 20) == 0 && chan->channel >= 5120) {
} else if ((freq % 20) == 0 && freq >= 5120) {
channelSel = ath_hal_reverseBits(
((chan->channel - 4800) / 20 << 2), 8);
((freq - 4800) / 20 << 2), 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else if ((chan->channel % 10) == 0) {
} else if ((freq % 10) == 0) {
channelSel = ath_hal_reverseBits(
((chan->channel - 4800) / 10 << 1), 8);
((freq - 4800) / 10 << 1), 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else if ((chan->channel % 5) == 0) {
} else if ((freq % 5) == 0) {
channelSel = ath_hal_reverseBits(
(chan->channel - 4800) / 5, 8);
(freq - 4800) / 5, 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",
__func__, chan->channel);
__func__, freq);
return AH_FALSE;
}
@ -149,7 +149,9 @@ ar2425SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
ar2425SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIndex, uint16_t *rfXpdGain)
ar2425SetRfRegs(struct ath_hal *ah,
const struct ieee80211_channel *chan,
uint16_t modesIndex, uint16_t *rfXpdGain)
{
#define RF_BANK_SETUP(_priv, _ix, _col) do { \
int i; \
@ -162,27 +164,18 @@ ar2425SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
uint16_t ob2GHz = 0, db2GHz = 0;
int regWrites = 0;
HALDEBUG(ah, HAL_DEBUG_RFPARAM,
"==>%s:chan 0x%x flag 0x%x modesIndex 0x%x\n",
__func__, chan->channel, chan->channelFlags, modesIndex);
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
__func__, chan->ic_freq, chan->ic_flags, modesIndex);
HALASSERT(priv);
/* Setup rf parameters */
switch (chan->channelFlags & CHANNEL_ALL) {
case CHANNEL_B:
if (IEEE80211_IS_CHAN_B(chan)) {
ob2GHz = ee->ee_obFor24;
db2GHz = ee->ee_dbFor24;
break;
case CHANNEL_G:
case CHANNEL_108G:
} else {
ob2GHz = ee->ee_obFor24g;
db2GHz = ee->ee_dbFor24g;
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
return AH_FALSE;
}
/* Bank 1 Write */
@ -501,9 +494,11 @@ ar2425getGainBoundariesAndPdadcsForPowers(struct ath_hal *ah, uint16_t channel,
/* Same as 2413 set power table */
static HAL_BOOL
ar2425SetPowerTable(struct ath_hal *ah,
int16_t *minPower, int16_t *maxPower, HAL_CHANNEL_INTERNAL *chan,
int16_t *minPower, int16_t *maxPower,
const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2413 *pRawDataset = AH_NULL;
@ -514,11 +509,11 @@ ar2425SetPowerTable(struct ath_hal *ah,
uint32_t i, reg32, regoffset;
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s:chan 0x%x flag 0x%x\n",
__func__, chan->channel,chan->channelFlags);
__func__, freq, chan->ic_flags);
if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
else if (IS_CHAN_B(chan))
else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s:illegal mode\n", __func__);
@ -528,7 +523,7 @@ ar2425SetPowerTable(struct ath_hal *ah,
pdGainOverlap_t2 = (uint16_t) SM(OS_REG_READ(ah, AR_PHY_TPCRG5),
AR_PHY_TPCRG5_PD_GAIN_OVERLAP);
ar2425getGainBoundariesAndPdadcsForPowers(ah, chan->channel,
ar2425getGainBoundariesAndPdadcsForPowers(ah, freq,
pRawDataset, pdGainOverlap_t2,&minCalPower2413_t2,gainBoundaries,
rfXpdGain, pdadcValues);
@ -603,9 +598,11 @@ ar2425GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2413 *data)
static
HAL_BOOL
ar2425GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
int16_t *maxPow, int16_t *minPow)
ar2425GetChannelMaxMinPower(struct ath_hal *ah,
const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
uint16_t freq = chan->ic_freq; /* NB: never mapped */
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2413 *pRawDataset = AH_NULL;
const RAW_DATA_PER_CHANNEL_2413 *data = AH_NULL;
@ -614,9 +611,9 @@ ar2425GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
*maxPow = 0;
if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
else if (IS_CHAN_B(chan))
else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else
return(AH_FALSE);
@ -630,9 +627,9 @@ ar2425GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
if (numChannels < 1)
return(AH_FALSE);
if ((chan->channel < data[0].channelValue) ||
(chan->channel > data[numChannels-1].channelValue)) {
if (chan->channel < data[0].channelValue) {
if ((freq < data[0].channelValue) ||
(freq > data[numChannels-1].channelValue)) {
if (freq < data[0].channelValue) {
*maxPow = ar2425GetMaxPower(ah, &data[0]);
*minPow = ar2425GetMinPower(ah, &data[0]);
return(AH_TRUE);
@ -644,19 +641,19 @@ ar2425GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
}
/* Linearly interpolate the power value now */
for (last=0,i=0; (i<numChannels) && (chan->channel > data[i].channelValue);
for (last=0,i=0; (i<numChannels) && (freq > data[i].channelValue);
last = i++);
totalD = data[i].channelValue - data[last].channelValue;
if (totalD > 0) {
totalF = ar2425GetMaxPower(ah, &data[i]) - ar2425GetMaxPower(ah, &data[last]);
*maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) +
*maxPow = (int8_t) ((totalF*(freq-data[last].channelValue) +
ar2425GetMaxPower(ah, &data[last])*totalD)/totalD);
totalMin = ar2425GetMinPower(ah, &data[i]) - ar2425GetMinPower(ah, &data[last]);
*minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) +
*minPow = (int8_t) ((totalMin*(freq-data[last].channelValue) +
ar2425GetMinPower(ah, &data[last])*totalD)/totalD);
return(AH_TRUE);
} else {
if (chan->channel == data[i].channelValue) {
if (freq == data[i].channelValue) {
*maxPow = ar2425GetMaxPower(ah, &data[i]);
*minPow = ar2425GetMinPower(ah, &data[i]);
return(AH_TRUE);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -74,9 +74,10 @@ ar5111WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
ar5111SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar5111SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
#define CI_2GHZ_INDEX_CORRECTION 19
uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t refClk, reg32, data2111;
int16_t chan5111, chanIEEE;
@ -140,10 +141,10 @@ ar5111SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
{ 1, 0x46, 180 } /* 2732 26 */
};
OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
chanIEEE = ath_hal_mhz2ieee(ah, chan->channel, chan->channelFlags);
if (IS_CHAN_2GHZ(chan)) {
chanIEEE = chan->ic_ieee;
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
const CHAN_INFO_2GHZ* ci =
&chan2GHzData[chanIEEE + CI_2GHZ_INDEX_CORRECTION];
uint32_t txctl;
@ -153,7 +154,7 @@ ar5111SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
| (ci->refClkSel << 4);
chan5111 = ci->channel5111;
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
if (chan->channel == 2484) {
if (freq == 2484) {
/* Enable channel spreading for channel 14 */
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@ -214,9 +215,10 @@ ar5111GetRfBank(struct ath_hal *ah, int bank)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
ar5111SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan,
uint16_t modesIndex, uint16_t *rfXpdGain)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
uint16_t rfXpdGainFixed, rfPloSel, rfPwdXpd, gainI;
@ -224,20 +226,22 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
uint32_t ob2GHz, db2GHz, rfReg[N(ar5212Bank6_5111)];
int i, regWrites = 0;
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
__func__, chan->ic_freq, chan->ic_flags, modesIndex);
/* Setup rf parameters */
switch (chan->channelFlags & CHANNEL_ALL) {
case CHANNEL_A:
case CHANNEL_T:
if (4000 < chan->channel && chan->channel < 5260) {
switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
case IEEE80211_CHAN_A:
if (4000 < freq && freq < 5260) {
tempOB = ee->ee_ob1;
tempDB = ee->ee_db1;
} else if (5260 <= chan->channel && chan->channel < 5500) {
} else if (5260 <= freq && freq < 5500) {
tempOB = ee->ee_ob2;
tempDB = ee->ee_db2;
} else if (5500 <= chan->channel && chan->channel < 5725) {
} else if (5500 <= freq && freq < 5725) {
tempOB = ee->ee_ob3;
tempDB = ee->ee_db3;
} else if (chan->channel >= 5725) {
} else if (freq >= 5725) {
tempOB = ee->ee_ob4;
tempDB = ee->ee_db4;
} else {
@ -251,7 +255,7 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
rfPwdXpd = !ee->ee_xpd[headerInfo11A];
gainI = ee->ee_gainI[headerInfo11A];
break;
case CHANNEL_B:
case IEEE80211_CHAN_B:
tempOB = ee->ee_obFor24;
tempDB = ee->ee_dbFor24;
ob2GHz = ee->ee_ob2GHz[0];
@ -262,7 +266,8 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
rfPwdXpd = !ee->ee_xpd[headerInfo11B];
gainI = ee->ee_gainI[headerInfo11B];
break;
case CHANNEL_G:
case IEEE80211_CHAN_G:
case IEEE80211_CHAN_PUREG: /* NB: really 108G */
tempOB = ee->ee_obFor24g;
tempDB = ee->ee_dbFor24g;
ob2GHz = ee->ee_ob2GHz[1];
@ -275,7 +280,7 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
__func__, chan->ic_flags);
return AH_FALSE;
}
@ -285,7 +290,7 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
/* Bank 0 Write */
for (i = 0; i < N(ar5212Bank0_5111); i++)
rfReg[i] = ar5212Bank0_5111[i][modesIndex];
if (IS_CHAN_2GHZ(chan)) {
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ar5212ModifyRfBuffer(rfReg, ob2GHz, 3, 119, 0);
ar5212ModifyRfBuffer(rfReg, db2GHz, 3, 122, 0);
}
@ -303,7 +308,7 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
/* Bank 6 Write */
for (i = 0; i < N(ar5212Bank6_5111); i++)
rfReg[i] = ar5212Bank6_5111[i][modesIndex];
if (IS_CHAN_A(chan)) { /* NB: CHANNEL_A | CHANNEL_T */
if (IEEE80211_IS_CHAN_A(chan)) { /* NB: CHANNEL_A | CHANNEL_T */
ar5212ModifyRfBuffer(rfReg, ee->ee_cornerCal.pd84, 1, 51, 3);
ar5212ModifyRfBuffer(rfReg, ee->ee_cornerCal.pd90, 1, 45, 3);
}
@ -320,11 +325,11 @@ ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
ar5212ModifyRfBuffer(rfReg, gainI, 6, 29, 0);
ar5212ModifyRfBuffer(rfReg, rfPloSel, 1, 4, 0);
if (IS_CHAN_QUARTER_RATE(chan) || IS_CHAN_HALF_RATE(chan)) {
if (IEEE80211_IS_CHAN_QUARTER(chan) || IEEE80211_IS_CHAN_HALF(chan)) {
uint32_t rfWaitI, rfWaitS, rfMaxTime;
rfWaitS = 0x1f;
rfWaitI = (IS_CHAN_HALF_RATE(chan)) ? 0x10 : 0x1f;
rfWaitI = (IEEE80211_IS_CHAN_HALF(chan)) ? 0x10 : 0x1f;
rfMaxTime = 3;
ar5212ModifyRfBuffer(rfReg, rfWaitS, 5, 19, 0);
ar5212ModifyRfBuffer(rfReg, rfWaitI, 5, 24, 0);
@ -383,9 +388,11 @@ interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
*/
static HAL_BOOL
ar5111SetPowerTable(struct ath_hal *ah,
int16_t *pMinPower, int16_t *pMaxPower, HAL_CHANNEL_INTERNAL *chan,
int16_t *pMinPower, int16_t *pMaxPower,
const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
FULL_PCDAC_STRUCT pcdacStruct;
@ -404,27 +411,27 @@ ar5111SetPowerTable(struct ath_hal *ah,
PCDACS_EEPROM eepromPcdacs;
/* setup the pcdac struct to point to the correct info, based on mode */
switch (chan->channelFlags & CHANNEL_ALL) {
case CHANNEL_A:
case CHANNEL_T:
switch (chan->ic_flags & IEEE80211_CHAN_ALLTURBOFULL) {
case IEEE80211_CHAN_A:
case IEEE80211_CHAN_ST:
eepromPcdacs.numChannels = ee->ee_numChannels11a;
eepromPcdacs.pChannelList = ee->ee_channels11a;
eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11a;
break;
case CHANNEL_B:
case IEEE80211_CHAN_B:
eepromPcdacs.numChannels = ee->ee_numChannels2_4;
eepromPcdacs.pChannelList = ee->ee_channels11b;
eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11b;
break;
case CHANNEL_G:
case CHANNEL_108G:
case IEEE80211_CHAN_G:
case IEEE80211_CHAN_108G:
eepromPcdacs.numChannels = ee->ee_numChannels2_4;
eepromPcdacs.pChannelList = ee->ee_channels11g;
eepromPcdacs.pDataPerChannel = ee->ee_dataPerChannel11g;
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
__func__, chan->ic_flags);
return AH_FALSE;
}
@ -444,7 +451,7 @@ ar5111SetPowerTable(struct ath_hal *ah,
/* Fill out the power values for this channel */
for (j = 0; j < pcdacStruct.numPcdacValues; j++ )
pScaledUpDbm[j] = ar5212GetScaledPower(chan->channel,
pScaledUpDbm[j] = ar5212GetScaledPower(freq,
pPcdacValues[j], pSrcStruct);
/* Now scale the pcdac values to fit in the 64 entry power table */
@ -617,7 +624,8 @@ ar5212GetLowerUpperPcdacs(uint16_t pcdac, uint16_t channel,
}
static HAL_BOOL
ar5111GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
ar5111GetChannelMaxMinPower(struct ath_hal *ah,
const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
/* XXX - Get 5111 power limits! */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5112.c,v 1.7 2008/11/10 04:08:03 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -75,29 +75,29 @@ ar5112WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
ar5112SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar5112SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
uint32_t aModeRefSel = 0;
uint32_t reg32 = 0;
uint16_t freq;
OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
if (chan->channel < 4800) {
if (freq < 4800) {
uint32_t txctl;
if (((chan->channel - 2192) % 5) == 0) {
channelSel = ((chan->channel - 672) * 2 - 3040)/10;
if (((freq - 2192) % 5) == 0) {
channelSel = ((freq - 672) * 2 - 3040)/10;
bModeSynth = 0;
} else if (((chan->channel - 2224) % 5) == 0) {
channelSel = ((chan->channel - 704) * 2 - 3040) / 10;
} else if (((freq - 2224) % 5) == 0) {
channelSel = ((freq - 704) * 2 - 3040) / 10;
bModeSynth = 1;
} else {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u MHz\n",
__func__, chan->channel);
__func__, freq);
return AH_FALSE;
}
@ -105,7 +105,7 @@ ar5112SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
channelSel = ath_hal_reverseBits(channelSel, 8);
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
if (chan->channel == 2484) {
if (freq == 2484) {
/* Enable channel spreading for channel 14 */
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@ -113,26 +113,26 @@ ar5112SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
}
} else if (((chan->channel % 5) == 2) && (chan->channel <= 5435)) {
freq = chan->channel - 2; /* Align to even 5MHz raster */
} else if (((freq % 5) == 2) && (freq <= 5435)) {
freq = freq - 2; /* Align to even 5MHz raster */
channelSel = ath_hal_reverseBits(
(uint32_t)(((freq - 4800)*10)/25 + 1), 8);
aModeRefSel = ath_hal_reverseBits(0, 2);
} else if ((chan->channel % 20) == 0 && chan->channel >= 5120) {
} else if ((freq % 20) == 0 && freq >= 5120) {
channelSel = ath_hal_reverseBits(
((chan->channel - 4800) / 20 << 2), 8);
((freq - 4800) / 20 << 2), 8);
aModeRefSel = ath_hal_reverseBits(3, 2);
} else if ((chan->channel % 10) == 0) {
} else if ((freq % 10) == 0) {
channelSel = ath_hal_reverseBits(
((chan->channel - 4800) / 10 << 1), 8);
((freq - 4800) / 10 << 1), 8);
aModeRefSel = ath_hal_reverseBits(2, 2);
} else if ((chan->channel % 5) == 0) {
} else if ((freq % 5) == 0) {
channelSel = ath_hal_reverseBits(
(chan->channel - 4800) / 5, 8);
(freq - 4800) / 5, 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",
__func__, chan->channel);
__func__, freq);
return AH_FALSE;
}
@ -175,7 +175,8 @@ ar5112GetRfBank(struct ath_hal *ah, int bank)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
ar5112SetRfRegs(struct ath_hal *ah,
const struct ieee80211_channel *chan,
uint16_t modesIndex, uint16_t *rfXpdGain)
{
#define RF_BANK_SETUP(_priv, _ix, _col) do { \
@ -183,6 +184,7 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
for (i = 0; i < N(ar5212Bank##_ix##_5112); i++) \
(_priv)->Bank##_ix##Data[i] = ar5212Bank##_ix##_5112[i][_col];\
} while (0)
uint16_t freq = ath_hal_gethwchannel(ah, chan);
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
uint16_t rfXpdSel, gainI;
@ -194,20 +196,22 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
HALASSERT(priv);
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
__func__, chan->ic_freq, chan->ic_flags, modesIndex);
/* Setup rf parameters */
switch (chan->channelFlags & CHANNEL_ALL) {
case CHANNEL_A:
case CHANNEL_T:
if (chan->channel > 4000 && chan->channel < 5260) {
switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
case IEEE80211_CHAN_A:
if (freq > 4000 && freq < 5260) {
ob5GHz = ee->ee_ob1;
db5GHz = ee->ee_db1;
} else if (chan->channel >= 5260 && chan->channel < 5500) {
} else if (freq >= 5260 && freq < 5500) {
ob5GHz = ee->ee_ob2;
db5GHz = ee->ee_db2;
} else if (chan->channel >= 5500 && chan->channel < 5725) {
} else if (freq >= 5500 && freq < 5725) {
ob5GHz = ee->ee_ob3;
db5GHz = ee->ee_db3;
} else if (chan->channel >= 5725) {
} else if (freq >= 5725) {
ob5GHz = ee->ee_ob4;
db5GHz = ee->ee_db4;
} else {
@ -216,14 +220,14 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
rfXpdSel = ee->ee_xpd[headerInfo11A];
gainI = ee->ee_gainI[headerInfo11A];
break;
case CHANNEL_B:
case IEEE80211_CHAN_B:
ob2GHz = ee->ee_ob2GHz[0];
db2GHz = ee->ee_db2GHz[0];
rfXpdSel = ee->ee_xpd[headerInfo11B];
gainI = ee->ee_gainI[headerInfo11B];
break;
case CHANNEL_G:
case CHANNEL_108G:
case IEEE80211_CHAN_G:
case IEEE80211_CHAN_PUREG: /* NB: really 108G */
ob2GHz = ee->ee_ob2GHz[1];
db2GHz = ee->ee_ob2GHz[1];
rfXpdSel = ee->ee_xpd[headerInfo11G];
@ -231,7 +235,7 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
__func__, chan->ic_flags);
return AH_FALSE;
}
@ -252,7 +256,7 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
ar5212ModifyRfBuffer(priv->Bank6Data, rfXpdGain[0], 2, 270, 0);
ar5212ModifyRfBuffer(priv->Bank6Data, rfXpdGain[1], 2, 257, 0);
if (IS_CHAN_OFDM(chan)) {
if (IEEE80211_IS_CHAN_OFDM(chan)) {
ar5212ModifyRfBuffer(priv->Bank6Data,
gv->currStep->paramVal[GP_PWD_138], 1, 168, 3);
ar5212ModifyRfBuffer(priv->Bank6Data,
@ -268,7 +272,7 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
}
/* Only the 5 or 2 GHz OB/DB need to be set for a mode */
if (IS_CHAN_2GHZ(chan)) {
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ar5212ModifyRfBuffer(priv->Bank6Data, ob2GHz, 3, 287, 0);
ar5212ModifyRfBuffer(priv->Bank6Data, db2GHz, 3, 290, 0);
} else {
@ -296,18 +300,18 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
/* Setup Bank 7 Setup */
RF_BANK_SETUP(priv, 7, modesIndex);
if (IS_CHAN_OFDM(chan))
if (IEEE80211_IS_CHAN_OFDM(chan))
ar5212ModifyRfBuffer(priv->Bank7Data,
gv->currStep->paramVal[GP_MIXGAIN_OVR], 2, 37, 0);
ar5212ModifyRfBuffer(priv->Bank7Data, gainI, 6, 14, 0);
/* Adjust params for Derby TX power control */
if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) {
if (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan)) {
uint32_t rfDelay, rfPeriod;
rfDelay = 0xf;
rfPeriod = (IS_CHAN_HALF_RATE(chan)) ? 0x8 : 0xf;
rfPeriod = (IEEE80211_IS_CHAN_HALF(chan)) ? 0x8 : 0xf;
ar5212ModifyRfBuffer(priv->Bank7Data, rfDelay, 4, 58, 0);
ar5212ModifyRfBuffer(priv->Bank7Data, rfPeriod, 4, 70, 0);
}
@ -338,9 +342,11 @@ ar5112SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
*/
static HAL_BOOL
ar5112SetPowerTable(struct ath_hal *ah,
int16_t *pPowerMin, int16_t *pPowerMax, HAL_CHANNEL_INTERNAL *chan,
int16_t *pPowerMin, int16_t *pPowerMax,
const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
uint32_t numXpdGain = IS_RADX112_REV2(ah) ? 2 : 1;
@ -367,24 +373,24 @@ ar5112SetPowerTable(struct ath_hal *ah,
uint16_t xgainList[2];
uint16_t xpdMask;
switch (chan->channelFlags & CHANNEL_ALL) {
case CHANNEL_A:
case CHANNEL_T:
switch (chan->ic_flags & IEEE80211_CHAN_ALLTURBOFULL) {
case IEEE80211_CHAN_A:
case IEEE80211_CHAN_ST:
pPowerExpn = &ee->ee_modePowerArray5112[headerInfo11A];
xpdGainMask = ee->ee_xgain[headerInfo11A];
break;
case CHANNEL_B:
case IEEE80211_CHAN_B:
pPowerExpn = &ee->ee_modePowerArray5112[headerInfo11B];
xpdGainMask = ee->ee_xgain[headerInfo11B];
break;
case CHANNEL_G:
case CHANNEL_108G:
case IEEE80211_CHAN_G:
case IEEE80211_CHAN_108G:
pPowerExpn = &ee->ee_modePowerArray5112[headerInfo11G];
xpdGainMask = ee->ee_xgain[headerInfo11G];
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown channel flags 0x%x\n",
__func__, chan->channelFlags & CHANNEL_ALL);
__func__, chan->ic_flags);
return AH_FALSE;
}
@ -416,7 +422,7 @@ ar5112SetPowerTable(struct ath_hal *ah,
}
}
ar5212GetLowerUpperIndex(chan->channel, &pPowerExpn->pChannels[0],
ar5212GetLowerUpperIndex(freq, &pPowerExpn->pChannels[0],
pPowerExpn->numChannels, &chan_idx_L, &chan_idx_R);
kk = 0;
@ -474,7 +480,7 @@ ar5112SetPowerTable(struct ath_hal *ah,
if (xgainList[1] == 0xDEAD) {
for (jj = 0; jj < 64; jj++) {
pwr_table0[jj] = interpolate_signed(
chan->channel, chan_L, chan_R,
freq, chan_L, chan_R,
powTableLXPD[0][jj], powTableLXPD[kk][jj]);
}
Pmin = getPminAndPcdacTableFromPowerTable(&pwr_table0[0],
@ -487,10 +493,10 @@ ar5112SetPowerTable(struct ath_hal *ah,
} else {
for (jj = 0; jj < 64; jj++) {
pwr_table0[jj] = interpolate_signed(
chan->channel, chan_L, chan_R,
freq, chan_L, chan_R,
powTableLXPD[0][jj], powTableLXPD[kk][jj]);
pwr_table1[jj] = interpolate_signed(
chan->channel, chan_L, chan_R,
freq, chan_L, chan_R,
powTableHXPD[0][jj], powTableHXPD[kk][jj]);
}
if (numXpdGain == 2) {
@ -757,9 +763,11 @@ ar5112GetMinPower(struct ath_hal *ah, const EXPN_DATA_PER_CHANNEL_5112 *data)
}
static HAL_BOOL
ar5112GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
ar5112GetChannelMaxMinPower(struct ath_hal *ah,
const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
uint16_t freq = chan->ic_freq; /* NB: never mapped */
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
int numChannels=0,i,last;
int totalD, totalF,totalMin;
@ -767,16 +775,16 @@ ar5112GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
const EEPROM_POWER_EXPN_5112 *powerArray=AH_NULL;
*maxPow = 0;
if (IS_CHAN_A(chan)) {
if (IEEE80211_IS_CHAN_A(chan)) {
powerArray = ee->ee_modePowerArray5112;
data = powerArray[headerInfo11A].pDataPerChannel;
numChannels = powerArray[headerInfo11A].numChannels;
} else if (IS_CHAN_G(chan) || IS_CHAN_108G(chan)) {
} else if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan)) {
/* XXX - is this correct? Should we also use the same power for turbo G? */
powerArray = ee->ee_modePowerArray5112;
data = powerArray[headerInfo11G].pDataPerChannel;
numChannels = powerArray[headerInfo11G].numChannels;
} else if (IS_CHAN_B(chan)) {
} else if (IEEE80211_IS_CHAN_B(chan)) {
powerArray = ee->ee_modePowerArray5112;
data = powerArray[headerInfo11B].pDataPerChannel;
numChannels = powerArray[headerInfo11B].numChannels;
@ -789,9 +797,9 @@ ar5112GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
if (numChannels < 1)
return(AH_FALSE);
if ((chan->channel < data[0].channelValue) ||
(chan->channel > data[numChannels-1].channelValue)) {
if (chan->channel < data[0].channelValue) {
if ((freq < data[0].channelValue) ||
(freq > data[numChannels-1].channelValue)) {
if (freq < data[0].channelValue) {
*maxPow = data[0].maxPower_t4;
*minPow = ar5112GetMinPower(ah, &data[0]);
return(AH_TRUE);
@ -804,18 +812,18 @@ ar5112GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
/* Linearly interpolate the power value now */
for (last=0,i=0;
(i<numChannels) && (chan->channel > data[i].channelValue);
(i<numChannels) && (freq > data[i].channelValue);
last=i++);
totalD = data[i].channelValue - data[last].channelValue;
if (totalD > 0) {
totalF = data[i].maxPower_t4 - data[last].maxPower_t4;
*maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) + data[last].maxPower_t4*totalD)/totalD);
*maxPow = (int8_t) ((totalF*(freq-data[last].channelValue) + data[last].maxPower_t4*totalD)/totalD);
totalMin = ar5112GetMinPower(ah,&data[i]) - ar5112GetMinPower(ah, &data[last]);
*minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) + ar5112GetMinPower(ah, &data[last])*totalD)/totalD);
*minPow = (int8_t) ((totalMin*(freq-data[last].channelValue) + ar5112GetMinPower(ah, &data[last])*totalD)/totalD);
return (AH_TRUE);
} else {
if (chan->channel == data[i].channelValue) {
if (freq == data[i].channelValue) {
*maxPow = data[i].maxPower_t4;
*minPow = ar5112GetMinPower(ah, &data[i]);
return(AH_TRUE);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5212.h,v 1.16 2008/11/22 07:42:00 sam Exp $
* $FreeBSD$
*/
#ifndef _ATH_AR5212_H_
#define _ATH_AR5212_H_
@ -133,16 +133,18 @@ typedef struct RfHalFuncs {
void (*rfDetach)(struct ath_hal *ah);
void (*writeRegs)(struct ath_hal *,
u_int modeIndex, u_int freqIndex, int regWrites);
u_int modeIndex, u_int freqIndex, int regWrites);
uint32_t *(*getRfBank)(struct ath_hal *ah, int bank);
HAL_BOOL (*setChannel)(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
HAL_BOOL (*setChannel)(struct ath_hal *,
const struct ieee80211_channel *);
HAL_BOOL (*setRfRegs)(struct ath_hal *,
HAL_CHANNEL_INTERNAL *, uint16_t modesIndex,
const struct ieee80211_channel *, uint16_t modesIndex,
uint16_t *rfXpdGain);
HAL_BOOL (*setPowerTable)(struct ath_hal *ah,
int16_t *minPower, int16_t *maxPower,
HAL_CHANNEL_INTERNAL *, uint16_t *rfXpdGain);
HAL_BOOL (*getChannelMaxMinPower)(struct ath_hal *ah, HAL_CHANNEL *,
const struct ieee80211_channel *, uint16_t *rfXpdGain);
HAL_BOOL (*getChannelMaxMinPower)(struct ath_hal *ah,
const const struct ieee80211_channel *,
int16_t *maxPow, int16_t *minPow);
int16_t (*getNfAdjust)(struct ath_hal *, const HAL_CHANNEL_INTERNAL*);
} RF_HAL_FUNCS;
@ -186,8 +188,6 @@ struct ar5212AniState {
uint32_t listenTime;
/* NB: intentionally ordered so data exported to user space is first */
HAL_CHANNEL c;
HAL_BOOL isSetup; /* has state to do a restore */
uint32_t txFrameCount; /* Last txFrameCount */
uint32_t rxFrameCount; /* Last rx Frame count */
uint32_t cycleCount; /* Last cycleCount
@ -319,7 +319,7 @@ struct ath_hal_5212 {
struct ar5212AniParams ah_aniParams24; /* 2.4GHz parameters */
struct ar5212AniParams ah_aniParams5; /* 5GHz parameters */
struct ar5212AniState *ah_curani; /* cached last reference */
struct ar5212AniState ah_ani[64]; /* per-channel state */
struct ar5212AniState ah_ani[AH_MAXCHAN]; /* per-channel state */
/*
* Transmit power state. Note these are maintained
@ -395,16 +395,16 @@ struct ath_hal_5212 {
*/
#define SAVE_CCK(_ah, _chan, _flag) do { \
if ((IS_2425(_ah) || IS_2417(_ah)) && \
(((_chan)->channelFlags) & CHANNEL_CCK)) { \
(_chan)->channelFlags &= ~CHANNEL_CCK; \
(_chan)->channelFlags |= CHANNEL_OFDM; \
(((_chan)->ic_flags) & IEEE80211_CHAN_CCK)) { \
(_chan)->ic_flags &= ~IEEE80211_CHAN_CCK; \
(_chan)->ic_flags |= IEEE80211_CHAN_DYN; \
(_flag) = AH_TRUE; \
} \
} while (0)
#define RESTORE_CCK(_ah, _chan, _flag) do { \
if ((IS_2425(_ah) || IS_2417(_ah)) && (_flag) == AH_TRUE) {\
(_chan)->channelFlags &= ~CHANNEL_OFDM; \
(_chan)->channelFlags |= CHANNEL_CCK; \
if ((IS_2425(_ah) || IS_2417(_ah)) && (_flag)) { \
(_chan)->ic_flags &= ~IEEE80211_CHAN_DYN; \
(_chan)->ic_flags |= IEEE80211_CHAN_CCK; \
} \
} while (0)
@ -525,26 +525,32 @@ extern HAL_STATUS ar5212ProcRxDesc(struct ath_hal *ah, struct ath_desc *,
struct ath_rx_status *);
extern HAL_BOOL ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status);
extern HAL_BOOL ar5212SetChannel(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
struct ieee80211_channel *chan, HAL_BOOL bChannelChange,
HAL_STATUS *status);
extern HAL_BOOL ar5212SetChannel(struct ath_hal *,
const struct ieee80211_channel *);
extern void ar5212SetOperatingMode(struct ath_hal *ah, int opmode);
extern HAL_BOOL ar5212PhyDisable(struct ath_hal *ah);
extern HAL_BOOL ar5212Disable(struct ath_hal *ah);
extern HAL_BOOL ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *);
extern HAL_BOOL ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan,
HAL_BOOL *isIQdone);
extern HAL_BOOL ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
extern HAL_BOOL ar5212ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan);
extern HAL_BOOL ar5212ChipReset(struct ath_hal *ah,
const struct ieee80211_channel *);
extern HAL_BOOL ar5212PerCalibration(struct ath_hal *ah,
struct ieee80211_channel *chan, HAL_BOOL *isIQdone);
extern HAL_BOOL ar5212PerCalibrationN(struct ath_hal *ah,
struct ieee80211_channel *chan, u_int chainMask,
HAL_BOOL longCal, HAL_BOOL *isCalDone);
extern HAL_BOOL ar5212ResetCalValid(struct ath_hal *ah,
const struct ieee80211_channel *);
extern int16_t ar5212GetNoiseFloor(struct ath_hal *ah);
extern void ar5212InitNfCalHistBuffer(struct ath_hal *);
extern int16_t ar5212GetNfHistMid(const int16_t calData[]);
extern void ar5212SetSpurMitigation(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
extern void ar5212SetSpurMitigation(struct ath_hal *,
const struct ieee80211_channel *);
extern HAL_BOOL ar5212SetAntennaSwitchInternal(struct ath_hal *ah,
HAL_ANT_SETTING settings, const HAL_CHANNEL_INTERNAL *ichan);
HAL_ANT_SETTING settings, const struct ieee80211_channel *);
extern HAL_BOOL ar5212SetTxPowerLimit(struct ath_hal *ah, uint32_t limit);
extern HAL_BOOL ar5212GetChipPowerLimits(struct ath_hal *ah,
HAL_CHANNEL *chans, uint32_t nchans);
struct ieee80211_channel *chan);
extern void ar5212InitializeGainValues(struct ath_hal *);
extern HAL_RFGAIN ar5212GetRfgain(struct ath_hal *ah);
extern void ar5212RequestRfgain(struct ath_hal *);
@ -597,7 +603,7 @@ extern void ar5212AniPhyErrReport(struct ath_hal *ah,
const struct ath_rx_status *rs);
extern void ar5212ProcessMibIntr(struct ath_hal *, const HAL_NODE_STATS *);
extern void ar5212AniPoll(struct ath_hal *, const HAL_NODE_STATS *,
HAL_CHANNEL *);
extern void ar5212AniReset(struct ath_hal *, HAL_CHANNEL_INTERNAL *,
const struct ieee80211_channel *);
extern void ar5212AniReset(struct ath_hal *, const struct ieee80211_channel *,
HAL_OPMODE, int);
#endif /* _ATH_AR5212_H_ */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -98,43 +98,6 @@ disableAniMIBCounters(struct ath_hal *ah)
OS_REG_WRITE(ah, AR_PHYCNTMASK2, 0);
}
/*
* This routine returns the index into the aniState array that
* corresponds to the channel in *chan. If no match is found and the
* array is still not fully utilized, a new entry is created for the
* channel. We assume the attach function has already initialized the
* ah_ani values and only the channel field needs to be set.
*/
static int
ar5212GetAniChannelIndex(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
struct ath_hal_5212 *ahp = AH5212(ah);
int i;
for (i = 0; i < N(ahp->ah_ani); i++) {
struct ar5212AniState *asp = &ahp->ah_ani[i];
if (asp->c.channel == chan->channel)
return i;
if (asp->c.channel == 0) {
asp->c.channel = chan->channel;
asp->c.channelFlags = chan->channelFlags;
asp->c.privFlags = chan->privFlags;
asp->isSetup = AH_FALSE;
if (IS_CHAN_2GHZ(chan))
asp->params = &ahp->ah_aniParams24;
else
asp->params = &ahp->ah_aniParams5;
return i;
}
}
/* XXX statistic */
HALDEBUG(ah, HAL_DEBUG_ANY,
"No more channel states left. Using channel 0\n");
return 0; /* XXX gotta return something valid */
#undef N
}
/*
* Return the current ANI state of the channel we're on
*/
@ -421,7 +384,7 @@ static void
ar5212AniOfdmErrTrigger(struct ath_hal *ah)
{
struct ath_hal_5212 *ahp = AH5212(ah);
HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
struct ar5212AniState *aniState;
const struct ar5212AniParams *params;
@ -504,8 +467,7 @@ ar5212AniOfdmErrTrigger(struct ath_hal *ah)
* weak signal detection and zero firstepLevel to
* maximize CCK sensitivity
*/
/* XXX can optimize */
if (IS_CHAN_B(chan) || IS_CHAN_G(chan)) {
if (IEEE80211_IS_CHAN_CCK(chan)) {
if (!aniState->ofdmWeakSigDetectOff) {
HALDEBUG(ah, HAL_DEBUG_ANI,
"%s: rssi %d OWSD off\n",
@ -532,7 +494,7 @@ static void
ar5212AniCckErrTrigger(struct ath_hal *ah)
{
struct ath_hal_5212 *ahp = AH5212(ah);
HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
struct ar5212AniState *aniState;
const struct ar5212AniParams *params;
@ -572,7 +534,8 @@ ar5212AniCckErrTrigger(struct ath_hal *ah)
* CCK sensitivity in 11b/g mode.
*/
/* XXX can optimize */
if (IS_CHAN_B(chan) || IS_CHAN_G(chan)) {
if (IEEE80211_IS_CHAN_B(chan) ||
IEEE80211_IS_CHAN_G(chan)) {
if (aniState->firstepLevel > 0) {
HALDEBUG(ah, HAL_DEBUG_ANI,
"%s: rssi %d zero ST (was %u)\n",
@ -613,31 +576,35 @@ ar5212AniRestart(struct ath_hal *ah, struct ar5212AniState *aniState)
/*
* Restore/reset the ANI parameters and reset the statistics.
* This routine must be called for every channel change.
*
* NOTE: This is where ah_curani is set; other ani code assumes
* it is setup to reflect the current channel.
*/
void
ar5212AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
ar5212AniReset(struct ath_hal *ah, const struct ieee80211_channel *chan,
HAL_OPMODE opmode, int restore)
{
struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212AniState *aniState;
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
/* XXX bounds check ic_devdata */
struct ar5212AniState *aniState = &ahp->ah_ani[chan->ic_devdata];
uint32_t rxfilter;
int index;
index = ar5212GetAniChannelIndex(ah, chan);
aniState = &ahp->ah_ani[index];
if ((ichan->privFlags & CHANNEL_ANI_INIT) == 0) {
OS_MEMZERO(aniState, sizeof(*aniState));
if (IEEE80211_IS_CHAN_2GHZ(chan))
aniState->params = &ahp->ah_aniParams24;
else
aniState->params = &ahp->ah_aniParams5;
ichan->privFlags |= CHANNEL_ANI_INIT;
HALASSERT((ichan->privFlags & CHANNEL_ANI_SETUP) == 0);
}
ahp->ah_curani = aniState;
#if 0
ath_hal_printf(ah,"%s: chan %u/0x%x restore %d setup %d opmode %u\n",
__func__, chan->channel, chan->channelFlags, restore,
aniState->isSetup, opmode);
ath_hal_printf(ah,"%s: chan %u/0x%x restore %d opmode %u%s\n",
__func__, chan->ic_freq, chan->ic_flags, restore, opmode,
ichan->privFlags & CHANNEL_ANI_SETUP ? " setup" : "");
#else
HALDEBUG(ah, HAL_DEBUG_ANI,
"%s: chan %u/0x%x restore %d setup %d opmode %u\n",
__func__, chan->channel, chan->channelFlags, restore,
aniState->isSetup, opmode);
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: chan %u/0x%x restore %d opmode %u%s\n",
__func__, chan->ic_freq, chan->ic_flags, restore, opmode,
ichan->privFlags & CHANNEL_ANI_SETUP ? " setup" : "");
#endif
OS_MARK(ah, AH_MARK_ANI_RESET, opmode);
@ -659,7 +626,7 @@ ar5212AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
* XXX if ANI follows hardware, we don't care what mode we're
* XXX in, we should keep the ani parameters
*/
if (restore && aniState->isSetup) {
if (restore && (ichan->privFlags & CHANNEL_ANI_SETUP)) {
ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
aniState->noiseImmunityLevel);
ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
@ -677,7 +644,7 @@ ar5212AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
AH_TRUE);
ar5212AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR, AH_FALSE);
ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
aniState->isSetup = AH_TRUE;
ichan->privFlags |= CHANNEL_ANI_SETUP;
}
ar5212AniRestart(ah, aniState);
@ -953,7 +920,7 @@ updateMIBStats(struct ath_hal *ah, struct ar5212AniState *aniState)
*/
void
ar5212AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
HAL_CHANNEL *chan)
const struct ieee80211_channel *chan)
{
struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212AniState *aniState = ahp->ah_curani;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5212_attach.c,v 1.18 2008/11/19 22:10:42 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -32,7 +32,6 @@
static const struct ath_hal_private ar5212hal = {{
.ah_magic = AR5212_MAGIC,
.ah_abi = HAL_ABI_VERSION,
.ah_countryCode = CTRY_DEFAULT,
.ah_getRateTable = ar5212GetRateTable,
.ah_detach = ar5212Detach,
@ -653,12 +652,12 @@ HAL_BOOL
ar5212GetChannelEdges(struct ath_hal *ah,
uint16_t flags, uint16_t *low, uint16_t *high)
{
if (flags & CHANNEL_5GHZ) {
if (flags & IEEE80211_CHAN_5GHZ) {
*low = 4915;
*high = 6100;
return AH_TRUE;
}
if ((flags & CHANNEL_2GHZ) &&
if ((flags & IEEE80211_CHAN_2GHZ) &&
(ath_hal_eepromGetFlag(ah, AR_EEP_BMODE) ||
ath_hal_eepromGetFlag(ah, AR_EEP_GMODE))) {
*low = 2312;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -34,8 +34,6 @@
#define AR_NUM_GPIO 6 /* 6 GPIO pins */
#define AR_GPIOD_MASK 0x0000002F /* GPIO data reg r/w mask */
extern void ar5212SetRateDurationTable(struct ath_hal *, HAL_CHANNEL *);
void
ar5212GetMacAddress(struct ath_hal *ah, uint8_t *mac)
{
@ -294,12 +292,12 @@ ar5212ResetTsf(struct ath_hal *ah)
void
ar5212SetBasicRate(struct ath_hal *ah, HAL_RATE_SET *rs)
{
HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
uint32_t reg;
uint8_t xset;
int i;
if (chan == AH_NULL || !IS_CHAN_CCK(chan))
if (chan == AH_NULL || !IEEE80211_IS_CHAN_CCK(chan))
return;
xset = 0;
for (i = 0; i < rs->rs_count; i++) {
@ -423,15 +421,15 @@ HAL_BOOL
ar5212SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING setting)
{
struct ath_hal_5212 *ahp = AH5212(ah);
const HAL_CHANNEL_INTERNAL *ichan = AH_PRIVATE(ah)->ah_curchan;
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
if (!ahp->ah_phyPowerOn || ichan == AH_NULL) {
if (!ahp->ah_phyPowerOn || chan == AH_NULL) {
/* PHY powered off, just stash settings */
ahp->ah_antControl = setting;
ahp->ah_diversity = (setting == HAL_ANT_VARIABLE);
return AH_TRUE;
}
return ar5212SetAntennaSwitchInternal(ah, setting, ichan);
return ar5212SetAntennaSwitchInternal(ah, setting, chan);
}
HAL_BOOL
@ -453,7 +451,7 @@ ar5212SetSifsTime(struct ath_hal *ah, u_int us)
} else {
/* convert to system clocks */
OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, ath_hal_mac_clks(ah, us));
ahp->ah_sifstime = us;
ahp->ah_slottime = us;
return AH_TRUE;
}
}
@ -592,7 +590,7 @@ ar5212SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
return;
/* Don't apply coverage class to non A channels */
if (!IS_CHAN_A(AH_PRIVATE(ah)->ah_curchan))
if (!IEEE80211_IS_CHAN_A(AH_PRIVATE(ah)->ah_curchan))
return;
/* Get core clock rate */
@ -601,10 +599,10 @@ ar5212SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
/* Compute EIFS */
slot = coverageclass * 3 * clkRate;
eifs = coverageclass * 6 * clkRate;
if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {
if (IEEE80211_IS_CHAN_HALF(AH_PRIVATE(ah)->ah_curchan)) {
slot += IFS_SLOT_HALF_RATE;
eifs += IFS_EIFS_HALF_RATE;
} else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {
} else if (IEEE80211_IS_CHAN_QUARTER(AH_PRIVATE(ah)->ah_curchan)) {
slot += IFS_SLOT_QUARTER_RATE;
eifs += IFS_EIFS_QUARTER_RATE;
} else { /* full rate */

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5212_xmit.c,v 1.7 2008/11/10 04:08:03 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -263,7 +263,7 @@ ar5212ResetTxQueue(struct ath_hal *ah, u_int q)
{
struct ath_hal_5212 *ahp = AH5212(ah);
HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
HAL_TX_QUEUE_INFO *qi;
uint32_t cwMin, chanCwMin, value, qmisc, dmisc;
@ -286,7 +286,7 @@ ar5212ResetTxQueue(struct ath_hal *ah, u_int q)
* Select cwmin according to channel type.
* NB: chan can be NULL during attach
*/
if (chan && IS_CHAN_B(chan))
if (chan && IEEE80211_IS_CHAN_B(chan))
chanCwMin = INIT_CWMIN_11B;
else
chanCwMin = INIT_CWMIN;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5413.c,v 1.8 2008/11/15 22:15:46 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -75,29 +75,29 @@ ar5413WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
ar5413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar5413SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint16_t freq = ath_hal_gethwchannel(ah, chan);
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
uint32_t aModeRefSel = 0;
uint32_t reg32 = 0;
uint16_t freq;
OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
OS_MARK(ah, AH_MARK_SETCHANNEL, freq);
if (chan->channel < 4800) {
if (freq < 4800) {
uint32_t txctl;
if (((chan->channel - 2192) % 5) == 0) {
channelSel = ((chan->channel - 672) * 2 - 3040)/10;
if (((freq - 2192) % 5) == 0) {
channelSel = ((freq - 672) * 2 - 3040)/10;
bModeSynth = 0;
} else if (((chan->channel - 2224) % 5) == 0) {
channelSel = ((chan->channel - 704) * 2 - 3040) / 10;
} else if (((freq - 2224) % 5) == 0) {
channelSel = ((freq - 704) * 2 - 3040) / 10;
bModeSynth = 1;
} else {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u MHz\n",
__func__, chan->channel);
__func__, freq);
return AH_FALSE;
}
@ -105,7 +105,7 @@ ar5413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
channelSel = ath_hal_reverseBits(channelSel, 8);
txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
if (chan->channel == 2484) {
if (freq == 2484) {
/* Enable channel spreading for channel 14 */
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
@ -113,26 +113,26 @@ ar5413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
}
} else if (((chan->channel % 5) == 2) && (chan->channel <= 5435)) {
freq = chan->channel - 2; /* Align to even 5MHz raster */
} else if (((freq % 5) == 2) && (freq <= 5435)) {
freq = freq - 2; /* Align to even 5MHz raster */
channelSel = ath_hal_reverseBits(
(uint32_t)(((freq - 4800)*10)/25 + 1), 8);
aModeRefSel = ath_hal_reverseBits(0, 2);
} else if ((chan->channel % 20) == 0 && chan->channel >= 5120) {
} else if ((freq % 20) == 0 && freq >= 5120) {
channelSel = ath_hal_reverseBits(
((chan->channel - 4800) / 20 << 2), 8);
((freq - 4800) / 20 << 2), 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else if ((chan->channel % 10) == 0) {
} else if ((freq % 10) == 0) {
channelSel = ath_hal_reverseBits(
((chan->channel - 4800) / 10 << 1), 8);
((freq - 4800) / 10 << 1), 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else if ((chan->channel % 5) == 0) {
} else if ((freq % 5) == 0) {
channelSel = ath_hal_reverseBits(
(chan->channel - 4800) / 5, 8);
(freq - 4800) / 5, 8);
aModeRefSel = ath_hal_reverseBits(1, 2);
} else {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",
__func__, chan->channel);
__func__, freq);
return AH_FALSE;
}
@ -154,7 +154,9 @@ ar5413SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
ar5413SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIndex, uint16_t *rfXpdGain)
ar5413SetRfRegs(struct ath_hal *ah,
const struct ieee80211_channel *chan,
uint16_t modesIndex, uint16_t *rfXpdGain)
{
#define RF_BANK_SETUP(_priv, _ix, _col) do { \
int i; \
@ -162,50 +164,49 @@ ar5413SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
(_priv)->Bank##_ix##Data[i] = ar5212Bank##_ix##_5413[i][_col];\
} while (0)
struct ath_hal_5212 *ahp = AH5212(ah);
uint16_t freq = ath_hal_gethwchannel(ah, chan);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
uint16_t ob5GHz = 0, db5GHz = 0;
uint16_t ob2GHz = 0, db2GHz = 0;
struct ar5413State *priv = AR5413(ah);
int regWrites = 0;
HALDEBUG(ah, HAL_DEBUG_RFPARAM,
"%s: chan 0x%x flag 0x%x modesIndex 0x%x\n",
__func__, chan->channel, chan->channelFlags, modesIndex);
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan %u/0x%x modesIndex %u\n",
__func__, chan->ic_freq, chan->ic_flags, modesIndex);
HALASSERT(priv != AH_NULL);
/* Setup rf parameters */
switch (chan->channelFlags & CHANNEL_ALL) {
case CHANNEL_A:
case CHANNEL_T:
if (chan->channel > 4000 && chan->channel < 5260) {
switch (chan->ic_flags & IEEE80211_CHAN_ALLFULL) {
case IEEE80211_CHAN_A:
if (freq > 4000 && freq < 5260) {
ob5GHz = ee->ee_ob1;
db5GHz = ee->ee_db1;
} else if (chan->channel >= 5260 && chan->channel < 5500) {
} else if (freq >= 5260 && freq < 5500) {
ob5GHz = ee->ee_ob2;
db5GHz = ee->ee_db2;
} else if (chan->channel >= 5500 && chan->channel < 5725) {
} else if (freq >= 5500 && freq < 5725) {
ob5GHz = ee->ee_ob3;
db5GHz = ee->ee_db3;
} else if (chan->channel >= 5725) {
} else if (freq >= 5725) {
ob5GHz = ee->ee_ob4;
db5GHz = ee->ee_db4;
} else {
/* XXX else */
}
break;
case CHANNEL_B:
case IEEE80211_CHAN_B:
ob2GHz = ee->ee_obFor24;
db2GHz = ee->ee_dbFor24;
break;
case CHANNEL_G:
case CHANNEL_108G:
case IEEE80211_CHAN_G:
case IEEE80211_CHAN_PUREG: /* NB: really 108G */
ob2GHz = ee->ee_obFor24g;
db2GHz = ee->ee_dbFor24g;
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
__func__, chan->ic_flags);
return AH_FALSE;
}
@ -222,7 +223,7 @@ ar5413SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t modesIn
RF_BANK_SETUP(priv, 6, modesIndex);
/* Only the 5 or 2 GHz OB/DB need to be set for a mode */
if (IS_CHAN_2GHZ(chan)) {
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ar5212ModifyRfBuffer(priv->Bank6Data, ob2GHz, 3, 241, 0);
ar5212ModifyRfBuffer(priv->Bank6Data, db2GHz, 3, 238, 0);
@ -537,10 +538,12 @@ ar5413getGainBoundariesAndPdadcsForPowers(struct ath_hal *ah, uint16_t channel,
static HAL_BOOL
ar5413SetPowerTable(struct ath_hal *ah,
int16_t *minPower, int16_t *maxPower, HAL_CHANNEL_INTERNAL *chan,
int16_t *minPower, int16_t *maxPower,
const struct ieee80211_channel *chan,
uint16_t *rfXpdGain)
{
struct ath_hal_5212 *ahp = AH5212(ah);
uint16_t freq = ath_hal_gethwchannel(ah, chan);
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2413 *pRawDataset = AH_NULL;
uint16_t pdGainOverlap_t2;
@ -554,14 +557,14 @@ ar5413SetPowerTable(struct ath_hal *ah,
#endif
HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: chan 0x%x flag 0x%x\n",
__func__, chan->channel,chan->channelFlags);
__func__, chan->ic_freq, chan->ic_flags);
if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
else if (IS_CHAN_B(chan))
else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else {
HALASSERT(IS_CHAN_5GHZ(chan));
HALASSERT(IEEE80211_IS_CHAN_5GHZ(chan));
pRawDataset = &ee->ee_rawDataset2413[headerInfo11A];
}
@ -569,7 +572,7 @@ ar5413SetPowerTable(struct ath_hal *ah,
AR_PHY_TPCRG5_PD_GAIN_OVERLAP);
numPdGainsUsed = ar5413getGainBoundariesAndPdadcsForPowers(ah,
chan->channel, pRawDataset, pdGainOverlap_t2,
freq, pRawDataset, pdGainOverlap_t2,
&minCalPower5413_t2,gainBoundaries, rfXpdGain, pdadcValues);
HALASSERT(1 <= numPdGainsUsed && numPdGainsUsed <= 3);
@ -676,9 +679,11 @@ ar5413GetMaxPower(struct ath_hal *ah, const RAW_DATA_PER_CHANNEL_2413 *data)
}
static HAL_BOOL
ar5413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
ar5413GetChannelMaxMinPower(struct ath_hal *ah,
const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
uint16_t freq = chan->ic_freq; /* NB: never mapped */
const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
const RAW_DATA_STRUCT_2413 *pRawDataset = AH_NULL;
const RAW_DATA_PER_CHANNEL_2413 *data=AH_NULL;
@ -687,12 +692,12 @@ ar5413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
*maxPow = 0;
if (IS_CHAN_G(chan) || IS_CHAN_108G(chan))
if (IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_108G(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11G];
else if (IS_CHAN_B(chan))
else if (IEEE80211_IS_CHAN_B(chan))
pRawDataset = &ee->ee_rawDataset2413[headerInfo11B];
else {
HALASSERT(IS_CHAN_5GHZ(chan));
HALASSERT(IEEE80211_IS_CHAN_5GHZ(chan));
pRawDataset = &ee->ee_rawDataset2413[headerInfo11A];
}
@ -705,9 +710,9 @@ ar5413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
if (numChannels < 1)
return(AH_FALSE);
if ((chan->channel < data[0].channelValue) ||
(chan->channel > data[numChannels-1].channelValue)) {
if (chan->channel < data[0].channelValue) {
if ((freq < data[0].channelValue) ||
(freq > data[numChannels-1].channelValue)) {
if (freq < data[0].channelValue) {
*maxPow = ar5413GetMaxPower(ah, &data[0]);
*minPow = ar5413GetMinPower(ah, &data[0]);
return(AH_TRUE);
@ -719,19 +724,19 @@ ar5413GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan,
}
/* Linearly interpolate the power value now */
for (last=0,i=0; (i<numChannels) && (chan->channel > data[i].channelValue);
for (last=0,i=0; (i<numChannels) && (freq > data[i].channelValue);
last = i++);
totalD = data[i].channelValue - data[last].channelValue;
if (totalD > 0) {
totalF = ar5413GetMaxPower(ah, &data[i]) - ar5413GetMaxPower(ah, &data[last]);
*maxPow = (int8_t) ((totalF*(chan->channel-data[last].channelValue) +
*maxPow = (int8_t) ((totalF*(freq-data[last].channelValue) +
ar5413GetMaxPower(ah, &data[last])*totalD)/totalD);
totalMin = ar5413GetMinPower(ah, &data[i]) - ar5413GetMinPower(ah, &data[last]);
*minPow = (int8_t) ((totalMin*(chan->channel-data[last].channelValue) +
*minPow = (int8_t) ((totalMin*(freq-data[last].channelValue) +
ar5413GetMinPower(ah, &data[last])*totalD)/totalD);
return(AH_TRUE);
} else {
if (chan->channel == data[i].channelValue) {
if (freq == data[i].channelValue) {
*maxPow = ar5413GetMaxPower(ah, &data[i]);
*minPow = ar5413GetMinPower(ah, &data[i]);
return(AH_TRUE);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -60,8 +60,10 @@ extern void ar5312SetupClock(struct ath_hal *ah, HAL_OPMODE opmode);
extern void ar5312RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode);
extern void ar5312DumpState(struct ath_hal *ah);
extern HAL_BOOL ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status);
extern HAL_BOOL ar5312ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan);
struct ieee80211_channel *chan,
HAL_BOOL bChannelChange, HAL_STATUS *status);
extern HAL_BOOL ar5312ChipReset(struct ath_hal *ah,
struct ieee80211_channel *chan);
extern HAL_BOOL ar5312SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode,
int setChip);
extern HAL_BOOL ar5312PhyDisable(struct ath_hal *ah);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -34,15 +34,21 @@
#define BASE_ACTIVATE_DELAY 100 /* 100 usec */
#define PLL_SETTLE_DELAY 300 /* 300 usec */
extern int16_t ar5212GetNf(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
extern void ar5212SetRateDurationTable(struct ath_hal *, HAL_CHANNEL *);
extern int16_t ar5212GetNf(struct ath_hal *, const struct ieee80211_channel *);
extern void ar5212SetRateDurationTable(struct ath_hal *,
const struct ieee80211_channel *);
extern HAL_BOOL ar5212SetTransmitPower(struct ath_hal *ah,
HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain);
extern void ar5212SetDeltaSlope(struct ath_hal *, HAL_CHANNEL *);
extern HAL_BOOL ar5212SetBoardValues(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
extern void ar5212SetIFSTiming(struct ath_hal *, HAL_CHANNEL *);
extern HAL_BOOL ar5212IsSpurChannel(struct ath_hal *, HAL_CHANNEL *);
extern HAL_BOOL ar5212ChannelChange(struct ath_hal *, HAL_CHANNEL *);
const struct ieee80211_channel *chan, uint16_t *rfXpdGain);
extern void ar5212SetDeltaSlope(struct ath_hal *,
const struct ieee80211_channel *);
extern HAL_BOOL ar5212SetBoardValues(struct ath_hal *,
const struct ieee80211_channel *);
extern void ar5212SetIFSTiming(struct ath_hal *,
const struct ieee80211_channel *);
extern HAL_BOOL ar5212IsSpurChannel(struct ath_hal *,
const struct ieee80211_channel *);
extern HAL_BOOL ar5212ChannelChange(struct ath_hal *,
const struct ieee80211_channel *);
static HAL_BOOL ar5312SetResetReg(struct ath_hal *, uint32_t resetMask);
@ -81,7 +87,8 @@ write_common(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
*/
HAL_BOOL
ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status)
struct ieee80211_channel *chan,
HAL_BOOL bChannelChange, HAL_STATUS *status)
{
#define N(a) (sizeof (a) / sizeof (a[0]))
#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
@ -102,20 +109,6 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
ee = AH_PRIVATE(ah)->ah_eeprom;
OS_MARK(ah, AH_MARK_RESET, bChannelChange);
#define IS(_c,_f) (((_c)->channelFlags & _f) || 0)
if ((IS(chan, CHANNEL_2GHZ) ^ IS(chan, CHANNEL_5GHZ)) == 0) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
__func__, chan->channel, chan->channelFlags);
FAIL(HAL_EINVAL);
}
if ((IS(chan, CHANNEL_OFDM) ^ IS(chan, CHANNEL_CCK)) == 0) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; not marked as OFDM or CCK\n",
__func__, chan->channel, chan->channelFlags);
FAIL(HAL_EINVAL);
}
#undef IS
/*
* Map public channel to private.
*/
@ -123,7 +116,7 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; no mapping\n",
__func__, chan->channel, chan->channelFlags);
__func__, chan->ic_freq, chan->ic_flags);
FAIL(HAL_EINVAL);
}
switch (opmode) {
@ -176,10 +169,10 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
* -the modes of the previous and requested channel are the same - some ugly code for XR
*/
if (bChannelChange &&
(AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
(chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) &&
((chan->channelFlags & CHANNEL_ALL) ==
(AH_PRIVATE(ah)->ah_curchan->channelFlags & CHANNEL_ALL))) {
AH_PRIVATE(ah)->ah_curchan != AH_NULL &&
(chan->ic_freq != AH_PRIVATE(ah)->ah_curchan->ic_freq) &&
((chan->ic_flags & IEEE80211_CHAN_ALLTURBO) ==
(AH_PRIVATE(ah)->ah_curchan->ic_flags & IEEE80211_CHAN_ALLTURBO))) {
if (ar5212ChannelChange(ah, chan))
/* If ChannelChange completed - skip the rest of reset */
return AH_TRUE;
@ -217,31 +210,13 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
}
/* Setup the indices for the next set of register array writes */
switch (chan->channelFlags & CHANNEL_ALL) {
case CHANNEL_A:
modesIndex = 1;
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
freqIndex = 2;
modesIndex = IEEE80211_IS_CHAN_108G(chan) ? 5 :
IEEE80211_IS_CHAN_G(chan) ? 4 : 3;
} else {
freqIndex = 1;
break;
case CHANNEL_T:
modesIndex = 2;
freqIndex = 1;
break;
case CHANNEL_B:
modesIndex = 3;
freqIndex = 2;
break;
case CHANNEL_PUREG:
modesIndex = 4;
freqIndex = 2;
break;
case CHANNEL_108G:
modesIndex = 5;
freqIndex = 2;
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
FAIL(HAL_EINVAL);
modesIndex = IEEE80211_IS_CHAN_ST(chan) ? 2 : 1;
}
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
@ -256,9 +231,8 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) {
if (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))
ar5212SetIFSTiming(ah, chan);
}
/* Overwrite INI values for revised chipsets */
if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) {
@ -276,7 +250,7 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
cckOfdmPwrDelta = SCALE_OC_DELTA(ee->ee_cckOfdmPwrDelta);
}
if (IS_CHAN_G(chan)) {
if (IEEE80211_IS_CHAN_G(chan)) {
OS_REG_WRITE(ah, AR_PHY_TXPWRADJ,
SM((ee->ee_cckOfdmPwrDelta*-1), AR_PHY_TXPWRADJ_CCK_GAIN_DELTA) |
SM((cckOfdmPwrDelta*-1), AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX));
@ -315,18 +289,18 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
SM(0x16, AR_PHY_SIGMA_DELTA_FILT1) |
SM(0, AR_PHY_SIGMA_DELTA_ADC_CLIP));
if (IS_CHAN_2GHZ(chan))
if (IEEE80211_IS_CHAN_2GHZ(chan))
OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN, AR_PHY_RXGAIN_TXRX_RF_MAX, 0x0F);
/* CCK Short parameter adjustment in 11B mode */
if (IS_CHAN_B(chan))
if (IEEE80211_IS_CHAN_B(chan))
OS_REG_RMW_FIELD(ah, AR_PHY_CCK_RXCTRL4, AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT, 12);
/* Set ADC/DAC select values */
OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x04);
/* Increase 11A AGC Settling */
if ((chan->channelFlags & CHANNEL_ALL) == CHANNEL_A)
if (IEEE80211_IS_CHAN_A(chan))
OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_AGC, 32);
} else {
/* Set ADC/DAC select values */
@ -334,29 +308,29 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
}
/* Setup the transmit power values. */
if (!ar5212SetTransmitPower(ah, ichan, rfXpdGain)) {
if (!ar5212SetTransmitPower(ah, chan, rfXpdGain)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: error init'ing transmit power\n", __func__);
FAIL(HAL_EIO);
}
/* Write the analog registers */
if (!ahp->ah_rfHal->setRfRegs(ah, ichan, modesIndex, rfXpdGain)) {
if (!ahp->ah_rfHal->setRfRegs(ah, chan, modesIndex, rfXpdGain)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5212SetRfRegs failed\n",
__func__);
FAIL(HAL_EIO);
}
/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
if (IS_CHAN_OFDM(chan)) {
if ((IS_5413(ah) || (AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)) &&
(!IS_CHAN_B(chan)))
ar5212SetSpurMitigation(ah, ichan);
if (IEEE80211_IS_CHAN_OFDM(chan)) {
if (IS_5413(ah) ||
AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)
ar5212SetSpurMitigation(ah, chan);
ar5212SetDeltaSlope(ah, chan);
}
/* Setup board specific options for EEPROM version 3 */
if (!ar5212SetBoardValues(ah, ichan)) {
if (!ar5212SetBoardValues(ah, chan)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: error setting board options\n", __func__);
FAIL(HAL_EIO);
@ -396,7 +370,7 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
if (!ar5212SetChannel(ah, ichan))
if (!ar5212SetChannel(ah, chan))
FAIL(HAL_EIO);
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
@ -407,10 +381,9 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
/* Set Tx frame start to tx data start delay */
if (IS_RAD5112_ANY(ah) &&
(IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan) ||
IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan))) {
(IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))) {
txFrm2TxDStart =
(IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) ?
IEEE80211_IS_CHAN_HALF(chan) ?
TX_FRAME_D_START_HALF_RATE:
TX_FRAME_D_START_QUARTER_RATE;
OS_REG_RMW_FIELD(ah, AR_PHY_TX_CTL,
@ -445,7 +418,7 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
* Value is in 100ns increments.
*/
synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
if (IS_CHAN_CCK(chan)) {
if (IEEE80211_IS_CHAN_B(chan)) {
synthDelay = (4 * synthDelay) / 22;
} else {
synthDelay /= 10;
@ -461,9 +434,9 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
* extra BASE_ACTIVATE_DELAY usecs to ensure this condition
* does not happen.
*/
if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {
if (IEEE80211_IS_CHAN_HALF(chan)) {
OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY);
} else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {
} else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY);
} else {
OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
@ -487,7 +460,7 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
| AR_PHY_AGC_CONTROL_CAL
| AR_PHY_AGC_CONTROL_NF);
if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) {
if (!IEEE80211_IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) {
/* Start IQ calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
@ -583,12 +556,8 @@ ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
if (bChannelChange) {
if (!(ichan->privFlags & CHANNEL_DFS))
ichan->privFlags &= ~CHANNEL_INTERFERENCE;
chan->channelFlags = ichan->channelFlags;
chan->privFlags = ichan->privFlags;
}
if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan))
chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
@ -639,10 +608,10 @@ ar5312Disable(struct ath_hal *ah)
* WARNING: The order of the PLL and mode registers must be correct.
*/
HAL_BOOL
ar5312ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
ar5312ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0);
OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
/*
* Reset the HW
@ -683,50 +652,49 @@ ar5312ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
if (IS_RAD5112_ANY(ah)) {
rfMode = AR_PHY_MODE_AR5112;
if (!IS_5315(ah)) {
if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
if (IEEE80211_IS_CHAN_CCK(chan)) {
phyPLL = AR_PHY_PLL_CTL_44_5312;
} else {
if (IS_CHAN_HALF_RATE(chan)) {
if (IEEE80211_IS_CHAN_HALF(chan)) {
phyPLL = AR_PHY_PLL_CTL_40_5312_HALF;
} else if (IS_CHAN_QUARTER_RATE(chan)) {
} else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
phyPLL = AR_PHY_PLL_CTL_40_5312_QUARTER;
} else {
phyPLL = AR_PHY_PLL_CTL_40_5312;
}
}
} else {
if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
if (IEEE80211_IS_CHAN_CCK(chan))
phyPLL = AR_PHY_PLL_CTL_44_5112;
else
phyPLL = AR_PHY_PLL_CTL_40_5112;
if (IS_CHAN_HALF_RATE(chan))
if (IEEE80211_IS_CHAN_HALF(chan))
phyPLL |= AR_PHY_PLL_CTL_HALF;
else if (IS_CHAN_QUARTER_RATE(chan))
else if (IEEE80211_IS_CHAN_QUARTER(chan))
phyPLL |= AR_PHY_PLL_CTL_QUARTER;
}
} else {
rfMode = AR_PHY_MODE_AR5111;
if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
if (IEEE80211_IS_CHAN_CCK(chan))
phyPLL = AR_PHY_PLL_CTL_44;
else
phyPLL = AR_PHY_PLL_CTL_40;
if (IS_CHAN_HALF_RATE(chan))
if (IEEE80211_IS_CHAN_HALF(chan))
phyPLL = AR_PHY_PLL_CTL_HALF;
else if (IS_CHAN_QUARTER_RATE(chan))
else if (IEEE80211_IS_CHAN_QUARTER(chan))
phyPLL = AR_PHY_PLL_CTL_QUARTER;
}
if (IS_CHAN_OFDM(chan) && (IS_CHAN_CCK(chan) ||
IS_CHAN_G(chan)))
if (IEEE80211_IS_CHAN_G(chan))
rfMode |= AR_PHY_MODE_DYNAMIC;
else if (IS_CHAN_OFDM(chan))
else if (IEEE80211_IS_CHAN_OFDM(chan))
rfMode |= AR_PHY_MODE_OFDM;
else
rfMode |= AR_PHY_MODE_CCK;
if (IS_CHAN_5GHZ(chan))
if (IEEE80211_IS_CHAN_5GHZ(chan))
rfMode |= AR_PHY_MODE_RF5GHZ;
else
rfMode |= AR_PHY_MODE_RF2GHZ;
turbo = IS_CHAN_TURBO(chan) ?
turbo = IEEE80211_IS_CHAN_TURBO(chan) ?
(AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT) : 0;
curPhyPLL = OS_REG_READ(ah, AR_PHY_PLL_CTL);
/*
@ -736,7 +704,7 @@ ar5312ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
* mode bit is set
* - Turbo cannot be set at the same time as CCK or DYNAMIC
*/
if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
if (IEEE80211_IS_CHAN_CCK(chan)) {
OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
if (curPhyPLL != phyPLL) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar2133.c,v 1.13 2008/11/11 00:11:30 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -46,14 +46,8 @@ struct ar2133State {
#define ar5416ModifyRfBuffer ar5212ModifyRfBuffer /*XXX*/
extern void ar5416ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32,
uint32_t numBits, uint32_t firstBit, uint32_t column);
HAL_BOOL ar2133GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL
*chans, uint32_t nchans);
static HAL_BOOL ar2133GetChannelMaxMinPower(struct ath_hal *, HAL_CHANNEL *,
int16_t *maxPow,int16_t *minPow);
int16_t ar2133GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c);
void ar5416ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32,
uint32_t numBits, uint32_t firstBit, uint32_t column);
static void
ar2133WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
@ -69,7 +63,7 @@ ar2133WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex,
* ASSUMES: Writes enabled to analog bus
*/
static HAL_BOOL
ar2133SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar2133SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
uint32_t channelSel = 0;
uint32_t bModeSynth = 0;
@ -78,9 +72,9 @@ ar2133SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
uint16_t freq;
CHAN_CENTERS centers;
OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);
OS_MARK(ah, AH_MARK_SETCHANNEL, chan->ic_freq);
ar5416GetChannelCenters(ah, chan, &centers);
ar5416GetChannelCenters(ah, chan, &centers);
freq = centers.synth_center;
if (freq < 4800) {
@ -169,7 +163,7 @@ ar2133GetRfBank(struct ath_hal *ah, int bank)
* REQUIRES: Access to the analog rf device
*/
static HAL_BOOL
ar2133SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
ar2133SetRfRegs(struct ath_hal *ah, const struct ieee80211_channel *chan,
uint16_t modesIndex, uint16_t *rfXpdGain)
{
struct ar2133State *priv = AR2133(ah);
@ -193,7 +187,7 @@ ar2133SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
ath_hal_ini_bank_setup(priv->Bank6Data, &AH5416(ah)->ah_ini_bank6, modesIndex);
/* Only the 5 or 2 GHz OB/DB need to be set for a mode */
if (IS_CHAN_2GHZ(chan)) {
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ar5416ModifyRfBuffer(priv->Bank6Data,
ath_hal_eepromGet(ah, AR_EEP_OB_2, AH_NULL), 3, 197, 0);
ar5416ModifyRfBuffer(priv->Bank6Data,
@ -233,7 +227,7 @@ ar2133SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
static HAL_BOOL
ar2133SetPowerTable(struct ath_hal *ah, int16_t *pPowerMin, int16_t *pPowerMax,
HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain)
const struct ieee80211_channel *chan, uint16_t *rfXpdGain)
{
return AH_TRUE;
}
@ -267,8 +261,9 @@ ar2133GetMinPower(struct ath_hal *ah, EXPN_DATA_PER_CHANNEL_5112 *data)
#endif
static HAL_BOOL
ar2133GetChannelMaxMinPower(struct ath_hal *ah, HAL_CHANNEL *chan, int16_t *maxPow,
int16_t *minPow)
ar2133GetChannelMaxMinPower(struct ath_hal *ah,
const struct ieee80211_channel *chan,
int16_t *maxPow, int16_t *minPow)
{
#if 0
struct ath_hal_5212 *ahp = AH5212(ah);
@ -390,7 +385,7 @@ ar2133GetNoiseFloor(struct ath_hal *ah, int16_t nfarray[])
* Adjust NF based on statistical values for 5GHz frequencies.
* Stubbed:Not used by Fowl
*/
int16_t
static int16_t
ar2133GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c)
{
return 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5416.h,v 1.19 2008/11/11 21:38:13 sam Exp $
* $FreeBSD$
*/
#ifndef _ATH_AR5416_H_
#define _ATH_AR5416_H_
@ -92,7 +92,8 @@ extern void ar5416Detach(struct ath_hal *ah);
extern HAL_BOOL ar5416FillCapabilityInfo(struct ath_hal *ah);
#define IS_5GHZ_FAST_CLOCK_EN(_ah, _c) \
(IS_CHAN_5GHZ(_c) && ath_hal_eepromGetFlag(ah, AR_EEP_FSTCLK_5G))
(IEEE80211_IS_CHAN_5GHZ(_c) && \
ath_hal_eepromGetFlag(ah, AR_EEP_FSTCLK_5G))
extern void ar5416AniAttach(struct ath_hal *, const struct ar5212AniParams *,
const struct ar5212AniParams *, HAL_BOOL ena);
@ -102,8 +103,8 @@ extern HAL_BOOL ar5416AniSetParams(struct ath_hal *,
const struct ar5212AniParams *, const struct ar5212AniParams *);
extern void ar5416ProcessMibIntr(struct ath_hal *, const HAL_NODE_STATS *);
extern void ar5416AniPoll(struct ath_hal *, const HAL_NODE_STATS *,
HAL_CHANNEL *);
extern void ar5416AniReset(struct ath_hal *, HAL_CHANNEL_INTERNAL *,
const struct ieee80211_channel *);
extern void ar5416AniReset(struct ath_hal *, const struct ieee80211_channel *,
HAL_OPMODE, int);
extern void ar5416SetBeaconTimers(struct ath_hal *, const HAL_BEACON_TIMERS *);
@ -160,17 +161,19 @@ extern HAL_STATUS ar5416ProcRxDesc(struct ath_hal *ah, struct ath_desc *,
struct ath_rx_status *);
extern HAL_BOOL ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status);
struct ieee80211_channel *chan,
HAL_BOOL bChannelChange, HAL_STATUS *status);
extern HAL_BOOL ar5416PhyDisable(struct ath_hal *ah);
extern HAL_RFGAIN ar5416GetRfgain(struct ath_hal *ah);
extern HAL_BOOL ar5416Disable(struct ath_hal *ah);
extern HAL_BOOL ar5416ChipReset(struct ath_hal *ah, HAL_CHANNEL *);
extern HAL_BOOL ar5416ChipReset(struct ath_hal *ah,
const struct ieee80211_channel *);
extern HAL_BOOL ar5416SetResetReg(struct ath_hal *, uint32_t type);
extern HAL_BOOL ar5416SetTxPowerLimit(struct ath_hal *ah, uint32_t limit);
extern HAL_BOOL ar5416GetChipPowerLimits(struct ath_hal *ah,
HAL_CHANNEL *chans, uint32_t nchans);
struct ieee80211_channel *chan);
extern void ar5416GetChannelCenters(struct ath_hal *,
HAL_CHANNEL_INTERNAL *chan, CHAN_CENTERS *centers);
const struct ieee80211_channel *chan, CHAN_CENTERS *centers);
extern HAL_BOOL ar5416StopTxDma(struct ath_hal *ah, u_int q);
extern HAL_BOOL ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5416_ani.c,v 1.1 2008/11/11 20:46:06 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -102,43 +102,6 @@ disableAniMIBCounters(struct ath_hal *ah)
OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, 0);
}
/*
* This routine returns the index into the aniState array that
* corresponds to the channel in *chan. If no match is found and the
* array is still not fully utilized, a new entry is created for the
* channel. We assume the attach function has already initialized the
* ah_ani values and only the channel field needs to be set.
*/
static int
ar5416GetAniChannelIndex(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
struct ath_hal_5212 *ahp = AH5212(ah);
int i;
for (i = 0; i < N(ahp->ah_ani); i++) {
struct ar5212AniState *asp = &ahp->ah_ani[i];
if (asp->c.channel == chan->channel)
return i;
if (asp->c.channel == 0) {
asp->c.channel = chan->channel;
asp->c.channelFlags = chan->channelFlags;
asp->c.privFlags = chan->privFlags;
asp->isSetup = AH_FALSE;
if (IS_CHAN_2GHZ(chan))
asp->params = &ahp->ah_aniParams24;
else
asp->params = &ahp->ah_aniParams5;
return i;
}
}
/* XXX statistic */
HALDEBUG(ah, HAL_DEBUG_ANY,
"No more channel states left. Using channel 0\n");
return 0; /* XXX gotta return something valid */
#undef N
}
static void
setPhyErrBase(struct ath_hal *ah, struct ar5212AniParams *params)
{
@ -374,7 +337,7 @@ static void
ar5416AniOfdmErrTrigger(struct ath_hal *ah)
{
struct ath_hal_5212 *ahp = AH5212(ah);
HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
struct ar5212AniState *aniState;
const struct ar5212AniParams *params;
@ -441,8 +404,7 @@ ar5416AniOfdmErrTrigger(struct ath_hal *ah)
* weak signal detection and zero firstepLevel to
* maximize CCK sensitivity
*/
/* XXX can optimize */
if (IS_CHAN_B(chan) || IS_CHAN_G(chan)) {
if (IEEE80211_IS_CHAN_CCK(chan)) {
if (!aniState->ofdmWeakSigDetectOff)
ar5416AniControl(ah,
HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
@ -460,7 +422,7 @@ static void
ar5416AniCckErrTrigger(struct ath_hal *ah)
{
struct ath_hal_5212 *ahp = AH5212(ah);
HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
struct ar5212AniState *aniState;
const struct ar5212AniParams *params;
@ -493,8 +455,7 @@ ar5416AniCckErrTrigger(struct ath_hal *ah)
* Beacon rssi is low, zero firstep level to maximize
* CCK sensitivity in 11b/g mode.
*/
/* XXX can optimize */
if (IS_CHAN_B(chan) || IS_CHAN_G(chan)) {
if (IEEE80211_IS_CHAN_CCK(chan)) {
if (aniState->firstepLevel > 0)
ar5416AniControl(ah,
HAL_ANI_FIRSTEP_LEVEL, 0);
@ -536,26 +497,33 @@ ar5416AniRestart(struct ath_hal *ah, struct ar5212AniState *aniState)
* it is setup to reflect the current channel.
*/
void
ar5416AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
ar5416AniReset(struct ath_hal *ah, const struct ieee80211_channel *chan,
HAL_OPMODE opmode, int restore)
{
struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212AniState *aniState;
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
/* XXX bounds check ic_devdata */
struct ar5212AniState *aniState = &ahp->ah_ani[chan->ic_devdata];
uint32_t rxfilter;
int index;
index = ar5416GetAniChannelIndex(ah, chan);
aniState = &ahp->ah_ani[index];
if ((ichan->privFlags & CHANNEL_ANI_INIT) == 0) {
OS_MEMZERO(aniState, sizeof(*aniState));
if (IEEE80211_IS_CHAN_2GHZ(chan))
aniState->params = &ahp->ah_aniParams24;
else
aniState->params = &ahp->ah_aniParams5;
ichan->privFlags |= CHANNEL_ANI_INIT;
HALASSERT((ichan->privFlags & CHANNEL_ANI_SETUP) == 0);
}
ahp->ah_curani = aniState;
#if 0
ath_hal_printf(ah,"%s: chan %u/0x%x restore %d setup %d opmode %u\n",
__func__, chan->channel, chan->channelFlags, restore,
aniState->isSetup, opmode);
ath_hal_printf(ah,"%s: chan %u/0x%x restore %d opmode %u%s\n",
__func__, chan->ic_freq, chan->ic_flags, restore, opmode,
ichan->privFlags & CHANNEL_ANI_SETUP ? " setup" : "");
#else
HALDEBUG(ah, HAL_DEBUG_ANI,
"%s: chan %u/0x%x restore %d setup %d opmode %u\n",
__func__, chan->channel, chan->channelFlags, restore,
aniState->isSetup, opmode);
HALDEBUG(ah, HAL_DEBUG_ANI, "%s: chan %u/0x%x restore %d opmode %u%s\n",
__func__, chan->ic_freq, chan->ic_flags, restore, opmode,
ichan->privFlags & CHANNEL_ANI_SETUP ? " setup" : "");
#endif
OS_MARK(ah, AH_MARK_ANI_RESET, opmode);
@ -577,7 +545,7 @@ ar5416AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
* XXX if ANI follows hardware, we don't care what mode we're
* XXX in, we should keep the ani parameters
*/
if (restore && aniState->isSetup) {
if (restore && (ichan->privFlags & CHANNEL_ANI_SETUP)) {
ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
aniState->noiseImmunityLevel);
ar5416AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
@ -595,7 +563,7 @@ ar5416AniReset(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
AH_TRUE);
ar5416AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR, AH_FALSE);
ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
aniState->isSetup = AH_TRUE;
ichan->privFlags |= CHANNEL_ANI_SETUP;
}
ar5416AniRestart(ah, aniState);
@ -831,7 +799,7 @@ updateMIBStats(struct ath_hal *ah, struct ar5212AniState *aniState)
*/
void
ar5416AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
HAL_CHANNEL *chan)
const struct ieee80211_channel *chan)
{
struct ath_hal_5212 *ahp = AH5212(ah);
struct ar5212AniState *aniState = ahp->ah_curani;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5416_cal.c,v 1.7 2008/11/11 17:43:23 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"
@ -32,26 +32,27 @@
#define NUM_NOISEFLOOR_READINGS 6 /* 3 chains * (ctl + ext) */
static void ar5416StartNFCal(struct ath_hal *ah);
static void ar5416LoadNF(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *);
static int16_t ar5416GetNf(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
static void ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *);
static int16_t ar5416GetNf(struct ath_hal *, struct ieee80211_channel *);
/*
* Determine if calibration is supported by device and channel flags
*/
static OS_INLINE HAL_BOOL
ar5416IsCalSupp(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_CAL_TYPE calType)
ar5416IsCalSupp(struct ath_hal *ah, const struct ieee80211_channel *chan,
HAL_CAL_TYPE calType)
{
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
switch (calType & cal->suppCals) {
case IQ_MISMATCH_CAL:
/* Run IQ Mismatch for non-CCK only */
return !IS_CHAN_B(chan);
return !IEEE80211_IS_CHAN_B(chan);
case ADC_GAIN_CAL:
case ADC_DC_CAL:
/* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */
return !IS_CHAN_B(chan) &&
!(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan));
return !IEEE80211_IS_CHAN_B(chan) &&
!(IEEE80211_IS_CHAN_2GHZ(chan) && IEEE80211_IS_CHAN_HT20(chan));
}
return AH_FALSE;
}
@ -164,7 +165,7 @@ ar5416RunInitCals(struct ath_hal *ah, int init_cal_count)
* Initialize Calibration infrastructure.
*/
HAL_BOOL
ar5416InitCal(struct ath_hal *ah, HAL_CHANNEL *chan)
ar5416InitCal(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
HAL_CHANNEL_INTERNAL *ichan;
@ -279,7 +280,7 @@ ar5416InitCal(struct ath_hal *ah, HAL_CHANNEL *chan)
* Reset the calibration valid bit in channel.
*/
HAL_BOOL
ar5416ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
ar5416ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
@ -292,7 +293,7 @@ ar5416ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; no mapping\n",
__func__, chan->channel, chan->channelFlags);
__func__, chan->ic_freq, chan->ic_flags);
return AH_FALSE;
}
/*
@ -312,8 +313,8 @@ ar5416ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
HALDEBUG(ah, HAL_DEBUG_PERCAL,
"%s: Resetting Cal %d state for channel %u/0x%x\n",
__func__, currCal->calData->calType, chan->channel,
chan->channelFlags);
__func__, currCal->calData->calType, chan->ic_freq,
chan->ic_flags);
/* Disable cal validity in channel */
ichan->calValid &= ~currCal->calData->calType;
@ -384,7 +385,7 @@ ar5416DoCalibration(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan,
* Internal interface to schedule periodic calibration work.
*/
HAL_BOOL
ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
ar5416PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
u_int rxchainmask, HAL_BOOL longcal, HAL_BOOL *isCalDone)
{
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
@ -400,7 +401,7 @@ ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
if (ichan == AH_NULL) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel %u/0x%x; no mapping\n",
__func__, chan->channel, chan->channelFlags);
__func__, chan->ic_freq, chan->ic_flags);
return AH_FALSE;
}
@ -432,7 +433,7 @@ ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
* Get the value from the previous NF cal
* and update the history buffer.
*/
ar5416GetNf(ah, ichan);
ar5416GetNf(ah, chan);
/*
* Load the NF from history buffer of the current channel.
@ -443,12 +444,6 @@ ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
/* start NF calibration, without updating BB NF register*/
ar5416StartNFCal(ah);
if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
/* report up and clear internal state */
chan->channelFlags |= CHANNEL_CW_INT;
ichan->channelFlags &= ~CHANNEL_CW_INT;
}
}
return AH_TRUE;
}
@ -458,7 +453,8 @@ ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
* changes.
*/
HAL_BOOL
ar5416PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
ar5416PerCalibration(struct ath_hal *ah, struct ieee80211_channel *chan,
HAL_BOOL *isIQdone)
{
struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416PerCal *cal = &AH5416(ah)->ah_cal;
@ -478,29 +474,19 @@ ar5416PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
static HAL_BOOL
ar5416GetEepromNoiseFloorThresh(struct ath_hal *ah,
const HAL_CHANNEL_INTERNAL *chan, int16_t *nft)
const struct ieee80211_channel *chan, int16_t *nft)
{
switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
case CHANNEL_A:
case CHANNEL_A_HT20:
case CHANNEL_A_HT40PLUS:
case CHANNEL_A_HT40MINUS:
if (IEEE80211_IS_CHAN_5GHZ(chan)) {
ath_hal_eepromGet(ah, AR_EEP_NFTHRESH_5, nft);
break;
case CHANNEL_B:
case CHANNEL_G:
case CHANNEL_G_HT20:
case CHANNEL_G_HT40PLUS:
case CHANNEL_G_HT40MINUS:
ath_hal_eepromGet(ah, AR_EEP_NFTHRESH_2, nft);
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: invalid channel flags 0x%x\n",
__func__, chan->channelFlags);
return AH_FALSE;
return AH_TRUE;
}
return AH_TRUE;
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ath_hal_eepromGet(ah, AR_EEP_NFTHRESH_2, nft);
return AH_TRUE;
}
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
__func__, chan->ic_flags);
return AH_FALSE;
}
static void
@ -512,7 +498,7 @@ ar5416StartNFCal(struct ath_hal *ah)
}
static void
ar5416LoadNF(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
static const uint32_t ar5416_cca_regs[] = {
AR_PHY_CCA,
@ -624,7 +610,7 @@ ar5416UpdateNFHistBuff(struct ar5212NfCalHist *h, int16_t *nfarray)
* Read the NF and check it against the noise floor threshhold
*/
static int16_t
ar5416GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
ar5416GetNf(struct ath_hal *ah, struct ieee80211_channel *chan)
{
int16_t nf, nfThresh;
@ -635,6 +621,7 @@ ar5416GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
} else {
/* Finished NF cal, check against threshold */
int16_t nfarray[NUM_NOISEFLOOR_READINGS] = { 0 };
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
/* TODO - enhance for multiple chains and ext ch */
ath_hal_getNoiseFloor(ah, nfarray);
@ -650,14 +637,14 @@ ar5416GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
* happens it indicates a problem regardless
* of the band.
*/
chan->channelFlags |= CHANNEL_CW_INT;
chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
nf = 0;
}
} else {
nf = 0;
}
ar5416UpdateNFHistBuff(AH5416(ah)->ah_cal.nfCalHist, nfarray);
chan->rawNoiseFloor = nf;
ichan->rawNoiseFloor = nf;
}
return nf;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5416_cal.h,v 1.3 2008/11/11 17:43:23 sam Exp $
* $FreeBSD$
*/
#ifndef _ATH_AR5416_CAL_H_
#define _ATH_AR5416_CAL_H_
@ -102,12 +102,13 @@ struct ar5416PerCal {
} \
} while (0)
HAL_BOOL ar5416InitCal(struct ath_hal *ah, HAL_CHANNEL *chan);
HAL_BOOL ar5416PerCalibration(struct ath_hal *, HAL_CHANNEL *,
HAL_BOOL ar5416InitCal(struct ath_hal *, const struct ieee80211_channel *);
HAL_BOOL ar5416PerCalibration(struct ath_hal *, struct ieee80211_channel *,
HAL_BOOL *isIQdone);
HAL_BOOL ar5416PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan,
HAL_BOOL ar5416PerCalibrationN(struct ath_hal *, struct ieee80211_channel *,
u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone);
HAL_BOOL ar5416ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan);
HAL_BOOL ar5416ResetCalValid(struct ath_hal *,
const struct ieee80211_channel *);
void ar5416IQCalCollect(struct ath_hal *ah);
void ar5416IQCalibration(struct ath_hal *ah, uint8_t numChains);

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2008 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $Id: ar5416_xmit.c,v 1.9 2008/11/27 22:30:08 sam Exp $
* $FreeBSD$
*/
#include "opt_ah.h"

View File

@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
#include <net/if_llc.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_regdomain.h>
#ifdef ATH_SUPPORT_TDMA
#include <net80211/ieee80211_tdma.h>
#endif
@ -116,9 +117,6 @@ CTASSERT(ATH_BCBUF <= 8);
((((u_int8_t *)(p))[0] ) | (((u_int8_t *)(p))[1] << 8) | \
(((u_int8_t *)(p))[2] << 16) | (((u_int8_t *)(p))[3] << 24)))
#define CTRY_XR9 5001 /* Ubiquiti XR9 */
#define CTRY_GZ901 5002 /* ZComax GZ-901 */
static struct ieee80211vap *ath_vap_create(struct ieee80211com *,
const char name[IFNAMSIZ], int unit, int opmode,
int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
@ -661,7 +659,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
sc->sc_hastsfadd = ath_hal_hastsfadjust(ah);
if (ath_hal_hasfastframes(ah))
ic->ic_caps |= IEEE80211_C_FF;
wmodes = ath_hal_getwirelessmodes(ah, ic->ic_regdomain.country);
wmodes = ath_hal_getwirelessmodes(ah);
if (wmodes & (HAL_MODE_108G|HAL_MODE_TURBO))
ic->ic_caps |= IEEE80211_C_TURBOP;
#ifdef ATH_SUPPORT_TDMA
@ -1203,7 +1201,7 @@ ath_resume(struct ath_softc *sc)
* Must reset the chip before we reload the
* keycache as we were powered down on suspend.
*/
ath_hal_reset(ah, sc->sc_opmode, &sc->sc_curchan, AH_FALSE, &status);
ath_hal_reset(ah, sc->sc_opmode, sc->sc_curchan, AH_FALSE, &status);
ath_reset_keycache(sc);
if (sc->sc_resume_up) {
if (ic->ic_opmode == IEEE80211_M_STA) {
@ -1422,56 +1420,6 @@ ath_bmiss_proc(void *arg, int pending)
ieee80211_beacon_miss(ifp->if_l2com);
}
/*
* Convert net80211 channel to a HAL channel with the flags
* constrained to reflect the current operating mode and
* the frequency possibly mapped for GSM channels.
*/
static void
ath_mapchan(const struct ieee80211com *ic,
HAL_CHANNEL *hc, const struct ieee80211_channel *chan)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
static const u_int modeflags[IEEE80211_MODE_MAX] = {
0, /* IEEE80211_MODE_AUTO */
CHANNEL_A, /* IEEE80211_MODE_11A */
CHANNEL_B, /* IEEE80211_MODE_11B */
CHANNEL_PUREG, /* IEEE80211_MODE_11G */
0, /* IEEE80211_MODE_FH */
CHANNEL_108A, /* IEEE80211_MODE_TURBO_A */
CHANNEL_108G, /* IEEE80211_MODE_TURBO_G */
CHANNEL_ST, /* IEEE80211_MODE_STURBO_A */
CHANNEL_A, /* IEEE80211_MODE_11NA */
CHANNEL_PUREG, /* IEEE80211_MODE_11NG */
};
enum ieee80211_phymode mode = ieee80211_chan2mode(chan);
KASSERT(mode < N(modeflags), ("unexpected phy mode %u", mode));
KASSERT(modeflags[mode] != 0, ("mode %u undefined", mode));
hc->channelFlags = modeflags[mode];
if (IEEE80211_IS_CHAN_HALF(chan))
hc->channelFlags |= CHANNEL_HALF;
if (IEEE80211_IS_CHAN_QUARTER(chan))
hc->channelFlags |= CHANNEL_QUARTER;
if (IEEE80211_IS_CHAN_HT20(chan))
hc->channelFlags |= CHANNEL_HT20;
if (IEEE80211_IS_CHAN_HT40D(chan))
hc->channelFlags |= CHANNEL_HT40MINUS;
if (IEEE80211_IS_CHAN_HT40U(chan))
hc->channelFlags |= CHANNEL_HT40PLUS;
if (IEEE80211_IS_CHAN_GSM(chan)) {
if (ic->ic_regdomain.country == CTRY_XR9)
hc->channel = 1520 + chan->ic_freq;
else if (ic->ic_regdomain.country == CTRY_GZ901)
hc->channel = 1544 + chan->ic_freq;
else
hc->channel = 3344 - chan->ic_freq;
} else
hc->channel = chan->ic_freq;
#undef N
}
/*
* Handle TKIP MIC setup to deal hardware that doesn't do MIC
* calcs together with WME. If necessary disable the crypto
@ -1521,9 +1469,8 @@ ath_init(void *arg)
* be followed by initialization of the appropriate bits
* and then setup of the interrupt mask.
*/
ath_mapchan(ic, &sc->sc_curchan, ic->ic_curchan);
ath_settkipmic(sc);
if (!ath_hal_reset(ah, sc->sc_opmode, &sc->sc_curchan, AH_FALSE, &status)) {
if (!ath_hal_reset(ah, sc->sc_opmode, ic->ic_curchan, AH_FALSE, &status)) {
if_printf(ifp, "unable to reset hardware; hal status %u\n",
status);
ATH_UNLOCK(sc);
@ -1655,18 +1602,12 @@ ath_reset(struct ifnet *ifp)
struct ath_hal *ah = sc->sc_ah;
HAL_STATUS status;
/*
* Convert to a HAL channel description with the flags
* constrained to reflect the current operating mode.
*/
ath_mapchan(ic, &sc->sc_curchan, ic->ic_curchan);
ath_hal_intrset(ah, 0); /* disable interrupts */
ath_draintxq(sc); /* stop xmit side */
ath_stoprecv(sc); /* stop recv side */
ath_settkipmic(sc); /* configure TKIP MIC handling */
/* NB: indicate channel change so we do a full reset */
if (!ath_hal_reset(ah, sc->sc_opmode, &sc->sc_curchan, AH_TRUE, &status))
if (!ath_hal_reset(ah, sc->sc_opmode, ic->ic_curchan, AH_TRUE, &status))
if_printf(ifp, "%s: unable to reset hardware; hal status %u\n",
__func__, status);
sc->sc_diversity = ath_hal_getdiversity(ah);
@ -3874,13 +3815,11 @@ ath_node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise)
struct ieee80211com *ic = ni->ni_ic;
struct ath_softc *sc = ic->ic_ifp->if_softc;
struct ath_hal *ah = sc->sc_ah;
HAL_CHANNEL hchan;
*rssi = ic->ic_node_getrssi(ni);
if (ni->ni_chan != IEEE80211_CHAN_ANYC) {
ath_mapchan(ic, &hchan, ni->ni_chan);
*noise = ath_hal_getchannoise(ah, &hchan);
} else
if (ni->ni_chan != IEEE80211_CHAN_ANYC)
*noise = ath_hal_getchannoise(ah, ni->ni_chan);
else
*noise = -95; /* nominally correct */
}
@ -4070,9 +4009,11 @@ ath_rx_tap(struct ifnet *ifp, struct mbuf *m,
#ifdef AH_SUPPORT_AR5416
sc->sc_rx_th.wr_chan_flags &= ~CHAN_HT;
if (sc->sc_rx_th.wr_rate & IEEE80211_RATE_MCS) { /* HT rate */
struct ieee80211com *ic = ifp->if_l2com;
if ((rs->rs_flags & HAL_RX_2040) == 0)
sc->sc_rx_th.wr_chan_flags |= CHAN_HT20;
else if (sc->sc_curchan.channelFlags & CHANNEL_HT40PLUS)
else if (IEEE80211_IS_CHAN_HT40U(ic->ic_curchan))
sc->sc_rx_th.wr_chan_flags |= CHAN_HT40U;
else
sc->sc_rx_th.wr_chan_flags |= CHAN_HT40D;
@ -4135,7 +4076,7 @@ ath_rx_proc(void *arg, int npending)
DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending);
ngood = 0;
nf = ath_hal_getchannoise(ah, &sc->sc_curchan);
nf = ath_hal_getchannoise(ah, sc->sc_curchan);
sc->sc_stats.ast_rx_noise = nf;
tsf = ath_hal_gettsf64(ah);
do {
@ -4401,7 +4342,7 @@ ath_rx_proc(void *arg, int npending)
} while (ath_rxbuf_init(sc, bf) == 0);
/* rx signal state monitoring */
ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan);
ath_hal_rxmonitor(ah, &sc->sc_halstats, sc->sc_curchan);
if (ngood)
sc->sc_lastrx = tsf;
@ -5696,6 +5637,7 @@ ath_chan_change(struct ath_softc *sc, struct ieee80211_channel *chan)
mode = ieee80211_chan2mode(chan);
if (mode != sc->sc_curmode)
ath_setcurmode(sc, mode);
sc->sc_curchan = chan;
sc->sc_rx_th.wr_chan_flags = htole32(chan->ic_flags);
sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags;
@ -5719,27 +5661,12 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ath_hal *ah = sc->sc_ah;
HAL_CHANNEL hchan;
/*
* Convert to a HAL channel description with
* the flags constrained to reflect the current
* operating mode.
*/
ath_mapchan(ic, &hchan, chan);
DPRINTF(sc, ATH_DEBUG_RESET,
"%s: %u (%u MHz, hal flags 0x%x) -> %u (%u MHz, hal flags 0x%x)\n",
__func__,
ath_hal_mhz2ieee(ah, sc->sc_curchan.channel,
sc->sc_curchan.channelFlags),
sc->sc_curchan.channel, sc->sc_curchan.channelFlags,
ath_hal_mhz2ieee(ah, hchan.channel, hchan.channelFlags),
hchan.channel, hchan.channelFlags);
if (hchan.channel != sc->sc_curchan.channel ||
hchan.channelFlags != sc->sc_curchan.channelFlags) {
DPRINTF(sc, ATH_DEBUG_RESET, "%s: %u (%u MHz, flags 0x%x)\n",
__func__, ieee80211_chan2ieee(ic, chan),
chan->ic_freq, chan->ic_flags);
if (chan != sc->sc_curchan) {
HAL_STATUS status;
/*
* To switch channels clear any pending DMA operations;
* wait long enough for the RX fifo to drain, reset the
@ -5749,15 +5676,13 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
ath_hal_intrset(ah, 0); /* disable interrupts */
ath_draintxq(sc); /* clear pending tx frames */
ath_stoprecv(sc); /* turn off frame recv */
if (!ath_hal_reset(ah, sc->sc_opmode, &hchan, AH_TRUE, &status)) {
if (!ath_hal_reset(ah, sc->sc_opmode, chan, AH_TRUE, &status)) {
if_printf(ifp, "%s: unable to reset "
"channel %u (%u Mhz, flags 0x%x hal flags 0x%x), "
"hal status %u\n", __func__,
ieee80211_chan2ieee(ic, chan), chan->ic_freq,
chan->ic_flags, hchan.channelFlags, status);
"channel %u (%u Mhz, flags 0x%x), hal status %u\n",
__func__, ieee80211_chan2ieee(ic, chan),
chan->ic_freq, chan->ic_flags, status);
return EIO;
}
sc->sc_curchan = hchan;
sc->sc_diversity = ath_hal_getdiversity(ah);
/*
@ -5817,12 +5742,12 @@ ath_calibrate(void *arg)
* reset the data collection state so we start fresh.
*/
if (sc->sc_resetcal) {
(void) ath_hal_calreset(ah, &sc->sc_curchan);
(void) ath_hal_calreset(ah, sc->sc_curchan);
sc->sc_lastcalreset = ticks;
sc->sc_resetcal = 0;
}
}
if (ath_hal_calibrateN(ah, &sc->sc_curchan, longCal, &isCalDone)) {
if (ath_hal_calibrateN(ah, sc->sc_curchan, longCal, &isCalDone)) {
if (longCal) {
/*
* Calibrate noise floor data again in case of change.
@ -5832,7 +5757,7 @@ ath_calibrate(void *arg)
} else {
DPRINTF(sc, ATH_DEBUG_ANY,
"%s: calibration of channel %u failed\n",
__func__, sc->sc_curchan.channel);
__func__, sc->sc_curchan->ic_freq);
sc->sc_stats.ast_per_calfail++;
}
if (!isCalDone) {
@ -6191,141 +6116,24 @@ ath_newassoc(struct ieee80211_node *ni, int isnew)
}
static int
getchannels(struct ath_softc *sc, int *nchans, struct ieee80211_channel chans[],
int cc, int ecm, int outdoor)
{
struct ath_hal *ah = sc->sc_ah;
HAL_CHANNEL *halchans;
int i, nhalchans, error;
DPRINTF(sc, ATH_DEBUG_REGDOMAIN, "%s: cc %u outdoor %u ecm %u\n",
__func__, cc, outdoor, ecm);
halchans = malloc(IEEE80211_CHAN_MAX * sizeof(HAL_CHANNEL),
M_TEMP, M_NOWAIT | M_ZERO);
if (halchans == NULL) {
device_printf(sc->sc_dev,
"%s: unable to allocate channel table\n", __func__);
return ENOMEM;
}
error = 0;
if (!ath_hal_init_channels(ah, halchans, IEEE80211_CHAN_MAX, &nhalchans,
NULL, 0, NULL, cc, HAL_MODE_ALL, outdoor, ecm)) {
u_int32_t rd;
(void) ath_hal_getregdomain(ah, &rd);
device_printf(sc->sc_dev, "ath_hal_init_channels failed, "
"rd %d cc %u outdoor %u ecm %u\n", rd, cc, outdoor, ecm);
error = EINVAL;
goto done;
}
if (nchans == NULL) /* no table requested */
goto done;
/*
* Convert HAL channels to ieee80211 ones.
*/
for (i = 0; i < nhalchans; i++) {
HAL_CHANNEL *c = &halchans[i];
struct ieee80211_channel *ichan = &chans[i];
ichan->ic_ieee = ath_hal_mhz2ieee(ah, c->channel,
c->channelFlags);
if (bootverbose)
device_printf(sc->sc_dev, "hal channel %u/%x -> %u "
"maxpow %d minpow %d maxreg %d\n",
c->channel, c->channelFlags, ichan->ic_ieee,
c->maxTxPower, c->minTxPower, c->maxRegTxPower);
ichan->ic_freq = c->channel;
if ((c->channelFlags & CHANNEL_PUREG) == CHANNEL_PUREG) {
/*
* Except for AR5211, HAL's PUREG means mixed
* DSSS and OFDM.
*/
ichan->ic_flags = c->channelFlags &~ CHANNEL_PUREG;
ichan->ic_flags |= IEEE80211_CHAN_G;
} else {
ichan->ic_flags = c->channelFlags;
}
if (ath_hal_isgsmsku(ah)) {
/*
* Remap to true frequencies: Ubiquiti XR9 cards use a
* frequency mapping different from their SR9 cards.
* We define special country codes to deal with this.
*/
if (cc == CTRY_XR9)
ichan->ic_freq = ichan->ic_freq - 1520;
else if (cc == CTRY_GZ901)
ichan->ic_freq = ichan->ic_freq - 1544;
else
ichan->ic_freq = 3344 - ichan->ic_freq;
ichan->ic_flags |= IEEE80211_CHAN_GSM;
ichan->ic_ieee = ieee80211_mhz2ieee(ichan->ic_freq,
ichan->ic_flags);
}
ichan->ic_maxregpower = c->maxRegTxPower; /* dBm */
/* XXX: old hal's don't provide maxTxPower for some parts */
ichan->ic_maxpower = (c->maxTxPower != 0) ?
c->maxTxPower : 2*c->maxRegTxPower; /* 1/2 dBm */
ichan->ic_minpower = c->minTxPower; /* 1/2 dBm */
}
*nchans = nhalchans;
done:
free(halchans, M_TEMP);
return error;
}
/* XXX hard to include ieee80211_regdomain.h right now */
#define SKU_DEBUG 0x1ff
static void
ath_maprd(const struct ieee80211_regdomain *rd,
u_int32_t *ath_rd, u_int32_t *ath_cc)
{
/* map SKU's to Atheros sku's */
switch (rd->regdomain) {
case SKU_DEBUG:
if (rd->country == 0) {
*ath_rd = 0;
*ath_cc = CTRY_DEBUG;
return;
}
break;
}
*ath_rd = rd->regdomain;
*ath_cc = rd->country;
}
static int
ath_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
ath_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *reg,
int nchans, struct ieee80211_channel chans[])
{
struct ath_softc *sc = ic->ic_ifp->if_softc;
struct ath_hal *ah = sc->sc_ah;
u_int32_t ord, regdomain, cc;
int error;
HAL_STATUS status;
(void) ath_hal_getregdomain(ah, &ord);
ath_maprd(rd, &regdomain, &cc);
DPRINTF(sc, ATH_DEBUG_REGDOMAIN,
"%s: rd %u cc %u location %c ecm %u (mapped rd %u cc %u)\n",
__func__, rd->regdomain, rd->country, rd->location, rd->ecm,
regdomain, cc);
ath_hal_setregdomain(ah, regdomain);
"%s: rd %u cc %u location %c%s\n",
__func__, reg->regdomain, reg->country, reg->location,
reg->ecm ? " ecm" : "");
error = getchannels(sc, &nchans, chans, cc,
rd->ecm ? AH_TRUE : AH_FALSE,
rd->location != 'I' ? AH_TRUE : AH_FALSE);
if (error != 0) {
/*
* Restore previous state.
*/
ath_hal_setregdomain(ah, ord);
(void) getchannels(sc, NULL, NULL, ic->ic_regdomain.country,
ic->ic_regdomain.ecm ? AH_TRUE : AH_FALSE,
ic->ic_regdomain.location != 'I' ? AH_TRUE : AH_FALSE);
return error;
status = ath_hal_set_channels(ah, chans, nchans,
reg->country, reg->regdomain);
if (status != HAL_OK) {
DPRINTF(sc, ATH_DEBUG_REGDOMAIN, "%s: failed, status %u\n",
__func__, status);
return EINVAL; /* XXX */
}
return 0;
}
@ -6336,43 +6144,14 @@ ath_getradiocaps(struct ieee80211com *ic,
{
struct ath_softc *sc = ic->ic_ifp->if_softc;
struct ath_hal *ah = sc->sc_ah;
u_int32_t ord;
(void) ath_hal_getregdomain(ah, &ord);
DPRINTF(sc, ATH_DEBUG_REGDOMAIN, "%s: use rd %u cc %d\n",
__func__, SKU_DEBUG, CTRY_DEFAULT);
DPRINTF(sc, ATH_DEBUG_REGDOMAIN, "%s: use rd %u cc %d, ord %u\n",
__func__, 0, CTRY_DEBUG, ord);
/* XXX check return */
(void) ath_hal_getchannels(ah, chans, maxchans, nchans,
HAL_MODE_ALL, CTRY_DEFAULT, SKU_DEBUG, AH_TRUE);
ath_hal_setregdomain(ah, 0);
/* XXX not quite right but close enough for now */
getchannels(sc, nchans, chans, CTRY_DEBUG, AH_TRUE, AH_FALSE);
/* NB: restore previous state */
ath_hal_setregdomain(ah, ord);
(void) getchannels(sc, NULL, NULL, ic->ic_regdomain.country,
ic->ic_regdomain.ecm ? AH_TRUE : AH_FALSE,
ic->ic_regdomain.location != 'I' ? AH_TRUE : AH_FALSE);
}
static void
ath_mapsku(u_int32_t ath_rd, u_int32_t ath_cc, struct ieee80211_regdomain *rd)
{
rd->isocc[0] = ' '; /* XXX don't know */
rd->isocc[1] = ' ';
/* map Atheros sku's to SKU's */
switch (ath_rd) {
case 0:
if (ath_cc == CTRY_DEBUG) {
rd->regdomain = SKU_DEBUG;
rd->country = 0;
return;
}
break;
}
/* XXX net80211 types too small */
rd->regdomain = (uint16_t) ath_rd;
rd->country = (uint16_t) ath_cc;
}
static int
@ -6381,33 +6160,35 @@ ath_getchannels(struct ath_softc *sc)
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ath_hal *ah = sc->sc_ah;
int error;
HAL_STATUS status;
/*
* Convert HAL channels to ieee80211 ones.
* Collect channel set based on EEPROM contents.
*/
error = getchannels(sc, &ic->ic_nchans, ic->ic_channels,
CTRY_DEFAULT, AH_TRUE, AH_FALSE);
status = ath_hal_init_channels(ah, ic->ic_channels, IEEE80211_CHAN_MAX,
&ic->ic_nchans, HAL_MODE_ALL, CTRY_DEFAULT, SKU_NONE, AH_TRUE);
if (status != HAL_OK) {
if_printf(ifp, "%s: unable to collect channel list from hal, "
"status %d\n", __func__, status);
return EINVAL;
}
(void) ath_hal_getregdomain(ah, &sc->sc_eerd);
ath_hal_getcountrycode(ah, &sc->sc_eecc); /* NB: cannot fail */
if (error) {
if_printf(ifp, "%s: unable to collect channel list from hal, "
"error %d\n", __func__, error);
if (error == EINVAL) {
if_printf(ifp, "%s: regdomain likely %u country code %u\n",
__func__, sc->sc_eerd, sc->sc_eecc);
}
return error;
}
/* XXX map Atheros sku's to net80211 SKU's */
/* XXX net80211 types too small */
ic->ic_regdomain.regdomain = (uint16_t) sc->sc_eerd;
ic->ic_regdomain.country = (uint16_t) sc->sc_eecc;
ic->ic_regdomain.isocc[0] = ' '; /* XXX don't know */
ic->ic_regdomain.isocc[1] = ' ';
ic->ic_regdomain.ecm = 1;
ic->ic_regdomain.location = 'I';
ath_mapsku(sc->sc_eerd, sc->sc_eecc, &ic->ic_regdomain);
DPRINTF(sc, ATH_DEBUG_REGDOMAIN,
"%s: eeprom rd %u cc %u (mapped rd %u cc %u) location %c ecm %u\n",
"%s: eeprom rd %u cc %u (mapped rd %u cc %u) location %c%s\n",
__func__, sc->sc_eerd, sc->sc_eecc,
ic->ic_regdomain.regdomain, ic->ic_regdomain.country,
ic->ic_regdomain.location, ic->ic_regdomain.ecm);
ic->ic_regdomain.location, ic->ic_regdomain.ecm ? " ecm" : "");
return 0;
}
@ -7470,7 +7251,7 @@ ath_announce(struct ath_softc *sc)
#define HAL_MODE_DUALBAND (HAL_MODE_11A|HAL_MODE_11B)
struct ifnet *ifp = sc->sc_ifp;
struct ath_hal *ah = sc->sc_ah;
u_int modes, cc;
u_int modes;
if_printf(ifp, "mac %d.%d phy %d.%d",
ah->ah_macVersion, ah->ah_macRev,
@ -7480,8 +7261,7 @@ ath_announce(struct ath_softc *sc)
* to avoid falsely printing revs for inoperable parts.
* Dual-band radio revs are returned in the 5Ghz rev number.
*/
ath_hal_getcountrycode(ah, &cc);
modes = ath_hal_getwirelessmodes(ah, cc);
modes = ath_hal_getwirelessmodes(ah);
if ((modes & HAL_MODE_DUALBAND) == HAL_MODE_DUALBAND) {
if (ah->ah_analog5GhzRev && ah->ah_analog2GhzRev)
printf(" 5ghz radio %d.%d 2ghz radio %d.%d",

View File

@ -267,7 +267,7 @@ struct ath_softc {
HAL_OPMODE sc_opmode; /* current operating mode */
u_int16_t sc_curtxpow; /* current tx power limit */
u_int16_t sc_curaid; /* current association id */
HAL_CHANNEL sc_curchan; /* current h/w channel */
struct ieee80211_channel *sc_curchan; /* current installed channel */
u_int8_t sc_curbssid[IEEE80211_ADDR_LEN];
u_int8_t sc_rixmap[256]; /* IEEE to h/w rate table ix */
struct {