aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
diff options
context:
space:
mode:
authorGuy Cohen <guy.cohen@intel.com>2008-04-23 20:15:03 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-07 15:02:19 -0400
commit07bc28ed87424af13f622b7c4e2a1bff06112d94 (patch)
tree316d92d2f65fcfa9b85b0f1e26b133f3dbc3b47e /drivers/net/wireless/iwlwifi/iwl-4965-rs.c
parentf935a6daa07ac78a35d1513fc61c88774b628a4c (diff)
iwlwifi: more RS improvements
Main changes: 1. no need to re-calculate expected_tpt when only toggling antenna 2. changing the code to be more strict on input and status of variables 3. enhanced debug prints 4. move to search table only if improving tpt (don't move if SR is improved but tpt is not) Signed-off-by: Guy Cohen <guy.cohen@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-4965-rs.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.c121
1 files changed, 56 insertions, 65 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 5129d57ed591..c8c54b14920d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -178,8 +178,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
178 struct sta_info *sta); 178 struct sta_info *sta);
179static void rs_fill_link_cmd(const struct iwl_priv *priv, 179static void rs_fill_link_cmd(const struct iwl_priv *priv,
180 struct iwl4965_lq_sta *lq_sta, 180 struct iwl4965_lq_sta *lq_sta,
181 u32 rate_n_flags, 181 u32 rate_n_flags);
182 struct iwl_link_quality_cmd *tbl);
183 182
184 183
185#ifdef CONFIG_MAC80211_DEBUGFS 184#ifdef CONFIG_MAC80211_DEBUGFS
@@ -1320,7 +1319,6 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1320 lq_sta->action_counter++; 1319 lq_sta->action_counter++;
1321 1320
1322 /* Don't change antenna if success has been great */ 1321 /* Don't change antenna if success has been great */
1323 /*FIXME:RS:not sure this is really needed*/
1324 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1322 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1325 break; 1323 break;
1326 1324
@@ -1329,7 +1327,6 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1329 1327
1330 if (rs_toggle_antenna(valid_tx_ant, 1328 if (rs_toggle_antenna(valid_tx_ant,
1331 &search_tbl->current_rate, search_tbl)) { 1329 &search_tbl->current_rate, search_tbl)) {
1332 rs_set_expected_tpt_table(lq_sta, search_tbl);
1333 lq_sta->search_better_tbl = 1; 1330 lq_sta->search_better_tbl = 1;
1334 goto out; 1331 goto out;
1335 } 1332 }
@@ -1410,7 +1407,6 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1410 switch (tbl->action) { 1407 switch (tbl->action) {
1411 case IWL_SISO_SWITCH_ANTENNA: 1408 case IWL_SISO_SWITCH_ANTENNA:
1412 IWL_DEBUG_RATE("LQ: SISO toggle Antenna\n"); 1409 IWL_DEBUG_RATE("LQ: SISO toggle Antenna\n");
1413 /*FIXME:RS: is this really needed for SISO?*/
1414 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1410 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1415 break; 1411 break;
1416 1412
@@ -1738,27 +1734,16 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1738 if (!rate_scale_index_msk) 1734 if (!rate_scale_index_msk)
1739 rate_scale_index_msk = rate_mask; 1735 rate_scale_index_msk = rate_mask;
1740 1736
1741 /* If current rate is no longer supported on current association, 1737 if (!((1 << index) & rate_scale_index_msk)) {
1742 * or user changed preferences for rates, find a new supported rate. */ 1738 IWL_ERROR("Current Rate is not valid\n");
1743 if (index < 0 || !((1 << index) & rate_scale_index_msk)) { 1739 return;
1744 index = IWL_INVALID_VALUE;
1745 update_lq = 1;
1746
1747 /* get the highest available rate */
1748 for (i = 0; i <= IWL_RATE_COUNT; i++) {
1749 if ((1 << i) & rate_scale_index_msk)
1750 index = i;
1751 }
1752
1753 if (index == IWL_INVALID_VALUE) {
1754 IWL_WARNING("Can not find a suitable rate\n");
1755 return;
1756 }
1757 } 1740 }
1758 1741
1759 /* Get expected throughput table and history window for current rate */ 1742 /* Get expected throughput table and history window for current rate */
1760 if (!tbl->expected_tpt) 1743 if (!tbl->expected_tpt) {
1761 rs_set_expected_tpt_table(lq_sta, tbl); 1744 IWL_ERROR("tbl->expected_tpt is NULL\n");
1745 return;
1746 }
1762 1747
1763 window = &(tbl->win[index]); 1748 window = &(tbl->win[index]);
1764 1749
@@ -1770,10 +1755,9 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1770 * in current association (use new rate found above). 1755 * in current association (use new rate found above).
1771 */ 1756 */
1772 fail_count = window->counter - window->success_counter; 1757 fail_count = window->counter - window->success_counter;
1773 if (((fail_count < IWL_RATE_MIN_FAILURE_TH) && 1758 if ((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
1774 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) 1759 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {
1775 || (tbl->expected_tpt == NULL)) { 1760 IWL_DEBUG_RATE("LQ: still below TH. succ=%d total=%d "
1776 IWL_DEBUG_RATE("LQ: still below TH succ %d total %d "
1777 "for index %d\n", 1761 "for index %d\n",
1778 window->success_counter, window->counter, index); 1762 window->success_counter, window->counter, index);
1779 1763
@@ -1784,44 +1768,51 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1784 * or search for a new one? */ 1768 * or search for a new one? */
1785 rs_stay_in_table(lq_sta); 1769 rs_stay_in_table(lq_sta);
1786 1770
1787 /* Set up new rate table in uCode, if needed */
1788 if (update_lq) {
1789 rate = rate_n_flags_from_tbl(tbl, index, is_green);
1790 rs_fill_link_cmd(priv, lq_sta, rate, &lq_sta->lq);
1791 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
1792 }
1793 goto out; 1771 goto out;
1794 1772
1795 /* Else we have enough samples; calculate estimate of 1773 /* Else we have enough samples; calculate estimate of
1796 * actual average throughput */ 1774 * actual average throughput */
1797 } else 1775 } else {
1798 window->average_tpt = ((window->success_ratio * 1776 /*FIXME:RS remove this else if we don't get this error*/
1777 if (window->average_tpt != ((window->success_ratio *
1778 tbl->expected_tpt[index] + 64) / 128)) {
1779 IWL_ERROR("expected_tpt should have been calculated"
1780 " by now\n");
1781 window->average_tpt = ((window->success_ratio *
1799 tbl->expected_tpt[index] + 64) / 128); 1782 tbl->expected_tpt[index] + 64) / 128);
1783 }
1784 }
1800 1785
1801 /* If we are searching for better modulation mode, check success. */ 1786 /* If we are searching for better modulation mode, check success. */
1802 if (lq_sta->search_better_tbl) { 1787 if (lq_sta->search_better_tbl) {
1803 int success_limit = IWL_RATE_SCALE_SWITCH;
1804 1788
1805 /* If good success, continue using the "search" mode; 1789 /* If good success, continue using the "search" mode;
1806 * no need to send new link quality command, since we're 1790 * no need to send new link quality command, since we're
1807 * continuing to use the setup that we've been trying. */ 1791 * continuing to use the setup that we've been trying. */
1808 if ((window->success_ratio > success_limit) || 1792 if (window->average_tpt > lq_sta->last_tpt) {
1809 (window->average_tpt > lq_sta->last_tpt)) { 1793
1810 if (!is_legacy(tbl->lq_type)) { 1794 IWL_DEBUG_RATE("LQ: SWITCHING TO CURRENT TABLE "
1811 IWL_DEBUG_RATE("LQ: we are switching to HT" 1795 "suc=%d cur-tpt=%d old-tpt=%d\n",
1812 " rate suc %d current tpt %d" 1796 window->success_ratio,
1813 " old tpt %d\n", 1797 window->average_tpt,
1814 window->success_ratio, 1798 lq_sta->last_tpt);
1815 window->average_tpt, 1799
1816 lq_sta->last_tpt); 1800 if (!is_legacy(tbl->lq_type))
1817 lq_sta->enable_counter = 1; 1801 lq_sta->enable_counter = 1;
1818 } 1802
1819 /* Swap tables; "search" becomes "active" */ 1803 /* Swap tables; "search" becomes "active" */
1820 lq_sta->active_tbl = active_tbl; 1804 lq_sta->active_tbl = active_tbl;
1821 current_tpt = window->average_tpt; 1805 current_tpt = window->average_tpt;
1822 1806
1823 /* Else poor success; go back to mode in "active" table */ 1807 /* Else poor success; go back to mode in "active" table */
1824 } else { 1808 } else {
1809
1810 IWL_DEBUG_RATE("LQ: GOING BACK TO THE OLD TABLE "
1811 "suc=%d cur-tpt=%d old-tpt=%d\n",
1812 window->success_ratio,
1813 window->average_tpt,
1814 lq_sta->last_tpt);
1815
1825 /* Nullify "search" table */ 1816 /* Nullify "search" table */
1826 tbl->lq_type = LQ_NONE; 1817 tbl->lq_type = LQ_NONE;
1827 1818
@@ -1836,7 +1827,6 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1836 1827
1837 /* Need to set up a new rate table in uCode */ 1828 /* Need to set up a new rate table in uCode */
1838 update_lq = 1; 1829 update_lq = 1;
1839 IWL_DEBUG_RATE("XXY GO BACK TO OLD TABLE\n");
1840 } 1830 }
1841 1831
1842 /* Either way, we've made a decision; modulation mode 1832 /* Either way, we've made a decision; modulation mode
@@ -1952,7 +1942,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1952 /* Replace uCode's rate table for the destination station. */ 1942 /* Replace uCode's rate table for the destination station. */
1953 if (update_lq) { 1943 if (update_lq) {
1954 rate = rate_n_flags_from_tbl(tbl, index, is_green); 1944 rate = rate_n_flags_from_tbl(tbl, index, is_green);
1955 rs_fill_link_cmd(priv, lq_sta, rate, &lq_sta->lq); 1945 rs_fill_link_cmd(priv, lq_sta, rate);
1956 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 1946 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
1957 } 1947 }
1958 1948
@@ -1991,8 +1981,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1991 1981
1992 IWL_DEBUG_RATE("Switch current mcs: %X index: %d\n", 1982 IWL_DEBUG_RATE("Switch current mcs: %X index: %d\n",
1993 tbl->current_rate, index); 1983 tbl->current_rate, index);
1994 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate, 1984 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
1995 &lq_sta->lq);
1996 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 1985 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
1997 } 1986 }
1998 1987
@@ -2109,7 +2098,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2109 rate = rate_n_flags_from_tbl(tbl, rate_idx, use_green); 2098 rate = rate_n_flags_from_tbl(tbl, rate_idx, use_green);
2110 tbl->current_rate = rate; 2099 tbl->current_rate = rate;
2111 rs_set_expected_tpt_table(lq_sta, tbl); 2100 rs_set_expected_tpt_table(lq_sta, tbl);
2112 rs_fill_link_cmd(NULL, lq_sta, rate, &lq_sta->lq); 2101 rs_fill_link_cmd(NULL, lq_sta, rate);
2113 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 2102 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
2114 out: 2103 out:
2115 return; 2104 return;
@@ -2220,7 +2209,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
2220 for (i = 0; i < IWL_RATE_COUNT; i++) 2209 for (i = 0; i < IWL_RATE_COUNT; i++)
2221 rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); 2210 rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i]));
2222 2211
2223 IWL_DEBUG_RATE("rate scale global init\n"); 2212 IWL_DEBUG_RATE("LQ: *** rate scale global init ***\n");
2224 /* TODO: what is a good starting rate for STA? About middle? Maybe not 2213 /* TODO: what is a good starting rate for STA? About middle? Maybe not
2225 * the lowest or the highest rate.. Could consider using RSSI from 2214 * the lowest or the highest rate.. Could consider using RSSI from
2226 * previous packets? Need to have IEEE 802.1X auth succeed immediately 2215 * previous packets? Need to have IEEE 802.1X auth succeed immediately
@@ -2292,11 +2281,15 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
2292 lq_sta->active_mimo3_rate &= ~((u16)0x2); 2281 lq_sta->active_mimo3_rate &= ~((u16)0x2);
2293 lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE; 2282 lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
2294 2283
2295 IWL_DEBUG_RATE("SISO RATE %X MIMO2 RATE %X MIMO3 RATE %X\n", 2284 IWL_DEBUG_RATE("SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n",
2296 lq_sta->active_siso_rate, 2285 lq_sta->active_siso_rate,
2297 lq_sta->active_mimo2_rate, 2286 lq_sta->active_mimo2_rate,
2298 lq_sta->active_mimo3_rate); 2287 lq_sta->active_mimo3_rate);
2299 2288
2289 /* These values will be overriden later */
2290 lq_sta->lq.general_params.single_stream_ant_msk = ANT_A;
2291 lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB;
2292
2300 /* as default allow aggregation for all tids */ 2293 /* as default allow aggregation for all tids */
2301 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; 2294 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
2302#endif /*CONFIG_IWL4965_HT*/ 2295#endif /*CONFIG_IWL4965_HT*/
@@ -2312,8 +2305,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
2312 2305
2313static void rs_fill_link_cmd(const struct iwl_priv *priv, 2306static void rs_fill_link_cmd(const struct iwl_priv *priv,
2314 struct iwl4965_lq_sta *lq_sta, 2307 struct iwl4965_lq_sta *lq_sta,
2315 u32 new_rate, 2308 u32 new_rate)
2316 struct iwl_link_quality_cmd *lq_cmd)
2317{ 2309{
2318 struct iwl4965_scale_tbl_info tbl_type; 2310 struct iwl4965_scale_tbl_info tbl_type;
2319 int index = 0; 2311 int index = 0;
@@ -2322,6 +2314,7 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
2322 u8 ant_toggle_cnt = 0; 2314 u8 ant_toggle_cnt = 0;
2323 u8 use_ht_possible = 1; 2315 u8 use_ht_possible = 1;
2324 u8 valid_tx_ant = 0; 2316 u8 valid_tx_ant = 0;
2317 struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq;
2325 2318
2326 /* Override starting rate (index 0) if needed for debug purposes */ 2319 /* Override starting rate (index 0) if needed for debug purposes */
2327 rs_dbgfs_set_mcs(lq_sta, &new_rate, index); 2320 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
@@ -2345,13 +2338,13 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
2345 /* Fill 1st table entry (index 0) */ 2338 /* Fill 1st table entry (index 0) */
2346 lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate); 2339 lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate);
2347 2340
2348 /*FIXME:RS*/ 2341 if (num_of_ant(tbl_type.ant_type) == 1) {
2349 if (is_mimo(tbl_type.lq_type) || (tbl_type.ant_type == ANT_A)) 2342 lq_cmd->general_params.single_stream_ant_msk =
2350 lq_cmd->general_params.single_stream_ant_msk 2343 tbl_type.ant_type;
2351 = LINK_QUAL_ANT_A_MSK; 2344 } else if (num_of_ant(tbl_type.ant_type) == 2) {
2352 else 2345 lq_cmd->general_params.dual_stream_ant_msk =
2353 lq_cmd->general_params.single_stream_ant_msk 2346 tbl_type.ant_type;
2354 = LINK_QUAL_ANT_B_MSK; 2347 } /* otherwise we don't modify the existing value */
2355 2348
2356 index++; 2349 index++;
2357 repeat_rate--; 2350 repeat_rate--;
@@ -2425,7 +2418,6 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
2425 repeat_rate--; 2418 repeat_rate--;
2426 } 2419 }
2427 2420
2428 lq_cmd->general_params.dual_stream_ant_msk = 3;
2429 lq_cmd->agg_params.agg_dis_start_th = 3; 2421 lq_cmd->agg_params.agg_dis_start_th = 3;
2430 lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000); 2422 lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000);
2431} 2423}
@@ -2512,8 +2504,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2512 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); 2504 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
2513 2505
2514 if (lq_sta->dbg_fixed_rate) { 2506 if (lq_sta->dbg_fixed_rate) {
2515 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate, 2507 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
2516 &lq_sta->lq);
2517 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC); 2508 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC);
2518 } 2509 }
2519 2510