2019-06-12 19:36:37

by Sven Eckelmann

[permalink] [raw]
Subject: [PATCH v3 0/3] mac80211/ath11k: HE mesh support

Hi,

Some features of 802.11ax without central organizing (AP) STA can also be
used in mesh mode. The main goal is to get HE mesh working with ath11k.
For persons without ath11k compatible hw, hwsim can be used in the as basis
for further development of these features.


* v3

- force ath11k PHY mode for meshpoint vif to HE mode to avoid hang of
firmware when HE (or VHT on 2.4GHz) device tries to connect

* v2:

- add of ath11k patch

* v1:

- initial RFC


Kind regards,
Sven

Sven Eckelmann (3):
mac80211_hwsim: Register support for HE meshpoint
mac80211: implement HE support for mesh
ath11k: register HE mesh capabilities

drivers/net/wireless/ath/ath11k/mac.c | 63 ++++++
drivers/net/wireless/mac80211_hwsim.c | 283 +++++++++++++++++---------
include/net/cfg80211.h | 19 ++
net/mac80211/ieee80211_i.h | 2 +
net/mac80211/mesh.c | 61 ++++++
net/mac80211/mesh.h | 4 +
net/mac80211/mesh_plink.c | 11 +-
net/mac80211/util.c | 52 +++++
8 files changed, 400 insertions(+), 95 deletions(-)

--
2.20.1


2019-06-12 19:36:38

by Sven Eckelmann

[permalink] [raw]
Subject: [PATCH v3 1/3] mac80211_hwsim: Register support for HE meshpoint

From: Sven Eckelmann <[email protected]>

Some features of 802.11ax without central organizing (AP) STA can also be
used in mesh mode. hwsim can be used to assist initial development of these
features without having access to HW.

Signed-off-by: Sven Eckelmann <[email protected]>
---
drivers/net/wireless/mac80211_hwsim.c | 283 +++++++++++++++++---------
1 file changed, 189 insertions(+), 94 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 524eb5805995..e4d542f08b7c 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2501,116 +2501,211 @@ static void hwsim_mcast_new_radio(int id, struct genl_info *info,
nlmsg_free(mcast_skb);
}

-static const struct ieee80211_sband_iftype_data he_capa_2ghz = {
- /* TODO: should we support other types, e.g., P2P?*/
- .types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP),
- .he_cap = {
- .has_he = true,
- .he_cap_elem = {
- .mac_cap_info[0] =
- IEEE80211_HE_MAC_CAP0_HTC_HE,
- .mac_cap_info[1] =
- IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
- IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
- .mac_cap_info[2] =
- IEEE80211_HE_MAC_CAP2_BSR |
- IEEE80211_HE_MAC_CAP2_MU_CASCADING |
- IEEE80211_HE_MAC_CAP2_ACK_EN,
- .mac_cap_info[3] =
- IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
- .phy_cap_info[1] =
- IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
- IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
- IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
- IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
- .phy_cap_info[2] =
- IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
- IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
- IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ |
- IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
- IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO,
-
- /* Leave all the other PHY capability bytes unset, as
- * DCM, beam forming, RU and PPE threshold information
- * are not supported
- */
+static const struct ieee80211_sband_iftype_data he_capa_2ghz[] = {
+ {
+ /* TODO: should we support other types, e.g., P2P?*/
+ .types_mask = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_AP),
+ .he_cap = {
+ .has_he = true,
+ .he_cap_elem = {
+ .mac_cap_info[0] =
+ IEEE80211_HE_MAC_CAP0_HTC_HE,
+ .mac_cap_info[1] =
+ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
+ IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
+ .mac_cap_info[2] =
+ IEEE80211_HE_MAC_CAP2_BSR |
+ IEEE80211_HE_MAC_CAP2_MU_CASCADING |
+ IEEE80211_HE_MAC_CAP2_ACK_EN,
+ .mac_cap_info[3] =
+ IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
+ .phy_cap_info[1] =
+ IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
+ IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
+ IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
+ .phy_cap_info[2] =
+ IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
+ IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
+ IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ |
+ IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
+ IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO,
+
+ /* Leave all the other PHY capability bytes
+ * unset, as DCM, beam forming, RU and PPE
+ * threshold information are not supported
+ */
+ },
+ .he_mcs_nss_supp = {
+ .rx_mcs_80 = cpu_to_le16(0xfffa),
+ .tx_mcs_80 = cpu_to_le16(0xfffa),
+ .rx_mcs_160 = cpu_to_le16(0xffff),
+ .tx_mcs_160 = cpu_to_le16(0xffff),
+ .rx_mcs_80p80 = cpu_to_le16(0xffff),
+ .tx_mcs_80p80 = cpu_to_le16(0xffff),
+ },
},
- .he_mcs_nss_supp = {
- .rx_mcs_80 = cpu_to_le16(0xfffa),
- .tx_mcs_80 = cpu_to_le16(0xfffa),
- .rx_mcs_160 = cpu_to_le16(0xffff),
- .tx_mcs_160 = cpu_to_le16(0xffff),
- .rx_mcs_80p80 = cpu_to_le16(0xffff),
- .tx_mcs_80p80 = cpu_to_le16(0xffff),
+ },
+#ifdef CONFIG_MAC80211_MESH
+ {
+ /* TODO: should we support other types, e.g., IBSS?*/
+ .types_mask = BIT(NL80211_IFTYPE_MESH_POINT),
+ .he_cap = {
+ .has_he = true,
+ .he_cap_elem = {
+ .mac_cap_info[0] =
+ IEEE80211_HE_MAC_CAP0_HTC_HE,
+ .mac_cap_info[1] =
+ IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
+ .mac_cap_info[2] =
+ IEEE80211_HE_MAC_CAP2_ACK_EN,
+ .mac_cap_info[3] =
+ IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
+ .phy_cap_info[1] =
+ IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
+ IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
+ IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
+ .phy_cap_info[2] = 0,
+
+ /* Leave all the other PHY capability bytes
+ * unset, as DCM, beam forming, RU and PPE
+ * threshold information are not supported
+ */
+ },
+ .he_mcs_nss_supp = {
+ .rx_mcs_80 = cpu_to_le16(0xfffa),
+ .tx_mcs_80 = cpu_to_le16(0xfffa),
+ .rx_mcs_160 = cpu_to_le16(0xffff),
+ .tx_mcs_160 = cpu_to_le16(0xffff),
+ .rx_mcs_80p80 = cpu_to_le16(0xffff),
+ .tx_mcs_80p80 = cpu_to_le16(0xffff),
+ },
},
},
+#endif
};

-static const struct ieee80211_sband_iftype_data he_capa_5ghz = {
- /* TODO: should we support other types, e.g., P2P?*/
- .types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP),
- .he_cap = {
- .has_he = true,
- .he_cap_elem = {
- .mac_cap_info[0] =
- IEEE80211_HE_MAC_CAP0_HTC_HE,
- .mac_cap_info[1] =
- IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
- IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
- .mac_cap_info[2] =
- IEEE80211_HE_MAC_CAP2_BSR |
- IEEE80211_HE_MAC_CAP2_MU_CASCADING |
- IEEE80211_HE_MAC_CAP2_ACK_EN,
- .mac_cap_info[3] =
- IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
- .phy_cap_info[0] =
- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G,
- .phy_cap_info[1] =
- IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
- IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
- IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
- IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
- .phy_cap_info[2] =
- IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
- IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
- IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ |
- IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
- IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO,
-
- /* Leave all the other PHY capability bytes unset, as
- * DCM, beam forming, RU and PPE threshold information
- * are not supported
- */
+static const struct ieee80211_sband_iftype_data he_capa_5ghz[] = {
+ {
+ /* TODO: should we support other types, e.g., P2P?*/
+ .types_mask = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_AP),
+ .he_cap = {
+ .has_he = true,
+ .he_cap_elem = {
+ .mac_cap_info[0] =
+ IEEE80211_HE_MAC_CAP0_HTC_HE,
+ .mac_cap_info[1] =
+ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
+ IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
+ .mac_cap_info[2] =
+ IEEE80211_HE_MAC_CAP2_BSR |
+ IEEE80211_HE_MAC_CAP2_MU_CASCADING |
+ IEEE80211_HE_MAC_CAP2_ACK_EN,
+ .mac_cap_info[3] =
+ IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
+ .phy_cap_info[0] =
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G,
+ .phy_cap_info[1] =
+ IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
+ IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
+ IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
+ .phy_cap_info[2] =
+ IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
+ IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
+ IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ |
+ IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
+ IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO,
+
+ /* Leave all the other PHY capability bytes
+ * unset, as DCM, beam forming, RU and PPE
+ * threshold information are not supported
+ */
+ },
+ .he_mcs_nss_supp = {
+ .rx_mcs_80 = cpu_to_le16(0xfffa),
+ .tx_mcs_80 = cpu_to_le16(0xfffa),
+ .rx_mcs_160 = cpu_to_le16(0xfffa),
+ .tx_mcs_160 = cpu_to_le16(0xfffa),
+ .rx_mcs_80p80 = cpu_to_le16(0xfffa),
+ .tx_mcs_80p80 = cpu_to_le16(0xfffa),
+ },
},
- .he_mcs_nss_supp = {
- .rx_mcs_80 = cpu_to_le16(0xfffa),
- .tx_mcs_80 = cpu_to_le16(0xfffa),
- .rx_mcs_160 = cpu_to_le16(0xfffa),
- .tx_mcs_160 = cpu_to_le16(0xfffa),
- .rx_mcs_80p80 = cpu_to_le16(0xfffa),
- .tx_mcs_80p80 = cpu_to_le16(0xfffa),
+ },
+#ifdef CONFIG_MAC80211_MESH
+ {
+ /* TODO: should we support other types, e.g., IBSS?*/
+ .types_mask = BIT(NL80211_IFTYPE_MESH_POINT),
+ .he_cap = {
+ .has_he = true,
+ .he_cap_elem = {
+ .mac_cap_info[0] =
+ IEEE80211_HE_MAC_CAP0_HTC_HE,
+ .mac_cap_info[1] =
+ IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
+ .mac_cap_info[2] =
+ IEEE80211_HE_MAC_CAP2_ACK_EN,
+ .mac_cap_info[3] =
+ IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
+ .phy_cap_info[0] =
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G,
+ .phy_cap_info[1] =
+ IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
+ IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
+ IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
+ .phy_cap_info[2] = 0,
+
+ /* Leave all the other PHY capability bytes
+ * unset, as DCM, beam forming, RU and PPE
+ * threshold information are not supported
+ */
+ },
+ .he_mcs_nss_supp = {
+ .rx_mcs_80 = cpu_to_le16(0xfffa),
+ .tx_mcs_80 = cpu_to_le16(0xfffa),
+ .rx_mcs_160 = cpu_to_le16(0xfffa),
+ .tx_mcs_160 = cpu_to_le16(0xfffa),
+ .rx_mcs_80p80 = cpu_to_le16(0xfffa),
+ .tx_mcs_80p80 = cpu_to_le16(0xfffa),
+ },
},
},
+#endif
};

static void mac80211_hswim_he_capab(struct ieee80211_supported_band *sband)
{
- if (sband->band == NL80211_BAND_2GHZ)
+ u16 n_iftype_data;
+
+ if (sband->band == NL80211_BAND_2GHZ) {
+ n_iftype_data = ARRAY_SIZE(he_capa_2ghz);
sband->iftype_data =
- (struct ieee80211_sband_iftype_data *)&he_capa_2ghz;
- else if (sband->band == NL80211_BAND_5GHZ)
+ (struct ieee80211_sband_iftype_data *)he_capa_2ghz;
+ } else if (sband->band == NL80211_BAND_5GHZ) {
+ n_iftype_data = ARRAY_SIZE(he_capa_5ghz);
sband->iftype_data =
- (struct ieee80211_sband_iftype_data *)&he_capa_5ghz;
- else
+ (struct ieee80211_sband_iftype_data *)he_capa_5ghz;
+ } else {
return;
+ }

- sband->n_iftype_data = 1;
+ sband->n_iftype_data = n_iftype_data;
}

#ifdef CONFIG_MAC80211_MESH
--
2.20.1

2019-06-12 19:36:45

by Sven Eckelmann

[permalink] [raw]
Subject: [PATCH v3 3/3] ath11k: register HE mesh capabilities

From: Sven Eckelmann <[email protected]>

The capabilities for the HE mesh are generated from the capabilities
reported by the fw. But the firmware only reports the overall capabilities
and not the one which are specific for mesh. Some of them (TWT, MU UL/DL,
TB PPDU, ...) require an infrastructure setup with a main STA (AP)
controlling the operations. This is not the case for mesh and thus these
capabilities are removed from the list of capabilities.

Signed-off-by: Sven Eckelmann <[email protected]>
---
drivers/net/wireless/ath/ath11k/mac.c | 63 +++++++++++++++++++++++++++
1 file changed, 63 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 8c47e09a84e7..b55a98902fba 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -3274,6 +3274,7 @@ static int ath11k_mac_copy_he_cap(struct ath11k *ar,
switch (i) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_MESH_POINT:
break;

default:
@@ -3314,6 +3315,61 @@ static int ath11k_mac_copy_he_cap(struct ath11k *ar,
he_cap_elem->phy_cap_info[9] |=
IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU;
break;
+ case NL80211_IFTYPE_MESH_POINT:
+ he_cap_elem->mac_cap_info[0] &=
+ ~(IEEE80211_HE_MAC_CAP0_TWT_RES |
+ IEEE80211_HE_MAC_CAP0_TWT_REQ);
+ he_cap_elem->mac_cap_info[2] &=
+ ~(IEEE80211_HE_MAC_CAP2_TRS |
+ IEEE80211_HE_MAC_CAP2_BCAST_TWT |
+ IEEE80211_HE_MAC_CAP2_MU_CASCADING);
+ he_cap_elem->mac_cap_info[3] &=
+ ~(IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED |
+ IEEE80211_HE_MAC_CAP2_BCAST_TWT |
+ IEEE80211_HE_MAC_CAP2_MU_CASCADING);
+ he_cap_elem->mac_cap_info[4] &=
+ ~(IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG |
+ IEEE80211_HE_MAC_CAP4_BQR);
+ he_cap_elem->mac_cap_info[5] &=
+ ~(IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECVITE_TRANSMISSION |
+ IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU |
+ IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING |
+ IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX);
+
+ he_cap_elem->phy_cap_info[2] &=
+ ~(IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
+ IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO);
+ he_cap_elem->phy_cap_info[3] &=
+ ~(IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA |
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK |
+ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK);
+ he_cap_elem->phy_cap_info[4] &=
+ ~IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;
+ he_cap_elem->phy_cap_info[5] &=
+ ~IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK;
+ he_cap_elem->phy_cap_info[6] &=
+ ~(IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
+ IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
+ IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO);
+ he_cap_elem->phy_cap_info[7] &=
+ ~(IEEE80211_HE_PHY_CAP7_SRP_BASED_SR |
+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
+ IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ |
+ IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ);
+ he_cap_elem->phy_cap_info[8] &=
+ ~(IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
+ IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
+ IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
+ IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU);
+ he_cap_elem->phy_cap_info[9] &=
+ ~(IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM |
+ IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |
+ IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU |
+ IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |
+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
+ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB);
+ break;
}

he_cap->he_mcs_nss_supp.rx_mcs_80 =
@@ -4239,6 +4295,13 @@ ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif,
int he_support = arvif->vif->bss_conf.he_support;
int ret = 0;

+ /* mesh_point interfaces don't use bss_conf.he_support and still
+ * requires HE PHY mode to be set during vdev restart to avoid
+ * FW hangs when a sta with HE support tries to associate
+ */
+ if (arvif->vif->type == NL80211_IFTYPE_MESH_POINT)
+ he_support = true;
+
lockdep_assert_held(&ar->conf_mutex);

reinit_completion(&ar->vdev_setup_done);
--
2.20.1

2019-06-12 19:37:42

by Sven Eckelmann

[permalink] [raw]
Subject: [PATCH v3 2/3] mac80211: implement HE support for mesh

From: Sven Eckelmann <[email protected]>

Implement the basics required for supporting high efficiency with mesh:
include HE information elements in beacons, probe responses, and peering
action frames, and check for compatible HE configurations when peering.

Signed-off-by: Sven Eckelmann <[email protected]>
---
include/net/cfg80211.h | 19 ++++++++++++
net/mac80211/ieee80211_i.h | 2 ++
net/mac80211/mesh.c | 61 ++++++++++++++++++++++++++++++++++++++
net/mac80211/mesh.h | 4 +++
net/mac80211/mesh_plink.c | 11 ++++++-
net/mac80211/util.c | 52 ++++++++++++++++++++++++++++++++
6 files changed, 148 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 13bfeb712d36..9caa0ca5020d 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -399,6 +399,25 @@ ieee80211_get_he_sta_cap(const struct ieee80211_supported_band *sband)
return NULL;
}

+/**
+ * ieee80211_get_he_mesh_cap - return HE capabilities for an sband's mesh STA
+ * @sband: the sband to search for the mesh STA on
+ *
+ * Return: pointer to the struct ieee80211_sta_he_cap, or NULL is none found
+ */
+static inline const struct ieee80211_sta_he_cap *
+ieee80211_get_he_mesh_cap(const struct ieee80211_supported_band *sband)
+{
+ const struct ieee80211_sband_iftype_data *data =
+ ieee80211_get_sband_iftype_data(sband,
+ NL80211_IFTYPE_MESH_POINT);
+
+ if (data && data->he_cap.has_he)
+ return &data->he_cap;
+
+ return NULL;
+}
+
/**
* wiphy_read_of_freq_limits - read frequency limits from device tree
*
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 159eb9506bdc..8a3b74b3f356 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -2130,9 +2130,11 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
u32 cap);
u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
const struct cfg80211_chan_def *chandef);
+u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata);
u8 *ieee80211_ie_build_he_cap(u8 *pos,
const struct ieee80211_sta_he_cap *he_cap,
u8 *end);
+u8 *ieee80211_ie_build_he_oper(u8 *pos);
int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
const struct ieee80211_supported_band *sband,
const u8 *srates, int srates_len, u32 *rates);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 766e5e5bab8a..47ef885c4060 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -535,6 +535,61 @@ int mesh_add_vht_oper_ie(struct ieee80211_sub_if_data *sdata,
return 0;
}

+int mesh_add_he_cap_ie(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb, u8 ie_len)
+{
+ const struct ieee80211_sta_he_cap *he_cap;
+ struct ieee80211_supported_band *sband;
+ u8 *pos;
+
+ sband = ieee80211_get_sband(sdata);
+ if (!sband)
+ return -EINVAL;
+
+ he_cap = ieee80211_get_he_mesh_cap(sband);
+
+ if (!he_cap ||
+ sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
+ sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
+ sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
+ return 0;
+
+ if (skb_tailroom(skb) < ie_len)
+ return -ENOMEM;
+
+ pos = skb_put(skb, ie_len);
+ ieee80211_ie_build_he_cap(pos, he_cap, pos + ie_len);
+
+ return 0;
+}
+
+int mesh_add_he_oper_ie(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb)
+{
+ const struct ieee80211_sta_he_cap *he_cap;
+ struct ieee80211_supported_band *sband;
+ u8 *pos;
+
+ sband = ieee80211_get_sband(sdata);
+ if (!sband)
+ return -EINVAL;
+
+ he_cap = ieee80211_get_he_mesh_cap(sband);
+ if (!he_cap ||
+ sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
+ sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
+ sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
+ return 0;
+
+ if (skb_tailroom(skb) < 2 + 1 + sizeof(struct ieee80211_he_operation))
+ return -ENOMEM;
+
+ pos = skb_put(skb, 2 + 1 + sizeof(struct ieee80211_he_operation));
+ ieee80211_ie_build_he_oper(pos);
+
+ return 0;
+}
+
static void ieee80211_mesh_path_timer(struct timer_list *t)
{
struct ieee80211_sub_if_data *sdata =
@@ -680,6 +735,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
struct ieee80211_chanctx_conf *chanctx_conf;
struct mesh_csa_settings *csa;
enum nl80211_band band;
+ u8 ie_len_he_cap;
u8 *pos;
struct ieee80211_sub_if_data *sdata;
int hdr_len = offsetofend(struct ieee80211_mgmt, u.beacon);
@@ -690,6 +746,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
band = chanctx_conf->def.chan->band;
rcu_read_unlock();

+ ie_len_he_cap = ieee80211_ie_len_he_cap(sdata);
head_len = hdr_len +
2 + /* NULL SSID */
/* Channel Switch Announcement */
@@ -709,6 +766,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
2 + sizeof(__le16) + /* awake window */
2 + sizeof(struct ieee80211_vht_cap) +
2 + sizeof(struct ieee80211_vht_operation) +
+ ie_len_he_cap +
+ 2 + 1 + sizeof(struct ieee80211_he_operation) +
ifmsh->ie_len;

bcn = kzalloc(sizeof(*bcn) + head_len + tail_len, GFP_KERNEL);
@@ -826,6 +885,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
mesh_add_awake_window_ie(sdata, skb) ||
mesh_add_vht_cap_ie(sdata, skb) ||
mesh_add_vht_oper_ie(sdata, skb) ||
+ mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) ||
+ mesh_add_he_oper_ie(sdata, skb) ||
mesh_add_vendor_ies(sdata, skb))
goto out_free;

diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 574c3891c4b2..af1d9154b255 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -221,6 +221,10 @@ int mesh_add_vht_cap_ie(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb);
int mesh_add_vht_oper_ie(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb);
+int mesh_add_he_cap_ie(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb, u8 ie_len);
+int mesh_add_he_oper_ie(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb);
void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
void ieee80211s_init(void);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 8afd0ece94c9..e18e433fde29 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -221,9 +221,11 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
bool include_plid = false;
u16 peering_proto = 0;
u8 *pos, ie_len = 4;
+ u8 ie_len_he_cap;
int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.self_prot);
int err = -ENOMEM;

+ ie_len_he_cap = ieee80211_ie_len_he_cap(sdata);
skb = dev_alloc_skb(local->tx_headroom +
hdr_len +
2 + /* capability info */
@@ -236,6 +238,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
2 + sizeof(struct ieee80211_ht_operation) +
2 + sizeof(struct ieee80211_vht_cap) +
2 + sizeof(struct ieee80211_vht_operation) +
+ ie_len_he_cap +
+ 2 + 1 + sizeof(struct ieee80211_he_operation) +
2 + 8 + /* peering IE */
sdata->u.mesh.ie_len);
if (!skb)
@@ -324,7 +328,9 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
if (mesh_add_ht_cap_ie(sdata, skb) ||
mesh_add_ht_oper_ie(sdata, skb) ||
mesh_add_vht_cap_ie(sdata, skb) ||
- mesh_add_vht_oper_ie(sdata, skb))
+ mesh_add_vht_oper_ie(sdata, skb) ||
+ mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) ||
+ mesh_add_he_oper_ie(sdata, skb))
goto free;
}

