aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/net/wireless/ath9k/main.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c3
-rw-r--r--include/linux/skbuff.h4
-rw-r--r--include/net/mac80211.h8
-rw-r--r--net/core/skbuff.c1
-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
10 files changed, 76 insertions, 63 deletions
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 795fed5cadfa..f6dc4c826044 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -953,10 +953,7 @@ static int ath_attach(u16 devid,
953 &sc->sbands[IEEE80211_BAND_5GHZ]; 953 &sc->sbands[IEEE80211_BAND_5GHZ];
954 } 954 }
955 955
956 /* FIXME: Have to figure out proper hw init values later */
957
958 hw->queues = 4; 956 hw->queues = 4;
959 hw->ampdu_queues = 1;
960 957
961 /* Register rate control */ 958 /* Register rate control */
962 hw->rate_control_algorithm = "ath9k_rate_control"; 959 hw->rate_control_algorithm = "ath9k_rate_control";
@@ -1745,7 +1742,8 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1745 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 1742 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
1746 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 1743 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1747 IEEE80211_HW_SIGNAL_DBM | 1744 IEEE80211_HW_SIGNAL_DBM |
1748 IEEE80211_HW_NOISE_DBM; 1745 IEEE80211_HW_NOISE_DBM |
1746 IEEE80211_HW_AMPDU_AGGREGATION;
1749 1747
1750 hw->wiphy->interface_modes = 1748 hw->wiphy->interface_modes =
1751 BIT(NL80211_IFTYPE_AP) | 1749 BIT(NL80211_IFTYPE_AP) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 20c7ff382914..ba05f5ddc6d0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -871,7 +871,8 @@ int iwl_setup_mac(struct iwl_priv *priv)
871 871
872 /* Tell mac80211 our characteristics */ 872 /* Tell mac80211 our characteristics */
873 hw->flags = IEEE80211_HW_SIGNAL_DBM | 873 hw->flags = IEEE80211_HW_SIGNAL_DBM |
874 IEEE80211_HW_NOISE_DBM; 874 IEEE80211_HW_NOISE_DBM |
875 IEEE80211_HW_AMPDU_AGGREGATION;
875 hw->wiphy->interface_modes = 876 hw->wiphy->interface_modes =
876 BIT(NL80211_IFTYPE_AP) | 877 BIT(NL80211_IFTYPE_AP) |
877 BIT(NL80211_IFTYPE_STATION) | 878 BIT(NL80211_IFTYPE_STATION) |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 487e34507b41..a01b6f84e3bc 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -250,6 +250,9 @@ typedef unsigned char *sk_buff_data_t;
250 * @tc_verd: traffic control verdict 250 * @tc_verd: traffic control verdict
251 * @ndisc_nodetype: router type (from link layer) 251 * @ndisc_nodetype: router type (from link layer)
252 * @do_not_encrypt: set to prevent encryption of this frame 252 * @do_not_encrypt: set to prevent encryption of this frame
253 * @requeue: set to indicate that the wireless core should attempt
254 * a software retry on this frame if we failed to
255 * receive an ACK for it
253 * @dma_cookie: a cookie to one of several possible DMA operations 256 * @dma_cookie: a cookie to one of several possible DMA operations
254 * done by skb DMA functions 257 * done by skb DMA functions
255 * @secmark: security marking 258 * @secmark: security marking
@@ -326,6 +329,7 @@ struct sk_buff {
326#endif 329#endif
327#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) 330#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
328 __u8 do_not_encrypt:1; 331 __u8 do_not_encrypt:1;
332 __u8 requeue:1;
329#endif 333#endif
330 /* 0/13/14 bit hole */ 334 /* 0/13/14 bit hole */
331 335
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 16c895969e6e..bba96a203885 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -242,7 +242,6 @@ struct ieee80211_bss_conf {
242 * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be 242 * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be
243 * set by rate control algorithms to indicate probe rate, will 243 * set by rate control algorithms to indicate probe rate, will
244 * be cleared for fragmented frames (except on the last fragment) 244 * be cleared for fragmented frames (except on the last fragment)
245 * @IEEE80211_TX_CTL_REQUEUE: REMOVE THIS
246 */ 245 */
247enum mac80211_tx_control_flags { 246enum mac80211_tx_control_flags {
248 IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), 247 IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
@@ -258,9 +257,6 @@ enum mac80211_tx_control_flags {
258 IEEE80211_TX_STAT_AMPDU = BIT(10), 257 IEEE80211_TX_STAT_AMPDU = BIT(10),
259 IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(11), 258 IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(11),
260 IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), 259 IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12),
261
262 /* XXX: remove this */
263 IEEE80211_TX_CTL_REQUEUE = BIT(13),
264}; 260};
265 261
266enum mac80211_rate_control_flags { 262enum mac80211_rate_control_flags {
@@ -847,6 +843,9 @@ enum ieee80211_tkip_key_type {
847 * @IEEE80211_HW_SPECTRUM_MGMT: 843 * @IEEE80211_HW_SPECTRUM_MGMT:
848 * Hardware supports spectrum management defined in 802.11h 844 * Hardware supports spectrum management defined in 802.11h
849 * Measurement, Channel Switch, Quieting, TPC 845 * Measurement, Channel Switch, Quieting, TPC
846 *
847 * @IEEE80211_HW_AMPDU_AGGREGATION:
848 * Hardware supports 11n A-MPDU aggregation.
850 */ 849 */
851enum ieee80211_hw_flags { 850enum ieee80211_hw_flags {
852 IEEE80211_HW_RX_INCLUDES_FCS = 1<<1, 851 IEEE80211_HW_RX_INCLUDES_FCS = 1<<1,
@@ -858,6 +857,7 @@ enum ieee80211_hw_flags {
858 IEEE80211_HW_SIGNAL_DBM = 1<<7, 857 IEEE80211_HW_SIGNAL_DBM = 1<<7,
859 IEEE80211_HW_NOISE_DBM = 1<<8, 858 IEEE80211_HW_NOISE_DBM = 1<<8,
860 IEEE80211_HW_SPECTRUM_MGMT = 1<<9, 859 IEEE80211_HW_SPECTRUM_MGMT = 1<<9,
860 IEEE80211_HW_AMPDU_AGGREGATION = 1<<10,
861}; 861};
862 862
863/** 863/**
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index cdfe473181af..c4c8a33f3418 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -544,6 +544,7 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
544 C(truesize); 544 C(truesize);
545#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) 545#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
546 C(do_not_encrypt); 546 C(do_not_encrypt);
547 C(requeue);
547#endif 548#endif
548 atomic_set(&n->users, 1); 549 atomic_set(&n->users, 1);
549 550
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();