summaryrefslogtreecommitdiffstats
path: root/iwlwifi_-code-cleanup-for-connectivity-recovery.patch
diff options
context:
space:
mode:
authorJesse Keating <jkeating@redhat.com>2010-07-29 17:18:45 -0700
committerJesse Keating <jkeating@redhat.com>2010-07-29 17:18:45 -0700
commit2f82dda4a9bf41e64e864889bf06564bdf826e25 (patch)
tree118a7b483ae5de4dbf83d20001302f1404866ef0 /iwlwifi_-code-cleanup-for-connectivity-recovery.patch
parent64ba2e5ffde5f2418eb26c700cb0ab62b04e5013 (diff)
downloaddom0-kernel-2f82dda4a9bf41e64e864889bf06564bdf826e25.tar.gz
dom0-kernel-2f82dda4a9bf41e64e864889bf06564bdf826e25.tar.xz
dom0-kernel-2f82dda4a9bf41e64e864889bf06564bdf826e25.zip
initial srpm import
Diffstat (limited to 'iwlwifi_-code-cleanup-for-connectivity-recovery.patch')
-rw-r--r--iwlwifi_-code-cleanup-for-connectivity-recovery.patch230
1 files changed, 230 insertions, 0 deletions
diff --git a/iwlwifi_-code-cleanup-for-connectivity-recovery.patch b/iwlwifi_-code-cleanup-for-connectivity-recovery.patch
new file mode 100644
index 0000000..587c5ff
--- /dev/null
+++ b/iwlwifi_-code-cleanup-for-connectivity-recovery.patch
@@ -0,0 +1,230 @@
+diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-1000.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-1000.c
+--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-1000.c.orig 2010-03-22 16:42:34.000000000 -0400
++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-1000.c 2010-03-22 16:42:57.000000000 -0400
+@@ -136,7 +136,8 @@ static struct iwl_lib_ops iwl1000_lib =
+ .set_ct_kill = iwl1000_set_ct_threshold,
+ },
+ .recover_from_tx_stall = iwl_bg_monitor_recover,
+- .recover_from_statistics = iwl_recover_from_statistics,
++ .check_plcp_health = iwl_good_plcp_health,
++ .check_ack_health = iwl_good_ack_health,
+ };
+
+ static struct iwl_ops iwl1000_ops = {
+diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c
+--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c.orig 2010-03-22 16:42:34.000000000 -0400
++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c 2010-03-22 16:42:57.000000000 -0400
+@@ -2340,7 +2340,7 @@ static struct iwl_lib_ops iwl4965_lib =
+ .temperature = iwl4965_temperature_calib,
+ .set_ct_kill = iwl4965_set_ct_threshold,
+ },
+- .recover_from_statistics = iwl_recover_from_statistics,
++ .check_plcp_health = iwl_good_plcp_health,
+ };
+
+ static struct iwl_ops iwl4965_ops = {
+diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-5000.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-5000.c
+--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-5000.c.orig 2010-03-22 16:42:34.000000000 -0400
++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-5000.c 2010-03-22 16:42:57.000000000 -0400
+@@ -1580,7 +1580,8 @@ struct iwl_lib_ops iwl5000_lib = {
+ .set_ct_kill = iwl5000_set_ct_threshold,
+ },
+ .recover_from_tx_stall = iwl_bg_monitor_recover,
+- .recover_from_statistics = iwl_recover_from_statistics,
++ .check_plcp_health = iwl_good_plcp_health,
++ .check_ack_health = iwl_good_ack_health,
+ };
+
+ static struct iwl_lib_ops iwl5150_lib = {
+@@ -1634,7 +1635,8 @@ static struct iwl_lib_ops iwl5150_lib =
+ .set_ct_kill = iwl5150_set_ct_threshold,
+ },
+ .recover_from_tx_stall = iwl_bg_monitor_recover,
+- .recover_from_statistics = iwl_recover_from_statistics,
++ .check_plcp_health = iwl_good_plcp_health,
++ .check_ack_health = iwl_good_ack_health,
+ };
+
+ struct iwl_ops iwl5000_ops = {
+diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-6000.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-6000.c
+--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-6000.c.orig 2010-03-22 16:42:34.000000000 -0400
++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-6000.c 2010-03-22 16:42:57.000000000 -0400
+@@ -138,7 +138,8 @@ static struct iwl_lib_ops iwl6000_lib =
+ .set_ct_kill = iwl6000_set_ct_threshold,
+ },
+ .recover_from_tx_stall = iwl_bg_monitor_recover,
+- .recover_from_statistics = iwl_recover_from_statistics,
++ .check_plcp_health = iwl_good_plcp_health,
++ .check_ack_health = iwl_good_ack_health,
+ };
+
+ static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = {
+diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.h.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.h
+--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.h.orig 2010-03-22 16:42:34.000000000 -0400
++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.h 2010-03-22 16:42:57.000000000 -0400
+@@ -185,8 +185,11 @@ struct iwl_lib_ops {
+ struct iwl_temp_ops temp_ops;
+ /* recover from tx queue stall */
+ void (*recover_from_tx_stall)(unsigned long data);
+- /* recover from errors showed in statistics */
+- void (*recover_from_statistics)(struct iwl_priv *priv,
++ /* check for plcp health */
++ bool (*check_plcp_health)(struct iwl_priv *priv,
++ struct iwl_rx_packet *pkt);
++ /* check for ack health */
++ bool (*check_ack_health)(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt);
+ };
+
+@@ -401,7 +404,9 @@ int iwl_tx_queue_reclaim(struct iwl_priv
+ /* Handlers */
+ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+-void iwl_recover_from_statistics(struct iwl_priv *priv,
++bool iwl_good_plcp_health(struct iwl_priv *priv,
++ struct iwl_rx_packet *pkt);
++bool iwl_good_ack_health(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt);
+ void iwl_rx_statistics(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-rx.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-rx.c
+--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-rx.c.orig 2010-03-22 16:42:34.000000000 -0400
++++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-rx.c 2010-03-22 16:45:03.000000000 -0400
+@@ -555,24 +555,18 @@ static void iwl_rx_calc_noise(struct iwl
+ #define BA_TIMEOUT_CNT (5)
+ #define BA_TIMEOUT_MAX (16)
+
+-#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n"
+-/*
+- * This function checks for plcp error, ACK count ratios, aggregated BA
+- * timeout retries.
+- * - When the ACK count ratio is 0 and aggregated BA timeout retries is
+- * exceeding the BA_TIMEOUT_MAX, it will recover the failure by resetting
+- * the firmware.
+- * - When the plcp error is exceeding the thresholds, it will reset the radio
+- * to improve the throughput.
++/**
++ * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries.
++ *
++ * When the ACK count ratio is 0 and aggregated BA timeout retries exceeding
++ * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
++ * operation state.
+ */
+-void iwl_recover_from_statistics(struct iwl_priv *priv,
+- struct iwl_rx_packet *pkt)
++bool iwl_good_ack_health(struct iwl_priv *priv,
++ struct iwl_rx_packet *pkt)
+ {
+- int combined_plcp_delta;
+- unsigned int plcp_msec;
+- unsigned long plcp_received_jiffies;
+- int actual_ack_cnt_delta;
+- int expected_ack_cnt_delta;
++ bool rc = true;
++ int actual_ack_cnt_delta, expected_ack_cnt_delta;
+ int ba_timeout_delta;
+
+ actual_ack_cnt_delta =
+@@ -594,13 +588,27 @@ void iwl_recover_from_statistics(struct
+ actual_ack_cnt_delta, expected_ack_cnt_delta);
+ IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n",
+ ba_timeout_delta);
+- if ((actual_ack_cnt_delta == 0) &&
+- (ba_timeout_delta >= BA_TIMEOUT_MAX)) {
+- IWL_DEBUG_RADIO(priv,
+- "call iwl_force_reset(IWL_FW_RESET)\n");
+- iwl_force_reset(priv, IWL_FW_RESET);
+- }
++ if (!actual_ack_cnt_delta &&
++ (ba_timeout_delta >= BA_TIMEOUT_MAX))
++ rc = false;
+ }
++ return rc;
++}
++EXPORT_SYMBOL(iwl_good_ack_health);
++
++/**
++ * iwl_good_plcp_health - checks for plcp error.
++ *
++ * When the plcp error is exceeding the thresholds, reset the radio
++ * to improve the throughput.
++ */
++bool iwl_good_plcp_health(struct iwl_priv *priv,
++ struct iwl_rx_packet *pkt)
++{
++ bool rc = true;
++ int combined_plcp_delta;
++ unsigned int plcp_msec;
++ unsigned long plcp_received_jiffies;
+
+ /*
+ * check for plcp_err and trigger radio reset if it exceeds
+@@ -635,7 +643,8 @@ void iwl_recover_from_statistics(struct
+ * combined_plcp_delta,
+ * plcp_msec
+ */
+- IWL_DEBUG_RADIO(priv, PLCP_MSG,
++ IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
++ "%u, %u, %u, %u, %d, %u mSecs\n",
+ priv->cfg->plcp_delta_threshold,
+ le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
+ le32_to_cpu(priv->statistics.rx.ofdm.plcp_err),
+@@ -643,15 +652,42 @@ void iwl_recover_from_statistics(struct
+ le32_to_cpu(
+ priv->statistics.rx.ofdm_ht.plcp_err),
+ combined_plcp_delta, plcp_msec);
+- /*
+- * Reset the RF radio due to the high plcp
+- * error rate
+- */
+- iwl_force_reset(priv, IWL_RF_RESET);
++ rc = false;
++ }
++ }
++ return rc;
++}
++EXPORT_SYMBOL(iwl_good_plcp_health);
++
++static void iwl_recover_from_statistics(struct iwl_priv *priv,
++ struct iwl_rx_packet *pkt)
++{
++ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
++ return;
++ if (iwl_is_associated(priv)) {
++ if (priv->cfg->ops->lib->check_ack_health) {
++ if (!priv->cfg->ops->lib->check_ack_health(
++ priv, pkt)) {
++ /*
++ * low ack count detected
++ * restart Firmware
++ */
++ IWL_ERR(priv, "low ack count detected, "
++ "restart firmware\n");
++ iwl_force_reset(priv, IWL_FW_RESET);
++ }
++ } else if (priv->cfg->ops->lib->check_plcp_health) {
++ if (!priv->cfg->ops->lib->check_plcp_health(
++ priv, pkt)) {
++ /*
++ * high plcp error detected
++ * reset Radio
++ */
++ iwl_force_reset(priv, IWL_RF_RESET);
++ }
+ }
+ }
+ }
+-EXPORT_SYMBOL(iwl_recover_from_statistics);
+
+ void iwl_rx_statistics(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+@@ -670,8 +706,7 @@ void iwl_rx_statistics(struct iwl_priv *
+ STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
+ (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
+
+- if (priv->cfg->ops->lib->recover_from_statistics)
+- priv->cfg->ops->lib->recover_from_statistics(priv, pkt);
++ iwl_recover_from_statistics(priv, pkt);
+
+ memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
+