@@ -436,6 +442,9 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
elems->vht_cap_elem, sta);

+ ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, elems->he_cap,
+ elems->he_cap_len, sta);
+
if (bw != sta->sta.bandwidth)
changed |= IEEE80211_RC_BW_CHANGED;

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 4c1655972565..d86925438b5f 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2663,6 +2663,30 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
return pos;
}

+u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata)
+{
+ const struct ieee80211_sta_he_cap *he_cap;
+ struct ieee80211_supported_band *sband;
+ u8 ie_len;
+ u8 n;
+
+ sband = ieee80211_get_sband(sdata);
+ if (!sband)
+ return 0;
+
+ he_cap = ieee80211_get_he_mesh_cap(sband);
+ if (!he_cap)
+ return 0;
+
+ n = ieee80211_he_mcs_nss_size(&he_cap->he_cap_elem);
+ ie_len = 2 + 1 +
+ sizeof(he_cap->he_cap_elem) + n +
+ ieee80211_he_ppe_size(he_cap->ppe_thres[0],
+ he_cap->he_cap_elem.phy_cap_info);
+
+ return ie_len;
+}
+
u8 *ieee80211_ie_build_he_cap(u8 *pos,
const struct ieee80211_sta_he_cap *he_cap,
u8 *end)
@@ -2852,6 +2876,34 @@ u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
return pos + sizeof(struct ieee80211_vht_operation);
}

