[sgruszka@] iwlwifi: fix general 11n instability (#648732,#666646)

This commit is contained in:
Kyle McMartin 2011-06-20 10:35:50 -04:00
parent fcf9248627
commit 398aba2d45
4 changed files with 302 additions and 1 deletions

View File

@ -0,0 +1,58 @@
From sgruszka@redhat.com Mon Jun 20 10:14:55 2011
From: Stanislaw Gruszka <sgruszka@redhat.com>
To: kernel@lists.fedoraproject.org
Subject: [PATCH 2.6.35 2/3] iwlagn: fix "Received BA when not expected"
Date: Mon, 20 Jun 2011 16:15:13 +0200
Message-Id: <1308579314-19348-3-git-send-email-sgruszka@redhat.com>
commit bfd36103ec26599557c2bd3225a1f1c9267f8fcb upstream.
Need to use broadcast sta_id for management frames, otherwise we broke
BA session in the firmware and get messages like that:
"Received BA when not expected"
or (on older kernels):
"BA scd_flow 0 does not match txq_id 10"
This fix regression introduced in 2.6.35 during station management
code rewrite by:
commit 2a87c26bbe9587baeb9e56d3ce0b4971bd777643
Author: Johannes Berg <johannes.berg@intel.com>
Date: Fri Apr 30 11:30:45 2010 -0700
iwlwifi: use iwl_find_station less
Patch partially resolve:
https://bugzilla.kernel.org/show_bug.cgi?id=16691
However, there are still 11n performance problems on 4965 and 5xxx
devices that need to be investigated.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index cf64575..6df61b4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -548,10 +548,11 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc);
- /* Find index into station table for destination station */
- if (!info->control.sta)
+ /* For management frames use broadcast id to do not break aggregation */
+ if (!ieee80211_is_data(fc) || !info->control.sta)
sta_id = priv->hw_params.bcast_sta_id;
else
+ /* Find index into station table for destination station */
sta_id = iwl_sta_id(info->control.sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
--
1.7.1

View File

@ -0,0 +1,133 @@
From sgruszka@redhat.com Mon Jun 20 10:14:57 2011
From: Stanislaw Gruszka <sgruszka@redhat.com>
To: kernel@lists.fedoraproject.org
Subject: [PATCH 2.6.35 3/3] iwlagn: use cts-to-self protection on 5000 adapters series
Date: Mon, 20 Jun 2011 16:15:14 +0200
Message-Id: <1308579314-19348-4-git-send-email-sgruszka@redhat.com>
This patch fixes 802.11n stability and performance regression we have
since 2.6.35. It boost performance on my 5GHz N-only network from about
5MB/s to 8MB/s. Similar percentage boost can be observed on 2.4 GHz.
These are test results of 5x downloading of approximately 700MB iso
image:
vanilla: 5.27 5.22 4.94 4.47 5.31 ; avr 5.0420 std 0.35110
patched: 8.07 7.95 8.06 7.99 7.96 ; avr 8.0060 std 0.055946
This was achieved with NetworkManager configured to do not perform
periodical scans, by configuring constant BSSID. With periodical scans,
after some time, performance downgrade to unpatched driver level, like
in example below:
patched: 7.40 7.61 4.28 4.37 4.80 avr 5.6920 std 1.6683
However patch still make better here, since similar test on unpatched
driver make link disconnects with below messages after some time:
wlan1: authenticate with 00:23:69:35:d1:3f (try 1)
wlan1: authenticate with 00:23:69:35:d1:3f (try 2)
wlan1: authenticate with 00:23:69:35:d1:3f (try 3)
wlan1: authentication with 00:23:69:35:d1:3f timed out
On 2.6.35 kernel patch helps against connection hangs with messages:
iwlagn 0000:20:00.0: queue 10 stuck 3 time. Fw reload.
iwlagn 0000:20:00.0: On demand firmware reload
iwlagn 0000:20:00.0: Stopping AGG while state not ON or starting
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/iwlwifi/iwl-5000.c | 5 -----
drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 11 ++---------
drivers/net/wireless/iwlwifi/iwl-agn.c | 7 +++++++
3 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 0a67558..8270ed6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -458,7 +458,6 @@ struct iwl_cfg iwl5300_agn_cfg = {
.use_bsm = false,
.ht_greenfield_support = true,
.led_compensation = 51,
- .use_rts_for_ht = true, /* use rts/cts protection */
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
@@ -489,7 +488,6 @@ struct iwl_cfg iwl5100_bgn_cfg = {
.use_bsm = false,
.ht_greenfield_support = true,
.led_compensation = 51,
- .use_rts_for_ht = true, /* use rts/cts protection */
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
@@ -549,7 +547,6 @@ struct iwl_cfg iwl5100_agn_cfg = {
.use_bsm = false,
.ht_greenfield_support = true,
.led_compensation = 51,
- .use_rts_for_ht = true, /* use rts/cts protection */
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
@@ -580,7 +577,6 @@ struct iwl_cfg iwl5350_agn_cfg = {
.use_bsm = false,
.ht_greenfield_support = true,
.led_compensation = 51,
- .use_rts_for_ht = true, /* use rts/cts protection */
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
@@ -611,7 +607,6 @@ struct iwl_cfg iwl5150_agn_cfg = {
.use_bsm = false,
.ht_greenfield_support = true,
.led_compensation = 51,
- .use_rts_for_ht = true, /* use rts/cts protection */
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.chain_noise_scale = 1000,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 2a30397..44e91af 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -214,16 +214,9 @@ static void iwlagn_rts_tx_cmd_flag(struct iwl_priv *priv,
__le16 fc, __le32 *tx_flags)
{
if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS ||
- info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+ info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT ||
+ info->flags & IEEE80211_TX_CTL_AMPDU)
*tx_flags |= TX_CMD_FLG_RTS_CTS_MSK;
- return;
- }
-
- if (priv->cfg->use_rts_for_ht &&
- info->flags & IEEE80211_TX_CTL_AMPDU) {
- *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK;
- return;
- }
}
/* Calc max signal level (dBm) among 3 possible receivers */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 6bd11c7..20ffe4b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -103,6 +103,13 @@ int iwl_commit_rxon(struct iwl_priv *priv)
if (!iwl_is_alive(priv))
return -EBUSY;
+ /*
+ * force CTS-to-self frames protection if RTS-CTS is not preferred
+ * one aggregation protection method
+ */
+ if (!priv->cfg->use_rts_for_ht)
+ priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
+
/* always get timestamp with Rx frame */
priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
--
1.7.1

View File

@ -0,0 +1,97 @@
From sgruszka@redhat.com Mon Jun 20 10:14:54 2011
From: Stanislaw Gruszka <sgruszka@redhat.com>
To: kernel@lists.fedoraproject.org
Subject: [PATCH 2.6.35 1/3] iwlwifi: add {ack, plpc}_check module parameters
Date: Mon, 20 Jun 2011 16:15:12 +0200
Message-Id: <1308579314-19348-2-git-send-email-sgruszka@redhat.com>
commit b7977ffaab5187ad75edaf04ac854615cea93828 upstream.
Add module ack_check, and plcp_check parameters. Ack_check is disabled
by default since is proved that check ack health can cause troubles.
Plcp_check is enabled by default.
This prevent connection hangs with "low ack count detected" messages.
Resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=666646
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 +
drivers/net/wireless/iwlwifi/iwl-agn.c | 6 ++++++
drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++
drivers/net/wireless/iwlwifi/iwl-rx.c | 8 ++++++--
4 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 0f292a2..3a79907 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -387,6 +387,7 @@ const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
struct iwl_mod_params iwlagn_mod_params = {
.amsdu_size_8K = 1,
.restart_fw = 1,
+ .plcp_check = true,
/* the rest are 0 by default */
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 8a2c4d7..6bd11c7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -4180,3 +4180,9 @@ module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int,
S_IRUGO);
MODULE_PARM_DESC(ucode_alternative,
"specify ucode alternative to use from ucode file");
+
+module_param_named(plcp_check, iwlagn_mod_params.plcp_check, bool, S_IRUGO);
+MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])");
+
+module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO);
+MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])");
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index e8ef317..ef03c24 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -226,6 +226,8 @@ struct iwl_mod_params {
int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
int antenna; /* def: 0 = both antennas (use diversity) */
int restart_fw; /* def: 1 = restart firmware */
+ bool plcp_check; /* def: true = enable plcp health check */
+ bool ack_check; /* def: false = disable ack health check */
};
/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 0a5d7cf..d6c5927 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -401,10 +401,13 @@ EXPORT_SYMBOL(iwl_good_plcp_health);
void iwl_recover_from_statistics(struct iwl_priv *priv,
struct iwl_rx_packet *pkt)
{
+ const struct iwl_mod_params *mod_params = priv->cfg->mod_params;
+
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
if (iwl_is_associated(priv)) {
- if (priv->cfg->ops->lib->check_ack_health) {
+ if (mod_params->ack_check &&
+ priv->cfg->ops->lib->check_ack_health) {
if (!priv->cfg->ops->lib->check_ack_health(
priv, pkt)) {
/*
@@ -417,7 +420,8 @@ void iwl_recover_from_statistics(struct iwl_priv *priv,
return;
}
}
- if (priv->cfg->ops->lib->check_plcp_health) {
+ if (mod_params->plcp_check &&
+ priv->cfg->ops->lib->check_plcp_health) {
if (!priv->cfg->ops->lib->check_plcp_health(
priv, pkt)) {
/*
--
1.7.1

View File

@ -48,7 +48,7 @@ Summary: The Linux kernel
# reset this by hand to 1 (or to 0 and then use rpmdev-bumpspec).
# scripts/rebase.sh should be made to do that for you, actually.
#
%global baserelease 92
%global baserelease 93
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
@ -858,6 +858,11 @@ Patch13980: dccp-handle-invalid-feature-options-length.patch
# the rest of the pgoff wrap fix
Patch13990: vm-fix-vm_pgoff-wrap-in-stack-expansion.patch
Patch14000: iwlagn-fix-Received-BA-when-not-expected.patch
Patch14001: iwlagn-use-cts-to-self-protection-on-5000-adapters-series.patch
Patch14002: iwlwifi-add_ack_plpc_check-module-parameters.patch
%endif
BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@ -1615,6 +1620,11 @@ ApplyPatch dccp-handle-invalid-feature-options-length.patch
# the rest of the pgoff wrap fix
ApplyPatch vm-fix-vm_pgoff-wrap-in-stack-expansion.patch
# rhbz#666646,648732
ApplyPatch iwlwifi-add_ack_plpc_check-module-parameters.patch
ApplyPatch iwlagn-fix-Received-BA-when-not-expected.patch
ApplyPatch iwlagn-use-cts-to-self-protection-on-5000-adapters-series.patch
# END OF PATCH APPLICATIONS
%endif
@ -2201,6 +2211,9 @@ fi
# and build.
%changelog
* Mon Jun 20 2011 Kyle McMartin <kmcmartin@redhat.com> 2.6.35.13-93
- [sgruszka@] iwlwifi: fix general 11n instability (#648732,#666646)
* Fri May 20 2011 Chuck Ebbert <cebbert@redhat.com> 2.6.35.13-92
- Add the rest of the fix for bug #704059
- dccp: handle invalid feature options length (CVE-2011-1770)