diff options
author | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2010-11-10 14:05:38 -0500 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2010-11-16 10:43:42 -0500 |
commit | 8829c9e2ec144baeb3cee599e1e653a396ad521b (patch) | |
tree | 456621f28e8d6a65203863be092cd26add4de84b | |
parent | b1d771ee33c6e4006676002b9d74abf45b71d3d6 (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.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 68 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-commands.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 5 |
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 | ||
2625 | struct iwl_cfg iwl4965_agn_cfg = { | 2626 | struct 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 | */ | ||
295 | struct iwl_base_params { | 297 | struct 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 |