Commit 99556438 authored by Ron Rindjunsky's avatar Ron Rindjunsky Committed by John W. Linville

iwlwifi: A-MPDU Tx conform block Ack rate scaling to mac80211

This patch uses the changes in ieee80211_tx_status to pass Block Ack data
to rate scaling module, and uses this data in rate scaling calculations
Signed-off-by: default avatarRon Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent fe01b477
...@@ -277,7 +277,8 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) ...@@ -277,7 +277,8 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window)
* packets. * packets.
*/ */
static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
int scale_index, s32 tpt, u32 status) int scale_index, s32 tpt, int retries,
int successes)
{ {
struct iwl4965_rate_scale_data *window = NULL; struct iwl4965_rate_scale_data *window = NULL;
u64 mask; u64 mask;
...@@ -298,26 +299,33 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, ...@@ -298,26 +299,33 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
* subtract "1" from the success counter (this is the main reason * subtract "1" from the success counter (this is the main reason
* we keep these bitmaps!). * we keep these bitmaps!).
*/ */
if (window->counter >= win_size) { while (retries > 0) {
window->counter = win_size - 1; if (window->counter >= win_size) {
mask = 1; window->counter = win_size - 1;
mask = (mask << (win_size - 1)); mask = 1;
if ((window->data & mask)) { mask = (mask << (win_size - 1));
window->data &= ~mask; if (window->data & mask) {
window->success_counter = window->success_counter - 1; window->data &= ~mask;
window->success_counter =
window->success_counter - 1;
}
} }
}
/* Increment frames-attempted counter */ /* Increment frames-attempted counter */
window->counter = window->counter + 1; window->counter++;
/* Shift bitmap by one frame (throw away oldest history),
* OR in "1", and increment "success" if this
* frame was successful. */
mask = window->data;
window->data = (mask << 1);
if (successes > 0) {
window->success_counter = window->success_counter + 1;
window->data |= 0x1;
successes--;
}
/* Shift bitmap by one frame (throw away oldest history), retries--;
* OR in "1", and increment "success" if this frame was successful. */
mask = window->data;
window->data = (mask << 1);
if (status != 0) {
window->success_counter = window->success_counter + 1;
window->data |= 0x1;
} }
/* Calculate current success ratio, avoid divide-by-0! */ /* Calculate current success ratio, avoid divide-by-0! */
...@@ -677,6 +685,11 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, ...@@ -677,6 +685,11 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
return; return;
/* This packet was aggregated but doesn't carry rate scale info */
if ((tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) &&
!(tx_resp->flags & IEEE80211_TX_STATUS_AMPDU))
return;
retries = tx_resp->retry_count; retries = tx_resp->retry_count;
if (retries > 15) if (retries > 15)
...@@ -766,7 +779,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, ...@@ -766,7 +779,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
tpt = search_tbl->expected_tpt[rs_index]; tpt = search_tbl->expected_tpt[rs_index];
else else
tpt = 0; tpt = 0;
rs_collect_tx_data(search_win, rs_index, tpt, 0); rs_collect_tx_data(search_win, rs_index, tpt, 1, 0);
/* Else if type matches "current/active" table, /* Else if type matches "current/active" table,
* add failure to "current/active" history */ * add failure to "current/active" history */
...@@ -777,7 +790,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, ...@@ -777,7 +790,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
tpt = curr_tbl->expected_tpt[rs_index]; tpt = curr_tbl->expected_tpt[rs_index];
else else
tpt = 0; tpt = 0;
rs_collect_tx_data(window, rs_index, tpt, 0); rs_collect_tx_data(window, rs_index, tpt, 1, 0);
} }
/* If not searching for a new mode, increment failed counter /* If not searching for a new mode, increment failed counter
...@@ -818,9 +831,13 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, ...@@ -818,9 +831,13 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
tpt = search_tbl->expected_tpt[rs_index]; tpt = search_tbl->expected_tpt[rs_index];
else else
tpt = 0; tpt = 0;
rs_collect_tx_data(search_win, if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU)
rs_index, tpt, status); rs_collect_tx_data(search_win, rs_index, tpt,
tx_resp->ampdu_ack_len,
tx_resp->ampdu_ack_map);
else
rs_collect_tx_data(search_win, rs_index, tpt,
1, status);
/* Else if type matches "current/active" table, /* Else if type matches "current/active" table,
* add final tx status to "current/active" history */ * add final tx status to "current/active" history */
} else if ((tbl_type.lq_type == curr_tbl->lq_type) && } else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
...@@ -830,16 +847,28 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, ...@@ -830,16 +847,28 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
tpt = curr_tbl->expected_tpt[rs_index]; tpt = curr_tbl->expected_tpt[rs_index];
else else
tpt = 0; tpt = 0;
rs_collect_tx_data(window, rs_index, tpt, status); if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU)
rs_collect_tx_data(window, rs_index, tpt,
tx_resp->ampdu_ack_len,
tx_resp->ampdu_ack_map);
else
rs_collect_tx_data(window, rs_index, tpt,
1, status);
} }
/* If not searching for new mode, increment success/failed counter /* If not searching for new mode, increment success/failed counter
* ... these help determine when to start searching again */ * ... these help determine when to start searching again */
if (lq_sta->stay_in_tbl) { if (lq_sta->stay_in_tbl) {
if (status) if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) {
lq_sta->total_success++; lq_sta->total_success += tx_resp->ampdu_ack_map;
else lq_sta->total_failed +=
lq_sta->total_failed++; (tx_resp->ampdu_ack_len - tx_resp->ampdu_ack_map);
} else {
if (status)
lq_sta->total_success++;
else
lq_sta->total_failed++;
}
} }
/* See if there's a better rate or modulation mode to try. */ /* See if there's a better rate or modulation mode to try. */
......
...@@ -4286,12 +4286,9 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv, ...@@ -4286,12 +4286,9 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv,
tx_status = &priv->txq[scd_flow].txb[agg->start_idx].status; tx_status = &priv->txq[scd_flow].txb[agg->start_idx].status;
tx_status->flags = IEEE80211_TX_STATUS_ACK; tx_status->flags = IEEE80211_TX_STATUS_ACK;
tx_status->retry_count++; tx_status->flags |= IEEE80211_TX_STATUS_AMPDU;
#ifdef CONFIG_IWL4965_HT_AGG tx_status->ampdu_ack_map = successes;
tx_status->flags |= IEEE80211_TX_STATUS_AGG_STATS; tx_status->ampdu_ack_len = agg->frame_count;
tx_status->successes = successes;
tx_status->frame_count = agg->frame_count;
#endif /* CONFIG_IWL4965_HT_AGG */
tx_status->control.tx_rate = agg->rate_n_flags; tx_status->control.tx_rate = agg->rate_n_flags;
IWL_DEBUG_TX_REPLY("Bitmap %llx\n", bitmap); IWL_DEBUG_TX_REPLY("Bitmap %llx\n", bitmap);
......
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