Jesse Keating 2f82dda
Back-port of the following upstream commit...
Jesse Keating 2f82dda
Jesse Keating 2f82dda
commit 8a472da431998b7357e6dc562e79a3061ed56cad
Jesse Keating 2f82dda
Author: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Jesse Keating 2f82dda
Date:   Thu Feb 18 22:03:06 2010 -0800
Jesse Keating 2f82dda
Jesse Keating 2f82dda
    iwlwifi: separated time check for different type of force reset
Jesse Keating 2f82dda
    
Jesse Keating 2f82dda
    Use different timing duration check for different type of force reset,
Jesse Keating 2f82dda
    force reset request can come from different source and based on
Jesse Keating 2f82dda
    different reason; one type of reset request should not block other type of
Jesse Keating 2f82dda
    reset request.
Jesse Keating 2f82dda
    
Jesse Keating 2f82dda
    Adding structure to keep track of different force reset request.
Jesse Keating 2f82dda
    
Jesse Keating 2f82dda
    Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Jesse Keating 2f82dda
    Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Jesse Keating 2f82dda
    Signed-off-by: John W. Linville <linville@tuxdriver.com>
Jesse Keating 2f82dda
Jesse Keating 2f82dda
diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-agn.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-agn.c
Jesse Keating 2f82dda
diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.c.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.c
Jesse Keating 2f82dda
--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.c.orig	2010-03-22 15:24:28.000000000 -0400
Jesse Keating 2f82dda
+++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-core.c	2010-03-22 15:40:48.000000000 -0400
Jesse Keating 2f82dda
@@ -1497,6 +1497,12 @@ int iwl_init_drv(struct iwl_priv *priv)
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
 	priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
+	/* initialize force reset */
Jesse Keating 2f82dda
+	priv->force_reset[IWL_RF_RESET].reset_duration =
Jesse Keating 2f82dda
+		IWL_DELAY_NEXT_FORCE_RF_RESET;
Jesse Keating 2f82dda
+	priv->force_reset[IWL_FW_RESET].reset_duration =
Jesse Keating 2f82dda
+		IWL_DELAY_NEXT_FORCE_FW_RELOAD;
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
 	/* Choose which receivers/antennas to use */
Jesse Keating 2f82dda
 	if (priv->cfg->ops->hcmd->set_rxon_chain)
Jesse Keating 2f82dda
 		priv->cfg->ops->hcmd->set_rxon_chain(priv);
Jesse Keating 2f82dda
@@ -3058,22 +3064,30 @@ static void iwl_force_rf_reset(struct iw
Jesse Keating 2f82dda
 	return;
Jesse Keating 2f82dda
 }
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
-#define IWL_DELAY_NEXT_FORCE_RESET (HZ*3)
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
 int iwl_force_reset(struct iwl_priv *priv, int mode)
