2008-10-04 05:45:40

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 0/3] ath9k: pending patches

This is the list of pending patches for wireless-testing for ath9k.
I hadn't ported over today's fix so its going in this series.

Luis


2008-10-05 02:32:20

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 2/3] ath9k: fix oops on trying to hold the wrong spinlock

On Fri, Oct 3, 2008 at 3:45 PM, Luis R. Rodriguez
<[email protected]> wrote:
> We were trying to hold the wrong spinlock due to a typo
> on IEEE80211_BAR_CTL_TID_S's definition. We use this to
> compute the tid number and then hold this this tid number's
> spinlock.
>
> Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
> Signed-off-by: Sujith <[email protected]>
> Signed-off-by: Luis R. Rodriguez <[email protected]>

Just a head up John -- Ingo has already sucked this into his tree with
a proper Reported-by. We still need it in wireless-testing though, not
sure how that will be handled.

Luis

2008-10-05 02:48:19

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 2/3] ath9k: fix oops on trying to hold the wrong spinlock

On Sat, Oct 4, 2008 at 7:40 PM, Steven Noonan <[email protected]> wrote:
> On Sat, Oct 4, 2008 at 7:32 PM, Luis R. Rodriguez
> <[email protected]> wrote:
>> On Fri, Oct 3, 2008 at 3:45 PM, Luis R. Rodriguez
>> <[email protected]> wrote:
>>> We were trying to hold the wrong spinlock due to a typo
>>> on IEEE80211_BAR_CTL_TID_S's definition. We use this to
>>> compute the tid number and then hold this this tid number's
>>> spinlock.
>>>
>>> Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
>>> Signed-off-by: Sujith <[email protected]>
>>> Signed-off-by: Luis R. Rodriguez <[email protected]>
>>
>> Just a head up John -- Ingo has already sucked this into his tree with
>> a proper Reported-by. We still need it in wireless-testing though, not
>> sure how that will be handled.
>>
>> Luis
>
> Oh, I should add a tested-by for this.
>
> Tested-by: Steven Noonan <[email protected]>

Thanks a lot for testing this Steven, your reports and tests are
greatly appreciated.

Let us know how ANI goes :)

Luis

2008-10-05 02:40:06

by Steven Noonan

[permalink] [raw]
Subject: Re: [PATCH 2/3] ath9k: fix oops on trying to hold the wrong spinlock

On Sat, Oct 4, 2008 at 7:32 PM, Luis R. Rodriguez
<[email protected]> wrote:
> On Fri, Oct 3, 2008 at 3:45 PM, Luis R. Rodriguez
> <[email protected]> wrote:
>> We were trying to hold the wrong spinlock due to a typo
>> on IEEE80211_BAR_CTL_TID_S's definition. We use this to
>> compute the tid number and then hold this this tid number's
>> spinlock.
>>
>> Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
>> Signed-off-by: Sujith <[email protected]>
>> Signed-off-by: Luis R. Rodriguez <[email protected]>
>
> Just a head up John -- Ingo has already sucked this into his tree with
> a proper Reported-by. We still need it in wireless-testing though, not
> sure how that will be handled.
>
> Luis

Oh, I should add a tested-by for this.

Tested-by: Steven Noonan <[email protected]>

2008-10-04 05:45:44

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 3/3] ath9k: enable ANI to help with noisy environments

This enables Adaptive Noise Immunity (ANI) on ath9k.
ANI is as algorithm designed to minimize the detrimental
effects of time-varying interferences. This should
help with throughput in noisy environments. To use
ANI we re-enable the MIB interrupt. Since ANI works
on a timer and updates the noise floor we take
advantage of this and also report a non-static noise
floor now to mac80211.

Signed-off-by: Sujith Manoharan <[email protected]>
Signed-off-by: Jouni Malinen <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---

I've tested this on x86 and x86_64

