linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/3] mac80211/ath11k: HE mesh support
@ 2019-06-11 18:02 Sven Eckelmann
  2019-06-11 18:02 ` [RFC PATCH v2 1/3] mac80211_hwsim: Register support for HE meshpoint Sven Eckelmann
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Sven Eckelmann @ 2019-06-11 18:02 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath11k, Sven Eckelmann

Hi,

Some features of 802.11ax without central organizing (AP) STA can also be
used in mesh mode. The main goal is to get this working for ath11k. But
there are various problems at the moment with the firmware. I hangs
from time to time during assoc (especially when using HE) or just doesn't
enable HE rates when communicating with peers. Even when the peer was
successfully detected as HE capable by the upper layers:

    root@OpenWrt:/# cat /sys/kernel/debug/ieee80211/phy2/netdev:mesh2/stations/00:03:7f:12:bb:97/he_capa
    HE supported
    MAC-CAP: 0x09 0x0d 0x08 0x0a 0x40 0x00
                    HTC-HE
                    DYNAMIC-FRAG-LEVEL-1
                    MAX-NUM-FRAG-MSDU-1
                    MIN-FRAG-SIZE-128
                    TF-MAC-PAD-DUR-24US
                    MULTI-TID-AGG-RX-QOS-1
                    LINK-ADAPTATION-NO-FEEDBACK
                    BSR
                    OMI-CONTROL
                    MAX-AMPDU-LEN-EXP-VHT-1
                    AMSDU-IN-AMPDU
                    MULTI-TID-AGG-TX-QOS-0
    PHY CAP: 0x1c 0x70 0x0c 0x80 0x0d 0x43 0x81 0x1c 0x00 0x00 0x00
                    CHANNEL-WIDTH-SET-40MHZ-80MHZ-IN-5G
                    CHANNEL-WIDTH-SET-160MHZ-IN-5G
                    CHANNEL-WIDTH-SET-80PLUS80-MHZ-IN-5G
                    IEEE80211-HE-PHY-CAP1-DEVICE-CLASS-A
                    LDPC-CODING-IN-PAYLOAD
                    HY-CAP1-HE-LTF-AND-GI-FOR-HE-PPDUS-0-8US
                    MIDAMBLE-RX-MAX-NSTS-0
                    STBC-TX-UNDER-80MHZ
                    STBC-RX-UNDER-80MHZ
                    DCM-MAX-CONST-TX-NO-DCM
                    DCM-MAX-CONST-RX-NO-DCM
                    SU-BEAMFORMER
                    SU-BEAMFORMEE
                    BEAMFORMEE-MAX-STS-UNDER-7
                    BEAMFORMEE-MAX-STS-ABOVE-4
                    NUM-SND-DIM-UNDER-80MHZ-4
                    NUM-SND-DIM-ABOVE-80MHZ-1
                    NG16-SU-FEEDBACK
                    CODEBOOK-SIZE-42-SU
                    PPE-THRESHOLD-PRESENT
                    HE-SU-MU-PPDU-4XLTF-AND-08-US-GI
                    MAX-NC-4
                    DCM-MAX-RU-242
                    NOMINAL-PACKET-PADDING-0US
    RX-MCS-80: 0xffaa
                    RX-MCS-80-0-SUPPORT-0-11
                    RX-MCS-80-1-SUPPORT-0-11
                    RX-MCS-80-2-SUPPORT-0-11
                    RX-MCS-80-3-SUPPORT-0-11
    TX-MCS-80: 0xffaa
                    TX-MCS-80-0-SUPPORT-0-11
                    TX-MCS-80-1-SUPPORT-0-11
                    TX-MCS-80-2-SUPPORT-0-11
                    TX-MCS-80-3-SUPPORT-0-11
    RX-MCS-160: 0xfffa
                    RX-MCS-160-0-SUPPORT-0-11
                    RX-MCS-160-1-SUPPORT-0-11
                    RX-MCS-160-2-NOT-SUPPORTED
                    RX-MCS-160-3-NOT-SUPPORTED
    TX-MCS-160: 0xfffa
                    TX-MCS-160-0-SUPPORT-0-11
                    TX-MCS-160-1-SUPPORT-0-11
                    TX-MCS-160-2-NOT-SUPPORTED
                    TX-MCS-160-3-NOT-SUPPORTED
    RX-MCS-80P80: 0xfffa
                    RX-MCS-80P80-0-SUPPORT-0-11
                    RX-MCS-80P80-1-SUPPORT-0-11
                    RX-MCS-80P80-2-NOT-SUPPORTED
                    RX-MCS-80P80-3-NOT-SUPPORTED
    TX-MCS-80P80: 0xfffa
                    TX-MCS-80P80-0-SUPPORT-0-11
                    TX-MCS-80P80-1-SUPPORT-0-11
                    TX-MCS-80P80-2-NOT-SUPPORTED
                    TX-MCS-80P80-3-NOT-SUPPORTED
    PPE-THRESHOLDS: 0x3b 0x1c 0xc7 0x71 0x1c 0xc7 0x71 0x1c 0xc7 0x71
    root@OpenWrt:/# iw dev mesh2 station dump
    Station 00:03:7f:12:bb:97 (on mesh2)
            inactive time:  310 ms
            rx bytes:       161064
            rx packets:     1619
            tx bytes:       55454
            tx packets:     477
            tx retries:     405
            tx failed:      0
            rx drop misc:   6
            signal:         -95 dBm
            signal avg:     -67 dBm
            tx bitrate:     1733.3 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 4
            rx bitrate:     1733.3 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 4
            rx duration:    0 us
            mesh llid:      0
            mesh plid:      0
            mesh plink:     ESTAB
            mesh local PS mode:     ACTIVE
            mesh peer PS mode:      ACTIVE
            mesh non-peer PS mode:  ACTIVE
            authorized:     yes
            authenticated:  yes
            associated:     yes
            preamble:       long
            WMM/WME:        yes
            MFP:            no
            TDLS peer:      no
            DTIM period:    2
            beacon interval:1000
            connected time: 536 seconds

But there is currently no documentation what the firmware requires (next to
the already existing things for AP/managed) to enable HE for mesh.

hwsim can be used in the meantime as basis for initial development of these
features without having access to HW.

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 |  56 +++++
 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, 393 insertions(+), 95 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC PATCH v2 1/3] mac80211_hwsim: Register support for HE meshpoint
  2019-06-11 18:02 [RFC PATCH v2 0/3] mac80211/ath11k: HE mesh support Sven Eckelmann
@ 2019-06-11 18:02 ` Sven Eckelmann
  2019-06-11 18:02 ` [RFC PATCH v2 2/3] mac80211: implement HE support for mesh Sven Eckelmann
  2019-06-11 18:02 ` [RFC PATCH v2 3/3] ath11k: register HE mesh capabilities Sven Eckelmann
  2 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2019-06-11 18:02 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath11k, Sven Eckelmann

