iwlwifi: separated time check for different type of force reset
authorWey-Yi Guy <wey-yi.w.guy@intel.com>
Fri, 19 Feb 2010 06:03:06 +0000 (22:03 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 19 Feb 2010 20:52:50 +0000 (15:52 -0500)
Use different timing duration check for different type of force reset,
force reset request can come from different source and based on
different reason; one type of reset request should not block other type of
reset request.

Adding structure to keep track of different force reset request.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-dev.h

index 52b6beb371fe846f0c0e648d56a4c69c17f45913..c5b724eaf3065f495a96b92bd090154b753a6732 100644 (file)
@@ -3378,6 +3378,12 @@ static int iwl_init_drv(struct iwl_priv *priv)
        priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
        priv->agg_tids_count = 0;
 
+       /* initialize force reset */
+       priv->force_reset[IWL_RF_RESET].reset_duration =
+               IWL_DELAY_NEXT_FORCE_RF_RESET;
+       priv->force_reset[IWL_FW_RESET].reset_duration =
+               IWL_DELAY_NEXT_FORCE_FW_RELOAD;
+
        /* Choose which receivers/antennas to use */
        if (priv->cfg->ops->hcmd->set_rxon_chain)
                priv->cfg->ops->hcmd->set_rxon_chain(priv);
index bd56827b8fefa327afc5f8f1614f06e215630597..55252a692de7ea430baac4a05f9e673af8d16bbc 100644 (file)
@@ -3357,22 +3357,30 @@ static void iwl_force_rf_reset(struct iwl_priv *priv)
        return;
 }
 
-#define IWL_DELAY_NEXT_FORCE_RESET (HZ*3)
 
 int iwl_force_reset(struct iwl_priv *priv, int mode)
 {
+       struct iwl_force_reset *force_reset;
+
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return -EINVAL;
 
-       if (priv->last_force_reset_jiffies &&
-           time_after(priv->last_force_reset_jiffies +
-                      IWL_DELAY_NEXT_FORCE_RESET, jiffies)) {
+       if (mode >= IWL_MAX_FORCE_RESET) {
+               IWL_DEBUG_INFO(priv, "invalid reset request.\n");
+               return -EINVAL;
+       }
+       force_reset = &priv->force_reset[mode];
+       force_reset->reset_request_count++;
+       if (force_reset->last_force_reset_jiffies &&
+           time_after(force_reset->last_force_reset_jiffies +
+           force_reset->reset_duration, jiffies)) {
                IWL_DEBUG_INFO(priv, "force reset rejected\n");
+               force_reset->reset_reject_count++;
                return -EAGAIN;
        }
-
+       force_reset->reset_success_count++;
+       force_reset->last_force_reset_jiffies = jiffies;
        IWL_DEBUG_INFO(priv, "perform force reset (%d)\n", mode);
-
        switch (mode) {
        case IWL_RF_RESET:
                iwl_force_rf_reset(priv);
@@ -3389,12 +3397,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode)
                clear_bit(STATUS_READY, &priv->status);
                queue_work(priv->workqueue, &priv->restart);
                break;
-       default:
-               IWL_DEBUG_INFO(priv, "invalid reset request.\n");
-               return -EINVAL;
        }
-       priv->last_force_reset_jiffies = jiffies;
-
        return 0;
 }
 
index 021c68658718ce45fba35b43d522f44d2da059f5..7914d65a5a55f6716f946d784dfbb9553c794f7d 100644 (file)
@@ -1036,9 +1036,21 @@ struct iwl_event_log {
 #define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF        (200)
 #define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255)
 
+#define IWL_DELAY_NEXT_FORCE_RF_RESET  (HZ*3)
+#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)
+
 enum iwl_reset {
        IWL_RF_RESET = 0,
        IWL_FW_RESET,
+       IWL_MAX_FORCE_RESET,
+};
+
+struct iwl_force_reset {
+       int reset_request_count;
+       int reset_success_count;
+       int reset_reject_count;
+       unsigned long reset_duration;
+       unsigned long last_force_reset_jiffies;
 };
 
 struct iwl_priv {
@@ -1076,7 +1088,7 @@ struct iwl_priv {
        u8 agg_tids_count;
 
        /* force reset */
-       unsigned long last_force_reset_jiffies;
+       struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];
 
        /* we allocate array of iwl4965_channel_info for NIC's valid channels.
         *    Access via channel # using indirect index array */