static void ar5111WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex, int regWrites) { REG_WRITE_ARRAY(ar5212Modes_5111, modesIndex, regWrites); REG_WRITE_ARRAY(ar5212Common_5111, 1, regWrites); REG_WRITE_ARRAY(ar5212BB_RfGain_5111, freqIndex, regWrites); }
static void ar2316WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex, int regWrites) { REG_WRITE_ARRAY(ar5212Modes_2316, modesIndex, regWrites); REG_WRITE_ARRAY(ar5212Common_2316, 1, regWrites); REG_WRITE_ARRAY(ar5212BB_RfGain_2316, freqIndex, regWrites); if (AH_PRIVATE(ah)->ah_cwCalRequire !=AH_TRUE) { OS_REG_WRITE(ah,0xa358, (OS_REG_READ(ah,0xa358) & ~2) ); } else { AH_PRIVATE(ah)->ah_cwCalRequire = AH_FALSE; } }
static void ar2425WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex, int regWrites) { REG_WRITE_ARRAY(ar5212Modes_2425, modesIndex, regWrites); #ifdef __CARRIER_PLATFORM__ if (IS_2417(ah)) { REG_WRITE_ARRAY(ar5212Modes_2417_Carr, modesIndex, regWrites); } #endif REG_WRITE_ARRAY(ar5212Common_2425, 1, regWrites); #ifdef __CARRIER_PLATFORM__ if (IS_2417(ah)) { REG_WRITE_ARRAY(ar5212Common_2417_Carr, 1, regWrites); } #endif REG_WRITE_ARRAY(ar5212BB_RfGain_2425, freqIndex, regWrites); /* Enable LED for Nala */ if (IS_2417(ah)) { OS_REG_WRITE(ah, AR_PCICFG, AR_ENABLE_LED); #if defined(__LINUX_MIPS32_ARCH__) || defined(__LINUX_MIPS64_ARCH__) /* Nala doesn't work with 128 bytes burst on pb42(Hydra). 16 bytes seems ok, 4 bytes is better */ OS_REG_WRITE(ah, AR_RXCFG, 0x00); #endif } /* WAR for SWAN similar to Condor * Bit 0 enables link to go to L1 when MAC goes to sleep. * Bit 3 enables the loop back the link down to reset. */ if (IS_PCIE(ah) && AH_PRIVATE(ah)->ah_config.ath_hal_pcieL1SKPEnable) { OS_REG_WRITE(ah, AR_PCIE_PMC, AR_PCIE_PMC_ENABLE_L1 | AR_PCIE_PMC_EN_RESET); } /* * WAR for Standby issue in Swan/Condor. * Bit 9 (MAC_WOW_PWR_STATE_MASK_D2)to be set to avoid skips before last Training Sequence 2 (TS2) * Bit 8 (MAC_WOW_PWR_STATE_MASK_D1)to be unset to assert Power Reset along with PCI Reset */ if (!IS_2417(ah) && AH_PRIVATE(ah)->ah_config.ath_hal_pciePowerReset) { OS_REG_WRITE(ah, AR_PCIE_PMC, (AH_PRIVATE(ah)->ah_config.ath_hal_pciePowerReset | OS_REG_READ(ah, AR_PCIE_PMC))); } }
static void ar2133WriteRegs(struct ath_hal *ah, u_int modesIndex, u_int freqIndex, int regWrites) { struct ath_hal_5416 *ahp = AH5416(ah); REG_WRITE_ARRAY(&ahp->ah_iniBB_RfGain, freqIndex, regWrites); }
void ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex, u32 freqIndex, int regWrites) { struct ath_hal_5416 *ahp = AH5416(ah); REG_WRITE_ARRAY(&ahp->ah_iniBB_RfGain, freqIndex, regWrites); }
static HAL_BOOL ar9280SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan) { struct ath_hal_5416 *ahp = AH5416(ah); u_int16_t bMode, fracMode, aModeRefSel = 0; u_int32_t freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0; CHAN_CENTERS centers; u_int32_t refDivA = 24; OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel); ar5416GetChannelCenters(ah, chan, ¢ers); freq = centers.synth_center; reg32 = OS_REG_READ(ah, AR_PHY_SYNTH_CONTROL); reg32 &= 0xc0000000; if (freq < 4800) { /* 2 GHz, fractional mode */ u_int32_t txctl; int regWrites = 0; bMode = 1; fracMode = 1; aModeRefSel = 0; channelSel = (freq * 0x10000)/15; if (AR_SREV_KIWI_11_OR_LATER(ah)) { if (freq == 2484) { REG_WRITE_ARRAY(&ahp->ah_iniCckfirJapan2484, 1, regWrites); } else { REG_WRITE_ARRAY(&ahp->ah_iniCckfirNormal, 1, regWrites); } } else { txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL); 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); } else { OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN); } } } else { bMode = 0; fracMode = 0; HALASSERT(aModeRefSel == 0); switch (ar5416EepromGet(ahp, EEP_FRAC_N_5G)) { case 0: if ((freq % 20) == 0) { aModeRefSel = 3; } else if ((freq % 10) == 0) { aModeRefSel = 2; } if (aModeRefSel) break; case 1: default: aModeRefSel = 0; /* Enable 2G (fractional) mode for channels which are 5MHz spaced */ fracMode = 1; refDivA = 1; channelSel = (freq * 0x8000)/15; /* RefDivA setting */ analogShiftRegRMW(ah, AR_AN_SYNTH9, AR_AN_SYNTH9_REFDIVA, AR_AN_SYNTH9_REFDIVA_S, refDivA); } if (!fracMode) { ndiv = (freq * (refDivA >> aModeRefSel))/60; channelSel = ndiv & 0x1ff; channelFrac = (ndiv & 0xfffffe00) * 2; channelSel = (channelSel << 17) | channelFrac; } }
/** * ar9002_hw_set_channel - set channel on single-chip device * @ah: atheros hardware structure * @chan: * * This is the function to change channel on single-chip devices, that is * all devices after ar9280. * * This function takes the channel value in MHz and sets * hardware channel value. Assumes writes have been enabled to analog bus. * * Actual Expression, * * For 2GHz channel, * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) * (freq_ref = 40MHz) * * For 5GHz channel, * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10) * (freq_ref = 40MHz/(24>>amodeRefSel)) */ static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) { u16 bMode, fracMode, aModeRefSel = 0; u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0; struct chan_centers centers; u32 refDivA = 24; ath9k_hw_get_channel_centers(ah, chan, ¢ers); freq = centers.synth_center; reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL); reg32 &= 0xc0000000; if (freq < 4800) { /* 2 GHz, fractional mode */ u32 txctl; int regWrites = 0; bMode = 1; fracMode = 1; aModeRefSel = 0; channelSel = CHANSEL_2G(freq); if (AR_SREV_9287_11_OR_LATER(ah)) { if (freq == 2484) { /* Enable channel spreading for channel 14 */ REG_WRITE_ARRAY(&ah->iniCckfirJapan2484, 1, regWrites); } else { REG_WRITE_ARRAY(&ah->iniCckfirNormal, 1, regWrites); } } else { txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL); if (freq == 2484) { /* Enable channel spreading for channel 14 */ REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, txctl | AR_PHY_CCK_TX_CTRL_JAPAN); } else { REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN); } } } else { bMode = 0; fracMode = 0; switch (ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) { case 0: if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) aModeRefSel = 0; else if ((freq % 20) == 0) aModeRefSel = 3; else if ((freq % 10) == 0) aModeRefSel = 2; if (aModeRefSel) break; case 1: default: aModeRefSel = 0; /* * Enable 2G (fractional) mode for channels * which are 5MHz spaced. */ fracMode = 1; refDivA = 1; channelSel = CHANSEL_5G(freq); /* RefDivA setting */ ath9k_hw_analog_shift_rmw(ah, AR_AN_SYNTH9, AR_AN_SYNTH9_REFDIVA, AR_AN_SYNTH9_REFDIVA_S, refDivA); } if (!fracMode) { ndiv = (freq * (refDivA >> aModeRefSel)) / 60; channelSel = ndiv & 0x1ff; channelFrac = (ndiv & 0xfffffe00) * 2; channelSel = (channelSel << 17) | channelFrac; } }
/** * ath9k_hw_write_regs - ?? * * @ah: atheros hardware structure * @freqIndex: * @regWrites: * * Used for both the chipsets with an external AR2133/AR5133 radios and * single-chip devices. */ void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites) { REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); }
static int ar9003_hw_process_ini(struct ath_hw *ah, struct ath9k_channel *chan) { struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); unsigned int regWrites = 0, i; struct ieee80211_channel *channel = chan->chan; u32 modesIndex, freqIndex; switch (chan->chanmode) { case CHANNEL_A: case CHANNEL_A_HT20: modesIndex = 1; freqIndex = 1; break; case CHANNEL_A_HT40PLUS: case CHANNEL_A_HT40MINUS: modesIndex = 2; freqIndex = 1; break; case CHANNEL_G: case CHANNEL_G_HT20: case CHANNEL_B: modesIndex = 4; freqIndex = 2; break; case CHANNEL_G_HT40PLUS: case CHANNEL_G_HT40MINUS: modesIndex = 3; freqIndex = 2; break; default: return -EINVAL; } for (i = 0; i < ATH_INI_NUM_SPLIT; i++) { ar9003_hw_prog_ini(ah, &ah->iniSOC[i], modesIndex); ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex); ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex); ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex); } REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites); REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); /* * For 5GHz channels requiring Fast Clock, apply * different modal values. */ if (IS_CHAN_A_FAST_CLOCK(ah, chan)) REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites); ar9003_hw_override_ini(ah); ar9003_hw_set_channel_regs(ah, chan); ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); /* Set TX power */ ah->eep_ops->set_txpower(ah, chan, ath9k_regd_get_ctl(regulatory, chan), channel->max_antenna_gain * 2, channel->max_power * 2, min((u32) MAX_RATE_POWER, (u32) regulatory->power_limit)); return 0; }
/* * Enable radar detection and set the radar parameters per the * values in pe */ void ar9300_enable_dfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) { u_int32_t val; struct ath_hal_private *ahp = AH_PRIVATE(ah); HAL_CHANNEL_INTERNAL *ichan = ahp->ah_curchan; struct ath_hal_9300 *ah9300 = AH9300(ah); bool asleep = ah9300->ah_chip_full_sleep; int reg_writes = 0; if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_AWAKE, true); } val = OS_REG_READ(ah, AR_PHY_RADAR_0); val |= AR_PHY_RADAR_0_FFT_ENA | AR_PHY_RADAR_0_ENA; if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_FIRPWR; val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR); } if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_RRSSI; val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI); } if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_HEIGHT; val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT); } if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_PRSSI; if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) { if (ah->ah_use_cac_prssi) { val |= SM(AR9300_DFS_PRSSI_CAC, AR_PHY_RADAR_0_PRSSI); } else { val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI); } } else { val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI); } } if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_INBAND; val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND); } OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); val = OS_REG_READ(ah, AR_PHY_RADAR_1); val |= AR_PHY_RADAR_1_MAX_RRSSI | AR_PHY_RADAR_1_BLOCK_CHECK; if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_1_MAXLEN; val |= SM(pe->pe_maxlen, AR_PHY_RADAR_1_MAXLEN); } if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_1_RELSTEP_THRESH; val |= SM(pe->pe_relstep, AR_PHY_RADAR_1_RELSTEP_THRESH); } if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_1_RELPWR_THRESH; val |= SM(pe->pe_relpwr, AR_PHY_RADAR_1_RELPWR_THRESH); } OS_REG_WRITE(ah, AR_PHY_RADAR_1, val); if (ath_hal_getcapability(ah, HAL_CAP_EXT_CHAN_DFS, 0, 0) == HAL_OK) { val = OS_REG_READ(ah, AR_PHY_RADAR_EXT); if (IS_CHAN_HT40(ichan)) { /* Enable extension channel radar detection */ OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val | AR_PHY_RADAR_EXT_ENA); } else { /* HT20 mode, disable extension channel radar detect */ OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA); } } /* apply DFS postamble array from INI column 0 is register ID, column 1 is HT20 value, colum2 is HT40 value */ if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_OSPREY_22(ah) || AR_SREV_SCORPION(ah)) { REG_WRITE_ARRAY(&ah9300->ah_ini_dfs,IS_CHAN_HT40(ichan)? 2:1, reg_writes); } #ifdef ATH_HAL_DFS_CHIRPING_FIX_APH128 HDPRINTF(ah, HAL_DBG_DFS,"DFS change the timing value\n"); if (AR_SREV_AR9580(ah) && IS_CHAN_HT40(ichan)) { OS_REG_WRITE(ah, AR_PHY_TIMING6, 0x3140c00a); } #endif if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true); } }
/* * Reads EEPROM header info from device structure and programs * all rf registers * * REQUIRES: Access to the analog rf device */ static HAL_BOOL ar5111SetRfRegs(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, u_int16_t modesIndex, u_int16_t *rfXpdGain) { struct ath_hal_5212 *ahp = AH5212(ah); u_int16_t rfXpdGainFixed, rfPloSel, rfPwdXpd, gainI; u_int16_t tempOB, tempDB; u_int32_t ob2GHz, db2GHz, rfReg[N(ar5212Bank6_5111)]; int i, regWrites = 0; /* Setup rf parameters */ switch (chan->channelFlags & CHANNEL_ALL) { case CHANNEL_A: case CHANNEL_T: if (4000 < chan->channel && chan->channel < 5260) { tempOB = ahp->ah_ob1; tempDB = ahp->ah_db1; } else if (5260 <= chan->channel && chan->channel < 5500) { tempOB = ahp->ah_ob2; tempDB = ahp->ah_db2; } else if (5500 <= chan->channel && chan->channel < 5725) { tempOB = ahp->ah_ob3; tempDB = ahp->ah_db3; } else if (chan->channel >= 5725) { tempOB = ahp->ah_ob4; tempDB = ahp->ah_db4; } else { /* XXX when does this happen??? */ tempOB = tempDB = 0; } ob2GHz = db2GHz = 0; rfXpdGainFixed = ahp->ah_xgain[headerInfo11A]; rfPloSel = ahp->ah_xpd[headerInfo11A]; rfPwdXpd = !ahp->ah_xpd[headerInfo11A]; gainI = ahp->ah_gainI[headerInfo11A]; break; case CHANNEL_B: tempOB = ahp->ah_obFor24; tempDB = ahp->ah_dbFor24; ob2GHz = ahp->ah_ob2GHz[0]; db2GHz = ahp->ah_db2GHz[0]; rfXpdGainFixed = ahp->ah_xgain[headerInfo11B]; rfPloSel = ahp->ah_xpd[headerInfo11B]; rfPwdXpd = !ahp->ah_xpd[headerInfo11B]; gainI = ahp->ah_gainI[headerInfo11B]; break; case CHANNEL_G: tempOB = ahp->ah_obFor24g; tempDB = ahp->ah_dbFor24g; ob2GHz = ahp->ah_ob2GHz[1]; db2GHz = ahp->ah_db2GHz[1]; rfXpdGainFixed = ahp->ah_xgain[headerInfo11G]; rfPloSel = ahp->ah_xpd[headerInfo11G]; rfPwdXpd = !ahp->ah_xpd[headerInfo11G]; gainI = ahp->ah_gainI[headerInfo11G]; break; default: HDPRINTF(ah, HAL_DBG_CHANNEL, "%s: invalid channel flags 0x%x\n", __func__, chan->channelFlags); return AH_FALSE; } HALASSERT(1 <= tempOB && tempOB <= 5); HALASSERT(1 <= tempDB && tempDB <= 5); /* Bank 0 Write */ for (i = 0; i < N(ar5212Bank0_5111); i++) rfReg[i] = ar5212Bank0_5111[i][modesIndex]; if (IS_CHAN_2GHZ(chan)) { ar5212ModifyRfBuffer(rfReg, ob2GHz, 3, 119, 0); ar5212ModifyRfBuffer(rfReg, db2GHz, 3, 122, 0); } for (i = 0; i < N(ar5212Bank0_5111); i++) { OS_REG_WRITE(ah, ar5212Bank0_5111[i][0], rfReg[i]); ALLOW_DMA_READ_COMPLETE(regWrites); } /* Bank 1 Write */ REG_WRITE_ARRAY(ar5212Bank1_5111, 1, regWrites); /* Bank 2 Write */ REG_WRITE_ARRAY(ar5212Bank2_5111, modesIndex, regWrites); /* Bank 3 Write */ REG_WRITE_ARRAY(ar5212Bank3_5111, modesIndex, regWrites); /* 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 */ ar5212ModifyRfBuffer(rfReg, ahp->ah_cornerCal.pd84, 1, 51, 3); ar5212ModifyRfBuffer(rfReg, ahp->ah_cornerCal.pd90, 1, 45, 3); } ar5212ModifyRfBuffer(rfReg, rfPwdXpd, 1, 95, 0); ar5212ModifyRfBuffer(rfReg, rfXpdGainFixed, 4, 96, 0); /* Set 5212 OB & DB */ ar5212ModifyRfBuffer(rfReg, tempOB, 3, 104, 0); ar5212ModifyRfBuffer(rfReg, tempDB, 3, 107, 0); for (i = 0; i < N(ar5212Bank6_5111); i++) { OS_REG_WRITE(ah, ar5212Bank6_5111[i][0], rfReg[i]); ALLOW_DMA_READ_COMPLETE(regWrites); } /* Bank 7 Write */ for (i = 0; i < N(ar5212Bank7_5111); i++) rfReg[i] = ar5212Bank7_5111[i][modesIndex]; ar5212ModifyRfBuffer(rfReg, gainI, 6, 29, 0); ar5212ModifyRfBuffer(rfReg, rfPloSel, 1, 4, 0); if (IS_CHAN_QUARTER_RATE(chan) || IS_CHAN_HALF_RATE(chan)) { u_int32_t rfWaitI, rfWaitS, rfMaxTime; rfWaitS = 0x1f; rfWaitI = (IS_CHAN_HALF_RATE(chan)) ? 0x10 : 0x1f; rfMaxTime = 3; ar5212ModifyRfBuffer(rfReg, rfWaitS, 5, 19, 0); ar5212ModifyRfBuffer(rfReg, rfWaitI, 5, 24, 0); ar5212ModifyRfBuffer(rfReg, rfMaxTime, 2, 49, 0); } for (i = 0; i < N(ar5212Bank7_5111); i++) { OS_REG_WRITE(ah, ar5212Bank7_5111[i][0], rfReg[i]); ALLOW_DMA_READ_COMPLETE(regWrites); } /* Now that we have reprogrammed rfgain value, clear the flag. */ ahp->ah_rfgainState = HAL_RFGAIN_INACTIVE; return AH_TRUE; }