drivers/net/wireless/ath9k/ath9k.h | 2 +-
drivers/net/wireless/ath9k/core.c | 129 ++++++++++++++++++++++++++++++++++--
drivers/net/wireless/ath9k/core.h | 25 +++++++
drivers/net/wireless/ath9k/hw.c | 35 ++++++++--
drivers/net/wireless/ath9k/main.c | 18 +++++-
drivers/net/wireless/ath9k/recv.c | 13 +---
6 files changed, 197 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
index 0e897c2..accace5 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -854,7 +854,7 @@ bool ath9k_hw_calibrate(struct ath_hal *ah,
u8 rxchainmask,
bool longcal,
bool *isCalDone);
-int16_t ath9k_hw_getchan_noise(struct ath_hal *ah,
+s16 ath9k_hw_getchan_noise(struct ath_hal *ah,
struct ath9k_channel *chan);
void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
u16 assocId);
diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c
index 5af7dfb..c5033f6 100644
--- a/drivers/net/wireless/ath9k/core.c
+++ b/drivers/net/wireless/ath9k/core.c
@@ -490,6 +490,122 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht)
__func__, sc->sc_tx_chainmask, sc->sc_rx_chainmask);
}

+/*******/
+/* ANI */
+/*******/
+
+/*
+ * This routine performs the periodic noise floor calibration function
+ * that is used to adjust and optimize the chip performance. This
+ * takes environmental changes (location, temperature) into account.
+ * When the task is complete, it reschedules itself depending on the
+ * appropriate interval that was calculated.
+ */
+
+static void ath_ani_calibrate(unsigned long data)
+{
+ struct ath_softc *sc;
+ struct ath_hal *ah;
+ bool longcal = false;
+ bool shortcal = false;
+ bool aniflag = false;
+ unsigned int timestamp = jiffies_to_msecs(jiffies);
+ u32 cal_interval;
+
+ sc = (struct ath_softc *)data;
+ ah = sc->sc_ah;
+
+ /*
+ * don't calibrate when we're scanning.
+ * we are most likely not on our home channel.
+ */
+ if (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)
+ return;
+
+ /* Long calibration runs independently of short calibration. */
+ if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) {
+ longcal = true;
+ DPRINTF(sc, ATH_DBG_ANI, "%s: longcal @%lu\n",
+ __func__, jiffies);
+ sc->sc_ani.sc_longcal_timer = timestamp;
+ }
+
+ /* Short calibration applies only while sc_caldone is false */
+ if (!sc->sc_ani.sc_caldone) {
+ if ((timestamp - sc->sc_ani.sc_shortcal_timer) >=
+ ATH_SHORT_CALINTERVAL) {
+ shortcal = true;
+ DPRINTF(sc, ATH_DBG_ANI, "%s: shortcal @%lu\n",
+ __func__, jiffies);
+ sc->sc_ani.sc_shortcal_timer = timestamp;
+ sc->sc_ani.sc_resetcal_timer = timestamp;
+ }
+ } else {
+ if ((timestamp - sc->sc_ani.sc_resetcal_timer) >=
+ ATH_RESTART_CALINTERVAL) {
+ ath9k_hw_reset_calvalid(ah, ah->ah_curchan,
+ &sc->sc_ani.sc_caldone);
+ if (sc->sc_ani.sc_caldone)
+ sc->sc_ani.sc_resetcal_timer = timestamp;
+ }
+ }
+
+ /* Verify whether we must check ANI */
+ if ((timestamp - sc->sc_ani.sc_checkani_timer) >=
+ ATH_ANI_POLLINTERVAL) {
+ aniflag = true;
+ sc->sc_ani.sc_checkani_timer = timestamp;
+ }
+
+ /* Skip all processing if there's nothing to do. */
+ if (longcal || shortcal || aniflag) {
+ /* Call ANI routine if necessary */
+ if (aniflag)
+ ath9k_hw_ani_monitor(ah, &sc->sc_halstats,
+ ah->ah_curchan);
+
+ /* Perform calibration if necessary */
+ if (longcal || shortcal) {
+ bool iscaldone = false;
+
+ if (ath9k_hw_calibrate(ah, ah->ah_curchan,
+ sc->sc_rx_chainmask, longcal,
+ &iscaldone)) {
+ if (longcal)
+ sc->sc_ani.sc_noise_floor =
+ ath9k_hw_getchan_noise(ah,
+ ah->ah_curchan);
+
+ DPRINTF(sc, ATH_DBG_ANI,
+ "%s: calibrate chan %u/%x nf: %d\n",
+ __func__,
+ ah->ah_curchan->channel,
+ ah->ah_curchan->channelFlags,
+ sc->sc_ani.sc_noise_floor);
+ } else {
+ DPRINTF(sc, ATH_DBG_ANY,
+ "%s: calibrate chan %u/%x failed\n",
+ __func__,
+ ah->ah_curchan->channel,
+ ah->ah_curchan->channelFlags);
+ }
+ sc->sc_ani.sc_caldone = iscaldone;
+ }
+ }
+
+ /*
+ * Set timer interval based on previous results.
+ * The interval must be the shortest necessary to satisfy ANI,
+ * short calibration and long calibration.
+ */
+
+ cal_interval = ATH_ANI_POLLINTERVAL;
+ if (!sc->sc_ani.sc_caldone)
+ cal_interval = min(cal_interval, (u32)ATH_SHORT_CALINTERVAL);
+
+ mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(cal_interval));
+}
+
/******************/
/* VAP management */
/******************/
@@ -676,12 +792,6 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
sc->sc_imask |= ATH9K_INT_CST;

