aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c63
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c81
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h50
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c39
6 files changed, 125 insertions, 119 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 222c2baa95ca..881bf0472564 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -822,7 +822,6 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
822 } 822 }
823 823
824 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; 824 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
825 priv->hw_params.first_ampdu_q = IWL49_FIRST_AMPDU_QUEUE;
826 priv->hw_params.max_stations = IWL4965_STATION_COUNT; 825 priv->hw_params.max_stations = IWL4965_STATION_COUNT;
827 priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; 826 priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
828 priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; 827 priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
@@ -2059,7 +2058,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
2059 agg->rate_n_flags = rate_n_flags; 2058 agg->rate_n_flags = rate_n_flags;
2060 agg->bitmap = 0; 2059 agg->bitmap = 0;
2061 2060
2062 /* # frames attempted by Tx command */ 2061 /* num frames attempted by Tx command */
2063 if (agg->frame_count == 1) { 2062 if (agg->frame_count == 1) {
2064 /* Only one frame was attempted; no block-ack will arrive */ 2063 /* Only one frame was attempted; no block-ack will arrive */
2065 status = le16_to_cpu(frame_status[0].status); 2064 status = le16_to_cpu(frame_status[0].status);
@@ -2158,12 +2157,13 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2158 int txq_id = SEQ_TO_QUEUE(sequence); 2157 int txq_id = SEQ_TO_QUEUE(sequence);
2159 int index = SEQ_TO_INDEX(sequence); 2158 int index = SEQ_TO_INDEX(sequence);
2160 struct iwl_tx_queue *txq = &priv->txq[txq_id]; 2159 struct iwl_tx_queue *txq = &priv->txq[txq_id];
2160 struct ieee80211_hdr *hdr;
2161 struct ieee80211_tx_info *info; 2161 struct ieee80211_tx_info *info;
2162 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; 2162 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
2163 u32 status = le32_to_cpu(tx_resp->u.status); 2163 u32 status = le32_to_cpu(tx_resp->u.status);
2164 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; 2164 int tid = MAX_TID_COUNT;
2165 __le16 fc; 2165 int sta_id;
2166 struct ieee80211_hdr *hdr; 2166 int freed;
2167 u8 *qc = NULL; 2167 u8 *qc = NULL;
2168 2168
2169 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { 2169 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
@@ -2178,8 +2178,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2178 memset(&info->status, 0, sizeof(info->status)); 2178 memset(&info->status, 0, sizeof(info->status));
2179 2179
2180 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); 2180 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
2181 fc = hdr->frame_control; 2181 if (ieee80211_is_data_qos(hdr->frame_control)) {
2182 if (ieee80211_is_data_qos(fc)) {
2183 qc = ieee80211_get_qos_ctl(hdr); 2182 qc = ieee80211_get_qos_ctl(hdr);
2184 tid = qc[0] & 0xf; 2183 tid = qc[0] & 0xf;
2185 } 2184 }
@@ -2194,8 +2193,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2194 const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); 2193 const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
2195 struct iwl_ht_agg *agg = NULL; 2194 struct iwl_ht_agg *agg = NULL;
2196 2195
2197 if (!qc) 2196 WARN_ON(!qc);
2198 return;
2199 2197
2200 agg = &priv->stations[sta_id].tid[tid].agg; 2198 agg = &priv->stations[sta_id].tid[tid].agg;
2201 2199
@@ -2206,54 +2204,49 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2206 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 2204 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
2207 2205
2208 if (txq->q.read_ptr != (scd_ssn & 0xff)) { 2206 if (txq->q.read_ptr != (scd_ssn & 0xff)) {
2209 int freed, ampdu_q;
2210 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); 2207 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
2211 IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " 2208 IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
2212 "%d index %d\n", scd_ssn , index); 2209 "%d index %d\n", scd_ssn , index);
2213 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 2210 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
2214 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 2211 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
2215 2212
2216 if (iwl_queue_space(&txq->q) > txq->q.low_mark && 2213 if (priv->mac80211_registered &&
2217 txq_id >= 0 && priv->mac80211_registered && 2214 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
2218 agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) { 2215 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
2219 /* calculate mac80211 ampdu sw queue to wake */
2220 ampdu_q = txq_id - IWL49_FIRST_AMPDU_QUEUE +
2221 priv->hw->queues;
2222 if (agg->state == IWL_AGG_OFF) 2216 if (agg->state == IWL_AGG_OFF)
2223 ieee80211_wake_queue(priv->hw, txq_id); 2217 ieee80211_wake_queue(priv->hw, txq_id);
2224 else 2218 else
2225 ieee80211_wake_queue(priv->hw, ampdu_q); 2219 ieee80211_wake_queue(priv->hw,
2220 txq->swq_id);
2226 } 2221 }
2227 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
2228 } 2222 }
2229 } else { 2223 } else {
2230 info->status.rates[0].count = tx_resp->failure_frame + 1; 2224 info->status.rates[0].count = tx_resp->failure_frame + 1;
2231 info->flags |= 2225 info->flags |= iwl_is_tx_success(status) ?
2232 iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; 2226 IEEE80211_TX_STAT_ACK : 0;
2233 iwl_hwrate_to_tx_control(priv, 2227 iwl_hwrate_to_tx_control(priv,
2234 le32_to_cpu(tx_resp->rate_n_flags), 2228 le32_to_cpu(tx_resp->rate_n_flags),
2235 info); 2229 info);
2236 2230
2237 IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags " 2231 IWL_DEBUG_TX_REPLY("TXQ %d status %s (0x%08x) "
2238 "0x%x retries %d\n", txq_id, 2232 "rate_n_flags 0x%x retries %d\n",
2239 iwl_get_tx_fail_reason(status), 2233 txq_id,
2240 status, le32_to_cpu(tx_resp->rate_n_flags), 2234 iwl_get_tx_fail_reason(status), status,
2241 tx_resp->failure_frame); 2235 le32_to_cpu(tx_resp->rate_n_flags),
2242 2236 tx_resp->failure_frame);
2243 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
2244 2237
2245 if (index != -1) { 2238 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
2246 int freed = iwl_tx_queue_reclaim(priv, txq_id, index); 2239 if (qc)
2247 if (tid != MAX_TID_COUNT)
2248 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 2240 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
2249 if (iwl_queue_space(&txq->q) > txq->q.low_mark && 2241
2250 (txq_id >= 0) && priv->mac80211_registered) 2242 if (priv->mac80211_registered &&
2243 (iwl_queue_space(&txq->q) > txq->q.low_mark))
2251 ieee80211_wake_queue(priv->hw, txq_id); 2244 ieee80211_wake_queue(priv->hw, txq_id);
2252 if (tid != MAX_TID_COUNT)
2253 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
2254 }
2255 } 2245 }
2256 2246
2247 if (qc)
2248 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
2249
2257 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) 2250 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
2258 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); 2251 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
2259} 2252}
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index ad566ef233b8..a8c8c858e209 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -683,7 +683,7 @@ static void iwl5000_tx_queue_set_status(struct iwl_priv *priv,
683 int tx_fifo_id, int scd_retry) 683 int tx_fifo_id, int scd_retry)
684{ 684{
685 int txq_id = txq->q.id; 685 int txq_id = txq->q.id;
686 int active = test_bit(txq_id, &priv->txq_ctx_active_msk)?1:0; 686 int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0;
687 687
688 iwl_write_prph(priv, IWL50_SCD_QUEUE_STATUS_BITS(txq_id), 688 iwl_write_prph(priv, IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
689 (active << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE) | 689 (active << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
@@ -801,7 +801,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
801 } 801 }
802 802
803 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; 803 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
804 priv->hw_params.first_ampdu_q = IWL50_FIRST_AMPDU_QUEUE;
805 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 804 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
806 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 805 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
807 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE; 806 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
@@ -1159,7 +1158,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
1159 info->status.rates[0].count = tx_resp->failure_frame + 1; 1158 info->status.rates[0].count = tx_resp->failure_frame + 1;
1160 info->flags &= ~IEEE80211_TX_CTL_AMPDU; 1159 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
1161 info->flags |= iwl_is_tx_success(status)? 1160 info->flags |= iwl_is_tx_success(status)?
1162 IEEE80211_TX_STAT_ACK : 0; 1161 IEEE80211_TX_STAT_ACK : 0;
1163 iwl_hwrate_to_tx_control(priv, rate_n_flags, info); 1162 iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
1164 1163
1165 /* FIXME: code repetition end */ 1164 /* FIXME: code repetition end */
@@ -1245,9 +1244,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1245 struct ieee80211_tx_info *info; 1244 struct ieee80211_tx_info *info;
1246 struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; 1245 struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
1247 u32 status = le16_to_cpu(tx_resp->status.status); 1246 u32 status = le16_to_cpu(tx_resp->status.status);
1248 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; 1247 int tid;
1249 struct ieee80211_hdr *hdr; 1248 int sta_id;
1250 u8 *qc = NULL; 1249 int freed;
1251 1250
1252 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { 1251 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
1253 IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " 1252 IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
@@ -1260,25 +1259,13 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1260 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); 1259 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
1261 memset(&info->status, 0, sizeof(info->status)); 1260 memset(&info->status, 0, sizeof(info->status));
1262 1261
1263 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); 1262 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS;
1264 if (ieee80211_is_data_qos(hdr->frame_control)) { 1263 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS;
1265 qc = ieee80211_get_qos_ctl(hdr);
1266 tid = qc[0] & 0xf;
1267 }
1268
1269 sta_id = iwl_get_ra_sta_id(priv, hdr);
1270 if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
1271 IWL_ERROR("Station not known\n");
1272 return;
1273 }
1274 1264
1275 if (txq->sched_retry) { 1265 if (txq->sched_retry) {
1276 const u32 scd_ssn = iwl5000_get_scd_ssn(tx_resp); 1266 const u32 scd_ssn = iwl5000_get_scd_ssn(tx_resp);
1277 struct iwl_ht_agg *agg = NULL; 1267 struct iwl_ht_agg *agg = NULL;
1278 1268
1279 if (!qc)
1280 return;
1281
1282 agg = &priv->stations[sta_id].tid[tid].agg; 1269 agg = &priv->stations[sta_id].tid[tid].agg;
1283 1270
1284 iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); 1271 iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
@@ -1288,53 +1275,53 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1288 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 1275 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
1289 1276
1290 if (txq->q.read_ptr != (scd_ssn & 0xff)) { 1277 if (txq->q.read_ptr != (scd_ssn & 0xff)) {
1291 int freed, ampdu_q;
1292 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); 1278 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
1293 IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " 1279 IWL_DEBUG_TX_REPLY("Retry scheduler reclaim "
1294 "%d index %d\n", scd_ssn , index); 1280 "scd_ssn=%d idx=%d txq=%d swq=%d\n",
1281 scd_ssn , index, txq_id, txq->swq_id);
1282
1295 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 1283 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
1296 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 1284 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
1297 1285
1298 if (iwl_queue_space(&txq->q) > txq->q.low_mark && 1286 if (priv->mac80211_registered &&
1299 txq_id >= 0 && priv->mac80211_registered && 1287 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1300 agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) { 1288 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
1301 /* calculate mac80211 ampdu sw queue to wake */
1302 ampdu_q = txq_id - IWL50_FIRST_AMPDU_QUEUE +
1303 priv->hw->queues;
1304 if (agg->state == IWL_AGG_OFF) 1289 if (agg->state == IWL_AGG_OFF)
1305 ieee80211_wake_queue(priv->hw, txq_id); 1290 ieee80211_wake_queue(priv->hw, txq_id);
1306 else 1291 else
1307 ieee80211_wake_queue(priv->hw, ampdu_q); 1292 ieee80211_wake_queue(priv->hw,
1293 txq->swq_id);
1308 } 1294 }
1309 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
1310 } 1295 }
1311 } else { 1296 } else {
1297 BUG_ON(txq_id != txq->swq_id);
1298
1312 info->status.rates[0].count = tx_resp->failure_frame + 1; 1299 info->status.rates[0].count = tx_resp->failure_frame + 1;
1313 info->flags = 1300 info->flags |= iwl_is_tx_success(status) ?
1314 iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; 1301 IEEE80211_TX_STAT_ACK : 0;
1315 iwl_hwrate_to_tx_control(priv, 1302 iwl_hwrate_to_tx_control(priv,
1316 le32_to_cpu(tx_resp->rate_n_flags), 1303 le32_to_cpu(tx_resp->rate_n_flags),
1317 info); 1304 info);
1318 1305
1319 IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags " 1306 IWL_DEBUG_TX_REPLY("TXQ %d status %s (0x%08x) rate_n_flags "
1320 "0x%x retries %d\n", txq_id, 1307 "0x%x retries %d\n",
1321 iwl_get_tx_fail_reason(status), 1308 txq_id,
1322 status, le32_to_cpu(tx_resp->rate_n_flags), 1309 iwl_get_tx_fail_reason(status), status,
1323 tx_resp->failure_frame); 1310 le32_to_cpu(tx_resp->rate_n_flags),
1311 tx_resp->failure_frame);
1324 1312
1325 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); 1313 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
1326 if (index != -1) { 1314 if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
1327 int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
1328 if (tid != MAX_TID_COUNT)
1329 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 1315 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
1330 if (iwl_queue_space(&txq->q) > txq->q.low_mark && 1316
1331 (txq_id >= 0) && priv->mac80211_registered) 1317 if (priv->mac80211_registered &&
1318 (iwl_queue_space(&txq->q) > txq->q.low_mark))
1332 ieee80211_wake_queue(priv->hw, txq_id); 1319 ieee80211_wake_queue(priv->hw, txq_id);
1333 if (tid != MAX_TID_COUNT)
1334 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
1335 }
1336 } 1320 }
1337 1321
1322 if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
1323 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
1324
1338 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) 1325 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
1339 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); 1326 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
1340} 1327}
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 67680a74afde..8f8734fc4f39 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1413,21 +1413,21 @@ enum {
1413}; 1413};
1414 1414
1415enum { 1415enum {
1416 TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */ 1416 TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */
1417 TX_STATUS_DELAY_MSK = 0x00000040, 1417 TX_STATUS_DELAY_MSK = 0x00000040,
1418 TX_STATUS_ABORT_MSK = 0x00000080, 1418 TX_STATUS_ABORT_MSK = 0x00000080,
1419 TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */ 1419 TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */
1420 TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */ 1420 TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */
1421 TX_RESERVED = 0x00780000, /* bits 19:22 */ 1421 TX_RESERVED = 0x00780000, /* bits 19:22 */
1422 TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */ 1422 TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */
1423 TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ 1423 TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */
1424}; 1424};
1425 1425
1426static inline int iwl_is_tx_success(u32 status) 1426static inline bool iwl_is_tx_success(u32 status)
1427{ 1427{
1428 status &= TX_STATUS_MSK; 1428 status &= TX_STATUS_MSK;
1429 return (status == TX_STATUS_SUCCESS) 1429 return (status == TX_STATUS_SUCCESS) ||
1430 || (status == TX_STATUS_DIRECT_DONE); 1430 (status == TX_STATUS_DIRECT_DONE);
1431} 1431}
1432 1432
1433 1433
@@ -1452,10 +1452,9 @@ enum {
1452 AGG_TX_STATE_DELAY_TX_MSK = 0x400 1452 AGG_TX_STATE_DELAY_TX_MSK = 0x400
1453}; 1453};
1454 1454
1455#define AGG_TX_STATE_LAST_SENT_MSK \ 1455#define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL_MSK | \
1456(AGG_TX_STATE_LAST_SENT_TTL_MSK | \ 1456 AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \
1457 AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \ 1457 AGG_TX_STATE_LAST_SENT_BT_KILL_MSK)
1458 AGG_TX_STATE_LAST_SENT_BT_KILL_MSK)
1459 1458
1460/* # tx attempts for first frame in aggregation */ 1459/* # tx attempts for first frame in aggregation */
1461#define AGG_TX_STATE_TRY_CNT_POS 12 1460#define AGG_TX_STATE_TRY_CNT_POS 12
@@ -1528,6 +1527,28 @@ struct iwl4965_tx_resp {
1528 } u; 1527 } u;
1529} __attribute__ ((packed)); 1528} __attribute__ ((packed));
1530 1529
1530/*
1531 * definitions for initial rate index field
1532 * bits [3:0] inital rate index
1533 * bits [6:4] rate table color, used for the initial rate
1534 * bit-7 invalid rate indication
1535 * i.e. rate was not chosen from rate table
1536 * or rate table color was changed during frame retries
1537 * refer tlc rate info
1538 */
1539
1540#define IWL50_TX_RES_INIT_RATE_INDEX_POS 0
1541#define IWL50_TX_RES_INIT_RATE_INDEX_MSK 0x0f
1542#define IWL50_TX_RES_RATE_TABLE_COLOR_POS 4
1543#define IWL50_TX_RES_RATE_TABLE_COLOR_MSK 0x70
1544#define IWL50_TX_RES_INV_RATE_INDEX_MSK 0x80
1545
1546/* refer to ra_tid */
1547#define IWL50_TX_RES_TID_POS 0
1548#define IWL50_TX_RES_TID_MSK 0x0f
1549#define IWL50_TX_RES_RA_POS 4
1550#define IWL50_TX_RES_RA_MSK 0xf0
1551
1531struct iwl5000_tx_resp { 1552struct iwl5000_tx_resp {
1532 u8 frame_count; /* 1 no aggregation, >1 aggregation */ 1553 u8 frame_count; /* 1 no aggregation, >1 aggregation */
1533 u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */ 1554 u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */
@@ -1542,14 +1563,17 @@ struct iwl5000_tx_resp {
1542 * For agg: RTS + CTS + aggregation tx time + block-ack time. */ 1563 * For agg: RTS + CTS + aggregation tx time + block-ack time. */
1543 __le16 wireless_media_time; /* uSecs */ 1564 __le16 wireless_media_time; /* uSecs */
1544 1565
1545 __le16 reserved; 1566 u8 pa_status; /* RF power amplifier measurement (not used) */
1546 __le32 pa_power1; /* RF power amplifier measurement (not used) */ 1567 u8 pa_integ_res_a[3];
1547 __le32 pa_power2; 1568 u8 pa_integ_res_b[3];
1569 u8 pa_integ_res_C[3];
1548 1570
1549 __le32 tfd_info; 1571 __le32 tfd_info;
1550 __le16 seq_ctl; 1572 __le16 seq_ctl;
1551 __le16 byte_cnt; 1573 __le16 byte_cnt;
1552 __le32 tlc_info; 1574 u8 tlc_info;
1575 u8 ra_tid; /* tid (0:3), sta_id (4:7) */
1576 __le16 frame_ctrl;
1553 /* 1577 /*
1554 * For non-agg: frame status TX_STATUS_* 1578 * For non-agg: frame status TX_STATUS_*
1555 * For agg: status of 1st frame, AGG_TX_STATE_*; other frame status 1579 * For agg: status of 1st frame, AGG_TX_STATE_*; other frame status
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index e548d67f87fd..2b48a4c01776 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -183,6 +183,8 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
183#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a) 183#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
184#define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a) 184#define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a)
185#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a) 185#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
186#define IWL_DEBUG_TX_REPLY_LIMIT(f, a...) \
187 IWL_DEBUG_LIMIT(IWL_DL_TX_REPLY, f, ## a)
186#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a) 188#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a)
187#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a) 189#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a)
188#define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a) 190#define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 1f42e90c5f30..2f871f0c5d36 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -135,9 +135,10 @@ struct iwl_tx_queue {
135 struct iwl_tfd *tfds; 135 struct iwl_tfd *tfds;
136 struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS]; 136 struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
137 struct iwl_tx_info *txb; 137 struct iwl_tx_info *txb;
138 int need_update; 138 u8 need_update;
139 int sched_retry; 139 u8 sched_retry;
140 int active; 140 u8 active;
141 u8 swq_id;
141}; 142};
142 143
143#define IWL_NUM_SCAN_RATES (2) 144#define IWL_NUM_SCAN_RATES (2)
@@ -519,7 +520,6 @@ struct iwl_sensitivity_ranges {
519 * @ct_kill_threshold: temperature threshold 520 * @ct_kill_threshold: temperature threshold
520 * @calib_init_cfg: setup initial claibrations for the hw 521 * @calib_init_cfg: setup initial claibrations for the hw
521 * @struct iwl_sensitivity_ranges: range of sensitivity values 522 * @struct iwl_sensitivity_ranges: range of sensitivity values
522 * @first_ampdu_q: first HW queue available for ampdu
523 */ 523 */
524struct iwl_hw_params { 524struct iwl_hw_params {
525 u16 max_txq_num; 525 u16 max_txq_num;
@@ -541,7 +541,6 @@ struct iwl_hw_params {
541 u32 ct_kill_threshold; /* value in hw-dependent units */ 541 u32 ct_kill_threshold; /* value in hw-dependent units */
542 u32 calib_init_cfg; 542 u32 calib_init_cfg;
543 const struct iwl_sensitivity_ranges *sens; 543 const struct iwl_sensitivity_ranges *sens;
544 u8 first_ampdu_q;
545}; 544};
546 545
547#define HT_SHORT_GI_20MHZ (1 << 0) 546#define HT_SHORT_GI_20MHZ (1 << 0)
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 6cf4a7c428dd..cfa78260c594 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -895,9 +895,9 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
895 priv->stations[sta_id].tid[tid].tfds_in_queue++; 895 priv->stations[sta_id].tid[tid].tfds_in_queue++;
896 } 896 }
897 897
898 /* Descriptor for chosen Tx queue */
899 txq = &priv->txq[txq_id]; 898 txq = &priv->txq[txq_id];
900 q = &txq->q; 899 q = &txq->q;
900 txq->swq_id = swq_id;
901 901
902 spin_lock_irqsave(&priv->lock, flags); 902 spin_lock_irqsave(&priv->lock, flags);
903 903
@@ -1023,7 +1023,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
1023 iwl_txq_update_write_ptr(priv, txq); 1023 iwl_txq_update_write_ptr(priv, txq);
1024 spin_unlock_irqrestore(&priv->lock, flags); 1024 spin_unlock_irqrestore(&priv->lock, flags);
1025 } else { 1025 } else {
1026 ieee80211_stop_queue(priv->hw, swq_id); 1026 ieee80211_stop_queue(priv->hw, txq->swq_id);
1027 } 1027 }
1028 } 1028 }
1029 1029
@@ -1395,8 +1395,8 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
1395 case IWL_EMPTYING_HW_QUEUE_DELBA: 1395 case IWL_EMPTYING_HW_QUEUE_DELBA:
1396 /* We are reclaiming the last packet of the */ 1396 /* We are reclaiming the last packet of the */
1397 /* aggregated HW queue */ 1397 /* aggregated HW queue */
1398 if (txq_id == tid_data->agg.txq_id && 1398 if ((txq_id == tid_data->agg.txq_id) &&
1399 q->read_ptr == q->write_ptr) { 1399 (q->read_ptr == q->write_ptr)) {
1400 u16 ssn = SEQ_TO_SN(tid_data->seq_number); 1400 u16 ssn = SEQ_TO_SN(tid_data->seq_number);
1401 int tx_fifo = default_tid_to_tx_fifo[tid]; 1401 int tx_fifo = default_tid_to_tx_fifo[tid];
1402 IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n"); 1402 IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n");
@@ -1447,7 +1447,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1447 IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl); 1447 IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
1448 1448
1449 /* Calculate shift to align block-ack bits with our Tx window bits */ 1449 /* Calculate shift to align block-ack bits with our Tx window bits */
1450 sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl>>4); 1450 sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
1451 if (sh < 0) /* tbw something is wrong with indices */ 1451 if (sh < 0) /* tbw something is wrong with indices */
1452 sh += 0x100; 1452 sh += 0x100;
1453 1453
@@ -1497,9 +1497,11 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1497{ 1497{
1498 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 1498 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
1499 struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; 1499 struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
1500 int index;
1501 struct iwl_tx_queue *txq = NULL; 1500 struct iwl_tx_queue *txq = NULL;
1502 struct iwl_ht_agg *agg; 1501 struct iwl_ht_agg *agg;
1502 int index;
1503 int sta_id;
1504 int tid;
1503 1505
1504 /* "flow" corresponds to Tx queue */ 1506 /* "flow" corresponds to Tx queue */
1505 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); 1507 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
@@ -1514,14 +1516,16 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1514 } 1516 }
1515 1517
1516 txq = &priv->txq[scd_flow]; 1518 txq = &priv->txq[scd_flow];
1517 agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg; 1519 sta_id = ba_resp->sta_id;
1520 tid = ba_resp->tid;
1521 agg = &priv->stations[sta_id].tid[tid].agg;
1518 1522
1519 /* Find index just before block-ack window */ 1523 /* Find index just before block-ack window */
1520 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); 1524 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
1521 1525
1522 /* TODO: Need to get this copy more safely - now good for debug */ 1526 /* TODO: Need to get this copy more safely - now good for debug */
1523 1527
1524 IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %pM, " 1528 IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d] Received from %pM, "
1525 "sta_id = %d\n", 1529 "sta_id = %d\n",
1526 agg->wait_for_ba, 1530 agg->wait_for_ba,
1527 (u8 *) &ba_resp->sta_addr_lo32, 1531 (u8 *) &ba_resp->sta_addr_lo32,
@@ -1545,18 +1549,15 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1545 * transmitted ... if not, it's too late anyway). */ 1549 * transmitted ... if not, it's too late anyway). */
1546 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { 1550 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
1547 /* calculate mac80211 ampdu sw queue to wake */ 1551 /* calculate mac80211 ampdu sw queue to wake */
1548 int ampdu_q =
1549 scd_flow - priv->hw_params.first_ampdu_q + priv->hw->queues;
1550 int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); 1552 int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
1551 priv->stations[ba_resp->sta_id]. 1553 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
1552 tid[ba_resp->tid].tfds_in_queue -= freed; 1554
1553 if (iwl_queue_space(&txq->q) > txq->q.low_mark && 1555 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1554 priv->mac80211_registered && 1556 priv->mac80211_registered &&
1555 agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) 1557 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
1556 ieee80211_wake_queue(priv->hw, ampdu_q); 1558 ieee80211_wake_queue(priv->hw, txq->swq_id);
1557 1559
1558 iwl_txq_check_empty(priv, ba_resp->sta_id, 1560 iwl_txq_check_empty(priv, sta_id, tid, scd_flow);
1559 ba_resp->tid, scd_flow);
1560 } 1561 }
1561} 1562}
1562EXPORT_SYMBOL(iwl_rx_reply_compressed_ba); 1563EXPORT_SYMBOL(iwl_rx_reply_compressed_ba);