2011-04-22 06:02:38

by Senthil Balasubramanian

[permalink] [raw]
Subject: [PATCH 1/5] ath9k: Fix LED gpio for AR93xx chipsets.

The LED gpio is incorrectly programmed for AR9300 and so the led
is not working propelry. AR93xx uses gpio 10 for LED and not the
default.

Signed-off-by: Senthil Balasubramanian <[email protected]>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 1 +
drivers/net/wireless/ath/ath9k/gpio.c | 2 ++
2 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index a6b5388..5ebfc57 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -453,6 +453,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc);

#define ATH_LED_PIN_DEF 1
#define ATH_LED_PIN_9287 8
+#define ATH_LED_PIN_9300 10
#define ATH_LED_PIN_9485 6

#ifdef CONFIG_MAC80211_LEDS
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 44a0a88..3e617e7 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -46,6 +46,8 @@ void ath_init_leds(struct ath_softc *sc)
sc->sc_ah->led_pin = ATH_LED_PIN_9287;
else if (AR_SREV_9485(sc->sc_ah))
sc->sc_ah->led_pin = ATH_LED_PIN_9485;
+ else if (AR_SREV_9300(sc->sc_ah))
+ sc->sc_ah->led_pin = ATH_LED_PIN_9300;
else
sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
}
--
1.7.0.4



2011-04-22 06:02:49

by Senthil Balasubramanian

[permalink] [raw]
Subject: [PATCH 3/5] ath9k: optimize the usage of power save wrappers.

We need not wake up the chip even before mutex lock is acquired and also
that it is required only if we are going to drain the txq. So place the
wrappers accordingly and this change is also useful when there are no
pending frames in the txq as we do not wake up the chip unnecessarily.

Signed-off-by: Senthil Balasubramanian <[email protected]>
---
drivers/net/wireless/ath/ath9k/main.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a8d9009..37b80ac 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2219,9 +2219,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
int timeout = 200; /* ms */
int i, j;

- ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex);
-
cancel_delayed_work_sync(&sc->tx_complete_work);

if (drop)
@@ -2244,15 +2242,15 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
goto out;
}

+ ath9k_ps_wakeup(sc);
if (!ath_drain_all_txq(sc, false))
ath_reset(sc, false);
-
+ ath9k_ps_restore(sc);
ieee80211_wake_queues(hw);

out:
ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
mutex_unlock(&sc->mutex);
- ath9k_ps_restore(sc);
}

static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
--
1.7.0.4


2011-04-22 06:02:54

by Senthil Balasubramanian

[permalink] [raw]
Subject: [PATCH 4/5] ath9k: cleanup hw pll work handler

There is no reason why pll work handler should be part of xmit
file. move it to main.c so that reading hw check routines are
all in the same place.

Signed-off-by: Senthil Balasubramanian <[email protected]>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 1 +
drivers/net/wireless/ath/ath9k/init.c | 1 +
drivers/net/wireless/ath/ath9k/main.c | 23 +++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/xmit.c | 23 -----------------------
4 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 5ebfc57..0312aa0 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -423,6 +423,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
#define ATH_PAPRD_TIMEOUT 100 /* msecs */

void ath_hw_check(struct work_struct *work);
+void ath_hw_pll_work(struct work_struct *work);
void ath_paprd_calibrate(struct work_struct *work);
void ath_ani_calibrate(unsigned long data);

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index e78b6ae..b172d15 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -801,6 +801,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,

INIT_WORK(&sc->hw_check_work, ath_hw_check);
INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
+ INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
sc->last_rssi = ATH_RSSI_DUMMY_MARKER;

ath_init_leds(sc);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 37b80ac..fa80e13 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -624,6 +624,29 @@ out:
ath9k_ps_restore(sc);
}

+void ath_hw_pll_work(struct work_struct *work)
+{
+ struct ath_softc *sc = container_of(work, struct ath_softc,
+ hw_pll_work.work);
+ static int count;
+
+ if (AR_SREV_9485(sc->sc_ah)) {
+ if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) {
+ count++;
+
+ if (count == 3) {
+ /* Rx is hung for more than 500ms. Reset it */
+ ath_reset(sc, true);
+ count = 0;
+ }
+ } else
+ count = 0;
+
+ ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
+ }
+}
+
+
void ath9k_tasklet(unsigned long data)
{
struct ath_softc *sc = (struct ath_softc *)data;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index e9e99f7..7b91b2a 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2180,28 +2180,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
}
}