- /* Note: We disable MIB interrupts for now as we don't yet
- * handle processing ANI, otherwise you will get an interrupt
- * storm after about 7 hours of usage making the system unusable
- * with huge latency. Once we do have ANI processing included
- * we can re-enable this interrupt. */
-#if 0
/*
* Enable MIB interrupts when there are hardware phy counters.
* Note we only do this (at the moment) for station mode.
@@ -690,7 +800,6 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
((sc->sc_ah->ah_opmode == ATH9K_M_STA) ||
(sc->sc_ah->ah_opmode == ATH9K_M_IBSS)))
sc->sc_imask |= ATH9K_INT_MIB;
-#endif
/*
* Some hardware processes the TIM IE and fires an
* interrupt when the TIM bit is set. For hardware
@@ -991,6 +1100,10 @@ int ath_init(u16 devid, struct ath_softc *sc)
}
sc->sc_ah = ah;

+ /* Initializes the noise floor to a reasonable default value.
+ * Later on this will be updated during ANI processing. */
+ sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR;
+
/* Get the hardware key cache size. */
sc->sc_keymax = ah->ah_caps.keycache_size;
if (sc->sc_keymax > ATH_KEYMAX) {
@@ -1098,6 +1211,8 @@ int ath_init(u16 devid, struct ath_softc *sc)
goto bad2;
}

+ setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc);
+
sc->sc_rc = ath_rate_attach(ah);
if (sc->sc_rc == NULL) {
error = -EIO;
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index 5b4f1c4..cb3e61e 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -800,6 +800,28 @@ void ath_slow_ant_div(struct ath_antdiv *antdiv,
struct ath_rx_status *rx_stats);
void ath_setdefantenna(void *sc, u32 antenna);

+/*******/
+/* ANI */
+/*******/
+
+/* ANI values for STA only.
+ FIXME: Add appropriate values for AP later */
+
+#define ATH_ANI_POLLINTERVAL 100 /* 100 milliseconds between ANI poll */
+#define ATH_SHORT_CALINTERVAL 1000 /* 1 second between calibrations */
+#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds between calibrations */
+#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes between calibrations */
+
+struct ath_ani {
+ bool sc_caldone;
+ int16_t sc_noise_floor;
+ unsigned int sc_longcal_timer;
+ unsigned int sc_shortcal_timer;
+ unsigned int sc_resetcal_timer;
+ unsigned int sc_checkani_timer;
+ struct timer_list timer;
+};
+
/********************/
/* LED Control */
/********************/
@@ -1028,6 +1050,9 @@ struct ath_softc {

/* Rfkill */
struct ath_rfkill rf_kill;
+
+ /* ANI */
+ struct ath_ani sc_ani;
};

int ath_init(u16 devid, struct ath_softc *sc);
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index 272c758..62e44a0 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -329,7 +329,7 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah)
ah->ah_config.ofdm_trig_high = 500;
ah->ah_config.cck_trig_high = 200;
ah->ah_config.cck_trig_low = 100;
- ah->ah_config.enable_ani = 0;
+ ah->ah_config.enable_ani = 1;
ah->ah_config.noise_immunity_level = 4;
ah->ah_config.ofdm_weaksignal_det = 1;
ah->ah_config.cck_weaksignal_thr = 0;
@@ -8405,23 +8405,48 @@ u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
}
}

