diff options
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r-- | net/mac80211/sta_info.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 7d4fe4a52929..f2ba653b9d69 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -135,6 +135,7 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx, | |||
135 | /** | 135 | /** |
136 | * __sta_info_free - internal STA free helper | 136 | * __sta_info_free - internal STA free helper |
137 | * | 137 | * |
138 | * @local: pointer to the global information | ||
138 | * @sta: STA info to free | 139 | * @sta: STA info to free |
139 | * | 140 | * |
140 | * This function must undo everything done by sta_info_alloc() | 141 | * This function must undo everything done by sta_info_alloc() |
@@ -202,14 +203,12 @@ void sta_info_destroy(struct sta_info *sta) | |||
202 | dev_kfree_skb_any(skb); | 203 | dev_kfree_skb_any(skb); |
203 | 204 | ||
204 | for (i = 0; i < STA_TID_NUM; i++) { | 205 | for (i = 0; i < STA_TID_NUM; i++) { |
205 | spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); | 206 | spin_lock_bh(&sta->lock); |
206 | if (sta->ampdu_mlme.tid_rx[i]) | 207 | if (sta->ampdu_mlme.tid_rx[i]) |
207 | del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); | 208 | del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); |
208 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | ||
209 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
210 | if (sta->ampdu_mlme.tid_tx[i]) | 209 | if (sta->ampdu_mlme.tid_tx[i]) |
211 | del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); | 210 | del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); |
212 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 211 | spin_unlock_bh(&sta->lock); |
213 | } | 212 | } |
214 | 213 | ||
215 | __sta_info_free(local, sta); | 214 | __sta_info_free(local, sta); |
@@ -236,6 +235,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
236 | if (!sta) | 235 | if (!sta) |
237 | return NULL; | 236 | return NULL; |
238 | 237 | ||
238 | spin_lock_init(&sta->lock); | ||
239 | spin_lock_init(&sta->flaglock); | ||
240 | |||
239 | memcpy(sta->addr, addr, ETH_ALEN); | 241 | memcpy(sta->addr, addr, ETH_ALEN); |
240 | sta->local = local; | 242 | sta->local = local; |
241 | sta->sdata = sdata; | 243 | sta->sdata = sdata; |
@@ -249,15 +251,13 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
249 | return NULL; | 251 | return NULL; |
250 | } | 252 | } |
251 | 253 | ||
252 | spin_lock_init(&sta->ampdu_mlme.ampdu_rx); | ||
253 | spin_lock_init(&sta->ampdu_mlme.ampdu_tx); | ||
254 | for (i = 0; i < STA_TID_NUM; i++) { | 254 | for (i = 0; i < STA_TID_NUM; i++) { |
255 | /* timer_to_tid must be initialized with identity mapping to | 255 | /* timer_to_tid must be initialized with identity mapping to |
256 | * enable session_timer's data differentiation. refer to | 256 | * enable session_timer's data differentiation. refer to |
257 | * sta_rx_agg_session_timer_expired for useage */ | 257 | * sta_rx_agg_session_timer_expired for useage */ |
258 | sta->timer_to_tid[i] = i; | 258 | sta->timer_to_tid[i] = i; |
259 | /* tid to tx queue: initialize according to HW (0 is valid) */ | 259 | /* tid to tx queue: initialize according to HW (0 is valid) */ |
260 | sta->tid_to_tx_q[i] = local->hw.queues; | 260 | sta->tid_to_tx_q[i] = ieee80211_num_queues(&local->hw); |
261 | /* rx */ | 261 | /* rx */ |
262 | sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE; | 262 | sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE; |
263 | sta->ampdu_mlme.tid_rx[i] = NULL; | 263 | sta->ampdu_mlme.tid_rx[i] = NULL; |
@@ -276,7 +276,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
276 | 276 | ||
277 | #ifdef CONFIG_MAC80211_MESH | 277 | #ifdef CONFIG_MAC80211_MESH |
278 | sta->plink_state = PLINK_LISTEN; | 278 | sta->plink_state = PLINK_LISTEN; |
279 | spin_lock_init(&sta->plink_lock); | ||
280 | init_timer(&sta->plink_timer); | 279 | init_timer(&sta->plink_timer); |
281 | #endif | 280 | #endif |
282 | 281 | ||
@@ -321,7 +320,9 @@ int sta_info_insert(struct sta_info *sta) | |||
321 | /* notify driver */ | 320 | /* notify driver */ |
322 | if (local->ops->sta_notify) { | 321 | if (local->ops->sta_notify) { |
323 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) | 322 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) |
324 | sdata = sdata->u.vlan.ap; | 323 | sdata = container_of(sdata->bss, |
324 | struct ieee80211_sub_if_data, | ||
325 | u.ap); | ||
325 | 326 | ||
326 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, | 327 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, |
327 | STA_NOTIFY_ADD, sta->addr); | 328 | STA_NOTIFY_ADD, sta->addr); |
@@ -376,8 +377,10 @@ static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) | |||
376 | static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, | 377 | static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, |
377 | struct sta_info *sta) | 378 | struct sta_info *sta) |
378 | { | 379 | { |
379 | if (bss) | 380 | BUG_ON(!bss); |
380 | __bss_tim_set(bss, sta->aid); | 381 | |
382 | __bss_tim_set(bss, sta->aid); | ||
383 | |||
381 | if (sta->local->ops->set_tim) { | 384 | if (sta->local->ops->set_tim) { |
382 | sta->local->tim_in_locked_section = true; | 385 | sta->local->tim_in_locked_section = true; |
383 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); | 386 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); |
@@ -389,6 +392,8 @@ void sta_info_set_tim_bit(struct sta_info *sta) | |||
389 | { | 392 | { |
390 | unsigned long flags; | 393 | unsigned long flags; |
391 | 394 | ||
395 | BUG_ON(!sta->sdata->bss); | ||
396 | |||
392 | spin_lock_irqsave(&sta->local->sta_lock, flags); | 397 | spin_lock_irqsave(&sta->local->sta_lock, flags); |
393 | __sta_info_set_tim_bit(sta->sdata->bss, sta); | 398 | __sta_info_set_tim_bit(sta->sdata->bss, sta); |
394 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); | 399 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); |
@@ -397,8 +402,10 @@ void sta_info_set_tim_bit(struct sta_info *sta) | |||
397 | static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, | 402 | static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, |
398 | struct sta_info *sta) | 403 | struct sta_info *sta) |
399 | { | 404 | { |
400 | if (bss) | 405 | BUG_ON(!bss); |
401 | __bss_tim_clear(bss, sta->aid); | 406 | |
407 | __bss_tim_clear(bss, sta->aid); | ||
408 | |||
402 | if (sta->local->ops->set_tim) { | 409 | if (sta->local->ops->set_tim) { |
403 | sta->local->tim_in_locked_section = true; | 410 | sta->local->tim_in_locked_section = true; |
404 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); | 411 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); |
@@ -410,6 +417,8 @@ void sta_info_clear_tim_bit(struct sta_info *sta) | |||
410 | { | 417 | { |
411 | unsigned long flags; | 418 | unsigned long flags; |
412 | 419 | ||
420 | BUG_ON(!sta->sdata->bss); | ||
421 | |||
413 | spin_lock_irqsave(&sta->local->sta_lock, flags); | 422 | spin_lock_irqsave(&sta->local->sta_lock, flags); |
414 | __sta_info_clear_tim_bit(sta->sdata->bss, sta); | 423 | __sta_info_clear_tim_bit(sta->sdata->bss, sta); |
415 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); | 424 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); |
@@ -437,10 +446,10 @@ void __sta_info_unlink(struct sta_info **sta) | |||
437 | 446 | ||
438 | list_del(&(*sta)->list); | 447 | list_del(&(*sta)->list); |
439 | 448 | ||
440 | if ((*sta)->flags & WLAN_STA_PS) { | 449 | if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) { |
441 | (*sta)->flags &= ~WLAN_STA_PS; | 450 | BUG_ON(!sdata->bss); |
442 | if (sdata->bss) | 451 | |
443 | atomic_dec(&sdata->bss->num_sta_ps); | 452 | atomic_dec(&sdata->bss->num_sta_ps); |
444 | __sta_info_clear_tim_bit(sdata->bss, *sta); | 453 | __sta_info_clear_tim_bit(sdata->bss, *sta); |
445 | } | 454 | } |
446 | 455 | ||
@@ -448,7 +457,9 @@ void __sta_info_unlink(struct sta_info **sta) | |||
448 | 457 | ||
449 | if (local->ops->sta_notify) { | 458 | if (local->ops->sta_notify) { |
450 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) | 459 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) |
451 | sdata = sdata->u.vlan.ap; | 460 | sdata = container_of(sdata->bss, |
461 | struct ieee80211_sub_if_data, | ||
462 | u.ap); | ||
452 | 463 | ||
453 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, | 464 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, |
454 | STA_NOTIFY_REMOVE, (*sta)->addr); | 465 | STA_NOTIFY_REMOVE, (*sta)->addr); |
@@ -515,20 +526,20 @@ static inline int sta_info_buffer_expired(struct ieee80211_local *local, | |||
515 | struct sta_info *sta, | 526 | struct sta_info *sta, |
516 | struct sk_buff *skb) | 527 | struct sk_buff *skb) |
517 | { | 528 | { |
518 | struct ieee80211_tx_packet_data *pkt_data; | 529 | struct ieee80211_tx_info *info; |
519 | int timeout; | 530 | int timeout; |
520 | 531 | ||
521 | if (!skb) | 532 | if (!skb) |
522 | return 0; | 533 | return 0; |
523 | 534 | ||
524 | pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; | 535 | info = IEEE80211_SKB_CB(skb); |
525 | 536 | ||
526 | /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ | 537 | /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ |
527 | timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / | 538 | timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / |
528 | 15625) * HZ; | 539 | 15625) * HZ; |
529 | if (timeout < STA_TX_BUFFER_EXPIRE) | 540 | if (timeout < STA_TX_BUFFER_EXPIRE) |
530 | timeout = STA_TX_BUFFER_EXPIRE; | 541 | timeout = STA_TX_BUFFER_EXPIRE; |
531 | return time_after(jiffies, pkt_data->jiffies + timeout); | 542 | return time_after(jiffies, info->control.jiffies + timeout); |
532 | } | 543 | } |
533 | 544 | ||
534 | 545 | ||
@@ -557,8 +568,10 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
557 | 568 | ||
558 | sdata = sta->sdata; | 569 | sdata = sta->sdata; |
559 | local->total_ps_buffered--; | 570 | local->total_ps_buffered--; |
571 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | ||
560 | printk(KERN_DEBUG "Buffered frame expired (STA " | 572 | printk(KERN_DEBUG "Buffered frame expired (STA " |
561 | "%s)\n", print_mac(mac, sta->addr)); | 573 | "%s)\n", print_mac(mac, sta->addr)); |
574 | #endif | ||
562 | dev_kfree_skb(skb); | 575 | dev_kfree_skb(skb); |
563 | 576 | ||
564 | if (skb_queue_empty(&sta->ps_tx_buf)) | 577 | if (skb_queue_empty(&sta->ps_tx_buf)) |