aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorShanyu Zhao <shanyu.zhao@intel.com>2010-03-19 16:34:45 -0400
committerReinette Chatre <reinette.chatre@intel.com>2010-04-02 14:12:37 -0400
commit04f2dec1c3d375c4072613880f28f43b66524876 (patch)
treef0544c88fc1205197df3680a33fe75098bf50074 /drivers
parentdd48744964296b5713032ea1d66eb9e3d990e287 (diff)
iwlwifi: use consistent table for tx data collect
When collecting tx data for non-aggregation packets in rate scaling, if the tx data matches "other table", it still uses current table to update the stats and calculate average throughput in function rs_collect_tx_data(). This can mess up the rate scaling data structure and cause a kernel panic in a BUG_ON statement in rs_rate_scale_perform(). To fix this bug, we pass table pointer instead of window pointer (pointed to by table pointer) to function rs_collect_tx_data() so that the table being used is consistent. Signed-off-by: Shanyu Zhao <shanyu.zhao@intel.com> Signed-off-by: Henry Zhang <hongx.c.zhang@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c55
1 files changed, 24 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..be00cb3b1d0e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -345,6 +345,17 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
345 !!(rate_n_flags & RATE_MCS_ANT_C_MSK); 345 !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
346} 346}
347 347
348/*
349 * Static function to get the expected throughput from an iwl_scale_tbl_info
350 * that wraps a NULL pointer check
351 */
352static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
353{
354 if (tbl->expected_tpt)
355 return tbl->expected_tpt[rs_index];
356 return 0;
357}
358
348/** 359/**
349 * rs_collect_tx_data - Update the success/failure sliding window 360 * rs_collect_tx_data - Update the success/failure sliding window
350 * 361 *
@@ -352,19 +363,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 363 * at this rate. window->data contains the bitmask of successful
353 * packets. 364 * packets.
354 */ 365 */
355static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, 366static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
356 int scale_index, s32 tpt, int attempts, 367 int scale_index, int attempts, int successes)
357 int successes)
358{ 368{
359 struct iwl_rate_scale_data *window = NULL; 369 struct iwl_rate_scale_data *window = NULL;
360 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); 370 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
361 s32 fail_count; 371 s32 fail_count, tpt;
362 372
363 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) 373 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
364 return -EINVAL; 374 return -EINVAL;
365 375
366 /* Select window for current tx bit rate */ 376 /* Select window for current tx bit rate */
367 window = &(windows[scale_index]); 377 window = &(tbl->win[scale_index]);
378
379 /* Get expected throughput */
380 tpt = get_expected_tpt(tbl, scale_index);
368 381
369 /* 382 /*
370 * Keep track of only the latest 62 tx frame attempts in this rate's 383 * Keep track of only the latest 62 tx frame attempts in this rate's
@@ -738,16 +751,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) && 751 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
739 (a->is_SGI == b->is_SGI); 752 (a->is_SGI == b->is_SGI);
740} 753}
741/*
742 * Static function to get the expected throughput from an iwl_scale_tbl_info
743 * that wraps a NULL pointer check
744 */
745static 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 754
752/* 755/*
753 * mac80211 sends us Tx status 756 * mac80211 sends us Tx status
@@ -764,12 +767,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
764 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 767 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
765 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 768 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
766 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 769 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; 770 enum mac80211_rate_control_flags mac_flags;
769 u32 tx_rate; 771 u32 tx_rate;
770 struct iwl_scale_tbl_info tbl_type; 772 struct iwl_scale_tbl_info tbl_type;
771 struct iwl_scale_tbl_info *curr_tbl, *other_tbl; 773 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
772 s32 tpt = 0;
773 774
774 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); 775 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
775 776
@@ -852,7 +853,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"); 853 IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
853 return; 854 return;
854 } 855 }
855 window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
856 856
857 /* 857 /*
858 * Updating the frame history depends on whether packets were 858 * Updating the frame history depends on whether packets were
@@ -865,8 +865,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); 865 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, 866 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
867 &rs_index); 867 &rs_index);
868 tpt = get_expected_tpt(curr_tbl, rs_index); 868 rs_collect_tx_data(curr_tbl, rs_index,
869 rs_collect_tx_data(window, rs_index, tpt,
870 info->status.ampdu_ack_len, 869 info->status.ampdu_ack_len,
871 info->status.ampdu_ack_map); 870 info->status.ampdu_ack_map);
872 871
@@ -896,19 +895,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
896 * table as active/search. 895 * table as active/search.
897 */ 896 */
898 if (table_type_matches(&tbl_type, curr_tbl)) 897 if (table_type_matches(&tbl_type, curr_tbl))
899 tpt = get_expected_tpt(curr_tbl, rs_index); 898 tmp_tbl = curr_tbl;
900 else if (table_type_matches(&tbl_type, other_tbl)) 899 else if (table_type_matches(&tbl_type, other_tbl))
901 tpt = get_expected_tpt(other_tbl, rs_index); 900 tmp_tbl = other_tbl;
902 else 901 else
903 continue; 902 continue;
904 903 rs_collect_tx_data(tmp_tbl, rs_index, 1,
905 /* Constants mean 1 transmission, 0 successes */ 904 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 } 905 }
913 906
914 /* Update success/fail counts if not searching for new mode */ 907 /* Update success/fail counts if not searching for new mode */