diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-helpers.h | 52 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 1 | ||||
-rw-r--r-- | include/net/mac80211.h | 14 | ||||
-rw-r--r-- | net/mac80211/agg-tx.c | 44 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 7 | ||||
-rw-r--r-- | net/mac80211/main.c | 9 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 12 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 2 | ||||
-rw-r--r-- | net/mac80211/tx.c | 19 | ||||
-rw-r--r-- | net/mac80211/util.c | 58 |
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 | */ | ||
107 | static 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 | |||
115 | static 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 | |||
130 | static 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 | */ |
99 | enum ieee80211_max_queues { | 97 | enum 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); | |||
474 | int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) | 436 | int 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); |