iwlwifi: mvm: add debugfs for powersave
authorAlexander Bondar <alexander.bondar@intel.com>
Tue, 21 May 2013 11:49:09 +0000 (14:49 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 29 May 2013 07:03:24 +0000 (09:03 +0200)
Add debugfs files to control powersave parameters for testing.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/iwlwifi/mvm/debugfs.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/power.c

index 95871b2d63d15f976e4e1325af34797ba9f410ad..69e0806075a22cd739f8a6807d21009d9e89afdd 100644 (file)
@@ -300,6 +300,146 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file,
        return count;
 }
 
+static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
+                                struct ieee80211_vif *vif,
+                                enum iwl_dbgfs_pm_mask param, int val)
+{
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       struct iwl_dbgfs_pm *dbgfs_pm = &mvmvif->dbgfs_pm;
+
+       dbgfs_pm->mask |= param;
+
+       switch (param) {
+       case MVM_DEBUGFS_PM_KEEP_ALIVE: {
+               struct ieee80211_hw *hw = mvm->hw;
+               int dtimper = hw->conf.ps_dtim_period ?: 1;
+               int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
+
+               IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val);
+               if (val * MSEC_PER_SEC < 3 * dtimper_msec) {
+                       IWL_WARN(mvm,
+                                "debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n",
+                                val * MSEC_PER_SEC, 3 * dtimper_msec);
+               }
+               dbgfs_pm->keep_alive_seconds = val;
+               break;
+       }
+       case MVM_DEBUGFS_PM_SKIP_OVER_DTIM:
+               IWL_DEBUG_POWER(mvm, "skip_over_dtim %s\n",
+                               val ? "enabled" : "disabled");
+               dbgfs_pm->skip_over_dtim = val;
+               break;
+       case MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS:
+               IWL_DEBUG_POWER(mvm, "skip_dtim_periods=%d\n", val);
+               dbgfs_pm->skip_dtim_periods = val;
+               break;
+       case MVM_DEBUGFS_PM_RX_DATA_TIMEOUT:
+               IWL_DEBUG_POWER(mvm, "rx_data_timeout=%d\n", val);
+               dbgfs_pm->rx_data_timeout = val;
+               break;
+       case MVM_DEBUGFS_PM_TX_DATA_TIMEOUT:
+               IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val);
+               dbgfs_pm->tx_data_timeout = val;
+               break;
+       case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
+               IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
+               dbgfs_pm->disable_power_off = val;
+               break;
+       }
+}
+
+static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
+                                        const char __user *user_buf,
+                                        size_t count, loff_t *ppos)
+{
+       struct ieee80211_vif *vif = file->private_data;
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       struct iwl_mvm *mvm = mvmvif->dbgfs_data;
+       enum iwl_dbgfs_pm_mask param;
+       char buf[32] = {};
+       int val;
+       int ret;
+
+       if (copy_from_user(buf, user_buf, sizeof(buf)))
+               return -EFAULT;
+
+       if (!strncmp("keep_alive=", buf, 11)) {
+               if (sscanf(buf + 11, "%d", &val) != 1)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_PM_KEEP_ALIVE;
+       } else if (!strncmp("skip_over_dtim=", buf, 15)) {
+               if (sscanf(buf + 15, "%d", &val) != 1)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_PM_SKIP_OVER_DTIM;
+       } else if (!strncmp("skip_dtim_periods=", buf, 18)) {
+               if (sscanf(buf + 18, "%d", &val) != 1)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS;
+       } else if (!strncmp("rx_data_timeout=", buf, 16)) {
+               if (sscanf(buf + 16, "%d", &val) != 1)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_PM_RX_DATA_TIMEOUT;
+       } else if (!strncmp("tx_data_timeout=", buf, 16)) {
+               if (sscanf(buf + 16, "%d", &val) != 1)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
+       } else if (!strncmp("disable_power_off=", buf, 18)) {
+               if (sscanf(buf + 18, "%d", &val) != 1)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
+       } else {
+               return -EINVAL;
+       }
+
+       mutex_lock(&mvm->mutex);
+       iwl_dbgfs_update_pm(mvm, vif, param, val);
+       ret = iwl_mvm_power_update_mode(mvm, vif);
+       mutex_unlock(&mvm->mutex);
+
+       return ret ?: count;
+}
+
+static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
+                                       char __user *user_buf,
+                                       size_t count, loff_t *ppos)
+{
+       struct ieee80211_vif *vif = file->private_data;
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       struct iwl_mvm *mvm = mvmvif->dbgfs_data;
+       struct iwl_powertable_cmd cmd = {};
+       char buf[256];
+       int bufsz = sizeof(buf);
+       int pos = 0;
+
+       iwl_mvm_power_build_cmd(mvm, vif, &cmd);
+
+       pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n",
+                        (cmd.flags &
+                        cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ?
+                        0 : 1);
+       pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
+                        le32_to_cpu(cmd.skip_dtim_periods));
+       pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
+                        iwlmvm_mod_params.power_scheme);
+       pos += scnprintf(buf+pos, bufsz-pos, "flags = %d\n",
+                        le16_to_cpu(cmd.flags));
+       pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
+                        cmd.keep_alive_seconds);
+
+       if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
+               pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n",
+                                (cmd.flags &
+                                cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ?
+                                1 : 0);
+               pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n",
+                                le32_to_cpu(cmd.rx_data_timeout));
+               pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
+                                le32_to_cpu(cmd.tx_data_timeout));
+       }
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
 static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
                                         char __user *user_buf,
                                         size_t count, loff_t *ppos)
