#include "opt_ah.h"
#ifdef AH_SUPPORT_AR5312
#include "ah.h"
#include "ah_internal.h"
#include "ah_devid.h"
#include "ar5312/ar5312.h"
#include "ar5312/ar5312reg.h"
#include "ar5312/ar5312phy.h"
#include "ah_eeprom_v3.h"
#define BASE_ACTIVATE_DELAY 100
#define PLL_SETTLE_DELAY 300
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,
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);
static int
write_common(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
HAL_BOOL bChannelChange, int writes)
{
#define IS_NO_RESET_TIMER_ADDR(x) \
( (((x) >= AR_BEACON) && ((x) <= AR_CFP_DUR)) || \
(((x) >= AR_SLEEP1) && ((x) <= AR_SLEEP3)))
#define V(r, c) (ia)->data[((r)*(ia)->cols) + (c)]
int i;
for (i = 0; i < ia->rows; i++) {
uint32_t reg = V(i, 0);
if (!(bChannelChange && IS_NO_RESET_TIMER_ADDR(reg))) {
OS_REG_WRITE(ah, reg, V(i, 1));
DMA_YIELD(writes);
}
}
return writes;
#undef IS_NO_RESET_TIMER_ADDR
#undef V
}
HAL_BOOL
ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
struct ieee80211_channel *chan,
HAL_BOOL bChannelChange,
HAL_RESET_TYPE resetType,
HAL_STATUS *status)
{
#define N(a) (sizeof (a) / sizeof (a[0]))
#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
struct ath_hal_5212 *ahp = AH5212(ah);
HAL_CHANNEL_INTERNAL *ichan;
const HAL_EEPROM *ee;
uint32_t saveFrameSeqCount, saveDefAntenna;
uint32_t macStaId1, synthDelay, txFrm2TxDStart;
uint16_t rfXpdGain[MAX_NUM_PDGAINS_PER_CHANNEL];
int16_t cckOfdmPwrDelta = 0;
u_int modesIndex, freqIndex;
HAL_STATUS ecode;
int i, regWrites = 0;
uint32_t testReg;
uint32_t saveLedState = 0;
HALASSERT(ah->ah_magic == AR5212_MAGIC);
ee = AH_PRIVATE(ah)->ah_eeprom;
OS_MARK(ah, AH_MARK_RESET, bChannelChange);
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->ic_freq, chan->ic_flags);
FAIL(HAL_EINVAL);
}
switch (opmode) {
case HAL_M_STA:
case HAL_M_IBSS:
case HAL_M_HOSTAP:
case HAL_M_MONITOR:
break;
default:
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n",
__func__, opmode);
FAIL(HAL_EINVAL);
break;
}
HALASSERT(ahp->ah_eeversion >= AR_EEPROM_VER3);
if (bChannelChange) {
saveFrameSeqCount = OS_REG_READ(ah, AR_D_SEQNUM);
} else
saveFrameSeqCount = 0;
if ((IS_2413(ah) || IS_5413(ah))) {
if (bChannelChange &&
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))
return AH_TRUE;
}
}
saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
if (saveDefAntenna == 0)
saveDefAntenna = 1;
macStaId1 = OS_REG_READ(ah, AR_STA_ID1) &
(AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT);
if (!IS_5315(ah))
saveLedState = OS_REG_READ(ah, AR5312_PCICFG) &
(AR_PCICFG_LEDCTL | AR_PCICFG_LEDMODE | AR_PCICFG_LEDBLINK |
AR_PCICFG_LEDSLOW);
ar5312RestoreClock(ah, opmode);
(void) ar5212GetRfgain(ah);
if (!ar5312ChipReset(ah, chan)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
FAIL(HAL_EIO);
}
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;
modesIndex = IEEE80211_IS_CHAN_ST(chan) ? 2 : 1;
}
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 0);
regWrites = write_common(ah, &ahp->ah_ini_common, bChannelChange,
regWrites);
ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites);
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
if (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))
ar5212SetIFSTiming(ah, chan);
if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) {
OS_REG_WRITE(ah, AR_PHY_ADC_CTL,
SM(2, AR_PHY_ADC_CTL_OFF_INBUFGAIN) |
SM(2, AR_PHY_ADC_CTL_ON_INBUFGAIN) |
AR_PHY_ADC_CTL_OFF_PWDDAC |
AR_PHY_ADC_CTL_OFF_PWDADC);
if (chan->channel == 2484) {
cckOfdmPwrDelta = SCALE_OC_DELTA(ee->ee_cckOfdmPwrDelta - ee->ee_scaledCh14FilterCckDelta);
} else {
cckOfdmPwrDelta = SCALE_OC_DELTA(ee->ee_cckOfdmPwrDelta);
}
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));
} else {
OS_REG_WRITE(ah, AR_PHY_TXPWRADJ, 0);
}
OS_REG_CLR_BIT(ah, AR_PHY_DAG_CTRLCCK,
AR_PHY_DAG_CTRLCCK_EN_RSSI_THR);
OS_REG_RMW_FIELD(ah, AR_PHY_DAG_CTRLCCK,
AR_PHY_DAG_CTRLCCK_RSSI_THR, 2);
OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F);
}
if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) {
OS_REG_WRITE(ah, AR_PHY_BLUETOOTH, 0);
}
if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) {
#ifdef notyet
OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... );
OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS);
#endif
}
if (IS_5312_2_X(ah)) {
OS_REG_WRITE(ah, AR_PHY_SIGMA_DELTA,
SM(2, AR_PHY_SIGMA_DELTA_ADC_SEL) |
SM(4, AR_PHY_SIGMA_DELTA_FILT2) |
SM(0x16, AR_PHY_SIGMA_DELTA_FILT1) |
SM(0, AR_PHY_SIGMA_DELTA_ADC_CLIP));
if (IEEE80211_IS_CHAN_2GHZ(chan))
OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN, AR_PHY_RXGAIN_TXRX_RF_MAX, 0x0F);
if (IEEE80211_IS_CHAN_B(chan))
OS_REG_RMW_FIELD(ah, AR_PHY_CCK_RXCTRL4, AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT, 12);
OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x04);
if (IEEE80211_IS_CHAN_A(chan))
OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_AGC, 32);
} else {
OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
}
if (!ar5212SetTransmitPower(ah, chan, rfXpdGain)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: error init'ing transmit power\n", __func__);
FAIL(HAL_EIO);
}
if (!ahp->ah_rfHal->setRfRegs(ah, chan, modesIndex, rfXpdGain)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5212SetRfRegs failed\n",
__func__);
FAIL(HAL_EIO);
}
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);
}
if (!ar5212SetBoardValues(ah, chan)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: error setting board options\n", __func__);
FAIL(HAL_EIO);
}
if (bChannelChange)
OS_REG_WRITE(ah, AR_D_SEQNUM, saveFrameSeqCount);
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
| macStaId1
| AR_STA_ID1_RTS_USE_DEF
| ahp->ah_staId1Defaults
);
ar5212SetOperatingMode(ah, opmode);
OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));
OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));
if (!IS_5315(ah))
OS_REG_WRITE(ah, AR5312_PCICFG, OS_REG_READ(ah, AR_PCICFG) | saveLedState);
OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4));
OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr);
OS_REG_WRITE(ah, AR_ISR, ~0);
if (!ar5212SetChannel(ah, chan))
FAIL(HAL_EIO);
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1);
ar5212SetRateDurationTable(ah, chan);
if (IS_RAD5112_ANY(ah) &&
(IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))) {
txFrm2TxDStart =
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,
AR_PHY_TX_FRAME_TO_TX_DATA_START, txFrm2TxDStart);
}
if (IS_5312_2_X(ah)) {
(void) OS_REG_READ(ah, AR_PHY_SLEEP_SCAL);
}
synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
if (IEEE80211_IS_CHAN_B(chan)) {
synthDelay = (4 * synthDelay) / 22;
} else {
synthDelay /= 10;
}
OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
if (IEEE80211_IS_CHAN_HALF(chan)) {
OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY);
} else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY);
} else {
OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
}
testReg = OS_REG_READ(ah, AR_PHY_TESTCTRL);
OS_REG_WRITE(ah, AR_PHY_TESTCTRL, AR_PHY_TESTCTRL_TXHOLD);
i = 0;
while ((i++ < 20) &&
(OS_REG_READ(ah, 0x9c24) & 0x10)) OS_DELAY(200);
OS_REG_WRITE(ah, AR_PHY_TESTCTRL, testReg);
OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
OS_REG_READ(ah, AR_PHY_AGC_CONTROL)
| AR_PHY_AGC_CONTROL_CAL
| AR_PHY_AGC_CONTROL_NF);
if (!IEEE80211_IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) {
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
INIT_IQCAL_LOG_COUNT_MAX);
OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
AR_PHY_TIMING_CTRL4_DO_IQCAL);
ahp->ah_bIQCalibration = IQ_CAL_RUNNING;
} else
ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
ar5212SetCompRegs(ah);
for (i = 0; i < AR_NUM_DCU; i++)
OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
ahp->ah_intrTxqs = 0;
for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++)
ar5212ResetTxQueue(ah, i);
ahp->ah_maskReg = AR_IMR_TXOK | AR_IMR_TXERR | AR_IMR_TXURN
| AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXORN
| AR_IMR_HIUERR
;
if (opmode == HAL_M_HOSTAP)
ahp->ah_maskReg |= AR_IMR_MIB;
OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
OS_REG_WRITE(ah, AR_IMR_S2,
OS_REG_READ(ah, AR_IMR_S2)
| AR_IMR_S2_MCABT | AR_IMR_S2_SSERR | AR_IMR_S2_DPERR);
if (AH_PRIVATE(ah)->ah_rfkillEnabled)
ar5212EnableRfKill(ah);
if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
HALDEBUG(ah, HAL_DEBUG_ANY,
"%s: offset calibration failed to complete in 1ms;"
" noisy environment?\n", __func__);
}
ar5312SetupClock(ah, opmode);
OS_REG_WRITE(ah, AR_BEACON,
(OS_REG_READ(ah, AR_BEACON) &~ (AR_BEACON_EN | AR_BEACON_RESET_TSF)));
if (AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE ||
(AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE &&
AH_PRIVATE(ah)->ah_macRev >= AR_SREV_GRIFFIN_LITE)) {
OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa);
OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210);
}
OS_REG_WRITE(ah, AR_NOACK,
SM(2, AR_NOACK_2BIT_VALUE) |
SM(5, AR_NOACK_BIT_OFFSET) |
SM(0, AR_NOACK_BYTE_OFFSET));
if (ahp->ah_miscMode != 0)
OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
if (ahp->ah_slottime != (u_int) -1)
ar5212SetSlotTime(ah, ahp->ah_slottime);
if (ahp->ah_acktimeout != (u_int) -1)
ar5212SetAckTimeout(ah, ahp->ah_acktimeout);
if (ahp->ah_ctstimeout != (u_int) -1)
ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout);
if (ahp->ah_sifstime != (u_int) -1)
ar5212SetSifsTime(ah, ahp->ah_sifstime);
if (AH_PRIVATE(ah)->ah_diagreg != 0)
OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
AH_PRIVATE(ah)->ah_opmode = opmode;
if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan))
chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
OS_MARK(ah, AH_MARK_RESET_DONE, 0);
return AH_TRUE;
bad:
OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
if (status != AH_NULL)
*status = ecode;
return AH_FALSE;
#undef FAIL
#undef N
}
HAL_BOOL
ar5312PhyDisable(struct ath_hal *ah)
{
return ar5312SetResetReg(ah, AR_RC_BB);
}
HAL_BOOL
ar5312Disable(struct ath_hal *ah)
{
if (!ar5312SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
return AH_FALSE;
return ar5312SetResetReg(ah, AR_RC_MAC | AR_RC_BB);
}
HAL_BOOL
ar5312ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
if (!ar5312SetResetReg(ah, AR_RC_MAC | AR_RC_BB)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetResetReg failed\n",
__func__);
return AH_FALSE;
}
if (!ar5312SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetPowerMode failed\n",
__func__);
return AH_FALSE;
}
if (!ar5312SetResetReg(ah, 0)) {
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetResetReg failed\n",
__func__);
return AH_FALSE;
}
if (chan != AH_NULL) {
uint32_t rfMode, phyPLL = 0, curPhyPLL, turbo;
if (IS_RAD5112_ANY(ah)) {
rfMode = AR_PHY_MODE_AR5112;
if (!IS_5315(ah)) {
if (IEEE80211_IS_CHAN_CCK(chan)) {
phyPLL = AR_PHY_PLL_CTL_44_5312;
} else {
if (IEEE80211_IS_CHAN_HALF(chan)) {
phyPLL = AR_PHY_PLL_CTL_40_5312_HALF;
} 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 (IEEE80211_IS_CHAN_CCK(chan))
phyPLL = AR_PHY_PLL_CTL_44_5112;
else
phyPLL = AR_PHY_PLL_CTL_40_5112;
if (IEEE80211_IS_CHAN_HALF(chan))
phyPLL |= AR_PHY_PLL_CTL_HALF;
else if (IEEE80211_IS_CHAN_QUARTER(chan))
phyPLL |= AR_PHY_PLL_CTL_QUARTER;
}
} else {
rfMode = AR_PHY_MODE_AR5111;
if (IEEE80211_IS_CHAN_CCK(chan))
phyPLL = AR_PHY_PLL_CTL_44;
else
phyPLL = AR_PHY_PLL_CTL_40;
if (IEEE80211_IS_CHAN_HALF(chan))
phyPLL = AR_PHY_PLL_CTL_HALF;
else if (IEEE80211_IS_CHAN_QUARTER(chan))
phyPLL = AR_PHY_PLL_CTL_QUARTER;
}
if (IEEE80211_IS_CHAN_G(chan))
rfMode |= AR_PHY_MODE_DYNAMIC;
else if (IEEE80211_IS_CHAN_OFDM(chan))
rfMode |= AR_PHY_MODE_OFDM;
else
rfMode |= AR_PHY_MODE_CCK;
if (IEEE80211_IS_CHAN_5GHZ(chan))
rfMode |= AR_PHY_MODE_RF5GHZ;
else
rfMode |= AR_PHY_MODE_RF2GHZ;
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);
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) {
OS_REG_WRITE(ah, AR_PHY_PLL_CTL, phyPLL);
OS_DELAY(PLL_SETTLE_DELAY);
}
} else {
if (curPhyPLL != phyPLL) {
OS_REG_WRITE(ah, AR_PHY_PLL_CTL, phyPLL);
OS_DELAY(PLL_SETTLE_DELAY);
}
OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
}
}
return AH_TRUE;
}
static HAL_BOOL
ar5312SetResetReg(struct ath_hal *ah, uint32_t resetMask)
{
uint32_t mask = resetMask ? resetMask : ~0;
HAL_BOOL rt;
if ((rt = ar5312MacReset(ah, mask)) == AH_FALSE) {
return rt;
}
if ((resetMask & AR_RC_MAC) == 0) {
if (isBigEndian()) {
#ifdef AH_NEED_DESC_SWAP
mask = INIT_CONFIG_STATUS | AR_CFG_SWRD;
#else
mask = INIT_CONFIG_STATUS |
AR_CFG_SWTD | AR_CFG_SWRD;
#endif
OS_REG_WRITE(ah, AR_CFG, mask);
} else
OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS);
}
return rt;
}
HAL_BOOL
ar5312MacReset(struct ath_hal *ah, unsigned int RCMask)
{
int wlanNum = AR5312_UNIT(ah);
uint32_t resetBB, resetBits, regMask;
uint32_t reg;
if (RCMask == 0)
return(AH_FALSE);
#if ( AH_SUPPORT_2316 || AH_SUPPORT_2317 )
if (IS_5315(ah)) {
switch(wlanNum) {
case 0:
resetBB = AR5315_RC_BB0_CRES | AR5315_RC_WBB0_RES;
resetBits = AR5315_RC_WMAC0_RES;
break;
case 1:
resetBB = AR5315_RC_BB1_CRES | AR5315_RC_WBB1_RES;
resetBits = AR5315_RC_WMAC1_RES;
break;
default:
return(AH_FALSE);
}
regMask = ~(resetBB | resetBits);
reg = OS_REG_READ(ah,
(AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh) + AR5315_RESET));
if (RCMask == AR_RC_BB) {
reg |= resetBB;
} else {
reg &= regMask;
reg |= (resetBits | resetBB) ;
}
OS_REG_WRITE(ah,
(AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5315_RESET),
reg);
OS_REG_READ(ah,
(AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh) +AR5315_RESET));
OS_DELAY(100);
reg &= regMask;
OS_REG_READ(ah,
(AR5315_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5315_RESET));
OS_REG_WRITE(ah,
(AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5315_RESET),
reg);
OS_REG_READ(ah,
(AR5315_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5315_RESET));
}
else
#endif
{
switch(wlanNum) {
case 0:
resetBB = AR5312_RC_BB0_CRES | AR5312_RC_WBB0_RES;
resetBits = AR5312_RC_WMAC0_RES;
break;
case 1:
resetBB = AR5312_RC_BB1_CRES | AR5312_RC_WBB1_RES;
resetBits = AR5312_RC_WMAC1_RES;
break;
default:
return(AH_FALSE);
}
regMask = ~(resetBB | resetBits);
reg = OS_REG_READ(ah,
(AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh) + AR5312_RESET));
if (RCMask == AR_RC_BB) {
reg |= resetBB;
} else {
reg &= regMask;
reg |= (resetBits | resetBB) ;
}
OS_REG_WRITE(ah,
(AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5312_RESET),
reg);
OS_REG_READ(ah,
(AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh) +AR5312_RESET));
OS_DELAY(100);
reg &= regMask;
OS_REG_READ(ah,
(AR5312_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5312_RESET));
OS_REG_WRITE(ah,
(AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5312_RESET),
reg);
OS_REG_READ(ah,
(AR5312_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5312_RESET));
}
return(AH_TRUE);
}
#endif