From: Sven Eckelmann <seckelmann@datto.com>

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 <seckelmann@datto.com>
---
 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


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH v2 2/3] mac80211: implement HE support for mesh
  2019-06-11 18:02 [RFC PATCH v2 0/3] mac80211/ath11k: HE mesh support Sven Eckelmann
  2019-06-11 18:02 ` [RFC PATCH v2 1/3] mac80211_hwsim: Register support for HE meshpoint Sven Eckelmann
@ 2019-06-11 18:02 ` Sven Eckelmann
  2019-06-11 18:02 ` [RFC PATCH v2 3/3] ath11k: register HE mesh capabilities Sven Eckelmann
  2 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2019-06-11 18:02 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath11k, Sven Eckelmann

From: Sven Eckelmann <seckelmann@datto.com>

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 <seckelmann@datto.com>
---
 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


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH v2 3/3] ath11k: register HE mesh capabilities
  2019-06-11 18:02 [RFC PATCH v2 0/3] mac80211/ath11k: HE mesh support Sven Eckelmann
  2019-06-11 18:02 ` [RFC PATCH v2 1/3] mac80211_hwsim: Register support for HE meshpoint Sven Eckelmann
  2019-06-11 18:02 ` [RFC PATCH v2 2/3] mac80211: implement HE support for mesh Sven Eckelmann
@ 2019-06-11 18:02 ` Sven Eckelmann
  2019-06-11 19:52   ` Sven Eckelmann
  2 siblings, 1 reply; 7+ messages in thread
From: Sven Eckelmann @ 2019-06-11 18:02 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath11k, Sven Eckelmann

From: Sven Eckelmann <seckelmann@datto.com>

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 <seckelmann@datto.com>
---
This doesn't work currently as expected. No HE rates are used between
the two HE mesh peers:

    root@OpenWrt:/# cat /sys/kernel/debug/ieee80211/phy2/netdev:mesh2/stations/00:03:7f:12:bb:97/he_capa
    HE supported
    MAC-CAP: 0x09 0x0d 0x08 0x0a 0x40 0x00
                    HTC-HE
                    DYNAMIC-FRAG-LEVEL-1
                    MAX-NUM-FRAG-MSDU-1
                    MIN-FRAG-SIZE-128
                    TF-MAC-PAD-DUR-24US
                    MULTI-TID-AGG-RX-QOS-1
                    LINK-ADAPTATION-NO-FEEDBACK
                    BSR
                    OMI-CONTROL
                    MAX-AMPDU-LEN-EXP-VHT-1
                    AMSDU-IN-AMPDU
                    MULTI-TID-AGG-TX-QOS-0
    PHY CAP: 0x1c 0x70 0x0c 0x80 0x0d 0x43 0x81 0x1c 0x00 0x00 0x00
                    CHANNEL-WIDTH-SET-40MHZ-80MHZ-IN-5G
                    CHANNEL-WIDTH-SET-160MHZ-IN-5G
                    CHANNEL-WIDTH-SET-80PLUS80-MHZ-IN-5G
                    IEEE80211-HE-PHY-CAP1-DEVICE-CLASS-A
                    LDPC-CODING-IN-PAYLOAD
                    HY-CAP1-HE-LTF-AND-GI-FOR-HE-PPDUS-0-8US
                    MIDAMBLE-RX-MAX-NSTS-0
                    STBC-TX-UNDER-80MHZ
                    STBC-RX-UNDER-80MHZ
                    DCM-MAX-CONST-TX-NO-DCM
                    DCM-MAX-CONST-RX-NO-DCM
                    SU-BEAMFORMER
                    SU-BEAMFORMEE
                    BEAMFORMEE-MAX-STS-UNDER-7
                    BEAMFORMEE-MAX-STS-ABOVE-4
                    NUM-SND-DIM-UNDER-80MHZ-4
                    NUM-SND-DIM-ABOVE-80MHZ-1
                    NG16-SU-FEEDBACK
                    CODEBOOK-SIZE-42-SU
                    PPE-THRESHOLD-PRESENT
                    HE-SU-MU-PPDU-4XLTF-AND-08-US-GI
                    MAX-NC-4
                    DCM-MAX-RU-242
                    NOMINAL-PACKET-PADDING-0US
    RX-MCS-80: 0xffaa
                    RX-MCS-80-0-SUPPORT-0-11
                    RX-MCS-80-1-SUPPORT-0-11
                    RX-MCS-80-2-SUPPORT-0-11
                    RX-MCS-80-3-SUPPORT-0-11
    TX-MCS-80: 0xffaa
                    TX-MCS-80-0-SUPPORT-0-11
                    TX-MCS-80-1-SUPPORT-0-11
                    TX-MCS-80-2-SUPPORT-0-11
                    TX-MCS-80-3-SUPPORT-0-11
    RX-MCS-160: 0xfffa
                    RX-MCS-160-0-SUPPORT-0-11
                    RX-MCS-160-1-SUPPORT-0-11
                    RX-MCS-160-2-NOT-SUPPORTED
                    RX-MCS-160-3-NOT-SUPPORTED
    TX-MCS-160: 0xfffa
                    TX-MCS-160-0-SUPPORT-0-11
                    TX-MCS-160-1-SUPPORT-0-11
                    TX-MCS-160-2-NOT-SUPPORTED
                    TX-MCS-160-3-NOT-SUPPORTED
    RX-MCS-80P80: 0xfffa
                    RX-MCS-80P80-0-SUPPORT-0-11
                    RX-MCS-80P80-1-SUPPORT-0-11
                    RX-MCS-80P80-2-NOT-SUPPORTED
                    RX-MCS-80P80-3-NOT-SUPPORTED
    TX-MCS-80P80: 0xfffa
                    TX-MCS-80P80-0-SUPPORT-0-11
                    TX-MCS-80P80-1-SUPPORT-0-11
                    TX-MCS-80P80-2-NOT-SUPPORTED
                    TX-MCS-80P80-3-NOT-SUPPORTED
    PPE-THRESHOLDS: 0x3b 0x1c 0xc7 0x71 0x1c 0xc7 0x71 0x1c 0xc7 0x71
    root@OpenWrt:/# iw dev mesh2 station dump
    Station 00:03:7f:12:bb:97 (on mesh2)
            inactive time:  310 ms
            rx bytes:       161064
            rx packets:     1619
            tx bytes:       55454
            tx packets:     477
            tx retries:     405
            tx failed:      0
            rx drop misc:   6
            signal:         -95 dBm
            signal avg:     -67 dBm
            tx bitrate:     1733.3 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 4
            rx bitrate:     1733.3 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 4
            rx duration:    0 us
            mesh llid:      0
            mesh plid:      0
            mesh plink:     ESTAB
            mesh local PS mode:     ACTIVE
            mesh peer PS mode:      ACTIVE
            mesh non-peer PS mode:  ACTIVE
            authorized:     yes
            authenticated:  yes
            associated:     yes
            preamble:       long
            WMM/WME:        yes
            MFP:            no
            TDLS peer:      no
            DTIM period:    2
            beacon interval:1000
            connected time: 536 seconds

 drivers/net/wireless/ath/ath11k/mac.c | 56 +++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 13da2e8262ba..7dcf4bb896b5 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 =
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH v2 3/3] ath11k: register HE mesh capabilities
  2019-06-11 18:02 ` [RFC PATCH v2 3/3] ath11k: register HE mesh capabilities Sven Eckelmann
@ 2019-06-11 19:52   ` Sven Eckelmann
  2019-06-12  8:42     ` Sven Eckelmann
  2019-06-12 16:34     ` Bob Copeland
  0 siblings, 2 replies; 7+ messages in thread
From: Sven Eckelmann @ 2019-06-11 19:52 UTC (permalink / raw)
  To: ath11k; +Cc: linux-wireless, Bob Copeland

[-- Attachment #1: Type: text/plain, Size: 1684 bytes --]

On Tuesday, 11 June 2019 20:02:47 CEST Sven Eckelmann wrote:
[...]
> ---
> This doesn't work currently as expected. No HE rates are used between
> the two HE mesh peers:
[...]

There seems to be also an ordering problem. ath11k_peer_assoc_h_he is only 
called before ieee80211_he_cap_ie_to_sta_he_cap is called. So ath11k_bss_assoc 
will not have the information whether the remote has HE support or not.

Looks like I have adjust mesh_sta_info_init to get this somehow to 
ath11k_peer_assoc_h_he. Maybe through ath11k_sta_rc_update but this is not 
called by mesh_sta_info_init at the moment. Just because 
rate_control_rate_init is called and not rate_control_rate_update.

The easiest method seems to adjust the check at the end of mesh_sta_info_init 
to 

	if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL) &&
	    !ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) {
		rate_control_rate_init(sta);
	} else {
		rate_control_rate_update(local, sband, sta, changed);
	}

and to create a IEEE80211_RC_SUPP_RATES_CHANGED change when the has_he state 
changes. And yes, I know that Bob Copeland added this because it would have 
crashed ath10k when rate_control_rate_init is not used [1]. The other 
suggestion would be:

	if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
		rate_control_rate_init(sta);

   /* inform drivers about changes */
	rate_control_rate_update(local, sband, sta, changed);

Both will at least cause a call to ath11k_peer_assoc_prepare + 
ath11k_wmi_send_peer_assoc_cmd but unfortunately the ath11k firmware hangs 
afterwards.

Kind regards,
	Sven

[1] https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?id=1d6741d86429a294f51f2773c751c8f7662e7ca2

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH v2 3/3] ath11k: register HE mesh capabilities
  2019-06-11 19:52   ` Sven Eckelmann