-int16_t
+/* We can tune this as we go by monitoring really low values */
+#define ATH9K_NF_TOO_LOW -60
+
+/* AR5416 may return very high value (like -31 dBm), in those cases the nf
+ * is incorrect and we should use the static NF value. Later we can try to
+ * find out why they are reporting these values */
+static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf)
+{
+ if (nf > ATH9K_NF_TOO_LOW) {
+ DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
+ "%s: noise floor value detected (%d) is "
+ "lower than what we think is a "
+ "reasonable value (%d)\n",
+ __func__, nf, ATH9K_NF_TOO_LOW);
+ return false;
+ }
+ return true;
+}
+
+s16
ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
{
struct ath9k_channel *ichan;
+ s16 nf;

ichan = ath9k_regd_check_channel(ah, chan);
if (ichan == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
"%s: invalid channel %u/0x%x; no mapping\n",
__func__, chan->channel, chan->channelFlags);
- return 0;
+ return ATH_DEFAULT_NOISE_FLOOR;
}
if (ichan->rawNoiseFloor == 0) {
enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
- return NOISE_FLOOR[mode];
+ nf = NOISE_FLOOR[mode];
} else
- return ichan->rawNoiseFloor;
+ nf = ichan->rawNoiseFloor;
+
+ if (!ath9k_hw_nf_in_range(ah, nf))
+ nf = ATH_DEFAULT_NOISE_FLOOR;
+
+ return nf;
}

bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 2caba44..7472699 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -274,10 +274,12 @@ static void ath9k_rx_prepare(struct ath_softc *sc,
rx_status->mactime = status->tsf;
rx_status->band = curchan->band;
rx_status->freq = curchan->center_freq;
- rx_status->noise = ATH_DEFAULT_NOISE_FLOOR;
+ rx_status->noise = sc->sc_ani.sc_noise_floor;
rx_status->signal = rx_status->noise + status->rssi;
rx_status->rate_idx = ath_rate2idx(sc, (status->rateKbps / 100));
rx_status->antenna = status->antenna;
+
+ /* XXX Fix me, 64 cannot be the max rssi value, rigure it out */
rx_status->qual = status->rssi * 100 / 64;

if (status->flags & ATH_RX_MIC_ERROR)
@@ -427,6 +429,11 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
ath_rate_newstate(sc, avp);
/* Update ratectrl about the new state */
ath_rc_node_update(hw, avp->rc_node);
+
+ /* Start ANI */
+ mod_timer(&sc->sc_ani.timer,
+ jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
+
} else {
DPRINTF(sc, ATH_DBG_CONFIG,
"%s: Bss Info DISSOC\n", __func__);
@@ -1173,6 +1180,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
return error;
}

+ if (conf->type == NL80211_IFTYPE_AP) {
+ /* TODO: is this a suitable place to start ANI for AP mode? */
+ /* Start ANI */
+ mod_timer(&sc->sc_ani.timer,
+ jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
+ }
+
return 0;
}

@@ -1195,6 +1209,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
#ifdef CONFIG_SLOW_ANT_DIV
ath_slow_ant_div_stop(&sc->sc_antdiv);
#endif
+ /* Stop ANI */
+ del_timer_sync(&sc->sc_ani.timer);

/* Update ratectrl */
ath_rate_newstate(sc, avp);
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index f4be5d1..4983402 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -999,20 +999,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
rx_status.flags |= ATH_RX_SHORT_GI;
}