@@ -481,6 +621,191 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
        return count;
 }
 
+static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
+                               enum iwl_dbgfs_bf_mask param, int value)
+{
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
+
+       dbgfs_bf->mask |= param;
+
+       switch (param) {
+       case MVM_DEBUGFS_BF_ENERGY_DELTA:
+               dbgfs_bf->bf_energy_delta = value;
+               break;
+       case MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA:
+               dbgfs_bf->bf_roaming_energy_delta = value;
+               break;
+       case MVM_DEBUGFS_BF_ROAMING_STATE:
+               dbgfs_bf->bf_roaming_state = value;
+               break;
+       case MVM_DEBUGFS_BF_TEMPERATURE_DELTA:
+               dbgfs_bf->bf_temperature_delta = value;
+               break;
+       case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER:
+               dbgfs_bf->bf_enable_beacon_filter = value;
+               break;
+       case MVM_DEBUGFS_BF_DEBUG_FLAG:
+               dbgfs_bf->bf_debug_flag = value;
+               break;
+       case MVM_DEBUGFS_BF_ESCAPE_TIMER:
+               dbgfs_bf->bf_escape_timer = value;
+               break;
+       case MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT:
+               dbgfs_bf->ba_enable_beacon_abort = value;
+               break;
+       case MVM_DEBUGFS_BA_ESCAPE_TIMER:
+               dbgfs_bf->ba_escape_timer = value;
+               break;
+       }
+}
+
+static ssize_t iwl_dbgfs_bf_params_write(struct file *file,
+                                        const char __user *user_buf,
+                                        size_t count, loff_t *ppos)
+{
+       struct ieee80211_vif *vif = file->private_data;
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       struct iwl_mvm *mvm = mvmvif->dbgfs_data;
+       enum iwl_dbgfs_bf_mask param;
+       char buf[256];
+       int buf_size;
+       int value;
+       int ret = 0;
+
+       memset(buf, 0, sizeof(buf));
+       buf_size = min(count, sizeof(buf) - 1);
+       if (copy_from_user(buf, user_buf, buf_size))
+               return -EFAULT;
+
+       if (!strncmp("bf_energy_delta=", buf, 16)) {
+               if (sscanf(buf+16, "%d", &value) != 1)
+                       return -EINVAL;
+               if (value < IWL_BF_ENERGY_DELTA_MIN ||
+                   value > IWL_BF_ENERGY_DELTA_MAX)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_BF_ENERGY_DELTA;
+       } else if (!strncmp("bf_roaming_energy_delta=", buf, 24)) {
+               if (sscanf(buf+24, "%d", &value) != 1)
+                       return -EINVAL;
+               if (value < IWL_BF_ROAMING_ENERGY_DELTA_MIN ||
+                   value > IWL_BF_ROAMING_ENERGY_DELTA_MAX)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA;
+       } else if (!strncmp("bf_roaming_state=", buf, 17)) {
+               if (sscanf(buf+17, "%d", &value) != 1)
+                       return -EINVAL;
+               if (value < IWL_BF_ROAMING_STATE_MIN ||
+                   value > IWL_BF_ROAMING_STATE_MAX)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_BF_ROAMING_STATE;
+       } else if (!strncmp("bf_temperature_delta=", buf, 21)) {
+               if (sscanf(buf+21, "%d", &value) != 1)
+                       return -EINVAL;
+               if (value < IWL_BF_TEMPERATURE_DELTA_MIN ||
+                   value > IWL_BF_TEMPERATURE_DELTA_MAX)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_BF_TEMPERATURE_DELTA;
+       } else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) {
+               if (sscanf(buf+24, "%d", &value) != 1)
+                       return -EINVAL;
+               if (value < 0 || value > 1)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER;
+       } else if (!strncmp("bf_debug_flag=", buf, 14)) {
+               if (sscanf(buf+14, "%d", &value) != 1)
+                       return -EINVAL;
+               if (value < 0 || value > 1)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_BF_DEBUG_FLAG;
+       } else if (!strncmp("bf_escape_timer=", buf, 16)) {
+               if (sscanf(buf+16, "%d", &value) != 1)
+                       return -EINVAL;
+               if (value < IWL_BF_ESCAPE_TIMER_MIN ||
+                   value > IWL_BF_ESCAPE_TIMER_MAX)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_BF_ESCAPE_TIMER;
+       } else if (!strncmp("ba_escape_timer=", buf, 16)) {
+               if (sscanf(buf+16, "%d", &value) != 1)
+                       return -EINVAL;
+               if (value < IWL_BA_ESCAPE_TIMER_MIN ||
+                   value > IWL_BA_ESCAPE_TIMER_MAX)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_BA_ESCAPE_TIMER;
+       } else if (!strncmp("ba_enable_beacon_abort=", buf, 23)) {
+               if (sscanf(buf+23, "%d", &value) != 1)
+                       return -EINVAL;
+               if (value < 0 || value > 1)
+                       return -EINVAL;
+               param = MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT;
+       } else {
+               return -EINVAL;
+       }
+
+       mutex_lock(&mvm->mutex);
+       iwl_dbgfs_update_bf(vif, param, value);
+       if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value) {
+               ret = iwl_mvm_disable_beacon_filter(mvm, vif);
+       } else {
+               if (mvmvif->bf_enabled)
+                       ret = iwl_mvm_enable_beacon_filter(mvm, vif);
+               else
+                       ret = iwl_mvm_disable_beacon_filter(mvm, vif);
+       }
+       mutex_unlock(&mvm->mutex);
+
+       return ret ?: count;
+}
+
+static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
+                                       char __user *user_buf,
+                                       size_t count, loff_t *ppos)
+{
+       struct ieee80211_vif *vif = file->private_data;
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       char buf[256];
+       int pos = 0;
+       const size_t bufsz = sizeof(buf);
+       struct iwl_beacon_filter_cmd cmd = {
+               .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_enable_beacon_filter = IWL_BF_ENABLE_BEACON_FILTER_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,
+       };
+
+       iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
+       if (mvmvif->bf_enabled)
+               cmd.bf_enable_beacon_filter = 1;
+       else
+               cmd.bf_enable_beacon_filter = 0;
+
+       pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n",
+                        cmd.bf_energy_delta);
+       pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n",
+                        cmd.bf_roaming_energy_delta);
+       pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n",
+                        cmd.bf_roaming_state);
+       pos += scnprintf(buf+pos, bufsz-pos, "bf_temperature_delta = %d\n",
+                        cmd.bf_temperature_delta);
+       pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n",
+                        cmd.bf_enable_beacon_filter);
+       pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n",
+                        cmd.bf_debug_flag);
+       pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n",
+                        cmd.bf_escape_timer);
+       pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n",
+                        cmd.ba_escape_timer);
+       pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n",
+                        cmd.ba_enable_beacon_abort);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
 #ifdef CONFIG_PM_SLEEP
 static ssize_t iwl_dbgfs_d3_sram_write(struct file *file,
                                       const char __user *user_buf,
@@ -594,6 +919,8 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram);
 
 /* Interface specific debugfs entries */
 MVM_DEBUGFS_READ_FILE_OPS(mac_params);
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params);
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params);
 
 int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
 {
@@ -647,9 +974,19 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
                return;
        }
 
