static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif,
					       u32 flags, bool is_assoc)
{
	if (!is_assoc)
		return 0;
	if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
		return cpu_to_le32(ieee80211_tu_to_usec(SHORT_OUT_TIME_PERIOD));
	return cpu_to_le32(ieee80211_tu_to_usec(LONG_OUT_TIME_PERIOD));
}
Exemple #2
0
static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif)
{
	if (!vif->bss_conf.assoc)
		return 0;

	return cpu_to_le32(ieee80211_tu_to_usec(vif->bss_conf.beacon_int));
}
static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif,
					       bool is_assoc)
{
	if (!is_assoc)
		return 0;
	return cpu_to_le32(ieee80211_tu_to_usec(SUSPEND_TIME_PERIOD));
}
Exemple #4
0
static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
                                    struct ieee80211_vif *vif,
                                    struct iwl_mac_power_cmd *cmd)
{
    int dtimper, bi;
    int keep_alive;
    bool radar_detect = false;
    struct iwl_mvm_vif *mvmvif __maybe_unused =
        iwl_mvm_vif_from_mac80211(vif);

    cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
                                    mvmvif->color));
    dtimper = vif->bss_conf.dtim_period;
    bi = vif->bss_conf.beacon_int;

    /*
     * Regardless of power management state the driver must set
     * keep alive period. FW will use it for sending keep alive NDPs
     * immediately after association. Check that keep alive period
     * is at least 3 * DTIM
     */
    keep_alive = DIV_ROUND_UP(ieee80211_tu_to_usec(3 * dtimper * bi),
                              USEC_PER_SEC);
    keep_alive = max(keep_alive, POWER_KEEP_ALIVE_PERIOD_SEC);
    cmd->keep_alive_seconds = cpu_to_le16(keep_alive);

    if (mvm->ps_disabled)
        return;

    cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);

    if (!vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif) ||
            !mvmvif->pm_enabled || iwl_mvm_tdls_sta_count(mvm, vif))
        return;

    cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);

    if (vif->bss_conf.beacon_rate &&
            (vif->bss_conf.beacon_rate->bitrate == 10 ||
             vif->bss_conf.beacon_rate->bitrate == 60)) {
        cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
        cmd->lprx_rssi_threshold = POWER_LPRX_RSSI_THRESHOLD;
    }

    /* Check if radar detection is required on current channel */
    radar_detect = iwl_mvm_power_is_radar(vif);

    /* Check skip over DTIM conditions */
    if (!radar_detect && (dtimper < 10) &&
            (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP ||
             mvm->cur_ucode == IWL_UCODE_WOWLAN)) {
        cmd->skip_dtim_periods =
            iwl_mvm_power_get_skip_over_dtim(dtimper, bi);
        if (cmd->skip_dtim_periods)
            cmd->flags |=
                cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
    }

    if (mvm->cur_ucode != IWL_UCODE_WOWLAN) {
        cmd->rx_data_timeout =
            cpu_to_le32(IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT);
        cmd->tx_data_timeout =
            cpu_to_le32(IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT);
    } else {
        cmd->rx_data_timeout =
            cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT);
        cmd->tx_data_timeout =
            cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
    }

    if (iwl_mvm_power_allow_uapsd(mvm, vif))
        iwl_mvm_power_configure_uapsd(mvm, vif, cmd);

#ifdef CONFIG_IWLWIFI_DEBUGFS
    if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE)
        cmd->keep_alive_seconds =
            cpu_to_le16(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 = mvmvif->dbgfs_pm.skip_dtim_periods;
    if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_ENA) {
        if (mvmvif->dbgfs_pm.lprx_ena)
            cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
        else
            cmd->flags &= cpu_to_le16(~POWER_FLAGS_LPRX_ENA_MSK);
    }
    if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD)
        cmd->lprx_rssi_threshold = mvmvif->dbgfs_pm.lprx_rssi_threshold;
    if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SNOOZE_ENABLE) {
        if (mvmvif->dbgfs_pm.snooze_ena)
            cmd->flags |=
                cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK);
        else
            cmd->flags &=
                cpu_to_le16(~POWER_FLAGS_SNOOZE_ENA_MSK);
    }
    if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_UAPSD_MISBEHAVING) {
        u16 flag = POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK;
        if (mvmvif->dbgfs_pm.uapsd_misbehaving)
            cmd->flags |= cpu_to_le16(flag);
        else
            cmd->flags &= cpu_to_le16(flag);
    }
#endif /* CONFIG_IWLWIFI_DEBUGFS */
}
Exemple #5
0
static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
				     struct ieee80211_vif *vif,
				     int n_ssids,
				     struct iwl_mvm_scan_params *params)
{
	bool global_bound = false;
	enum ieee80211_band band;

	ieee80211_iterate_active_interfaces_atomic(mvm->hw,
					    IEEE80211_IFACE_ITER_NORMAL,
					    iwl_mvm_scan_condition_iterator,
					    &global_bound);
	/*
	 * Under low latency traffic passive scan is fragmented meaning
	 * that dwell on a particular channel will be fragmented. Each fragment
	 * dwell time is 20ms and fragments period is 105ms. Skipping to next
	 * channel will be delayed by the same period - 105ms. So suspend_time
	 * parameter describing both fragments and channels skipping periods is
	 * set to 105ms. This value is chosen so that overall passive scan
	 * duration will not be too long. Max_out_time in this case is set to
	 * 70ms, so for active scanning operating channel will be left for 70ms
	 * while for passive still for 20ms (fragment dwell).
	 */
	if (global_bound) {
		if (!iwl_mvm_low_latency(mvm)) {
			params->suspend_time = ieee80211_tu_to_usec(100);
			params->max_out_time = ieee80211_tu_to_usec(600);
		} else {
			params->suspend_time = ieee80211_tu_to_usec(105);
			/* P2P doesn't support fragmented passive scan, so
			 * configure max_out_time to be at least longest dwell
			 * time for passive scan.
			 */
			if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p) {
				params->max_out_time = ieee80211_tu_to_usec(70);
				params->passive_fragmented = true;
			} else {
				u32 passive_dwell;

				/*
				 * Use band G so that passive channel dwell time
				 * will be assigned with maximum value.
				 */
				band = IEEE80211_BAND_2GHZ;
				passive_dwell = iwl_mvm_get_passive_dwell(band);
				params->max_out_time =
					ieee80211_tu_to_usec(passive_dwell);
			}
		}
	}

	for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
		if (params->passive_fragmented)
			params->dwell[band].passive = 20;
		else
			params->dwell[band].passive =
				iwl_mvm_get_passive_dwell(band);
		params->dwell[band].active = iwl_mvm_get_active_dwell(band,
								      n_ssids);
	}
}