aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlexander Bondar <alexander.bondar@intel.com>2013-05-06 06:03:59 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-05-27 07:30:10 -0400
commit071d4990fd9fe6fe27b47f1587ba11db3111c3fd (patch)
tree04142cd9b8d05e6911f23134859b789647949d2b /drivers
parent129219c0fd234164ebc19e8694641927317eda13 (diff)
iwlwifi: mvm: Add beacon abort enablement
Beacon abort is used by device to increase idle dwell time when system is idle. This algorithm is on top of beacon filtering feature. Enable beacon abort only if power management is enabled. Signed-off-by: Alexander Bondar <alexander.bondar@intel.com> Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h9
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c121
3 files changed, 86 insertions, 46 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index 05e51927b848..b6bdfd36bebe 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -193,4 +193,13 @@ struct iwl_beacon_filter_cmd {
193 193
194#define IWL_BA_ENABLE_BEACON_ABORT_DEFAULT 1 194#define IWL_BA_ENABLE_BEACON_ABORT_DEFAULT 1
195 195
196#define IWL_BF_CMD_CONFIG_DEFAULTS \
197 .bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT, \
198 .bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT, \
199 .bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT, \
200 .bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT, \
201 .bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT, \
202 .bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT), \
203 .ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT)
204
196#endif 205#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 712c39ae748f..02ba8303a09f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -173,6 +173,8 @@ struct iwl_mvm_vif {
173 bool uploaded; 173 bool uploaded;
174 bool ap_active; 174 bool ap_active;
175 bool monitor_active; 175 bool monitor_active;
176 /* indicate whether beacon filtering is enabled */
177 bool bf_enabled;
176 178
177 u32 ap_beacon_time; 179 u32 ap_beacon_time;
178 180
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index f5bdfb71c790..c818d6d6aee6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -75,6 +75,53 @@
75 75
76#define POWER_KEEP_ALIVE_PERIOD_SEC 25 76#define POWER_KEEP_ALIVE_PERIOD_SEC 25
77 77
78static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
79 struct iwl_beacon_filter_cmd *cmd)
80{
81 int ret;
82
83 ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, CMD_SYNC,
84 sizeof(struct iwl_beacon_filter_cmd), cmd);
85
86 if (!ret) {
87 IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n",
88 cmd->ba_enable_beacon_abort);
89 IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n",
90 cmd->ba_escape_timer);
91 IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n",
92 cmd->bf_debug_flag);
93 IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n",
94 cmd->bf_enable_beacon_filter);
95 IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n",
96 cmd->bf_energy_delta);
97 IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n",
98 cmd->bf_escape_timer);
99 IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n",
100 cmd->bf_roaming_energy_delta);
101 IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n",
102 cmd->bf_roaming_state);
103 IWL_DEBUG_POWER(mvm, "bf_temperature_delta is: %d\n",
104 cmd->bf_temperature_delta);
105 }
106 return ret;
107}
108
109static int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm,
110 struct ieee80211_vif *vif, bool enable)
111{
112 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
113 struct iwl_beacon_filter_cmd cmd = {
114 IWL_BF_CMD_CONFIG_DEFAULTS,
115 .bf_enable_beacon_filter = 1,
116 .ba_enable_beacon_abort = enable,
117 };
118
119 if (!mvmvif->bf_enabled)
120 return 0;
121
122 return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
123}
124
78static void iwl_mvm_power_log(struct iwl_mvm *mvm, 125static void iwl_mvm_power_log(struct iwl_mvm *mvm,
79 struct iwl_powertable_cmd *cmd) 126 struct iwl_powertable_cmd *cmd)
80{ 127{
@@ -162,6 +209,8 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
162 209
163int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 210int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
164{ 211{
212 int ret;
213 bool ba_enable;
165 struct iwl_powertable_cmd cmd = {}; 214 struct iwl_powertable_cmd cmd = {};
166 215
167 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 216 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
@@ -170,8 +219,15 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
170 iwl_mvm_power_build_cmd(mvm, vif, &cmd); 219 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
171 iwl_mvm_power_log(mvm, &cmd); 220 iwl_mvm_power_log(mvm, &cmd);
172 221
173 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, 222 ret = iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
174 sizeof(cmd), &cmd); 223 sizeof(cmd), &cmd);
224 if (ret)
225 return ret;
226
227 ba_enable = !!(cmd.flags &
228 cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));
229
230 return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable);
175} 231}
176 232
177int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 233int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
@@ -190,69 +246,42 @@ int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
190 sizeof(cmd), &cmd); 246 sizeof(cmd), &cmd);
191} 247}
192 248
193static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
194 struct iwl_beacon_filter_cmd *cmd)
195{
196 int ret;
197
198 ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, CMD_SYNC,
199 sizeof(struct iwl_beacon_filter_cmd), cmd);
200
201 if (!ret) {
202 IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n",
203 cmd->ba_enable_beacon_abort);
204 IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n",
205 cmd->ba_escape_timer);
206 IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n",
207 cmd->bf_debug_flag);
208 IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n",
209 cmd->bf_enable_beacon_filter);
210 IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n",
211 cmd->bf_energy_delta);
212 IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n",
213 cmd->bf_escape_timer);
214 IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n",
215 cmd->bf_roaming_energy_delta);
216 IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n",
217 cmd->bf_roaming_state);
218 IWL_DEBUG_POWER(mvm, "bf_temperature_delta is: %d\n",
219 cmd->bf_temperature_delta);
220 }
221 return ret;
222}
223
224int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, 249int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
225 struct ieee80211_vif *vif) 250 struct ieee80211_vif *vif)
226{ 251{
227 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 252 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
228 struct iwl_beacon_filter_cmd cmd = { 253 struct iwl_beacon_filter_cmd cmd = {
254 IWL_BF_CMD_CONFIG_DEFAULTS,
229 .bf_enable_beacon_filter = 1, 255 .bf_enable_beacon_filter = 1,
230 .bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT,
231 .bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT,
232 .bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT,
233 .bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT,
234 .bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT,
235 .bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT),
236 .ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT),
237 .ba_enable_beacon_abort = IWL_BA_ENABLE_BEACON_ABORT_DEFAULT,
238 }; 256 };
257 int ret;
239 258
240 if (mvmvif != mvm->bf_allowed_vif || 259 if (mvmvif != mvm->bf_allowed_vif ||
241 vif->type != NL80211_IFTYPE_STATION || vif->p2p) 260 vif->type != NL80211_IFTYPE_STATION || vif->p2p)
242 return 0; 261 return 0;
243 262
244 return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); 263 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
264
265 if (!ret)
266 mvmvif->bf_enabled = true;
267
268 return ret;
245} 269}
246 270
247int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, 271int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
248 struct ieee80211_vif *vif) 272 struct ieee80211_vif *vif)
249{ 273{
250 struct iwl_beacon_filter_cmd cmd = { 274 struct iwl_beacon_filter_cmd cmd = {};
251 .bf_enable_beacon_filter = 0, 275 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
252 }; 276 int ret;
253 277
254 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 278 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
255 return 0; 279 return 0;
256 280
257 return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd); 281 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
282
283 if (!ret)
284 mvmvif->bf_enabled = false;
285
286 return ret;
258} 287}