Aruba 105 APs announce a mandatory Rx MCS set in association responses.
Specifically, they claim to require that all clients support MCS 0-31.
This seems very wrong, and I believe it's a bug in this brand of APs.

Because our Intel drivers only do MCS 0-16, and the AP tells us that
we're required to support MSC 0-31, we don't enable 11n with such APs.
However, the APs still behave as if we did 11n, and performance goes
down the drain as we throw away the aggregated frames they send at us.

However, in their beacons these APs announce different requirements:
No particular Rx MCS is required according to their beacons.

I checked the 802.11-2012 spec again and found that the mandatory
Rx MCS set is reserved for beacon and probe response frames only:

Table 8-130—HT Operation element fields and subfields, says:
  "Basic MCS Set | Indicates the MCS values that are supported by
   all HT STAs in the BSS.  Present in Beacon, Probe Response,
   Mesh Peering Open and Mesh Peering Confirm frames.
   Otherwise reserved."

Which means that one way to work around this without violating the spec
is to ignore Rx MCS requirements we receive in association responses.
This makes us do 11n with Aruba 105 APs -- download speed goes up from
about 80 kbit/s to 2.4MB/s.

OK?

Index: ieee80211_input.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v
retrieving revision 1.201
diff -u -p -r1.201 ieee80211_input.c
--- ieee80211_input.c   5 May 2018 06:58:05 -0000       1.201
+++ ieee80211_input.c   6 Aug 2018 17:50:52 -0000
@@ -1538,7 +1538,7 @@ ieee80211_recv_probe_resp(struct ieee802
 
        if (htcaps)
                ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
-       if (htop && !ieee80211_setup_htop(ni, htop + 2, htop[1]))
+       if (htop && !ieee80211_setup_htop(ni, htop + 2, htop[1], 1))
                htop = NULL; /* invalid HTOP */
 
        ni->ni_dtimcount = dtim_count;
@@ -2314,7 +2314,7 @@ ieee80211_recv_assoc_resp(struct ieee802
        if (htcaps)
                ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
        if (htop)
-               ieee80211_setup_htop(ni, htop + 2, htop[1]);
+               ieee80211_setup_htop(ni, htop + 2, htop[1], 0);
        ieee80211_ht_negotiate(ic, ni);
 
        /* Hop into 11n mode after associating to an HT AP in a non-11n mode. */
Index: ieee80211_node.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.c,v
retrieving revision 1.138
diff -u -p -r1.138 ieee80211_node.c
--- ieee80211_node.c    6 Aug 2018 11:28:01 -0000       1.138
+++ ieee80211_node.c    6 Aug 2018 17:49:26 -0000
@@ -1929,7 +1929,7 @@ ieee80211_clear_htcaps(struct ieee80211_
  */
 int
 ieee80211_setup_htop(struct ieee80211_node *ni, const uint8_t *data,
-    uint8_t len)
+    uint8_t len, int isprobe)
 {
        if (len != 22)
                return 0;
@@ -1940,7 +1940,8 @@ ieee80211_setup_htop(struct ieee80211_no
        ni->ni_htop1 = (data[2] | (data[3] << 8));
        ni->ni_htop2 = (data[3] | (data[4] << 8));
 
-       memcpy(ni->ni_basic_mcs, &data[6], sizeof(ni->ni_basic_mcs));
+       if (isprobe)
+               memcpy(ni->ni_basic_mcs, &data[6], sizeof(ni->ni_basic_mcs));
 
        return 1;
 }
Index: ieee80211_node.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.h,v
retrieving revision 1.75
diff -u -p -r1.75 ieee80211_node.h
--- ieee80211_node.h    11 Jul 2018 20:18:09 -0000      1.75
+++ ieee80211_node.h    6 Aug 2018 17:49:13 -0000
@@ -402,7 +402,7 @@ void ieee80211_setup_htcaps(struct ieee8
     uint8_t);
 void ieee80211_clear_htcaps(struct ieee80211_node *);
 int ieee80211_setup_htop(struct ieee80211_node *, const uint8_t *,
-    uint8_t);
+    uint8_t, int);
 int ieee80211_setup_rates(struct ieee80211com *,
            struct ieee80211_node *, const u_int8_t *, const u_int8_t *, int);
 int ieee80211_iserp_sta(const struct ieee80211_node *);

Reply via email to