diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/phy.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath5k/phy.c | 143 | 
1 files changed, 88 insertions, 55 deletions
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 78c26fdccad..62ce2f4e860 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -282,6 +282,34 @@ int ath5k_hw_phy_disable(struct ath5k_hw *ah)  	return 0;  } +/* + * Wait for synth to settle + */ +static void ath5k_hw_wait_for_synth(struct ath5k_hw *ah, +			struct ieee80211_channel *channel) +{ +	/* +	 * On 5211+ read activation -> rx delay +	 * and use it (100ns steps). +	 */ +	if (ah->ah_version != AR5K_AR5210) { +		u32 delay; +		delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & +			AR5K_PHY_RX_DELAY_M; +		delay = (channel->hw_value & CHANNEL_CCK) ? +			((delay << 2) / 22) : (delay / 10); +		if (ah->ah_bwmode == AR5K_BWMODE_10MHZ) +			delay = delay << 1; +		if (ah->ah_bwmode == AR5K_BWMODE_5MHZ) +			delay = delay << 2; +		/* XXX: /2 on turbo ? Let's be safe +		 * for now */ +		udelay(100 + delay); +	} else { +		mdelay(1); +	} +} +  /**********************\  * RF Gain optimization * @@ -1253,6 +1281,7 @@ static int ath5k_hw_channel(struct ath5k_hw *ah,  	case AR5K_RF5111:  		ret = ath5k_hw_rf5111_channel(ah, channel);  		break; +	case AR5K_RF2317:  	case AR5K_RF2425:  		ret = ath5k_hw_rf2425_channel(ah, channel);  		break; @@ -3237,6 +3266,13 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,  		/* Failed */  		if (i >= 100)  			return -EIO; + +		/* Set channel and wait for synth */ +		ret = ath5k_hw_channel(ah, channel); +		if (ret) +			return ret; + +		ath5k_hw_wait_for_synth(ah, channel);  	}  	/* @@ -3251,13 +3287,53 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,  	if (ret)  		return ret; +	/* Write OFDM timings on 5212*/ +	if (ah->ah_version == AR5K_AR5212 && +		channel->hw_value & CHANNEL_OFDM) { + +		ret = ath5k_hw_write_ofdm_timings(ah, channel); +		if (ret) +			return ret; + +		/* Spur info is available only from EEPROM versions +		 * greater than 5.3, but the EEPROM routines will use +		 * static values for older versions */ +		if (ah->ah_mac_srev >= AR5K_SREV_AR5424) +			ath5k_hw_set_spur_mitigation_filter(ah, +							    channel); +	} + +	/* If we used fast channel switching +	 * we are done, release RF bus and +	 * fire up NF calibration. +	 * +	 * Note: Only NF calibration due to +	 * channel change, not AGC calibration +	 * since AGC is still running ! +	 */ +	if (fast) { +		/* +		 * Release RF Bus grant +		 */ +		AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, +				    AR5K_PHY_RFBUS_REQ_REQUEST); + +		/* +		 * Start NF calibration +		 */ +		AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, +					AR5K_PHY_AGCCTL_NF); + +		return ret; +	} +  	/*  	 * For 5210 we do all initialization using  	 * initvals, so we don't have to modify  	 * any settings (5210 also only supports  	 * a/aturbo modes)  	 */ -	if ((ah->ah_version != AR5K_AR5210) && !fast) { +	if (ah->ah_version != AR5K_AR5210) {  		/*  		 * Write initial RF gain settings @@ -3276,22 +3352,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,  		if (ret)  			return ret; -		/* Write OFDM timings on 5212*/ -		if (ah->ah_version == AR5K_AR5212 && -			channel->hw_value & CHANNEL_OFDM) { - -			ret = ath5k_hw_write_ofdm_timings(ah, channel); -			if (ret) -				return ret; - -			/* Spur info is available only from EEPROM versions -			 * greater than 5.3, but the EEPROM routines will use -			 * static values for older versions */ -			if (ah->ah_mac_srev >= AR5K_SREV_AR5424) -				ath5k_hw_set_spur_mitigation_filter(ah, -								    channel); -		} -  		/*Enable/disable 802.11b mode on 5111  		(enable 2111 frequency converter + CCK)*/  		if (ah->ah_radio == AR5K_RF5111) { @@ -3322,47 +3382,20 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,  	 */  	ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); +	ath5k_hw_wait_for_synth(ah, channel); +  	/* -	 * On 5211+ read activation -> rx delay -	 * and use it. +	 * Perform ADC test to see if baseband is ready +	 * Set tx hold and check adc test register  	 */ -	if (ah->ah_version != AR5K_AR5210) { -		u32 delay; -		delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & -			AR5K_PHY_RX_DELAY_M; -		delay = (channel->hw_value & CHANNEL_CCK) ? -			((delay << 2) / 22) : (delay / 10); -		if (ah->ah_bwmode == AR5K_BWMODE_10MHZ) -			delay = delay << 1; -		if (ah->ah_bwmode == AR5K_BWMODE_5MHZ) -			delay = delay << 2; -		/* XXX: /2 on turbo ? Let's be safe -		 * for now */ -		udelay(100 + delay); -	} else { -		mdelay(1); -	} - -	if (fast) -		/* -		 * Release RF Bus grant -		 */ -		AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, -				    AR5K_PHY_RFBUS_REQ_REQUEST); -	else { -		/* -		 * Perform ADC test to see if baseband is ready -		 * Set tx hold and check adc test register -		 */ -		phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); -		ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); -		for (i = 0; i <= 20; i++) { -			if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) -				break; -			udelay(200); -		} -		ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); +	phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); +	ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); +	for (i = 0; i <= 20; i++) { +		if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) +			break; +		udelay(200);  	} +	ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);  	/*  	 * Start automatic gain control calibration  |