Commit f0e72851f7ad108fed20426b46a18ab5fcd5729f

Authored by Johannes Berg
Committed by John W. Linville
1 parent 2de8e0d999

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>

Showing 1 changed file with 27 additions and 8 deletions Side-by-side Diff

... ... @@ -1024,13 +1024,8 @@
1024 1024  
1025 1025 spin_lock_irqsave(&tx->sta->lock, flags);
1026 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 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 1029 spin_unlock_irqrestore(&tx->sta->lock, flags);
1035 1030 }
1036 1031  
1037 1032  
... ... @@ -1103,10 +1098,29 @@
1103 1098 skb_get_queue_mapping(skb)))
1104 1099 return IEEE80211_TX_PENDING;
1105 1100  
1106   - if (fragm) {
1107   - info = IEEE80211_SKB_CB(skb);
  1101 + info = IEEE80211_SKB_CB(skb);
  1102 +
  1103 + if (fragm)
1108 1104 info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT |
1109 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 1126 next = skb->next;
1113 1127  
... ... @@ -1817,9 +1831,11 @@
1817 1831 struct ieee80211_local *local = (struct ieee80211_local *)data;
1818 1832 struct net_device *dev = local->mdev;
1819 1833 struct ieee80211_tx_stored_packet *store;
  1834 + struct ieee80211_hdr *hdr;
1820 1835 struct ieee80211_tx_data tx;
1821 1836 int i, ret;
1822 1837  
  1838 + rcu_read_lock();
1823 1839 netif_tx_lock_bh(dev);
1824 1840 for (i = 0; i < local->hw.queues; i++) {
1825 1841 /* Check that this queue is ok */
... ... @@ -1839,6 +1855,8 @@
1839 1855 store = &local->pending_packet[i];
1840 1856 tx.flags = 0;
1841 1857 tx.skb = store->skb;
  1858 + hdr = (struct ieee80211_hdr *)tx.skb->data;
  1859 + tx.sta = sta_info_get(local, hdr->addr1);
1842 1860 ret = __ieee80211_tx(local, &tx);
1843 1861 store->skb = tx.skb;
1844 1862 if (!ret) {
... ... @@ -1847,6 +1865,7 @@
1847 1865 }
1848 1866 }
1849 1867 netif_tx_unlock_bh(dev);
  1868 + rcu_read_unlock();
1850 1869 }
1851 1870  
1852 1871 /* functions for drivers to get certain frames */