|
Kyle McMartin |
928e7a8 |
From sgruszka@redhat.com Thu Feb 3 07:58:52 2011
|
|
Kyle McMartin |
928e7a8 |
Date: Thu, 3 Feb 2011 13:58:51 +0100
|
|
Kyle McMartin |
928e7a8 |
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
|
Kyle McMartin |
928e7a8 |
To: kernel@lists.fedoraproject.org
|
|
Kyle McMartin |
928e7a8 |
Cc: Kyle McMartin <kmcmartin@redhat.com>
|
|
Kyle McMartin |
928e7a8 |
Subject: [PATCH F-15] ath5k: fix fast channel change
|
|
Kyle McMartin |
928e7a8 |
Message-ID: <20110203125134.GA4515@redhat.com>
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
From: Nick Kossifidis <mickflemm@gmail.com>
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
Fast channel change fixes:
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
a) Always set OFDM timings
|
|
Kyle McMartin |
928e7a8 |
b) Don't re-activate PHY
|
|
Kyle McMartin |
928e7a8 |
c) Enable only NF calibration, not AGC
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
Resolves:
|
|
Kyle McMartin |
928e7a8 |
https://bugzilla.redhat.com/show_bug.cgi?id=672778
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
---
|
|
Kyle McMartin |
928e7a8 |
drivers/net/wireless/ath/ath5k/phy.c | 142 +++++++++++++++++++++-------------
|
|
Kyle McMartin |
928e7a8 |
1 files changed, 87 insertions(+), 55 deletions(-)
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
|
|
Kyle McMartin |
928e7a8 |
index 78c26fd..d673ab2 100644
|
|
Kyle McMartin |
928e7a8 |
--- a/drivers/net/wireless/ath/ath5k/phy.c
|
|
Kyle McMartin |
928e7a8 |
+++ b/drivers/net/wireless/ath/ath5k/phy.c
|
|
Kyle McMartin |
928e7a8 |
@@ -282,6 +282,34 @@ int ath5k_hw_phy_disable(struct ath5k_hw *ah)
|
|
Kyle McMartin |
928e7a8 |
return 0;
|
|
Kyle McMartin |
928e7a8 |
}
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
+/*
|
|
Kyle McMartin |
928e7a8 |
+ * Wait for synth to settle
|
|
Kyle McMartin |
928e7a8 |
+ */
|
|
Kyle McMartin |
928e7a8 |
+static void ath5k_hw_wait_for_synth(struct ath5k_hw *ah,
|
|
Kyle McMartin |
928e7a8 |
+ struct ieee80211_channel *channel)
|
|
Kyle McMartin |
928e7a8 |
+{
|
|
Kyle McMartin |
928e7a8 |
+ /*
|
|
Kyle McMartin |
928e7a8 |
+ * On 5211+ read activation -> rx delay
|
|
Kyle McMartin |
928e7a8 |
+ * and use it (100ns steps).
|
|
Kyle McMartin |
928e7a8 |
+ */
|
|
Kyle McMartin |
928e7a8 |
+ if (ah->ah_version != AR5K_AR5210) {
|
|
Kyle McMartin |
928e7a8 |
+ u32 delay;
|
|
Kyle McMartin |
928e7a8 |
+ delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
|
|
Kyle McMartin |
928e7a8 |
+ AR5K_PHY_RX_DELAY_M;
|
|
Kyle McMartin |
928e7a8 |
+ delay = (channel->hw_value & CHANNEL_CCK) ?
|
|
Kyle McMartin |
928e7a8 |
+ ((delay << 2) / 22) : (delay / 10);
|
|
Kyle McMartin |
928e7a8 |
+ if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)
|
|
Kyle McMartin |
928e7a8 |
+ delay = delay << 1;
|
|
Kyle McMartin |
928e7a8 |
+ if (ah->ah_bwmode == AR5K_BWMODE_5MHZ)
|
|
Kyle McMartin |
928e7a8 |
+ delay = delay << 2;
|
|
Kyle McMartin |
928e7a8 |
+ /* XXX: /2 on turbo ? Let's be safe
|
|
Kyle McMartin |
928e7a8 |
+ * for now */
|
|
Kyle McMartin |
928e7a8 |
+ udelay(100 + delay);
|
|
Kyle McMartin |
928e7a8 |
+ } else {
|
|
Kyle McMartin |
928e7a8 |
+ mdelay(1);
|
|
Kyle McMartin |
928e7a8 |
+ }
|
|
Kyle McMartin |
928e7a8 |
+}
|
|
Kyle McMartin |
928e7a8 |
+
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
/**********************\
|
|
Kyle McMartin |
928e7a8 |
* RF Gain optimization *
|
|
Kyle McMartin |
928e7a8 |
@@ -3237,6 +3265,13 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
|
Kyle McMartin |
928e7a8 |
/* Failed */
|
|
Kyle McMartin |
928e7a8 |
if (i >= 100)
|
|
Kyle McMartin |
928e7a8 |
return -EIO;
|
|
Kyle McMartin |
928e7a8 |
+
|
|
Kyle McMartin |
928e7a8 |
+ /* Set channel and wait for synth */
|
|
Kyle McMartin |
928e7a8 |
+ ret = ath5k_hw_channel(ah, channel);
|
|
Kyle McMartin |
928e7a8 |
+ if (ret)
|
|
Kyle McMartin |
928e7a8 |
+ return ret;
|
|
Kyle McMartin |
928e7a8 |
+
|
|
Kyle McMartin |
928e7a8 |
+ ath5k_hw_wait_for_synth(ah, channel);
|
|
Kyle McMartin |
928e7a8 |
}
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
/*
|
|
Kyle McMartin |
928e7a8 |
@@ -3251,13 +3286,53 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
|
Kyle McMartin |
928e7a8 |
if (ret)
|
|
Kyle McMartin |
928e7a8 |
return ret;
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
+ /* Write OFDM timings on 5212*/
|
|
Kyle McMartin |
928e7a8 |
+ if (ah->ah_version == AR5K_AR5212 &&
|
|
Kyle McMartin |
928e7a8 |
+ channel->hw_value & CHANNEL_OFDM) {
|
|
Kyle McMartin |
928e7a8 |
+
|
|
Kyle McMartin |
928e7a8 |
+ ret = ath5k_hw_write_ofdm_timings(ah, channel);
|
|
Kyle McMartin |
928e7a8 |
+ if (ret)
|
|
Kyle McMartin |
928e7a8 |
+ return ret;
|
|
Kyle McMartin |
928e7a8 |
+
|
|
Kyle McMartin |
928e7a8 |
+ /* Spur info is available only from EEPROM versions
|
|
Kyle McMartin |
928e7a8 |
+ * greater than 5.3, but the EEPROM routines will use
|
|
Kyle McMartin |
928e7a8 |
+ * static values for older versions */
|
|
Kyle McMartin |
928e7a8 |
+ if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
|
|
Kyle McMartin |
928e7a8 |
+ ath5k_hw_set_spur_mitigation_filter(ah,
|
|
Kyle McMartin |
928e7a8 |
+ channel);
|
|
Kyle McMartin |
928e7a8 |
+ }
|
|
Kyle McMartin |
928e7a8 |
+
|
|
Kyle McMartin |
928e7a8 |
+ /* If we used fast channel switching
|
|
Kyle McMartin |
928e7a8 |
+ * we are done, release RF bus and
|
|
Kyle McMartin |
928e7a8 |
+ * fire up NF calibration.
|
|
Kyle McMartin |
928e7a8 |
+ *
|
|
Kyle McMartin |
928e7a8 |
+ * Note: Only NF calibration due to
|
|
Kyle McMartin |
928e7a8 |
+ * channel change, not AGC calibration
|
|
Kyle McMartin |
928e7a8 |
+ * since AGC is still running !
|
|
Kyle McMartin |
928e7a8 |
+ */
|
|
Kyle McMartin |
928e7a8 |
+ if (fast) {
|
|
Kyle McMartin |
928e7a8 |
+ /*
|
|
Kyle McMartin |
928e7a8 |
+ * Release RF Bus grant
|
|
Kyle McMartin |
928e7a8 |
+ */
|
|
Kyle McMartin |
928e7a8 |
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
|
|
Kyle McMartin |
928e7a8 |
+ AR5K_PHY_RFBUS_REQ_REQUEST);
|
|
Kyle McMartin |
928e7a8 |
+
|
|
Kyle McMartin |
928e7a8 |
+ /*
|
|
Kyle McMartin |
928e7a8 |
+ * Start NF calibration
|
|
Kyle McMartin |
928e7a8 |
+ */
|
|
Kyle McMartin |
928e7a8 |
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
|
|
Kyle McMartin |
928e7a8 |
+ AR5K_PHY_AGCCTL_NF);
|
|
Kyle McMartin |
928e7a8 |
+
|
|
Kyle McMartin |
928e7a8 |
+ return ret;
|
|
Kyle McMartin |
928e7a8 |
+ }
|
|
Kyle McMartin |
928e7a8 |
+
|
|
Kyle McMartin |
928e7a8 |
/*
|
|
Kyle McMartin |
928e7a8 |
* For 5210 we do all initialization using
|
|
Kyle McMartin |
928e7a8 |
* initvals, so we don't have to modify
|
|
Kyle McMartin |
928e7a8 |
* any settings (5210 also only supports
|
|
Kyle McMartin |
928e7a8 |
* a/aturbo modes)
|
|
Kyle McMartin |
928e7a8 |
*/
|
|
Kyle McMartin |
928e7a8 |
- if ((ah->ah_version != AR5K_AR5210) && !fast) {
|
|
Kyle McMartin |
928e7a8 |
+ if (ah->ah_version != AR5K_AR5210) {
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
/*
|
|
Kyle McMartin |
928e7a8 |
* Write initial RF gain settings
|
|
Kyle McMartin |
928e7a8 |
@@ -3276,22 +3351,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
|
Kyle McMartin |
928e7a8 |
if (ret)
|
|
Kyle McMartin |
928e7a8 |
return ret;
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
- /* Write OFDM timings on 5212*/
|
|
Kyle McMartin |
928e7a8 |
- if (ah->ah_version == AR5K_AR5212 &&
|
|
Kyle McMartin |
928e7a8 |
- channel->hw_value & CHANNEL_OFDM) {
|
|
Kyle McMartin |
928e7a8 |
-
|
|
Kyle McMartin |
928e7a8 |
- ret = ath5k_hw_write_ofdm_timings(ah, channel);
|
|
Kyle McMartin |
928e7a8 |
- if (ret)
|
|
Kyle McMartin |
928e7a8 |
- return ret;
|
|
Kyle McMartin |
928e7a8 |
-
|
|
Kyle McMartin |
928e7a8 |
- /* Spur info is available only from EEPROM versions
|
|
Kyle McMartin |
928e7a8 |
- * greater than 5.3, but the EEPROM routines will use
|
|
Kyle McMartin |
928e7a8 |
- * static values for older versions */
|
|
Kyle McMartin |
928e7a8 |
- if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
|
|
Kyle McMartin |
928e7a8 |
- ath5k_hw_set_spur_mitigation_filter(ah,
|
|
Kyle McMartin |
928e7a8 |
- channel);
|
|
Kyle McMartin |
928e7a8 |
- }
|
|
Kyle McMartin |
928e7a8 |
-
|
|
Kyle McMartin |
928e7a8 |
/*Enable/disable 802.11b mode on 5111
|
|
Kyle McMartin |
928e7a8 |
(enable 2111 frequency converter + CCK)*/
|
|
Kyle McMartin |
928e7a8 |
if (ah->ah_radio == AR5K_RF5111) {
|
|
Kyle McMartin |
928e7a8 |
@@ -3322,47 +3381,20 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
|
|
Kyle McMartin |
928e7a8 |
*/
|
|
Kyle McMartin |
928e7a8 |
ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
+ ath5k_hw_wait_for_synth(ah, channel);
|
|
Kyle McMartin |
928e7a8 |
+
|
|
Kyle McMartin |
928e7a8 |
/*
|
|
Kyle McMartin |
928e7a8 |
- * On 5211+ read activation -> rx delay
|
|
Kyle McMartin |
928e7a8 |
- * and use it.
|
|
Kyle McMartin |
928e7a8 |
+ * Perform ADC test to see if baseband is ready
|
|
Kyle McMartin |
928e7a8 |
+ * Set tx hold and check adc test register
|
|
Kyle McMartin |
928e7a8 |
*/
|
|
Kyle McMartin |
928e7a8 |
- if (ah->ah_version != AR5K_AR5210) {
|
|
Kyle McMartin |
928e7a8 |
- u32 delay;
|
|
Kyle McMartin |
928e7a8 |
- delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
|
|
Kyle McMartin |
928e7a8 |
- AR5K_PHY_RX_DELAY_M;
|
|
Kyle McMartin |
928e7a8 |
- delay = (channel->hw_value & CHANNEL_CCK) ?
|
|
Kyle McMartin |
928e7a8 |
- ((delay << 2) / 22) : (delay / 10);
|
|
Kyle McMartin |
928e7a8 |
- if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)
|
|
Kyle McMartin |
928e7a8 |
- delay = delay << 1;
|
|
Kyle McMartin |
928e7a8 |
- if (ah->ah_bwmode == AR5K_BWMODE_5MHZ)
|
|
Kyle McMartin |
928e7a8 |
- delay = delay << 2;
|
|
Kyle McMartin |
928e7a8 |
- /* XXX: /2 on turbo ? Let's be safe
|
|
Kyle McMartin |
928e7a8 |
- * for now */
|
|
Kyle McMartin |
928e7a8 |
- udelay(100 + delay);
|
|
Kyle McMartin |
928e7a8 |
- } else {
|
|
Kyle McMartin |
928e7a8 |
- mdelay(1);
|
|
Kyle McMartin |
928e7a8 |
- }
|
|
Kyle McMartin |
928e7a8 |
-
|
|
Kyle McMartin |
928e7a8 |
- if (fast)
|
|
Kyle McMartin |
928e7a8 |
- /*
|
|
Kyle McMartin |
928e7a8 |
- * Release RF Bus grant
|
|
Kyle McMartin |
928e7a8 |
- */
|
|
Kyle McMartin |
928e7a8 |
- AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
|
|
Kyle McMartin |
928e7a8 |
- AR5K_PHY_RFBUS_REQ_REQUEST);
|
|
Kyle McMartin |
928e7a8 |
- else {
|
|
Kyle McMartin |
928e7a8 |
- /*
|
|
Kyle McMartin |
928e7a8 |
- * Perform ADC test to see if baseband is ready
|
|
Kyle McMartin |
928e7a8 |
- * Set tx hold and check adc test register
|
|
Kyle McMartin |
928e7a8 |
- */
|
|
Kyle McMartin |
928e7a8 |
- phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
|
|
Kyle McMartin |
928e7a8 |
- ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
|
|
Kyle McMartin |
928e7a8 |
- for (i = 0; i <= 20; i++) {
|
|
Kyle McMartin |
928e7a8 |
- if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
|
|
Kyle McMartin |
928e7a8 |
- break;
|
|
Kyle McMartin |
928e7a8 |
- udelay(200);
|
|
Kyle McMartin |
928e7a8 |
- }
|
|
Kyle McMartin |
928e7a8 |
- ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
|
|
Kyle McMartin |
928e7a8 |
+ phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
|
|
Kyle McMartin |
928e7a8 |
+ ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
|
|
Kyle McMartin |
928e7a8 |
+ for (i = 0; i <= 20; i++) {
|
|
Kyle McMartin |
928e7a8 |
+ if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
|
|
Kyle McMartin |
928e7a8 |
+ break;
|
|
Kyle McMartin |
928e7a8 |
+ udelay(200);
|
|
Kyle McMartin |
928e7a8 |
}
|
|
Kyle McMartin |
928e7a8 |
+ ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
|
|
Kyle McMartin |
928e7a8 |
|
|
Kyle McMartin |
928e7a8 |
/*
|
|
Kyle McMartin |
928e7a8 |
* Start automatic gain control calibration
|