aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c55
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)
376static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, 377static 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)
397static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, 402static 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))