+u8 *ieee80211_ie_build_he_oper(u8 *pos)
+{
+ struct ieee80211_he_operation *he_oper;
+ u32 he_oper_params;
+
+ *pos++ = WLAN_EID_EXTENSION;
+ *pos++ = 1 + sizeof(struct ieee80211_he_operation);
+ *pos++ = WLAN_EID_EXT_HE_OPERATION;
+
+ he_oper_params = 0;
+ he_oper_params |= u32_encode_bits(1023, /* disabled */
+ IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK);
+ he_oper_params |= u32_encode_bits(1,
+ IEEE80211_HE_OPERATION_ER_SU_DISABLE);
+ he_oper_params |= u32_encode_bits(1,
+ IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED);
+
+ he_oper = (struct ieee80211_he_operation *)pos;
+ he_oper->he_oper_params = cpu_to_le32(he_oper_params);
+
+ /* don't require special HE peer rates */
+ he_oper->he_mcs_nss_set = cpu_to_le16(0xffff);
+
+ /* TODO add VHT operational and 6GHz operational subelement? */
+
+ return pos + sizeof(struct ieee80211_vht_operation);
+}
+
bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper,
struct cfg80211_chan_def *chandef)
{
--
2.20.1

2019-06-14 14:11:55

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH v3 0/3] mac80211/ath11k: HE mesh support

