diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-rs.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 56 |
1 files changed, 25 insertions, 31 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 8bf7c20b9d39..1460116d329f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/skbuff.h> | 28 | #include <linux/skbuff.h> |
29 | #include <linux/slab.h> | ||
29 | #include <linux/wireless.h> | 30 | #include <linux/wireless.h> |
30 | #include <net/mac80211.h> | 31 | #include <net/mac80211.h> |
31 | 32 | ||
@@ -345,6 +346,17 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags) | |||
345 | !!(rate_n_flags & RATE_MCS_ANT_C_MSK); | 346 | !!(rate_n_flags & RATE_MCS_ANT_C_MSK); |
346 | } | 347 | } |
347 | 348 | ||
349 | /* | ||
350 | * Static function to get the expected throughput from an iwl_scale_tbl_info | ||
351 | * that wraps a NULL pointer check | ||
352 | */ | ||
353 | static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) | ||
354 | { | ||
355 | if (tbl->expected_tpt) | ||
356 | return tbl->expected_tpt[rs_index]; | ||
357 | return 0; | ||
358 | } | ||
359 | |||
348 | /** | 360 | /** |
349 | * rs_collect_tx_data - Update the success/failure sliding window | 361 | * rs_collect_tx_data - Update the success/failure sliding window |
350 | * | 362 | * |
@@ -352,19 +364,21 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags) | |||
352 | * at this rate. window->data contains the bitmask of successful | 364 | * at this rate. window->data contains the bitmask of successful |
353 | * packets. | 365 | * packets. |
354 | */ | 366 | */ |
355 | static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, | 367 | static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl, |
356 | int scale_index, s32 tpt, int attempts, | 368 | int scale_index, int attempts, int successes) |
357 | int successes) | ||
358 | { | 369 | { |
359 | struct iwl_rate_scale_data *window = NULL; | 370 | struct iwl_rate_scale_data *window = NULL; |
360 | static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); | 371 | static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); |
361 | s32 fail_count; | 372 | s32 fail_count, tpt; |
362 | 373 | ||
363 | if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) | 374 | if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) |
364 | return -EINVAL; | 375 | return -EINVAL; |
365 | 376 | ||
366 | /* Select window for current tx bit rate */ | 377 | /* Select window for current tx bit rate */ |
367 | window = &(windows[scale_index]); | 378 | window = &(tbl->win[scale_index]); |
379 | |||
380 | /* Get expected throughput */ | ||
381 | tpt = get_expected_tpt(tbl, scale_index); | ||
368 | 382 | ||
369 | /* | 383 | /* |
370 | * Keep track of only the latest 62 tx frame attempts in this rate's | 384 | * Keep track of only the latest 62 tx frame attempts in this rate's |
@@ -738,16 +752,6 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a, | |||
738 | return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && | 752 | return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && |
739 | (a->is_SGI == b->is_SGI); | 753 | (a->is_SGI == b->is_SGI); |
740 | } | 754 | } |
741 | /* | ||
742 | * Static function to get the expected throughput from an iwl_scale_tbl_info | ||
743 | * that wraps a NULL pointer check | ||
744 | */ | ||
745 | static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) | ||
746 | { | ||
747 | if (tbl->expected_tpt) | ||
748 | return tbl->expected_tpt[rs_index]; | ||
749 | return 0; | ||
750 | } | ||
751 | 755 | ||
752 | /* | 756 | /* |
753 | * mac80211 sends us Tx status | 757 | * mac80211 sends us Tx status |
@@ -764,12 +768,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
764 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 768 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
765 | struct iwl_priv *priv = (struct iwl_priv *)priv_r; | 769 | struct iwl_priv *priv = (struct iwl_priv *)priv_r; |
766 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 770 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
767 | struct iwl_rate_scale_data *window = NULL; | ||
768 | enum mac80211_rate_control_flags mac_flags; | 771 | enum mac80211_rate_control_flags mac_flags; |
769 | u32 tx_rate; | 772 | u32 tx_rate; |
770 | struct iwl_scale_tbl_info tbl_type; | 773 | struct iwl_scale_tbl_info tbl_type; |
771 | struct iwl_scale_tbl_info *curr_tbl, *other_tbl; | 774 | struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; |
772 | s32 tpt = 0; | ||
773 | 775 | ||
774 | IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); | 776 | IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); |
775 | 777 | ||
@@ -852,7 +854,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
852 | IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); | 854 | IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); |
853 | return; | 855 | return; |
854 | } | 856 | } |
855 | window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]); | ||
856 | 857 | ||
857 | /* | 858 | /* |
858 | * Updating the frame history depends on whether packets were | 859 | * Updating the frame history depends on whether packets were |
@@ -865,8 +866,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
865 | tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); | 866 | tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); |
866 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, | 867 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, |
867 | &rs_index); | 868 | &rs_index); |
868 | tpt = get_expected_tpt(curr_tbl, rs_index); | 869 | rs_collect_tx_data(curr_tbl, rs_index, |
869 | rs_collect_tx_data(window, rs_index, tpt, | ||
870 | info->status.ampdu_ack_len, | 870 | info->status.ampdu_ack_len, |
871 | info->status.ampdu_ack_map); | 871 | info->status.ampdu_ack_map); |
872 | 872 | ||
@@ -896,19 +896,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
896 | * table as active/search. | 896 | * table as active/search. |
897 | */ | 897 | */ |
898 | if (table_type_matches(&tbl_type, curr_tbl)) | 898 | if (table_type_matches(&tbl_type, curr_tbl)) |
899 | tpt = get_expected_tpt(curr_tbl, rs_index); | 899 | tmp_tbl = curr_tbl; |
900 | else if (table_type_matches(&tbl_type, other_tbl)) | 900 | else if (table_type_matches(&tbl_type, other_tbl)) |
901 | tpt = get_expected_tpt(other_tbl, rs_index); | 901 | tmp_tbl = other_tbl; |
902 | else | 902 | else |
903 | continue; | 903 | continue; |
904 | 904 | rs_collect_tx_data(tmp_tbl, rs_index, 1, | |
905 | /* Constants mean 1 transmission, 0 successes */ | 905 | i < retries ? 0 : legacy_success); |
906 | if (i < retries) | ||
907 | rs_collect_tx_data(window, rs_index, tpt, 1, | ||
908 | 0); | ||
909 | else | ||
910 | rs_collect_tx_data(window, rs_index, tpt, 1, | ||
911 | legacy_success); | ||
912 | } | 906 | } |
913 | 907 | ||
914 | /* Update success/fail counts if not searching for new mode */ | 908 | /* Update success/fail counts if not searching for new mode */ |