aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-09-08 11:44:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-11 15:53:37 -0400
commitbacac545f10f2bf6e5ceff0d8e2b82dfc493602a (patch)
tree16c590d0c71e5368e75e7a108fa4df0fa196767f /net/mac80211/main.c
parent44d414dbff9d5bf46fc09f2e68567b5848cbbfd3 (diff)
mac80211: move some HT code out of main.c
Now that I've created ht.c, I can move the aggregation code from main.c into it. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c373
1 files changed, 0 insertions, 373 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 6df4a2e1509..f90254a5948 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -593,379 +593,6 @@ static int ieee80211_stop(struct net_device *dev)
593 return 0; 593 return 0;
594} 594}
595 595
596int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
597{
598 struct ieee80211_local *local = hw_to_local(hw);
599 struct sta_info *sta;
600 struct ieee80211_sub_if_data *sdata;
601 u16 start_seq_num;
602 u8 *state;
603 int ret;
604 DECLARE_MAC_BUF(mac);
605
606 if (tid >= STA_TID_NUM)
607 return -EINVAL;
608
609#ifdef CONFIG_MAC80211_HT_DEBUG
610 printk(KERN_DEBUG "Open BA session requested for %s tid %u\n",
611 print_mac(mac, ra), tid);
612#endif /* CONFIG_MAC80211_HT_DEBUG */
613
614 rcu_read_lock();
615
616 sta = sta_info_get(local, ra);
617 if (!sta) {
618#ifdef CONFIG_MAC80211_HT_DEBUG
619 printk(KERN_DEBUG "Could not find the station\n");
620#endif
621 ret = -ENOENT;
622 goto exit;
623 }
624
625 spin_lock_bh(&sta->lock);
626
627 /* we have tried too many times, receiver does not want A-MPDU */
628 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
629 ret = -EBUSY;
630 goto err_unlock_sta;
631 }
632
633 state = &sta->ampdu_mlme.tid_state_tx[tid];
634 /* check if the TID is not in aggregation flow already */
635 if (*state != HT_AGG_STATE_IDLE) {
636#ifdef CONFIG_MAC80211_HT_DEBUG
637 printk(KERN_DEBUG "BA request denied - session is not "
638 "idle on tid %u\n", tid);
639#endif /* CONFIG_MAC80211_HT_DEBUG */
640 ret = -EAGAIN;
641 goto err_unlock_sta;
642 }
643
644 /* prepare A-MPDU MLME for Tx aggregation */
645 sta->ampdu_mlme.tid_tx[tid] =
646 kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
647 if (!sta->ampdu_mlme.tid_tx[tid]) {
648#ifdef CONFIG_MAC80211_HT_DEBUG
649 if (net_ratelimit())
650 printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
651 tid);
652#endif
653 ret = -ENOMEM;
654 goto err_unlock_sta;
655 }
656 /* Tx timer */
657 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
658 sta_addba_resp_timer_expired;
659 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
660 (unsigned long)&sta->timer_to_tid[tid];
661 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
662
663 /* create a new queue for this aggregation */
664 ret = ieee80211_ht_agg_queue_add(local, sta, tid);
665
666 /* case no queue is available to aggregation
667 * don't switch to aggregation */
668 if (ret) {
669#ifdef CONFIG_MAC80211_HT_DEBUG
670 printk(KERN_DEBUG "BA request denied - queue unavailable for"
671 " tid %d\n", tid);
672#endif /* CONFIG_MAC80211_HT_DEBUG */
673 goto err_unlock_queue;
674 }
675 sdata = sta->sdata;
676
677 /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
678 * call back right away, it must see that the flow has begun */
679 *state |= HT_ADDBA_REQUESTED_MSK;
680
681 /* This is slightly racy because the queue isn't stopped */
682 start_seq_num = sta->tid_seq[tid];
683
684 if (local->ops->ampdu_action)
685 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
686 ra, tid, &start_seq_num);
687
688 if (ret) {
689 /* No need to requeue the packets in the agg queue, since we
690 * held the tx lock: no packet could be enqueued to the newly
691 * allocated queue */
692 ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
693#ifdef CONFIG_MAC80211_HT_DEBUG
694 printk(KERN_DEBUG "BA request denied - HW unavailable for"
695 " tid %d\n", tid);
696#endif /* CONFIG_MAC80211_HT_DEBUG */
697 *state = HT_AGG_STATE_IDLE;
698 goto err_unlock_queue;
699 }
700
701 /* Will put all the packets in the new SW queue */
702 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
703 spin_unlock_bh(&sta->lock);
704
705 /* send an addBA request */
706 sta->ampdu_mlme.dialog_token_allocator++;
707 sta->ampdu_mlme.tid_tx[tid]->dialog_token =
708 sta->ampdu_mlme.dialog_token_allocator;
709 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
710
711
712 ieee80211_send_addba_request(sta->sdata, ra, tid,
713 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
714 sta->ampdu_mlme.tid_tx[tid]->ssn,
715 0x40, 5000);
716 /* activate the timer for the recipient's addBA response */
717 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
718 jiffies + ADDBA_RESP_INTERVAL;
719 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
720#ifdef CONFIG_MAC80211_HT_DEBUG
721 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
722#endif
723 goto exit;
724
725err_unlock_queue:
726 kfree(sta->ampdu_mlme.tid_tx[tid]);
727 sta->ampdu_mlme.tid_tx[tid] = NULL;
728 ret = -EBUSY;
729err_unlock_sta:
730 spin_unlock_bh(&sta->lock);
731exit:
732 rcu_read_unlock();
733 return ret;
734}
735EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
736
737int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
738 u8 *ra, u16 tid,
739 enum ieee80211_back_parties initiator)
740{
741 struct ieee80211_local *local = hw_to_local(hw);
742 struct sta_info *sta;
743 u8 *state;
744 int ret = 0;
745 DECLARE_MAC_BUF(mac);
746
747 if (tid >= STA_TID_NUM)
748 return -EINVAL;
749
750 rcu_read_lock();
751 sta = sta_info_get(local, ra);
752 if (!sta) {
753 rcu_read_unlock();
754 return -ENOENT;
755 }
756
757 /* check if the TID is in aggregation */
758 state = &sta->ampdu_mlme.tid_state_tx[tid];
759 spin_lock_bh(&sta->lock);
760
761 if (*state != HT_AGG_STATE_OPERATIONAL) {
762 ret = -ENOENT;
763 goto stop_BA_exit;
764 }
765
766#ifdef CONFIG_MAC80211_HT_DEBUG
767 printk(KERN_DEBUG "Tx BA session stop requested for %s tid %u\n",
768 print_mac(mac, ra), tid);
769#endif /* CONFIG_MAC80211_HT_DEBUG */
770
771 ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]);
772
773 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
774 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
775
776 if (local->ops->ampdu_action)
777 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_STOP,
778 ra, tid, NULL);
779
780 /* case HW denied going back to legacy */
781 if (ret) {
782 WARN_ON(ret != -EBUSY);
783 *state = HT_AGG_STATE_OPERATIONAL;
784 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
785 goto stop_BA_exit;
786 }
787
788stop_BA_exit:
789 spin_unlock_bh(&sta->lock);
790 rcu_read_unlock();
791 return ret;
792}
793EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
794
795void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
796{
797 struct ieee80211_local *local = hw_to_local(hw);
798 struct sta_info *sta;
799 u8 *state;
800 DECLARE_MAC_BUF(mac);
801
802 if (tid >= STA_TID_NUM) {
803#ifdef CONFIG_MAC80211_HT_DEBUG
804 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
805 tid, STA_TID_NUM);
806#endif
807 return;
808 }
809
810 rcu_read_lock();
811 sta = sta_info_get(local, ra);
812 if (!sta) {
813 rcu_read_unlock();
814#ifdef CONFIG_MAC80211_HT_DEBUG
815 printk(KERN_DEBUG "Could not find station: %s\n",
816 print_mac(mac, ra));
817#endif
818 return;
819 }
820
821 state = &sta->ampdu_mlme.tid_state_tx[tid];
822 spin_lock_bh(&sta->lock);
823
824 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
825#ifdef CONFIG_MAC80211_HT_DEBUG
826 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
827 *state);
828#endif
829 spin_unlock_bh(&sta->lock);
830 rcu_read_unlock();
831 return;
832 }
833
834 WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK);
835
836 *state |= HT_ADDBA_DRV_READY_MSK;
837
838 if (*state == HT_AGG_STATE_OPERATIONAL) {
839#ifdef CONFIG_MAC80211_HT_DEBUG
840 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
841#endif
842 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
843 }
844 spin_unlock_bh(&sta->lock);
845 rcu_read_unlock();
846}
847EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
848
849void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
850{
851 struct ieee80211_local *local = hw_to_local(hw);
852 struct sta_info *sta;
853 u8 *state;
854 int agg_queue;
855 DECLARE_MAC_BUF(mac);
856
857 if (tid >= STA_TID_NUM) {
858#ifdef CONFIG_MAC80211_HT_DEBUG
859 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
860 tid, STA_TID_NUM);
861#endif
862 return;
863 }
864
865#ifdef CONFIG_MAC80211_HT_DEBUG
866 printk(KERN_DEBUG "Stopping Tx BA session for %s tid %d\n",
867 print_mac(mac, ra), tid);
868#endif /* CONFIG_MAC80211_HT_DEBUG */
869
870 rcu_read_lock();
871 sta = sta_info_get(local, ra);
872 if (!sta) {
873#ifdef CONFIG_MAC80211_HT_DEBUG
874 printk(KERN_DEBUG "Could not find station: %s\n",
875 print_mac(mac, ra));
876#endif
877 rcu_read_unlock();
878 return;
879 }
880 state = &sta->ampdu_mlme.tid_state_tx[tid];
881
882 /* NOTE: no need to use sta->lock in this state check, as
883 * ieee80211_stop_tx_ba_session will let only one stop call to
884 * pass through per sta/tid
885 */
886 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
887#ifdef CONFIG_MAC80211_HT_DEBUG
888 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
889#endif
890 rcu_read_unlock();
891 return;
892 }
893
894 if (*state & HT_AGG_STATE_INITIATOR_MSK)
895 ieee80211_send_delba(sta->sdata, ra, tid,
896 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
897
898 agg_queue = sta->tid_to_tx_q[tid];
899
900 ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
901
902 /* We just requeued the all the frames that were in the
903 * removed queue, and since we might miss a softirq we do
904 * netif_schedule_queue. ieee80211_wake_queue is not used
905 * here as this queue is not necessarily stopped
906 */
907 netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue));
908 spin_lock_bh(&sta->lock);
909 *state = HT_AGG_STATE_IDLE;
910 sta->ampdu_mlme.addba_req_num[tid] = 0;
911 kfree(sta->ampdu_mlme.tid_tx[tid]);
912 sta->ampdu_mlme.tid_tx[tid] = NULL;
913 spin_unlock_bh(&sta->lock);
914
915 rcu_read_unlock();
916}
917EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
918
919void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
920 const u8 *ra, u16 tid)
921{
922 struct ieee80211_local *local = hw_to_local(hw);
923 struct ieee80211_ra_tid *ra_tid;
924 struct sk_buff *skb = dev_alloc_skb(0);
925
926 if (unlikely(!skb)) {
927#ifdef CONFIG_MAC80211_HT_DEBUG
928 if (net_ratelimit())
929 printk(KERN_WARNING "%s: Not enough memory, "
930 "dropping start BA session", skb->dev->name);
931#endif
932 return;
933 }
934 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
935 memcpy(&ra_tid->ra, ra, ETH_ALEN);
936 ra_tid->tid = tid;
937
938 skb->pkt_type = IEEE80211_ADDBA_MSG;
939 skb_queue_tail(&local->skb_queue, skb);
940 tasklet_schedule(&local->tasklet);
941}
942EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
943
944void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
945 const u8 *ra, u16 tid)
946{
947 struct ieee80211_local *local = hw_to_local(hw);
948 struct ieee80211_ra_tid *ra_tid;
949 struct sk_buff *skb = dev_alloc_skb(0);
950
951 if (unlikely(!skb)) {
952#ifdef CONFIG_MAC80211_HT_DEBUG
953 if (net_ratelimit())
954 printk(KERN_WARNING "%s: Not enough memory, "
955 "dropping stop BA session", skb->dev->name);
956#endif
957 return;
958 }
959 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
960 memcpy(&ra_tid->ra, ra, ETH_ALEN);
961 ra_tid->tid = tid;
962
963 skb->pkt_type = IEEE80211_DELBA_MSG;
964 skb_queue_tail(&local->skb_queue, skb);
965 tasklet_schedule(&local->tasklet);
966}
967EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
968
969static void ieee80211_set_multicast_list(struct net_device *dev) 596static void ieee80211_set_multicast_list(struct net_device *dev)
970{ 597{
971 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 598 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);