+       if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
+           vif->type == NL80211_IFTYPE_STATION && !vif->p2p)
+               MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR |
+                                        S_IRUSR);
+
        MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
                                 S_IRUSR);
 
+       if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
+           mvmvif == mvm->bf_allowed_vif)
+               MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir,
+                                        S_IRUSR | S_IWUSR);
+
        /*
         * Create symlink for convenience pointing to interface specific
         * debugfs entries for the driver. For example, under
index 0e7450372f2c1aa65805247e3439ea9618062929..6a3220b6273ed052c3a22e9186a6c52525a5a123 100644 (file)
@@ -150,6 +150,54 @@ enum iwl_power_scheme {
 
 #define IWL_CONN_MAX_LISTEN_INTERVAL   70
 
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+enum iwl_dbgfs_pm_mask {
+       MVM_DEBUGFS_PM_KEEP_ALIVE = BIT(0),
+       MVM_DEBUGFS_PM_SKIP_OVER_DTIM = BIT(1),
+       MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS = BIT(2),
+       MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3),
+       MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4),
+       MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5),
+};
+
+struct iwl_dbgfs_pm {
+       u8 keep_alive_seconds;
+       u32 rx_data_timeout;
+       u32 tx_data_timeout;
+       bool skip_over_dtim;
+       u8 skip_dtim_periods;
+       bool disable_power_off;
+       int mask;
+};
+
+/* beacon filtering */
+
+enum iwl_dbgfs_bf_mask {
+       MVM_DEBUGFS_BF_ENERGY_DELTA = BIT(0),
+       MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA = BIT(1),
+       MVM_DEBUGFS_BF_ROAMING_STATE = BIT(2),
+       MVM_DEBUGFS_BF_TEMPERATURE_DELTA = BIT(3),
+       MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER = BIT(4),
+       MVM_DEBUGFS_BF_DEBUG_FLAG = BIT(5),
+       MVM_DEBUGFS_BF_ESCAPE_TIMER = BIT(6),
+       MVM_DEBUGFS_BA_ESCAPE_TIMER = BIT(7),
+       MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT = BIT(8),
+};
+
+struct iwl_dbgfs_bf {
+       u8 bf_energy_delta;
+       u8 bf_roaming_energy_delta;
+       u8 bf_roaming_state;
+       u8 bf_temperature_delta;
+       u8 bf_enable_beacon_filter;
+       u8 bf_debug_flag;
+       u32 bf_escape_timer;
+       u32 ba_escape_timer;
+       u8 ba_enable_beacon_abort;
+       int mask;
+};
+#endif
+
 enum iwl_mvm_smps_type_request {
        IWL_MVM_SMPS_REQ_BT_COEX,
        IWL_MVM_SMPS_REQ_TT,
@@ -225,6 +273,8 @@ struct iwl_mvm_vif {
        struct dentry *dbgfs_dir;
        struct dentry *dbgfs_slink;
        void *dbgfs_data;
+       struct iwl_dbgfs_pm dbgfs_pm;
+       struct iwl_dbgfs_bf dbgfs_bf;
 #endif
 
        enum ieee80211_smps_mode smps_requests[NUM_IWL_MVM_SMPS_REQ];
@@ -631,6 +681,21 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
 
 /* beacon filtering */
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+void
+iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
+                                        struct iwl_beacon_filter_cmd *cmd);
+int iwl_mvm_dbgfs_set_fw_dbg_log(struct iwl_mvm *mvm);
+#else
+static inline void
+iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
+                                        struct iwl_beacon_filter_cmd *cmd)
+{}
+static inline int iwl_mvm_dbgfs_set_fw_dbg_log(struct iwl_mvm *mvm)
+{
+       return 0;
+}
+#endif
 int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
                                 struct ieee80211_vif *vif);
 int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
