aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-tx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c68
1 files changed, 46 insertions, 22 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 2b078a995729..522c77f23e04 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -1241,37 +1241,61 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1241 if (sh < 0) /* tbw something is wrong with indices */ 1241 if (sh < 0) /* tbw something is wrong with indices */
1242 sh += 0x100; 1242 sh += 0x100;
1243 1243
1244 /* don't use 64-bit values for now */
1245 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1246
1247 if (agg->frame_count > (64 - sh)) { 1244 if (agg->frame_count > (64 - sh)) {
1248 IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size"); 1245 IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
1249 return -1; 1246 return -1;
1250 } 1247 }
1251 1248 if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
1252 /* check for success or failure according to the 1249 /*
1253 * transmitted bitmap and block-ack bitmap */ 1250 * sent and ack information provided by uCode
1254 sent_bitmap = bitmap & agg->bitmap; 1251 * use it instead of figure out ourself
1255 1252 */
1256 /* For each frame attempted in aggregation, 1253 if (ba_resp->txed_2_done > ba_resp->txed) {
1257 * update driver's record of tx frame's status. */ 1254 IWL_DEBUG_TX_REPLY(priv,
1258 i = 0; 1255 "bogus sent(%d) and ack(%d) count\n",
1259 while (sent_bitmap) { 1256 ba_resp->txed, ba_resp->txed_2_done);
1260 ack = sent_bitmap & 1ULL; 1257 /*
1261 successes += ack; 1258 * set txed_2_done = txed,
1262 IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n", 1259 * so it won't impact rate scale
1263 ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff, 1260 */
1264 agg->start_idx + i); 1261 ba_resp->txed = ba_resp->txed_2_done;
1265 sent_bitmap >>= 1; 1262 }
1266 ++i; 1263 IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
1264 ba_resp->txed, ba_resp->txed_2_done);
1265 } else {
1266 /* don't use 64-bit values for now */
1267 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1268
1269 /* check for success or failure according to the
1270 * transmitted bitmap and block-ack bitmap */
1271 sent_bitmap = bitmap & agg->bitmap;
1272
1273 /* For each frame attempted in aggregation,
1274 * update driver's record of tx frame's status. */
1275 i = 0;
1276 while (sent_bitmap) {
1277 ack = sent_bitmap & 1ULL;
1278 successes += ack;
1279 IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
1280 ack ? "ACK" : "NACK", i,
1281 (agg->start_idx + i) & 0xff,
1282 agg->start_idx + i);
1283 sent_bitmap >>= 1;
1284 ++i;
1285 }
1267 } 1286 }
1268
1269 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb); 1287 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb);
1270 memset(&info->status, 0, sizeof(info->status)); 1288 memset(&info->status, 0, sizeof(info->status));
1271 info->flags |= IEEE80211_TX_STAT_ACK; 1289 info->flags |= IEEE80211_TX_STAT_ACK;
1272 info->flags |= IEEE80211_TX_STAT_AMPDU; 1290 info->flags |= IEEE80211_TX_STAT_AMPDU;
1273 info->status.ampdu_ack_len = successes; 1291 if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
1274 info->status.ampdu_len = agg->frame_count; 1292 info->status.ampdu_ack_len = ba_resp->txed_2_done;
1293 info->status.ampdu_len = ba_resp->txed;
1294
1295 } else {
1296 info->status.ampdu_ack_len = successes;
1297 info->status.ampdu_len = agg->frame_count;
1298 }
1275 iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); 1299 iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
1276 1300
1277 IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap); 1301 IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);