- /* sc->sc_noise_floor is only available when the station
+ /* sc_noise_floor is only available when the station
attaches to an AP, so we use a default value
if we are not yet attached. */
-
- /* XXX we should use either sc->sc_noise_floor or
- * ath_hal_getChanNoise(ah, &sc->sc_curchan)
- * to calculate the noise floor.
- * However, the value returned by ath_hal_getChanNoise
- * seems to be incorrect (-31dBm on the last test),
- * so we will use a hard-coded value until we
- * figure out what is going on.
- */
rx_status.abs_rssi =
- ds->ds_rxstat.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
+ ds->ds_rxstat.rs_rssi + sc->sc_ani.sc_noise_floor;

pci_dma_sync_single_for_cpu(sc->pdev,
bf->bf_buf_addr,
--
1.5.6.rc2.15.g457bb.dirty


2008-10-05 07:34:37

by Ingo Molnar

[permalink] [raw]
Subject: [PATCH] ath9k: fix oops on trying to hold the wrong spinlock


* Luis R. Rodriguez <[email protected]> wrote:

> On Fri, Oct 3, 2008 at 3:45 PM, Luis R. Rodriguez
> <[email protected]> wrote:
> > We were trying to hold the wrong spinlock due to a typo
> > on IEEE80211_BAR_CTL_TID_S's definition. We use this to
> > compute the tid number and then hold this this tid number's
> > spinlock.
> >
> > Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
> > Signed-off-by: Sujith <[email protected]>
> > Signed-off-by: Luis R. Rodriguez <[email protected]>
>
> Just a head up John -- Ingo has already sucked this into his tree with
> a proper Reported-by. We still need it in wireless-testing though, not
> sure how that will be handled.

Small sidenote: in terms of upstream merging tip/out-of-tree is a
dead-end (as its name implies) - it's a special temporary throw-away
branch for hot fixes that fall outside the normal scope of -tip. We
periodically rebase tip/out-of-tree against -git and throw away patches
that go upstream via other routes. It's never merged directly to Linus.
Perhaps we should rename it tip/not-for-linus ?

So we are glad to test out patches, but John please apply the patch
below to the wireless tree so that it's not lost. (probably for
v2.6.27.1) We are just helping out with testing and we do not want to
interfere in any way with the wireless git workflow.

Ingo

------------------>
>From fff3ddac71cf05dda8501a3449c167340e46b755 Mon Sep 17 00:00:00 2001
From: Luis R. Rodriguez <[email protected]>
Date: Fri, 3 Oct 2008 04:49:21 -0700
Subject: [PATCH] ath9k: fix oops on trying to hold the wrong spinlock

Steven Noonan reported a crash that occurs during ath9k module load.

We were trying to hold the wrong spinlock due to a typo
on IEEE80211_BAR_CTL_TID_S's definition. We use this to
compute the tid number and then hold this this tid number's
spinlock during ath_bar_rx().

Reported-by: Steven Noonan <[email protected]>
Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
Signed-off-by: Sujith <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
Tested-by: Steven Noonan <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
---
drivers/net/wireless/ath9k/core.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index 2f84093..88f4cc3 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -316,7 +316,7 @@ void ath_descdma_cleanup(struct ath_softc *sc,
#define ATH_RX_TIMEOUT 40 /* 40 milliseconds */
#define WME_NUM_TID 16
#define IEEE80211_BAR_CTL_TID_M 0xF000 /* tid mask */
-#define IEEE80211_BAR_CTL_TID_S 2 /* tid shift */
+#define IEEE80211_BAR_CTL_TID_S 12 /* tid shift */

enum ATH_RX_TYPE {
ATH_RX_NON_CONSUMED = 0,

2008-10-04 05:45:42

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 1/3] ath9k: kill ath9k's memzero() and use memset() instead

Part of the cleanup on ath9k -- this was also causing some
annoying compile time warnings.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath9k/beacon.c | 8 ++++----
drivers/net/wireless/ath9k/core.c | 14 +++++++-------
drivers/net/wireless/ath9k/core.h | 5 +----
drivers/net/wireless/ath9k/recv.c | 4 ++--
drivers/net/wireless/ath9k/xmit.c | 10 +++++-----
5 files changed, 19 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index eedb465..9e15c30 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -129,7 +129,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
ds /* first descriptor */
);