Hi Sven,

Two comments:

1) It seems to me that patches 1/2 really should be in opposite order,
since you can't really claim HE mesh support in hwsim when you don't
have it in mac80211?
Or maybe I misunderstand?

2) This series breaks the wpas_mesh_max_peering wpa_supplicant/hwsim
test, and I'm not sure why. Perhaps some length calculations are bad?

johannes

2019-06-14 14:13:48

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH v3 2/3] mac80211: implement HE support for mesh

On Wed, 2019-06-12 at 21:35 +0200, Sven Eckelmann wrote:
>
> +u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata)
> +{
> + const struct ieee80211_sta_he_cap *he_cap;
> + struct ieee80211_supported_band *sband;
> + u8 ie_len;
> + u8 n;
> +
> + sband = ieee80211_get_sband(sdata);
> + if (!sband)
> + return 0;
> +
> + he_cap = ieee80211_get_he_mesh_cap(sband);
> + if (!he_cap)
> + return 0;
> +
> + n = ieee80211_he_mcs_nss_size(&he_cap->he_cap_elem);
> + ie_len = 2 + 1 +
> + sizeof(he_cap->he_cap_elem) + n +
> + ieee80211_he_ppe_size(he_cap->ppe_thres[0],
> + he_cap->he_cap_elem.phy_cap_info);
> +
> + return ie_len;

There's no value in the "ie_len" variable here.

johannes

2019-06-14 14:15:13

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH v3 2/3] mac80211: implement HE support for mesh

