iwlwifi: mvm: Add set NIC temperature debug option
authorMatti Gottlieb <matti.gottlieb@intel.com>
Thu, 17 Jul 2014 13:41:14 +0000 (16:41 +0300)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Wed, 3 Sep 2014 19:33:06 +0000 (22:33 +0300)
Add ability to set the NIC's temperature and ignore the actual temperature
that the FW supplies.

Signed-off-by: Matti Gottlieb <matti.gottlieb@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/mvm/debugfs.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/rx.c

index 7d18f466fbb3351b3b173fdcf4aa15bddd5d0b75..f7e44889182a66b6d311355de029fc74c306dd47 100644 (file)
@@ -257,6 +257,60 @@ static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf,
        return count;
 }
 
+static ssize_t iwl_dbgfs_set_nic_temperature_read(struct file *file,
+                                                 char __user *user_buf,
+                                                 size_t count, loff_t *ppos)
+{
+       struct iwl_mvm *mvm = file->private_data;
+       char buf[16];
+       int pos;
+
+       if (!mvm->temperature_test)
+               pos = scnprintf(buf , sizeof(buf), "disabled\n");
+       else
+               pos = scnprintf(buf , sizeof(buf), "%d\n", mvm->temperature);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
+/*
+ * Set NIC Temperature
+ * Cause the driver to ignore the actual NIC temperature reported by the FW
+ * Enable: any value between IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -
+ * IWL_MVM_DEBUG_SET_TEMPERATURE_MAX
+ * Disable: IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE
+ */
+static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm,
+                                                  char *buf, size_t count,
+                                                  loff_t *ppos)
+{
+       int temperature;
+
+       if (kstrtoint(buf, 10, &temperature))
+               return -EINVAL;
+       /* not a legal temperature */
+       if ((temperature > IWL_MVM_DEBUG_SET_TEMPERATURE_MAX &&
+            temperature != IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) ||
+           temperature < IWL_MVM_DEBUG_SET_TEMPERATURE_MIN)
+               return -EINVAL;
+
+       mutex_lock(&mvm->mutex);
+       if (temperature == IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) {
+               mvm->temperature_test = false;
+       } else {
+               mvm->temperature_test = true;
+               mvm->temperature = temperature;
+       }
+       IWL_DEBUG_TEMP(mvm, "%sabling debug set temperature (temp = %d)\n",
+                      mvm->temperature_test ? "En" : "Dis" ,
+                      mvm->temperature);
+       /* handle the temperature change */
+       iwl_mvm_tt_handler(mvm);
+       mutex_unlock(&mvm->mutex);
+
+       return count;
+}
+
 static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
                                       size_t count, loff_t *ppos)
 {
@@ -1296,6 +1350,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
 MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
 MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature, 64);
 MVM_DEBUGFS_READ_FILE_OPS(stations);
 MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
 MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
@@ -1336,6 +1391,8 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
        MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, S_IWUSR);
        MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR);
        MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
+       MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir,
+                            S_IWUSR | S_IRUSR);
        MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
        MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR);
        MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
index 2e73d3bd7757605e2483fa00f147086abe32b09c..802d29e971f747444400896974b6d9eea32ff19a 100644 (file)
@@ -512,6 +512,10 @@ enum {
        D0I3_PENDING_WAKEUP,
 };
 
+#define IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE 0xff
+#define IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -100
+#define IWL_MVM_DEBUG_SET_TEMPERATURE_MAX 200
+
 struct iwl_mvm {
        /* for logger access */
        struct device *dev;
@@ -694,6 +698,12 @@ struct iwl_mvm {
        /* Thermal Throttling and CTkill */
        struct iwl_mvm_tt_mgmt thermal_throttle;
        s32 temperature;        /* Celsius */
+       /*
+        * Debug option to set the NIC temperature. This option makes the
+        * driver think this is the actual NIC temperature, and ignore the
+        * real temperature that is received from the fw
+        */
+       bool temperature_test;  /* Debug test temperature is enabled */
 
 #ifdef CONFIG_NL80211_TESTMODE
        u32 noa_duration;
index 4b98987fc4133f6b7d7c0a21a1d11e57658a35f7..8f43affe266f48f5e03b7f0239e039c26fa293cb 100644 (file)
@@ -491,10 +491,29 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
                .mvm = mvm,
        };
 
+       /*
+        * set temperature debug enabled - ignore FW temperature updates
+        * and use the user set temperature.
+        */
+       if (mvm->temperature_test) {
+               if (mvm->temperature < le32_to_cpu(common->temperature))
+                       IWL_DEBUG_TEMP(mvm,
+                                      "Ignoring FW temperature update that is greater than the debug set temperature (debug temp = %d, fw temp = %d)\n",
+                                      mvm->temperature,
+                                      le32_to_cpu(common->temperature));
+               /*
+                * skip iwl_mvm_tt_handler since we are in
+                * temperature debug mode and we are ignoring
+                * the new temperature value
+                */
+               goto update;
+       }
+
        if (mvm->temperature != le32_to_cpu(common->temperature)) {
                mvm->temperature = le32_to_cpu(common->temperature);
                iwl_mvm_tt_handler(mvm);
        }
+update:
        iwl_mvm_update_rx_statistics(mvm, stats);
 
        ieee80211_iterate_active_interfaces(mvm->hw,