diff options
author | Ron Rindjunsky <ron.rindjunsky@intel.com> | 2008-01-28 07:07:25 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-02-29 15:19:19 -0500 |
commit | 995564382f9d177214b6ec64db6b9109d4cd41dd (patch) | |
tree | d65b0ad05881d6a5efeabf4e4eab2933e16b05d8 | |
parent | fe01b477bbd23e69c3bdc6bce5be510ddad8297d (diff) |
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: Ron Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 85 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 9 |
2 files changed, 60 insertions, 34 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index d06462264147..f4f2497646bd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -277,7 +277,8 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) | |||
277 | * packets. | 277 | * packets. |
278 | */ | 278 | */ |
279 | static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | 279 | static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, |
280 | int scale_index, s32 tpt, u32 status) | 280 | int scale_index, s32 tpt, int retries, |
281 | int successes) | ||
281 | { | 282 | { |
282 | struct iwl4965_rate_scale_data *window = NULL; | 283 | struct iwl4965_rate_scale_data *window = NULL; |
283 | u64 mask; | 284 | u64 mask; |
@@ -298,26 +299,33 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | |||
298 | * subtract "1" from the success counter (this is the main reason | 299 | * subtract "1" from the success counter (this is the main reason |
299 | * we keep these bitmaps!). | 300 | * we keep these bitmaps!). |
300 | */ | 301 | */ |
301 | if (window->counter >= win_size) { | 302 | while (retries > 0) { |
302 | window->counter = win_size - 1; | 303 | if (window->counter >= win_size) { |
303 | mask = 1; | 304 | window->counter = win_size - 1; |
304 | mask = (mask << (win_size - 1)); | 305 | mask = 1; |
305 | if ((window->data & mask)) { | 306 | mask = (mask << (win_size - 1)); |
306 | window->data &= ~mask; | 307 | if (window->data & mask) { |
307 | window->success_counter = window->success_counter - 1; | 308 | window->data &= ~mask; |
309 | window->success_counter = | ||
310 | window->success_counter - 1; | ||
311 | } | ||
308 | } | 312 | } |
309 | } | ||
310 | 313 | ||
311 | /* Increment frames-attempted counter */ | 314 | /* Increment frames-attempted counter */ |
312 | window->counter = window->counter + 1; | 315 | window->counter++; |
316 | |||
317 | /* Shift bitmap by one frame (throw away oldest history), | ||
318 | * OR in "1", and increment "success" if this | ||
319 | * frame was successful. */ | ||
320 | mask = window->data; | ||
321 | window->data = (mask << 1); | ||
322 | if (successes > 0) { | ||
323 | window->success_counter = window->success_counter + 1; | ||
324 | window->data |= 0x1; | ||
325 | successes--; | ||
326 | } | ||
313 | 327 | ||
314 | /* Shift bitmap by one frame (throw away oldest history), | 328 | retries--; |
315 | * OR in "1", and increment "success" if this frame was successful. */ | ||
316 | mask = window->data; | ||
317 | window->data = (mask << 1); | ||
318 | if (status != 0) { | ||
319 | window->success_counter = window->success_counter + 1; | ||
320 | window->data |= 0x1; | ||
321 | } | 329 | } |
322 | 330 | ||
323 | /* Calculate current success ratio, avoid divide-by-0! */ | 331 | /* 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 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) | 685 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) |
678 | return; | 686 | return; |
679 | 687 | ||
688 | /* This packet was aggregated but doesn't carry rate scale info */ | ||
689 | if ((tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) && | ||
690 | !(tx_resp->flags & IEEE80211_TX_STATUS_AMPDU)) | ||
691 | return; | ||
692 | |||
680 | retries = tx_resp->retry_count; | 693 | retries = tx_resp->retry_count; |
681 | 694 | ||
682 | if (retries > 15) | 695 | if (retries > 15) |
@@ -766,7 +779,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
766 | tpt = search_tbl->expected_tpt[rs_index]; | 779 | tpt = search_tbl->expected_tpt[rs_index]; |
767 | else | 780 | else |
768 | tpt = 0; | 781 | tpt = 0; |
769 | rs_collect_tx_data(search_win, rs_index, tpt, 0); | 782 | rs_collect_tx_data(search_win, rs_index, tpt, 1, 0); |
770 | 783 | ||
771 | /* Else if type matches "current/active" table, | 784 | /* Else if type matches "current/active" table, |
772 | * add failure to "current/active" history */ | 785 | * add failure to "current/active" history */ |
@@ -777,7 +790,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
777 | tpt = curr_tbl->expected_tpt[rs_index]; | 790 | tpt = curr_tbl->expected_tpt[rs_index]; |
778 | else | 791 | else |
779 | tpt = 0; | 792 | tpt = 0; |
780 | rs_collect_tx_data(window, rs_index, tpt, 0); | 793 | rs_collect_tx_data(window, rs_index, tpt, 1, 0); |
781 | } | 794 | } |
782 | 795 | ||
783 | /* If not searching for a new mode, increment failed counter | 796 | /* 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 | tpt = search_tbl->expected_tpt[rs_index]; | 831 | tpt = search_tbl->expected_tpt[rs_index]; |
819 | else | 832 | else |
820 | tpt = 0; | 833 | tpt = 0; |
821 | rs_collect_tx_data(search_win, | 834 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) |
822 | rs_index, tpt, status); | 835 | rs_collect_tx_data(search_win, rs_index, tpt, |
823 | 836 | tx_resp->ampdu_ack_len, | |
837 | tx_resp->ampdu_ack_map); | ||
838 | else | ||
839 | rs_collect_tx_data(search_win, rs_index, tpt, | ||
840 | 1, status); | ||
824 | /* Else if type matches "current/active" table, | 841 | /* Else if type matches "current/active" table, |
825 | * add final tx status to "current/active" history */ | 842 | * add final tx status to "current/active" history */ |
826 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && | 843 | } 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 | tpt = curr_tbl->expected_tpt[rs_index]; | 847 | tpt = curr_tbl->expected_tpt[rs_index]; |
831 | else | 848 | else |
832 | tpt = 0; | 849 | tpt = 0; |
833 | rs_collect_tx_data(window, rs_index, tpt, status); | 850 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) |
851 | rs_collect_tx_data(window, rs_index, tpt, | ||
852 | tx_resp->ampdu_ack_len, | ||
853 | tx_resp->ampdu_ack_map); | ||
854 | else | ||
855 | rs_collect_tx_data(window, rs_index, tpt, | ||
856 | 1, status); | ||
834 | } | 857 | } |
835 | 858 | ||
836 | /* If not searching for new mode, increment success/failed counter | 859 | /* If not searching for new mode, increment success/failed counter |
837 | * ... these help determine when to start searching again */ | 860 | * ... these help determine when to start searching again */ |
838 | if (lq_sta->stay_in_tbl) { | 861 | if (lq_sta->stay_in_tbl) { |
839 | if (status) | 862 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) { |
840 | lq_sta->total_success++; | 863 | lq_sta->total_success += tx_resp->ampdu_ack_map; |
841 | else | 864 | lq_sta->total_failed += |
842 | lq_sta->total_failed++; | 865 | (tx_resp->ampdu_ack_len - tx_resp->ampdu_ack_map); |
866 | } else { | ||
867 | if (status) | ||
868 | lq_sta->total_success++; | ||
869 | else | ||
870 | lq_sta->total_failed++; | ||
871 | } | ||
843 | } | 872 | } |
844 | 873 | ||
845 | /* See if there's a better rate or modulation mode to try. */ | 874 | /* See if there's a better rate or modulation mode to try. */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index b315a099d1a0..89aff4aae45f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -4286,12 +4286,9 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv, | |||
4286 | 4286 | ||
4287 | tx_status = &priv->txq[scd_flow].txb[agg->start_idx].status; | 4287 | tx_status = &priv->txq[scd_flow].txb[agg->start_idx].status; |
4288 | tx_status->flags = IEEE80211_TX_STATUS_ACK; | 4288 | tx_status->flags = IEEE80211_TX_STATUS_ACK; |
4289 | tx_status->retry_count++; | 4289 | tx_status->flags |= IEEE80211_TX_STATUS_AMPDU; |
4290 | #ifdef CONFIG_IWL4965_HT_AGG | 4290 | tx_status->ampdu_ack_map = successes; |
4291 | tx_status->flags |= IEEE80211_TX_STATUS_AGG_STATS; | 4291 | tx_status->ampdu_ack_len = agg->frame_count; |
4292 | tx_status->successes = successes; | ||
4293 | tx_status->frame_count = agg->frame_count; | ||
4294 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
4295 | tx_status->control.tx_rate = agg->rate_n_flags; | 4292 | tx_status->control.tx_rate = agg->rate_n_flags; |
4296 | 4293 | ||
4297 | IWL_DEBUG_TX_REPLY("Bitmap %llx\n", bitmap); | 4294 | IWL_DEBUG_TX_REPLY("Bitmap %llx\n", bitmap); |