diff options
author | Marco Porsch <marco.porsch@etit.tu-chemnitz.de> | 2012-10-10 12:39:50 -0700 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-10-19 15:43:51 +0200 |
commit | d012a605108a482392be80710ea35f1db27c4aa9 (patch) | |
tree | d39be4edcc102a07a7bb764bef154ccd1b46b399 /net/mac80211/sta_info.c | |
parent | 5c95b940bd97e744267249e3b0780e6ef04b029c (diff) |
mac80211: make client powersave independent of interface type
This patch prepares mac80211 for a later implementation of mesh or
ad-hoc powersave clients.
The structures related to powersave (buffer, TIM map, counters) are
moved from the AP-specific interface structure to a generic structure
that can be embedded into any interface type.
The functions related to powersave are prepared to allow easy
extension with different interface types. For example with:
+ } else if (sta->sdata->vif.type == NL80211_IFTYPE_MESH_POINT) {
+ ps = &sdata->u.mesh.ps;
Some references to the AP's beacon structure are removed where they
were obviously not used.
The patch compiles without warning and has been briefly tested as AP
interface with one client in PS mode.
Signed-off-by: Marco Porsch <marco.porsch@etit.tu-chemnitz.de>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r-- | net/mac80211/sta_info.c | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index d5a5d62b6b0..daf55e1e0fd 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -98,6 +98,7 @@ static void free_sta_work(struct work_struct *wk) struct tid_ampdu_tx *tid_tx; struct ieee80211_sub_if_data *sdata = sta->sdata; struct ieee80211_local *local = sdata->local; + struct ps_data *ps; /* * At this point, when being called as call_rcu callback, @@ -107,11 +108,15 @@ static void free_sta_work(struct work_struct *wk) */ if (test_sta_flag(sta, WLAN_STA_PS_STA)) { - BUG_ON(!sdata->bss); + if (sta->sdata->vif.type == NL80211_IFTYPE_AP || + sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + ps = &sdata->bss->ps; + else + return; clear_sta_flag(sta, WLAN_STA_PS_STA); - atomic_dec(&sdata->bss->num_sta_ps); + atomic_dec(&ps->num_sta_ps); sta_info_recalc_tim(sta); } @@ -502,22 +507,22 @@ int sta_info_insert(struct sta_info *sta) return err; } -static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) +static inline void __bss_tim_set(u8 *tim, u16 id) { /* * This format has been mandated by the IEEE specifications, * so this line may not be changed to use the __set_bit() format. */ - bss->tim[aid / 8] |= (1 << (aid % 8)); + tim[id / 8] |= (1 << (id % 8)); } -static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) +static inline void __bss_tim_clear(u8 *tim, u16 id) { /* * This format has been mandated by the IEEE specifications, * so this line may not be changed to use the __clear_bit() format. */ - bss->tim[aid / 8] &= ~(1 << (aid % 8)); + tim[id / 8] &= ~(1 << (id % 8)); } static unsigned long ieee80211_tids_for_ac(int ac) @@ -541,14 +546,23 @@ static unsigned long ieee80211_tids_for_ac(int ac) void sta_info_recalc_tim(struct sta_info *sta) { struct ieee80211_local *local = sta->local; - struct ieee80211_if_ap *bss = sta->sdata->bss; + struct ps_data *ps; unsigned long flags; bool indicate_tim = false; u8 ignore_for_tim = sta->sta.uapsd_queues; int ac; + u16 id; + + if (sta->sdata->vif.type == NL80211_IFTYPE_AP || + sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { + if (WARN_ON_ONCE(!sta->sdata->bss)) + return; - if (WARN_ON_ONCE(!sta->sdata->bss)) + ps = &sta->sdata->bss->ps; + id = sta->sta.aid; + } else { return; + } /* No need to do anything if the driver does all */ if (local->hw.flags & IEEE80211_HW_AP_LINK_PS) @@ -587,9 +601,9 @@ void sta_info_recalc_tim(struct sta_info *sta) spin_lock_irqsave(&local->tim_lock, flags); if (indicate_tim) - __bss_tim_set(bss, sta->sta.aid); + __bss_tim_set(ps->tim, id); else - __bss_tim_clear(bss, sta->sta.aid); + __bss_tim_clear(ps->tim, id); if (local->ops->set_tim) { local->tim_in_locked_section = true; @@ -948,10 +962,17 @@ static void clear_sta_ps_flags(void *_sta) { struct sta_info *sta = _sta; struct ieee80211_sub_if_data *sdata = sta->sdata; + struct ps_data *ps; + + if (sdata->vif.type == NL80211_IFTYPE_AP || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + ps = &sdata->bss->ps; + else + return; clear_sta_flag(sta, WLAN_STA_PS_DRIVER); if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA)) - atomic_dec(&sdata->bss->num_sta_ps); + atomic_dec(&ps->num_sta_ps); } /* powersave support code */ |