Skip to content

Commit

Permalink
iwlwifi: mvm: add registration to thermal zone
Browse files Browse the repository at this point in the history
Register to thermal_zone interface and implement the
thermal ops.
The thermal handles the device throttling, and sets the
the temperature thresholds the Thermal Manager would be
notified of crossing.
The thermal interface adds a new thermal zone device sensor
under /sys/class/thermal/ folder.

Signed-off-by: Chaya Rachel Ivgi <chaya.rachel.ivgi@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
  • Loading branch information
Chaya Rachel Ivgi authored and Emmanuel Grumbach committed Feb 27, 2016
1 parent 0a3b711 commit c221daf
Show file tree
Hide file tree
Showing 5 changed files with 353 additions and 17 deletions.
33 changes: 30 additions & 3 deletions drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ enum {
*/
enum iwl_phy_ops_subcmd_ids {
CMD_DTS_MEASUREMENT_TRIGGER_WIDE = 0x0,
TEMP_REPORTING_THRESHOLDS_CMD = 0x04,
CT_KILL_NOTIFICATION = 0xFE,
DTS_MEASUREMENT_NOTIF_WIDE = 0xFF,
};
Expand Down Expand Up @@ -1676,15 +1677,28 @@ struct iwl_ext_dts_measurement_cmd {
} __packed; /* XVT_FW_DTS_CONTROL_MEASUREMENT_REQUEST_API_S */

/**
* iwl_dts_measurement_notif - notification received with the measurements
* struct iwl_dts_measurement_notif_v1 - measurements notification
*
* @temp: the measured temperature
* @voltage: the measured voltage
*/
struct iwl_dts_measurement_notif {
struct iwl_dts_measurement_notif_v1 {
__le32 temp;
__le32 voltage;
} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S */
} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S_VER_1*/

/**
* struct iwl_dts_measurement_notif_v2 - measurements notification
*
* @temp: the measured temperature
* @voltage: the measured voltage
* @threshold_idx: the trip index that was crossed
*/
struct iwl_dts_measurement_notif_v2 {
__le32 temp;
__le32 voltage;
__le32 threshold_idx;
} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S_VER_2 */

/**
* struct ct_kill_notif - CT-kill entry notification
Expand All @@ -1697,6 +1711,19 @@ struct ct_kill_notif {
__le16 reserved;
} __packed; /* GRP_PHY_CT_KILL_NTF */

#define IWL_MAX_DTS_TRIPS 8

/**
* struct iwl_temp_report_ths_cmd - set temperature thresholds
*
* @num_temps: number of temperature thresholds passed
* @thresholds: array with the thresholds to be configured
*/
struct temp_report_ths_cmd {
__le32 num_temps;
__le16 thresholds[IWL_MAX_DTS_TRIPS];
} __packed; /* GRP_PHY_TEMP_REPORTING_THRESHOLDS_CMD */

/***********************************
* TDLS API
***********************************/
Expand Down
13 changes: 13 additions & 0 deletions drivers/net/wireless/intel/iwlwifi/mvm/fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -952,8 +952,21 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
goto error;
}

#ifdef CONFIG_THERMAL
if (iwl_mvm_is_tt_in_fw(mvm)) {
/* in order to give the responsibility of ct-kill and
* TX backoff to FW we need to send empty temperature reporting
* cmd during init time
*/
iwl_mvm_send_temp_report_ths_cmd(mvm);
} else {
/* Initialize tx backoffs to the minimal possible */
iwl_mvm_tt_tx_backoff(mvm, 0);
}
#else
/* Initialize tx backoffs to the minimal possible */
iwl_mvm_tt_tx_backoff(mvm, 0);
#endif

WARN_ON(iwl_mvm_config_ltr(mvm));

Expand Down
31 changes: 29 additions & 2 deletions drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@
#include <linux/leds.h>
#include <linux/in6.h>

#ifdef CONFIG_THERMAL
#include <linux/thermal.h>
#endif

#include "iwl-op-mode.h"
#include "iwl-trans.h"
#include "iwl-notif-wait.h"
Expand Down Expand Up @@ -519,6 +523,20 @@ struct iwl_mvm_tt_mgmt {
bool throttle;
};

