iwlwifi: split force_reset debugfs file
authorJohannes Berg <johannes.berg@intel.com>
Tue, 10 Apr 2012 00:46:57 +0000 (17:46 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 12 Apr 2012 19:06:09 +0000 (15:06 -0400)
Split the force_reset debugfs file into two
different files:
 * "rf_reset" triggers a reset of the RF when
   written to and exposes statistics on RF
   resets when read
 * fw_restart triggers a firmware restart when
   written to and lives in the transport

This cleans up all sources of firmware restart
to originate within the transport layer and
allows us to simplify some code.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlwifi/iwl-agn-rx.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c

index 25abbb9b5e071b498b6582c56aafe2bc47bb8ffc..934ace9468d68af2014a59baf455fd6067056272 100644 (file)
@@ -307,7 +307,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv,
 
        if (iwlagn_mod_params.plcp_check &&
            !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
-               iwl_force_reset(priv, IWL_RF_RESET, false);
+               iwl_force_rf_reset(priv, false);
 }
 
 /* Calculate noise level, based on measurements during network silence just
index 096c227640a7aeaf1273fd25d0321f8f9f404b56..5216713105c6b629626de98492435a923816de51 100644 (file)
@@ -1332,12 +1332,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
 
        priv->ucode_owner = IWL_OWNERSHIP_DRIVER;
 
-       /* 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;
-
        priv->rx_statistics_jiffies = jiffies;
 
        /* Choose which receivers/antennas to use */
index 51001622430b3238e865e773e0527e3019be7394..da5ea1b87e6b90f605deb5f0aea5065846e5fdf7 100644 (file)
@@ -195,6 +195,7 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
 /* scan */
 void iwlagn_post_scan(struct iwl_priv *priv);
 void iwlagn_disable_roc(struct iwl_priv *priv);
+int iwl_force_rf_reset(struct iwl_priv *priv, bool external);
 
 /* bt coex */
 void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
index 6fc1841ff536fc84c801ec03460a711a8c2e27bb..6a02ade07a24125cdded1b9e20a46ce1c333e9d0 100644 (file)
@@ -746,15 +746,30 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
 }
 #endif
 
-static void iwl_force_rf_reset(struct iwl_priv *priv)
+int iwl_force_rf_reset(struct iwl_priv *priv, bool external)
 {
+       struct iwl_rf_reset *rf_reset;
+
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-               return;
+               return -EAGAIN;
 
        if (!iwl_is_any_associated(priv)) {
                IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
-               return;
+               return -ENOLINK;
        }
+
+       rf_reset = &priv->rf_reset;
+       rf_reset->reset_request_count++;
+       if (!external && rf_reset->last_reset_jiffies &&
+           time_after(rf_reset->last_reset_jiffies +
+                      IWL_DELAY_NEXT_FORCE_RF_RESET, jiffies)) {
+               IWL_DEBUG_INFO(priv, "RF reset rejected\n");
+               rf_reset->reset_reject_count++;
+               return -EAGAIN;
+       }
+       rf_reset->reset_success_count++;
+       rf_reset->last_reset_jiffies = jiffies;
+
        /*
         * There is no easy and better way to force reset the radio,
         * the only known method is switching channel which will force to
@@ -766,56 +781,6 @@ static void iwl_force_rf_reset(struct iwl_priv *priv)
         */
        IWL_DEBUG_INFO(priv, "perform radio reset.\n");
        iwl_internal_short_hw_scan(priv);
-}
-
-
-int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
-{
-       struct iwl_force_reset *force_reset;
-
-       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-               return -EINVAL;
-
-       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 (!external) {
-               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);
-               break;
-       case IWL_FW_RESET:
-               /*
-                * if the request is from external(ex: debugfs),
-                * then always perform the request in regardless the module
-                * parameter setting
-                * if the request is from internal (uCode error or driver
-                * detect failure), then fw_restart module parameter
-                * need to be check before performing firmware reload
-                */
-               if (!external && !iwlagn_mod_params.restart_fw) {
-                       IWL_DEBUG_INFO(priv, "Cancel firmware reload based on "
-                                      "module parameter setting\n");
-                       break;
-               }
-               IWL_ERR(priv, "On demand firmware reload\n");
-               iwlagn_fw_error(priv, true);
-               break;
-       }
        return 0;
 }
 
index f388dc4474da6ac2b97249c69249553b78efcd60..999a806a3848b9debca27e55bff0f4564c5dd9cb 100644 (file)
@@ -164,7 +164,6 @@ int iwl_scan_cancel(struct iwl_priv *priv);
 void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
 void iwl_force_scan_end(struct iwl_priv *priv);
 void iwl_internal_short_hw_scan(struct iwl_priv *priv);
-int iwl_force_reset(struct iwl_priv *priv, int mode, bool external);
 void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
 void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
 void iwl_cancel_scan_deferred_work(struct iwl_priv *priv);
index eaf5e66e603c903ce58f2d7b4bdca05e65589725..2e85edac560c82ddb197dcb0b17dbdd79d88606d 100644 (file)
@@ -2267,59 +2267,39 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
        return count;
 }
 
