diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-11-22 15:28:30 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-11-22 15:28:30 -0500 |
commit | 840fd8ff64f7b6c9cbfa9b7d0419f015f33303ff (patch) | |
tree | bcdc472c9b794f1d141534c14dcb0dd17015f030 /drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |
parent | b84a7d3d9e7cd5a25f4fd32142cebdf4481a74a4 (diff) | |
parent | 9e2e7422d059f9b98c3a0810df92a1ff660ade2f (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.c | 77 |
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 | } |