#ifdef CONFIG_THERMAL
/**
*struct iwl_mvm_thermal_device - thermal zone related data
* @temp_trips: temperature thresholds for report
* @fw_trips_index: keep indexes to original array - temp_trips
* @tzone: thermal zone device data
*/
struct iwl_mvm_thermal_device {
s16 temp_trips[IWL_MAX_DTS_TRIPS];
u8 fw_trips_index[IWL_MAX_DTS_TRIPS];
struct thermal_zone_device *tzone;
};
#endif

#define IWL_MVM_NUM_LAST_FRAMES_UCODE_RATES 8

struct iwl_mvm_frame_stats {
Expand Down Expand Up @@ -799,6 +817,10 @@ struct iwl_mvm {

/* Thermal Throttling and CTkill */
struct iwl_mvm_tt_mgmt thermal_throttle;
#ifdef CONFIG_THERMAL
struct iwl_mvm_thermal_device tz_device;
#endif

s32 temperature; /* Celsius */
/*
* Debug option to set the NIC temperature. This option makes the
Expand Down Expand Up @@ -1032,6 +1054,7 @@ static inline bool iwl_mvm_has_new_rx_api(struct iwl_mvm *mvm)

static inline bool iwl_mvm_is_tt_in_fw(struct iwl_mvm *mvm)
{
#ifdef CONFIG_THERMAL
/* these two TLV are redundant since the responsibility to CT-kill by
* FW happens only after we send at least one command of
* temperature THs report.
Expand All @@ -1040,6 +1063,9 @@ static inline bool iwl_mvm_is_tt_in_fw(struct iwl_mvm *mvm)
IWL_UCODE_TLV_CAPA_CT_KILL_BY_FW) &&
fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT);
#else /* CONFIG_THERMAL */
return false;
#endif /* CONFIG_THERMAL */
}

extern const u8 iwl_mvm_ac_to_tx_fifo[];
Expand Down Expand Up @@ -1512,11 +1538,12 @@ void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp);
void iwl_mvm_temp_notif(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb);
void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff);
void iwl_mvm_tt_exit(struct iwl_mvm *mvm);
void iwl_mvm_thermal_initialize(struct iwl_mvm *mvm, u32 min_backoff);
void iwl_mvm_thermal_exit(struct iwl_mvm *mvm);
void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp);
void iwl_mvm_ct_kill_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm);

/* Location Aware Regulatory */
struct iwl_mcc_update_resp *
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/wireless/intel/iwlwifi/mvm/ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
*/
static const struct iwl_hcmd_names iwl_mvm_phy_names[] = {
HCMD_NAME(CMD_DTS_MEASUREMENT_TRIGGER_WIDE),
HCMD_NAME(TEMP_REPORTING_THRESHOLDS_CMD),
HCMD_NAME(CT_KILL_NOTIFICATION),
HCMD_NAME(DTS_MEASUREMENT_NOTIF_WIDE),
};
Expand Down Expand Up @@ -591,7 +592,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
mvm->cfg->name, mvm->trans->hw_rev);

min_backoff = calc_min_backoff(trans, cfg);
iwl_mvm_tt_initialize(mvm, min_backoff);
iwl_mvm_thermal_initialize(mvm, min_backoff);

if (iwlwifi_mod_params.nvm_file)
mvm->nvm_file_name = iwlwifi_mod_params.nvm_file;
Expand Down Expand Up @@ -664,6 +665,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
out_unregister:
ieee80211_unregister_hw(mvm->hw);
iwl_mvm_leds_exit(mvm);
iwl_mvm_thermal_exit(mvm);
out_free:
flush_delayed_work(&mvm->fw_dump_wk);
iwl_phy_db_free(mvm->phy_db);
Expand All @@ -681,7 +683,7 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)

iwl_mvm_leds_exit(mvm);

iwl_mvm_tt_exit(mvm);
iwl_mvm_thermal_exit(mvm);

ieee80211_unregister_hw(mvm->hw);

Expand Down
Loading

0 comments on commit c221daf

Please sign in to comment.