aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c186
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
133enum rs_action {
134 RS_ACTION_STAY = 0,
135 RS_ACTION_DOWNSCALE = -1,
136 RS_ACTION_UPSCALE = 1,
137};
138
133enum rs_column_mode { 139enum 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
1625static 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;