Commit 8829c9e2 authored by Wey-Yi Guy's avatar Wey-Yi Guy

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: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
parent b1d771ee
...@@ -2620,6 +2620,7 @@ static struct iwl_base_params iwl4965_base_params = { ...@@ -2620,6 +2620,7 @@ static struct iwl_base_params iwl4965_base_params = {
.ucode_tracing = true, .ucode_tracing = true,
.sensitivity_calib_by_driver = true, .sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true, .chain_noise_calib_by_driver = true,
.no_agg_framecnt_info = true,
}; };
struct iwl_cfg iwl4965_agn_cfg = { struct iwl_cfg iwl4965_agn_cfg = {
......
...@@ -1241,13 +1241,30 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, ...@@ -1241,13 +1241,30 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
if (sh < 0) /* tbw something is wrong with indices */ if (sh < 0) /* tbw something is wrong with indices */
sh += 0x100; sh += 0x100;
/* don't use 64-bit values for now */
bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
if (agg->frame_count > (64 - sh)) { if (agg->frame_count > (64 - sh)) {
IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size"); IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
return -1; return -1;
} }
if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
/*
* sent and ack information provided by uCode
* use it instead of figure out ourself
*/
if (ba_resp->txed_2_done > ba_resp->txed) {
IWL_DEBUG_TX_REPLY(priv,
"bogus sent(%d) and ack(%d) count\n",
ba_resp->txed, ba_resp->txed_2_done);
/*
* set txed_2_done = txed,
* so it won't impact rate scale
*/
ba_resp->txed = ba_resp->txed_2_done;
}
IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
ba_resp->txed, ba_resp->txed_2_done);
} else {
/* don't use 64-bit values for now */
bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
/* check for success or failure according to the /* check for success or failure according to the
* transmitted bitmap and block-ack bitmap */ * transmitted bitmap and block-ack bitmap */
...@@ -1260,18 +1277,25 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, ...@@ -1260,18 +1277,25 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
ack = sent_bitmap & 1ULL; ack = sent_bitmap & 1ULL;
successes += ack; successes += ack;
IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n", IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff, ack ? "ACK" : "NACK", i,
(agg->start_idx + i) & 0xff,
agg->start_idx + i); agg->start_idx + i);
sent_bitmap >>= 1; sent_bitmap >>= 1;
++i; ++i;
} }
}
info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb); info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb);
memset(&info->status, 0, sizeof(info->status)); memset(&info->status, 0, sizeof(info->status));
info->flags |= IEEE80211_TX_STAT_ACK; info->flags |= IEEE80211_TX_STAT_ACK;
info->flags |= IEEE80211_TX_STAT_AMPDU; info->flags |= IEEE80211_TX_STAT_AMPDU;
if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
info->status.ampdu_ack_len = ba_resp->txed_2_done;
info->status.ampdu_len = ba_resp->txed;
} else {
info->status.ampdu_ack_len = successes; info->status.ampdu_ack_len = successes;
info->status.ampdu_len = agg->frame_count; info->status.ampdu_len = agg->frame_count;
}
iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap); IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
......
...@@ -2022,6 +2022,9 @@ struct iwl_compressed_ba_resp { ...@@ -2022,6 +2022,9 @@ struct iwl_compressed_ba_resp {
__le64 bitmap; __le64 bitmap;
__le16 scd_flow; __le16 scd_flow;
__le16 scd_ssn; __le16 scd_ssn;
/* following only for 5000 series and up */
u8 txed; /* number of frames sent */
u8 txed_2_done; /* number of frames acked */
} __packed; } __packed;
/* /*
......
...@@ -291,7 +291,9 @@ struct iwl_mod_params { ...@@ -291,7 +291,9 @@ struct iwl_mod_params {
* @chain_noise_calib_by_driver: driver has the capability to perform * @chain_noise_calib_by_driver: driver has the capability to perform
* chain noise calibration operation * chain noise calibration operation
* @shadow_reg_enable: HW shadhow register bit * @shadow_reg_enable: HW shadhow register bit
*/ * @no_agg_framecnt_info: uCode do not provide aggregation frame count
* information
*/
struct iwl_base_params { struct iwl_base_params {
int eeprom_size; int eeprom_size;
int num_of_queues; /* def: HW dependent */ int num_of_queues; /* def: HW dependent */
...@@ -322,6 +324,7 @@ struct iwl_base_params { ...@@ -322,6 +324,7 @@ struct iwl_base_params {
const bool sensitivity_calib_by_driver; const bool sensitivity_calib_by_driver;
const bool chain_noise_calib_by_driver; const bool chain_noise_calib_by_driver;
const bool shadow_reg_enable; const bool shadow_reg_enable;
const bool no_agg_framecnt_info;
}; };
/* /*
* @advanced_bt_coexist: support advanced bt coexist * @advanced_bt_coexist: support advanced bt coexist
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment