aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEyal Shapira <eyal@wizery.com>2014-04-05 19:42:18 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-04-13 09:51:04 -0400
commite53839eb9882c99d3781eab0fe1b2d4369a6a2cc (patch)
tree9eedaa4715a809d7508896a9d214dbd50e59e13c
parent198266a3c110e8a68895a24e937003f5da0c5f60 (diff)
iwlwifi: mvm: rs: fix and cleanup rs_get_rate_action
Change the down/upscale decision logic a bit to be based on different success ratio thresholds. This fixes the implementation compared to the rate scale algorithm which was planned to yield optimal results. Also fix a case where a lower rate wasn't explored despite being a potential for better throughput. While at it rewrite rs_get_rate_action to be more clear and clean. Cc: <stable@vger.kernel.org> [3.14] Signed-off-by: Eyal Shapira <eyalx.shapira@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c127
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h1
2 files changed, 60 insertions, 68 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index cd32ad54384e..97b8fac214a1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -1658,85 +1658,76 @@ static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm,
1658{ 1658{
1659 enum rs_action action = RS_ACTION_STAY; 1659 enum rs_action action = RS_ACTION_STAY;
1660 1660
1661 /* Too many failures, decrease rate */
1662 if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) { 1661 if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) {
1663 IWL_DEBUG_RATE(mvm, 1662 IWL_DEBUG_RATE(mvm,
1664 "decrease rate because of low SR\n"); 1663 "Decrease rate because of low SR\n");
1665 action = RS_ACTION_DOWNSCALE; 1664 return RS_ACTION_DOWNSCALE;
1666 /* No throughput measured yet for adjacent rates; try increase. */
1667 } else if ((low_tpt == IWL_INVALID_VALUE) &&
1668 (high_tpt == IWL_INVALID_VALUE)) {
1669 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) {
1670 IWL_DEBUG_RATE(mvm,
1671 "Good SR and no high rate measurement. "
1672 "Increase rate\n");
1673 action = RS_ACTION_UPSCALE;
1674 } else if (low != IWL_RATE_INVALID) {
1675 IWL_DEBUG_RATE(mvm,
1676 "Remain in current rate\n");
1677 action = RS_ACTION_STAY;
1678 }
1679 } 1665 }
1680 1666
1681 /* Both adjacent throughputs are measured, but neither one has better 1667 if ((low_tpt == IWL_INVALID_VALUE) &&
1682 * throughput; we're using the best rate, don't change it! 1668 (high_tpt == IWL_INVALID_VALUE) &&
1683 */ 1669 (high != IWL_RATE_INVALID)) {
1684 else if ((low_tpt != IWL_INVALID_VALUE) &&
1685 (high_tpt != IWL_INVALID_VALUE) &&
1686 (low_tpt < current_tpt) &&
1687 (high_tpt < current_tpt)) {
1688 IWL_DEBUG_RATE(mvm, 1670 IWL_DEBUG_RATE(mvm,
1689 "Both high and low are worse. " 1671 "No data about high/low rates. Increase rate\n");
1690 "Maintain rate\n"); 1672 return RS_ACTION_UPSCALE;
1691 action = RS_ACTION_STAY;
1692 } 1673 }
1693 1674
1694 /* At least one adjacent rate's throughput is measured, 1675 if ((high_tpt == IWL_INVALID_VALUE) &&
1695 * and may have better performance. 1676 (high != IWL_RATE_INVALID) &&
1696 */ 1677 (low_tpt != IWL_INVALID_VALUE) &&
1697 else { 1678 (low_tpt < current_tpt)) {
1698 /* Higher adjacent rate's throughput is measured */ 1679 IWL_DEBUG_RATE(mvm,
1699 if (high_tpt != IWL_INVALID_VALUE) { 1680 "No data about high rate and low rate is worse. Increase rate\n");
1700 /* Higher rate has better throughput */ 1681 return RS_ACTION_UPSCALE;
1701 if (high_tpt > current_tpt && 1682 }
1702 sr >= IWL_RATE_INCREASE_TH) {
1703 IWL_DEBUG_RATE(mvm,
1704 "Higher rate is better and good "
1705 "SR. Increate rate\n");
1706 action = RS_ACTION_UPSCALE;
1707 } else {
1708 IWL_DEBUG_RATE(mvm,
1709 "Higher rate isn't better OR "
1710 "no good SR. Maintain rate\n");
1711 action = RS_ACTION_STAY;
1712 }
1713 1683
1714 /* Lower adjacent rate's throughput is measured */ 1684 if ((high_tpt != IWL_INVALID_VALUE) &&
1715 } else if (low_tpt != IWL_INVALID_VALUE) { 1685 (high_tpt > current_tpt)) {
1716 /* Lower rate has better throughput */ 1686 IWL_DEBUG_RATE(mvm,
1717 if (low_tpt > current_tpt) { 1687 "Higher rate is better. Increate rate\n");
1718 IWL_DEBUG_RATE(mvm, 1688 return RS_ACTION_UPSCALE;
1719 "Lower rate is better. "
1720 "Decrease rate\n");
1721 action = RS_ACTION_DOWNSCALE;
1722 } else if (sr >= IWL_RATE_INCREASE_TH) {
1723 IWL_DEBUG_RATE(mvm,
1724 "Lower rate isn't better and "
1725 "good SR. Increase rate\n");
1726 action = RS_ACTION_UPSCALE;
1727 }
1728 }
1729 } 1689 }
1730 1690
1731 /* Sanity check; asked for decrease, but success rate or throughput 1691 if ((low_tpt != IWL_INVALID_VALUE) &&
1732 * has been good at old rate. Don't change it. 1692 (high_tpt != IWL_INVALID_VALUE) &&
1733 */ 1693 (low_tpt < current_tpt) &&
1734 if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID) && 1694 (high_tpt < current_tpt)) {
1735 ((sr > IWL_RATE_HIGH_TH) ||
1736 (current_tpt > (100 * tbl->expected_tpt[low])))) {
1737 IWL_DEBUG_RATE(mvm, 1695 IWL_DEBUG_RATE(mvm,
1738 "Sanity check failed. Maintain rate\n"); 1696 "Both high and low are worse. Maintain rate\n");
1739 action = RS_ACTION_STAY; 1697 return RS_ACTION_STAY;
1698 }
1699
1700 if ((low_tpt != IWL_INVALID_VALUE) &&
1701 (low_tpt > current_tpt)) {
1702 IWL_DEBUG_RATE(mvm,
1703 "Lower rate is better\n");
1704 action = RS_ACTION_DOWNSCALE;
1705 goto out;
1706 }
1707
1708 if ((low_tpt == IWL_INVALID_VALUE) &&
1709 (low != IWL_RATE_INVALID)) {
1710 IWL_DEBUG_RATE(mvm,
1711 "No data about lower rate\n");
1712 action = RS_ACTION_DOWNSCALE;
1713 goto out;
1714 }
1715
1716 IWL_DEBUG_RATE(mvm, "Maintain rate\n");
1717
1718out:
1719 if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) {
1720 if (sr >= RS_SR_NO_DECREASE) {
1721 IWL_DEBUG_RATE(mvm,
1722 "SR is above NO DECREASE. Avoid downscale\n");
1723 action = RS_ACTION_STAY;
1724 } else if (current_tpt > (100 * tbl->expected_tpt[low])) {
1725 IWL_DEBUG_RATE(mvm,
1726 "Current TPT is higher than max expected in low rate. Avoid downscale\n");
1727 action = RS_ACTION_STAY;
1728 } else {
1729 IWL_DEBUG_RATE(mvm, "Decrease rate\n");
1730 }
1740 } 1731 }
1741 1732
1742 return action; 1733 return action;
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 9892d92d5901..fbb476aadb22 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -156,6 +156,7 @@ enum {
156#define IWL_RATE_HIGH_TH 10880 /* 85% */ 156#define IWL_RATE_HIGH_TH 10880 /* 85% */
157#define IWL_RATE_INCREASE_TH 6400 /* 50% */ 157#define IWL_RATE_INCREASE_TH 6400 /* 50% */
158#define RS_SR_FORCE_DECREASE 1920 /* 15% */ 158#define RS_SR_FORCE_DECREASE 1920 /* 15% */
159#define RS_SR_NO_DECREASE 10880 /* 85% */
159 160
160#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ 161#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
161#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000) 162#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)