|
@@ -613,6 +613,37 @@ static void ieee80211_change_ps(struct ieee80211_local *local)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+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 */
|
|
/* need to hold RTNL or interface lock */
|
|
void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
|
|
void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
|
|
{
|
|
{
|
|
@@ -647,11 +678,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
|
|
count++;
|
|
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;
|
|
struct ieee80211_conf *conf = &local->hw.conf;
|
|
s32 beaconint_us;
|
|
s32 beaconint_us;
|
|
|
|
|