aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2010-11-10 14:05:38 -0500
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2010-11-16 10:43:42 -0500
commit8829c9e2ec144baeb3cee599e1e653a396ad521b (patch)
tree456621f28e8d6a65203863be092cd26add4de84b
parentb1d771ee33c6e4006676002b9d74abf45b71d3d6 (diff)
iwlagn: used frame count info in compressed ba packet
For newer devices, uCode provide both "number of frames sent" and "number of frames acked" information inside the compressed_ba packet. So instead of figure the success/failure information through the bitmap, use those information which is much betrer approach. Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c68
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h5
4 files changed, 54 insertions, 23 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 4748d067eb1d..a172bd171a0c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2620,6 +2620,7 @@ static struct iwl_base_params iwl4965_base_params = {
2620 .ucode_tracing = true, 2620 .ucode_tracing = true,
2621 .sensitivity_calib_by_driver = true, 2621 .sensitivity_calib_by_driver = true,
2622 .chain_noise_calib_by_driver = true, 2622 .chain_noise_calib_by_driver = true,
2623 .no_agg_framecnt_info = true,
2623}; 2624};
2624 2625
2625struct iwl_cfg iwl4965_agn_cfg = { 2626struct iwl_cfg iwl4965_agn_cfg = {
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);
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 424801abc80e..31c29a5fe8b1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2022,6 +2022,9 @@ struct iwl_compressed_ba_resp {
2022 __le64 bitmap; 2022 __le64 bitmap;
2023 __le16 scd_flow; 2023 __le16 scd_flow;
2024 __le16 scd_ssn; 2024 __le16 scd_ssn;
2025 /* following only for 5000 series and up */
2026 u8 txed; /* number of frames sent */
2027 u8 txed_2_done; /* number of frames acked */
2025} __packed; 2028} __packed;
2026 2029
2027/* 2030/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index ee8cf240d65d..98b79f627720 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -291,7 +291,9 @@ struct iwl_mod_params {
291 * @chain_noise_calib_by_driver: driver has the capability to perform 291 * @chain_noise_calib_by_driver: driver has the capability to perform
292 * chain noise calibration operation 292 * chain noise calibration operation
293 * @shadow_reg_enable: HW shadhow register bit 293 * @shadow_reg_enable: HW shadhow register bit
294*/ 294 * @no_agg_framecnt_info: uCode do not provide aggregation frame count
295 * information
296 */
295struct iwl_base_params { 297struct iwl_base_params {
296 int eeprom_size; 298 int eeprom_size;
297 int num_of_queues; /* def: HW dependent */ 299 int num_of_queues; /* def: HW dependent */
@@ -322,6 +324,7 @@ struct iwl_base_params {
322 const bool sensitivity_calib_by_driver; 324 const bool sensitivity_calib_by_driver;
323 const bool chain_noise_calib_by_driver; 325 const bool chain_noise_calib_by_driver;
324 const bool shadow_reg_enable; 326 const bool shadow_reg_enable;
327 const bool no_agg_framecnt_info;
325}; 328};
326/* 329/*
327 * @advanced_bt_coexist: support advanced bt coexist 330 * @advanced_bt_coexist: support advanced bt coexist