📄 ar5212_reset.c
字号:
/* Restore soft Led state to GPIO */ OS_REG_WRITE(ah, AR_GPIOCR, softLedCfg); OS_REG_WRITE(ah, AR_GPIODO, softLedState); /* Restore previous antenna */ OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); /* then our BSSID */ 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_ISR, ~0); /* cleared on write */ OS_REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); if (!ahp->ah_rfHal.setChannel(ah, ichan)) FAIL(HAL_EIO); OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1); ar5212SetRateDurationTable(ah, chan); /* Set Tx frame start to tx data start delay */ if (IS_5112(ah) && (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan) || IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan))) { txFrm2TxDStart = (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) ? 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); } /* * Setup fast diversity. * Fast diversity can be enabled or disabled via regadd.txt. * Default is enabled. * For reference, * Disable: reg val * 0x00009860 0x00009d18 (if 11a / 11g, else no change) * 0x00009970 0x192bb514 * 0x0000a208 0xd03e4648 * * Enable: 0x00009860 0x00009d10 (if 11a / 11g, else no change) * 0x00009970 0x192fb514 * 0x0000a208 0xd03e6788 */ /* XXX Setup pre PHY ENABLE EAR additions */ /* * 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; } /* Activate the PHY (includes baseband activate and synthesizer on) */ OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); /* * There is an issue if the AP starts the calibration before * the base band timeout completes. This could result in the * rx_clear false triggering. As a workaround we add delay 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); } /* Calibrate the AGC and start a NF calculation */ 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 (!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, 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. */ ar5212SetupClock(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)); if (!IS_5416(ah)) { /* 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; } else { 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); /* 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; 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)) { OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_TOT_DES, -34); OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, AR_PHY_AGC_CTL1_COARSE_LOW, -52); OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, AR_PHY_AGC_CTL1_COARSE_HIGH, -18); OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRPWR, -70);#if 0 /* Reset all ANI parameters now to a good value */ ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, 0);#endif ar5212AniControl(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, 0); ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0); ar5212AniControl(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, HAL_ANI_USE_OFDM_WEAK_SIG); ar5212AniControl(ah, HAL_ANI_CCK_WEAK_SIGNAL_THR, !HAL_ANI_CCK_WEAK_SIG_THR); ath_hal_printf(ah, "Resetting ani parameters\n"); if ((chan->privFlags & CHANNEL_DFS_CLEAR) == 0) ar5212TxEnable(ah, AH_FALSE); } else#endif ar5212TxEnable(ah,AH_TRUE); }#if 1 // Steven Kuo: Work around TI chip bug.{ u_int32_t uVal; //ath_hal_printf(ah, "<ar5212Reset> Over Writing the Register \n"); // Write 0x9860(5:3) = 0x03 uVal = OS_REG_READ(ah, AR_PHY_AGC_CONTROL); //ath_hal_printf(ah, "Read AR_PHY_AGC_CONTROL original=0x%08x\n", uVal); uVal = ((uVal & ~(0x38)) | (0x03 << 3)); OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL, uVal); //ath_hal_printf(ah, "Write Value of AR_PHY_AGC_CONTROL=%x\n", uVal); //ath_hal_printf(ah, "Read AR_PHY_AGC_CONTROL=0x%08x\n", OS_REG_READ(ah, AR_PHY_AGC_CONTROL)); //ath_hal_printf(ah, "****************************\n"); // Write 0x9844(13:7) = 0x2C uVal = OS_REG_READ(ah, AR_PHY_SETTLING); //ath_hal_printf(ah, "Read AR_PHY_SETTLING original=0x%08x\n", uVal); uVal = ((uVal & ~(0x3F80)) | (0x2C << 7)); OS_REG_WRITE(ah, AR_PHY_SETTLING, uVal); //ath_hal_printf(ah, "Write Value of AR_PHY_SETTLING=%x\n", uVal); //ath_hal_printf(ah, "Read AR_PHY_SETTLING=0x%08x\n", OS_REG_READ(ah, AR_PHY_SETTLING)); //ath_hal_printf(ah, "****************************\n"); // Write 0x9844(6:0) = 0x1C uVal = OS_REG_READ(ah, AR_PHY_SETTLING); //ath_hal_printf(ah, "Read AR_PHY_SETTLING original=0x%08x\n", uVal); uVal = ((uVal & ~(0x7F)) | (0x1C)); OS_REG_WRITE(ah, AR_PHY_SETTLING, uVal); //ath_hal_printf(ah, "Write Value of AR_PHY_SETTLING=%x\n", uVal); //ath_hal_printf(ah, "Read AR_PHY_SETTLING=0x%08x\n", OS_REG_READ(ah, AR_PHY_SETTLING)); //ath_hal_printf(ah, "****************************\n"); // Write 0x985c(29:22) = 0xD8 = -40 uVal = OS_REG_READ(ah, AR_PHY_AGC_CTL1); //ath_hal_printf(ah, "Read AR_PHY_AGC_CTL1 original=0x%08x\n", uVal); uVal = (uVal & ~(0x3fc00000)) | ( (0xD8 << 22)); OS_REG_WRITE(ah, AR_PHY_AGC_CTL1, uVal); //ath_hal_printf(ah, "Write Value of AR_PHY_AGC_CTL1=%x\n", uVal); //ath_hal_printf(ah, "Read AR_PHY_AGC_CTL1=0x%08x\n", OS_REG_READ(ah, AR_PHY_AGC_CTL1)); //ath_hal_printf(ah, "****************************\n"); uVal = OS_REG_READ(ah, AR_PHY_RESTART); //ath_hal_printf(ah, "Read AR_PHY_RESTART original=0x%08x\n", uVal); uVal = ((uVal & ~(0x1C0000)) | (GET_COR_RESTART(chan) << 18)); //ath_hal_printf(ah, "%s, 5G write AR_PHY_RESTART to 0x%08x\n", __func__, uVal); OS_REG_WRITE(ah, AR_PHY_RESTART, uVal); uVal = OS_REG_READ(ah, AR_PHY_RESTART); //ath_hal_printf(ah, "%s, 2G AR_PHY_RESTART=0x%08x\n", __func__, uVal); //ath_hal_printf(ah, "Write Value of AR_PHY_RESTART=%x\n", uVal); //ath_hal_printf(ah, "Read AR_PHY_RESTART=0x%08x\n", OS_REG_READ(ah, AR_PHY_RESTART)); //ath_hal_printf(ah, "****************************\n");}#endif // Steven Kuo: Work around TI chip bug. 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}/* * Call the rf backend to change the channel and then * setup any radar-related state if DFS is enabled. */HAL_BOOLar5212SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan){ struct ath_hal_5212 *ahp = AH5212(ah); /* Change the synth */ if (!ahp->ah_rfHal.setChannel(ah, chan)) return AH_FALSE; return AH_TRUE;}/* * 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_BOOLar5212ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan){ u_int32_t ulCount; u_int32_t data, synthDelay, qnum; u_int16_t rfXpdGain[4]; HAL_BOOL txStopped = AH_TRUE; 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)) { txStopped = AH_FALSE; break; } } if (!txStopped) return AH_FALSE; /* Kill last Baseband Rx Frame */ OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST); /* Request analog bus grant */ for (ulCount = 0; ulCount < 100; ulCount++) { if (OS_REG_READ(ah, AR_PHY_RFBUS_GNT)) break; OS_DELAY(5); } if (ulCount >= 100) return AH_FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -