diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-tx.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 68 |
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); |