2011-03-19 12:55:49

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 1/7] ath9k: remove unnecessary debugfs return code checks

Since the ath9k debugfs directory is cleaned up by debugfs_remove_recursive,
there's no point in checking the return code of every single debugfs create
line.

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath9k/debug.c | 88 ++++++++++---------------------
1 files changed, 29 insertions(+), 59 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 8df5a92..9fe8693 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1088,67 +1088,37 @@ int ath9k_init_debug(struct ath_hw *ah)
return -ENOMEM;

#ifdef CONFIG_ATH_DEBUG
- if (!debugfs_create_file("debug", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_debug))
- goto err;
+ debugfs_create_file("debug", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+ sc, &fops_debug);
#endif
-
- if (!debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_dma))
- goto err;
-
- if (!debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_interrupt))
- goto err;
-
- if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_wiphy))
- goto err;
-
- if (!debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_xmit))
- goto err;
-
- if (!debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_stations))
- goto err;
-
- if (!debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_misc))
- goto err;
-
- if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_recv))
- goto err;
-
- if (!debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_rx_chainmask))
- goto err;
-
- if (!debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_tx_chainmask))
- goto err;
-
- if (!debugfs_create_file("regidx", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_regidx))
- goto err;
-
- if (!debugfs_create_file("regval", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_regval))
- goto err;
-
- if (!debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca))
- goto err;
-
- if (!debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy,
- sc, &fops_regdump))
- goto err;
+ debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_dma);
+ debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_interrupt);
+ debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+ sc, &fops_wiphy);
+ debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_xmit);
+ debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_stations);
+ debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_misc);
+ debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_recv);
+ debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy, sc, &fops_rx_chainmask);
+ debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
+ debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+ sc, &fops_regidx);
+ debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+ sc, &fops_regval);
+ debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy,
+ &ah->config.cwm_ignore_extcca);
+ debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_regdump);

sc->debug.regidx = 0;
return 0;
-err:
- debugfs_remove_recursive(sc->debug.debugfs_phy);
- sc->debug.debugfs_phy = NULL;
- return -ENOMEM;
}
--
1.7.3.2



2011-03-19 12:55:49

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 2/7] ath9k: add an interface for overriding the value of specific GPIO pins

Some devices control antenna settings or other things through GPIO pins
of the wireless interface. Add a debugfs interface for changing those
and keeping them set across card resets.

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath9k/debug.c | 6 ++++++
drivers/net/wireless/ath/ath9k/hw.c | 16 ++++++++++++++++
drivers/net/wireless/ath/ath9k/hw.h | 2 ++
3 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 9fe8693..a762cad 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1119,6 +1119,12 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_regdump);

+ debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
+
+ debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
+
sc->debug.regidx = 0;
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 338b075..b170c45 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1212,6 +1212,20 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
return true;
}

+static void ath9k_hw_apply_gpio_override(struct ath_hw *ah)
+{
+ u32 gpio_mask = ah->gpio_mask;
+ int i;
+
+ for (i = 0; gpio_mask; i++, gpio_mask >>= 1) {
+ if (!(gpio_mask & 1))
+ continue;
+
+ ath9k_hw_cfg_output(ah, i, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i)));
+ }
+}
+
bool ath9k_hw_check_alive(struct ath_hw *ah)
{
int count = 50;
@@ -1500,6 +1514,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (AR_SREV_9300_20_OR_LATER(ah))
ar9003_hw_bb_watchdog_config(ah);

+ ath9k_hw_apply_gpio_override(ah);
+
return 0;
}
EXPORT_SYMBOL(ath9k_hw_reset);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 6650fd4..91010e3 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -795,6 +795,8 @@ struct ath_hw {
int initPDADC;
int PDADCdelta;
u8 led_pin;
+ u32 gpio_mask;
+ u32 gpio_val;

struct ar5416IniArray iniModes;
struct ar5416IniArray iniCommon;
--
1.7.3.2


2011-03-19 12:55:49

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 6/7] ath9k_hw: force rx chainmask to 7 on AR9100

Most AR9100 devices already have a chainmask of 7 (three antennas), however
on the ones that don't (rx and tx chainmask set to 5), problems with IQ
mismatch calibration have been observed.
This shows up as tx queue hangs (and subsequent hardware resets) if traffic
is sent during this type of calibration.
Forcing the rx chainmask to 7 fixes the calibration issues with no apparent
negative side effects on throughput and stability.

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

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 175c36f..8b86568 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1869,6 +1869,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
!(AR_SREV_9271(ah)))
/* CB71: GPIO 0 is pulled down to indicate 3 rx chains */
pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
+ else if (AR_SREV_9100(ah))
+ pCap->rx_chainmask = 0x7;
else
/* Use rx_chainmask from EEPROM. */
pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
--
1.7.3.2