@ 2019-06-12  8:42     ` Sven Eckelmann
  2019-06-12 16:34     ` Bob Copeland
  1 sibling, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2019-06-12  8:42 UTC (permalink / raw)
  To: ath11k; +Cc: Bob Copeland, linux-wireless

[-- Attachment #1: Type: text/plain, Size: 1041 bytes --]

On Tuesday, 11 June 2019 21:52:20 CEST Sven Eckelmann wrote:
[...]
> 	if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
> 		rate_control_rate_init(sta);
> 
>    /* inform drivers about changes */
> 	rate_control_rate_update(local, sband, sta, changed);
> 
> Both will at least cause a call to ath11k_peer_assoc_prepare + 
> ath11k_wmi_send_peer_assoc_cmd but unfortunately the ath11k firmware hangs 
> afterwards.

The fw hang seems to be related to the not set bss_conf.he_support in 
ath11k_mac_vdev_start_restart. This has to be set when ieee80211_join_mesh 
calls ieee80211_vif_use_channel. Otherwise the firmware will set a HT/VHT mode 
in the firmware. Any sta with an higher phy mode will just hang the firmware.

So the two main problems right now are:

* set bss_conf.he_support during mesh_join before 
  ath11k_mac_vdev_start_restart is called

   - no clue what the best approach is

* let ath11k redo the association procedure with he_cap->has_he set to true 
  when wpa_supplicant is in control of the peers.

Kind regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH v2 3/3] ath11k: register HE mesh capabilities
  2019-06-11 19:52   ` Sven Eckelmann
  2019-06-12  8:42     ` Sven Eckelmann
