aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-11-22 15:28:30 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-11-22 15:28:30 -0500
commit840fd8ff64f7b6c9cbfa9b7d0419f015f33303ff (patch)
treebcdc472c9b794f1d141534c14dcb0dd17015f030 /drivers/net/wireless/iwlwifi/iwl-agn-tx.c
parentb84a7d3d9e7cd5a25f4fd32142cebdf4481a74a4 (diff)
parent9e2e7422d059f9b98c3a0810df92a1ff660ade2f (diff)
Merge branch 'wireless-next-2.6' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-tx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c77
1 files changed, 50 insertions, 27 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 1205cecfcaf0..07bbc915529a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -518,7 +518,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
518 struct iwl_cmd_meta *out_meta; 518 struct iwl_cmd_meta *out_meta;
519 struct iwl_tx_cmd *tx_cmd; 519 struct iwl_tx_cmd *tx_cmd;
520 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 520 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
521 int swq_id, txq_id; 521 int txq_id;
522 dma_addr_t phys_addr; 522 dma_addr_t phys_addr;
523 dma_addr_t txcmd_phys; 523 dma_addr_t txcmd_phys;
524 dma_addr_t scratch_phys; 524 dma_addr_t scratch_phys;
@@ -620,7 +620,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
620 } 620 }
621 621
622 txq = &priv->txq[txq_id]; 622 txq = &priv->txq[txq_id];
623 swq_id = txq->swq_id;
624 q = &txq->q; 623 q = &txq->q;
625 624
626 if (unlikely(iwl_queue_space(q) < q->high_mark)) { 625 if (unlikely(iwl_queue_space(q) < q->high_mark)) {
@@ -775,7 +774,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
775 iwl_txq_update_write_ptr(priv, txq); 774 iwl_txq_update_write_ptr(priv, txq);
776 spin_unlock_irqrestore(&priv->lock, flags); 775 spin_unlock_irqrestore(&priv->lock, flags);
777 } else { 776 } else {
778 iwl_stop_queue(priv, txq->swq_id); 777 iwl_stop_queue(priv, txq);
779 } 778 }
780 } 779 }
781 780
@@ -1004,7 +1003,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
1004 tid_data = &priv->stations[sta_id].tid[tid]; 1003 tid_data = &priv->stations[sta_id].tid[tid];
1005 *ssn = SEQ_TO_SN(tid_data->seq_number); 1004 *ssn = SEQ_TO_SN(tid_data->seq_number);
1006 tid_data->agg.txq_id = txq_id; 1005 tid_data->agg.txq_id = txq_id;
1007 priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(get_ac_from_tid(tid), txq_id); 1006 iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id);
1008 spin_unlock_irqrestore(&priv->sta_lock, flags); 1007 spin_unlock_irqrestore(&priv->sta_lock, flags);
1009 1008
1010 ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo, 1009 ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
@@ -1232,37 +1231,61 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1232 if (sh < 0) /* tbw something is wrong with indices */ 1231 if (sh < 0) /* tbw something is wrong with indices */
1233 sh += 0x100; 1232 sh += 0x100;
1234 1233
1235 /* don't use 64-bit values for now */
1236 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1237
1238 if (agg->frame_count > (64 - sh)) { 1234 if (agg->frame_count > (64 - sh)) {
1239 IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size"); 1235 IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
1240 return -1; 1236 return -1;
1241 } 1237 }
1242 1238 if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
1243 /* check for success or failure according to the 1239 /*
1244 * transmitted bitmap and block-ack bitmap */ 1240 * sent and ack information provided by uCode
1245 sent_bitmap = bitmap & agg->bitmap; 1241 * use it instead of figure out ourself
1246 1242 */
1247 /* For each frame attempted in aggregation, 1243 if (ba_resp->txed_2_done > ba_resp->txed) {
1248 * update driver's record of tx frame's status. */ 1244 IWL_DEBUG_TX_REPLY(priv,
1249 i = 0; 1245 "bogus sent(%d) and ack(%d) count\n",
1250 while (sent_bitmap) { 1246 ba_resp->txed, ba_resp->txed_2_done);
1251 ack = sent_bitmap & 1ULL; 1247 /*
1252 successes += ack; 1248 * set txed_2_done = txed,
1253 IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n", 1249 * so it won't impact rate scale
1254 ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff, 1250 */
1255 agg->start_idx + i); 1251 ba_resp->txed = ba_resp->txed_2_done;
1256 sent_bitmap >>= 1; 1252 }
1257 ++i; 1253 IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
1254 ba_resp->txed, ba_resp->txed_2_done);
1255 } else {
1256 /* don't use 64-bit values for now */
1257 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1258
1259 /* check for success or failure according to the
1260 * transmitted bitmap and block-ack bitmap */
1261 sent_bitmap = bitmap & agg->bitmap;
1262
1263 /* For each frame attempted in aggregation,
1264 * update driver's record of tx frame's status. */
1265 i = 0;
1266 while (sent_bitmap) {
1267 ack = sent_bitmap & 1ULL;
1268 successes += ack;
1269 IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
1270 ack ? "ACK" : "NACK", i,
1271 (agg->start_idx + i) & 0xff,
1272 agg->start_idx + i);
1273 sent_bitmap >>= 1;
1274 ++i;
1275 }
1258 } 1276 }
1259
1260 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb); 1277 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb);
1261 memset(&info->status, 0, sizeof(info->status)); 1278 memset(&info->status, 0, sizeof(info->status));
1262 info->flags |= IEEE80211_TX_STAT_ACK; 1279 info->flags |= IEEE80211_TX_STAT_ACK;
1263 info->flags |= IEEE80211_TX_STAT_AMPDU; 1280 info->flags |= IEEE80211_TX_STAT_AMPDU;
1264 info->status.ampdu_ack_len = successes; 1281 if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
1265 info->status.ampdu_len = agg->frame_count; 1282 info->status.ampdu_ack_len = ba_resp->txed_2_done;
1283 info->status.ampdu_len = ba_resp->txed;
1284
1285 } else {
1286 info->status.ampdu_ack_len = successes;
1287 info->status.ampdu_len = agg->frame_count;
1288 }
1266 iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); 1289 iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
1267 1290
1268 IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap); 1291 IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
@@ -1376,7 +1399,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1376 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && 1399 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1377 priv->mac80211_registered && 1400 priv->mac80211_registered &&
1378 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) 1401 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
1379 iwl_wake_queue(priv, txq->swq_id); 1402 iwl_wake_queue(priv, txq);
1380 1403
1381 iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow); 1404 iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow);
1382 } 1405 }