2011-03-19 12:55:49

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 4/7] ath9k: add support for overriding LED pin and GPIO settings from platform data

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath9k/gpio.c | 14 ++++++++------
drivers/net/wireless/ath/ath9k/hw.h | 2 +-
drivers/net/wireless/ath/ath9k/init.c | 8 +++++++-
include/linux/ath9k_platform.h | 4 ++++
4 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 0fb8f8a..44a0a88 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -41,12 +41,14 @@ void ath_init_leds(struct ath_softc *sc)
{
int ret;

- if (AR_SREV_9287(sc->sc_ah))
- 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
- sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
+ if (sc->sc_ah->led_pin < 0) {
+ if (AR_SREV_9287(sc->sc_ah))
+ 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
+ sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
+ }

/* Configure gpio 1 for output */
ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 91010e3..cd314d6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -794,7 +794,7 @@ struct ath_hw {
u32 originalGain[22];
int initPDADC;
int PDADCdelta;
- u8 led_pin;
+ int led_pin;
u32 gpio_mask;
u32 gpio_val;

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index e22e821..cdb0f1c 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -553,8 +553,14 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
ah->hw_version.subsysid = subsysid;
sc->sc_ah = ah;

- if (!pdata)
+ if (!pdata) {
ah->ah_flags |= AH_USE_EEPROM;
+ sc->sc_ah->led_pin = -1;
+ } else {
+ sc->sc_ah->gpio_mask = pdata->gpio_mask;
+ sc->sc_ah->gpio_val = pdata->gpio_val;
+ sc->sc_ah->led_pin = pdata->led_pin;
+ }

common = ath9k_hw_common(ah);
common->ops = &ath9k_common_ops;
diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h
index b5f0658..020387a 100644
--- a/include/linux/ath9k_platform.h
+++ b/include/linux/ath9k_platform.h
@@ -24,6 +24,10 @@
struct ath9k_platform_data {
u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
u8 *macaddr;
+
+ int led_pin;
+ u32 gpio_mask;
+ u32 gpio_val;
};

#endif /* _LINUX_ATH9K_PLATFORM_H */
--
1.7.3.2


2011-03-19 12:55:49

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 3/7] ath9k: add support for overriding the MAC address through platform data

On some devices the correct MAC address is not in the EEPROM data, but
stored somewhere else.

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath9k/init.c | 7 ++++++-
include/linux/ath9k_platform.h | 1 +
2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 79aec98..e22e821 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -15,6 +15,7 @@
*/

#include <linux/slab.h>
+#include <linux/ath9k_platform.h>

#include "ath9k.h"

@@ -537,6 +538,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
const struct ath_bus_ops *bus_ops)
{
+ struct ath9k_platform_data *pdata = sc->dev->platform_data;
struct ath_hw *ah = NULL;
struct ath_common *common;
int ret = 0, i;
@@ -551,7 +553,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
ah->hw_version.subsysid = subsysid;
sc->sc_ah = ah;

- if (!sc->dev->platform_data)
+ if (!pdata)
ah->ah_flags |= AH_USE_EEPROM;

common = ath9k_hw_common(ah);
@@ -587,6 +589,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
if (ret)
goto err_hw;

+ if (pdata && pdata->macaddr)
+ memcpy(common->macaddr, pdata->macaddr, ETH_ALEN);
+
ret = ath9k_init_queues(sc);
if (ret)
goto err_queues;
diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h
index b847fc7..b5f0658 100644
--- a/include/linux/ath9k_platform.h
+++ b/include/linux/ath9k_platform.h
@@ -23,6 +23,7 @@

struct ath9k_platform_data {
u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
+ u8 *macaddr;
};

#endif /* _LINUX_ATH9K_PLATFORM_H */
--
1.7.3.2


2011-03-19 12:55:49

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 7/7] ath9k: remove the pending frames ath_txq_schedule workaround

This workaround called ath_txq_schedule whenever there were still pending
frames for a queue, but the queue depth was zero. Because of its its high
false positive probability (e.g. with paused TIDs) and because it is in
the way of other pending work (AP powersave fixes), it is better to remove
this code entirely.

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath9k/xmit.c | 27 ---------------------------
1 files changed, 0 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index ef22096..65f1217 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2144,33 +2144,6 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
} else {
txq->axq_tx_inprogress = true;
}
- } else {
- /* If the queue has pending buffers, then it
- * should be doing tx work (and have axq_depth).
- * Shouldn't get to this state I think..but
- * we do.
- */
- if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) &&
- (txq->pending_frames > 0 ||
- !list_empty(&txq->axq_acq) ||
- txq->stopped)) {
- ath_err(ath9k_hw_common(sc->sc_ah),
- "txq: %p axq_qnum: %u,"
- " mac80211_qnum: %i"
- " axq_link: %p"
- " pending frames: %i"
- " axq_acq empty: %i"
- " stopped: %i"
- " axq_depth: 0 Attempting to"
- " restart tx logic.\n",
- txq, txq->axq_qnum,
- txq->mac80211_qnum,
- txq->axq_link,
- txq->pending_frames,
- list_empty(&txq->axq_acq),
- txq->stopped);
- ath_txq_schedule(sc, txq);
- }
}
spin_unlock_bh(&txq->axq_lock);
}
--
1.7.3.2


2011-03-19 12:55:49

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 5/7] ath9k_hw: enable a BlockAck related fixup specific to AR9100

Fixes interop issues with aggregation in combination with multi-BSSID

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

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index b170c45..175c36f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -410,6 +410,8 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
ah->sta_id1_defaults =
AR_STA_ID1_CRPT_MIC_ENABLE |
AR_STA_ID1_MCAST_KSRCH;
+ if (AR_SREV_9100(ah))
+ ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX;
ah->enable_32kHz_clock = DONT_USE_32KHZ;
ah->slottime = 20;
ah->globaltxtimeout = (u32) -1;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 8fa8acf..693d543 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1396,6 +1396,7 @@ enum {
#define AR_STA_ID1_PCF 0x00100000
#define AR_STA_ID1_USE_DEFANT 0x00200000
#define AR_STA_ID1_DEFANT_UPDATE 0x00400000
+#define AR_STA_ID1_AR9100_BA_FIX 0x00400000
#define AR_STA_ID1_RTS_USE_DEF 0x00800000
#define AR_STA_ID1_ACKCTS_6MB 0x01000000
#define AR_STA_ID1_BASE_RATE_11B 0x02000000
--
1.7.3.2