📄 ar5312_reset.c
字号:
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; /* Setup compression registers */ ar5212SetCompRegs(ah); /* Set 1:1 QCU to DCU mapping for all queues */ 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); /* * Setup interrupt handling. Note that ar5212ResetTxQueue * manipulates the secondary IMR's as queues are enabled * and disabled. This is done with RMW ops to insure the * settings we make here are preserved. */ 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); /* Enable bus errors that are OR'd to set the HIUERR bit */ 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 (ar5212GetRfKill(ah)) ar5212EnableRfKill(ah); if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) { HALDEBUG(ah, "%s: offset calibration failed to complete in 1ms;" " noisy environment?\n", __func__); } /* * Set clocks back to 32kHz if they had been using refClk, then * use an external 32kHz crystal when sleeping, if one exists. */ ar5312SetupClock(ah, opmode); /* * Writing to AR_BEACON will start timers. Hence it should * be the last register to be written. Do not reset tsf, do * not enable beacons at this point, but preserve other values * like beaconInterval. */ OS_REG_WRITE(ah, AR_BEACON, (OS_REG_READ(ah, AR_BEACON) &~ (AR_BEACON_EN | AR_BEACON_RESET_TSF))); /* XXX Setup post reset EAR additions */#ifdef AH_SUPPORT_XR /* it should be changed to IS_CHAN_XR once the reg domain sets the XR flags on channels */ if (opmode != HAL_M_STA && ahp->ah_xrEnable && !ar5212SetXrMode(ah, opmode,chan)) { HALDEBUG(ah, "%s: unable to setup XR mode\n", __func__); FAIL(HAL_EIO); }#endif /* AH_SUPPORT_XR */ /* QoS support */ 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); /* XXX magic */ OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210); /* XXX magic */ } /* Turn on NOACK Support for QoS packets */ OS_REG_WRITE(ah, AR_NOACK, SM(2, AR_NOACK_2BIT_VALUE) | SM(5, AR_NOACK_BIT_OFFSET) | SM(0, AR_NOACK_BYTE_OFFSET)); /* Get Antenna Gain reduction */ if (IS_CHAN_5GHZ(chan)) { twiceAntennaGain = ahp->ah_antennaGainMax[0]; } else { twiceAntennaGain = ahp->ah_antennaGainMax[1]; } twiceAntennaReduction = ath_hal_getantennareduction(ah, chan, twiceAntennaGain); /* TPC for self-generated frames */ ackTpcPow = MS(ahp->ah_macTPC, AR_TPC_ACK); if ((ackTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower) ackTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset; if (ackTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction)) ackTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction) + ahp->ah_txPowerIndexOffset; ctsTpcPow = MS(ahp->ah_macTPC, AR_TPC_CTS); if ((ctsTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower) ctsTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset; if (ctsTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction)) ctsTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction) + ahp->ah_txPowerIndexOffset; chirpTpcPow = MS(ahp->ah_macTPC, AR_TPC_CHIRP); if ((chirpTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower) chirpTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset; if (chirpTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction)) chirpTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction) + ahp->ah_txPowerIndexOffset; if (ackTpcPow > 63) ackTpcPow = 63; if (ctsTpcPow > 63) ctsTpcPow = 63; if (chirpTpcPow > 63) chirpTpcPow = 63; powerVal = SM(ackTpcPow, AR_TPC_ACK) | SM(ctsTpcPow, AR_TPC_CTS) | SM(chirpTpcPow, AR_TPC_CHIRP); OS_REG_WRITE(ah, AR_TPC, powerVal); /* Restore user-specified settings */ 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 (AH_PRIVATE(ah)->ah_diagreg != 0) OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */ if (bChannelChange) { if (!(ichan->channelFlags & CHANNEL_DFS)) ichan->privFlags &= ~CHANNEL_INTERFERENCE; chan->channelFlags = ichan->channelFlags; chan->privFlags = ichan->privFlags; chan->maxRegTxPower = ichan->maxRegTxPower; chan->maxTxPower = ichan->maxTxPower; chan->minTxPower = ichan->minTxPower; AH_PRIVATE(ah)->ah_curchan->ah_channel_time=0; AH_PRIVATE(ah)->ah_curchan->ah_tsf_last = ar5212GetTsf64(ah);#ifdef AH_SUPPORT_DFS if (opmode == HAL_M_HOSTAP && (chan->channelFlags & CHANNEL_DFS) && (chan->privFlags & CHANNEL_DFS_CLEAR) == 0 ) ar5212TxEnable(ah,AH_FALSE); else#endif ar5212TxEnable(ah,AH_TRUE); } HALDEBUG(ah, "%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) *status = ecode; return AH_FALSE;#undef FAIL#undef N}/* * Places the PHY and Radio chips into reset. A full reset * must be called to leave this state. The PCI/MAC/PCU are * not placed into reset as we must receive interrupt to * re-enable the hardware. */HAL_BOOLar5312PhyDisable(struct ath_hal *ah){ return ar5312SetResetReg(ah, AR_RC_BB);}/* * Places all of hardware into reset */HAL_BOOLar5312Disable(struct ath_hal *ah){ if (!ar5312SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) return AH_FALSE; /* * Reset the HW - PCI must be reset after the rest of the * device has been reset. */ return ar5312SetResetReg(ah, AR_RC_MAC | AR_RC_BB);}/* * Places the hardware into reset and then pulls it out of reset * * TODO: Only write the PLL if we're changing to or from CCK mode * * WARNING: The order of the PLL and mode registers must be correct. */HAL_BOOLar5312ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan){ struct ath_hal_5212 *ahp = AH5212(ah); OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0); /* * Reset the HW */ if (!ar5312SetResetReg(ah, AR_RC_MAC | AR_RC_BB)) return AH_FALSE; /* Bring out of sleep mode (AGAIN) */ if (!ar5312SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) return AH_FALSE; /* Clear warm reset register */ if (!ar5312SetResetReg(ah, 0)) return AH_FALSE; /* * Perform warm reset before the mode/PLL/turbo registers * are changed in order to deactivate the radio. Mode changes * with an active radio can result in corrupted shifts to the * radio device. */ /* * Set CCK and Turbo modes correctly. */ if (chan != AH_NULL) { /* NB: can be null during attach */ u_int32_t rfMode, phyPLL = 0, curPhyPLL, turbo; if (IS_5112(ah) || IS_2413(ah)) { rfMode = AR_PHY_MODE_AR5112; if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) { phyPLL = AR_PHY_PLL_CTL_44_5112; } else { if (IS_CHAN_HALF_RATE(chan)) { phyPLL = AR_PHY_PLL_CTL_40_5112_HALF; } else if (IS_CHAN_QUARTER_RATE(chan)) { phyPLL = AR_PHY_PLL_CTL_40_5112_QUARTER; } else { phyPLL = AR_PHY_PLL_CTL_40_5112; } } } else { rfMode = AR_PHY_MODE_AR5111; if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) { phyPLL = AR_PHY_PLL_CTL_44; } else { if (IS_CHAN_HALF_RATE(chan)) { phyPLL = AR_PHY_PLL_CTL_40_HALF; } else if (IS_CHAN_QUARTER_RATE(chan)) { phyPLL = AR_PHY_PLL_CTL_40_QUARTER; } else { phyPLL = AR_PHY_PLL_CTL_40; } } } if (IS_CHAN_OFDM(chan) && (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))) rfMode |= AR_PHY_MODE_DYNAMIC; else if (IS_CHAN_OFDM(chan)) rfMode |= AR_PHY_MODE_OFDM; else rfMode |= AR_PHY_MODE_CCK; if (IS_CHAN_5GHZ(chan)) rfMode |= AR_PHY_MODE_RF5GHZ; else rfMode |= AR_PHY_MODE_RF2GHZ; turbo = IS_CHAN_TURBO(chan) ? (AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT) : 0; curPhyPLL = OS_REG_READ(ah, AR_PHY_PLL_CTL);#ifdef AH_SUPPORT_XR if (ahp->ah_xrEnable) { rfMode |= AR_PHY_MODE_XR; }#endif /* * PLL, Mode, and Turbo values must be written in the correct * order to ensure: * - The PLL cannot be set to 44 unless the CCK or DYNAMIC * 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)) { 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); /* Wait for the PLL to settle */ OS_DELAY(PLL_SETTLE_DELAY); } } else { if (curPhyPLL != phyPLL) { OS_REG_WRITE(ah, AR_PHY_PLL_CTL, phyPLL); /* Wait for the PLL to settle */ OS_DELAY(PLL_SETTLE_DELAY); } OS_REG_WRITE(ah, AR_PHY_TURBO, turbo); OS_REG_WRITE(ah, AR_PHY_MODE, rfMode); } } return AH_TRUE;}/* * Write the given reset bit mask into the reset register */static HAL_BOOLar5312SetResetReg(struct ath_hal *ah, u_int32_t resetMask){ u_int32_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()) { /* * Set CFG, little-endian for register * and descriptor accesses. */#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;}/* * ar5312MacReset resets (and then un-resets) the specified * wireless components. * Note: The RCMask cannot be zero on entering from ar5312SetResetReg. */HAL_BOOLar5312MacReset(struct ath_hal *ah, unsigned int RCMask){ int wlanNum; u_int32_t resetBB, resetBits, regMask; u_int32_t reg; if (RCMask == 0) return(AH_FALSE); if ((wlanNum = GETWMACNUM(ah)) == -1) { return (AH_FALSE); }#if (AH_SUPPORT_2316 || AH_SUPPORT_2317) if((AH_PRIVATE(ah)->ah_devid == AR5212_AR2315_REV6) || (AH_PRIVATE(ah)->ah_devid == AR5212_AR2315_REV7) || (AH_PRIVATE(ah)->ah_devid == AR5212_AR2317_REV1) || (AH_PRIVATE(ah)->ah_devid == AR5212_AR2317_REV2)) { switch(wlanNum) { case 0: resetBB = AR5315_RC_BB0_CRES | AR5315_RC_WBB0_RES; /* Warm and cold reset bits for wbb */ resetBits = AR5315_RC_WMAC0_RES; break; case 1: resetBB = AR5315_RC_BB1_CRES | AR5315_RC_WBB1_RES; /* Warm and cold reset bits for wbb */ resetBits = AR5315_RC_WMAC1_RES; break; default: return(AH_FALSE); } regMask = ~(resetBB | resetBits); /* read before */ reg = OS_REG_READ(ah, (AR5315_RSTIMER_BASE - ((u_int32_t) ah->ah_sh) + AR5315_RESET)); if (RCMask == AR_RC_BB) { /* Put baseband in reset */ reg |= resetBB; /* Cold and warm reset the baseband bits */ } else { /* * Reset the MAC and baseband. This is a bit different than * the PCI version, but holding in reset causes problems. */ reg &= regMask; reg |= (resetBits | resetBB) ; } OS_REG_WRITE(ah, (AR5315_RSTIMER_BASE - ((u_int32_t) ah->ah_sh)+AR5315_RESET), reg); /* read after */ OS_REG_READ(ah, (AR5315_RSTIMER_BASE - ((u_int32_t) ah->ah_sh) +AR5315_RESET)); OS_DELAY(100); /* Bring MAC and baseband out of reset */ reg &= regMask; /* read before */ OS_REG_READ(ah, (AR5315_RSTIMER_BASE- ((u_int32_t) ah->ah_sh) +AR5315_RESET)); OS_REG_WRITE(ah, (AR5315_RSTIMER_BASE - ((u_int32_t) ah->ah_sh)+AR5315_RESET), reg); /* read after */ OS_REG_READ(ah, (AR5315_RSTIMER_BASE- ((u_int32_t) ah->ah_sh) +AR5315_RESET)); } else #endif { switch(wlanNum) { case 0: resetBB = AR_RC_BB0_CRES | AR_RC_WBB0_RES; /* Warm and cold reset bits for wbb */ resetBits = AR_RC_WMAC0_RES; break; case 1: resetBB = AR_RC_BB1_CRES | AR_RC_WBB1_RES; /* Warm and cold reset bits for wbb */ resetBits = AR_RC_WMAC1_RES; break; default: return(AH_FALSE); } regMask = ~(resetBB | resetBits); /* read before */ reg = OS_REG_READ(ah, (AR_RSTIMER_BASE - ((u_int32_t) ah->ah_sh) + AR531X_RESET)); if (RCMask == AR_RC_BB) { /* Put baseband in reset */ reg |= resetBB; /* Cold and warm reset the baseband bits */ } else { /* * Reset the MAC and baseband. This is a bit different than * the PCI version, but holding in reset causes problems. */ reg &= regMask; reg |= (resetBits | resetBB) ; } OS_REG_WRITE(ah, (AR_RSTIMER_BASE - ((u_int32_t) ah->ah_sh)+AR531X_RESET), reg); /* read after */ OS_REG_READ(ah, (AR_RSTIMER_BASE - ((u_int32_t) ah->ah_sh) +AR531X_RESET)); OS_DELAY(100); /* Bring MAC and baseband out of reset */ reg &= regMask; /* read before */ OS_REG_READ(ah, (AR_RSTIMER_BASE- ((u_int32_t) ah->ah_sh) +AR531X_RESET)); OS_REG_WRITE(ah, (AR_RSTIMER_BASE - ((u_int32_t) ah->ah_sh)+AR531X_RESET), reg); /* read after */ OS_REG_READ(ah, (AR_RSTIMER_BASE- ((u_int32_t) ah->ah_sh) +AR531X_RESET)); } return(AH_TRUE);}#endif /* AH_SUPPORT_AR5312 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -