From 398aba2d45dac2b17efa426a48c87b73377551aa Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Jun 20 2011 14:35:50 +0000 Subject: [sgruszka@] iwlwifi: fix general 11n instability (#648732,#666646) --- diff --git a/iwlagn-fix-Received-BA-when-not-expected.patch b/iwlagn-fix-Received-BA-when-not-expected.patch new file mode 100644 index 0000000..9d9b510 --- /dev/null +++ b/iwlagn-fix-Received-BA-when-not-expected.patch @@ -0,0 +1,58 @@ +From sgruszka@redhat.com Mon Jun 20 10:14:55 2011 +From: Stanislaw Gruszka +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 +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 +--- + 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 + diff --git a/iwlagn-use-cts-to-self-protection-on-5000-adapters-series.patch b/iwlagn-use-cts-to-self-protection-on-5000-adapters-series.patch new file mode 100644 index 0000000..ca9c98a --- /dev/null +++ b/iwlagn-use-cts-to-self-protection-on-5000-adapters-series.patch @@ -0,0 +1,133 @@ +From sgruszka@redhat.com Mon Jun 20 10:14:57 2011 +From: Stanislaw Gruszka +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 +--- + 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 + diff --git a/iwlwifi-add_ack_plpc_check-module-parameters.patch b/iwlwifi-add_ack_plpc_check-module-parameters.patch new file mode 100644 index 0000000..911ea29 --- /dev/null +++ b/iwlwifi-add_ack_plpc_check-module-parameters.patch @@ -0,0 +1,97 @@ +From sgruszka@redhat.com Mon Jun 20 10:14:54 2011 +From: Stanislaw Gruszka +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 +--- + 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 + diff --git a/kernel.spec b/kernel.spec index 2c15112..0ef4812 100644 --- a/kernel.spec +++ b/kernel.spec @@ -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 2.6.35.13-93 +- [sgruszka@] iwlwifi: fix general 11n instability (#648732,#666646) + * Fri May 20 2011 Chuck Ebbert 2.6.35.13-92 - Add the rest of the fix for bug #704059 - dccp: handle invalid feature options length (CVE-2011-1770)