aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-03-23 12:28:36 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-03-27 20:13:21 -0400
commitf0e72851f7ad108fed20426b46a18ab5fcd5729f (patch)
tree5e8d1795fa06127f9c9ae9755140eb0d871ae2f9 /net/mac80211/tx.c
parent2de8e0d999b8790861cd3749bec2236ccc1c8110 (diff)
mac80211: fix A-MPDU queue assignment
Internally, mac80211 requires the skb's queue mapping to be set to the AC queue, not the virtual A-MPDU queue. This is not done correctly currently, this patch moves the code down to directly before the driver is invoked and adds a comment that it will be moved into the driver later. Since this requires __ieee80211_tx() to have the sta pointer, make sure to provide it in ieee80211_tx_pending(). Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Reviewed-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 51bf49cc75bc..0d97cad84b1b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1024,13 +1024,8 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1024 1024
1025 spin_lock_irqsave(&tx->sta->lock, flags); 1025 spin_lock_irqsave(&tx->sta->lock, flags);
1026 state = &tx->sta->ampdu_mlme.tid_state_tx[tid]; 1026 state = &tx->sta->ampdu_mlme.tid_state_tx[tid];
1027 if (*state == HT_AGG_STATE_OPERATIONAL) { 1027 if (*state == HT_AGG_STATE_OPERATIONAL)
1028 info->flags |= IEEE80211_TX_CTL_AMPDU; 1028 info->flags |= IEEE80211_TX_CTL_AMPDU;
1029 if (local->hw.ampdu_queues)
1030 skb_set_queue_mapping(
1031 skb, tx->local->hw.queues +
1032 tx->sta->tid_to_tx_q[tid]);
1033 }
1034 spin_unlock_irqrestore(&tx->sta->lock, flags); 1029 spin_unlock_irqrestore(&tx->sta->lock, flags);
1035 } 1030 }
1036 1031
@@ -1103,10 +1098,29 @@ static int __ieee80211_tx(struct ieee80211_local *local,
1103 skb_get_queue_mapping(skb))) 1098 skb_get_queue_mapping(skb)))
1104 return IEEE80211_TX_PENDING; 1099 return IEEE80211_TX_PENDING;
1105 1100
1106 if (fragm) { 1101 info = IEEE80211_SKB_CB(skb);
1107 info = IEEE80211_SKB_CB(skb); 1102
1103 if (fragm)
1108 info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT | 1104 info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT |
1109 IEEE80211_TX_CTL_FIRST_FRAGMENT); 1105 IEEE80211_TX_CTL_FIRST_FRAGMENT);
1106
1107 /*
1108 * Internally, we need to have the queue mapping point to
1109 * the real AC queue, not the virtual A-MPDU queue. This
1110 * now finally sets the queue to what the driver wants.
1111 * We will later move this down into the only driver that
1112 * needs it, iwlwifi.
1113 */
1114 if (tx->sta && local->hw.ampdu_queues &&
1115 info->flags & IEEE80211_TX_CTL_AMPDU) {
1116 unsigned long flags;
1117 u8 *qc = ieee80211_get_qos_ctl((void *) skb->data);
1118 int tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
1119
1120 spin_lock_irqsave(&tx->sta->lock, flags);
1121 skb_set_queue_mapping(skb, local->hw.queues +
1122 tx->sta->tid_to_tx_q[tid]);
1123 spin_unlock_irqrestore(&tx->sta->lock, flags);
1110 } 1124 }
1111 1125
1112 next = skb->next; 1126 next = skb->next;
@@ -1817,9 +1831,11 @@ void ieee80211_tx_pending(unsigned long data)
1817 struct ieee80211_local *local = (struct ieee80211_local *)data; 1831 struct ieee80211_local *local = (struct ieee80211_local *)data;
1818 struct net_device *dev = local->mdev; 1832 struct net_device *dev = local->mdev;
1819 struct ieee80211_tx_stored_packet *store; 1833 struct ieee80211_tx_stored_packet *store;
1834 struct ieee80211_hdr *hdr;
1820 struct ieee80211_tx_data tx; 1835 struct ieee80211_tx_data tx;
1821 int i, ret; 1836 int i, ret;
1822 1837
1838 rcu_read_lock();
1823 netif_tx_lock_bh(dev); 1839 netif_tx_lock_bh(dev);
1824 for (i = 0; i < local->hw.queues; i++) { 1840 for (i = 0; i < local->hw.queues; i++) {
1825 /* Check that this queue is ok */ 1841 /* Check that this queue is ok */
@@ -1839,6 +1855,8 @@ void ieee80211_tx_pending(unsigned long data)
1839 store = &local->pending_packet[i]; 1855 store = &local->pending_packet[i];
1840 tx.flags = 0; 1856 tx.flags = 0;
1841 tx.skb = store->skb; 1857 tx.skb = store->skb;
1858 hdr = (struct ieee80211_hdr *)tx.skb->data;
1859 tx.sta = sta_info_get(local, hdr->addr1);
1842 ret = __ieee80211_tx(local, &tx); 1860 ret = __ieee80211_tx(local, &tx);
1843 store->skb = tx.skb; 1861 store->skb = tx.skb;
1844 if (!ret) { 1862 if (!ret) {
@@ -1847,6 +1865,7 @@ void ieee80211_tx_pending(unsigned long data)
1847 } 1865 }
1848 } 1866 }
1849 netif_tx_unlock_bh(dev); 1867 netif_tx_unlock_bh(dev);
1868 rcu_read_unlock();
1850} 1869}
1851 1870
1852/* functions for drivers to get certain frames */ 1871/* functions for drivers to get certain frames */