- memzero(series, sizeof(struct ath9k_11n_rate_series) * 4);
+ memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
series[0].Tries = 1;
series[0].Rate = rate;
series[0].ChSel = sc->sc_tx_chainmask;
@@ -282,7 +282,7 @@ int ath_beaconq_setup(struct ath_hal *ah)
{
struct ath9k_tx_queue_info qi;

- memzero(&qi, sizeof(qi));
+ memset(&qi, 0, sizeof(qi));
qi.tqi_aifs = 1;
qi.tqi_cwmin = 0;
qi.tqi_cwmax = 0;
@@ -662,7 +662,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
else
av_opmode = sc->sc_ah->ah_opmode;

- memzero(&conf, sizeof(struct ath_beacon_config));
+ memset(&conf, 0, sizeof(struct ath_beacon_config));

conf.beacon_interval = sc->hw->conf.beacon_int ?
sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
@@ -738,7 +738,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
}
} while (nexttbtt < tsftu);
#undef FUDGE
- memzero(&bs, sizeof(bs));
+ memset(&bs, 0, sizeof(bs));
bs.bs_intval = intval;
bs.bs_nexttbtt = nexttbtt;
bs.bs_dtimperiod = dtimperiod*intval;
diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c
index d7f5257..5af7dfb 100644
--- a/drivers/net/wireless/ath9k/core.c
+++ b/drivers/net/wireless/ath9k/core.c
@@ -65,7 +65,7 @@ static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
for (i = 0; i < rt->rateCount; i++)
sc->sc_rixmap[rt->info[i].rateCode] = (u8) i;

