diff mbox series

[1/6] Use LUT instead of macro

Message ID 20200602001018.83640-1-matthewmwang@chromium.org
State Accepted
Headers show
Series [1/6] Use LUT instead of macro | expand

Commit Message

Matthew Wang June 2, 2020, 12:10 a.m. UTC
Change INTERPOLATE_RATE macro to a lookup-table instead for the sake of
readability.

Signed-off-by: Matthew Wang <matthewmwang@chromium.org>
---
 wpa_supplicant/scan.c | 127 ++++++++++++++++++++++++++----------------
 1 file changed, 79 insertions(+), 48 deletions(-)

Comments

Jouni Malinen June 19, 2020, 3:59 p.m. UTC | #1
Thanks, I applied patches 1, 3, and 6. Patch 2/6 has an open question
and patches 4 and 5 did not work properly without 2/6, so I left them
waiting for the question on 2/6 to get resolved.
diff mbox series

Patch

diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index b47573094..85513779f 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -2186,6 +2186,63 @@  void scan_snr(struct wpa_scan_res *res)
 	}
 }
 
+/* Minimum SNR required to achieve a certain bitrate. */
+struct minsnr_bitrate_entry {
+	int minsnr;
+	unsigned int bitrate; /* in Mbps */
+};
+
+
+/* VHT needs to be enabled in order to achieve MCS8 and MCS9 rates. */
+static const int vht_mcs = 8;
+
+
+static struct minsnr_bitrate_entry vht20_table[] = {
+	{0, 0},
+	{2, 6500},   /* HT20 MCS0 */
+	{5, 13000},  /* HT20 MCS1 */
+	{9, 19500},  /* HT20 MCS2 */
+	{11, 26000}, /* HT20 MCS3 */
+	{15, 39000}, /* HT20 MCS4 */
+	{18, 52000}, /* HT20 MCS5 */
+	{20, 58500}, /* HT20 MCS6 */
+	{25, 65000}, /* HT20 MCS7 */
+	{29, 78000}, /* VHT20 MCS8 */
+	{-1, 78000}  /* SNR > 29 */
+};
+
+
+static struct minsnr_bitrate_entry vht40_table[] = {
+	{0, 0},
+	{5, 13500},   /* HT40 MCS0 */
+	{8, 27000},   /* HT40 MCS1 */
+	{12, 40500},  /* HT40 MCS2 */
+	{14, 54000},  /* HT40 MCS3 */
+	{18, 81000},  /* HT40 MCS4 */
+	{21, 108000}, /* HT40 MCS5 */
+	{23, 121500}, /* HT40 MCS6 */
+	{28, 135000}, /* HT40 MCS7 */
+	{32, 162000}, /* VHT40 MCS8 */
+	{34, 180000}, /* VHT40 MCS9 */
+	{-1, 180000}  /* SNR > 34 */
+};
+
+
+static struct minsnr_bitrate_entry vht80_table[] = {
+	{0, 0},
+	{8, 29300},   /* VHT80 MCS0 */
+	{11, 58500},  /* VHT80 MCS1 */
+	{15, 87800},  /* VHT80 MCS2 */
+	{17, 117000}, /* VHT80 MCS3 */
+	{21, 175500}, /* VHT80 MCS4 */
+	{24, 234000}, /* VHT80 MCS5 */
+	{26, 263300}, /* VHT80 MCS6 */
+	{31, 292500}, /* VHT80 MCS7 */
+	{35, 351000}, /* VHT80 MCS8 */
+	{37, 390000}, /* VHT80 MCS9 */
+	{-1, 390000}  /* SNR > 37 */
+};
+
 
 static unsigned int interpolate_rate(int snr, int snr0, int snr1,
 				     int rate0, int rate1)
@@ -2194,67 +2251,41 @@  static unsigned int interpolate_rate(int snr, int snr0, int snr1,
 }
 
 
