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: 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>
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 40207dac..52a4810 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -177,7 +177,7 @@
 				   struct sk_buff *skb,
 				   struct ieee80211_sta *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);
 
 
@@ -1398,6 +1398,12 @@
 	int ret = 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 (; ;) {
 		lq_sta->action_counter++;
 		switch (tbl->action) {
@@ -1529,6 +1535,11 @@
 	u8 update_search_tbl_counter = 0;
 	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 (;;) {
 		lq_sta->action_counter++;
 		switch (tbl->action) {
@@ -1663,6 +1674,12 @@
 	u8 update_search_tbl_counter = 0;
 	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 (;;) {
 		lq_sta->action_counter++;
 		switch (tbl->action) {
@@ -1799,6 +1816,12 @@
 	int ret;
 	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 (;;) {
 		lq_sta->action_counter++;
 		switch (tbl->action) {
@@ -2178,8 +2201,8 @@
 			tbl->expected_tpt[index] + 64) / 128));
 
 	/* 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;
 		 * no need to send new link quality command, since we're
 		 * continuing to use the setup that we've been trying. */
@@ -2307,7 +2330,11 @@
 		    ((sr > IWL_RATE_HIGH_TH) ||
 		     (current_tpt > (100 * tbl->expected_tpt[low]))))
 		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) {
 	case -1:
 		/* Decrease starting rate, update uCode's rate table */
@@ -2341,9 +2368,11 @@
 		rate = rs_update_rate_tbl(priv, lq_sta,
 					  tbl, index, is_green);
 
-	/* Should we stay with this modulation mode, or search for a new one? */
-	rs_stay_in_table(lq_sta);
-
+	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);
+	}
 	/*
 	 * Search for new modulation mode if we're:
 	 * 1)  Not changing rates right now
@@ -2400,7 +2429,8 @@
 		 * have been tried and compared, stay in this best modulation
 		 * mode for a while before next round of mode comparisons. */
 		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) &&
 			    (lq_sta->tx_agg_tid_en & (1 << tid)) &&
 			    (tid != MAX_TID_COUNT)) {
@@ -2686,7 +2716,7 @@
 	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_scale_tbl_info tbl_type;