Esempio n. 1
0
static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm,
				     struct ieee80211_vif *vif)
{
	struct iwl_mac_power_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;

	cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
							   mvmvif->color));

	if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
		cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);

#ifdef CPTCFG_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, MAC_PM_POWER_TABLE, CMD_ASYNC,
				    sizeof(cmd), &cmd);
}
Esempio n. 2
0
static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm,
					 struct ieee80211_vif *vif)
{
	int ret;
	bool ba_enable;
	struct iwl_mac_power_cmd cmd = {};

	if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
		return 0;

	/*
	 * TODO: The following vif_count verification is temporary condition.
	 * Avoid power mode update if more than one interface is currently
	 * active. Remove this condition when FW will support power management
	 * on multiple MACs.
	 */
	IWL_DEBUG_POWER(mvm, "Currently %d interfaces active\n",
			mvm->vif_count);
	if (mvm->vif_count > 1)
		return 0;

	iwl_mvm_power_build_cmd(mvm, vif, &cmd);
	iwl_mvm_power_log(mvm, &cmd);

	ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, 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);
}
static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm,
					 struct ieee80211_vif *vif)
{
	int ret;
	bool ba_enable;
	struct iwl_mac_power_cmd cmd = {};

	if (vif->type != NL80211_IFTYPE_STATION)
		return 0;

	if (vif->p2p &&
	    !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS))
		return 0;

	iwl_mvm_power_build_cmd(mvm, vif, &cmd);
	iwl_mvm_power_log(mvm, &cmd);

	ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, 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);
}
Esempio n. 4
0
int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
                                   struct ieee80211_vif *vif,
                                   bool enable, u32 flags)
{
    int ret;
    struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
    struct iwl_mac_power_cmd cmd = {};

    if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
        return 0;

    if (!vif->bss_conf.assoc)
        return 0;

    iwl_mvm_power_build_cmd(mvm, vif, &cmd);
    if (enable) {
        /* configure skip over dtim up to 306TU - 314 msec */
        int dtimper = vif->bss_conf.dtim_period ?: 1;
        int dtimper_tu = dtimper * vif->bss_conf.beacon_int;
        bool radar_detect = iwl_mvm_power_is_radar(vif);

        if (WARN_ON(!dtimper_tu))
            return 0;

        /* Check skip over DTIM conditions */
        /* TODO: check that multicast wake lock is off */
        if (!radar_detect && (dtimper < 10)) {
            cmd.skip_dtim_periods = 306 / dtimper_tu;
            if (cmd.skip_dtim_periods)
                cmd.flags |= cpu_to_le16(
                                 POWER_FLAGS_SKIP_OVER_DTIM_MSK);
        }
    }
    iwl_mvm_power_log(mvm, &cmd);
#ifdef CONFIG_IWLWIFI_DEBUGFS
    memcpy(&mvmvif->mac_pwr_cmd, &cmd, sizeof(cmd));
#endif
    ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, flags,
                               sizeof(cmd), &cmd);
    if (ret)
        return ret;

    /* configure beacon filtering */
    if (mvmvif != mvm->bf_allowed_vif)
        return 0;

    if (enable) {
        struct iwl_beacon_filter_cmd cmd_bf = {
            IWL_BF_CMD_CONFIG_D0I3,
            .bf_enable_beacon_filter = cpu_to_le32(1),
        };
        ret = _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd_bf,
                                            flags, true);
    } else {
        if (mvmvif->bf_data.bf_enabled)
Esempio n. 5
0
static int iwl_mvm_power_send_cmd(struct iwl_mvm *mvm,
                                  struct ieee80211_vif *vif)
{
    struct iwl_mac_power_cmd cmd = {};

    iwl_mvm_power_build_cmd(mvm, vif, &cmd);
    iwl_mvm_power_log(mvm, &cmd);
#ifdef CONFIG_IWLWIFI_DEBUGFS
    memcpy(&iwl_mvm_vif_from_mac80211(vif)->mac_pwr_cmd, &cmd, sizeof(cmd));
#endif

    return iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, 0,
                                sizeof(cmd), &cmd);
}
Esempio n. 6
0
int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
				   struct ieee80211_vif *vif,
				   bool enable, u32 flags)
{
	int ret;
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mac_power_cmd cmd = {};

	if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
		return 0;

	if (!vif->bss_conf.assoc)
		return 0;

	iwl_mvm_power_build_cmd(mvm, vif, &cmd);
	if (enable) {
		/* configure skip over dtim up to 300 msec */
		int dtimper = mvm->hw->conf.ps_dtim_period ?: 1;
		int dtimper_msec = dtimper * vif->bss_conf.beacon_int;

		if (WARN_ON(!dtimper_msec))
			return 0;

		cmd.skip_dtim_periods = 300 / dtimper_msec;
		if (cmd.skip_dtim_periods)
			cmd.flags |=
				cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
	}
	iwl_mvm_power_log(mvm, &cmd);
#ifdef CONFIG_IWLWIFI_DEBUGFS
	memcpy(&mvmvif->mac_pwr_cmd, &cmd, sizeof(cmd));
#endif
	ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, flags,
				   sizeof(cmd), &cmd);
	if (ret)
		return ret;

	/* configure beacon filtering */
	if (mvmvif != mvm->bf_allowed_vif)
		return 0;

	if (enable) {
		struct iwl_beacon_filter_cmd cmd_bf = {
			IWL_BF_CMD_CONFIG_D0I3,
			.bf_enable_beacon_filter = cpu_to_le32(1),
		};
		ret = _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd_bf,
						    flags, true);
	} else {
		if (mvmvif->bf_data.bf_enabled)