@ 2019-06-12 16:34     ` Bob Copeland
  1 sibling, 0 replies; 7+ messages in thread
From: Bob Copeland @ 2019-06-12 16:34 UTC (permalink / raw)
  To: Sven Eckelmann; +Cc: ath11k, linux-wireless

On Tue, Jun 11, 2019 at 09:52:20PM +0200, Sven Eckelmann wrote:
> On Tuesday, 11 June 2019 20:02:47 CEST Sven Eckelmann wrote:
> [...]
> > ---
> > This doesn't work currently as expected. No HE rates are used between
> > the two HE mesh peers:
> [...]
> 
> There seems to be also an ordering problem. ath11k_peer_assoc_h_he is only 
> called before ieee80211_he_cap_ie_to_sta_he_cap is called. So ath11k_bss_assoc 
> will not have the information whether the remote has HE support or not.
> 
> Looks like I have adjust mesh_sta_info_init to get this somehow to 
> ath11k_peer_assoc_h_he. Maybe through ath11k_sta_rc_update but this is not 
> called by mesh_sta_info_init at the moment. Just because 
> rate_control_rate_init is called and not rate_control_rate_update.
> 
> The easiest method seems to adjust the check at the end of mesh_sta_info_init 
> to 
> 
> 	if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL) &&
> 	    !ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) {
> 		rate_control_rate_init(sta);
> 	} else {
> 		rate_control_rate_update(local, sband, sta, changed);
> 	}

Maybe we should just do this?

diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 76f303fda3ed..6f8bde840bb9 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -42,7 +42,7 @@ void rate_control_rate_init(struct sta_info *sta)
 	ieee80211_sta_set_rx_nss(sta);
 
 	if (!ref)
-		return;
+		goto out;
 
 	rcu_read_lock();
 
@@ -59,6 +59,7 @@ void rate_control_rate_init(struct sta_info *sta)
 			    priv_sta);
 	spin_unlock_bh(&sta->rate_ctrl_lock);
 	rcu_read_unlock();
+out:
 	set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
 }


That was my intent, anyway -- that NSS always got set before
rate_control_rate_update() even if using HW rate control.

> 	if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
> 		rate_control_rate_init(sta);
> 
>    /* inform drivers about changes */
> 	rate_control_rate_update(local, sband, sta, changed);
> 
> Both will at least cause a call to ath11k_peer_assoc_prepare + 
> ath11k_wmi_send_peer_assoc_cmd but unfortunately the ath11k firmware hangs 
> afterwards.

I think this would be OK.

-- 
Bob Copeland %% https://bobcopeland.com/

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-06-12 16:35 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-06-11 18:02 [RFC PATCH v2 0/3] mac80211/ath11k: HE mesh support Sven Eckelmann
2019-06-11 18:02 ` [RFC PATCH v2 1/3] mac80211_hwsim: Register support for HE meshpoint Sven Eckelmann
2019-06-11 18:02 ` [RFC PATCH v2 2/3] mac80211: implement HE support for mesh Sven Eckelmann
2019-06-11 18:02 ` [RFC PATCH v2 3/3] ath11k: register HE mesh capabilities Sven Eckelmann
2019-06-11 19:52   ` Sven Eckelmann
2019-06-12  8:42     ` Sven Eckelmann
2019-06-12 16:34     ` Bob Copeland

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).