rcu_read_unlock();
+ if (sdata->vif.type == NL80211_IFTYPE_STATION &&
+ params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED))
+ ieee80211_recalc_ps(local, -1);
+
return 0;
}
}
}
+static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_if_managed *mgd = &sdata->u.mgd;
+ struct sta_info *sta = NULL;
+ u32 sta_flags = 0;
+
+ if (!mgd->powersave)
+ return false;
+
+ if (!mgd->associated)
+ return false;
+
+ if (!mgd->associated->beacon_ies)
+ return false;
+
+ if (mgd->flags & (IEEE80211_STA_BEACON_POLL |
+ IEEE80211_STA_CONNECTION_POLL))
+ return false;
+
+ rcu_read_lock();
+ sta = sta_info_get(sdata, mgd->bssid);
+ if (sta)
+ sta_flags = get_sta_flags(sta);
+ rcu_read_unlock();
+
+ if (!(sta_flags & WLAN_STA_AUTHORIZED))
+ return false;
+
+ return true;
+}
+
/* need to hold RTNL or interface lock */
void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
{
count++;
}
- if (count == 1 && found->u.mgd.powersave &&
- found->u.mgd.associated &&
- found->u.mgd.associated->beacon_ies &&
- !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
- IEEE80211_STA_CONNECTION_POLL))) {
+ if (count == 1 && ieee80211_powersave_allowed(found)) {
struct ieee80211_conf *conf = &local->hw.conf;
s32 beaconint_us;