aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h52
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c2
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c1
-rw-r--r--include/net/mac80211.h14
-rw-r--r--net/mac80211/agg-tx.c44
-rw-r--r--net/mac80211/ieee80211_i.h7
-rw-r--r--net/mac80211/main.c9
-rw-r--r--net/mac80211/sta_info.c12
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/tx.c19
-rw-r--r--net/mac80211/util.c58
17 files changed, 84 insertions, 169 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index d03f5534afee..2399328e8de7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -293,7 +293,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
293 if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && 293 if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
294 (txq_id != IWL_CMD_QUEUE_NUM) && 294 (txq_id != IWL_CMD_QUEUE_NUM) &&
295 priv->mac80211_registered) 295 priv->mac80211_registered)
296 ieee80211_wake_queue(priv->hw, txq_id); 296 iwl_wake_queue(priv, txq_id);
297} 297}
298 298
299/** 299/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index bd0140be774e..847a6220c5e6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2178,10 +2178,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2178 (iwl_queue_space(&txq->q) > txq->q.low_mark) && 2178 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
2179 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) { 2179 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
2180 if (agg->state == IWL_AGG_OFF) 2180 if (agg->state == IWL_AGG_OFF)
2181 ieee80211_wake_queue(priv->hw, txq_id); 2181 iwl_wake_queue(priv, txq_id);
2182 else 2182 else
2183 ieee80211_wake_queue(priv->hw, 2183 iwl_wake_queue(priv, txq->swq_id);
2184 txq->swq_id);
2185 } 2184 }
2186 } 2185 }
2187 } else { 2186 } else {
@@ -2205,7 +2204,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2205 2204
2206 if (priv->mac80211_registered && 2205 if (priv->mac80211_registered &&
2207 (iwl_queue_space(&txq->q) > txq->q.low_mark)) 2206 (iwl_queue_space(&txq->q) > txq->q.low_mark))
2208 ieee80211_wake_queue(priv->hw, txq_id); 2207 iwl_wake_queue(priv, txq_id);
2209 } 2208 }
2210 2209
2211 if (qc && likely(sta_id != IWL_INVALID_STATION)) 2210 if (qc && likely(sta_id != IWL_INVALID_STATION))
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index a3d9a95a9b37..e5ca2511a81a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1295,10 +1295,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1295 (iwl_queue_space(&txq->q) > txq->q.low_mark) && 1295 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1296 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) { 1296 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
1297 if (agg->state == IWL_AGG_OFF) 1297 if (agg->state == IWL_AGG_OFF)
1298 ieee80211_wake_queue(priv->hw, txq_id); 1298 iwl_wake_queue(priv, txq_id);
1299 else 1299 else
1300 ieee80211_wake_queue(priv->hw, 1300 iwl_wake_queue(priv, txq->swq_id);
1301 txq->swq_id);
1302 } 1301 }
1303 } 1302 }
1304 } else { 1303 } else {
@@ -1324,7 +1323,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1324 1323
1325 if (priv->mac80211_registered && 1324 if (priv->mac80211_registered &&
1326 (iwl_queue_space(&txq->q) > txq->q.low_mark)) 1325 (iwl_queue_space(&txq->q) > txq->q.low_mark))
1327 ieee80211_wake_queue(priv->hw, txq_id); 1326 iwl_wake_queue(priv, txq_id);
1328 } 1327 }
1329 1328
1330 if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) 1329 if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 4b1298c2b0da..c54fb93e9d72 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1309,9 +1309,6 @@ int iwl_setup_mac(struct iwl_priv *priv)
1309 1309
1310 /* Default value; 4 EDCA QOS priorities */ 1310 /* Default value; 4 EDCA QOS priorities */
1311 hw->queues = 4; 1311 hw->queues = 4;
1312 /* queues to support 11n aggregation */
1313 if (priv->cfg->sku & IWL_SKU_N)
1314 hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues;
1315 1312
1316 hw->conf.beacon_int = 100; 1313 hw->conf.beacon_int = 100;
1317 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; 1314 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 0baae8022824..ec9a13846edd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -996,6 +996,12 @@ struct iwl_priv {
996 u8 key_mapping_key; 996 u8 key_mapping_key;
997 unsigned long ucode_key_table; 997 unsigned long ucode_key_table;
998 998
999 /* queue refcounts */
1000#define IWL_MAX_HW_QUEUES 32
1001 unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)];
1002 /* for each AC */
1003 atomic_t queue_stop_count[4];
1004
999 /* Indication if ieee80211_ops->open has been called */ 1005 /* Indication if ieee80211_ops->open has been called */
1000 u8 is_open; 1006 u8 is_open;
1001 1007
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index fb64d297dd4e..a1328c3c81ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -93,4 +93,56 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
93 return (desc->v_addr != NULL) ? 0 : -ENOMEM; 93 return (desc->v_addr != NULL) ? 0 : -ENOMEM;
94} 94}
95 95
96/*
97 * we have 8 bits used like this:
98 *
99 * 7 6 5 4 3 2 1 0
100 * | | | | | | | |
101 * | | | | | | +-+-------- AC queue (0-3)
102 * | | | | | |
103 * | +-+-+-+-+------------ HW A-MPDU queue
104 * |
105 * +---------------------- indicates agg queue
106 */
107static inline u8 iwl_virtual_agg_queue_num(u8 ac, u8 hwq)
108{
109 BUG_ON(ac > 3); /* only have 2 bits */
110 BUG_ON(hwq > 31); /* only have 5 bits */
111
112 return 0x80 | (hwq << 2) | ac;
113}
114
115static inline void iwl_wake_queue(struct iwl_priv *priv, u8 queue)
116{
117 u8 ac = queue;
118 u8 hwq = queue;
119
120 if (queue & 0x80) {
121 ac = queue & 3;
122 hwq = (queue >> 2) & 0x1f;
123 }
124
125 if (test_and_clear_bit(hwq, priv->queue_stopped))
126 if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0)
127 ieee80211_wake_queue(priv->hw, ac);
128}
129
130static inline void iwl_stop_queue(struct iwl_priv *priv, u8 queue)
131{
132 u8 ac = queue;
133 u8 hwq = queue;
134
135 if (queue & 0x80) {
136 ac = queue & 3;
137 hwq = (queue >> 2) & 0x1f;
138 }
139
140 if (!test_and_set_bit(hwq, priv->queue_stopped))
141 if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0)
142 ieee80211_stop_queue(priv->hw, ac);
143}
144
145#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue
146#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue
147
96#endif /* __iwl_helpers_h__ */ 148#endif /* __iwl_helpers_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index b13862a598ef..1f117a49c569 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -763,8 +763,10 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
763 hdr->seq_ctrl |= cpu_to_le16(seq_number); 763 hdr->seq_ctrl |= cpu_to_le16(seq_number);
764 seq_number += 0x10; 764 seq_number += 0x10;
765 /* aggregation is on for this <sta,tid> */ 765 /* aggregation is on for this <sta,tid> */
766 if (info->flags & IEEE80211_TX_CTL_AMPDU) 766 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
767 txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; 767 txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
768 swq_id = iwl_virtual_agg_queue_num(swq_id, txq_id);
769 }
768 priv->stations[sta_id].tid[tid].tfds_in_queue++; 770 priv->stations[sta_id].tid[tid].tfds_in_queue++;
769 } 771 }
770 772
@@ -895,7 +897,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
895 iwl_txq_update_write_ptr(priv, txq); 897 iwl_txq_update_write_ptr(priv, txq);
896 spin_unlock_irqrestore(&priv->lock, flags); 898 spin_unlock_irqrestore(&priv->lock, flags);
897 } else { 899 } else {
898 ieee80211_stop_queue(priv->hw, txq->swq_id); 900 iwl_stop_queue(priv, txq->swq_id);
899 } 901 }
900 } 902 }
901 903
@@ -1433,7 +1435,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1433 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && 1435 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1434 priv->mac80211_registered && 1436 priv->mac80211_registered &&
1435 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) 1437 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
1436 ieee80211_wake_queue(priv->hw, txq->swq_id); 1438 iwl_wake_queue(priv, txq->swq_id);
1437 1439
1438 iwl_txq_check_empty(priv, sta_id, tid, scd_flow); 1440 iwl_txq_check_empty(priv, sta_id, tid, scd_flow);
1439 } 1441 }
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index ede29b6c4dc8..a71b08ca7c71 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1168,7 +1168,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
1168 spin_unlock_irqrestore(&priv->lock, flags); 1168 spin_unlock_irqrestore(&priv->lock, flags);
1169 } 1169 }
1170 1170
1171 ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb)); 1171 iwl_stop_queue(priv, skb_get_queue_mapping(skb));
1172 } 1172 }
1173 1173
1174 return 0; 1174 return 0;
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 551161024756..d4fdc8b7d7d8 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -933,7 +933,6 @@ static int __init init_mac80211_hwsim(void)
933 BIT(NL80211_IFTYPE_STATION) | 933 BIT(NL80211_IFTYPE_STATION) |
934 BIT(NL80211_IFTYPE_AP) | 934 BIT(NL80211_IFTYPE_AP) |
935 BIT(NL80211_IFTYPE_MESH_POINT); 935 BIT(NL80211_IFTYPE_MESH_POINT);
936 hw->ampdu_queues = 1;
937 936
938 hw->flags = IEEE80211_HW_MFP_CAPABLE; 937 hw->flags = IEEE80211_HW_MFP_CAPABLE;
939 938
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 841f7f804bb6..3b83a80e3fe0 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -93,12 +93,9 @@ struct ieee80211_ht_bss_info {
93 * enum ieee80211_max_queues - maximum number of queues 93 * enum ieee80211_max_queues - maximum number of queues
94 * 94 *
95 * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues. 95 * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
96 * @IEEE80211_MAX_AMPDU_QUEUES: Maximum number of queues usable
97 * for A-MPDU operation.
98 */ 96 */
99enum ieee80211_max_queues { 97enum ieee80211_max_queues {
100 IEEE80211_MAX_QUEUES = 4, 98 IEEE80211_MAX_QUEUES = 4,
101 IEEE80211_MAX_AMPDU_QUEUES = 16,
102}; 99};
103 100
104/** 101/**
@@ -952,12 +949,6 @@ enum ieee80211_hw_flags {
952 * data packets. WMM/QoS requires at least four, these 949 * data packets. WMM/QoS requires at least four, these
953 * queues need to have configurable access parameters. 950 * queues need to have configurable access parameters.
954 * 951 *
955 * @ampdu_queues: number of available hardware transmit queues
956 * for A-MPDU packets, these have no access parameters
957 * because they're used only for A-MPDU frames. Note that
958 * mac80211 will not currently use any of the regular queues
959 * for aggregation.
960 *
961 * @rate_control_algorithm: rate control algorithm for this hardware. 952 * @rate_control_algorithm: rate control algorithm for this hardware.
962 * If unset (NULL), the default algorithm will be used. Must be 953 * If unset (NULL), the default algorithm will be used. Must be
963 * set before calling ieee80211_register_hw(). 954 * set before calling ieee80211_register_hw().
@@ -982,7 +973,6 @@ struct ieee80211_hw {
982 int vif_data_size; 973 int vif_data_size;
983 int sta_data_size; 974 int sta_data_size;
984 u16 queues; 975 u16 queues;
985 u16 ampdu_queues;
986 u16 max_listen_interval; 976 u16 max_listen_interval;
987 s8 max_signal; 977 s8 max_signal;
988 u8 max_rates; 978 u8 max_rates;
@@ -1372,8 +1362,8 @@ enum ieee80211_ampdu_mlme_action {
1372 * @get_tx_stats: Get statistics of the current TX queue status. This is used 1362 * @get_tx_stats: Get statistics of the current TX queue status. This is used
1373 * to get number of currently queued packets (queue length), maximum queue 1363 * to get number of currently queued packets (queue length), maximum queue
1374 * size (limit), and total number of packets sent using each TX queue 1364 * size (limit), and total number of packets sent using each TX queue
1375 * (count). The 'stats' pointer points to an array that has hw->queues + 1365 * (count). The 'stats' pointer points to an array that has hw->queues
1376 * hw->ampdu_queues items. 1366 * items.
1377 * 1367 *
1378 * @get_tsf: Get the current TSF timer value from firmware/hardware. Currently, 1368 * @get_tsf: Get the current TSF timer value from firmware/hardware. Currently,
1379 * this is only used for IBSS mode BSSID merging and debugging. Is not a 1369 * this is only used for IBSS mode BSSID merging and debugging. Is not a
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 64b839bfbf17..947aaaad35d2 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -131,14 +131,6 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
131 131
132 state = &sta->ampdu_mlme.tid_state_tx[tid]; 132 state = &sta->ampdu_mlme.tid_state_tx[tid];
133 133
134 if (local->hw.ampdu_queues) {
135 /*
136 * Pretend the driver woke the queue, just in case
137 * it disabled it before the session was stopped.
138 */
139 ieee80211_wake_queue(
140 &local->hw, local->hw.queues + sta->tid_to_tx_q[tid]);
141 }
142 *state = HT_AGG_STATE_REQ_STOP_BA_MSK | 134 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
143 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 135 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
144 136
@@ -206,7 +198,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
206 struct sta_info *sta; 198 struct sta_info *sta;
207 struct ieee80211_sub_if_data *sdata; 199 struct ieee80211_sub_if_data *sdata;
208 u8 *state; 200 u8 *state;
209 int i, qn = -1, ret = 0; 201 int ret = 0;
210 u16 start_seq_num; 202 u16 start_seq_num;
211 203
212 if (WARN_ON(!local->ops->ampdu_action)) 204 if (WARN_ON(!local->ops->ampdu_action))
@@ -275,29 +267,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
275 goto err_unlock_sta; 267 goto err_unlock_sta;
276 } 268 }
277 269
278 if (hw->ampdu_queues) {
279 spin_lock(&local->queue_stop_reason_lock);
280 /* reserve a new queue for this session */
281 for (i = 0; i < local->hw.ampdu_queues; i++) {
282 if (local->ampdu_ac_queue[i] < 0) {
283 qn = i;
284 local->ampdu_ac_queue[qn] =
285 ieee80211_ac_from_tid(tid);
286 break;
287 }
288 }
289 spin_unlock(&local->queue_stop_reason_lock);
290
291 if (qn < 0) {
292#ifdef CONFIG_MAC80211_HT_DEBUG
293 printk(KERN_DEBUG "BA request denied - "
294 "queue unavailable for tid %d\n", tid);
295#endif /* CONFIG_MAC80211_HT_DEBUG */
296 ret = -ENOSPC;
297 goto err_unlock_sta;
298 }
299 }
300
301 /* 270 /*
302 * While we're asking the driver about the aggregation, 271 * While we're asking the driver about the aggregation,
303 * stop the AC queue so that we don't have to worry 272 * stop the AC queue so that we don't have to worry
@@ -319,7 +288,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
319 tid); 288 tid);
320#endif 289#endif
321 ret = -ENOMEM; 290 ret = -ENOMEM;
322 goto err_return_queue; 291 goto err_wake_queue;
323 } 292 }
324 293
325 skb_queue_head_init(&sta->ampdu_mlme.tid_tx[tid]->pending); 294 skb_queue_head_init(&sta->ampdu_mlme.tid_tx[tid]->pending);
@@ -348,7 +317,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
348 *state = HT_AGG_STATE_IDLE; 317 *state = HT_AGG_STATE_IDLE;
349 goto err_free; 318 goto err_free;
350 } 319 }
351 sta->tid_to_tx_q[tid] = qn;
352 320
353 /* Driver vetoed or OKed, but we can take packets again now */ 321 /* Driver vetoed or OKed, but we can take packets again now */
354 ieee80211_wake_queue_by_reason( 322 ieee80211_wake_queue_by_reason(
@@ -380,13 +348,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
380 err_free: 348 err_free:
381 kfree(sta->ampdu_mlme.tid_tx[tid]); 349 kfree(sta->ampdu_mlme.tid_tx[tid]);
382 sta->ampdu_mlme.tid_tx[tid] = NULL; 350 sta->ampdu_mlme.tid_tx[tid] = NULL;
383 err_return_queue: 351 err_wake_queue:
384 if (qn >= 0) {
385 /* give queue back to pool */
386 spin_lock(&local->queue_stop_reason_lock);
387 local->ampdu_ac_queue[qn] = -1;
388 spin_unlock(&local->queue_stop_reason_lock);
389 }
390 ieee80211_wake_queue_by_reason( 352 ieee80211_wake_queue_by_reason(
391 &local->hw, ieee80211_ac_from_tid(tid), 353 &local->hw, ieee80211_ac_from_tid(tid),
392 IEEE80211_QUEUE_STOP_REASON_AGGREGATION); 354 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 32345b479adb..e6ed78cb16b3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -594,12 +594,7 @@ struct ieee80211_local {
594 594
595 const struct ieee80211_ops *ops; 595 const struct ieee80211_ops *ops;
596 596
597 /* AC queue corresponding to each AMPDU queue */ 597 unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
598 s8 ampdu_ac_queue[IEEE80211_MAX_AMPDU_QUEUES];
599 unsigned int amdpu_ac_stop_refcnt[IEEE80211_MAX_AMPDU_QUEUES];
600
601 unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES +
602 IEEE80211_MAX_AMPDU_QUEUES];
603 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ 598 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
604 spinlock_t queue_stop_reason_lock; 599 spinlock_t queue_stop_reason_lock;
605 600
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 756284e0bbd3..a6f1d8a869bc 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -774,11 +774,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
774 setup_timer(&local->dynamic_ps_timer, 774 setup_timer(&local->dynamic_ps_timer,
775 ieee80211_dynamic_ps_timer, (unsigned long) local); 775 ieee80211_dynamic_ps_timer, (unsigned long) local);
776 776
777 for (i = 0; i < IEEE80211_MAX_AMPDU_QUEUES; i++)
778 local->ampdu_ac_queue[i] = -1;
779 /* using an s8 won't work with more than that */
780 BUILD_BUG_ON(IEEE80211_MAX_AMPDU_QUEUES > 127);
781
782 sta_info_init(local); 777 sta_info_init(local);
783 778
784 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) 779 for (i = 0; i < IEEE80211_MAX_QUEUES; i++)
@@ -874,10 +869,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
874 */ 869 */
875 if (hw->queues > IEEE80211_MAX_QUEUES) 870 if (hw->queues > IEEE80211_MAX_QUEUES)
876 hw->queues = IEEE80211_MAX_QUEUES; 871 hw->queues = IEEE80211_MAX_QUEUES;
877 if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES)
878 hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES;
879 if (hw->queues < 4)
880 hw->ampdu_queues = 0;
881 872
882 mdev = alloc_netdev_mq(sizeof(struct ieee80211_master_priv), 873 mdev = alloc_netdev_mq(sizeof(struct ieee80211_master_priv),
883 "wmaster%d", ieee80211_master_setup, 874 "wmaster%d", ieee80211_master_setup,
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index dd3593c1fd23..c5f14e6bbde2 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -203,17 +203,6 @@ void sta_info_destroy(struct sta_info *sta)
203 if (tid_rx) 203 if (tid_rx)
204 tid_rx->shutdown = true; 204 tid_rx->shutdown = true;
205 205
206 /*
207 * The stop callback cannot find this station any more, but
208 * it didn't complete its work -- start the queue if necessary
209 */
210 if (sta->ampdu_mlme.tid_state_tx[i] & HT_AGG_STATE_INITIATOR_MSK &&
211 sta->ampdu_mlme.tid_state_tx[i] & HT_AGG_STATE_REQ_STOP_BA_MSK &&
212 local->hw.ampdu_queues)
213 ieee80211_wake_queue_by_reason(&local->hw,
214 local->hw.queues + sta->tid_to_tx_q[i],
215 IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
216
217 spin_unlock_bh(&sta->lock); 206 spin_unlock_bh(&sta->lock);
218 207
219 /* 208 /*
@@ -292,7 +281,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
292 * enable session_timer's data differentiation. refer to 281 * enable session_timer's data differentiation. refer to
293 * sta_rx_agg_session_timer_expired for useage */ 282 * sta_rx_agg_session_timer_expired for useage */
294 sta->timer_to_tid[i] = i; 283 sta->timer_to_tid[i] = i;
295 sta->tid_to_tx_q[i] = -1;
296 /* rx */ 284 /* rx */
297 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE; 285 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE;
298 sta->ampdu_mlme.tid_rx[i] = NULL; 286 sta->ampdu_mlme.tid_rx[i] = NULL;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 18fd5d1a4422..5534d489f506 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -206,7 +206,6 @@ struct sta_ampdu_mlme {
206 * @tid_seq: per-TID sequence numbers for sending to this STA 206 * @tid_seq: per-TID sequence numbers for sending to this STA
207 * @ampdu_mlme: A-MPDU state machine state 207 * @ampdu_mlme: A-MPDU state machine state
208 * @timer_to_tid: identity mapping to ID timers 208 * @timer_to_tid: identity mapping to ID timers
209 * @tid_to_tx_q: map tid to tx queue (invalid == negative values)
210 * @llid: Local link ID 209 * @llid: Local link ID
211 * @plid: Peer link ID 210 * @plid: Peer link ID
212 * @reason: Cancel reason on PLINK_HOLDING state 211 * @reason: Cancel reason on PLINK_HOLDING state
@@ -281,7 +280,6 @@ struct sta_info {
281 */ 280 */
282 struct sta_ampdu_mlme ampdu_mlme; 281 struct sta_ampdu_mlme ampdu_mlme;
283 u8 timer_to_tid[STA_TID_NUM]; 282 u8 timer_to_tid[STA_TID_NUM];
284 s8 tid_to_tx_q[STA_TID_NUM];
285 283
286#ifdef CONFIG_MAC80211_MESH 284#ifdef CONFIG_MAC80211_MESH
287 /* 285 /*
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 906ab785db40..3fb04a86444d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1145,25 +1145,6 @@ static int __ieee80211_tx(struct ieee80211_local *local,
1145 info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT | 1145 info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT |
1146 IEEE80211_TX_CTL_FIRST_FRAGMENT); 1146 IEEE80211_TX_CTL_FIRST_FRAGMENT);
1147 1147
1148 /*
1149 * Internally, we need to have the queue mapping point to
1150 * the real AC queue, not the virtual A-MPDU queue. This
1151 * now finally sets the queue to what the driver wants.
1152 * We will later move this down into the only driver that
1153 * needs it, iwlwifi.
1154 */
1155 if (sta && local->hw.ampdu_queues &&
1156 info->flags & IEEE80211_TX_CTL_AMPDU) {
1157 unsigned long flags;
1158 u8 *qc = ieee80211_get_qos_ctl((void *) skb->data);
1159 int tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
1160
1161 spin_lock_irqsave(&sta->lock, flags);
1162 skb_set_queue_mapping(skb, local->hw.queues +
1163 sta->tid_to_tx_q[tid]);
1164 spin_unlock_irqrestore(&sta->lock, flags);
1165 }
1166
1167 next = skb->next; 1148 next = skb->next;
1168 len = skb->len; 1149 len = skb->len;
1169 ret = local->ops->tx(local_to_hw(local), skb); 1150 ret = local->ops->tx(local_to_hw(local), skb);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 0247d8022f5f..fdf432f14554 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -339,29 +339,8 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
339{ 339{
340 struct ieee80211_local *local = hw_to_local(hw); 340 struct ieee80211_local *local = hw_to_local(hw);
341 341
342 if (queue >= hw->queues) { 342 if (WARN_ON(queue >= hw->queues))
343 if (local->ampdu_ac_queue[queue - hw->queues] < 0) 343 return;
344 return;
345
346 /*
347 * for virtual aggregation queues, we need to refcount the
348 * internal mac80211 disable (multiple times!), keep track of
349 * driver disable _and_ make sure the regular queue is
350 * actually enabled.
351 */
352 if (reason == IEEE80211_QUEUE_STOP_REASON_AGGREGATION)
353 local->amdpu_ac_stop_refcnt[queue - hw->queues]--;
354 else
355 __clear_bit(reason, &local->queue_stop_reasons[queue]);
356
357 if (local->queue_stop_reasons[queue] ||
358 local->amdpu_ac_stop_refcnt[queue - hw->queues])
359 return;
360
361 /* now go on to treat the corresponding regular queue */
362 queue = local->ampdu_ac_queue[queue - hw->queues];
363 reason = IEEE80211_QUEUE_STOP_REASON_AGGREGATION;
364 }
365 344
366 __clear_bit(reason, &local->queue_stop_reasons[queue]); 345 __clear_bit(reason, &local->queue_stop_reasons[queue]);
367 346
@@ -400,25 +379,8 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
400{ 379{
401 struct ieee80211_local *local = hw_to_local(hw); 380 struct ieee80211_local *local = hw_to_local(hw);
402 381
403 if (queue >= hw->queues) { 382 if (WARN_ON(queue >= hw->queues))
404 if (local->ampdu_ac_queue[queue - hw->queues] < 0) 383 return;
405 return;
406
407 /*
408 * for virtual aggregation queues, we need to refcount the
409 * internal mac80211 disable (multiple times!), keep track of
410 * driver disable _and_ make sure the regular queue is
411 * actually enabled.
412 */
413 if (reason == IEEE80211_QUEUE_STOP_REASON_AGGREGATION)
414 local->amdpu_ac_stop_refcnt[queue - hw->queues]++;
415 else
416 __set_bit(reason, &local->queue_stop_reasons[queue]);
417
418 /* now go on to treat the corresponding regular queue */
419 queue = local->ampdu_ac_queue[queue - hw->queues];
420 reason = IEEE80211_QUEUE_STOP_REASON_AGGREGATION;
421 }
422 384
423 /* 385 /*
424 * Only stop if it was previously running, this is necessary 386 * Only stop if it was previously running, this is necessary
@@ -474,15 +436,9 @@ EXPORT_SYMBOL(ieee80211_stop_queues);
474int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) 436int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
475{ 437{
476 struct ieee80211_local *local = hw_to_local(hw); 438 struct ieee80211_local *local = hw_to_local(hw);
477 unsigned long flags;
478 439
479 if (queue >= hw->queues) { 440 if (WARN_ON(queue >= hw->queues))
480 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 441 return true;
481 queue = local->ampdu_ac_queue[queue - hw->queues];
482 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
483 if (queue < 0)
484 return true;
485 }
486 442
487 return __netif_subqueue_stopped(local->mdev, queue); 443 return __netif_subqueue_stopped(local->mdev, queue);
488} 444}
@@ -497,7 +453,7 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
497 453
498 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 454 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
499 455
500 for (i = 0; i < hw->queues + hw->ampdu_queues; i++) 456 for (i = 0; i < hw->queues; i++)
501 __ieee80211_wake_queue(hw, i, reason); 457 __ieee80211_wake_queue(hw, i, reason);
502 458
503 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 459 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);