📄 ar5416_reset.c
字号:
FAIL(HAL_EIO); OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); /* 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); ar5416InitIMR(ah, opmode); ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1); ar5416InitQoS(ah); ar5416InitUserSettings(ah); /* * disable seq number generation in hw */ OS_REG_WRITE(ah, AR_STA_ID1, OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); ar5416InitDMA(ah); /* * program OBS bus to see MAC interrupts */ OS_REG_WRITE(ah, AR_OBS, 8);#ifdef AR5416_INT_MITIGATION OS_REG_WRITE(ah, AR_MIRT, 0); OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);#endif ar5416InitBB(ah, chan); /* Setup compression registers */ ar5212SetCompRegs(ah); /* XXX not needed? */ /* * 5416 baseband will check the per rate power table * and select the lower of the two */ ackTpcPow = 63; ctsTpcPow = 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); if (!ar5416InitCal(ah, chan)) FAIL(HAL_ESELFTEST); 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; chan->maxRegTxPower = ichan->maxRegTxPower; chan->maxTxPower = ichan->maxTxPower; chan->minTxPower = ichan->minTxPower; } 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) *status = ecode; return AH_FALSE;#undef FAIL#undef N}#if 0/* * This channel change evaluates whether the selected hardware can * perform a synthesizer-only channel change (no reset). If the * TX is not stopped, or the RFBus cannot be granted in the given * time, the function returns false as a reset is necessary */HAL_BOOLar5416ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan){ uint32_t ulCount; uint32_t data, synthDelay, qnum; uint16_t rfXpdGain[4]; struct ath_hal_5212 *ahp = AH5212(ah); HAL_CHANNEL_INTERNAL *ichan; /* * Map public channel to private. */ ichan = ath_hal_checkchannel(ah, chan); /* TX must be stopped or RF Bus grant will not work */ for (qnum = 0; qnum < AH_PRIVATE(ah)->ah_caps.halTotalQueues; qnum++) { if (ar5212NumTxPending(ah, qnum)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: frames pending on queue %d\n", __func__, qnum); return AH_FALSE; } } /* * Kill last Baseband Rx Frame - Request analog bus grant */ OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST); if (!ath_hal_wait(ah, AR_PHY_RFBUS_GNT, AR_PHY_RFBUS_GRANT_EN, AR_PHY_RFBUS_GRANT_EN)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: could not kill baseband rx\n", __func__); return AH_FALSE; } ar5416Set11nRegs(ah, chan); /* NB: setup 5416-specific regs */ /* Change the synth */ if (!ar5212SetChannel(ah, ichan)) return AH_FALSE; /* Setup the transmit power values. */ if (!ar5416SetTransmitPower(ah, ichan, rfXpdGain)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: error init'ing transmit power\n", __func__); return AH_FALSE; } /* * Wait for the frequency synth to settle (synth goes on * via PHY_ACTIVE_EN). Read the phy active delay register. * Value is in 100ns increments. */ data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; if (IS_CHAN_CCK(ichan)) { synthDelay = (4 * data) / 22; } else { synthDelay = data / 10; } OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); /* Release the RFBus Grant */ OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ if (IS_CHAN_OFDM(ichan)|| IS_CHAN_HT(chan)) { if (ahp->ah_eeprom.ee_version >= AR_EEPROM_VER5_3 && !IS_CHAN_B(chan)) ar5212SetSpurMitigation(ah, ichan); ar5416SetDeltaSlope(ah, ichan); } /* XXX spur mitigation for Melin */ /* Copy over internal channel flags to public hal channel */ if (!(ichan->privFlags & 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); ar5212TxEnable(ah,AH_TRUE); return AH_TRUE;}#endifstatic voidar5416InitDMA(struct ath_hal *ah){ /* * set AHB_MODE not to do cacheline prefetches */ OS_REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN); /* * let mac dma reads be in 128 byte chunks */ OS_REG_WRITE(ah, AR_TXCFG, (OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK) | AR_TXCFG_DMASZ_128B); /* * let mac dma writes be in 128 byte chunks */ OS_REG_WRITE(ah, AR_RXCFG, (OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK) | AR_RXCFG_DMASZ_128B); /* XXX restore TX trigger level */ /* * Setup receive FIFO threshold to hold off TX activities */ OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); /* * reduce the number of usable entries in PCU TXBUF to avoid * wrap around. */ OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE);}static voidar5416InitBB(struct ath_hal *ah, HAL_CHANNEL *chan){ uint32_t synthDelay; /* * Wait for the frequency synth to settle (synth goes on * via AR_PHY_ACTIVE_EN). Read the phy active delay register. * Value is in 100ns increments. */ synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; if (IS_CHAN_CCK(chan)) { synthDelay = (4 * synthDelay) / 22; } else { synthDelay /= 10; } /* Turn on PLL on 5416 */ HALDEBUG(ah, HAL_DEBUG_RESET, "%s %s channel\n", __func__, IS_CHAN_5GHZ(chan) ? "5GHz" : "2GHz"); ar5416InitPLL(ah, chan); /* Activate the PHY (includes baseband activate and synthesizer on) */ OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); /* * If the AP starts the calibration before the base band timeout * completes we could get rx_clear false triggering. Add an * extra BASE_ACTIVATE_DELAY usecs to ensure this condition * does not happen. */ if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) { OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY); } else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) { OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY); } else { OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); }}static voidar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode){ struct ath_hal_5212 *ahp = AH5212(ah); /* * 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_TXERR | AR_IMR_TXURN | AR_IMR_RXERR | AR_IMR_RXORN | AR_IMR_BCNMISC;#ifdef AR5416_INT_MITIGATION ahp->ah_maskReg |= AR_IMR_TXINTM | AR_IMR_RXINTM | AR_IMR_TXMINTR | AR_IMR_RXMINTR;#else ahp->ah_maskReg |= AR_IMR_TXOK | AR_IMR_RXOK;#endif 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 */ #if 0 OS_REG_WRITE(ah, AR_IMR_S2, OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT | AR_IMR_S2_CST); #endif}static voidar5416InitQoS(struct ath_hal *ah){ /* QoS support */ 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)); /* * initialize TXOP for all TIDs */ OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL); OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF); OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF); OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF); OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);}static voidar5416InitUserSettings(struct ath_hal *ah){ struct ath_hal_5212 *ahp = AH5212(ah); /* Restore user-specified settings */ if (ahp->ah_miscMode != 0) OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); if (ahp->ah_sifstime != (u_int) -1) ar5212SetSifsTime(ah, ahp->ah_sifstime); 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);#if 0 /* XXX Todo */ if (ahp->ah_globaltxtimeout != (u_int) -1) ar5416SetGlobalTxTimeout(ah, ahp->ah_globaltxtimeout);#endif}/* * Places the hardware into reset and then pulls it out of reset */HAL_BOOLar5416ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan){ uint32_t rfMode = 0; OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0); /* * Warm reset is optimistic. */ if (AR_SREV_MERLIN_20_OR_LATER(ah) && ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) { if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) return AH_FALSE; } else { if (!ar5416SetResetReg(ah, HAL_RESET_WARM)) return AH_FALSE; } /* Bring out of sleep mode (AGAIN) */ if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) return AH_FALSE; ar5416InitPLL(ah, chan); /* * 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. */ if (chan != AH_NULL) { /* treat channel B as channel G , no B mode suport in owl */ rfMode |= (IS_CHAN_G(chan) || IS_CHAN_B(chan)) ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { /* phy mode bits for 5GHz channels require Fast Clock */ rfMode |= AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE; } else if (!AR_SREV_MERLIN_10_OR_LATER(ah)) { rfMode |= (IS_CHAN_5GHZ(chan)) ? AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; } OS_REG_WRITE(ah, AR_PHY_MODE, rfMode); } return AH_TRUE; }/* * Delta slope coefficient computation. * Required for OFDM operation. */static voidar5416GetDeltaSlopeValues(struct ath_hal *ah, uint32_t coef_scaled, uint32_t *coef_mantissa, uint32_t *coef_exponent){#define COEF_SCALE_S 24 uint32_t coef_exp, coef_man; /* * ALGO -> coef_exp = 14-floor(log2(coef)); * floor(log2(x)) is the highest set bit position */ for (coef_exp = 31; coef_exp > 0; coef_exp--)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -