2010-04-16 21:50:22

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 0/2] iwlwifi fixes for 2.6.34

We include two fixes for 2.6.34. A scan race resulting in system crashes is
fixed with "iwlwifi: fix scan races" - this issue is tracked in
https://bugzilla.kernel.org/show_bug.cgi?id=15667 . The second fixes how
regulatory information is read from the 6000 series EEPROM. Channels that
were previously wrongly identified as not supporting IBSS are now correctly
identified as now supporting IBSS.

These patches are also available from wireless-2.6 branch on
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git

Johannes Berg (1):
iwlwifi: fix scan races

Shanyu Zhao (1):
iwlwifi: correct 6000 EEPROM regulatory address

drivers/net/wireless/iwlwifi/iwl-6000.c | 4 +-
drivers/net/wireless/iwlwifi/iwl-agn.c | 1 +
drivers/net/wireless/iwlwifi/iwl-core.c | 1 -
drivers/net/wireless/iwlwifi/iwl-core.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-dev.h | 1 +
drivers/net/wireless/iwlwifi/iwl-eeprom.h | 4 +++
drivers/net/wireless/iwlwifi/iwl-scan.c | 31 ++++++++++++++++++----------
7 files changed, 29 insertions(+), 15 deletions(-)



2010-04-16 21:50:23

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 2/2] iwlwifi: correct 6000 EEPROM regulatory address

From: Shanyu Zhao <[email protected]>

For 6000 series, the 2.4G HT40 band regulatory settings address in EEPROM
was off by 2.

Before the fix, you'll see this in dmesg:
[79535.788877] ieee80211 phy8: U iwl_mod_ht40_chan_info HT40 Ch. 7 [2.4GHz]
WIDE (0x61 0dBm): Ad-Hoc not supported
[79535.788880] ieee80211 phy8: U iwl_mod_ht40_chan_info HT40 Ch. 11 [2.4GHz]
WIDE (0x61 0dBm): Ad-Hoc not supported

And after the fix:
[91132.688706] ieee80211 phy14: U iwl_mod_ht40_chan_info HT40 Ch. 7 [2.4GHz]
IBSS ACTIVE WIDE (0x6f 0dBm): Ad-Hoc supported
[91132.688709] ieee80211 phy14: U iwl_mod_ht40_chan_info HT40 Ch. 11 [2.4GHz]
IBSS ACTIVE WIDE (0x6f 0dBm): Ad-Hoc supported

Signed-off-by: Shanyu Zhao <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-6000.c | 4 ++--
drivers/net/wireless/iwlwifi/iwl-eeprom.h | 4 ++++
2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index c4844ad..92b3e64 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -259,7 +259,7 @@ static struct iwl_lib_ops iwl6000_lib = {
EEPROM_5000_REG_BAND_3_CHANNELS,
EEPROM_5000_REG_BAND_4_CHANNELS,
EEPROM_5000_REG_BAND_5_CHANNELS,
- EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
+ EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
EEPROM_5000_REG_BAND_52_HT40_CHANNELS
},
.verify_signature = iwlcore_eeprom_verify_signature,
@@ -323,7 +323,7 @@ static struct iwl_lib_ops iwl6050_lib = {
EEPROM_5000_REG_BAND_3_CHANNELS,
EEPROM_5000_REG_BAND_4_CHANNELS,
EEPROM_5000_REG_BAND_5_CHANNELS,
- EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
+ EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
EEPROM_5000_REG_BAND_52_HT40_CHANNELS
},
.verify_signature = iwlcore_eeprom_verify_signature,
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 4e1ba82..8171c70 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -203,6 +203,10 @@ struct iwl_eeprom_enhanced_txpwr {
#define EEPROM_5000_REG_BAND_52_HT40_CHANNELS ((0x92)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */

+/* 6000 regulatory - indirect access */
+#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\
+ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */
+
/* 6000 and up regulatory tx power - indirect access */
/* max. elements per section */
#define EEPROM_MAX_TXPOWER_SECTION_ELEMENTS (8)
--
1.6.3.3


2010-04-16 21:50:23

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 1/2] iwlwifi: fix scan races

From: Johannes Berg <[email protected]>

When an internal scan is started, nothing protects the
is_internal_short_scan variable which can cause crashes,
cf. https://bugzilla.kernel.org/show_bug.cgi?id=15667.
Fix this by making the short scan request use the mutex
for locking, which requires making the request go to a
work struct so that it can sleep.

Reported-by: Peter Zijlstra <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 1 +
drivers/net/wireless/iwlwifi/iwl-core.c | 1 -
drivers/net/wireless/iwlwifi/iwl-core.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-dev.h | 1 +
drivers/net/wireless/iwlwifi/iwl-scan.c | 31 ++++++++++++++++++++-----------
5 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index e4c2e1e..ba0fdba 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3330,6 +3330,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)

cancel_delayed_work_sync(&priv->init_alive_start);
cancel_delayed_work(&priv->scan_check);
+ cancel_work_sync(&priv->start_internal_scan);
cancel_delayed_work(&priv->alive_start);
cancel_work_sync(&priv->beacon_update);
del_timer_sync(&priv->statistics_periodic);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 894bcb8..1459cdb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -3357,7 +3357,6 @@ static void iwl_force_rf_reset(struct iwl_priv *priv)
*/
IWL_DEBUG_INFO(priv, "perform radio reset.\n");
iwl_internal_short_hw_scan(priv);
- return;
}


diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 732590f..36940a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -506,7 +506,7 @@ void iwl_init_scan_params(struct iwl_priv *priv);
int iwl_scan_cancel(struct iwl_priv *priv);
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
-int iwl_internal_short_hw_scan(struct iwl_priv *priv);
+void iwl_internal_short_hw_scan(struct iwl_priv *priv);
int iwl_force_reset(struct iwl_priv *priv, int mode);
u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
const u8 *ie, int ie_len, int left);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 6054c5f..ef1720a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1296,6 +1296,7 @@ struct iwl_priv {
struct work_struct tt_work;
struct work_struct ct_enter;
struct work_struct ct_exit;
+ struct work_struct start_internal_scan;

struct tasklet_struct irq_tasklet;

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index bd2f7c4..5062f4e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -469,6 +469,8 @@ EXPORT_SYMBOL(iwl_init_scan_params);

static int iwl_scan_initiate(struct iwl_priv *priv)
{
+ WARN_ON(!mutex_is_locked(&priv->mutex));
+
IWL_DEBUG_INFO(priv, "Starting scan...\n");
set_bit(STATUS_SCANNING, &priv->status);
priv->is_internal_short_scan = false;
@@ -546,24 +548,31 @@ EXPORT_SYMBOL(iwl_mac_hw_scan);
* internal short scan, this function should only been called while associated.
* It will reset and tune the radio to prevent possible RF related problem
*/
-int iwl_internal_short_hw_scan(struct iwl_priv *priv)
+void iwl_internal_short_hw_scan(struct iwl_priv *priv)
{
- int ret = 0;
+ queue_work(priv->workqueue, &priv->start_internal_scan);
+}
+
+static void iwl_bg_start_internal_scan(struct work_struct *work)
+{
+ struct iwl_priv *priv =
+ container_of(work, struct iwl_priv, start_internal_scan);
+
+ mutex_lock(&priv->mutex);

if (!iwl_is_ready_rf(priv)) {
- ret = -EIO;
IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
- goto out;
+ goto unlock;
}
+
if (test_bit(STATUS_SCANNING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
- ret = -EAGAIN;
- goto out;
+ goto unlock;
}
+
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
- ret = -EAGAIN;
- goto out;
+ goto unlock;
}

priv->scan_bands = 0;
@@ -576,9 +585,8 @@ int iwl_internal_short_hw_scan(struct iwl_priv *priv)
set_bit(STATUS_SCANNING, &priv->status);
priv->is_internal_short_scan = true;
queue_work(priv->workqueue, &priv->request_scan);
-
-out:
- return ret;
+ unlock:
+ mutex_unlock(&priv->mutex);
}
EXPORT_SYMBOL(iwl_internal_short_hw_scan);

@@ -964,6 +972,7 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
+ INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
}
EXPORT_SYMBOL(iwl_setup_scan_deferred_work);
--
1.6.3.3


2010-05-13 23:16:40

by Reinette Chatre

[permalink] [raw]
Subject: Re: [PATCH 0/2] iwlwifi fixes for 2.6.34

Hi Sedat,

On Thu, 2010-05-13 at 15:58 -0700, Sedat Dilek wrote:
> Sorry, I was confused by the comments in [1] and I am especially
> interested in the internal scans stuff:
>
> Port following patch to 3945.

Yeah ... in retrospect that commit message could benefit with the
details on why it is needed. Sorry for the confusion. It is indeed a
port of the iwlagn patch since iwlagn used internal scanning long before
iwl3945 and the race was thus fixed there first. The same fix was not
done at that time for iwl3945 since it (iwl3945) was not using internal
scanning.

>
> "commit 90c4162ff59a3281b6d2f7206740be6217bd6758
> Author: Johannes Berg <[email protected]>
> Date: Wed Apr 7 00:21:36 2010 -0700
> iwlwifi: fix scan races"
>
> The above mentionned patch is already accepted to upstream (2.6.34)
> [2] and iwlagn _is_ already using internal scans.

Right.

> So why is iwl3945
> different in 2.6.34 especially in that case?

In 2.6.34 iwl3945 never calls RF reset, which triggers an internal scan.
In 2.6.34 iwlagn calls RF reset if the information received in
statistics notification warrants it. This feature is added to iwl3945 in
2.6.35 with [3].

> On first sight, I can't see the correlation of "iwl3945: add plcp
> error checking" [3] and "iwl3945: fix scan races" [1].

Note that [3] adds a value (and implementation behind that value) to the
check_plcp_health function pointer, which is called from
iwl_recover_from_statistics() which is for the first time made available
to iwl3945 in this patch also (see changes to iwl-rx.c). It is
iwl_recover_from_statistics() that uses statistic information (now
available via the new check_plcp_health function) to decide if an RF
reset is needed. Before this patch iwl3945 merely recorded received
statistics, it never made decisions based on the information contained
in it. This patch introduces the logic to use statistics information to
decide if an RF reset is needed and will trigger and RF reset if needed.

Now, an RF reset is done via an internal scan and before [3] there was
nothing in iwl3945 that triggered an internal scan. We do have issues
with internal scanning, but they were not all addressed for iwl3945
since iwl3945 was not using internal scanning. With [3] we introduced
usage of internal scanning so needed to make sure that the internal scan
races are fixed for it also which was done with [1].


> [1] https://patchwork.kernel.org/patch/98326/
> [2] http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=88be026490ed89c2ffead81a52531fbac5507e01
> [3] http://git.kernel.org/?p=linux/kernel/git/iwlwifi/iwlwifi-2.6.git;a=commit;h=a29576a7844326c5223f4d4adbfd3f4d64173d4c

Reinette



2010-05-21 19:16:48

by Reinette Chatre

[permalink] [raw]
Subject: Re: [PATCH 0/2] iwlwifi fixes for 2.6.34

Hi John,

On Fri, 2010-05-21 at 11:23 -0700, John W. Linville wrote:
> On Thu, May 13, 2010 at 02:49:43PM -0700, Reinette Chatre wrote:
> > We include two late fixes hoping to make it into 2.6.34.
> >
> > "iwlwifi: fix internal scan race" fixes a kernel crash caused by
> > accessing a NULL pointer. More can be read in
> > https://bugzilla.kernel.org/show_bug.cgi?id=15824
> >
> > "iwlagn: work around rate scaling reset delay" is already in
> > wireless-next-2.6 but has since been shown to be an issue in 2.6.34 also.
> > This fixes spurious firmware restarts that has been documented in
> > http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2173 , but it is the
> > community report tracked in
> > https://bugzilla.kernel.org/show_bug.cgi?id=15782 that prompted us sending
> > this fix to wireless-2.6 also.
> >
> > These patches are also available from wireless-2.6 branch on
> > git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git
> >
> > Reinette Chatre (2):
> > iwlwifi: fix internal scan race
> > iwlagn: work around rate scaling reset delay
>
> Since the one of these is already in linux-2.6 now, I'll just apply
> the other one directly rather than pulling. I hope that isn't too
> inconvenient!

Makes sense to do this. No problem here. I'll work on getting them into
stable.

Thank you for the heads up.

Reinette



2010-05-21 18:30:20

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 0/2] iwlwifi fixes for 2.6.34

On Thu, May 13, 2010 at 02:49:43PM -0700, Reinette Chatre wrote:
> We include two late fixes hoping to make it into 2.6.34.
>
> "iwlwifi: fix internal scan race" fixes a kernel crash caused by
> accessing a NULL pointer. More can be read in
> https://bugzilla.kernel.org/show_bug.cgi?id=15824
>
> "iwlagn: work around rate scaling reset delay" is already in
> wireless-next-2.6 but has since been shown to be an issue in 2.6.34 also.
> This fixes spurious firmware restarts that has been documented in
> http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2173 , but it is the
> community report tracked in
> https://bugzilla.kernel.org/show_bug.cgi?id=15782 that prompted us sending
> this fix to wireless-2.6 also.
>
> These patches are also available from wireless-2.6 branch on
> git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git
>
> Reinette Chatre (2):
> iwlwifi: fix internal scan race
> iwlagn: work around rate scaling reset delay

Since the one of these is already in linux-2.6 now, I'll just apply
the other one directly rather than pulling. I hope that isn't too
inconvenient!

John
--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.