-static void ath_hw_pll_work(struct work_struct *work)
-{
- struct ath_softc *sc = container_of(work, struct ath_softc,
- hw_pll_work.work);
- static int count;
-
- if (AR_SREV_9485(sc->sc_ah)) {
- if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) {
- count++;
-
- if (count == 3) {
- /* Rx is hung for more than 500ms. Reset it */
- ath_reset(sc, true);
- count = 0;
- }
- } else
- count = 0;
-
- ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
- }
-}
-
static void ath_tx_complete_poll_work(struct work_struct *work)
{
struct ath_softc *sc = container_of(work, struct ath_softc,
@@ -2396,7 +2374,6 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
}

INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
- INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);

if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
error = ath_tx_edma_init(sc);
--
1.7.0.4


2011-04-22 06:03:00

by Senthil Balasubramanian

[permalink] [raw]
Subject: [PATCH 5/5] ath9k: Add power save wrappers and modularize hw_pll handler

We should protect hw_pll handler with power save wrappers and
also modularize hw_pll handler properly for better readability.

Also add a debug message to track chip resets on pll hang condition.

Signed-off-by: Senthil Balasubramanian <[email protected]>
---
drivers/net/wireless/ath/ath9k/hw.c | 2 +-
drivers/net/wireless/ath/ath9k/hw.h | 2 +-
drivers/net/wireless/ath/ath9k/main.c | 36 ++++++++++++++++++++++----------
3 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 289c03e..dfea703 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -673,7 +673,7 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
REGWRITE_BUFFER_FLUSH(ah);
}

-unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
+u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
{
REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
udelay(100);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 29a745c..6a028bd 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -932,7 +932,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
void ath9k_hw_reset_tsf(struct ath_hw *ah);
void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
void ath9k_hw_init_global_settings(struct ath_hw *ah);
-unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
+u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
void ath9k_hw_set11nmac2040(struct ath_hw *ah);
void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index fa80e13..475009b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -624,23 +624,37 @@ out:
ath9k_ps_restore(sc);
}

+static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
+{
+ static int count;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+
+ if (pll_sqsum >= 0x40000) {
+ count++;
+ if (count == 3) {
+ /* Rx is hung for more than 500ms. Reset it */
+ ath_dbg(common, ATH_DBG_RESET,
+ "Possible RX hang, resetting");
+ ath_reset(sc, true);
+ count = 0;
+ }
+ } else
+ count = 0;
+}
+
void ath_hw_pll_work(struct work_struct *work)
{
struct ath_softc *sc = container_of(work, struct ath_softc,
hw_pll_work.work);
- static int count;
+ u32 pll_sqsum;

if (AR_SREV_9485(sc->sc_ah)) {
- if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) {
- count++;

- if (count == 3) {
- /* Rx is hung for more than 500ms. Reset it */
- ath_reset(sc, true);
- count = 0;
- }
- } else
- count = 0;
+ ath9k_ps_wakeup(sc);
+ pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
+ ath9k_ps_restore(sc);
+
+ ath_hw_pll_rx_hang_check(sc, pll_sqsum);

ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
}
--
1.7.0.4


2011-04-22 06:02:44

by Senthil Balasubramanian

[permalink] [raw]
Subject: [PATCH 2/5] ath9k_hw: Fix incorrect baseband PLL phase shift for AR9485

we should program the AR9485 baseband PLL phase shift to 6 and
a redundant setting overwrites the correct value. Remove the
incorrect and unwnated register setting.

Signed-off-by: Senthil Balasubramanian <[email protected]>
---
drivers/net/wireless/ath/ath9k/hw.c | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 9a89855..289c03e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -686,7 +686,6 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
}
EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc);

-#define DPLL3_PHASE_SHIFT_VAL 0x1
static void ath9k_hw_init_pll(struct ath_hw *ah,
struct ath9k_channel *chan)
{
@@ -723,9 +722,6 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
AR_CH0_BB_DPLL2_PLL_PWD, 0x0);
udelay(1000);
-
- REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
- AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
} else if (AR_SREV_9340(ah)) {
u32 regval, pll2_divint, pll2_divfrac, refdiv;

--
1.7.0.4