diff options
author | Eyal Shapira <eyal@wizery.com> | 2013-12-10 17:55:36 -0500 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2013-12-17 12:39:56 -0500 |
commit | 4e4b815c08ce6257c15cede80b29247f1b88de04 (patch) | |
tree | 75b31bb07178c7969afdda515caeecea31c938c4 | |
parent | 4107dbd27758ada08303cfb51db4553156870554 (diff) |
iwlwifi: mvm: rs: refactor rate scale action decision
Extract the scale action decision to a different function
in preparation of modifying it. While at it also convert
the scale action values from hardcoded values to a clear enum.
Signed-off-by: Eyal Shapira <eyal@wizery.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/rs.c | 186 |
1 files changed, 103 insertions, 83 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 6d0bd45b0791..62b29d7f80f0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
@@ -130,6 +130,12 @@ static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = { | |||
130 | IWL_DECLARE_MCS_RATE(9), /* MCS 9 */ | 130 | IWL_DECLARE_MCS_RATE(9), /* MCS 9 */ |
131 | }; | 131 | }; |
132 | 132 | ||
133 | enum rs_action { | ||
134 | RS_ACTION_STAY = 0, | ||
135 | RS_ACTION_DOWNSCALE = -1, | ||
136 | RS_ACTION_UPSCALE = 1, | ||
137 | }; | ||
138 | |||
133 | enum rs_column_mode { | 139 | enum rs_column_mode { |
134 | RS_INVALID = 0, | 140 | RS_INVALID = 0, |
135 | RS_LEGACY, | 141 | RS_LEGACY, |
@@ -1616,6 +1622,97 @@ err: | |||
1616 | return -1; | 1622 | return -1; |
1617 | } | 1623 | } |
1618 | 1624 | ||
1625 | static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm, | ||
1626 | struct iwl_scale_tbl_info *tbl, | ||
1627 | s32 sr, int low, int high, | ||
1628 | int current_tpt, | ||
1629 | int low_tpt, int high_tpt) | ||
1630 | { | ||
1631 | enum rs_action action = RS_ACTION_STAY; | ||
1632 | |||
1633 | /* Too many failures, decrease rate */ | ||
1634 | if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) { | ||
1635 | IWL_DEBUG_RATE(mvm, | ||
1636 | "decrease rate because of low SR\n"); | ||
1637 | action = RS_ACTION_DOWNSCALE; | ||
1638 | /* No throughput measured yet for adjacent rates; try increase. */ | ||
1639 | } else if ((low_tpt == IWL_INVALID_VALUE) && | ||
1640 | (high_tpt == IWL_INVALID_VALUE)) { | ||
1641 | if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) { | ||
1642 | IWL_DEBUG_RATE(mvm, | ||
1643 | "Good SR and no high rate measurement. " | ||
1644 | "Increase rate\n"); | ||
1645 | action = RS_ACTION_UPSCALE; | ||
1646 | } else if (low != IWL_RATE_INVALID) { | ||
1647 | IWL_DEBUG_RATE(mvm, | ||
1648 | "Remain in current rate\n"); | ||
1649 | action = RS_ACTION_STAY; | ||
1650 | } | ||
1651 | } | ||
1652 | |||
1653 | /* Both adjacent throughputs are measured, but neither one has better | ||
1654 | * throughput; we're using the best rate, don't change it! | ||
1655 | */ | ||
1656 | else if ((low_tpt != IWL_INVALID_VALUE) && | ||
1657 | (high_tpt != IWL_INVALID_VALUE) && | ||
1658 | (low_tpt < current_tpt) && | ||
1659 | (high_tpt < current_tpt)) { | ||
1660 | IWL_DEBUG_RATE(mvm, | ||
1661 | "Both high and low are worse. " | ||
1662 | "Maintain rate\n"); | ||
1663 | action = RS_ACTION_STAY; | ||
1664 | } | ||
1665 | |||
1666 | /* At least one adjacent rate's throughput is measured, | ||
1667 | * and may have better performance. | ||
1668 | */ | ||
1669 | else { | ||
1670 | /* Higher adjacent rate's throughput is measured */ | ||
1671 | if (high_tpt != IWL_INVALID_VALUE) { | ||
1672 | /* Higher rate has better throughput */ | ||
1673 | if (high_tpt > current_tpt && | ||
1674 | sr >= IWL_RATE_INCREASE_TH) { | ||
1675 | IWL_DEBUG_RATE(mvm, | ||
1676 | "Higher rate is better and good " | ||
1677 | "SR. Increate rate\n"); | ||
1678 | action = RS_ACTION_UPSCALE; | ||
1679 | } else { | ||
1680 | IWL_DEBUG_RATE(mvm, | ||
1681 | "Higher rate isn't better OR " | ||
1682 | "no good SR. Maintain rate\n"); | ||
1683 | action = RS_ACTION_STAY; | ||
1684 | } | ||
1685 | |||
1686 | /* Lower adjacent rate's throughput is measured */ | ||
1687 | } else if (low_tpt != IWL_INVALID_VALUE) { | ||
1688 | /* Lower rate has better throughput */ | ||
1689 | if (low_tpt > current_tpt) { | ||
1690 | IWL_DEBUG_RATE(mvm, | ||
1691 | "Lower rate is better. " | ||
1692 | "Decrease rate\n"); | ||
1693 | action = RS_ACTION_DOWNSCALE; | ||
1694 | } else if (sr >= IWL_RATE_INCREASE_TH) { | ||
1695 | IWL_DEBUG_RATE(mvm, | ||
1696 | "Lower rate isn't better and " | ||
1697 | "good SR. Increase rate\n"); | ||
1698 | action = RS_ACTION_UPSCALE; | ||
1699 | } | ||
1700 | } | ||
1701 | } | ||
1702 | |||
1703 | /* Sanity check; asked for decrease, but success rate or throughput | ||
1704 | * has been good at old rate. Don't change it. | ||
1705 | */ | ||
1706 | if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID) && | ||
1707 | ((sr > IWL_RATE_HIGH_TH) || | ||
1708 | (current_tpt > (100 * tbl->expected_tpt[low])))) { | ||
1709 | IWL_DEBUG_RATE(mvm, | ||
1710 | "Sanity check failed. Maintain rate\n"); | ||
1711 | action = RS_ACTION_STAY; | ||
1712 | } | ||
1713 | |||
1714 | return action; | ||
1715 | } | ||
1619 | 1716 | ||
1620 | /* | 1717 | /* |
1621 | * Do rate scaling and search for new modulation mode. | 1718 | * Do rate scaling and search for new modulation mode. |
@@ -1636,7 +1733,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, | |||
1636 | int low_tpt = IWL_INVALID_VALUE; | 1733 | int low_tpt = IWL_INVALID_VALUE; |
1637 | int high_tpt = IWL_INVALID_VALUE; | 1734 | int high_tpt = IWL_INVALID_VALUE; |
1638 | u32 fail_count; | 1735 | u32 fail_count; |
1639 | s8 scale_action = 0; | 1736 | enum rs_action scale_action = RS_ACTION_STAY; |
1640 | u16 rate_mask; | 1737 | u16 rate_mask; |
1641 | u8 update_lq = 0; | 1738 | u8 update_lq = 0; |
1642 | struct iwl_scale_tbl_info *tbl, *tbl1; | 1739 | struct iwl_scale_tbl_info *tbl, *tbl1; |
@@ -1830,85 +1927,8 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, | |||
1830 | rs_pretty_lq_type(rate->type), index, current_tpt, sr, | 1927 | rs_pretty_lq_type(rate->type), index, current_tpt, sr, |
1831 | low, high, low_tpt, high_tpt); | 1928 | low, high, low_tpt, high_tpt); |
1832 | 1929 | ||
1833 | scale_action = 0; | 1930 | scale_action = rs_get_rate_action(mvm, tbl, sr, low, high, |
1834 | 1931 | current_tpt, low_tpt, high_tpt); | |
1835 | /* Too many failures, decrease rate */ | ||
1836 | if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) { | ||
1837 | IWL_DEBUG_RATE(mvm, | ||
1838 | "decrease rate because of low SR\n"); | ||
1839 | scale_action = -1; | ||
1840 | /* No throughput measured yet for adjacent rates; try increase. */ | ||
1841 | } else if ((low_tpt == IWL_INVALID_VALUE) && | ||
1842 | (high_tpt == IWL_INVALID_VALUE)) { | ||
1843 | if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) { | ||
1844 | IWL_DEBUG_RATE(mvm, | ||
1845 | "Good SR and no high rate measurement. " | ||
1846 | "Increase rate\n"); | ||
1847 | scale_action = 1; | ||
1848 | } else if (low != IWL_RATE_INVALID) { | ||
1849 | IWL_DEBUG_RATE(mvm, | ||
1850 | "Remain in current rate\n"); | ||
1851 | scale_action = 0; | ||
1852 | } | ||
1853 | } | ||
1854 | |||
1855 | /* Both adjacent throughputs are measured, but neither one has better | ||
1856 | * throughput; we're using the best rate, don't change it! */ | ||
1857 | else if ((low_tpt != IWL_INVALID_VALUE) && | ||
1858 | (high_tpt != IWL_INVALID_VALUE) && | ||
1859 | (low_tpt < current_tpt) && | ||
1860 | (high_tpt < current_tpt)) { | ||
1861 | IWL_DEBUG_RATE(mvm, | ||
1862 | "Both high and low are worse. " | ||
1863 | "Maintain rate\n"); | ||
1864 | scale_action = 0; | ||
1865 | } | ||
1866 | |||
1867 | /* At least one adjacent rate's throughput is measured, | ||
1868 | * and may have better performance. */ | ||
1869 | else { | ||
1870 | /* Higher adjacent rate's throughput is measured */ | ||
1871 | if (high_tpt != IWL_INVALID_VALUE) { | ||
1872 | /* Higher rate has better throughput */ | ||
1873 | if (high_tpt > current_tpt && | ||
1874 | sr >= IWL_RATE_INCREASE_TH) { | ||
1875 | IWL_DEBUG_RATE(mvm, | ||
1876 | "Higher rate is better and good " | ||
1877 | "SR. Increate rate\n"); | ||
1878 | scale_action = 1; | ||
1879 | } else { | ||
1880 | IWL_DEBUG_RATE(mvm, | ||
1881 | "Higher rate isn't better OR " | ||
1882 | "no good SR. Maintain rate\n"); | ||
1883 | scale_action = 0; | ||
1884 | } | ||
1885 | |||
1886 | /* Lower adjacent rate's throughput is measured */ | ||
1887 | } else if (low_tpt != IWL_INVALID_VALUE) { | ||
1888 | /* Lower rate has better throughput */ | ||
1889 | if (low_tpt > current_tpt) { | ||
1890 | IWL_DEBUG_RATE(mvm, | ||
1891 | "Lower rate is better. " | ||
1892 | "Decrease rate\n"); | ||
1893 | scale_action = -1; | ||
1894 | } else if (sr >= IWL_RATE_INCREASE_TH) { | ||
1895 | IWL_DEBUG_RATE(mvm, | ||
1896 | "Lower rate isn't better and " | ||
1897 | "good SR. Increase rate\n"); | ||
1898 | scale_action = 1; | ||
1899 | } | ||
1900 | } | ||
1901 | } | ||
1902 | |||
1903 | /* Sanity check; asked for decrease, but success rate or throughput | ||
1904 | * has been good at old rate. Don't change it. */ | ||
1905 | if ((scale_action == -1) && (low != IWL_RATE_INVALID) && | ||
1906 | ((sr > IWL_RATE_HIGH_TH) || | ||
1907 | (current_tpt > (100 * tbl->expected_tpt[low])))) { | ||
1908 | IWL_DEBUG_RATE(mvm, | ||
1909 | "Sanity check failed. Maintain rate\n"); | ||
1910 | scale_action = 0; | ||
1911 | } | ||
1912 | 1932 | ||
1913 | /* Force a search in case BT doesn't like us being in MIMO */ | 1933 | /* Force a search in case BT doesn't like us being in MIMO */ |
1914 | if (is_mimo(rate) && | 1934 | if (is_mimo(rate) && |
@@ -1920,7 +1940,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, | |||
1920 | } | 1940 | } |
1921 | 1941 | ||
1922 | switch (scale_action) { | 1942 | switch (scale_action) { |
1923 | case -1: | 1943 | case RS_ACTION_DOWNSCALE: |
1924 | /* Decrease starting rate, update uCode's rate table */ | 1944 | /* Decrease starting rate, update uCode's rate table */ |
1925 | if (low != IWL_RATE_INVALID) { | 1945 | if (low != IWL_RATE_INVALID) { |
1926 | update_lq = 1; | 1946 | update_lq = 1; |
@@ -1931,7 +1951,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, | |||
1931 | } | 1951 | } |
1932 | 1952 | ||
1933 | break; | 1953 | break; |
1934 | case 1: | 1954 | case RS_ACTION_UPSCALE: |
1935 | /* Increase starting rate, update uCode's rate table */ | 1955 | /* Increase starting rate, update uCode's rate table */ |
1936 | if (high != IWL_RATE_INVALID) { | 1956 | if (high != IWL_RATE_INVALID) { |
1937 | update_lq = 1; | 1957 | update_lq = 1; |
@@ -1942,7 +1962,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, | |||
1942 | } | 1962 | } |
1943 | 1963 | ||
1944 | break; | 1964 | break; |
1945 | case 0: | 1965 | case RS_ACTION_STAY: |
1946 | /* No change */ | 1966 | /* No change */ |
1947 | default: | 1967 | default: |
1948 | break; | 1968 | break; |