aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/ieee80211.c')
-rw-r--r--net/mac80211/ieee80211.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 616ce10d2a38..8c0f782d21e3 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -569,12 +569,12 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
569 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 569 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
570 570
571 /* we have tried too many times, receiver does not want A-MPDU */ 571 /* we have tried too many times, receiver does not want A-MPDU */
572 if (sta->ampdu_mlme.tid_tx[tid].addba_req_num > HT_AGG_MAX_RETRIES) { 572 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
573 ret = -EBUSY; 573 ret = -EBUSY;
574 goto start_ba_exit; 574 goto start_ba_exit;
575 } 575 }
576 576
577 state = &sta->ampdu_mlme.tid_tx[tid].state; 577 state = &sta->ampdu_mlme.tid_state_tx[tid];
578 /* check if the TID is not in aggregation flow already */ 578 /* check if the TID is not in aggregation flow already */
579 if (*state != HT_AGG_STATE_IDLE) { 579 if (*state != HT_AGG_STATE_IDLE) {
580#ifdef CONFIG_MAC80211_HT_DEBUG 580#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -585,6 +585,23 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
585 goto start_ba_exit; 585 goto start_ba_exit;
586 } 586 }
587 587
588 /* prepare A-MPDU MLME for Tx aggregation */
589 sta->ampdu_mlme.tid_tx[tid] =
590 kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
591 if (!sta->ampdu_mlme.tid_tx[tid]) {
592 if (net_ratelimit())
593 printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
594 tid);
595 ret = -ENOMEM;
596 goto start_ba_exit;
597 }
598 /* Tx timer */
599 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
600 sta_addba_resp_timer_expired;
601 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
602 (unsigned long)&sta->timer_to_tid[tid];
603 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
604
588 /* ensure that TX flow won't interrupt us 605 /* ensure that TX flow won't interrupt us
589 * until the end of the call to requeue function */ 606 * until the end of the call to requeue function */
590 spin_lock_bh(&local->mdev->queue_lock); 607 spin_lock_bh(&local->mdev->queue_lock);
@@ -596,11 +613,10 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
596 * don't switch to aggregation */ 613 * don't switch to aggregation */
597 if (ret) { 614 if (ret) {
598#ifdef CONFIG_MAC80211_HT_DEBUG 615#ifdef CONFIG_MAC80211_HT_DEBUG
599 printk(KERN_DEBUG "BA request denied - no queue available for" 616 printk(KERN_DEBUG "BA request denied - queue unavailable for"
600 " tid %d\n", tid); 617 " tid %d\n", tid);
601#endif /* CONFIG_MAC80211_HT_DEBUG */ 618#endif /* CONFIG_MAC80211_HT_DEBUG */
602 spin_unlock_bh(&local->mdev->queue_lock); 619 goto start_ba_err;
603 goto start_ba_exit;
604 } 620 }
605 sdata = sta->sdata; 621 sdata = sta->sdata;
606 622
@@ -618,38 +634,40 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
618 * allocated queue */ 634 * allocated queue */
619 ieee80211_ht_agg_queue_remove(local, sta, tid, 0); 635 ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
620#ifdef CONFIG_MAC80211_HT_DEBUG 636#ifdef CONFIG_MAC80211_HT_DEBUG
621 printk(KERN_DEBUG "BA request denied - HW or queue unavailable" 637 printk(KERN_DEBUG "BA request denied - HW unavailable for"
622 " for tid %d\n", tid); 638 " tid %d\n", tid);
623#endif /* CONFIG_MAC80211_HT_DEBUG */ 639#endif /* CONFIG_MAC80211_HT_DEBUG */
624 spin_unlock_bh(&local->mdev->queue_lock);
625 *state = HT_AGG_STATE_IDLE; 640 *state = HT_AGG_STATE_IDLE;
626 goto start_ba_exit; 641 goto start_ba_err;
627 } 642 }
628 643
629 /* Will put all the packets in the new SW queue */ 644 /* Will put all the packets in the new SW queue */
630 ieee80211_requeue(local, ieee802_1d_to_ac[tid]); 645 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
631 spin_unlock_bh(&local->mdev->queue_lock); 646 spin_unlock_bh(&local->mdev->queue_lock);
632 647
633 /* We have most probably almost emptied the legacy queue */
634 /* ieee80211_wake_queue(local_to_hw(local), ieee802_1d_to_ac[tid]); */
635
636 /* send an addBA request */ 648 /* send an addBA request */
637 sta->ampdu_mlme.dialog_token_allocator++; 649 sta->ampdu_mlme.dialog_token_allocator++;
638 sta->ampdu_mlme.tid_tx[tid].dialog_token = 650 sta->ampdu_mlme.tid_tx[tid]->dialog_token =
639 sta->ampdu_mlme.dialog_token_allocator; 651 sta->ampdu_mlme.dialog_token_allocator;
640 sta->ampdu_mlme.tid_tx[tid].ssn = start_seq_num; 652 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
641 653
642 ieee80211_send_addba_request(sta->sdata->dev, ra, tid, 654 ieee80211_send_addba_request(sta->sdata->dev, ra, tid,
643 sta->ampdu_mlme.tid_tx[tid].dialog_token, 655 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
644 sta->ampdu_mlme.tid_tx[tid].ssn, 656 sta->ampdu_mlme.tid_tx[tid]->ssn,
645 0x40, 5000); 657 0x40, 5000);
646 658
647 /* activate the timer for the recipient's addBA response */ 659 /* activate the timer for the recipient's addBA response */
648 sta->ampdu_mlme.tid_tx[tid].addba_resp_timer.expires = 660 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
649 jiffies + ADDBA_RESP_INTERVAL; 661 jiffies + ADDBA_RESP_INTERVAL;
650 add_timer(&sta->ampdu_mlme.tid_tx[tid].addba_resp_timer); 662 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
651 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); 663 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
664 goto start_ba_exit;
652 665
666start_ba_err:
667 kfree(sta->ampdu_mlme.tid_tx[tid]);
668 sta->ampdu_mlme.tid_tx[tid] = NULL;
669 spin_unlock_bh(&local->mdev->queue_lock);
670 ret = -EBUSY;
653start_ba_exit: 671start_ba_exit:
654 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 672 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
655 rcu_read_unlock(); 673 rcu_read_unlock();
@@ -683,7 +701,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
683 } 701 }
684 702
685 /* check if the TID is in aggregation */ 703 /* check if the TID is in aggregation */
686 state = &sta->ampdu_mlme.tid_tx[tid].state; 704 state = &sta->ampdu_mlme.tid_state_tx[tid];
687 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 705 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
688 706
689 if (*state != HT_AGG_STATE_OPERATIONAL) { 707 if (*state != HT_AGG_STATE_OPERATIONAL) {
@@ -741,7 +759,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
741 return; 759 return;
742 } 760 }
743 761
744 state = &sta->ampdu_mlme.tid_tx[tid].state; 762 state = &sta->ampdu_mlme.tid_state_tx[tid];
745 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 763 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
746 764
747 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 765 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
@@ -790,7 +808,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
790 rcu_read_unlock(); 808 rcu_read_unlock();
791 return; 809 return;
792 } 810 }
793 state = &sta->ampdu_mlme.tid_tx[tid].state; 811 state = &sta->ampdu_mlme.tid_state_tx[tid];
794 812
795 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); 813 spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
796 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { 814 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
@@ -819,7 +837,9 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
819 * necessarily stopped */ 837 * necessarily stopped */
820 netif_schedule(local->mdev); 838 netif_schedule(local->mdev);
821 *state = HT_AGG_STATE_IDLE; 839 *state = HT_AGG_STATE_IDLE;
822 sta->ampdu_mlme.tid_tx[tid].addba_req_num = 0; 840 sta->ampdu_mlme.addba_req_num[tid] = 0;
841 kfree(sta->ampdu_mlme.tid_tx[tid]);
842 sta->ampdu_mlme.tid_tx[tid] = NULL;
823 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 843 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
824 844
825 rcu_read_unlock(); 845 rcu_read_unlock();