index 516e64e7706f69678475ce1281ffff6709996add..67cf24aa72f9b855b2e306d7fbd42596620d0b63 100644 (file)
@@ -119,6 +119,7 @@ static int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm,
        if (!mvmvif->bf_enabled)
                return 0;
 
+       iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
        return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
 }
 
@@ -153,6 +154,8 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
        int dtimper, dtimper_msec;
        int keep_alive;
        bool radar_detect = false;
+       struct iwl_mvm_vif *mvmvif __maybe_unused =
+               iwl_mvm_vif_from_mac80211(vif);
 
        /*
         * Regardless of power management state the driver must set
@@ -166,6 +169,11 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 
        cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
 
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+       if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
+           mvmvif->dbgfs_pm.disable_power_off)
+               cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
+#endif
        if (!vif->bss_conf.ps)
                return;
 
@@ -205,6 +213,28 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
                cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
        }
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+       if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE)
+               cmd->keep_alive_seconds = mvmvif->dbgfs_pm.keep_alive_seconds;
+       if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_OVER_DTIM) {
+               if (mvmvif->dbgfs_pm.skip_over_dtim)
+                       cmd->flags |=
+                               cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
+               else
+                       cmd->flags &=
+                               cpu_to_le16(~POWER_FLAGS_SKIP_OVER_DTIM_MSK);
+       }
+       if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_RX_DATA_TIMEOUT)
+               cmd->rx_data_timeout =
+                       cpu_to_le32(mvmvif->dbgfs_pm.rx_data_timeout);
+       if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_TX_DATA_TIMEOUT)
+               cmd->tx_data_timeout =
+                       cpu_to_le32(mvmvif->dbgfs_pm.tx_data_timeout);
+       if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS)
+               cmd->skip_dtim_periods =
+                       cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods);
+#endif /* CONFIG_IWLWIFI_DEBUGFS */
 }
 
 int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
