diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-power.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-power.c | 68 |
1 files changed, 63 insertions, 5 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 21c5e6abfbd0..1eec18d909d8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -75,6 +75,10 @@ struct iwl_power_vec_entry { | |||
75 | 75 | ||
76 | #define NOSLP cpu_to_le16(0), 0, 0 | 76 | #define NOSLP cpu_to_le16(0), 0, 0 |
77 | #define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0 | 77 | #define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0 |
78 | #define ASLP (IWL_POWER_POWER_SAVE_ENA_MSK | \ | ||
79 | IWL_POWER_POWER_MANAGEMENT_ENA_MSK | \ | ||
80 | IWL_POWER_ADVANCE_PM_ENA_MSK) | ||
81 | #define ASLP_TOUT(T) cpu_to_le32(T) | ||
78 | #define TU_TO_USEC 1024 | 82 | #define TU_TO_USEC 1024 |
79 | #define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC) | 83 | #define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC) |
80 | #define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \ | 84 | #define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \ |
@@ -114,6 +118,52 @@ static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = { | |||
114 | {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} | 118 | {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} |
115 | }; | 119 | }; |
116 | 120 | ||
121 | /* advance power management */ | ||
122 | /* DTIM 0 - 2 */ | ||
123 | static const struct iwl_power_vec_entry apm_range_0[IWL_POWER_NUM] = { | ||
124 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
125 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
126 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
127 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
128 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
129 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
130 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
131 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
132 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
133 | SLP_VEC(1, 2, 6, 8, 0xFF), ASLP_TOUT(2)}, 2} | ||
134 | }; | ||
135 | |||
136 | |||
137 | /* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */ | ||
138 | /* DTIM 3 - 10 */ | ||
139 | static const struct iwl_power_vec_entry apm_range_1[IWL_POWER_NUM] = { | ||
140 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
141 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
142 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
143 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
144 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
145 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
146 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
147 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
148 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
149 | SLP_VEC(1, 2, 6, 8, 0xFF), 0}, 2} | ||
150 | }; | ||
151 | |||
152 | /* for DTIM period > IWL_DTIM_RANGE_1_MAX */ | ||
153 | /* DTIM 11 - */ | ||
154 | static const struct iwl_power_vec_entry apm_range_2[IWL_POWER_NUM] = { | ||
155 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
156 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
157 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
158 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
159 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
160 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
161 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
162 | SLP_VEC(1, 2, 4, 6, 0xFF), 0}, 0}, | ||
163 | {{ASLP, 0, 0, ASLP_TOUT(50), ASLP_TOUT(50), | ||
164 | SLP_VEC(1, 2, 6, 8, 0xFF), ASLP_TOUT(2)}, 2} | ||
165 | }; | ||
166 | |||
117 | static void iwl_static_sleep_cmd(struct iwl_priv *priv, | 167 | static void iwl_static_sleep_cmd(struct iwl_priv *priv, |
118 | struct iwl_powertable_cmd *cmd, | 168 | struct iwl_powertable_cmd *cmd, |
119 | enum iwl_power_level lvl, int period) | 169 | enum iwl_power_level lvl, int period) |
@@ -124,11 +174,19 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, | |||
124 | u8 skip; | 174 | u8 skip; |
125 | u32 slp_itrvl; | 175 | u32 slp_itrvl; |
126 | 176 | ||
127 | table = range_2; | 177 | if (priv->cfg->adv_pm) { |
128 | if (period <= IWL_DTIM_RANGE_1_MAX) | 178 | table = apm_range_2; |
129 | table = range_1; | 179 | if (period <= IWL_DTIM_RANGE_1_MAX) |
130 | if (period <= IWL_DTIM_RANGE_0_MAX) | 180 | table = apm_range_1; |
131 | table = range_0; | 181 | if (period <= IWL_DTIM_RANGE_0_MAX) |
182 | table = apm_range_0; | ||
183 | } else { | ||
184 | table = range_2; | ||
185 | if (period <= IWL_DTIM_RANGE_1_MAX) | ||
186 | table = range_1; | ||
187 | if (period <= IWL_DTIM_RANGE_0_MAX) | ||
188 | table = range_0; | ||
189 | } | ||
132 | 190 | ||
133 | BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM); | 191 | BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM); |
134 | 192 | ||