aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorDaniel C Halperin <daniel.c.halperin@intel.com>2009-09-17 13:43:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-07 16:39:34 -0400
commit95407aa4d48a8b3a2adf6a110853b544342913bd (patch)
tree1ba2eb6a31b932a728bc70c235e8535824575a18 /drivers/net/wireless/iwlwifi
parent4e30cb691b9ba62642cc1594ef08f7439deb5a02 (diff)
iwlwifi: clean up rs_tx_status
Cut down on redundant code, reorganize structure, and add/improve comments. Should contain no functional changes. Signed-off-by: Daniel C Halperin <daniel.c.halperin@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c230
1 files changed, 108 insertions, 122 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 469d56321d88..cd24763d5fde 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -821,27 +821,45 @@ out:
821} 821}
822 822
823/* 823/*
824 * Simple function to compare two rate scale table types
825 */
826static bool table_type_matches(struct iwl_scale_tbl_info *a,
827 struct iwl_scale_tbl_info *b)
828{
829 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
830 (a->is_SGI == b->is_SGI);
831}
832/*
833 * Static function to get the expected throughput from an iwl_scale_tbl_info
834 * that wraps a NULL pointer check
835 */
836static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
837{
838 if (tbl->expected_tpt)
839 return tbl->expected_tpt[rs_index];
840 return 0;
841}
842
843/*
824 * mac80211 sends us Tx status 844 * mac80211 sends us Tx status
825 */ 845 */
826static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, 846static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
827 struct ieee80211_sta *sta, void *priv_sta, 847 struct ieee80211_sta *sta, void *priv_sta,
828 struct sk_buff *skb) 848 struct sk_buff *skb)
829{ 849{
830 int status; 850 int legacy_success;
831 u8 retries; 851 int retries;
832 int rs_index, mac_index, index = 0; 852 int rs_index, mac_index, i;
833 struct iwl_lq_sta *lq_sta = priv_sta; 853 struct iwl_lq_sta *lq_sta = priv_sta;
834 struct iwl_link_quality_cmd *table; 854 struct iwl_link_quality_cmd *table;
835 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 855 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
836 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 856 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
837 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 857 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
838 struct iwl_rate_scale_data *window = NULL; 858 struct iwl_rate_scale_data *window = NULL;
839 struct iwl_rate_scale_data *search_win = NULL;
840 enum mac80211_rate_control_flags mac_flags; 859 enum mac80211_rate_control_flags mac_flags;
841 u32 tx_rate; 860 u32 tx_rate;
842 struct iwl_scale_tbl_info tbl_type; 861 struct iwl_scale_tbl_info tbl_type;
843 struct iwl_scale_tbl_info *curr_tbl, *search_tbl; 862 struct iwl_scale_tbl_info *curr_tbl, *other_tbl;
844 u8 active_index = 0;
845 s32 tpt = 0; 863 s32 tpt = 0;
846 864
847 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); 865 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
@@ -855,25 +873,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
855 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 873 !(info->flags & IEEE80211_TX_STAT_AMPDU))
856 return; 874 return;
857 875
858 if (info->flags & IEEE80211_TX_STAT_AMPDU)
859 retries = 0;
860 else
861 retries = info->status.rates[0].count - 1;
862
863 if (retries > 15)
864 retries = 15;
865 876
866 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && 877 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
867 !lq_sta->ibss_sta_added) 878 !lq_sta->ibss_sta_added)
868 goto out; 879 return;
869
870 table = &lq_sta->lq;
871 active_index = lq_sta->active_tbl;
872
873 curr_tbl = &(lq_sta->lq_info[active_index]);
874 search_tbl = &(lq_sta->lq_info[(1 - active_index)]);
875 window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
876 search_win = (struct iwl_rate_scale_data *)&(search_tbl->win[0]);
877 880
878 /* 881 /*
879 * Ignore this Tx frame response if its initial rate doesn't match 882 * Ignore this Tx frame response if its initial rate doesn't match
@@ -883,6 +886,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
883 * to check "search" mode, or a prior "search" mode after we've moved 886 * to check "search" mode, or a prior "search" mode after we've moved
884 * to a new "search" mode (which might become the new "active" mode). 887 * to a new "search" mode (which might become the new "active" mode).
885 */ 888 */
889 table = &lq_sta->lq;
886 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); 890 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
887 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index); 891 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
888 if (priv->band == IEEE80211_BAND_5GHZ) 892 if (priv->band == IEEE80211_BAND_5GHZ)
@@ -901,7 +905,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
901 if (priv->band == IEEE80211_BAND_2GHZ) 905 if (priv->band == IEEE80211_BAND_2GHZ)
902 mac_index += IWL_FIRST_OFDM_RATE; 906 mac_index += IWL_FIRST_OFDM_RATE;
903 } 907 }
904 908 /* Here we actually compare this rate to the latest LQ command */
905 if ((mac_index < 0) || 909 if ((mac_index < 0) ||
906 (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || 910 (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
907 (tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) || 911 (tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) ||
@@ -911,124 +915,106 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
911 (!!(tx_rate & RATE_MCS_GF_MSK) != !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) || 915 (!!(tx_rate & RATE_MCS_GF_MSK) != !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
912 (rs_index != mac_index)) { 916 (rs_index != mac_index)) {
913 IWL_DEBUG_RATE(priv, "initial rate %d does not match %d (0x%x)\n", mac_index, rs_index, tx_rate); 917 IWL_DEBUG_RATE(priv, "initial rate %d does not match %d (0x%x)\n", mac_index, rs_index, tx_rate);
914 /* the last LQ command could failed so the LQ in ucode not 918 /*
915 * the same in driver sync up 919 * Since rates mis-match, the last LQ command may have failed.
920 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
921 * ... driver.
916 */ 922 */
917 lq_sta->missed_rate_counter++; 923 lq_sta->missed_rate_counter++;
918 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { 924 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
919 lq_sta->missed_rate_counter = 0; 925 lq_sta->missed_rate_counter = 0;
920 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 926 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
921 } 927 }
922 goto out; 928 /* Regardless, ignore this status info for outdated rate */
929 return;
930 } else
931 /* Rate did match, so reset the missed_rate_counter */
932 lq_sta->missed_rate_counter = 0;
933
934 /* Figure out if rate scale algorithm is in active or search table */
935 if (table_type_matches(&tbl_type,
936 &(lq_sta->lq_info[lq_sta->active_tbl]))) {
937 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
938 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
939 } else if (table_type_matches(&tbl_type,
940 &lq_sta->lq_info[1 - lq_sta->active_tbl])) {
941 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
942 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
943 } else {
944 IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
945 return;
923 } 946 }
947 window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
924 948
925 lq_sta->missed_rate_counter = 0; 949 /*
926 /* Update frame history window with "failure" for each Tx retry. */ 950 * Updating the frame history depends on whether packets were
927 while (retries) { 951 * aggregated.
928 /* Look up the rate and other info used for each tx attempt. 952 *
929 * Each tx attempt steps one entry deeper in the rate table. */ 953 * For aggregation, all packets were transmitted at the same rate, the
930 tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags); 954 * first index into rate scale table.
931 rs_get_tbl_info_from_mcs(tx_rate, priv->band, 955 */
932 &tbl_type, &rs_index); 956 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
933 957 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
934 /* If type matches "search" table, 958 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
935 * add failure to "search" history */ 959 &rs_index);
936 if ((tbl_type.lq_type == search_tbl->lq_type) && 960 tpt = get_expected_tpt(curr_tbl, rs_index);
937 (tbl_type.ant_type == search_tbl->ant_type) && 961 rs_collect_tx_data(window, rs_index, tpt,
938 (tbl_type.is_SGI == search_tbl->is_SGI)) { 962 info->status.ampdu_ack_len,
939 if (search_tbl->expected_tpt) 963 info->status.ampdu_ack_map);
940 tpt = search_tbl->expected_tpt[rs_index]; 964
941 else 965 /* Update success/fail counts if not searching for new mode */
942 tpt = 0; 966 if (lq_sta->stay_in_tbl) {
943 rs_collect_tx_data(search_win, rs_index, tpt, 1, 0); 967 lq_sta->total_success += info->status.ampdu_ack_map;
944 968 lq_sta->total_failed += (info->status.ampdu_ack_len -
945 /* Else if type matches "current/active" table, 969 info->status.ampdu_ack_map);
946 * add failure to "current/active" history */
947 } else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
948 (tbl_type.ant_type == curr_tbl->ant_type) &&
949 (tbl_type.is_SGI == curr_tbl->is_SGI)) {
950 if (curr_tbl->expected_tpt)
951 tpt = curr_tbl->expected_tpt[rs_index];
952 else
953 tpt = 0;
954 rs_collect_tx_data(window, rs_index, tpt, 1, 0);
955 } 970 }
956 971 } else {
957 /* If not searching for a new mode, increment failed counter
958 * ... this helps determine when to start searching again */
959 if (lq_sta->stay_in_tbl)
960 lq_sta->total_failed++;
961 --retries;
962 index++;
963
964 }
965
966 /* 972 /*
967 * Find (by rate) the history window to update with final Tx attempt; 973 * For legacy, update frame history with for each Tx retry.
968 * if Tx was successful first try, use original rate,
969 * else look up the rate that was, finally, successful.
970 */ 974 */
971 tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags); 975 retries = info->status.rates[0].count - 1;
972 lq_sta->last_rate_n_flags = tx_rate; 976 /* HW doesn't send more than 15 retries */
973 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index); 977 retries = min(retries, 15);
974 978
975 /* Update frame history window with "success" if Tx got ACKed ... */ 979 /* The last transmission may have been successful */
976 status = !!(info->flags & IEEE80211_TX_STAT_ACK); 980 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
977 981 /* Collect data for each rate used during failed TX attempts */
978 /* If type matches "search" table, 982 for (i = 0; i <= retries; ++i) {
979 * add final tx status to "search" history */ 983 tx_rate = le32_to_cpu(table->rs_table[i].rate_n_flags);
980 if ((tbl_type.lq_type == search_tbl->lq_type) && 984 rs_get_tbl_info_from_mcs(tx_rate, priv->band,
981 (tbl_type.ant_type == search_tbl->ant_type) && 985 &tbl_type, &rs_index);
982 (tbl_type.is_SGI == search_tbl->is_SGI)) { 986 /*
983 if (search_tbl->expected_tpt) 987 * Only collect stats if retried rate is in the same RS
984 tpt = search_tbl->expected_tpt[rs_index]; 988 * table as active/search.
985 else 989 */
986 tpt = 0; 990 if (table_type_matches(&tbl_type, curr_tbl))
987 if (info->flags & IEEE80211_TX_STAT_AMPDU) 991 tpt = get_expected_tpt(curr_tbl, rs_index);
988 rs_collect_tx_data(search_win, rs_index, tpt, 992 else if (table_type_matches(&tbl_type, other_tbl))
989 info->status.ampdu_ack_len, 993 tpt = get_expected_tpt(other_tbl, rs_index);
990 info->status.ampdu_ack_map); 994 else
991 else 995 continue;
992 rs_collect_tx_data(search_win, rs_index, tpt,
993 1, status);
994 /* Else if type matches "current/active" table,
995 * add final tx status to "current/active" history */
996 } else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
997 (tbl_type.ant_type == curr_tbl->ant_type) &&
998 (tbl_type.is_SGI == curr_tbl->is_SGI)) {
999 if (curr_tbl->expected_tpt)
1000 tpt = curr_tbl->expected_tpt[rs_index];
1001 else
1002 tpt = 0;
1003 if (info->flags & IEEE80211_TX_STAT_AMPDU)
1004 rs_collect_tx_data(window, rs_index, tpt,
1005 info->status.ampdu_ack_len,
1006 info->status.ampdu_ack_map);
1007 else
1008 rs_collect_tx_data(window, rs_index, tpt,
1009 1, status);
1010 }
1011 996
1012 /* If not searching for new mode, increment success/failed counter 997 /* Constants mean 1 transmission, 0 successes */
1013 * ... these help determine when to start searching again */ 998 if (i < retries)
1014 if (lq_sta->stay_in_tbl) { 999 rs_collect_tx_data(window, rs_index, tpt, 1,
1015 if (info->flags & IEEE80211_TX_STAT_AMPDU) { 1000 0);
1016 lq_sta->total_success += info->status.ampdu_ack_map;
1017 lq_sta->total_failed +=
1018 (info->status.ampdu_ack_len - info->status.ampdu_ack_map);
1019 } else {
1020 if (status)
1021 lq_sta->total_success++;
1022 else 1001 else
1023 lq_sta->total_failed++; 1002 rs_collect_tx_data(window, rs_index, tpt, 1,
1003 legacy_success);
1004 }
1005
1006 /* Update success/fail counts if not searching for new mode */
1007 if (lq_sta->stay_in_tbl) {
1008 lq_sta->total_success += legacy_success;
1009 lq_sta->total_failed += retries + (1 - legacy_success);
1024 } 1010 }
1025 } 1011 }
1012 /* The last TX rate is cached in lq_sta; it's set in if/else above */
1013 lq_sta->last_rate_n_flags = tx_rate;
1026 1014
1027 /* See if there's a better rate or modulation mode to try. */ 1015 /* See if there's a better rate or modulation mode to try. */
1028 if (sta && sta->supp_rates[sband->band]) 1016 if (sta && sta->supp_rates[sband->band])
1029 rs_rate_scale_perform(priv, skb, sta, lq_sta); 1017 rs_rate_scale_perform(priv, skb, sta, lq_sta);
1030out:
1031 return;
1032} 1018}
1033 1019
1034/* 1020/*