On Fri, 2019-06-14 at 16:13 +0200, Sven Eckelmann wrote:
> On Friday, 14 June 2019 16:11:15 CEST Johannes Berg wrote:
> > > + ie_len = 2 + 1 +
> > > + sizeof(he_cap->he_cap_elem) + n +
> > > + ieee80211_he_ppe_size(he_cap->ppe_thres[0],
> > > + he_cap->he_cap_elem.phy_cap_info);
> > > +
> > > + return ie_len;
> >
> > There's no value in the "ie_len" variable here.
>
> Sorry, my parser just broke. Why is there no value in ie_len? Was just
> assigned a line before. Or are you talking about something else?

Heh, sorry. I mean, there's no value in having the variable, you could
just
return 2 + 1 + ...

johannes

2019-06-14 14:15:16

by Sven Eckelmann

[permalink] [raw]
Subject: Re: [PATCH v3 2/3] mac80211: implement HE support for mesh

On Friday, 14 June 2019 16:11:15 CEST Johannes Berg wrote:
> > + ie_len = 2 + 1 +
> > + sizeof(he_cap->he_cap_elem) + n +
> > + ieee80211_he_ppe_size(he_cap->ppe_thres[0],
> > + he_cap->he_cap_elem.phy_cap_info);
> > +
> > + return ie_len;
>
> There's no value in the "ie_len" variable here.

Sorry, my parser just broke. Why is there no value in ie_len? Was just
assigned a line before. Or are you talking about something else?

Kind regards,
Sven


Attachments:
signature.asc (849.00 B)
This is a digitally signed message part.

2019-07-03 09:34:05

by Sven Eckelmann

[permalink] [raw]
Subject: Re: [PATCH v3 0/3] mac80211/ath11k: HE mesh support

Hi,

Thanks for clarifying your statement regarding ie_len. I think I should have
been able to guess what you meant but for some reason my brain wasn't able to
understand the phrase at that time.

On Friday, 14 June 2019 16:10:46 CEST Johannes Berg wrote:
> Two comments:
>
> 1) It seems to me that patches 1/2 really should be in opposite order,
> since you can't really claim HE mesh support in hwsim when you don't
> have it in mac80211?
> Or maybe I misunderstand?

I personally didn't have an opinion regarding the patch order. It was just the
order how I committed the stuff. And it was just committed in this order
because I could easier amend changes to mac80211.

But yes, (in retrospective) it is a lot better to have first the mac80211
change and then the driver changes for meshpoint.

> 2) This series breaks the wpas_mesh_max_peering wpa_supplicant/hwsim
> test, and I'm not sure why. Perhaps some length calculations are bad?

I just went through all tests and saw following failed ones before the
patches:

failed tests: tnc_peap_soh tnc_peap_soh_errors tnc_ttls tnc_ttls_fragmentation tnc_fast ap_ft_ptk_rekey p2p_go_move_reg_change p2ps_connect_adv_go_persistent p2ps_channel_both_connected_different ap_wps_conf_5ghz ap_wps_upnp_http_proto wpas_mesh_gate_forwarding olbc proxyarp_open_ebtables p2p_device_persistent_group2 dpp_ap_config_p521_p521 wnm_bss_tm_reject

and following after the patches:

failed tests: tnc_peap_soh tnc_peap_soh_errors tnc_ttls tnc_ttls_fragmentation tnc_fast ap_ft_ptk_rekey ap_acs_vht discovery_group_client p2p_go_move_reg_change p2ps_stale_group_removal2 ap_wps_conf_5ghz ap_wps_upnp_http_proto radius_acct_interim_unreachable mesh_secure_ocv_mix_legacy mesh_secure_ocv_mix_ht wpas_mesh_max_peering wpas_mesh_open_ht40 wpas_mesh_gate_forwarding rrm_neighbor_rep_oom rrm_beacon_req_passive_scan_vht ap_vht160b ap_vht160_no_dfs_112_minus proxyarp_open_ebtables

So as you can see, even more stuff failed which I haven't touched. And other
stuff which I haven't touched now work. The interesting ones were:

* mesh_secure_ocv_mix_legacy
* mesh_secure_ocv_mix_ht
* wpas_mesh_open_ht40
* wpas_mesh_max_peering

The last one (mentioned by you) is interesting - because I can see the
accepting additional peers == No for the beacons in the dump. But it is not
recognized as such by the script. With new tshark:

~/tmp/wireshark/build/run/tshark -r /tmp/hwsim-test-logs/latest/wpas_mesh_max_peering.hwsim0.pcapng -T fields -e wlan.sa -e wlan.mesh.config.cap 'wlan.fc.type_subtype == 8'
02:00:00:00:01:00 0x00000009
02:00:00:00:00:00 0x00000009
02:00:00:00:01:00 0x00000009
02:00:00:00:02:00 0x00000009
02:00:00:00:00:00 0x00000008
02:00:00:00:01:00 0x00000009
02:00:00:00:02:00 0x00000009
02:00:00:00:00:00 0x00000008

