iwlwifi: support idle for 6000 series hw
authorJohannes Berg <johannes@sipsolutions.net>
Fri, 25 Sep 2009 21:24:27 +0000 (14:24 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 7 Oct 2009 20:39:36 +0000 (16:39 -0400)
Using powersave while idle saves a lot of power, but
we've had problems with this on some cards (5150 has
been reported to be problematic). However, on the new
6000 series we're seeing no problems, so for now let
that hardware benefit from idle mode, we can look at
the problems with other hardware one by one and then
enable those once we figure out the problems.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-power.c

index ad5d77c9649410e826aa0465287fb9875def7915..6f4ee27e07c969532e480c1ad017a41d96407b29 100644 (file)
@@ -254,6 +254,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .supports_idle = true,
 };
 
 struct iwl_cfg iwl6000h_2abg_cfg = {
@@ -276,6 +277,7 @@ struct iwl_cfg iwl6000h_2abg_cfg = {
        .ht_greenfield_support = true,
        .led_compensation = 51,
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .supports_idle = true,
 };
 
 struct iwl_cfg iwl6000h_2bg_cfg = {
@@ -298,6 +300,7 @@ struct iwl_cfg iwl6000h_2bg_cfg = {
        .ht_greenfield_support = true,
        .led_compensation = 51,
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .supports_idle = true,
 };
 
 /*
@@ -324,6 +327,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .supports_idle = true,
 };
 
 struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -346,6 +350,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
        .ht_greenfield_support = true,
        .led_compensation = 51,
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .supports_idle = true,
 };
 
 struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -368,6 +373,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
        .ht_greenfield_support = true,
        .led_compensation = 51,
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .supports_idle = true,
 };
 
 struct iwl_cfg iwl6050_2agn_cfg = {
@@ -391,6 +397,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .supports_idle = true,
 };
 
 struct iwl_cfg iwl6050_2abg_cfg = {
@@ -413,6 +420,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
        .ht_greenfield_support = true,
        .led_compensation = 51,
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .supports_idle = true,
 };
 
 struct iwl_cfg iwl6000_3agn_cfg = {
@@ -436,6 +444,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .supports_idle = true,
 };
 
 struct iwl_cfg iwl6050_3agn_cfg = {
@@ -459,6 +468,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .supports_idle = true,
 };
 
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
index e97b104ba1d5221765166ff8936b8b0597aa2e87..1cf2e04fe3f9d42a6caade87f2cc71f13a4388a6 100644 (file)
@@ -2650,7 +2650,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
                iwl_set_rate(priv);
        }
 
-       if (changed & IEEE80211_CONF_CHANGE_PS) {
+       if (changed & (IEEE80211_CONF_CHANGE_PS |
+                       IEEE80211_CONF_CHANGE_IDLE)) {
                ret = iwl_power_update_mode(priv, false);
                if (ret)
                        IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
index b66bf7b4b0a448c189fbe747e96480879d47d897..744f0cac685916e03552ac8d47f99fab391ac847 100644 (file)
@@ -265,6 +265,7 @@ struct iwl_cfg {
        const bool broken_powersave;
        bool use_rts_for_ht;
        int chain_noise_num_beacons;
+       const bool supports_idle;
 };
 
 /***************************
index 60be976afff8e49dd918d303f45e5fe6e9853759..e50d77bd7aadbcdfbcd933026c54703aa50809e2 100644 (file)
@@ -294,6 +294,9 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
 
        if (priv->cfg->broken_powersave)
                iwl_power_sleep_cam_cmd(priv, &cmd);
+       else if (priv->cfg->supports_idle &&
+                priv->hw->conf.flags & IEEE80211_CONF_IDLE)
+               iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20);
        else if (tt->state >= IWL_TI_1)
                iwl_static_sleep_cmd(priv, &cmd, tt->tt_power_mode, dtimper);
        else if (!enabled)