aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-10-24 02:48:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-10-31 19:02:23 -0400
commit3fd07a1e5aba89d4be3696c46cb7297f1873195a (patch)
tree48a6c3b68e30136af93c48d35bd1ce08a9237c4d /drivers/net/wireless
parent8b30b1fe368ab03049435884c11c5c50e4c4ef0b (diff)
iwlwifi: refactor TX response flow
This patch utilize 5000 new TX response command which contains all necessary information and avoids back referencing to the original TX frame. It also change handling of software queue tracking 4965 flow is aligned with changes as much as possible. Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Reviewed-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-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);