Commit 46f9381a authored by Wey-Yi Guy's avatar Wey-Yi Guy Committed by John W. Linville

iwlwifi: Thermal Throttling Management - part 2

Part 2 of Thermal Throttling Management -

Thermal Throttling feature is used to put NIC into low power state when
driver detect the Radio temperature reach pre-defined threshold

Two Thermal Throttling Management Methods; this patch introduce the
Advance Thermal Throttling:
TI-0: system power index, no tx/rx restriction, HT enabled
TI-1: power index 5, 1 spatial stream Tx, multiple spatial stream Rx, HT
enabled
TI-2: power index 5: 1 spatial stream Tx, 1 spatial stream Rx, HT
disabled
TI-CT-KILL: power index 5, no Tx, no Rx, HT disabled

For advance Thermal Throttling, CT_KILL_ENTER threshold and CT_KILL_EXIT
threshold are different; uCode will not stay awake until reach
CT_KILL_EXIT threshold.
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 39b73fb1
...@@ -177,7 +177,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, ...@@ -177,7 +177,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
struct sk_buff *skb, struct sk_buff *skb,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
struct iwl_lq_sta *lq_sta); struct iwl_lq_sta *lq_sta);
static void rs_fill_link_cmd(const struct iwl_priv *priv, static void rs_fill_link_cmd(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta, u32 rate_n_flags); struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
...@@ -1398,6 +1398,12 @@ static int rs_move_legacy_other(struct iwl_priv *priv, ...@@ -1398,6 +1398,12 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
int ret = 0; int ret = 0;
u8 update_search_tbl_counter = 0; u8 update_search_tbl_counter = 0;
if (!iwl_ht_enabled(priv))
/* stay in Legacy */
tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
else if (iwl_tx_ant_restriction(priv) == IWL_TX_SINGLE &&
tbl->action > IWL_LEGACY_SWITCH_SISO)
tbl->action = IWL_LEGACY_SWITCH_SISO;
for (; ;) { for (; ;) {
lq_sta->action_counter++; lq_sta->action_counter++;
switch (tbl->action) { switch (tbl->action) {
...@@ -1529,6 +1535,11 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, ...@@ -1529,6 +1535,11 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
u8 update_search_tbl_counter = 0; u8 update_search_tbl_counter = 0;
int ret; int ret;
if (iwl_tx_ant_restriction(priv) == IWL_TX_SINGLE &&
tbl->action > IWL_SISO_SWITCH_ANTENNA2) {
/* stay in SISO */
tbl->action = IWL_SISO_SWITCH_ANTENNA1;
}
for (;;) { for (;;) {
lq_sta->action_counter++; lq_sta->action_counter++;
switch (tbl->action) { switch (tbl->action) {
...@@ -1663,6 +1674,12 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, ...@@ -1663,6 +1674,12 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
u8 update_search_tbl_counter = 0; u8 update_search_tbl_counter = 0;
int ret; int ret;
if ((iwl_tx_ant_restriction(priv) == IWL_TX_SINGLE) &&
(tbl->action < IWL_MIMO2_SWITCH_SISO_A ||
tbl->action > IWL_MIMO2_SWITCH_SISO_C)) {
/* switch in SISO */
tbl->action = IWL_MIMO2_SWITCH_SISO_A;
}
for (;;) { for (;;) {
lq_sta->action_counter++; lq_sta->action_counter++;
switch (tbl->action) { switch (tbl->action) {
...@@ -1799,6 +1816,12 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, ...@@ -1799,6 +1816,12 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
int ret; int ret;
u8 update_search_tbl_counter = 0; u8 update_search_tbl_counter = 0;
if ((iwl_tx_ant_restriction(priv) == IWL_TX_SINGLE) &&
(tbl->action < IWL_MIMO3_SWITCH_SISO_A ||
tbl->action > IWL_MIMO3_SWITCH_SISO_C)) {
/* switch in SISO */
tbl->action = IWL_MIMO3_SWITCH_SISO_A;
}
for (;;) { for (;;) {
lq_sta->action_counter++; lq_sta->action_counter++;
switch (tbl->action) { switch (tbl->action) {
...@@ -2178,8 +2201,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, ...@@ -2178,8 +2201,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
tbl->expected_tpt[index] + 64) / 128)); tbl->expected_tpt[index] + 64) / 128));
/* If we are searching for better modulation mode, check success. */ /* If we are searching for better modulation mode, check success. */
if (lq_sta->search_better_tbl) { if (lq_sta->search_better_tbl &&
(iwl_tx_ant_restriction(priv) == IWL_TX_MULTI)) {
/* If good success, continue using the "search" mode; /* If good success, continue using the "search" mode;
* no need to send new link quality command, since we're * no need to send new link quality command, since we're
* continuing to use the setup that we've been trying. */ * continuing to use the setup that we've been trying. */
...@@ -2307,7 +2330,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, ...@@ -2307,7 +2330,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
((sr > IWL_RATE_HIGH_TH) || ((sr > IWL_RATE_HIGH_TH) ||
(current_tpt > (100 * tbl->expected_tpt[low])))) (current_tpt > (100 * tbl->expected_tpt[low]))))
scale_action = 0; scale_action = 0;
if (!iwl_ht_enabled(priv) && !is_legacy(tbl->lq_type))
scale_action = -1;
if (iwl_tx_ant_restriction(priv) != IWL_TX_MULTI &&
(is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type)))
scale_action = -1;
switch (scale_action) { switch (scale_action) {
case -1: case -1:
/* Decrease starting rate, update uCode's rate table */ /* Decrease starting rate, update uCode's rate table */
...@@ -2341,9 +2368,11 @@ lq_update: ...@@ -2341,9 +2368,11 @@ lq_update:
rate = rs_update_rate_tbl(priv, lq_sta, rate = rs_update_rate_tbl(priv, lq_sta,
tbl, index, is_green); tbl, index, is_green);
/* Should we stay with this modulation mode, or search for a new one? */ if (iwl_tx_ant_restriction(priv) == IWL_TX_MULTI) {
/* Should we stay with this modulation mode,
* or search for a new one? */
rs_stay_in_table(lq_sta); rs_stay_in_table(lq_sta);
}
/* /*
* Search for new modulation mode if we're: * Search for new modulation mode if we're:
* 1) Not changing rates right now * 1) Not changing rates right now
...@@ -2400,7 +2429,8 @@ lq_update: ...@@ -2400,7 +2429,8 @@ lq_update:
* have been tried and compared, stay in this best modulation * have been tried and compared, stay in this best modulation
* mode for a while before next round of mode comparisons. */ * mode for a while before next round of mode comparisons. */
if (lq_sta->enable_counter && if (lq_sta->enable_counter &&
(lq_sta->action_counter >= tbl1->max_search)) { (lq_sta->action_counter >= tbl1->max_search) &&
iwl_ht_enabled(priv)) {
if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
(lq_sta->tx_agg_tid_en & (1 << tid)) && (lq_sta->tx_agg_tid_en & (1 << tid)) &&
(tid != MAX_TID_COUNT)) { (tid != MAX_TID_COUNT)) {
...@@ -2686,7 +2716,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, ...@@ -2686,7 +2716,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
rs_initialize_lq(priv, conf, sta, lq_sta); rs_initialize_lq(priv, conf, sta, lq_sta);
} }
static void rs_fill_link_cmd(const struct iwl_priv *priv, static void rs_fill_link_cmd(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta, u32 new_rate) struct iwl_lq_sta *lq_sta, u32 new_rate)
{ {
struct iwl_scale_tbl_info tbl_type; struct iwl_scale_tbl_info tbl_type;
......
This diff is collapsed.
...@@ -33,8 +33,18 @@ ...@@ -33,8 +33,18 @@
struct iwl_priv; struct iwl_priv;
#define IWL_ABSOLUTE_ZERO 0
#define IWL_ABSOLUTE_MAX 0xFFFFFFFF
#define IWL_TT_INCREASE_MARGIN 5 #define IWL_TT_INCREASE_MARGIN 5
/* Tx/Rx restrictions */
#define IWL_TX_MULTI 0x02
#define IWL_TX_SINGLE 0x01
#define IWL_TX_NONE 0x00
#define IWL_RX_MULTI 0x02
#define IWL_RX_SINGLE 0x01
#define IWL_RX_NONE 0x00
/* Thermal Throttling State Machine states */ /* Thermal Throttling State Machine states */
enum iwl_tt_state { enum iwl_tt_state {
IWL_TI_0, /* normal temperature, system power state */ IWL_TI_0, /* normal temperature, system power state */
...@@ -44,6 +54,35 @@ enum iwl_tt_state { ...@@ -44,6 +54,35 @@ enum iwl_tt_state {
IWL_TI_STATE_MAX IWL_TI_STATE_MAX
}; };
/**
* struct iwl_tt_restriction - Thermal Throttling restriction table used
* by advance thermal throttling management
* based on the current thermal throttling state, determine
* number of tx/rx streams; and the status of HT operation
* @tx_stream: number of tx stream allowed
* @is_ht: ht enable/disable
* @rx_stream: number of rx stream allowed
*/
struct iwl_tt_restriction {
u8 tx_stream;
bool is_ht;
u8 rx_stream;
};
/**
* struct iwl_tt_trans - Thermal Throttling transaction table; used by
* advance thermal throttling algorithm to determine next
* thermal state to go based on the current temperature
* @next_state: next thermal throttling mode
* @tt_low: low temperature threshold to change state
* @tt_high: high temperature threshold to change state
*/
struct iwl_tt_trans {
enum iwl_tt_state next_state;
u32 tt_low;
u32 tt_high;
};
/** /**
* struct iwl_tt_mgnt - Thermal Throttling Management structure * struct iwl_tt_mgnt - Thermal Throttling Management structure
* @state: current Thermal Throttling state * @state: current Thermal Throttling state
...@@ -55,6 +94,11 @@ enum iwl_tt_state { ...@@ -55,6 +94,11 @@ enum iwl_tt_state {
* @sys_power_mode: previous system power mode * @sys_power_mode: previous system power mode
* before transition into TT state * before transition into TT state
* @tt_previous_temperature: last measured temperature * @tt_previous_temperature: last measured temperature
* @iwl_tt_restriction: ptr to restriction tbl, used by advance
* thermal throttling to determine how many tx/rx streams
* should be used in tt state; and can HT be enabled or not
* @iwl_tt_trans: ptr to adv trans table, used by advance thermal throttling
* state transaction
*/ */
struct iwl_tt_mgmt { struct iwl_tt_mgmt {
enum iwl_tt_state state; enum iwl_tt_state state;
...@@ -63,6 +107,8 @@ struct iwl_tt_mgmt { ...@@ -63,6 +107,8 @@ struct iwl_tt_mgmt {
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUG
s32 tt_previous_temp; s32 tt_previous_temp;
#endif #endif
struct iwl_tt_restriction *restriction;
struct iwl_tt_trans *transaction;
}; };
enum { enum {
...@@ -92,6 +138,8 @@ struct iwl_power_mgr { ...@@ -92,6 +138,8 @@ struct iwl_power_mgr {
u8 user_power_setting; /* set by user through sysfs */ u8 user_power_setting; /* set by user through sysfs */
u8 power_disabled; /* set by mac80211's CONF_PS */ u8 power_disabled; /* set by mac80211's CONF_PS */
struct iwl_tt_mgmt tt; /* Thermal Throttling Management */ struct iwl_tt_mgmt tt; /* Thermal Throttling Management */
bool adv_tt; /* false: legacy mode */
/* true: advance mode */
bool ct_kill_toggle; /* use to toggle the CSR bit when bool ct_kill_toggle; /* use to toggle the CSR bit when
* checking uCode temperature * checking uCode temperature
*/ */
...@@ -100,6 +148,9 @@ struct iwl_power_mgr { ...@@ -100,6 +148,9 @@ struct iwl_power_mgr {
int iwl_power_update_mode(struct iwl_priv *priv, bool force); int iwl_power_update_mode(struct iwl_priv *priv, bool force);
int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode); int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
bool iwl_ht_enabled(struct iwl_priv *priv);
u8 iwl_tx_ant_restriction(struct iwl_priv *priv);
u8 iwl_rx_ant_restriction(struct iwl_priv *priv);
void iwl_tt_enter_ct_kill(struct iwl_priv *priv); void iwl_tt_enter_ct_kill(struct iwl_priv *priv);
void iwl_tt_exit_ct_kill(struct iwl_priv *priv); void iwl_tt_exit_ct_kill(struct iwl_priv *priv);
void iwl_tt_handler(struct iwl_priv *priv); void iwl_tt_handler(struct iwl_priv *priv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment