diff options
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r-- | net/mac80211/sta_info.c | 87 |
1 files changed, 61 insertions, 26 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index a843bb7dd2d3..b31a627ff97f 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -191,6 +191,64 @@ struct sta_info * sta_info_add(struct ieee80211_local *local, | |||
191 | return sta; | 191 | return sta; |
192 | } | 192 | } |
193 | 193 | ||
194 | static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) | ||
195 | { | ||
196 | /* | ||
197 | * This format has been mandated by the IEEE specifications, | ||
198 | * so this line may not be changed to use the __set_bit() format. | ||
199 | */ | ||
200 | bss->tim[aid / 8] |= (1 << (aid % 8)); | ||
201 | } | ||
202 | |||
203 | static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) | ||
204 | { | ||
205 | /* | ||
206 | * This format has been mandated by the IEEE specifications, | ||
207 | * so this line may not be changed to use the __clear_bit() format. | ||
208 | */ | ||
209 | bss->tim[aid / 8] &= ~(1 << (aid % 8)); | ||
210 | } | ||
211 | |||
212 | static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, | ||
213 | struct sta_info *sta) | ||
214 | { | ||
215 | if (bss) | ||
216 | __bss_tim_set(bss, sta->aid); | ||
217 | if (sta->local->ops->set_tim) | ||
218 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); | ||
219 | } | ||
220 | |||
221 | void sta_info_set_tim_bit(struct sta_info *sta) | ||
222 | { | ||
223 | struct ieee80211_sub_if_data *sdata; | ||
224 | |||
225 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | ||
226 | |||
227 | read_lock_bh(&sta->local->sta_lock); | ||
228 | __sta_info_set_tim_bit(sdata->bss, sta); | ||
229 | read_unlock_bh(&sta->local->sta_lock); | ||
230 | } | ||
231 | |||
232 | static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, | ||
233 | struct sta_info *sta) | ||
234 | { | ||
235 | if (bss) | ||
236 | __bss_tim_clear(bss, sta->aid); | ||
237 | if (sta->local->ops->set_tim) | ||
238 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); | ||
239 | } | ||
240 | |||
241 | void sta_info_clear_tim_bit(struct sta_info *sta) | ||
242 | { | ||
243 | struct ieee80211_sub_if_data *sdata; | ||
244 | |||
245 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | ||
246 | |||
247 | read_lock_bh(&sta->local->sta_lock); | ||
248 | __sta_info_clear_tim_bit(sdata->bss, sta); | ||
249 | read_unlock_bh(&sta->local->sta_lock); | ||
250 | } | ||
251 | |||
194 | /* Caller must hold local->sta_lock */ | 252 | /* Caller must hold local->sta_lock */ |
195 | void sta_info_remove(struct sta_info *sta) | 253 | void sta_info_remove(struct sta_info *sta) |
196 | { | 254 | { |
@@ -207,10 +265,9 @@ void sta_info_remove(struct sta_info *sta) | |||
207 | sta->flags &= ~WLAN_STA_PS; | 265 | sta->flags &= ~WLAN_STA_PS; |
208 | if (sdata->bss) | 266 | if (sdata->bss) |
209 | atomic_dec(&sdata->bss->num_sta_ps); | 267 | atomic_dec(&sdata->bss->num_sta_ps); |
268 | __sta_info_clear_tim_bit(sdata->bss, sta); | ||
210 | } | 269 | } |
211 | local->num_sta--; | 270 | local->num_sta--; |
212 | sta_info_remove_aid_ptr(sta); | ||
213 | |||
214 | } | 271 | } |
215 | 272 | ||
216 | void sta_info_free(struct sta_info *sta) | 273 | void sta_info_free(struct sta_info *sta) |
@@ -310,13 +367,8 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
310 | "%s)\n", print_mac(mac, sta->addr)); | 367 | "%s)\n", print_mac(mac, sta->addr)); |
311 | dev_kfree_skb(skb); | 368 | dev_kfree_skb(skb); |
312 | 369 | ||
313 | if (skb_queue_empty(&sta->ps_tx_buf)) { | 370 | if (skb_queue_empty(&sta->ps_tx_buf)) |
314 | if (sdata->bss) | 371 | sta_info_clear_tim_bit(sta); |
315 | bss_tim_set(sta->local, sdata->bss, sta->aid); | ||
316 | if (sta->local->ops->set_tim) | ||
317 | sta->local->ops->set_tim(local_to_hw(sta->local), | ||
318 | sta->aid, 0); | ||
319 | } | ||
320 | } | 372 | } |
321 | } | 373 | } |
322 | 374 | ||
@@ -395,23 +447,6 @@ void sta_info_stop(struct ieee80211_local *local) | |||
395 | sta_info_flush(local, NULL); | 447 | sta_info_flush(local, NULL); |
396 | } | 448 | } |
397 | 449 | ||
398 | void sta_info_remove_aid_ptr(struct sta_info *sta) | ||
399 | { | ||
400 | struct ieee80211_sub_if_data *sdata; | ||
401 | |||
402 | if (sta->aid <= 0) | ||
403 | return; | ||
404 | |||
405 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | ||
406 | |||
407 | if (sdata->bss) | ||
408 | __bss_tim_clear(sdata->bss, sta->aid); | ||
409 | if (sdata->local->ops->set_tim) | ||
410 | sdata->local->ops->set_tim(local_to_hw(sdata->local), | ||
411 | sta->aid, 0); | ||
412 | } | ||
413 | |||
414 | |||
415 | /** | 450 | /** |
416 | * sta_info_flush - flush matching STA entries from the STA table | 451 | * sta_info_flush - flush matching STA entries from the STA table |
417 | * @local: local interface data | 452 | * @local: local interface data |