Commit 071d4990 authored by Alexander Bondar's avatar Alexander Bondar Committed by Johannes Berg
Browse files

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: default avatarAlexander Bondar <alexander.bondar@intel.com>
Reviewed-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 129219c0
......@@ -193,4 +193,13 @@ struct iwl_beacon_filter_cmd {
#define IWL_BA_ENABLE_BEACON_ABORT_DEFAULT 1
#define IWL_BF_CMD_CONFIG_DEFAULTS \
.bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT, \
.bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT, \
.bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT, \
.bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT, \
.bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT, \
.bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT), \
.ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT)
#endif
......@@ -173,6 +173,8 @@ struct iwl_mvm_vif {
bool uploaded;
bool ap_active;
bool monitor_active;
/* indicate whether beacon filtering is enabled */
bool bf_enabled;
u32 ap_beacon_time;
......
......@@ -75,6 +75,53 @@
#define POWER_KEEP_ALIVE_PERIOD_SEC 25
static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
struct iwl_beacon_filter_cmd *cmd)
{
int ret;
ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, CMD_SYNC,
sizeof(struct iwl_beacon_filter_cmd), cmd);
if (!ret) {
IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n",
cmd->ba_enable_beacon_abort);
IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n",
cmd->ba_escape_timer);
IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n",
cmd->bf_debug_flag);
IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n",
cmd->bf_enable_beacon_filter);
IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n",
cmd->bf_energy_delta);
IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n",
cmd->bf_escape_timer);
IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n",
cmd->bf_roaming_energy_delta);
IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n",
cmd->bf_roaming_state);
IWL_DEBUG_POWER(mvm, "bf_temperature_delta is: %d\n",
cmd->bf_temperature_delta);
}
return ret;
}
static int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm,
struct ieee80211_vif *vif, bool enable)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_beacon_filter_cmd cmd = {
IWL_BF_CMD_CONFIG_DEFAULTS,
.bf_enable_beacon_filter = 1,
.ba_enable_beacon_abort = enable,
};
if (!mvmvif->bf_enabled)
return 0;
return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
}
static void iwl_mvm_power_log(struct iwl_mvm *mvm,
struct iwl_powertable_cmd *cmd)
{
......@@ -162,6 +209,8 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
int ret;
bool ba_enable;
struct iwl_powertable_cmd cmd = {};
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)
iwl_mvm_power_build_cmd(mvm, vif, &cmd);
iwl_mvm_power_log(mvm, &cmd);
return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
sizeof(cmd), &cmd);
ret = iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
sizeof(cmd), &cmd);
if (ret)
return ret;
ba_enable = !!(cmd.flags &
cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));
return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable);
}
int 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)
sizeof(cmd), &cmd);
}
static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
struct iwl_beacon_filter_cmd *cmd)
{
int ret;
ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, CMD_SYNC,
sizeof(struct iwl_beacon_filter_cmd), cmd);
if (!ret) {
IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n",
cmd->ba_enable_beacon_abort);
IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n",
cmd->ba_escape_timer);
IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n",
cmd->bf_debug_flag);
IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n",
cmd->bf_enable_beacon_filter);
IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n",
cmd->bf_energy_delta);
IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n",
cmd->bf_escape_timer);
IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n",
cmd->bf_roaming_energy_delta);
IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n",
cmd->bf_roaming_state);
IWL_DEBUG_POWER(mvm, "bf_temperature_delta is: %d\n",
cmd->bf_temperature_delta);
}
return ret;
}
int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_beacon_filter_cmd cmd = {
IWL_BF_CMD_CONFIG_DEFAULTS,
.bf_enable_beacon_filter = 1,
.bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT,
.bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT,
.bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT,
.bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT,
.bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT,
.bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT),
.ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT),
.ba_enable_beacon_abort = IWL_BA_ENABLE_BEACON_ABORT_DEFAULT,
};
int ret;
if (mvmvif != mvm->bf_allowed_vif ||
vif->type != NL80211_IFTYPE_STATION || vif->p2p)
return 0;
return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
if (!ret)
mvmvif->bf_enabled = true;
return ret;
}
int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
struct iwl_beacon_filter_cmd cmd = {
.bf_enable_beacon_filter = 0,
};
struct iwl_beacon_filter_cmd cmd = {};
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int ret;
if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
return 0;
return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
if (!ret)
mvmvif->bf_enabled = false;
return ret;
}
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