-static ssize_t iwl_dbgfs_force_reset_read(struct file *file,
-                                       char __user *user_buf,
-                                       size_t count, loff_t *ppos)
+static ssize_t iwl_dbgfs_rf_reset_read(struct file *file,
+                                      char __user *user_buf,
+                                      size_t count, loff_t *ppos)
 {
        struct iwl_priv *priv = file->private_data;
-       int i, pos = 0;
+       int pos = 0;
        char buf[300];
        const size_t bufsz = sizeof(buf);
-       struct iwl_force_reset *force_reset;
+       struct iwl_rf_reset *rf_reset = &priv->rf_reset;
+
+       pos += scnprintf(buf + pos, bufsz - pos,
+                       "RF reset statistics\n");
+       pos += scnprintf(buf + pos, bufsz - pos,
+                       "\tnumber of reset request: %d\n",
+                       rf_reset->reset_request_count);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                       "\tnumber of reset request success: %d\n",
+                       rf_reset->reset_success_count);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                       "\tnumber of reset request reject: %d\n",
+                       rf_reset->reset_reject_count);
 
-       for (i = 0; i < IWL_MAX_FORCE_RESET; i++) {
-               force_reset = &priv->force_reset[i];
-               pos += scnprintf(buf + pos, bufsz - pos,
-                               "Force reset method %d\n", i);
-               pos += scnprintf(buf + pos, bufsz - pos,
-                               "\tnumber of reset request: %d\n",
-                               force_reset->reset_request_count);
-               pos += scnprintf(buf + pos, bufsz - pos,
-                               "\tnumber of reset request success: %d\n",
-                               force_reset->reset_success_count);
-               pos += scnprintf(buf + pos, bufsz - pos,
-                               "\tnumber of reset request reject: %d\n",
-                               force_reset->reset_reject_count);
-               pos += scnprintf(buf + pos, bufsz - pos,
-                               "\treset duration: %lu\n",
-                               force_reset->reset_duration);
-       }
        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
 
-static ssize_t iwl_dbgfs_force_reset_write(struct file *file,
+static ssize_t iwl_dbgfs_rf_reset_write(struct file *file,
                                        const char __user *user_buf,
                                        size_t count, loff_t *ppos) {
 
        struct iwl_priv *priv = file->private_data;
-       char buf[8];
-       int buf_size;
-       int reset, ret;
+       int ret;
 
-       memset(buf, 0, sizeof(buf));
-       buf_size = min(count, sizeof(buf) -  1);
-       if (copy_from_user(buf, user_buf, buf_size))
-               return -EFAULT;
-       if (sscanf(buf, "%d", &reset) != 1)
-               return -EINVAL;
-       switch (reset) {
-       case IWL_RF_RESET:
-       case IWL_FW_RESET:
-               ret = iwl_force_reset(priv, reset, true);
-               break;
-       default:
-               return -EINVAL;
-       }
+       ret = iwl_force_rf_reset(priv, true);
        return ret ? ret : count;
 }
 
@@ -2507,7 +2487,7 @@ DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
 DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
 DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
 DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
-DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
+DEBUGFS_READ_WRITE_FILE_OPS(rf_reset);
 DEBUGFS_READ_FILE_OPS(rxon_flags);
 DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
 DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
@@ -2565,7 +2545,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
        DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
        DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
        DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
-       DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
+       DEBUGFS_ADD_FILE(rf_reset, dir_debug, S_IWUSR | S_IRUSR);
        DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
        DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
        DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
index caaf14c3de1bc1a3162d0393535c22a261255bc3..58073da16279cfec94e97f107a431d27a9383334 100644 (file)
@@ -582,7 +582,6 @@ struct iwl_event_log {
 #define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE     (0)
 
 #define IWL_DELAY_NEXT_FORCE_RF_RESET  (HZ*3)
-#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)
 
 /* TX queue watchdog timeouts in mSecs */
 #define IWL_WATCHHDOG_DISABLED (0)
@@ -598,18 +597,11 @@ struct iwl_event_log {
 #define IWL_MAX_CONTINUE_RELOAD_CNT    4
 
 
-enum iwl_reset {
-       IWL_RF_RESET = 0,
-       IWL_FW_RESET,
-       IWL_MAX_FORCE_RESET,
-};
-
-struct iwl_force_reset {
+struct iwl_rf_reset {
        int reset_request_count;
        int reset_success_count;
        int reset_reject_count;
-       unsigned long reset_duration;
-       unsigned long last_force_reset_jiffies;
+       unsigned long last_reset_jiffies;
 };
 
 /* extend beacon time format bit shifting  */
@@ -806,8 +798,8 @@ struct iwl_priv {
        /*counters */
        u32 rx_handlers_stats[REPLY_MAX];
 
-       /* force reset */
-       struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];
+       /* rf reset */
+       struct iwl_rf_reset rf_reset;
 
        /* firmware reload counter and timestamp */
        unsigned long reload_jiffies;
index f3695fea45ef322f492ed8abc5bee121e6a6a8bb..914b6d5df9b2d25cc3d2245b027ec926fb74e189 100644 (file)
@@ -1994,11 +1994,26 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
        return ret;
 }
 
+static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
+                                         const char __user *user_buf,
+                                         size_t count, loff_t *ppos)
+{
+       struct iwl_trans *trans = file->private_data;
+
+       if (!trans->op_mode)
+               return -EAGAIN;
+
+       iwl_op_mode_nic_error(trans->op_mode);
+
+       return count;
+}
+
 DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
 DEBUGFS_READ_FILE_OPS(fh_reg);
 DEBUGFS_READ_FILE_OPS(rx_queue);
 DEBUGFS_READ_FILE_OPS(tx_queue);
 DEBUGFS_WRITE_FILE_OPS(csr);
+DEBUGFS_WRITE_FILE_OPS(fw_restart);
 
 /*
  * Create the debugfs files and directories
@@ -2012,6 +2027,7 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
        DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR);
        DEBUGFS_ADD_FILE(csr, dir, S_IWUSR);
        DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR);
+       DEBUGFS_ADD_FILE(fw_restart, dir, S_IWUSR);
        return 0;
 }
 #else