aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2008-10-24 00:25:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-10-31 19:02:14 -0400
commit8b30b1fe368ab03049435884c11c5c50e4c4ef0b (patch)
tree02b27b36cf90267d59584b493ad652e3a4cc6a7e /net/mac80211
parent4393dce9402c58744433c7a4f3931e17ddde4fb4 (diff)
mac80211: Re-enable aggregation
Wireless HW without any dedicated queues for aggregation do not need the ampdu_queues mechanism present right now in mac80211. Since mac80211 is still incomplete wrt TX MQ changes, do not allow aggregation sessions for drivers that set ampdu_queues. This is only an interim hack until Intel fixes the requeue issue. Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: Luis Rodriguez <Luis.Rodriguez@Atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ht.c60
-rw-r--r--net/mac80211/main.c7
-rw-r--r--net/mac80211/rx.c7
-rw-r--r--net/mac80211/tx.c19
-rw-r--r--net/mac80211/wme.c24
5 files changed, 63 insertions, 54 deletions
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 42c3e590df98..08009d4b7d6e 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -458,7 +458,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
458 u8 *state; 458 u8 *state;
459 int ret; 459 int ret;
460 460
461 if (tid >= STA_TID_NUM) 461 if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
462 return -EINVAL; 462 return -EINVAL;
463 463
464#ifdef CONFIG_MAC80211_HT_DEBUG 464#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -515,17 +515,19 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
515 (unsigned long)&sta->timer_to_tid[tid]; 515 (unsigned long)&sta->timer_to_tid[tid];
516 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 516 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
517 517
518 /* create a new queue for this aggregation */ 518 if (hw->ampdu_queues) {
519 ret = ieee80211_ht_agg_queue_add(local, sta, tid); 519 /* create a new queue for this aggregation */
520 ret = ieee80211_ht_agg_queue_add(local, sta, tid);
520 521
521 /* case no queue is available to aggregation 522 /* case no queue is available to aggregation
522 * don't switch to aggregation */ 523 * don't switch to aggregation */
523 if (ret) { 524 if (ret) {
524#ifdef CONFIG_MAC80211_HT_DEBUG 525#ifdef CONFIG_MAC80211_HT_DEBUG
525 printk(KERN_DEBUG "BA request denied - queue unavailable for" 526 printk(KERN_DEBUG "BA request denied - "
526 " tid %d\n", tid); 527 "queue unavailable for tid %d\n", tid);
527#endif /* CONFIG_MAC80211_HT_DEBUG */ 528#endif /* CONFIG_MAC80211_HT_DEBUG */
528 goto err_unlock_queue; 529 goto err_unlock_queue;
530 }
529 } 531 }
530 sdata = sta->sdata; 532 sdata = sta->sdata;
531 533
@@ -544,7 +546,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
544 /* No need to requeue the packets in the agg queue, since we 546 /* No need to requeue the packets in the agg queue, since we
545 * held the tx lock: no packet could be enqueued to the newly 547 * held the tx lock: no packet could be enqueued to the newly
546 * allocated queue */ 548 * allocated queue */
547 ieee80211_ht_agg_queue_remove(local, sta, tid, 0); 549 if (hw->ampdu_queues)
550 ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
548#ifdef CONFIG_MAC80211_HT_DEBUG 551#ifdef CONFIG_MAC80211_HT_DEBUG
549 printk(KERN_DEBUG "BA request denied - HW unavailable for" 552 printk(KERN_DEBUG "BA request denied - HW unavailable for"
550 " tid %d\n", tid); 553 " tid %d\n", tid);
@@ -554,7 +557,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
554 } 557 }
555 558
556 /* Will put all the packets in the new SW queue */ 559 /* Will put all the packets in the new SW queue */
557 ieee80211_requeue(local, ieee802_1d_to_ac[tid]); 560 if (hw->ampdu_queues)
561 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
558 spin_unlock_bh(&sta->lock); 562 spin_unlock_bh(&sta->lock);
559 563
560 /* send an addBA request */ 564 /* send an addBA request */
@@ -622,7 +626,8 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
622 ra, tid); 626 ra, tid);
623#endif /* CONFIG_MAC80211_HT_DEBUG */ 627#endif /* CONFIG_MAC80211_HT_DEBUG */
624 628
625 ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]); 629 if (hw->ampdu_queues)
630 ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]);
626 631
627 *state = HT_AGG_STATE_REQ_STOP_BA_MSK | 632 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
628 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 633 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
@@ -635,7 +640,8 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
635 if (ret) { 640 if (ret) {
636 WARN_ON(ret != -EBUSY); 641 WARN_ON(ret != -EBUSY);
637 *state = HT_AGG_STATE_OPERATIONAL; 642 *state = HT_AGG_STATE_OPERATIONAL;
638 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 643 if (hw->ampdu_queues)
644 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
639 goto stop_BA_exit; 645 goto stop_BA_exit;
640 } 646 }
641 647
@@ -691,7 +697,8 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
691#ifdef CONFIG_MAC80211_HT_DEBUG 697#ifdef CONFIG_MAC80211_HT_DEBUG
692 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); 698 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
693#endif 699#endif
694 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 700 if (hw->ampdu_queues)
701 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
695 } 702 }
696 spin_unlock_bh(&sta->lock); 703 spin_unlock_bh(&sta->lock);
697 rcu_read_unlock(); 704 rcu_read_unlock();
@@ -745,16 +752,18 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
745 ieee80211_send_delba(sta->sdata, ra, tid, 752 ieee80211_send_delba(sta->sdata, ra, tid,
746 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); 753 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
747 754
748 agg_queue = sta->tid_to_tx_q[tid]; 755 if (hw->ampdu_queues) {
749 756 agg_queue = sta->tid_to_tx_q[tid];
750 ieee80211_ht_agg_queue_remove(local, sta, tid, 1); 757 ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
751 758
752 /* We just requeued the all the frames that were in the 759 /* We just requeued the all the frames that were in the
753 * removed queue, and since we might miss a softirq we do 760 * removed queue, and since we might miss a softirq we do
754 * netif_schedule_queue. ieee80211_wake_queue is not used 761 * netif_schedule_queue. ieee80211_wake_queue is not used
755 * here as this queue is not necessarily stopped 762 * here as this queue is not necessarily stopped
756 */ 763 */
757 netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue)); 764 netif_schedule_queue(netdev_get_tx_queue(local->mdev,
765 agg_queue));
766 }
758 spin_lock_bh(&sta->lock); 767 spin_lock_bh(&sta->lock);
759 *state = HT_AGG_STATE_IDLE; 768 *state = HT_AGG_STATE_IDLE;
760 sta->ampdu_mlme.addba_req_num[tid] = 0; 769 sta->ampdu_mlme.addba_req_num[tid] = 0;
@@ -1011,7 +1020,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
1011 *state |= HT_ADDBA_RECEIVED_MSK; 1020 *state |= HT_ADDBA_RECEIVED_MSK;
1012 sta->ampdu_mlme.addba_req_num[tid] = 0; 1021 sta->ampdu_mlme.addba_req_num[tid] = 0;
1013 1022
1014 if (*state == HT_AGG_STATE_OPERATIONAL) 1023 if (*state == HT_AGG_STATE_OPERATIONAL &&
1024 local->hw.ampdu_queues)
1015 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 1025 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
1016 1026
1017 spin_unlock_bh(&sta->lock); 1027 spin_unlock_bh(&sta->lock);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 88c1975a97a5..fa0cc7a1e6b4 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -386,8 +386,6 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
386 struct sta_info *sta, 386 struct sta_info *sta,
387 struct sk_buff *skb) 387 struct sk_buff *skb)
388{ 388{
389 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
390
391 sta->tx_filtered_count++; 389 sta->tx_filtered_count++;
392 390
393 /* 391 /*
@@ -434,10 +432,9 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
434 return; 432 return;
435 } 433 }
436 434
437 if (!test_sta_flags(sta, WLAN_STA_PS) && 435 if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) {
438 !(info->flags & IEEE80211_TX_CTL_REQUEUE)) {
439 /* Software retry the packet once */ 436 /* Software retry the packet once */
440 info->flags |= IEEE80211_TX_CTL_REQUEUE; 437 skb->requeue = 1;
441 ieee80211_remove_tx_extra(local, sta->key, skb); 438 ieee80211_remove_tx_extra(local, sta->key, skb);
442 dev_queue_xmit(skb); 439 dev_queue_xmit(skb);
443 return; 440 return;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c4c95f1db605..648a1d0e6c82 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -669,7 +669,6 @@ static int ap_sta_ps_end(struct sta_info *sta)
669 struct ieee80211_local *local = sdata->local; 669 struct ieee80211_local *local = sdata->local;
670 struct sk_buff *skb; 670 struct sk_buff *skb;
671 int sent = 0; 671 int sent = 0;
672 struct ieee80211_tx_info *info;
673 672
674 atomic_dec(&sdata->bss->num_sta_ps); 673 atomic_dec(&sdata->bss->num_sta_ps);
675 674
@@ -685,13 +684,11 @@ static int ap_sta_ps_end(struct sta_info *sta)
685 684
686 /* Send all buffered frames to the station */ 685 /* Send all buffered frames to the station */
687 while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { 686 while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) {
688 info = IEEE80211_SKB_CB(skb);
689 sent++; 687 sent++;
690 info->flags |= IEEE80211_TX_CTL_REQUEUE; 688 skb->requeue = 1;
691 dev_queue_xmit(skb); 689 dev_queue_xmit(skb);
692 } 690 }
693 while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { 691 while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) {
694 info = IEEE80211_SKB_CB(skb);
695 local->total_ps_buffered--; 692 local->total_ps_buffered--;
696 sent++; 693 sent++;
697#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 694#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
@@ -699,7 +696,7 @@ static int ap_sta_ps_end(struct sta_info *sta)
699 "since STA not sleeping anymore\n", sdata->dev->name, 696 "since STA not sleeping anymore\n", sdata->dev->name,
700 sta->sta.addr, sta->sta.aid); 697 sta->sta.addr, sta->sta.aid);
701#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 698#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
702 info->flags |= IEEE80211_TX_CTL_REQUEUE; 699 skb->requeue = 1;
703 dev_queue_xmit(skb); 700 dev_queue_xmit(skb);
704 } 701 }
705 702
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 541e3e64493d..d6392af9cd20 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -661,6 +661,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
661static ieee80211_tx_result debug_noinline 661static ieee80211_tx_result debug_noinline
662ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) 662ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
663{ 663{
664 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
664 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 665 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
665 size_t hdrlen, per_fragm, num_fragm, payload_len, left; 666 size_t hdrlen, per_fragm, num_fragm, payload_len, left;
666 struct sk_buff **frags, *first, *frag; 667 struct sk_buff **frags, *first, *frag;
@@ -677,9 +678,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
677 * This scenario is handled in __ieee80211_tx_prepare but extra 678 * This scenario is handled in __ieee80211_tx_prepare but extra
678 * caution taken here as fragmented ampdu may cause Tx stop. 679 * caution taken here as fragmented ampdu may cause Tx stop.
679 */ 680 */
680 if (WARN_ON(tx->flags & IEEE80211_TX_CTL_AMPDU || 681 if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
681 skb_get_queue_mapping(tx->skb) >=
682 ieee80211_num_regular_queues(&tx->local->hw)))
683 return TX_DROP; 682 return TX_DROP;
684 683
685 first = tx->skb; 684 first = tx->skb;
@@ -951,7 +950,8 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
951 struct ieee80211_sub_if_data *sdata; 950 struct ieee80211_sub_if_data *sdata;
952 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 951 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
953 952
954 int hdrlen; 953 int hdrlen, tid;
954 u8 *qc, *state;
955 955
956 memset(tx, 0, sizeof(*tx)); 956 memset(tx, 0, sizeof(*tx));
957 tx->skb = skb; 957 tx->skb = skb;
@@ -982,6 +982,15 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
982 982
983 tx->sta = sta_info_get(local, hdr->addr1); 983 tx->sta = sta_info_get(local, hdr->addr1);
984 984
985 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control)) {
986 qc = ieee80211_get_qos_ctl(hdr);
987 tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
988
989 state = &tx->sta->ampdu_mlme.tid_state_tx[tid];
990 if (*state == HT_AGG_STATE_OPERATIONAL)
991 info->flags |= IEEE80211_TX_CTL_AMPDU;
992 }
993
985 if (is_multicast_ether_addr(hdr->addr1)) { 994 if (is_multicast_ether_addr(hdr->addr1)) {
986 tx->flags &= ~IEEE80211_TX_UNICAST; 995 tx->flags &= ~IEEE80211_TX_UNICAST;
987 info->flags |= IEEE80211_TX_CTL_NO_ACK; 996 info->flags |= IEEE80211_TX_CTL_NO_ACK;
@@ -1172,7 +1181,7 @@ retry:
1172 * queues, there's no reason for a driver to reject 1181 * queues, there's no reason for a driver to reject
1173 * a frame there, warn and drop it. 1182 * a frame there, warn and drop it.
1174 */ 1183 */
1175 if (WARN_ON(queue >= ieee80211_num_regular_queues(&local->hw))) 1184 if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
1176 goto drop; 1185 goto drop;
1177 1186
1178 store = &local->pending_packet[queue]; 1187 store = &local->pending_packet[queue];
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index d27ef7f2d4a7..ac71b38f7cb5 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -114,8 +114,8 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
114{ 114{
115 struct ieee80211_master_priv *mpriv = netdev_priv(dev); 115 struct ieee80211_master_priv *mpriv = netdev_priv(dev);
116 struct ieee80211_local *local = mpriv->local; 116 struct ieee80211_local *local = mpriv->local;
117 struct ieee80211_hw *hw = &local->hw;
117 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 118 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
118 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
119 struct sta_info *sta; 119 struct sta_info *sta;
120 u16 queue; 120 u16 queue;
121 u8 tid; 121 u8 tid;
@@ -124,21 +124,19 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
124 if (unlikely(queue >= local->hw.queues)) 124 if (unlikely(queue >= local->hw.queues))
125 queue = local->hw.queues - 1; 125 queue = local->hw.queues - 1;
126 126
127 if (info->flags & IEEE80211_TX_CTL_REQUEUE) { 127 if (skb->requeue) {
128 if (!hw->ampdu_queues)
129 return queue;
130
128 rcu_read_lock(); 131 rcu_read_lock();
129 sta = sta_info_get(local, hdr->addr1); 132 sta = sta_info_get(local, hdr->addr1);
130 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; 133 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
131 if (sta) { 134 if (sta) {
132 struct ieee80211_hw *hw = &local->hw;
133 int ampdu_queue = sta->tid_to_tx_q[tid]; 135 int ampdu_queue = sta->tid_to_tx_q[tid];
134 136
135 if ((ampdu_queue < ieee80211_num_queues(hw)) && 137 if ((ampdu_queue < ieee80211_num_queues(hw)) &&
136 test_bit(ampdu_queue, local->queue_pool)) { 138 test_bit(ampdu_queue, local->queue_pool))
137 queue = ampdu_queue; 139 queue = ampdu_queue;
138 info->flags |= IEEE80211_TX_CTL_AMPDU;
139 } else {
140 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
141 }
142 } 140 }
143 rcu_read_unlock(); 141 rcu_read_unlock();
144 142
@@ -159,20 +157,18 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
159 *p++ = ack_policy | tid; 157 *p++ = ack_policy | tid;
160 *p = 0; 158 *p = 0;
161 159
160 if (!hw->ampdu_queues)
161 return queue;
162
162 rcu_read_lock(); 163 rcu_read_lock();
163 164
164 sta = sta_info_get(local, hdr->addr1); 165 sta = sta_info_get(local, hdr->addr1);
165 if (sta) { 166 if (sta) {
166 int ampdu_queue = sta->tid_to_tx_q[tid]; 167 int ampdu_queue = sta->tid_to_tx_q[tid];
167 struct ieee80211_hw *hw = &local->hw;
168 168
169 if ((ampdu_queue < ieee80211_num_queues(hw)) && 169 if ((ampdu_queue < ieee80211_num_queues(hw)) &&
170 test_bit(ampdu_queue, local->queue_pool)) { 170 test_bit(ampdu_queue, local->queue_pool))
171 queue = ampdu_queue; 171 queue = ampdu_queue;
172 info->flags |= IEEE80211_TX_CTL_AMPDU;
173 } else {
174 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
175 }
176 } 172 }
177 173
178 rcu_read_unlock(); 174 rcu_read_unlock();