With wireshark 3.0.0:

tshark -r /tmp/hwsim-test-logs/latest/wpas_mesh_max_peering.hwsim0.pcapng -T fields -e wlan.sa -e wlan.mesh.config.cap 'wlan.fc.type_subtype == 8'
02:00:00:00:01:00 0x00000001
02:00:00:00:00:00 0x00000001
02:00:00:00:01:00 0x00000001
02:00:00:00:00:00 0x00000001
02:00:00:00:02:00 0x00000001
02:00:00:00:01:00 0x00000001
02:00:00:00:02:00 0x00000001
02:00:00:00:00:00 0x00000001

So I had to change the wireshark version (see below) which is used by hostapd.
(just to document for me what I have forced it to a different version)

diff --git a/tests/hwsim/tshark.py b/tests/hwsim/tshark.py
index 019df781a760c657b8854acfcee94dc83e30575f..ecf83a7a97dde0e52b54e994d2dd4d46bddaa9df 100644
--- a/tests/hwsim/tshark.py
+++ b/tests/hwsim/tshark.py
@@ -28,7 +28,7 @@ def _run_tshark(filename, filter, display=None, wait=True):
time.sleep(0.1)

try:
- arg = ["tshark", "-r", filename,
+ arg = ["/home/sven/tmp/wireshark/build/run/tshark", "-r", filename,
_tshark_filter_arg, filter]
if display:
arg.append('-Tfields')
@@ -102,7 +102,7 @@ def run_tshark(filename, filter, display=None, wait=True):
wait)

def run_tshark_json(filename, filter):
- arg = ["tshark", "-r", filename,
+ arg = ["/home/sven/tmp/wireshark/build/run/tshark", "-r", filename,
_tshark_filter_arg, filter]
arg.append('-Tjson')
arg.append('-x')

The first three things looks like wpa_supplicant problems. Seems to be
caused by the way HE forces VHT to be enabled and now the tests fail
which try to disable VHT. There was already a patch [0] for that but it
wasn't considered a good solution.

But beside these three things there are various other problems in
wpa_supplicant regarding HE with pending patches. So I've used
wpa_supplicant 91b6eba7732354ed3dfe0aa9715dc4c0746e3336 with two
additional patches [1,2] and increased the VM memory to 1024 MB. Also
wireshark (tshark to be more precise) had to be updated to
v3.1.0rc0-1192-gf64990438c

Kind regards,
Sven

[0] https://patchwork.ozlabs.org/patch/1125305/
[1] https://patchwork.ozlabs.org/patch/1125314/
[2] https://patchwork.ozlabs.org/patch/1125322/


Attachments:
signature.asc (849.00 B)
This is a digitally signed message part.

2019-07-12 08:01:33

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH v3 0/3] mac80211/ath11k: HE mesh support

On Wed, 2019-07-03 at 11:23 +0200, Sven Eckelmann wrote:
>
> ~/tmp/wireshark/build/run/tshark -r /tmp/hwsim-test-logs/latest/wpas_mesh_max_peering.hwsim0.pcapng -T fields -e wlan.sa -e wlan.mesh.config.cap 'wlan.fc.type_subtype == 8'
> 02:00:00:00:01:00 0x00000009
> 02:00:00:00:00:00 0x00000009
> 02:00:00:00:01:00 0x00000009
> 02:00:00:00:02:00 0x00000009
> 02:00:00:00:00:00 0x00000008
> 02:00:00:00:01:00 0x00000009
> 02:00:00:00:02:00 0x00000009
> 02:00:00:00:00:00 0x00000008
>
> With wireshark 3.0.0:
>
> tshark -r /tmp/hwsim-test-logs/latest/wpas_mesh_max_peering.hwsim0.pcapng -T fields -e wlan.sa -e wlan.mesh.config.cap 'wlan.fc.type_subtype == 8'
> 02:00:00:00:01:00 0x00000001
> 02:00:00:00:00:00 0x00000001
> 02:00:00:00:01:00 0x00000001
> 02:00:00:00:00:00 0x00000001
> 02:00:00:00:02:00 0x00000001
> 02:00:00:00:01:00 0x00000001
> 02:00:00:00:02:00 0x00000001
> 02:00:00:00:00:00 0x00000001
>
> So I had to change the wireshark version (see below) which is used by hostapd.
> (just to document for me what I have forced it to a different version)

What. +hostap list.

This makes no sense, is that a tshark bug in one of the versions?

Maybe we should just use the JSON output, and parse that, but if tshark
now has a different idea of what the "wlan.mesh.config.cap" field is,
that won't help us at all?

Older versions were misparsing the HE element, but that has a length so
should only affect the HE element *itself*?


So ultimately, what do we do here?

Should we take this and sort out the tests?

johannes

2019-07-12 09:38:20

by Sven Eckelmann

[permalink] [raw]
Subject: Re: [PATCH v3 0/3] mac80211/ath11k: HE mesh support

