rfgain probe is only necessary for OFDM operation on AR5111 and AR5112.
Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath5k/phy.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index e00ab5a..3f19e31 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1604,11 +1604,13 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
int ret;
if (ah->ah_radio == AR5K_RF5110)
- ret = ath5k_hw_rf5110_calibrate(ah, channel);
- else {
- ret = ath5k_hw_rf511x_iq_calibrate(ah);
+ return ath5k_hw_rf5110_calibrate(ah, channel);
+
+ ret = ath5k_hw_rf511x_iq_calibrate(ah);
+
+ if ((ah->ah_radio == AR5K_RF5111 || ah->ah_radio == AR5K_RF5112) &&
+ (channel->hw_value & CHANNEL_OFDM))
ath5k_hw_request_rfgain_probe(ah);
- }
return ret;
}
--
1.7.3.2
enabling the sleep clock alters the AR5K_USEC_32 field, but disabling
it didn't restore it.
Signed-off-by: Felix Fietkau <[email protected]>
Acked-by: Nick Kossifidis <[email protected]>
---
drivers/net/wireless/ath/ath5k/reset.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 57f2e56..0e89fc9 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -142,6 +142,7 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
/* Set 32MHz USEC counter */
if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF2413) ||
(ah->ah_radio == AR5K_RF5413) ||
(ah->ah_radio == AR5K_RF2316) ||
(ah->ah_radio == AR5K_RF2317))
@@ -233,7 +234,7 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- u32 scal, spending;
+ u32 scal, spending, sclock;
/* Only set 32KHz settings if we have an external
* 32KHz crystal present */
@@ -317,6 +318,15 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
/* Set up tsf increment on each cycle */
AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_radio == AR5K_RF2316) ||
+ (ah->ah_radio == AR5K_RF2317))
+ sclock = 40 - 1;
+ else
+ sclock = 32 - 1;
+ AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, sclock);
}
}
--
1.7.3.2
During scans the full calibration usually does not make much sense,
PAPD probing and IQ calibration should be deferred until there is
enough time to complete them. Adding 100 ms to the initial full
calibration delay should be enough to do this.
Signed-off-by: Felix Fietkau <[email protected]>
Acked-by: Nick Kossifidis <[email protected]>
---
drivers/net/wireless/ath/ath5k/base.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 523bb08..3b58e00 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2725,7 +2725,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
ath5k_ani_init(ah, ani_mode);
- ah->ah_cal_next_full = jiffies;
+ ah->ah_cal_next_full = jiffies + msecs_to_jiffies(100);
ah->ah_cal_next_ani = jiffies;
ah->ah_cal_next_nf = jiffies;
ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8);
--
1.7.3.2
While 32 KHz sleep clock might provide some power saving benefits,
it is also a major source of stability issues, on OpenWrt it produced
some reproducible data bus errors on register accesses on several
different MIPS platforms.
All the Atheros drivers that I can find do not enable this feature,
so it makes sense to leave it disabled in ath5k as well.
Signed-off-by: Felix Fietkau <[email protected]>
Acked-by: Nick Kossifidis <[email protected]>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 2 ++
drivers/net/wireless/ath/ath5k/debug.c | 3 +++
drivers/net/wireless/ath/ath5k/reset.c | 11 ++++++++---
3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 50d7580..8ff1794 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1067,6 +1067,8 @@ struct ath5k_hw {
u8 ah_retry_long;
u8 ah_retry_short;
+ u32 ah_use_32khz_clock;
+
u8 ah_coverage_class;
bool ah_ack_bitrate_high;
u8 ah_bwmode;
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index ae1112b..4edca70 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -922,6 +922,9 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, sc,
&fops_queue);
+
+ debugfs_create_bool("32khz_clock", S_IWUSR | S_IRUSR, phydir,
+ &sc->ah->ah_use_32khz_clock);
}
/* functions used in other places */
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 0e89fc9..9f9c2ad 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1287,11 +1287,16 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ath5k_hw_dma_init(ah);
- /* Enable 32KHz clock function for AR5212+ chips
+ /*
+ * Enable 32KHz clock function for AR5212+ chips
* Set clocks to 32KHz operation and use an
* external 32KHz crystal when sleeping if one
- * exists */
- if (ah->ah_version == AR5K_AR5212 &&
+ * exists.
+ * Disabled by default because it is also disabled in
+ * other drivers and it is known to cause stability
+ * issues on some devices
+ */
+ if (ah->ah_use_32khz_clock && ah->ah_version == AR5K_AR5212 &&
op_mode != NL80211_IFTYPE_AP)
ath5k_hw_set_sleep_clock(ah, true);
--
1.7.3.2
AR2413 uses the same reference clock as AR5413
Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath5k/phy.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index acf73a0..dd2b417 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -105,6 +105,7 @@ bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
if ((ah->ah_radio == AR5K_RF5112) ||
(ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_radio == AR5K_RF2413) ||
(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
refclk_freq = 40;
else
--
1.7.3.2
Might fix some stability issues on newer chips
Signed-off-by: Felix Fietkau <[email protected]>
Acked-by: Nick Kossifidis <[email protected]>
---
drivers/net/wireless/ath/ath5k/phy.c | 19 +++++++++++--------
1 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 3f19e31..acf73a0 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -970,17 +970,20 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
}
/* Lower synth voltage on Rev 2 */
- ath5k_hw_rfb_op(ah, rf_regs, 2,
- AR5K_RF_HIGH_VC_CP, true);
+ if (ah->ah_radio == AR5K_RF5112 &&
+ (ah->ah_radio_5ghz_revision & AR5K_SREV_REV) > 0) {
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_HIGH_VC_CP, true);
- ath5k_hw_rfb_op(ah, rf_regs, 2,
- AR5K_RF_MID_VC_CP, true);
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_MID_VC_CP, true);
- ath5k_hw_rfb_op(ah, rf_regs, 2,
- AR5K_RF_LOW_VC_CP, true);
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_LOW_VC_CP, true);
- ath5k_hw_rfb_op(ah, rf_regs, 2,
- AR5K_RF_PUSH_UP, true);
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_PUSH_UP, true);
+ }
/* Decrease power consumption on 5213+ BaseBand */
if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
--
1.7.3.2
Fixes a division by zero when setting distance before activating the
device for the first time.
Signed-off-by: Felix Fietkau <[email protected]>
Acked-by: Nick Kossifidis <[email protected]>
---
drivers/net/wireless/ath/ath5k/base.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 3e5e9b7..523bb08 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2420,6 +2420,7 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
common->ah = sc->ah;
common->hw = hw;
common->priv = sc;
+ common->clockrate = 40;
/*
* Cache line size is used to size and align various
--
1.7.3.2
Instead of using ieee80211_stop_queue, check the configured tx queue
limit before calling ieee80211_get_buffered_bc.
Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath5k/base.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 3b58e00..5f055d6 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1554,7 +1554,8 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
goto drop_packet;
}
- if (txq->txq_len >= txq->txq_max)
+ if (txq->txq_len >= txq->txq_max &&
+ txq->qnum <= AR5K_TX_QUEUE_ID_DATA_MAX)
ieee80211_stop_queue(hw, txq->qnum);
spin_lock_irqsave(&sc->txbuflock, flags);
@@ -1930,6 +1931,10 @@ ath5k_beacon_send(struct ath5k_softc *sc)
skb = ieee80211_get_buffered_bc(sc->hw, vif);
while (skb) {
ath5k_tx_queue(sc->hw, skb, sc->cabq);
+
+ if (sc->cabq->txq_len >= sc->cabq->txq_max)
+ break;
+
skb = ieee80211_get_buffered_bc(sc->hw, vif);
}
--
1.7.3.2