iwlwifi: mvm: Add beacon abort enablement
authorAlexander Bondar <alexander.bondar@intel.com>
Mon, 6 May 2013 10:03:59 +0000 (13:03 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 27 May 2013 11:30:10 +0000 (13:30 +0200)
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>
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/power.c

index 05e51927b8483dfe891f18225d73cb231b04d60e..b6bdfd36bebe92a03bfff84f12ccc04c9cccfa68 100644 (file)
@@ -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
index 712c39ae748fb3eb6d55ea2dd2a3761758da4603..02ba8303a09f5feff61278a0ade258000a2f4129 100644 (file)
@@ -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;
 
index f5bdfb71c7908228dec82fbe6b6dc397b41a6ab2..c818d6d6aee66cd5696b83f08d2bb7944789e98c 100644 (file)
 
 #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;
 }