summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/agg-tx.c8
-rw-r--r--net/mac80211/ieee80211_i.h24
-rw-r--r--net/mac80211/iface.c12
-rw-r--r--net/mac80211/main.c7
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/sta_info.c14
-rw-r--r--net/mac80211/tx.c136
-rw-r--r--net/mac80211/util.c23
8 files changed, 162 insertions, 64 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 42fa81031dfa..5650c46bf91a 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -194,17 +194,21 @@ static void
194ieee80211_agg_stop_txq(struct sta_info *sta, int tid) 194ieee80211_agg_stop_txq(struct sta_info *sta, int tid)
195{ 195{
196 struct ieee80211_txq *txq = sta->sta.txq[tid]; 196 struct ieee80211_txq *txq = sta->sta.txq[tid];
197 struct ieee80211_sub_if_data *sdata;
198 struct fq *fq;
197 struct txq_info *txqi; 199 struct txq_info *txqi;
198 200
199 if (!txq) 201 if (!txq)
200 return; 202 return;
201 203
202 txqi = to_txq_info(txq); 204 txqi = to_txq_info(txq);
205 sdata = vif_to_sdata(txq->vif);
206 fq = &sdata->local->fq;
203 207
204 /* Lock here to protect against further seqno updates on dequeue */ 208 /* Lock here to protect against further seqno updates on dequeue */
205 spin_lock_bh(&txqi->queue.lock); 209 spin_lock_bh(&fq->lock);
206 set_bit(IEEE80211_TXQ_STOP, &txqi->flags); 210 set_bit(IEEE80211_TXQ_STOP, &txqi->flags);
207 spin_unlock_bh(&txqi->queue.lock); 211 spin_unlock_bh(&fq->lock);
208} 212}
209 213
210static void 214static void
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 634603320374..6f8375f1df88 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -30,6 +30,7 @@
30#include <net/ieee80211_radiotap.h> 30#include <net/ieee80211_radiotap.h>
31#include <net/cfg80211.h> 31#include <net/cfg80211.h>
32#include <net/mac80211.h> 32#include <net/mac80211.h>
33#include <net/fq.h>
33#include "key.h" 34#include "key.h"
34#include "sta_info.h" 35#include "sta_info.h"
35#include "debug.h" 36#include "debug.h"
@@ -805,10 +806,17 @@ enum txq_info_flags {
805 IEEE80211_TXQ_NO_AMSDU, 806 IEEE80211_TXQ_NO_AMSDU,
806}; 807};
807 808
809/**
810 * struct txq_info - per tid queue
811 *
812 * @tin: contains packets split into multiple flows
813 * @def_flow: used as a fallback flow when a packet destined to @tin hashes to
814 * a fq_flow which is already owned by a different tin
815 */
808struct txq_info { 816struct txq_info {
809 struct sk_buff_head queue; 817 struct fq_tin tin;
818 struct fq_flow def_flow;
810 unsigned long flags; 819 unsigned long flags;
811 unsigned long byte_cnt;
812 820
813 /* keep last! */ 821 /* keep last! */
814 struct ieee80211_txq txq; 822 struct ieee80211_txq txq;
@@ -1099,6 +1107,8 @@ struct ieee80211_local {
1099 * it first anyway so they become a no-op */ 1107 * it first anyway so they become a no-op */
1100 struct ieee80211_hw hw; 1108 struct ieee80211_hw hw;
1101 1109
1110 struct fq fq;
1111
1102 const struct ieee80211_ops *ops; 1112 const struct ieee80211_ops *ops;
1103 1113
1104 /* 1114 /*
@@ -1931,9 +1941,13 @@ static inline bool ieee80211_can_run_worker(struct ieee80211_local *local)
1931 return true; 1941 return true;
1932} 1942}
1933 1943
1934void ieee80211_init_tx_queue(struct ieee80211_sub_if_data *sdata, 1944int ieee80211_txq_setup_flows(struct ieee80211_local *local);
1935 struct sta_info *sta, 1945void ieee80211_txq_teardown_flows(struct ieee80211_local *local);
1936 struct txq_info *txq, int tid); 1946void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
1947 struct sta_info *sta,
1948 struct txq_info *txq, int tid);
1949void ieee80211_txq_purge(struct ieee80211_local *local,
1950 struct txq_info *txqi);
1937void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 1951void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1938 u16 transaction, u16 auth_alg, u16 status, 1952 u16 transaction, u16 auth_alg, u16 status,
1939 const u8 *extra, size_t extra_len, const u8 *bssid, 1953 const u8 *extra, size_t extra_len, const u8 *bssid,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 609c5174d798..b123a9e325b3 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -779,6 +779,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
779 bool going_down) 779 bool going_down)
780{ 780{
781 struct ieee80211_local *local = sdata->local; 781 struct ieee80211_local *local = sdata->local;
782 struct fq *fq = &local->fq;
782 unsigned long flags; 783 unsigned long flags;
783 struct sk_buff *skb, *tmp; 784 struct sk_buff *skb, *tmp;
784 u32 hw_reconf_flags = 0; 785 u32 hw_reconf_flags = 0;
@@ -976,13 +977,10 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
976 977
977 if (sdata->vif.txq) { 978 if (sdata->vif.txq) {
978 struct txq_info *txqi = to_txq_info(sdata->vif.txq); 979 struct txq_info *txqi = to_txq_info(sdata->vif.txq);
979 int n = skb_queue_len(&txqi->queue);
980 980
981 spin_lock_bh(&txqi->queue.lock); 981 spin_lock_bh(&fq->lock);
982 ieee80211_purge_tx_queue(&local->hw, &txqi->queue); 982 ieee80211_txq_purge(local, txqi);
983 atomic_sub(n, &sdata->num_tx_queued); 983 spin_unlock_bh(&fq->lock);
984 txqi->byte_cnt = 0;
985 spin_unlock_bh(&txqi->queue.lock);
986 } 984 }
987 985
988 if (local->open_count == 0) 986 if (local->open_count == 0)
@@ -1792,7 +1790,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1792 1790
1793 if (txq_size) { 1791 if (txq_size) {
1794 txqi = netdev_priv(ndev) + size; 1792 txqi = netdev_priv(ndev) + size;
1795 ieee80211_init_tx_queue(sdata, NULL, txqi, 0); 1793 ieee80211_txq_init(sdata, NULL, txqi, 0);
1796 } 1794 }
1797 1795
1798 sdata->dev = ndev; 1796 sdata->dev = ndev;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 160ac6b8b9a1..d00ea9b13f49 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1086,6 +1086,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1086 1086
1087 rtnl_unlock(); 1087 rtnl_unlock();
1088 1088
1089 result = ieee80211_txq_setup_flows(local);
1090 if (result)
1091 goto fail_flows;
1092
1089#ifdef CONFIG_INET 1093#ifdef CONFIG_INET
1090 local->ifa_notifier.notifier_call = ieee80211_ifa_changed; 1094 local->ifa_notifier.notifier_call = ieee80211_ifa_changed;
1091 result = register_inetaddr_notifier(&local->ifa_notifier); 1095 result = register_inetaddr_notifier(&local->ifa_notifier);
@@ -1111,6 +1115,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1111#if defined(CONFIG_INET) || defined(CONFIG_IPV6) 1115#if defined(CONFIG_INET) || defined(CONFIG_IPV6)
1112 fail_ifa: 1116 fail_ifa:
1113#endif 1117#endif
1118 ieee80211_txq_teardown_flows(local);
1119 fail_flows:
1114 rtnl_lock(); 1120 rtnl_lock();
1115 rate_control_deinitialize(local); 1121 rate_control_deinitialize(local);
1116 ieee80211_remove_interfaces(local); 1122 ieee80211_remove_interfaces(local);
@@ -1169,6 +1175,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1169 skb_queue_purge(&local->skb_queue); 1175 skb_queue_purge(&local->skb_queue);
1170 skb_queue_purge(&local->skb_queue_unreliable); 1176 skb_queue_purge(&local->skb_queue_unreliable);
1171 skb_queue_purge(&local->skb_queue_tdls_chsw); 1177 skb_queue_purge(&local->skb_queue_tdls_chsw);
1178 ieee80211_txq_teardown_flows(local);
1172 1179
1173 destroy_workqueue(local->workqueue); 1180 destroy_workqueue(local->workqueue);
1174 wiphy_unregister(local->hw.wiphy); 1181 wiphy_unregister(local->hw.wiphy);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5e65e838992a..9a1eb70cb120 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1268,7 +1268,7 @@ static void sta_ps_start(struct sta_info *sta)
1268 for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { 1268 for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) {
1269 struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]); 1269 struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]);
1270 1270
1271 if (!skb_queue_len(&txqi->queue)) 1271 if (!txqi->tin.backlog_packets)
1272 set_bit(tid, &sta->txq_buffered_tids); 1272 set_bit(tid, &sta->txq_buffered_tids);
1273 else 1273 else
1274 clear_bit(tid, &sta->txq_buffered_tids); 1274 clear_bit(tid, &sta->txq_buffered_tids);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 177cc6cd6416..76b737dcc36f 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -90,6 +90,7 @@ static void __cleanup_single_sta(struct sta_info *sta)
90 struct tid_ampdu_tx *tid_tx; 90 struct tid_ampdu_tx *tid_tx;
91 struct ieee80211_sub_if_data *sdata = sta->sdata; 91 struct ieee80211_sub_if_data *sdata = sta->sdata;
92 struct ieee80211_local *local = sdata->local; 92 struct ieee80211_local *local = sdata->local;
93 struct fq *fq = &local->fq;
93 struct ps_data *ps; 94 struct ps_data *ps;
94 95
95 if (test_sta_flag(sta, WLAN_STA_PS_STA) || 96 if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
@@ -113,11 +114,10 @@ static void __cleanup_single_sta(struct sta_info *sta)
113 if (sta->sta.txq[0]) { 114 if (sta->sta.txq[0]) {
114 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { 115 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
115 struct txq_info *txqi = to_txq_info(sta->sta.txq[i]); 116 struct txq_info *txqi = to_txq_info(sta->sta.txq[i]);
116 int n = skb_queue_len(&txqi->queue);
117 117
118 ieee80211_purge_tx_queue(&local->hw, &txqi->queue); 118 spin_lock_bh(&fq->lock);
119 atomic_sub(n, &sdata->num_tx_queued); 119 ieee80211_txq_purge(local, txqi);
120 txqi->byte_cnt = 0; 120 spin_unlock_bh(&fq->lock);
121 } 121 }
122 } 122 }
123 123
@@ -368,7 +368,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
368 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { 368 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
369 struct txq_info *txq = txq_data + i * size; 369 struct txq_info *txq = txq_data + i * size;
370 370
371 ieee80211_init_tx_queue(sdata, sta, txq, i); 371 ieee80211_txq_init(sdata, sta, txq, i);
372 } 372 }
373 } 373 }
374 374
@@ -1211,7 +1211,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
1211 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { 1211 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
1212 struct txq_info *txqi = to_txq_info(sta->sta.txq[i]); 1212 struct txq_info *txqi = to_txq_info(sta->sta.txq[i]);
1213 1213
1214 if (!skb_queue_len(&txqi->queue)) 1214 if (!txqi->tin.backlog_packets)
1215 continue; 1215 continue;
1216 1216
1217 drv_wake_tx_queue(local, txqi); 1217 drv_wake_tx_queue(local, txqi);
@@ -1648,7 +1648,7 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
1648 for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { 1648 for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) {
1649 struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]); 1649 struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]);
1650 1650
1651 if (!(tids & BIT(tid)) || skb_queue_len(&txqi->queue)) 1651 if (!(tids & BIT(tid)) || txqi->tin.backlog_packets)
1652 continue; 1652 continue;
1653 1653
1654 sta_info_recalc_tim(sta); 1654 sta_info_recalc_tim(sta);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3e77da195ce8..1d8343fca6d4 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -25,6 +25,7 @@
25#include <net/cfg80211.h> 25#include <net/cfg80211.h>
26#include <net/mac80211.h> 26#include <net/mac80211.h>
27#include <asm/unaligned.h> 27#include <asm/unaligned.h>
28#include <net/fq_impl.h>
28 29
29#include "ieee80211_i.h" 30#include "ieee80211_i.h"
30#include "driver-ops.h" 31#include "driver-ops.h"
@@ -1266,46 +1267,121 @@ static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local,
1266 return to_txq_info(txq); 1267 return to_txq_info(txq);
1267} 1268}
1268 1269
1270static struct sk_buff *fq_tin_dequeue_func(struct fq *fq,
1271 struct fq_tin *tin,
1272 struct fq_flow *flow)
1273{
1274 return fq_flow_dequeue(fq, flow);
1275}
1276
1277static void fq_skb_free_func(struct fq *fq,
1278 struct fq_tin *tin,
1279 struct fq_flow *flow,
1280 struct sk_buff *skb)
1281{
1282 struct ieee80211_local *local;
1283
1284 local = container_of(fq, struct ieee80211_local, fq);
1285 ieee80211_free_txskb(&local->hw, skb);
1286}
1287
1288static struct fq_flow *fq_flow_get_default_func(struct fq *fq,
1289 struct fq_tin *tin,
1290 int idx,
1291 struct sk_buff *skb)
1292{
1293 struct txq_info *txqi;
1294
1295 txqi = container_of(tin, struct txq_info, tin);
1296 return &txqi->def_flow;
1297}
1298
1269static void ieee80211_txq_enqueue(struct ieee80211_local *local, 1299static void ieee80211_txq_enqueue(struct ieee80211_local *local,
1270 struct txq_info *txqi, 1300 struct txq_info *txqi,
1271 struct sk_buff *skb) 1301 struct sk_buff *skb)
1272{ 1302{
1273 struct ieee80211_sub_if_data *sdata = vif_to_sdata(txqi->txq.vif); 1303 struct fq *fq = &local->fq;
1304 struct fq_tin *tin = &txqi->tin;
1274 1305
1275 lockdep_assert_held(&txqi->queue.lock); 1306 fq_tin_enqueue(fq, tin, skb,
1307 fq_skb_free_func,
1308 fq_flow_get_default_func);
1309}
1276 1310
1277 if (atomic_read(&sdata->num_tx_queued) >= TOTAL_MAX_TX_BUFFER || 1311void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
1278 txqi->queue.qlen >= STA_MAX_TX_BUFFER) { 1312 struct sta_info *sta,
1279 ieee80211_free_txskb(&local->hw, skb); 1313 struct txq_info *txqi, int tid)
1280 return; 1314{
1315 fq_tin_init(&txqi->tin);
1316 fq_flow_init(&txqi->def_flow);
1317
1318 txqi->txq.vif = &sdata->vif;
1319
1320 if (sta) {
1321 txqi->txq.sta = &sta->sta;
1322 sta->sta.txq[tid] = &txqi->txq;
1323 txqi->txq.tid = tid;
1324 txqi->txq.ac = ieee802_1d_to_ac[tid & 7];
1325 } else {
1326 sdata->vif.txq = &txqi->txq;
1327 txqi->txq.tid = 0;
1328 txqi->txq.ac = IEEE80211_AC_BE;
1281 } 1329 }
1330}
1282 1331
1283 atomic_inc(&sdata->num_tx_queued); 1332void ieee80211_txq_purge(struct ieee80211_local *local,
1284 txqi->byte_cnt += skb->len; 1333 struct txq_info *txqi)
1285 __skb_queue_tail(&txqi->queue, skb); 1334{
1335 struct fq *fq = &local->fq;
1336 struct fq_tin *tin = &txqi->tin;
1337
1338 fq_tin_reset(fq, tin, fq_skb_free_func);
1339}
1340
1341int ieee80211_txq_setup_flows(struct ieee80211_local *local)
1342{
1343 struct fq *fq = &local->fq;
1344 int ret;
1345
1346 if (!local->ops->wake_tx_queue)
1347 return 0;
1348
1349 ret = fq_init(fq, 4096);
1350 if (ret)
1351 return ret;
1352
1353 return 0;
1354}
1355
1356void ieee80211_txq_teardown_flows(struct ieee80211_local *local)
1357{
1358 struct fq *fq = &local->fq;
1359
1360 if (!local->ops->wake_tx_queue)
1361 return;
1362
1363 fq_reset(fq, fq_skb_free_func);
1286} 1364}
1287 1365
1288struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, 1366struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
1289 struct ieee80211_txq *txq) 1367 struct ieee80211_txq *txq)
1290{ 1368{
1291 struct ieee80211_local *local = hw_to_local(hw); 1369 struct ieee80211_local *local = hw_to_local(hw);
1292 struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif);
1293 struct txq_info *txqi = container_of(txq, struct txq_info, txq); 1370 struct txq_info *txqi = container_of(txq, struct txq_info, txq);
1294 struct ieee80211_hdr *hdr; 1371 struct ieee80211_hdr *hdr;
1295 struct sk_buff *skb = NULL; 1372 struct sk_buff *skb = NULL;
1373 struct fq *fq = &local->fq;
1374 struct fq_tin *tin = &txqi->tin;
1296 1375
1297 spin_lock_bh(&txqi->queue.lock); 1376 spin_lock_bh(&fq->lock);
1298 1377
1299 if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags)) 1378 if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags))
1300 goto out; 1379 goto out;
1301 1380
1302 skb = __skb_dequeue(&txqi->queue); 1381 skb = fq_tin_dequeue(fq, tin, fq_tin_dequeue_func);
1303 if (!skb) 1382 if (!skb)
1304 goto out; 1383 goto out;
1305 1384
1306 atomic_dec(&sdata->num_tx_queued);
1307 txqi->byte_cnt -= skb->len;
1308
1309 hdr = (struct ieee80211_hdr *)skb->data; 1385 hdr = (struct ieee80211_hdr *)skb->data;
1310 if (txq->sta && ieee80211_is_data_qos(hdr->frame_control)) { 1386 if (txq->sta && ieee80211_is_data_qos(hdr->frame_control)) {
1311 struct sta_info *sta = container_of(txq->sta, struct sta_info, 1387 struct sta_info *sta = container_of(txq->sta, struct sta_info,
@@ -1320,7 +1396,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
1320 } 1396 }
1321 1397
1322out: 1398out:
1323 spin_unlock_bh(&txqi->queue.lock); 1399 spin_unlock_bh(&fq->lock);
1324 1400
1325 if (skb && skb_has_frag_list(skb) && 1401 if (skb && skb_has_frag_list(skb) &&
1326 !ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) 1402 !ieee80211_hw_check(&local->hw, TX_FRAG_LIST))
@@ -1337,6 +1413,7 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
1337 bool txpending) 1413 bool txpending)
1338{ 1414{
1339 struct ieee80211_tx_control control = {}; 1415 struct ieee80211_tx_control control = {};
1416 struct fq *fq = &local->fq;
1340 struct sk_buff *skb, *tmp; 1417 struct sk_buff *skb, *tmp;
1341 struct txq_info *txqi; 1418 struct txq_info *txqi;
1342 unsigned long flags; 1419 unsigned long flags;
@@ -1359,9 +1436,9 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
1359 1436
1360 __skb_unlink(skb, skbs); 1437 __skb_unlink(skb, skbs);
1361 1438
1362 spin_lock_bh(&txqi->queue.lock); 1439 spin_lock_bh(&fq->lock);
1363 ieee80211_txq_enqueue(local, txqi, skb); 1440 ieee80211_txq_enqueue(local, txqi, skb);
1364 spin_unlock_bh(&txqi->queue.lock); 1441 spin_unlock_bh(&fq->lock);
1365 1442
1366 drv_wake_tx_queue(local, txqi); 1443 drv_wake_tx_queue(local, txqi);
1367 1444
@@ -2893,6 +2970,9 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
2893 struct sk_buff *skb) 2970 struct sk_buff *skb)
2894{ 2971{
2895 struct ieee80211_local *local = sdata->local; 2972 struct ieee80211_local *local = sdata->local;
2973 struct fq *fq = &local->fq;
2974 struct fq_tin *tin;
2975 struct fq_flow *flow;
2896 u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; 2976 u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
2897 struct ieee80211_txq *txq = sta->sta.txq[tid]; 2977 struct ieee80211_txq *txq = sta->sta.txq[tid];
2898 struct txq_info *txqi; 2978 struct txq_info *txqi;
@@ -2904,6 +2984,7 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
2904 __be16 len; 2984 __be16 len;
2905 void *data; 2985 void *data;
2906 bool ret = false; 2986 bool ret = false;
2987 unsigned int orig_len;
2907 int n = 1, nfrags; 2988 int n = 1, nfrags;
2908 2989
2909 if (!ieee80211_hw_check(&local->hw, TX_AMSDU)) 2990 if (!ieee80211_hw_check(&local->hw, TX_AMSDU))
@@ -2920,12 +3001,20 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
2920 max_amsdu_len = min_t(int, max_amsdu_len, 3001 max_amsdu_len = min_t(int, max_amsdu_len,
2921 sta->sta.max_rc_amsdu_len); 3002 sta->sta.max_rc_amsdu_len);
2922 3003
2923 spin_lock_bh(&txqi->queue.lock); 3004 spin_lock_bh(&fq->lock);
2924 3005
2925 head = skb_peek_tail(&txqi->queue); 3006 /* TODO: Ideally aggregation should be done on dequeue to remain
3007 * responsive to environment changes.
3008 */
3009
3010 tin = &txqi->tin;
3011 flow = fq_flow_classify(fq, tin, skb, fq_flow_get_default_func);
3012 head = skb_peek_tail(&flow->queue);
2926 if (!head) 3013 if (!head)
2927 goto out; 3014 goto out;
2928 3015
3016 orig_len = head->len;
3017
2929 if (skb->len + head->len > max_amsdu_len) 3018 if (skb->len + head->len > max_amsdu_len)
2930 goto out; 3019 goto out;
2931 3020
@@ -2964,8 +3053,13 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
2964 head->data_len += skb->len; 3053 head->data_len += skb->len;
2965 *frag_tail = skb; 3054 *frag_tail = skb;
2966 3055
3056 flow->backlog += head->len - orig_len;
3057 tin->backlog_bytes += head->len - orig_len;
3058
3059 fq_recalc_backlog(fq, tin, flow);
3060
2967out: 3061out:
2968 spin_unlock_bh(&txqi->queue.lock); 3062 spin_unlock_bh(&fq->lock);
2969 3063
2970 return ret; 3064 return ret;
2971} 3065}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 0db46442bdcf..42bf0b6685e8 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -3389,25 +3389,6 @@ u8 *ieee80211_add_wmm_info_ie(u8 *buf, u8 qosinfo)
3389 return buf; 3389 return buf;
3390} 3390}
3391 3391
3392void ieee80211_init_tx_queue(struct ieee80211_sub_if_data *sdata,
3393 struct sta_info *sta,
3394 struct txq_info *txqi, int tid)
3395{
3396 skb_queue_head_init(&txqi->queue);
3397 txqi->txq.vif = &sdata->vif;
3398
3399 if (sta) {
3400 txqi->txq.sta = &sta->sta;
3401 sta->sta.txq[tid] = &txqi->txq;
3402 txqi->txq.tid = tid;
3403 txqi->txq.ac = ieee802_1d_to_ac[tid & 7];
3404 } else {
3405 sdata->vif.txq = &txqi->txq;
3406 txqi->txq.tid = 0;
3407 txqi->txq.ac = IEEE80211_AC_BE;
3408 }
3409}
3410
3411void ieee80211_txq_get_depth(struct ieee80211_txq *txq, 3392void ieee80211_txq_get_depth(struct ieee80211_txq *txq,
3412 unsigned long *frame_cnt, 3393 unsigned long *frame_cnt,
3413 unsigned long *byte_cnt) 3394 unsigned long *byte_cnt)
@@ -3415,9 +3396,9 @@ void ieee80211_txq_get_depth(struct ieee80211_txq *txq,
3415 struct txq_info *txqi = to_txq_info(txq); 3396 struct txq_info *txqi = to_txq_info(txq);
3416 3397
3417 if (frame_cnt) 3398 if (frame_cnt)
3418 *frame_cnt = txqi->queue.qlen; 3399 *frame_cnt = txqi->tin.backlog_packets;
3419 3400
3420 if (byte_cnt) 3401 if (byte_cnt)
3421 *byte_cnt = txqi->byte_cnt; 3402 *byte_cnt = txqi->tin.backlog_bytes;
3422} 3403}
3423EXPORT_SYMBOL(ieee80211_txq_get_depth); 3404EXPORT_SYMBOL(ieee80211_txq_get_depth);