IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n",
le32_to_cpu(cmd->ba_enable_beacon_abort));
IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n",
le32_to_cpu(cmd->ba_escape_timer));
IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n",
le32_to_cpu(cmd->bf_debug_flag));
IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n",
le32_to_cpu(cmd->bf_enable_beacon_filter));
IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n",
le32_to_cpu(cmd->bf_energy_delta));
IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n",
le32_to_cpu(cmd->bf_escape_timer));
IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n",
le32_to_cpu(cmd->bf_roaming_energy_delta));
IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n",
le32_to_cpu(cmd->bf_roaming_state));
IWL_DEBUG_POWER(mvm, "bf_temp_threshold is: %d\n",
le32_to_cpu(cmd->bf_temp_threshold));
IWL_DEBUG_POWER(mvm, "bf_temp_fast_filter is: %d\n",
le32_to_cpu(cmd->bf_temp_fast_filter));
IWL_DEBUG_POWER(mvm, "bf_temp_slow_filter is: %d\n",
le32_to_cpu(cmd->bf_temp_slow_filter));
IWL_DEBUG_POWER(mvm, "bf_threshold_absolute_low is: %d, %d\n",
le32_to_cpu(cmd->bf_threshold_absolute_low[0]),
le32_to_cpu(cmd->bf_threshold_absolute_low[1]));
IWL_DEBUG_POWER(mvm, "bf_threshold_absolute_high is: %d, %d\n",
le32_to_cpu(cmd->bf_threshold_absolute_high[0]),
le32_to_cpu(cmd->bf_threshold_absolute_high[1]));
if (fw_has_api(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_API_BEACON_FILTER_V4))
len = sizeof(struct iwl_beacon_filter_cmd); else
len = offsetof(struct iwl_beacon_filter_cmd,
bf_threshold_absolute_low);
if (vif->bss_conf.cqm_rssi_thold) {
cmd->bf_energy_delta =
cpu_to_le32(vif->bss_conf.cqm_rssi_hyst); /* fw uses an absolute value for this */
cmd->bf_roaming_state =
cpu_to_le32(-vif->bss_conf.cqm_rssi_thold);
}
cmd->ba_enable_beacon_abort = cpu_to_le32(mvmvif->ba_enabled);
}
staticvoid iwl_mvm_power_log(struct iwl_mvm *mvm, struct iwl_mac_power_cmd *cmd)
{
IWL_DEBUG_POWER(mvm, "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n",
cmd->id_and_color, iwlmvm_mod_params.power_scheme,
le16_to_cpu(cmd->flags));
IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n",
le16_to_cpu(cmd->keep_alive_seconds));
if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK))) {
IWL_DEBUG_POWER(mvm, "Disable power management\n"); return;
}
#ifdef CONFIG_IWLWIFI_DEBUGFS /* set advanced pm flag with no uapsd ACs to enable ps-poll */ if (mvmvif->dbgfs_pm.use_ps_poll) {
cmd->flags |= cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK); return;
} #endif
for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_BK; ac++) { if (!mvmvif->deflink.queue_params[ac].uapsd) continue;
if (!test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status))
cmd->flags |=
cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK);
cmd->uapsd_ac_flags |= BIT(ac);
/* QNDP TID - the highest TID with no admission control */ if (!tid_found && !mvmvif->deflink.queue_params[ac].acm) {
tid_found = true; switch (ac) { case IEEE80211_AC_VO:
cmd->qndp_tid = 6; break; case IEEE80211_AC_VI:
cmd->qndp_tid = 5; break; case IEEE80211_AC_BE:
cmd->qndp_tid = 0; break; case IEEE80211_AC_BK:
cmd->qndp_tid = 1; break;
}
}
}
/* exclude the given vif */ if (vif == data->current_vif) return;
switch (vif->type) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_ADHOC:
data->allow_uapsd = false; break; case NL80211_IFTYPE_STATION: /* allow UAPSD if P2P interface and BSS station interface share * the same channel.
*/ if (vif->cfg.assoc && other_mvmvif->deflink.phy_ctxt &&
curr_mvmvif->deflink.phy_ctxt &&
other_mvmvif->deflink.phy_ctxt->id != curr_mvmvif->deflink.phy_ctxt->id)
data->allow_uapsd = false; break;
if (ether_addr_equal(mvmvif->uapsd_misbehaving_ap_addr,
vif->cfg.ap_addr)) returnfalse;
/* * Avoid using uAPSD if P2P client is associated to GO that uses * opportunistic power save. This is due to current FW limitation.
*/ if (vif->p2p &&
(vif->bss_conf.p2p_noa_attr.oppps_ctwindow &
IEEE80211_P2P_OPPPS_ENABLE_BIT)) returnfalse;
if (vif->p2p && !iwl_mvm_is_p2p_scm_uapsd_supported(mvm)) returnfalse;
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);
/* The ap_sta_id is not expected to change during current * association so no explicit protection is needed
*/ if (link_info->ap_sta_id == *ap_sta_id) {
ether_addr_copy(mvmvif->uapsd_misbehaving_ap_addr,
vif->cfg.ap_addr); break;
}
}
rcu_read_unlock();
}
switch (ieee80211_vif_type_p2p(vif)) { case NL80211_IFTYPE_P2P_DEVICE: break;
case NL80211_IFTYPE_P2P_GO: case NL80211_IFTYPE_AP: /* only a single MAC of the same type */
WARN_ON(power_iterator->ap_vif);
power_iterator->ap_vif = vif; if (active)
power_iterator->ap_active = true; break;
case NL80211_IFTYPE_MONITOR: /* only a single MAC of the same type */
WARN_ON(power_iterator->monitor_vif);
power_iterator->monitor_vif = vif; if (active)
power_iterator->monitor_active = true; break;
case NL80211_IFTYPE_P2P_CLIENT: /* only a single MAC of the same type */
WARN_ON(power_iterator->p2p_vif);
power_iterator->p2p_vif = vif; if (active)
power_iterator->p2p_active = true; break;
case NL80211_IFTYPE_STATION:
power_iterator->bss_vif = vif; if (active)
power_iterator->bss_active = true; break;
/* set pm_enable to false */
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_power_disable_pm_iterator,
NULL);
if (vifs->bss_vif)
bss_mvmvif = iwl_mvm_vif_from_mac80211(vifs->bss_vif);
if (vifs->p2p_vif)
p2p_mvmvif = iwl_mvm_vif_from_mac80211(vifs->p2p_vif);
if (vifs->ap_vif)
ap_mvmvif = iwl_mvm_vif_from_mac80211(vifs->ap_vif);
/* don't allow PM if any TDLS stations exist */ if (iwl_mvm_tdls_sta_count(mvm, NULL)) return;
/* enable PM on bss if bss stand alone */ if (bss_mvmvif && vifs->bss_active && !vifs->p2p_active &&
!vifs->ap_active) {
bss_mvmvif->pm_enabled = true; return;
}
/* enable PM on p2p if p2p stand alone */ if (p2p_mvmvif && vifs->p2p_active && !vifs->bss_active &&
!vifs->ap_active) {
p2p_mvmvif->pm_enabled = true; return;
}
/* clients are not stand alone: enable PM if DCM */ if (!(client_same_channel || ap_same_channel)) { if (bss_mvmvif && vifs->bss_active)
bss_mvmvif->pm_enabled = true; if (p2p_mvmvif && vifs->p2p_active)
p2p_mvmvif->pm_enabled = true; return;
}
/* * There is only one channel in the system and there are only * bss and p2p clients that share it
*/ if (client_same_channel && !vifs->ap_active) { /* share same channel*/
bss_mvmvif->pm_enabled = true;
p2p_mvmvif->pm_enabled = true;
}
}
#ifdef CONFIG_IWLWIFI_DEBUGFS int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, struct ieee80211_vif *vif, char *buf, int bufsz)
{ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_mac_power_cmd cmd = {}; int pos = 0;
staticint iwl_mvm_power_set_ps(struct iwl_mvm *mvm)
{ bool disable_ps; int ret;
/* disable PS if CAM */
disable_ps = (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM); /* ...or if any of the vifs require PS to be off */
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_power_ps_disabled_iterator,
&disable_ps);
/* update device power state if it has changed */ if (mvm->ps_disabled != disable_ps) { bool old_ps_disabled = mvm->ps_disabled;
mvm->ps_disabled = disable_ps;
ret = iwl_mvm_power_update_device(mvm); if (ret) {
mvm->ps_disabled = old_ps_disabled; return ret;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.