@@ -233,6 +263,8 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 {
        struct iwl_powertable_cmd cmd = {};
+       struct iwl_mvm_vif *mvmvif __maybe_unused =
+               iwl_mvm_vif_from_mac80211(vif);
 
        if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
                return 0;
@@ -240,12 +272,45 @@ int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
        if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
                cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
 
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+       if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
+           mvmvif->dbgfs_pm.disable_power_off)
+               cmd.flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
+#endif
        iwl_mvm_power_log(mvm, &cmd);
 
        return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC,
                                    sizeof(cmd), &cmd);
 }
 
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+void
+iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
+                                        struct iwl_beacon_filter_cmd *cmd)
+{
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
+
+       if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ENERGY_DELTA)
+               cmd->bf_energy_delta = dbgfs_bf->bf_energy_delta;
+       if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA)
+               cmd->bf_roaming_energy_delta =
+                                dbgfs_bf->bf_roaming_energy_delta;
+       if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_STATE)
+               cmd->bf_roaming_state = dbgfs_bf->bf_roaming_state;
+       if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMPERATURE_DELTA)
+               cmd->bf_temperature_delta = dbgfs_bf->bf_temperature_delta;
+       if (dbgfs_bf->mask & MVM_DEBUGFS_BF_DEBUG_FLAG)
+               cmd->bf_debug_flag = dbgfs_bf->bf_debug_flag;
+       if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ESCAPE_TIMER)
+               cmd->bf_escape_timer = cpu_to_le32(dbgfs_bf->bf_escape_timer);
+       if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ESCAPE_TIMER)
+               cmd->ba_escape_timer = cpu_to_le32(dbgfs_bf->ba_escape_timer);
+       if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT)
+               cmd->ba_enable_beacon_abort = dbgfs_bf->ba_enable_beacon_abort;
+}
+#endif
+
 int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
                                 struct ieee80211_vif *vif)
 {
@@ -260,6 +325,7 @@ int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
            vif->type != NL80211_IFTYPE_STATION || vif->p2p)
                return 0;
 
+       iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
        ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
 
        if (!ret)