Commit 7303dd7f authored by Alexander Bondar's avatar Alexander Bondar Committed by Emmanuel Grumbach

iwlwifi: mvm: Enable power save on BSS and P2P client in DCM

New FW enables support for power save on BSS and P2P client MACs
simultaneously when they function on different channels (DCM).
Enable this case in the driver after examining new TLV flag -
IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM. Still power management is not
allowed on both MACs if they function on a same channel.
Remove another redundant TLV flag - IWL_UCODE_TLV_FLAGS_P2P_PS that
is not in use anymore. Remove bound_vif_cnt as redundant.
Signed-off-by: default avatarAlexander Bondar <alexander.bondar@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent f3c221f6
......@@ -92,8 +92,8 @@
* @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API
* @IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command
* containing CAM (Continuous Active Mode) indication.
* @IWL_UCODE_TLV_FLAGS_P2P_PS: P2P client power save is supported (only on a
* single bound interface).
* @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_DCM: support power save on BSS station and
* P2P client interfaces simultaneously if they are in different bindings.
* @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
* @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
* @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients
......@@ -118,7 +118,7 @@ enum iwl_ucode_tlv_flag {
IWL_UCODE_TLV_FLAGS_SCHED_SCAN = BIT(17),
IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19),
IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD = BIT(20),
IWL_UCODE_TLV_FLAGS_P2P_PS = BIT(21),
IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM = BIT(22),
IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24),
IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD = BIT(26),
IWL_UCODE_TLV_FLAGS_BCAST_FILTERING = BIT(29),
......
......@@ -591,7 +591,7 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) ||
(vif->type == NL80211_IFTYPE_STATION && vif->p2p &&
mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS)))
mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)))
MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR |
S_IRUSR);
......
......@@ -1305,7 +1305,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
mvmvif->ap_ibss_active = true;
/* power updated needs to be done before quotas */
mvm->bound_vif_cnt++;
iwl_mvm_power_update_mac(mvm, vif);
ret = iwl_mvm_update_quotas(mvm, vif);
......@@ -1324,7 +1323,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
return 0;
out_quota_failed:
mvm->bound_vif_cnt--;
iwl_mvm_power_update_mac(mvm, vif);
mvmvif->ap_ibss_active = false;
iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
......@@ -1361,7 +1359,6 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
iwl_mvm_binding_remove_vif(mvm, vif);
mvm->bound_vif_cnt--;
iwl_mvm_power_update_mac(mvm, vif);
iwl_mvm_mac_ctxt_remove(mvm, vif);
......@@ -2095,7 +2092,6 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
* Power state must be updated before quotas,
* otherwise fw will complain.
*/
mvm->bound_vif_cnt++;
iwl_mvm_power_update_mac(mvm, vif);
/* Setting the quota at this stage is only required for monitor
......@@ -2113,7 +2109,6 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
out_remove_binding:
iwl_mvm_binding_remove_vif(mvm, vif);
mvm->bound_vif_cnt--;
iwl_mvm_power_update_mac(mvm, vif);
out_unlock:
mutex_unlock(&mvm->mutex);
......@@ -2146,7 +2141,6 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
}
iwl_mvm_binding_remove_vif(mvm, vif);
mvm->bound_vif_cnt--;
iwl_mvm_power_update_mac(mvm, vif);
out_unlock:
......
......@@ -587,8 +587,6 @@ struct iwl_mvm {
u8 first_agg_queue;
u8 last_agg_queue;
u8 bound_vif_cnt;
/* Indicate if device power save is allowed */
bool ps_disabled;
/* Indicate if device power management is allowed */
......
......@@ -425,7 +425,7 @@ static int iwl_mvm_power_send_cmd(struct iwl_mvm *mvm,
return 0;
if (vif->p2p &&
!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS))
!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM))
return 0;
iwl_mvm_power_build_cmd(mvm, vif, &cmd);
......@@ -511,8 +511,11 @@ int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
struct iwl_power_constraint {
struct ieee80211_vif *bf_vif;
struct ieee80211_vif *bss_vif;
u16 bss_phyctx_id;
u16 p2p_phyctx_id;
bool pm_disabled;
bool ps_disabled;
struct iwl_mvm *mvm;
};
static void iwl_mvm_power_iterator(void *_data, u8 *mac,
......@@ -520,6 +523,7 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_power_constraint *power_iterator = _data;
struct iwl_mvm *mvm = power_iterator->mvm;
switch (ieee80211_vif_type_p2p(vif)) {
case NL80211_IFTYPE_P2P_DEVICE:
......@@ -539,11 +543,28 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
break;
case NL80211_IFTYPE_P2P_CLIENT:
/* no BSS power mgmt if we have a P2P client*/
power_iterator->pm_disabled = true;
if (mvmvif->phy_ctxt)
power_iterator->p2p_phyctx_id = mvmvif->phy_ctxt->id;
IWL_DEBUG_POWER(mvm, "p2p: p2p_id=%d, bss_id=%d\n",
power_iterator->p2p_phyctx_id,
power_iterator->bss_phyctx_id);
if (!(mvm->fw->ucode_capa.flags &
IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)) {
/* no BSS power mgmt if we have a P2P client*/
power_iterator->pm_disabled = true;
} else if (power_iterator->p2p_phyctx_id < MAX_PHYS &&
power_iterator->bss_phyctx_id < MAX_PHYS &&
power_iterator->p2p_phyctx_id ==
power_iterator->bss_phyctx_id) {
power_iterator->pm_disabled = true;
}
break;
case NL80211_IFTYPE_STATION:
if (mvmvif->phy_ctxt)
power_iterator->bss_phyctx_id = mvmvif->phy_ctxt->id;
/* we should have only one BSS vif */
WARN_ON(power_iterator->bss_vif);
power_iterator->bss_vif = vif;
......@@ -551,6 +572,17 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
if (mvmvif->bf_data.bf_enabled &&
!WARN_ON(power_iterator->bf_vif))
power_iterator->bf_vif = vif;
IWL_DEBUG_POWER(mvm, "bss: p2p_id=%d, bss_id=%d\n",
power_iterator->p2p_phyctx_id,
power_iterator->bss_phyctx_id);
if (mvm->fw->ucode_capa.flags &
IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM &&
(power_iterator->p2p_phyctx_id < MAX_PHYS &&
power_iterator->bss_phyctx_id < MAX_PHYS &&
power_iterator->p2p_phyctx_id ==
power_iterator->bss_phyctx_id))
power_iterator->pm_disabled = true;
break;
default:
......@@ -572,16 +604,16 @@ iwl_mvm_power_get_global_constraint(struct iwl_mvm *mvm,
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_power_iterator, constraint);
/* TODO: remove this and determine this variable in the iterator */
if (mvm->bound_vif_cnt > 1)
constraint->pm_disabled = true;
}
int iwl_mvm_power_update_mac(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_power_constraint constraint = {};
struct iwl_power_constraint constraint = {
.p2p_phyctx_id = MAX_PHYS,
.bss_phyctx_id = MAX_PHYS,
.mvm = mvm,
};
bool ba_enable;
int ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment