When a HT node leaves or reassociates as a non-HT node,
clear HT capabilities stored in its node cache object.
A node may switch from 11n mode to 11a/b/g mode.
If we don't clear HT capabilities from the cache the node will
be mistaken as 11n-capable after reassociation.
Index: ieee80211_input.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v
retrieving revision 1.181
diff -u -p -r1.181 ieee80211_input.c
--- ieee80211_input.c 9 Jan 2017 12:40:00 -0000 1.181
+++ ieee80211_input.c 9 Jan 2017 19:13:00 -0000
@@ -1802,6 +1802,8 @@ ieee80211_recv_probe_req(struct ieee8021
}
if (htcaps)
ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
+ else
+ ieee80211_clear_htcaps(ni);
IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
}
#endif /* IEEE80211_STA_ONLY */
@@ -2141,6 +2143,8 @@ ieee80211_recv_assoc_req(struct ieee8021
ni->ni_chan = ic->ic_bss->ni_chan;
if (htcaps)
ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
+ else
+ ieee80211_clear_htcaps(ni);
end:
if (status != 0) {
IEEE80211_SEND_MGMT(ic, ni, resp, status);
Index: ieee80211_node.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.c,v
retrieving revision 1.110
diff -u -p -r1.110 ieee80211_node.c
--- ieee80211_node.c 9 Jan 2017 16:24:20 -0000 1.110
+++ ieee80211_node.c 9 Jan 2017 19:16:17 -0000
@@ -1350,6 +1350,27 @@ ieee80211_setup_htcaps(struct ieee80211_
ni->ni_aselcaps = data[25];
}
+#ifndef IEEE80211_STA_ONLY
+/*
+ * Handle nodes switching from 11n into legacy modes.
+ */
+void
+ieee80211_clear_htcaps(struct ieee80211_node *ni)
+{
+ ni->ni_htcaps = 0;
+ ni->ni_ampdu_param = 0;
+ memset(ni->ni_rxmcs, 0, sizeof(ni->ni_rxmcs));
+ ni->ni_max_rxrate = 0;
+ ni->ni_tx_mcs_set = 0;
+ ni->ni_htxcaps = 0;
+ ni->ni_txbfcaps = 0;
+ ni->ni_aselcaps = 0;
+
+ ni->ni_flags &= ~IEEE80211_NODE_HT;
+
+}
+#endif
+
/*
* Install received HT op information in the node's state block.
*/
@@ -1626,6 +1647,8 @@ ieee80211_node_leave_ht(struct ieee80211
ba->ba_buf = NULL;
}
}
+
+ ieee80211_clear_htcaps(ni);
}
/*
Index: ieee80211_node.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.h,v
retrieving revision 1.63
diff -u -p -r1.63 ieee80211_node.h
--- ieee80211_node.h 21 Sep 2016 12:21:27 -0000 1.63
+++ ieee80211_node.h 9 Jan 2017 19:12:50 -0000
@@ -363,6 +363,7 @@ extern void ieee80211_clean_cached(struc
extern void ieee80211_clean_nodes(struct ieee80211com *, int);
void ieee80211_setup_htcaps(struct ieee80211_node *, const uint8_t *,
uint8_t);
+void ieee80211_clear_htcaps(struct ieee80211_node *);
int ieee80211_setup_htop(struct ieee80211_node *, const uint8_t *,
uint8_t);
extern int ieee80211_setup_rates(struct ieee80211com *,