On Friday, 12 July 2019 09:58:50 CEST Johannes Berg wrote:
> On Wed, 2019-07-03 at 11:23 +0200, Sven Eckelmann wrote:
> >
> > ~/tmp/wireshark/build/run/tshark -r /tmp/hwsim-test-logs/latest/wpas_mesh_max_peering.hwsim0.pcapng -T fields -e wlan.sa -e wlan.mesh.config.cap 'wlan.fc.type_subtype == 8'
> > 02:00:00:00:01:00 0x00000009
[...]
> > With wireshark 3.0.0:
> >
> > tshark -r /tmp/hwsim-test-logs/latest/wpas_mesh_max_peering.hwsim0.pcapng -T fields -e wlan.sa -e wlan.mesh.config.cap 'wlan.fc.type_subtype == 8'
> > 02:00:00:00:01:00 0x00000001
[...]
> > So I had to change the wireshark version (see below) which is used by hostapd.
> > (just to document for me what I have forced it to a different version)
>
> What. +hostap list.
>
> This makes no sense, is that a tshark bug in one of the versions?

Yes (but more a bug in the ieee80211 dissector), see
commit f3ef8575d462 ("ieee80211: fix wrong offset for mesh configuration
capability bitmask") [1].

I've also attached the pcap in case there are still doubts about my statement.

As you can see, it will just fail to parse the mesh peering management element
correctly. It should parse the last byte of the element payload but it falls
back to parsing the first byte (path selection protocol) as capabilities. See
9.4.2.98 "Mesh Configuration element" from 802.11-2016 for details.

There is already a workaround for that in the hostap testcases:

if all_cap_one:
# It looks like tshark parser was broken at some point for
# wlan.mesh.config.cap which is now (tshark 2.6.3) pointing to incorrect
# field (same as wlan.mesh.config.ps_protocol). This used to work with
# tshark 2.2.6.
#
# For now, assume the capability field ends up being the last octet of
# the frame.
one = [0, 0, 0]
zero = [0, 0, 0]
addrs = [addr0, addr1, addr2]
for idx in range(3):
addr = addrs[idx]
out = run_tshark_json(capfile, filt + " && wlan.sa == " + addr)
pkts = json.loads(out)
for pkt in pkts:
frame = pkt["_source"]["layers"]["frame_raw"][0]
cap = int(frame[-2:], 16)
if cap & 0x01:
one[idx] += 1
else:
zero[idx] += 1
logger.info("one: " + str(one))
logger.info("zero: " + str(zero))

But maybe you already spotted the problem - it requires that mesh
configuration element is the last element. Which is not the case here -
similar to 5GHz tests (where you have most likely a VHT cap/oper element
after the meshconf_ie).

I hope that this makes more sense now.

Kind regards,
Sven

[1] https://github.com/wireshark/wireshark/commit/f3ef8575d4620a62f1c4609bf14961c3e78993f3


Attachments:
wpas_mesh_max_peering.hwsim0.pcapng.gz (1.75 kB)
signature.asc (849.00 B)
This is a digitally signed message part.
Download all attachments

2019-07-12 09:44:34

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH v3 0/3] mac80211/ath11k: HE mesh support

On Fri, 2019-07-12 at 11:36 +0200, Sven Eckelmann wrote:
>
> There is already a workaround for that in the hostap testcases:
>
> if all_cap_one:
> # It looks like tshark parser was broken at some point for
> # wlan.mesh.config.cap which is now (tshark 2.6.3) pointing to incorrect
> # field (same as wlan.mesh.config.ps_protocol). This used to work with
> # tshark 2.2.6.
> #
> # For now, assume the capability field ends up being the last octet of
> # the frame.

> But maybe you already spotted the problem - it requires that mesh
> configuration element is the last element. Which is not the case here -
> similar to 5GHz tests (where you have most likely a VHT cap/oper element
> after the meshconf_ie).
>
> I hope that this makes more sense now.

Ah, yes, it does. So I guess we need to update/fix that workaround. And
I guess newer tshark (which you used) is fixed again, if I understand
correctly?

johannes

2019-07-12 10:40:15

by Sven Eckelmann

[permalink] [raw]
Subject: Re: [PATCH v3 0/3] mac80211/ath11k: HE mesh support

On Friday, 12 July 2019 11:42:51 CEST Johannes Berg wrote:
> On Fri, 2019-07-12 at 11:36 +0200, Sven Eckelmann wrote:
> >
> > There is already a workaround for that in the hostap testcases:
> >
> > if all_cap_one:
> > # It looks like tshark parser was broken at some point for
> > # wlan.mesh.config.cap which is now (tshark 2.6.3) pointing to incorrect
> > # field (same as wlan.mesh.config.ps_protocol). This used to work with
> > # tshark 2.2.6.
> > #
> > # For now, assume the capability field ends up being the last octet of
> > # the frame.
>
> > But maybe you already spotted the problem - it requires that mesh
> > configuration element is the last element. Which is not the case here -
> > similar to 5GHz tests (where you have most likely a VHT cap/oper element
> > after the meshconf_ie).
> >
> > I hope that this makes more sense now.
>
> Ah, yes, it does. So I guess we need to update/fix that workaround.

I will prepare a patch now for hostap after lunch.

> And
> I guess newer tshark (which you used) is fixed again, if I understand
> correctly?

Yes and no, the master branch is fixed. But unfortunately, there is no
release with this fix.

And the problems is there since commit 3c427376579a ("802.11: Use
proto_tree_add_bitmask") and release v2.4.0rc0. But unfortunately, the
workaround was added with commit 2cbaf0de223b ("tests: Work around tshark bug
in wpas_mesh_max_peering") instead of bringing a fix upstream.

Kind regards,
Sven


Attachments:
signature.asc (849.00 B)
This is a digitally signed message part.