-#define INTERPOLATE_RATE(snr0, snr1, rate0, rate1) \
-	if (snr < (snr1)) \
-		return interpolate_rate(snr, (snr0), (snr1), (rate0), (rate1))
+static unsigned int max_rate(struct minsnr_bitrate_entry table[],
+			     int snr, int vht)
+{
+	struct minsnr_bitrate_entry *prev, *entry = table;
+
+	while ((entry->minsnr != -1) &&
+	       (snr >= entry->minsnr) &&
+	       (vht || entry - table <= vht_mcs))
+		entry++;
+	if (entry == table)
+		return entry->bitrate;
+	prev = entry - 1;
+	if (entry->minsnr == -1 || (!vht && entry - table > vht_mcs))
+		return prev->bitrate;
+	return interpolate_rate(snr, prev->minsnr, entry->minsnr, prev->bitrate,
+				entry->bitrate);
+}
+
 
 static unsigned int max_ht20_rate(int snr, int vht)
 {
-	if (snr < 0)
-		return 0;
-	INTERPOLATE_RATE(0, 2, 0, 6500); /* HT20 MCS0 */
-	INTERPOLATE_RATE(2, 5, 6500, 13000); /* HT20 MCS1 */
-	INTERPOLATE_RATE(5, 9, 13000, 19500); /* HT20 MCS2 */
-	INTERPOLATE_RATE(9, 11, 19500, 26000); /* HT20 MCS3 */
-	INTERPOLATE_RATE(11, 15, 26000, 39000); /* HT20 MCS4 */
-	INTERPOLATE_RATE(15, 18, 39000, 52000); /* HT20 MCS5 */
-	INTERPOLATE_RATE(18, 20, 52000, 58500); /* HT20 MCS6 */
-	INTERPOLATE_RATE(20, 25, 58500, 65000); /* HT20 MCS7 */
-	if (!vht)
-		return 65000;
-	INTERPOLATE_RATE(25, 29, 65000, 78000); /* VHT20 MCS8 */
-	return 78000;
+	return max_rate(vht20_table, snr, vht);
 }
 
 
 static unsigned int max_ht40_rate(int snr, int vht)
 {
-	if (snr < 0)
-		return 0;
-	INTERPOLATE_RATE(0, 5, 0, 13500); /* HT40 MCS0 */
-	INTERPOLATE_RATE(5, 8, 13500, 27000); /* HT40 MCS1 */
-	INTERPOLATE_RATE(8, 12, 27000, 40500); /* HT40 MCS2 */
-	INTERPOLATE_RATE(12, 14, 40500, 54000); /* HT40 MCS3 */
-	INTERPOLATE_RATE(14, 18, 54000, 81000); /* HT40 MCS4 */
-	INTERPOLATE_RATE(18, 21, 81000, 108000); /* HT40 MCS5 */
-	INTERPOLATE_RATE(21, 23, 108000, 121500); /* HT40 MCS6 */
-	INTERPOLATE_RATE(23, 28, 121500, 135000); /* HT40 MCS7 */
-	if (!vht)
-		return 135000;
-	INTERPOLATE_RATE(28, 32, 135000, 162000); /* VHT40 MCS8 */
-	INTERPOLATE_RATE(32, 34, 162000, 180000); /* VHT40 MCS9 */
-	return 180000;
+	return max_rate(vht40_table, snr, vht);
 }
 
 
 static unsigned int max_vht80_rate(int snr)
 {
-	if (snr < 0)
-		return 0;
-	INTERPOLATE_RATE(0, 8, 0, 29300); /* VHT80 MCS0 */
-	INTERPOLATE_RATE(8, 11, 29300, 58500); /* VHT80 MCS1 */
-	INTERPOLATE_RATE(11, 15, 58500, 87800); /* VHT80 MCS2 */
-	INTERPOLATE_RATE(15, 17, 87800, 117000); /* VHT80 MCS3 */
-	INTERPOLATE_RATE(17, 21, 117000, 175500); /* VHT80 MCS4 */
-	INTERPOLATE_RATE(21, 24, 175500, 234000); /* VHT80 MCS5 */
-	INTERPOLATE_RATE(24, 26, 234000, 263300); /* VHT80 MCS6 */
-	INTERPOLATE_RATE(26, 31, 263300, 292500); /* VHT80 MCS7 */
-	INTERPOLATE_RATE(31, 35, 292500, 351000); /* VHT80 MCS8 */
-	INTERPOLATE_RATE(35, 37, 351000, 390000); /* VHT80 MCS9 */
-	return 390000;
-}
-
-#undef INTERPOLATE_RATE
+	return max_rate(vht80_table, snr, 1);
+}
 
 
 unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,