- memzero(sc->sc_hwmap, sizeof(sc->sc_hwmap));
+ memset(sc->sc_hwmap, 0, sizeof(sc->sc_hwmap));
for (i = 0; i < 256; i++) {
u8 ix = rt->rateCodeToIndex[i];

@@ -417,7 +417,7 @@ static void ath_chainmask_sel_init(struct ath_softc *sc, struct ath_node *an)
{
struct ath_chainmask_sel *cm = &an->an_chainmask_sel;

- memzero(cm, sizeof(struct ath_chainmask_sel));
+ memset(cm, 0, sizeof(struct ath_chainmask_sel));

cm->cur_tx_mask = sc->sc_tx_chainmask;
cm->cur_rx_mask = sc->sc_rx_chainmask;
@@ -526,7 +526,7 @@ int ath_vap_attach(struct ath_softc *sc,
if (avp == NULL)
return -ENOMEM;

- memzero(avp, sizeof(struct ath_vap));
+ memset(avp, 0, sizeof(struct ath_vap));
avp->av_if_data = if_data;
/* Set the VAP opmode */
avp->av_opmode = opmode;
@@ -1219,7 +1219,7 @@ struct ath_node *ath_node_attach(struct ath_softc *sc, u8 *addr, int if_id)
an = kmalloc(sizeof(struct ath_node), GFP_ATOMIC);
if (an == NULL)
return NULL;
- memzero(an, sizeof(*an));
+ memset(an, 0, sizeof(*an));

an->an_sc = sc;
memcpy(an->an_addr, addr, ETH_ALEN);
@@ -1606,7 +1606,7 @@ int ath_descdma_setup(struct ath_softc *sc,
error = -ENOMEM;
goto fail2;
}
- memzero(bf, bsize);
+ memset(bf, 0, bsize);
dd->dd_bufptr = bf;

INIT_LIST_HEAD(head);
@@ -1638,7 +1638,7 @@ fail2:
pci_free_consistent(sc->pdev,
dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr);
fail:
- memzero(dd, sizeof(*dd));
+ memset(dd, 0, sizeof(*dd));
return error;
#undef ATH_DESC_4KB_BOUND_CHECK
#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
@@ -1663,7 +1663,7 @@ void ath_descdma_cleanup(struct ath_softc *sc,

INIT_LIST_HEAD(head);
kfree(dd->dd_bufptr);
- memzero(dd, sizeof(*dd));
+ memset(dd, 0, sizeof(*dd));
}

/*************/
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index 872f0c5..80814c9 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -84,9 +84,6 @@ struct ath_node;
#define TSF_TO_TU(_h,_l) \
((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))

-/* XXX: remove */
-#define memzero(_buf, _len) memset(_buf, 0, _len)
-
#define ATH9K_BH_STATUS_INTACT 0
#define ATH9K_BH_STATUS_CHANGE 1

@@ -184,7 +181,7 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht);
(_bf)->bf_lastbf = NULL; \
(_bf)->bf_lastfrm = NULL; \
(_bf)->bf_next = NULL; \
- memzero(&((_bf)->bf_state), \
+ memset(&((_bf)->bf_state), 0, \
sizeof(struct ath_buf_state)); \
} while (0)

diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 4982563..f4be5d1 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -892,7 +892,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)

hdr = (struct ieee80211_hdr *)skb->data;
fc = hdr->frame_control;
- memzero(&rx_status, sizeof(struct ath_recv_status));
+ memset(&rx_status, 0, sizeof(struct ath_recv_status));

if (ds->ds_rxstat.rs_more) {
/*
@@ -1166,7 +1166,7 @@ int ath_rx_aggr_start(struct ath_softc *sc,
} else {
/* Ensure the memory is zeroed out (all internal
* pointers are null) */
- memzero(rxtid->rxbuf, ATH_TID_MAX_BUFS *
+ memset(rxtid->rxbuf, 0, ATH_TID_MAX_BUFS *
sizeof(struct ath_rxbuf));
DPRINTF(sc, ATH_DBG_AGGR,
"%s: Allocated @%p\n", __func__, rxtid->rxbuf);
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index 2592905..bdcb9e1 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -729,7 +729,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
/*
* Setup HAL rate series
*/
- memzero(series, sizeof(struct ath9k_11n_rate_series) * 4);
+ memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);

for (i = 0; i < 4; i++) {
if (!bf->bf_rcs[i].tries)
@@ -817,7 +817,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
* Disable multi-rate retry when using RTS/CTS by clearing
* series 1, 2 and 3.
*/
- memzero(&series[1], sizeof(struct ath9k_11n_rate_series) * 3);
+ memset(&series[1], 0, sizeof(struct ath9k_11n_rate_series) * 3);
}

/*
@@ -930,7 +930,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
ATH_DS_BA_BITMAP(ds),
WME_BA_BMP_SIZE >> 3);
} else {
- memzero(ba, WME_BA_BMP_SIZE >> 3);
+ memset(ba, 0, WME_BA_BMP_SIZE >> 3);

/*
* AR5416 can become deaf/mute when BA
@@ -943,7 +943,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
needreset = 1;
}
} else {
- memzero(ba, WME_BA_BMP_SIZE >> 3);
+ memset(ba, 0, WME_BA_BMP_SIZE >> 3);
}
}

@@ -2098,7 +2098,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
struct ath9k_tx_queue_info qi;
int qnum;

- memzero(&qi, sizeof(qi));
+ memset(&qi, 0, sizeof(qi));
qi.tqi_subtype = subtype;
qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
--
1.5.6.rc2.15.g457bb.dirty


2008-10-04 05:45:43

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 2/3] ath9k: fix oops on trying to hold the wrong spinlock

We were trying to hold the wrong spinlock due to a typo
on IEEE80211_BAR_CTL_TID_S's definition. We use this to
compute the tid number and then hold this this tid number's
spinlock.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
Signed-off-by: Sujith <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath9k/core.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index 80814c9..5b4f1c4 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -309,7 +309,7 @@ void ath_descdma_cleanup(struct ath_softc *sc,
#define ATH_RX_TIMEOUT 40 /* 40 milliseconds */
#define WME_NUM_TID 16
#define IEEE80211_BAR_CTL_TID_M 0xF000 /* tid mask */
-#define IEEE80211_BAR_CTL_TID_S 2 /* tid shift */
+#define IEEE80211_BAR_CTL_TID_S 12 /* tid shift */

enum ATH_RX_TYPE {
ATH_RX_NON_CONSUMED = 0,
--
1.5.6.rc2.15.g457bb.dirty