summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2017-04-10 11:17:44 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2017-04-10 11:17:44 +0200
commit2c8ee0919c2848f2593d39f335358558763db678 (patch)
tree7b7fc898fe639b86fe65f85e278e43cecbbac4e3
parentd96e0d776cb7fd6d66fd2fb98fb0c07ef4d41a18 (diff)
downloadNetworkManager-th/wifi-ap-max-rate-bgo779771.tar.gz
Revert "wifi: use highest rate IE field instead of MCSs for VHT"th/wifi-ap-max-rate-bgo779771
This reverts commit d96e0d776cb7fd6d66fd2fb98fb0c07ef4d41a18.
-rw-r--r--src/devices/wifi/nm-wifi-ap.c142
1 files changed, 138 insertions, 4 deletions
diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c
index f3ab45ef72..c45eaafa93 100644
--- a/src/devices/wifi/nm-wifi-ap.c
+++ b/src/devices/wifi/nm-wifi-ap.c
@@ -517,6 +517,114 @@ get_max_rate_ht_40 (int mcs)
return 0;
}
+static guint32
+get_max_rate_vht_80_ss1 (int mcs)
+{
+ switch (mcs) {
+ case 0: return 29300000;
+ case 1: return 58500000;
+ case 2: return 87800000;
+ case 3: return 117000000;
+ case 4: return 175500000;
+ case 5: return 234000000;
+ case 6: return 263300000;
+ case 7: return 292500000;
+ case 8: return 351000000;
+ case 9: return 390000000;
+ }
+ return 0;
+}
+
+static guint32
+get_max_rate_vht_80_ss2 (int mcs)
+{
+ switch (mcs) {
+ case 0: return 58500000;
+ case 1: return 117000000;
+ case 2: return 175500000;
+ case 3: return 234000000;
+ case 4: return 351000000;
+ case 5: return 468000000;
+ case 6: return 526500000;
+ case 7: return 585000000;
+ case 8: return 702000000;
+ case 9: return 780000000;
+ }
+ return 0;
+}
+
+static guint32
+get_max_rate_vht_80_ss3 (int mcs)
+{
+ switch (mcs) {
+ case 0: return 87800000;
+ case 1: return 175500000;
+ case 2: return 263300000;
+ case 3: return 351000000;
+ case 4: return 526500000;
+ case 5: return 702000000;
+ case 6: return 0;
+ case 7: return 877500000;
+ case 8: return 105300000;
+ case 9: return 117000000;
+ }
+ return 0;
+}
+
+static guint32
+get_max_rate_vht_160_ss1 (int mcs)
+{
+ switch (mcs) {
+ case 0: return 58500000;
+ case 1: return 117000000;
+ case 2: return 175500000;
+ case 3: return 234000000;
+ case 4: return 351000000;
+ case 5: return 468000000;
+ case 6: return 526500000;
+ case 7: return 585000000;
+ case 8: return 702000000;
+ case 9: return 780000000;
+ }
+ return 0;
+}
+
+static guint32
+get_max_rate_vht_160_ss2 (int mcs)
+{
+ switch (mcs) {
+ case 0: return 117000000;
+ case 1: return 234000000;
+ case 2: return 351000000;
+ case 3: return 468000000;
+ case 4: return 702000000;
+ case 5: return 936000000;
+ case 6: return 1053000000;
+ case 7: return 1170000000;
+ case 8: return 1404000000;
+ case 9: return 1560000000;
+ }
+ return 0;
+}
+
+static guint32
+get_max_rate_vht_160_ss3 (int mcs)
+{
+ switch (mcs) {
+ case 0: return 175500000;
+ case 1: return 351000000;
+ case 2: return 526500000;
+ case 3: return 702000000;
+ case 4: return 1053000000;
+ case 5: return 1404000000;
+ case 6: return 1579500000;
+ case 7: return 1755000000;
+ case 8: return 2106000000;
+ case 9: return 0;
+ }
+ return 0;
+}
+
static gboolean
get_max_rate_ht (const guint8 *bytes, guint len, guint32 *out_maxrate)
{
@@ -560,7 +668,8 @@ get_max_rate_ht (const guint8 *bytes, guint len, guint32 *out_maxrate)
static gboolean
get_max_rate_vht (const guint8 *bytes, guint len, guint32 *out_maxrate)
{
- guint16 tx_rate;
+ guint32 mcs, m;
+ guint8 vht_cap, tx_map;
/* https://tda802dot11.blogspot.it/2014/10/vht-capabilities-element-vht.html
* http://chimera.labs.oreilly.com/books/1234000001739/ch03.html#management_frames */
@@ -568,11 +677,36 @@ get_max_rate_vht (const guint8 *bytes, guint len, guint32 *out_maxrate)
if (len != 12)
return FALSE;
- tx_rate = bytes[10] | (bytes[11] << 8);
- tx_rate = (tx_rate & 0x1fff) * 1000000;
+ vht_cap = bytes[0];
+ tx_map = bytes[8];
- *out_maxrate = tx_rate;
+ /* Check for mcs rates 8 and 9 support */
+ if (tx_map & 0x2a)
+ mcs = 9;
+ else if (tx_map & 0x15)
+ mcs = 8;
+ else
+ mcs = 7;
+
+ /* Check for 160Mhz wide channel support and
+ * spatial stream support */
+ if (vht_cap & (1 << 2)) {
+ if (tx_map & 0x30)
+ m = get_max_rate_vht_160_ss3 (mcs);
+ else if (tx_map & 0x0C)
+ m = get_max_rate_vht_160_ss2 (mcs);
+ else
+ m = get_max_rate_vht_160_ss1 (mcs);
+ } else {
+ if (tx_map & 0x30)
+ m = get_max_rate_vht_80_ss3 (mcs);
+ else if (tx_map & 0x0C)
+ m = get_max_rate_vht_80_ss2 (mcs);
+ else
+ m = get_max_rate_vht_80_ss1 (mcs);
+ }
+ *out_maxrate = m;
return TRUE;
}