Jesse Keating 2f82dda
 {
Jesse Keating 2f82dda
+	struct iwl_force_reset *force_reset;
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
Jesse Keating 2f82dda
 		return -EINVAL;
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
-	if (priv->last_force_reset_jiffies &&
Jesse Keating 2f82dda
-	    time_after(priv->last_force_reset_jiffies +
Jesse Keating 2f82dda
-		       IWL_DELAY_NEXT_FORCE_RESET, jiffies)) {
Jesse Keating 2f82dda
+	if (mode >= IWL_MAX_FORCE_RESET) {
Jesse Keating 2f82dda
+		IWL_DEBUG_INFO(priv, "invalid reset request.\n");
Jesse Keating 2f82dda
+		return -EINVAL;
Jesse Keating 2f82dda
+	}
Jesse Keating 2f82dda
+	force_reset = &priv->force_reset[mode];
Jesse Keating 2f82dda
+	force_reset->reset_request_count++;
Jesse Keating 2f82dda
+	if (force_reset->last_force_reset_jiffies &&
Jesse Keating 2f82dda
+	    time_after(force_reset->last_force_reset_jiffies +
Jesse Keating 2f82dda
+	    force_reset->reset_duration, jiffies)) {
Jesse Keating 2f82dda
 		IWL_DEBUG_INFO(priv, "force reset rejected\n");
Jesse Keating 2f82dda
+		force_reset->reset_reject_count++;
Jesse Keating 2f82dda
 		return -EAGAIN;
Jesse Keating 2f82dda
 	}
Jesse Keating 2f82dda
-
Jesse Keating 2f82dda
+	force_reset->reset_success_count++;
Jesse Keating 2f82dda
+	force_reset->last_force_reset_jiffies = jiffies;
Jesse Keating 2f82dda
 	IWL_DEBUG_INFO(priv, "perform force reset (%d)\n", mode);
Jesse Keating 2f82dda
-
Jesse Keating 2f82dda
 	switch (mode) {
Jesse Keating 2f82dda
 	case IWL_RF_RESET:
Jesse Keating 2f82dda
 		iwl_force_rf_reset(priv);
Jesse Keating 2f82dda
@@ -3090,12 +3104,7 @@ int iwl_force_reset(struct iwl_priv *pri
Jesse Keating 2f82dda
 		clear_bit(STATUS_READY, &priv->status);
Jesse Keating 2f82dda
 		queue_work(priv->workqueue, &priv->restart);
Jesse Keating 2f82dda
 		break;
Jesse Keating 2f82dda
-	default:
Jesse Keating 2f82dda
-		IWL_DEBUG_INFO(priv, "invalid reset request.\n");
Jesse Keating 2f82dda
-		return -EINVAL;
Jesse Keating 2f82dda
 	}
Jesse Keating 2f82dda
-	priv->last_force_reset_jiffies = jiffies;
Jesse Keating 2f82dda
-
Jesse Keating 2f82dda
 	return 0;
Jesse Keating 2f82dda
 }
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
diff -up linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-dev.h.orig linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-dev.h
Jesse Keating 2f82dda
--- linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-dev.h.orig	2010-03-22 15:33:00.000000000 -0400
Jesse Keating 2f82dda
+++ linux-2.6.32.noarch/drivers/net/wireless/iwlwifi/iwl-dev.h	2010-03-22 15:37:04.000000000 -0400
Jesse Keating 2f82dda
@@ -973,9 +973,21 @@ struct traffic_stats {
Jesse Keating 2f82dda
 #define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF	(200)
Jesse Keating 2f82dda
 #define IWL_MAX_PLCP_ERR_THRESHOLD_MAX	(255)
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
+#define IWL_DELAY_NEXT_FORCE_RF_RESET  (HZ*3)
Jesse Keating 2f82dda
+#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
 enum iwl_reset {
Jesse Keating 2f82dda
 	IWL_RF_RESET = 0,
Jesse Keating 2f82dda
 	IWL_FW_RESET,
Jesse Keating 2f82dda
+	IWL_MAX_FORCE_RESET,
Jesse Keating 2f82dda
+};
Jesse Keating 2f82dda
+
Jesse Keating 2f82dda
+struct iwl_force_reset {
Jesse Keating 2f82dda
+	int reset_request_count;
Jesse Keating 2f82dda
+	int reset_success_count;
Jesse Keating 2f82dda
+	int reset_reject_count;
Jesse Keating 2f82dda
+	unsigned long reset_duration;
Jesse Keating 2f82dda
+	unsigned long last_force_reset_jiffies;
Jesse Keating 2f82dda
 };
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
 struct iwl_priv {
Jesse Keating 2f82dda
@@ -1010,7 +1022,7 @@ struct iwl_priv {
Jesse Keating 2f82dda
 	unsigned long plcp_jiffies;
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
 	/* force reset */
Jesse Keating 2f82dda
-	unsigned long last_force_reset_jiffies;
Jesse Keating 2f82dda
+	struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];
Jesse Keating 2f82dda
 
Jesse Keating 2f82dda
 	/* we allocate array of iwl4965_channel_info for NIC's valid channels.
Jesse Keating 2f82dda
 	 *    Access via channel # using indirect index array */