ret = 0;
goto out;
case NL80211_IFTYPE_STATION:
+ break;
case NL80211_IFTYPE_MONITOR:
+ /* always disable PS when a monitor interface is active */
+ mvmvif->ps_disabled = true;
break;
default:
ret = -EINVAL;
goto out;
case NL80211_IFTYPE_MONITOR:
mvmvif->monitor_active = false;
+ mvmvif->ps_disabled = false;
break;
case NL80211_IFTYPE_AP:
/* This part is triggered only during CSA */
* interface should get quota etc.
* @low_latency: indicates that this interface is in low-latency mode
* (VMACLowLatencyMode)
+ * @ps_disabled: indicates that this interface requires PS to be disabled
* @queue_params: QoS params for this MAC
* @bcast_sta: station used for broadcast packets. Used by the following
* vifs: P2P_DEVICE, GO and AP.
bool pm_enabled;
bool monitor_active;
bool low_latency;
+ bool ps_disabled;
struct iwl_mvm_vif_bf_data bf_data;
u32 ap_beacon_time;
mvmvif->pm_enabled = false;
}
+static void iwl_mvm_power_ps_disabled_iterator(void *_data, u8* mac,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ bool *disable_ps = _data;
+
+ if (mvmvif->phy_ctxt)
+ if (mvmvif->phy_ctxt->id < MAX_PHYS)
+ *disable_ps |= mvmvif->ps_disabled;
+}
+
static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac,
struct ieee80211_vif *vif)
{
return ret;
}
-static int iwl_mvm_power_set_ps(struct iwl_mvm *mvm,
- struct iwl_power_vifs *vifs)
+static int 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 there is an active monitor vif */
- disable_ps |= (vifs->monitor_vif && vifs->monitor_active);
+ /* ...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) {
IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_power_get_vifs_iterator, &vifs);
- ret = iwl_mvm_power_set_ps(mvm, &vifs);
+ ret = iwl_mvm_power_set_ps(mvm);
if (ret)
return ret;
iwl_mvm_power_set_pm(mvm, &vifs);
- ret = iwl_mvm_power_set_ps(mvm, &vifs);
+ ret = iwl_mvm_power_set_ps(mvm);
if (ret)
return ret;