Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH v6] mac80211_hwsim: Register support for HE meshpoint
From: Sven Eckelmann @ 2019-08-13 11:20 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: linux-wireless
In-Reply-To: <20190813105549.GA26160@w1.fi>

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

Hi,

On Tuesday, 13 August 2019 12:55:49 CEST Jouni Malinen wrote:
[...]
> > [1] https://patchwork.ozlabs.org/patch/1131273/
> > [2] https://patchwork.ozlabs.org/patch/1116968/
> > [3] https://lore.kernel.org/r/2152977.f3ncjnVLFo@bentobox
>
> And with the exact same snapshot of hostap.git.
> 
> Without [1] applied, this mac80211_hwsim patch to enable HE meshpoint
> results in the following test cases failing:
> 
> mesh_secure_ocv_mix_legacy
> wpas_mesh_open_ht40
> wpas_mesh_max_peering
> mesh_secure_ocv_mix_ht
> 
> [1] fixes wpas_mesh_max_peering
> 
> This leaves following three test cases failing ("Test exception:
> Couldn't join mesh"):
> 
> mesh_secure_ocv_mix_legacy
> wpas_mesh_open_ht40
> mesh_secure_ocv_mix_ht
> 
> Am I missing a patch somewhere that would be needed to make those pass?

No, these also failed for me without the mac80211_hwsim patch [3] in a full 
test run. And thus not analyzed further by me.

Interestingly, they don't fail (without the hwsim patch) when running them
without the full test suite.

[...]
> So is that missing of vht_enabled=1 from some configurations the problem
> here and if so, would you be able to point me to a hostap.git patch that
> addresses this?

No, there is no hostap.git patch here. There was one in the past in 
patchwork [4] but there were concerns by John. So if you reapply the patch 
then you will see that it doesn't fail anymore.

    diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
    index d71511cb5..b54900bc4 100644
    --- a/src/drivers/driver_nl80211.c
    +++ b/src/drivers/driver_nl80211.c
    @@ -4360,7 +4360,7 @@ static int nl80211_put_freq_params(struct nl_msg *msg,
     	is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G ||
     		hw_mode == HOSTAPD_MODE_IEEE80211B;
     
    -	if (freq->vht_enabled || (freq->he_enabled && !is_24ghz)) {
    +	if (freq->vht_enabled) {
     		enum nl80211_chan_width cw;
     
     		wpa_printf(MSG_DEBUG, "  * bandwidth=%d", freq->bandwidth);


So as a compromise, I can can propose a patch which tries to replicate this 
2.4GHz specific behavior from nl80211_put_freq_params also in 
ibss_mesh_setup_freq

Btw. thanks for pointing me towards specific test cases.

Kind regards,
	Sven

[4] https://patchwork.ozlabs.org/patch/1125305/

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

^ permalink raw reply

* Re: [PATCH v6] mac80211_hwsim: Register support for HE meshpoint
From: Jouni Malinen @ 2019-08-13 10:55 UTC (permalink / raw)
  To: Sven Eckelmann; +Cc: linux-wireless, Sven Eckelmann
In-Reply-To: <20190813063657.7544-1-sven@narfation.org>

On Tue, Aug 13, 2019 at 08:36:57AM +0200, Sven Eckelmann wrote:
> 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.

> * rebased on top of 690c4509e980 ("mac80211_hwsim: Fix a typo in the name
>    of function 'mac80211_hswim_he_capab()'")

I'm testing this now with a bit newer snapshot: 6a7ce95d752e
("staging/octeon: Fix build error without CONFIG_NETDEVICES").

> The patch was checked against hostapd's tests version 05822609d105
> ("HE: MCS size is always a minimum of 4 bytes") and the pending tshark < 3.1.0
> workaround [1]. The latter is only affecting test "wpas_mesh_max_peering".
> 
> The other patch  [2] I had in my hostapd queue in earlier tests [3] was not
> actually needed for hwsim+mesh.
> 
> [1] https://patchwork.ozlabs.org/patch/1131273/
> [2] https://patchwork.ozlabs.org/patch/1116968/
> [3] https://lore.kernel.org/r/2152977.f3ncjnVLFo@bentobox

And with the exact same snapshot of hostap.git.

Without [1] applied, this mac80211_hwsim patch to enable HE meshpoint
results in the following test cases failing:

mesh_secure_ocv_mix_legacy
wpas_mesh_open_ht40
wpas_mesh_max_peering
mesh_secure_ocv_mix_ht

[1] fixes wpas_mesh_max_peering

This leaves following three test cases failing ("Test exception:
Couldn't join mesh"):

mesh_secure_ocv_mix_legacy
wpas_mesh_open_ht40
mesh_secure_ocv_mix_ht

Am I missing a patch somewhere that would be needed to make those pass?


More specific reason for the failures:

wpas_mesh_open_ht40:

nl80211: mesh join (ifindex=3)
  * freq=5180
  * he_enabled=1
  * vht_enabled=0
  * ht_enabled=1
  * bandwidth=0
wlan0: mesh join error=-1

mesh_secure_ocv_mix_legacy:

same issues on dev1, but dev0 did complete join with a different set of
parameters:

nl80211: mesh join (ifindex=3)
  * freq=5200
  * he_enabled=1
  * vht_enabled=1
  * ht_enabled=1
  * bandwidth=80
  * channel_width=3
  * center_freq1=5210
  * center_freq2=0
  * Mesh ID (SSID)=wpas-mesh-sec
  * flags=0000000D
  * IEs - hexdump(len=22): 30 14 01 00 00 0f ac 04 01 00 00 0f ac 04 01 00 00 0f ac 08 c0 40
nl80211: mesh join request send successfully


(and same for mesh_secure_ocv_mix_ht)

So is that missing of vht_enabled=1 from some configurations the problem
here and if so, would you be able to point me to a hostap.git patch that
addresses this?

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply

* Re: [RFC PATCH v7] rtl8xxxu: Improve TX performance of RTL8723BU on rtl8xxxu driver
From: Daniel Drake @ 2019-08-13  7:15 UTC (permalink / raw)
  To: Jes Sorensen
  Cc: Kalle Valo, Chris Chiu, David Miller, linux-wireless, netdev,
	Linux Kernel, Linux Upstreaming Team
In-Reply-To: <a3ac212d-b976-fb16-227f-3246a317c4a2@gmail.com>

On Mon, Aug 12, 2019 at 11:21 PM Jes Sorensen <jes.sorensen@gmail.com> wrote:
> On 8/12/19 10:32 AM, Kalle Valo wrote:
> > This is marked as RFC so I'm not sure what's the plan. Should I apply
> > this?
>
> I think it's at a point where it's worth applying - I kinda wish I had
> had time to test it, but I won't be near my stash of USB dongles for a
> little while.

The last remaining reason it was RFC was pending feedback from Jes, to
check that his earlier comments had been adequately addressed. So yes
I think it's good to apply now.

Thanks,
Daniel

^ permalink raw reply

* [PATCH] mac80211: fix possible NULL pointerderef in obss pd code
From: John Crispin @ 2019-08-13  7:07 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, John Crispin, Dan Carpenter

he_spr_ie_elem is dereferenced before the NULL check. fix this by moving
the assignment after the check.

fixes commit 697f6c507c74 ("mac80211: propagate HE operation info into
bss_conf")

This was reported by the static code checker.

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
 net/mac80211/he.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/he.c b/net/mac80211/he.c
index a02abfc424aa..736da0035135 100644
--- a/net/mac80211/he.c
+++ b/net/mac80211/he.c
@@ -72,12 +72,13 @@ ieee80211_he_spr_ie_to_bss_conf(struct ieee80211_vif *vif,
 {
 	struct ieee80211_he_obss_pd *he_obss_pd =
 					&vif->bss_conf.he_obss_pd;
-	const u8 *data = he_spr_ie_elem->optional;
+	const u8 *data;
 
 	memset(he_obss_pd, 0, sizeof(*he_obss_pd));
 
 	if (!he_spr_ie_elem)
 		return;
+	data = he_spr_ie_elem->optional;
 
 	if (he_spr_ie_elem->he_sr_control &
 	    IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT)
-- 
2.20.1


^ permalink raw reply related

* [PATCH v6] mac80211_hwsim: Register support for HE meshpoint
From: Sven Eckelmann @ 2019-08-13  6:36 UTC (permalink / raw)
  To: linux-wireless; +Cc: 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>
---
v6:

* rebased on top of 690c4509e980 ("mac80211_hwsim: Fix a typo in the name
   of function 'mac80211_hswim_he_capab()'")
* dropped incorrectly left "Forwarded" tag in commit message
* drop merged mac80211 patch
* drop ath11k patches will go to some special post-upstreaming branch and
  will be submitted separately

v5-v1:

* see https://lore.kernel.org/r/20190724163359.3507-1-sven@narfation.org

The patch was checked against hostapd's tests version 05822609d105
("HE: MCS size is always a minimum of 4 bytes") and the pending tshark < 3.1.0
workaround [1]. The latter is only affecting test "wpas_mesh_max_peering".

The other patch  [2] I had in my hostapd queue in earlier tests [3] was not
actually needed for hwsim+mesh.

[1] https://patchwork.ozlabs.org/patch/1131273/
[2] https://patchwork.ozlabs.org/patch/1116968/
[3] https://lore.kernel.org/r/2152977.f3ncjnVLFo@bentobox
---
 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 f86c2891310a..635956024e88 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2497,116 +2497,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_hwsim_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

* Taking a day off...
From: David Miller @ 2019-08-13  4:26 UTC (permalink / raw)
  To: netdev, jakub.kicinski; +Cc: linux-wireless, netfilter-devel, bpf


Hello everyone,

Tomorrow I will be letting Jakub Kicinski manage the net and net-next
GIT trees.  So he will be integrating patches into GIT and doing git
pulls from people.  He will alway keep the patchwork states up to
date, just like I do.

I completely expect everyone to give Jakub the same respect and
consideration they usually give to me, because he deserves it.

In the future, when I need to take a few days off, I will hand things
over to Jakub in a similar way.

Thank you.

^ permalink raw reply

* Re: [PATCH] `iwlist scan` fails with many networks available
From: James Nylen @ 2019-08-13  0:43 UTC (permalink / raw)
  To: Johannes Berg; +Cc: David S. Miller, linux-wireless, netdev, linux-kernel
In-Reply-To: <f7de98001849bc98a0a084d2ffc369f4d9772d52.camel@sipsolutions.net>

>I suppose we could consider applying a workaround like this if it has a
>condition checking that the buffer passed in is the maximum possible
>buffer (65535 bytes, due to iw_point::length being u16)

This is what the latest patch does (attached to my email from
yesterday / https://lkml.org/lkml/2019/8/10/452 ).

If you'd like to apply it, I'm happy to make any needed revisions.
Otherwise I'm going to have to keep patching my kernels for this
issue, unfortunately I don't have the time to try to get wicd to
migrate to a better solution.

On 8/11/19, Johannes Berg <johannes@sipsolutions.net> wrote:
> On Sun, 2019-08-11 at 02:08 +0000, James Nylen wrote:
>> In 5.x it's still possible for `ieee80211_scan_results` (`iwlist
>> scan`) to fail when too many wireless networks are available.  This
>> code path is used by `wicd`.
>>
>> Previously: https://lkml.org/lkml/2017/4/2/192
>
> This has been known for probably a decade or longer. I don't know why
> 'wicd' still insists on using wext, unless it's no longer maintained at
> all. nl80211 doesn't have this problem at all, and I think gives more
> details about the networks found too.
>
>> I've been applying this updated patch to my own kernels since 2017 with
>> no issues.  I am sure it is not the ideal way to solve this problem, but
>> I'm making my fix available in case it helps others.
>
> I don't think silently dropping data is a good solution.
>
> I suppose we could consider applying a workaround like this if it has a
> condition checking that the buffer passed in is the maximum possible
> buffer (65535 bytes, due to iw_point::length being u16), but below that
> -E2BIG serves well-written implementations as an indicator that they
> need to retry with a bigger buffer.
>
>> Please advise on next steps or if this is a dead end.
>
> I think wireless extensions are in fact a dead end and all software
> (even 'wicd', which seems to be the lone holdout) should migrate to
> nl80211 instead.
>
> johannes
>
>

^ permalink raw reply

* [PATCH 5/5] rtlwifi: rtl8192cu: Fix value set in descriptor
From: Larry Finger @ 2019-08-12 19:27 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, pkshih, Larry Finger

In the process of converting the bit manipulation macros were converted
to use GENMASK(), the compiler reported a value too big for the field.
The offending statement was trying to write 0x100 into a 5-bit field.
An accompaning comment says to set bit 3, thus the code is changed
appropriately.

This error has been in the driver since its initial submission.

Fixes: 29d00a3e46bb ("rtlwifi: rtl8192cu: Add routine trx")
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
 drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c
index 0020adc004a5..9b5c7ec6b6f7 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c
@@ -611,7 +611,7 @@ void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 *pdesc,
 		SET_TX_DESC_NAV_USE_HDR(pdesc, 1);
 	} else {
 		SET_TX_DESC_HWSEQ_EN(pdesc, 1); /* Hw set sequence number */
-		SET_TX_DESC_PKT_ID(pdesc, 0x100); /* set bit3 to 1. */
+		SET_TX_DESC_PKT_ID(pdesc, BIT(3)); /* set bit3 to 1. */
 	}
 	SET_TX_DESC_USE_RATE(pdesc, 1); /* use data rate which is set by Sw */
 	SET_TX_DESC_OWN(pdesc, 1);
-- 
2.22.0


^ permalink raw reply related

* Re: [PATCH] mmc: core: Prevent processing SDIO IRQs when the card is suspended
From: Matthias Kaehlcke @ 2019-08-12 18:39 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Doug Anderson, Linux MMC List, Adrian Hunter, Brian Norris,
	Shawn Lin, Guenter Roeck, Heiko Stuebner, Kalle Valo,
	linux-wireless, # 4.0+
In-Reply-To: <CAPDyKFpqk4ZcVTqifnbnW1WgNfx9ZNebCttUPcK_e9KWqpDMjQ@mail.gmail.com>

Hi Ulf,

On Fri, Jun 14, 2019 at 01:55:54PM +0200, Ulf Hansson wrote:
> On Thu, 13 Jun 2019 at 20:05, Doug Anderson <dianders@chromium.org> wrote:
> >
> > Hi,
> >
> > On Thu, Jun 13, 2019 at 2:30 AM Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > >
> > > > A) Do we need to do anything extra to make sure we actually call the
> > > > interrupt handler after we've resumed?  I guess we can't actually
> > > > "lose" the interrupt since it will be sitting asserted in CCCR_INTx
> > > > until we deal with it (right?), but maybe we need to do something to
> > > > ensure the handler gets called once we're done resuming?
> > >
> > > Good point!
> > >
> > > Although, it also depends on if we are going to power off the SDIO
> > > card or not. In other words, if the SDIO IRQ are configured as a
> > > system wakeup.
> >
> > Even if it's not a system wakeup, we still don't want to drop the
> > interrupt on the ground though, do we?  For instance, think about a
> > level-triggered GPIO interrupt that's _not_ a wakeup interrupt.  If
> > that gets asserted in suspend then we won't wakeup the system, but as
> > soon as the system gets to a certain point in the resume sequence then
> > we should pass the interrupt on to the handler.  If an edge triggered
> > (but non-wakeup) interrupt fires when the system is resuming then we
> > should similarly not drop it, should we?
> 
> GPIOs is clearly different.
> 
> When it comes to SDIO cards, re-playing/re-kicking an SDIO IRQ doesn't
> make sense in case the SDIO card was powered off during system
> suspend. The reason is simply because the internal state inside the
> SDIO card gets lost at a power off. For example, the used SDIO func
> number, needs to re-enabled before any SDIO IRQs can be delivered for
> it.
> 
> So yes, I really think we should drop the SDIO IRQ, unless it's
> configured as a wakeup. Simply because it's not valid after the system
> has resumed.

With the dropped interrupts SDIO is broken on veyron jerry when
the Marvell 8997 Bluetooth controller sends events while
suspending. On the system MMC remains powered during suspend, but SDIO
isn't configured as wakeup. On this system the problem can be fixed by
processing the interrupt after resuming, however from the discussion
it seems this isn't universally a good solution.

Not sure if this is just a special case that is best worked around in
the downstream kernel of the device, or if this could affect other
systems and it would be worth to address it upstream (e.g. by
processing the dropped interrupt on resume if MMC_PM_KEEP_POWER is
set and the SDIO interrupt is not configured as wakeup).

^ permalink raw reply

* Re: [PATCH 2/2] mac80211_hwsim: Register support for HE meshpoint
From: Sven Eckelmann @ 2019-08-12 15:41 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, ath11k
In-Reply-To: <eaaff61b1e35c43ee64f728c97a02bfcd15c295a.camel@sipsolutions.net>

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

On Friday, 26 July 2019 15:32:50 CEST Johannes Berg wrote:
[...]
> Ok, dunno. But I don't really want to break everything in the hwsim
> tests, even if the kernel patch may be correct ... so I guess I'll wait
> until you resubmit after some fixes go into wpa_s?

Ok, will try to do this. Seems like Jouni merged parts of the patches but 
there are still things pending.

Btw. with the patches, I see following things broken in the test suite (single 
run):

failed tests: ibss_5ghz fst_sta_tear_down_session_bad_fsts_id tnc_peap_soh 
tnc_peap_soh_errors tnc_ttls tnc_ttls_fragmentation tnc_fast 
p2p_set_discoverability ap_ft_vlan_disconnected ap_ft_eap_vlan_multi 
ap_ft_ptk_rekey ap_acs_exclude_dfs discovery_while_go_p2p_dev 
go_neg_forced_freq_diff_than_bss_freq p2p_go_move_reg_change 
p2ps_stale_group_removal2 p2ps_channel_active_go_and_station_different_mcc 
radius_acct_interim_unreachable mesh_secure_ocv_mix_legacy 
mesh_secure_ocv_mix_ht wpas_mesh_open_ht40 wpas_mesh_gate_forwarding olbc_5ghz 
ap_ht40_csa ap_ht40_csa3 ap_ht_op_class_124 wpas_ap_dfs proxyarp_open_ebtables 
dpp_test_vector_p_521

Without the patches, I see following (single run):

failed tests: concurrent_grpform_while_connecting2 
fst_sta_remove_session_established fst_ap_config_oom tnc_peap_soh 
tnc_peap_soh_errors tnc_ttls tnc_ttls_fragmentation tnc_fast ap_ft_ptk_rekey 
ap_acs_exclude_dfs autogo_many discovery_group_client discovery_listen_find 
discovery_while_go p2p_go_move_reg_change p2ps_stale_group_removal2 grpform3_c 
mesh_secure_ocv_mix_legacy mesh_secure_ocv_mix_ht 
wpas_mesh_secure_sae_group_mismatch wpas_mesh_open_ht40 wpas_mesh_open_vht40 
wpas_mesh_open_vht20 mesh_open_vht_160 wpas_mesh_gate_forwarding scan 
scan_setband ap_vht160 ap_vht80_pwr_constraint proxyarp_open_ebtables

So the diff is (- == before HE patch, + == after HE patch):

     ap_acs_exclude_dfs
    +ap_ft_eap_vlan_multi
     ap_ft_ptk_rekey
    -ap_vht160
    -ap_vht80_pwr_constraint
    -autogo_many
    -concurrent_grpform_while_connecting2
    -discovery_group_client
    -discovery_listen_find
    -discovery_while_go
    -fst_ap_config_oom
    -fst_sta_remove_session_established
    -grpform3_c
    -mesh_open_vht_160
    +ap_ft_vlan_disconnected
    +ap_ht40_csa
    +ap_ht40_csa3
    +ap_ht_op_class_124
    +discovery_while_go_p2p_dev
    +dpp_test_vector_p_521
    +fst_sta_tear_down_session_bad_fsts_id
    +go_neg_forced_freq_diff_than_bss_freq
    +ibss_5ghz
     mesh_secure_ocv_mix_ht
     mesh_secure_ocv_mix_legacy
    +olbc_5ghz
     p2p_go_move_reg_change
    +p2ps_channel_active_go_and_station_different_mcc
    +p2p_set_discoverability
     p2ps_stale_group_removal2
     proxyarp_open_ebtables
    -scan
    -scan_setband
    +radius_acct_interim_unreachable
     tnc_fast
     tnc_peap_soh
     tnc_peap_soh_errors
     tnc_ttls
     tnc_ttls_fragmentation
    +wpas_ap_dfs
     wpas_mesh_gate_forwarding
     wpas_mesh_open_ht40
    -wpas_mesh_open_vht20
    -wpas_mesh_open_vht40
    -wpas_mesh_secure_sae_group_mismatch

None of the "+" marked tests are reproducible (they test suite just randomly 
fails as it looks like in the moment).

Hostapd version was 05822609d105 ("HE: MCS size is always a minimum of 4 
bytes") with two pending patches [1,2]. Either John will resend the first 
patch [1] or (when he is busy) I will do it in the next days.

Kind regards,
	Sven

[1] https://patchwork.ozlabs.org/patch/1116968/
[2] https://patchwork.ozlabs.org/patch/1131273/

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

^ permalink raw reply

* Re: [RFC PATCH v7] rtl8xxxu: Improve TX performance of RTL8723BU on rtl8xxxu driver
From: Jes Sorensen @ 2019-08-12 15:21 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Chris Chiu, davem, linux-wireless, netdev, linux-kernel, linux,
	Daniel Drake
In-Reply-To: <87wofibgk7.fsf@kamboji.qca.qualcomm.com>

On 8/12/19 10:32 AM, Kalle Valo wrote:
> Jes Sorensen <jes.sorensen@gmail.com> writes:
>> Looks good to me! Nice work! I am actually very curious if this will
>> improve performance 8192eu as well.
>>
>> Ideally I'd like to figure out how to make host controlled rates work,
>> but in all my experiments with that, I never really got it to work well.
>>
>> Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
> 
> This is marked as RFC so I'm not sure what's the plan. Should I apply
> this?

I think it's at a point where it's worth applying - I kinda wish I had
had time to test it, but I won't be near my stash of USB dongles for a
little while.

Cheers,
Jes


^ permalink raw reply

* Re: [RFC PATCH v7] rtl8xxxu: Improve TX performance of RTL8723BU on rtl8xxxu driver
From: Kalle Valo @ 2019-08-12 14:32 UTC (permalink / raw)
  To: Jes Sorensen
  Cc: Chris Chiu, davem, linux-wireless, netdev, linux-kernel, linux,
	Daniel Drake
In-Reply-To: <d0047834-957d-0cf3-5792-31faa5315ad1@gmail.com>

Jes Sorensen <jes.sorensen@gmail.com> writes:

> On 8/5/19 9:14 AM, Chris Chiu wrote:
>> We have 3 laptops which connect the wifi by the same RTL8723BU.
>> The PCI VID/PID of the wifi chip is 10EC:B720 which is supported.
>> They have the same problem with the in-kernel rtl8xxxu driver, the
>> iperf (as a client to an ethernet-connected server) gets ~1Mbps.
>> Nevertheless, the signal strength is reported as around -40dBm,
>> which is quite good. From the wireshark capture, the tx rate for each
>> data and qos data packet is only 1Mbps. Compare to the Realtek driver
>> at https://github.com/lwfinger/rtl8723bu, the same iperf test gets
>> ~12Mbps or better. The signal strength is reported similarly around
>> -40dBm. That's why we want to improve.
>> 
>> After reading the source code of the rtl8xxxu driver and Realtek's, the
>> major difference is that Realtek's driver has a watchdog which will keep
>> monitoring the signal quality and updating the rate mask just like the
>> rtl8xxxu_gen2_update_rate_mask() does if signal quality changes.
>> And this kind of watchdog also exists in rtlwifi driver of some specific
>> chips, ex rtl8192ee, rtl8188ee, rtl8723ae, rtl8821ae...etc. They have
>> the same member function named dm_watchdog and will invoke the
>> corresponding dm_refresh_rate_adaptive_mask to adjust the tx rate
>> mask.
>> 
>> With this commit, the tx rate of each data and qos data packet will
>> be 39Mbps (MCS4) with the 0xF00000 as the tx rate mask. The 20th bit
>> to 23th bit means MCS4 to MCS7. It means that the firmware still picks
>> the lowest rate from the rate mask and explains why the tx rate of
>> data and qos data is always lowest 1Mbps because the default rate mask
>> passed is always 0xFFFFFFF ranges from the basic CCK rate, OFDM rate,
>> and MCS rate. However, with Realtek's driver, the tx rate observed from
>> wireshark under the same condition is almost 65Mbps or 72Mbps, which
>> indicating that rtl8xxxu could still be further improved.
>> 
>> Signed-off-by: Chris Chiu <chiu@endlessm.com>
>> Reviewed-by: Daniel Drake <drake@endlessm.com>
>> ---
>
> Looks good to me! Nice work! I am actually very curious if this will
> improve performance 8192eu as well.
>
> Ideally I'd like to figure out how to make host controlled rates work,
> but in all my experiments with that, I never really got it to work well.
>
> Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>

This is marked as RFC so I'm not sure what's the plan. Should I apply
this?

-- 
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

^ permalink raw reply

* Re: [RFC PATCH v7] rtl8xxxu: Improve TX performance of RTL8723BU on rtl8xxxu driver
From: Jes Sorensen @ 2019-08-12 13:38 UTC (permalink / raw)
  To: Chris Chiu, kvalo, davem
  Cc: linux-wireless, netdev, linux-kernel, linux, Daniel Drake
In-Reply-To: <20190805131452.13257-1-chiu@endlessm.com>

On 8/5/19 9:14 AM, Chris Chiu wrote:
> We have 3 laptops which connect the wifi by the same RTL8723BU.
> The PCI VID/PID of the wifi chip is 10EC:B720 which is supported.
> They have the same problem with the in-kernel rtl8xxxu driver, the
> iperf (as a client to an ethernet-connected server) gets ~1Mbps.
> Nevertheless, the signal strength is reported as around -40dBm,
> which is quite good. From the wireshark capture, the tx rate for each
> data and qos data packet is only 1Mbps. Compare to the Realtek driver
> at https://github.com/lwfinger/rtl8723bu, the same iperf test gets
> ~12Mbps or better. The signal strength is reported similarly around
> -40dBm. That's why we want to improve.
> 
> After reading the source code of the rtl8xxxu driver and Realtek's, the
> major difference is that Realtek's driver has a watchdog which will keep
> monitoring the signal quality and updating the rate mask just like the
> rtl8xxxu_gen2_update_rate_mask() does if signal quality changes.
> And this kind of watchdog also exists in rtlwifi driver of some specific
> chips, ex rtl8192ee, rtl8188ee, rtl8723ae, rtl8821ae...etc. They have
> the same member function named dm_watchdog and will invoke the
> corresponding dm_refresh_rate_adaptive_mask to adjust the tx rate
> mask.
> 
> With this commit, the tx rate of each data and qos data packet will
> be 39Mbps (MCS4) with the 0xF00000 as the tx rate mask. The 20th bit
> to 23th bit means MCS4 to MCS7. It means that the firmware still picks
> the lowest rate from the rate mask and explains why the tx rate of
> data and qos data is always lowest 1Mbps because the default rate mask
> passed is always 0xFFFFFFF ranges from the basic CCK rate, OFDM rate,
> and MCS rate. However, with Realtek's driver, the tx rate observed from
> wireshark under the same condition is almost 65Mbps or 72Mbps, which
> indicating that rtl8xxxu could still be further improved.
> 
> Signed-off-by: Chris Chiu <chiu@endlessm.com>
> Reviewed-by: Daniel Drake <drake@endlessm.com>
> ---

Looks good to me! Nice work! I am actually very curious if this will
improve performance 8192eu as well.

Ideally I'd like to figure out how to make host controlled rates work,
but in all my experiments with that, I never really got it to work well.

Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>

Jes


> 
> Notes:
>   v2:
>    - Fix errors and warnings complained by checkpatch.pl
>    - Replace data structure rate_adaptive by 2 member variables
>    - Make rtl8xxxu_wireless_mode non-static
>    - Runs refresh_rate_mask() only in station mode
>   v3:
>    - Remove ugly rtl8xxxu_watchdog data structure
>    - Make sure only one vif exists
>   v4:
>    - Move cancel_delayed_work from rtl8xxxu_disconnect to rtl8xxxu_stop
>    - Clear priv->vif in rtl8xxxu_remove_interface
>    - Add rateid as the function argument of update_rate_mask
>    - Rephrase the comment for priv->vif more explicit.
>   v5:
>    - Make refresh_rate_mask() generic for all sub-drivers.
>    - Add definitions for SNR related to help determine rssi_level
>   v6: 
>    - Fix typo of the comment for priv->vif
>   v7:
>    - Fix reported bug of watchdog stop 
>    - refer to the RxPWDBAll in vendor driver for SNR calculation
> 
> 
>  .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h  |  55 ++++-
>  .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 229 +++++++++++++++++-
>  2 files changed, 277 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> index ade057d868f7..582c2a346cec 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> @@ -1187,6 +1187,48 @@ struct rtl8723bu_c2h {
>  
>  struct rtl8xxxu_fileops;
>  
> +/*mlme related.*/
> +enum wireless_mode {
> +	WIRELESS_MODE_UNKNOWN = 0,
> +	/* Sub-Element */
> +	WIRELESS_MODE_B = BIT(0),
> +	WIRELESS_MODE_G = BIT(1),
> +	WIRELESS_MODE_A = BIT(2),
> +	WIRELESS_MODE_N_24G = BIT(3),
> +	WIRELESS_MODE_N_5G = BIT(4),
> +	WIRELESS_AUTO = BIT(5),
> +	WIRELESS_MODE_AC = BIT(6),
> +	WIRELESS_MODE_MAX = 0x7F,
> +};
> +
> +/* from rtlwifi/wifi.h */
> +enum ratr_table_mode_new {
> +	RATEID_IDX_BGN_40M_2SS = 0,
> +	RATEID_IDX_BGN_40M_1SS = 1,
> +	RATEID_IDX_BGN_20M_2SS_BN = 2,
> +	RATEID_IDX_BGN_20M_1SS_BN = 3,
> +	RATEID_IDX_GN_N2SS = 4,
> +	RATEID_IDX_GN_N1SS = 5,
> +	RATEID_IDX_BG = 6,
> +	RATEID_IDX_G = 7,
> +	RATEID_IDX_B = 8,
> +	RATEID_IDX_VHT_2SS = 9,
> +	RATEID_IDX_VHT_1SS = 10,
> +	RATEID_IDX_MIX1 = 11,
> +	RATEID_IDX_MIX2 = 12,
> +	RATEID_IDX_VHT_3SS = 13,
> +	RATEID_IDX_BGN_3SS = 14,
> +};
> +
> +#define RTL8XXXU_RATR_STA_INIT 0
> +#define RTL8XXXU_RATR_STA_HIGH 1
> +#define RTL8XXXU_RATR_STA_MID  2
> +#define RTL8XXXU_RATR_STA_LOW  3
> +
> +#define RTL8XXXU_NOISE_FLOOR_MIN	-100
> +#define RTL8XXXU_SNR_THRESH_HIGH	50
> +#define RTL8XXXU_SNR_THRESH_LOW	20
> +
>  struct rtl8xxxu_priv {
>  	struct ieee80211_hw *hw;
>  	struct usb_device *udev;
> @@ -1291,6 +1333,13 @@ struct rtl8xxxu_priv {
>  	u8 pi_enabled:1;
>  	u8 no_pape:1;
>  	u8 int_buf[USB_INTR_CONTENT_LENGTH];
> +	u8 rssi_level;
> +	/*
> +	 * Only one virtual interface permitted because only STA mode
> +	 * is supported and no iface_combinations are provided.
> +	 */
> +	struct ieee80211_vif *vif;
> +	struct delayed_work ra_watchdog;
>  };
>  
>  struct rtl8xxxu_rx_urb {
> @@ -1326,7 +1375,7 @@ struct rtl8xxxu_fileops {
>  	void (*set_tx_power) (struct rtl8xxxu_priv *priv, int channel,
>  			      bool ht40);
>  	void (*update_rate_mask) (struct rtl8xxxu_priv *priv,
> -				  u32 ramask, int sgi);
> +				  u32 ramask, u8 rateid, int sgi);
>  	void (*report_connect) (struct rtl8xxxu_priv *priv,
>  				u8 macid, bool connect);
>  	void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
> @@ -1411,9 +1460,9 @@ void rtl8xxxu_gen2_config_channel(struct ieee80211_hw *hw);
>  void rtl8xxxu_gen1_usb_quirks(struct rtl8xxxu_priv *priv);
>  void rtl8xxxu_gen2_usb_quirks(struct rtl8xxxu_priv *priv);
>  void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv,
> -			       u32 ramask, int sgi);
> +			       u32 ramask, u8 rateid, int sgi);
>  void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
> -				    u32 ramask, int sgi);
> +				    u32 ramask, u8 rateid, int sgi);
>  void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv,
>  				  u8 macid, bool connect);
>  void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> index c6c41fb962ff..a6f358b9e447 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> @@ -4304,7 +4304,8 @@ static void rtl8xxxu_sw_scan_complete(struct ieee80211_hw *hw,
>  	rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
>  }
>  
> -void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv, u32 ramask, int sgi)
> +void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv,
> +			       u32 ramask, u8 rateid, int sgi)
>  {
>  	struct h2c_cmd h2c;
>  
> @@ -4324,7 +4325,7 @@ void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv, u32 ramask, int sgi)
>  }
>  
>  void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
> -				    u32 ramask, int sgi)
> +				    u32 ramask, u8 rateid, int sgi)
>  {
>  	struct h2c_cmd h2c;
>  	u8 bw = 0;
> @@ -4338,7 +4339,7 @@ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
>  	h2c.b_macid_cfg.ramask3 = (ramask >> 24) & 0xff;
>  
>  	h2c.ramask.arg = 0x80;
> -	h2c.b_macid_cfg.data1 = 0;
> +	h2c.b_macid_cfg.data1 = rateid;
>  	if (sgi)
>  		h2c.b_macid_cfg.data1 |= BIT(7);
>  
> @@ -4478,6 +4479,40 @@ static void rtl8xxxu_set_basic_rates(struct rtl8xxxu_priv *priv, u32 rate_cfg)
>  	rtl8xxxu_write8(priv, REG_INIRTS_RATE_SEL, rate_idx);
>  }
>  
> +static u16
> +rtl8xxxu_wireless_mode(struct ieee80211_hw *hw, struct ieee80211_sta *sta)
> +{
> +	u16 network_type = WIRELESS_MODE_UNKNOWN;
> +	u32 rate_mask;
> +
> +	rate_mask = (sta->supp_rates[0] & 0xfff) |
> +		    (sta->ht_cap.mcs.rx_mask[0] << 12) |
> +		    (sta->ht_cap.mcs.rx_mask[0] << 20);
> +
> +	if (hw->conf.chandef.chan->band == NL80211_BAND_5GHZ) {
> +		if (sta->vht_cap.vht_supported)
> +			network_type = WIRELESS_MODE_AC;
> +		else if (sta->ht_cap.ht_supported)
> +			network_type = WIRELESS_MODE_N_5G;
> +
> +		network_type |= WIRELESS_MODE_A;
> +	} else {
> +		if (sta->vht_cap.vht_supported)
> +			network_type = WIRELESS_MODE_AC;
> +		else if (sta->ht_cap.ht_supported)
> +			network_type = WIRELESS_MODE_N_24G;
> +
> +		if (sta->supp_rates[0] <= 0xf)
> +			network_type |= WIRELESS_MODE_B;
> +		else if (sta->supp_rates[0] & 0xf)
> +			network_type |= (WIRELESS_MODE_B | WIRELESS_MODE_G);
> +		else
> +			network_type |= WIRELESS_MODE_G;
> +	}
> +
> +	return network_type;
> +}
> +
>  static void
>  rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
>  			  struct ieee80211_bss_conf *bss_conf, u32 changed)
> @@ -4520,7 +4555,10 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
>  				sgi = 1;
>  			rcu_read_unlock();
>  
> -			priv->fops->update_rate_mask(priv, ramask, sgi);
> +			priv->vif = vif;
> +			priv->rssi_level = RTL8XXXU_RATR_STA_INIT;
> +
> +			priv->fops->update_rate_mask(priv, ramask, 0, sgi);
>  
>  			rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);
>  
> @@ -5464,6 +5502,10 @@ static int rtl8xxxu_add_interface(struct ieee80211_hw *hw,
>  
>  	switch (vif->type) {
>  	case NL80211_IFTYPE_STATION:
> +		if (!priv->vif)
> +			priv->vif = vif;
> +		else
> +			return -EOPNOTSUPP;
>  		rtl8xxxu_stop_tx_beacon(priv);
>  
>  		val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
> @@ -5487,6 +5529,9 @@ static void rtl8xxxu_remove_interface(struct ieee80211_hw *hw,
>  	struct rtl8xxxu_priv *priv = hw->priv;
>  
>  	dev_dbg(&priv->udev->dev, "%s\n", __func__);
> +
> +	if (priv->vif)
> +		priv->vif = NULL;
>  }
>  
>  static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed)
> @@ -5772,6 +5817,177 @@ rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
>  	return 0;
>  }
>  
> +static u8 rtl8xxxu_signal_to_snr(int signal)
> +{
> +	if (signal < RTL8XXXU_NOISE_FLOOR_MIN)
> +		signal = RTL8XXXU_NOISE_FLOOR_MIN;
> +	else if (signal > 0)
> +		signal = 0;
> +	return (u8)(signal - RTL8XXXU_NOISE_FLOOR_MIN);
> +}
> +
> +static void rtl8xxxu_refresh_rate_mask(struct rtl8xxxu_priv *priv,
> +				       int signal, struct ieee80211_sta *sta)
> +{
> +	struct ieee80211_hw *hw = priv->hw;
> +	u16 wireless_mode;
> +	u8 rssi_level, ratr_idx;
> +	u8 txbw_40mhz;
> +	u8 snr, snr_thresh_high, snr_thresh_low;
> +	u8 go_up_gap = 5;
> +
> +	rssi_level = priv->rssi_level;
> +	snr = rtl8xxxu_signal_to_snr(signal);
> +	snr_thresh_high = RTL8XXXU_SNR_THRESH_HIGH;
> +	snr_thresh_low = RTL8XXXU_SNR_THRESH_LOW;
> +	txbw_40mhz = (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) ? 1 : 0;
> +
> +	switch (rssi_level) {
> +	case RTL8XXXU_RATR_STA_MID:
> +		snr_thresh_high += go_up_gap;
> +		break;
> +	case RTL8XXXU_RATR_STA_LOW:
> +		snr_thresh_high += go_up_gap;
> +		snr_thresh_low += go_up_gap;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	if (snr > snr_thresh_high)
> +		rssi_level = RTL8XXXU_RATR_STA_HIGH;
> +	else if (snr > snr_thresh_low)
> +		rssi_level = RTL8XXXU_RATR_STA_MID;
> +	else
> +		rssi_level = RTL8XXXU_RATR_STA_LOW;
> +
> +	if (rssi_level != priv->rssi_level) {
> +		int sgi = 0;
> +		u32 rate_bitmap = 0;
> +
> +		rcu_read_lock();
> +		rate_bitmap = (sta->supp_rates[0] & 0xfff) |
> +				(sta->ht_cap.mcs.rx_mask[0] << 12) |
> +				(sta->ht_cap.mcs.rx_mask[1] << 20);
> +		if (sta->ht_cap.cap &
> +		    (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20))
> +			sgi = 1;
> +		rcu_read_unlock();
> +
> +		wireless_mode = rtl8xxxu_wireless_mode(hw, sta);
> +		switch (wireless_mode) {
> +		case WIRELESS_MODE_B:
> +			ratr_idx = RATEID_IDX_B;
> +			if (rate_bitmap & 0x0000000c)
> +				rate_bitmap &= 0x0000000d;
> +			else
> +				rate_bitmap &= 0x0000000f;
> +			break;
> +		case WIRELESS_MODE_A:
> +		case WIRELESS_MODE_G:
> +			ratr_idx = RATEID_IDX_G;
> +			if (rssi_level == RTL8XXXU_RATR_STA_HIGH)
> +				rate_bitmap &= 0x00000f00;
> +			else
> +				rate_bitmap &= 0x00000ff0;
> +			break;
> +		case (WIRELESS_MODE_B | WIRELESS_MODE_G):
> +			ratr_idx = RATEID_IDX_BG;
> +			if (rssi_level == RTL8XXXU_RATR_STA_HIGH)
> +				rate_bitmap &= 0x00000f00;
> +			else if (rssi_level == RTL8XXXU_RATR_STA_MID)
> +				rate_bitmap &= 0x00000ff0;
> +			else
> +				rate_bitmap &= 0x00000ff5;
> +			break;
> +		case WIRELESS_MODE_N_24G:
> +		case WIRELESS_MODE_N_5G:
> +		case (WIRELESS_MODE_G | WIRELESS_MODE_N_24G):
> +		case (WIRELESS_MODE_A | WIRELESS_MODE_N_5G):
> +			if (priv->tx_paths == 2 && priv->rx_paths == 2)
> +				ratr_idx = RATEID_IDX_GN_N2SS;
> +			else
> +				ratr_idx = RATEID_IDX_GN_N1SS;
> +		case (WIRELESS_MODE_B | WIRELESS_MODE_G | WIRELESS_MODE_N_24G):
> +		case (WIRELESS_MODE_B | WIRELESS_MODE_N_24G):
> +			if (txbw_40mhz) {
> +				if (priv->tx_paths == 2 && priv->rx_paths == 2)
> +					ratr_idx = RATEID_IDX_BGN_40M_2SS;
> +				else
> +					ratr_idx = RATEID_IDX_BGN_40M_1SS;
> +			} else {
> +				if (priv->tx_paths == 2 && priv->rx_paths == 2)
> +					ratr_idx = RATEID_IDX_BGN_20M_2SS_BN;
> +				else
> +					ratr_idx = RATEID_IDX_BGN_20M_1SS_BN;
> +			}
> +
> +			if (priv->tx_paths == 2 && priv->rx_paths == 2) {
> +				if (rssi_level == RTL8XXXU_RATR_STA_HIGH) {
> +					rate_bitmap &= 0x0f8f0000;
> +				} else if (rssi_level == RTL8XXXU_RATR_STA_MID) {
> +					rate_bitmap &= 0x0f8ff000;
> +				} else {
> +					if (txbw_40mhz)
> +						rate_bitmap &= 0x0f8ff015;
> +					else
> +						rate_bitmap &= 0x0f8ff005;
> +				}
> +			} else {
> +				if (rssi_level == RTL8XXXU_RATR_STA_HIGH) {
> +					rate_bitmap &= 0x000f0000;
> +				} else if (rssi_level == RTL8XXXU_RATR_STA_MID) {
> +					rate_bitmap &= 0x000ff000;
> +				} else {
> +					if (txbw_40mhz)
> +						rate_bitmap &= 0x000ff015;
> +					else
> +						rate_bitmap &= 0x000ff005;
> +				}
> +			}
> +			break;
> +		default:
> +			ratr_idx = RATEID_IDX_BGN_40M_2SS;
> +			rate_bitmap &= 0x0fffffff;
> +			break;
> +		}
> +
> +		priv->rssi_level = rssi_level;
> +		priv->fops->update_rate_mask(priv, rate_bitmap, ratr_idx, sgi);
> +	}
> +}
> +
> +static void rtl8xxxu_watchdog_callback(struct work_struct *work)
> +{
> +	struct ieee80211_vif *vif;
> +	struct rtl8xxxu_priv *priv;
> +
> +	priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work);
> +	vif = priv->vif;
> +
> +	if (vif && vif->type == NL80211_IFTYPE_STATION) {
> +		int signal;
> +		struct ieee80211_sta *sta;
> +
> +		rcu_read_lock();
> +		sta = ieee80211_find_sta(vif, vif->bss_conf.bssid);
> +		if (!sta) {
> +			struct device *dev = &priv->udev->dev;
> +
> +			dev_info(dev, "%s: no sta found\n", __func__);
> +			rcu_read_unlock();
> +			goto out;
> +		}
> +		rcu_read_unlock();
> +
> +		signal = ieee80211_ave_rssi(vif);
> +		rtl8xxxu_refresh_rate_mask(priv, signal, sta);
> +	}
> +
> +out:
> +	schedule_delayed_work(&priv->ra_watchdog, 2 * HZ);
> +}
> +
>  static int rtl8xxxu_start(struct ieee80211_hw *hw)
>  {
>  	struct rtl8xxxu_priv *priv = hw->priv;
> @@ -5828,6 +6044,8 @@ static int rtl8xxxu_start(struct ieee80211_hw *hw)
>  
>  		ret = rtl8xxxu_submit_rx_urb(priv, rx_urb);
>  	}
> +
> +	schedule_delayed_work(&priv->ra_watchdog, 2 * HZ);
>  exit:
>  	/*
>  	 * Accept all data and mgmt frames
> @@ -5879,6 +6097,8 @@ static void rtl8xxxu_stop(struct ieee80211_hw *hw)
>  	if (priv->usb_interrupts)
>  		rtl8xxxu_write32(priv, REG_USB_HIMR, 0);
>  
> +	cancel_delayed_work_sync(&priv->ra_watchdog);
> +
>  	rtl8xxxu_free_rx_resources(priv);
>  	rtl8xxxu_free_tx_resources(priv);
>  }
> @@ -6051,6 +6271,7 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
>  	INIT_LIST_HEAD(&priv->rx_urb_pending_list);
>  	spin_lock_init(&priv->rx_urb_lock);
>  	INIT_WORK(&priv->rx_urb_wq, rtl8xxxu_rx_urb_work);
> +	INIT_DELAYED_WORK(&priv->ra_watchdog, rtl8xxxu_watchdog_callback);
>  
>  	usb_set_intfdata(interface, hw);
>  
> 


^ permalink raw reply

* Re: [RFC] mt76: fix tx hung regression on MT7630E
From: Stanislaw Gruszka @ 2019-08-12 11:50 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linux-wireless, Felix Fietkau, Ryder Lee, Roy Luo
In-Reply-To: <20190805123916.GA24209@redhat.com>

On Mon, Aug 05, 2019 at 02:39:16PM +0200, Stanislaw Gruszka wrote:
> On Mon, Aug 05, 2019 at 01:27:19PM +0200, Lorenzo Bianconi wrote:
> > > ... but I think we have bug when do mt76_txq_schedule_all() in
> > > tx_tasklet, because we can schedule on queues that are stoped.
> > > So reverting 41634aa8d6db and then optimize by removing tx_tasklet
> > > for mmio and remove not needed mt76_txq_schedule_all() calls looks
> > > more reasoneble to me.
> > 
> > schedule a stopped queue seems not harmful at a first glance since we do not
> > copy pending skbs if we have not enough room in the dma ring.
> 
> mac80211 stop queues for various other reasons than 
> IEEE80211_QUEUE_STOP_REASON_DRIVER .

After looking in more details, we check if queue is stopped in 
ieee80211_tx_dequeue(). But we do not check that for skb's queued
in mtxq->retry_q .

> > diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
> > index 5397827668b9..bd2d34c4f326 100644
> > --- a/drivers/net/wireless/mediatek/mt76/tx.c
> > +++ b/drivers/net/wireless/mediatek/mt76/tx.c
> > @@ -495,6 +495,9 @@ mt76_txq_schedule_list(struct mt76_dev *dev, enum mt76_txq_id qid)
> >  	while (1) {
> >  		bool empty = false;
> >  
> > +		if (hwq->stopped)
> > +			break;
> > +
> >  		if (sq->swq_queued >= 4)
> >  			break;
> > 
> > Does it fix the issue you are facing?
> 
> I'll not be able to test this patch this week. Will have access to
> the hardware next week. 
> 
> I checeked before, if
> 'q->queued + (tx_info.nbuf + 1) / 2 >= q->ndesc - 1' is triggered
> when MT7630E hangs and it is not. But maybe second part of the patch
> will help.

Patch did not help.

I debugged problem a bit more and issue is related with HW encryption.
Using full mac80211 SW encyption by retuning -EOPNOTSUPP
mt76x02_set_key() make the problem gone as well. Looks there is
some race between setting HW keys and transmitting.

Stanislaw

^ permalink raw reply

* Re: [PATCH] mt76: mt76x02u: enable multi-vif support
From: Stanislaw Gruszka @ 2019-08-12 11:37 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: Lorenzo Bianconi, Felix Fietkau, linux-wireless
In-Reply-To: <CAJ0CqmVXC1-o3rXuho8rBqfa4Xip3WcxSTsQa=POdzXRZMaETg@mail.gmail.com>

On Mon, Aug 05, 2019 at 01:08:15PM +0200, Lorenzo Bianconi wrote:
> >
> > On Fri, Aug 02, 2019 at 04:36:20PM +0200, Lorenzo Bianconi wrote:
> > > Enable multi-interface support for mt76x02u driver. For the moment
> > > allow max two concurrent interfaces in order to preserve enough room
> > > for ps traffic since we are using beacon slots for it.
> > > I have successfully tested the following configuration:
> > > - AP + STA
> > > - AP0 + AP1
> >
> > The combination that did not work in my testing was STA + STA .
> > This should be fixed or disabled.
> >
> 
> Hi Stanislaw,
> 
> I have just tested STA/STA configuration and it works in my setup.

Confirmed, it works for me as well on current code base.

Tested-by: Stanislaw Gruszka <sgruszka@redhat.com>

^ permalink raw reply

* Re: [RFC PATCH v7] rtl8xxxu: Improve TX performance of RTL8723BU on rtl8xxxu driver
From: Chris Chiu @ 2019-08-12 10:37 UTC (permalink / raw)
  To: Jes Sorensen, Kalle Valo, David Miller
  Cc: linux-wireless, netdev, Linux Kernel, Linux Upstreaming Team,
	Daniel Drake
In-Reply-To: <20190805131452.13257-1-chiu@endlessm.com>

On Mon, Aug 5, 2019 at 9:15 PM Chris Chiu <chiu@endlessm.com> wrote:
>
> We have 3 laptops which connect the wifi by the same RTL8723BU.
> The PCI VID/PID of the wifi chip is 10EC:B720 which is supported.
> They have the same problem with the in-kernel rtl8xxxu driver, the
> iperf (as a client to an ethernet-connected server) gets ~1Mbps.
> Nevertheless, the signal strength is reported as around -40dBm,
> which is quite good. From the wireshark capture, the tx rate for each
> data and qos data packet is only 1Mbps. Compare to the Realtek driver
> at https://github.com/lwfinger/rtl8723bu, the same iperf test gets
> ~12Mbps or better. The signal strength is reported similarly around
> -40dBm. That's why we want to improve.
>
> After reading the source code of the rtl8xxxu driver and Realtek's, the
> major difference is that Realtek's driver has a watchdog which will keep
> monitoring the signal quality and updating the rate mask just like the
> rtl8xxxu_gen2_update_rate_mask() does if signal quality changes.
> And this kind of watchdog also exists in rtlwifi driver of some specific
> chips, ex rtl8192ee, rtl8188ee, rtl8723ae, rtl8821ae...etc. They have
> the same member function named dm_watchdog and will invoke the
> corresponding dm_refresh_rate_adaptive_mask to adjust the tx rate
> mask.
>
> With this commit, the tx rate of each data and qos data packet will
> be 39Mbps (MCS4) with the 0xF00000 as the tx rate mask. The 20th bit
> to 23th bit means MCS4 to MCS7. It means that the firmware still picks
> the lowest rate from the rate mask and explains why the tx rate of
> data and qos data is always lowest 1Mbps because the default rate mask
> passed is always 0xFFFFFFF ranges from the basic CCK rate, OFDM rate,
> and MCS rate. However, with Realtek's driver, the tx rate observed from
> wireshark under the same condition is almost 65Mbps or 72Mbps, which
> indicating that rtl8xxxu could still be further improved.
>
> Signed-off-by: Chris Chiu <chiu@endlessm.com>
> Reviewed-by: Daniel Drake <drake@endlessm.com>
Tested-by: Kleintje Jens <jkleintje@ultratronik.de>
> ---
>
>
> Notes:
>   v2:
>    - Fix errors and warnings complained by checkpatch.pl
>    - Replace data structure rate_adaptive by 2 member variables
>    - Make rtl8xxxu_wireless_mode non-static
>    - Runs refresh_rate_mask() only in station mode
>   v3:
>    - Remove ugly rtl8xxxu_watchdog data structure
>    - Make sure only one vif exists
>   v4:
>    - Move cancel_delayed_work from rtl8xxxu_disconnect to rtl8xxxu_stop
>    - Clear priv->vif in rtl8xxxu_remove_interface
>    - Add rateid as the function argument of update_rate_mask
>    - Rephrase the comment for priv->vif more explicit.
>   v5:
>    - Make refresh_rate_mask() generic for all sub-drivers.
>    - Add definitions for SNR related to help determine rssi_level
>   v6:
>    - Fix typo of the comment for priv->vif
>   v7:
>    - Fix reported bug of watchdog stop
>    - refer to the RxPWDBAll in vendor driver for SNR calculation
>
>
>  .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h  |  55 ++++-
>  .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 229 +++++++++++++++++-
>  2 files changed, 277 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> index ade057d868f7..582c2a346cec 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> @@ -1187,6 +1187,48 @@ struct rtl8723bu_c2h {
>
>  struct rtl8xxxu_fileops;
>
> +/*mlme related.*/
> +enum wireless_mode {
> +       WIRELESS_MODE_UNKNOWN = 0,
> +       /* Sub-Element */
> +       WIRELESS_MODE_B = BIT(0),
> +       WIRELESS_MODE_G = BIT(1),
> +       WIRELESS_MODE_A = BIT(2),
> +       WIRELESS_MODE_N_24G = BIT(3),
> +       WIRELESS_MODE_N_5G = BIT(4),
> +       WIRELESS_AUTO = BIT(5),
> +       WIRELESS_MODE_AC = BIT(6),
> +       WIRELESS_MODE_MAX = 0x7F,
> +};
> +
> +/* from rtlwifi/wifi.h */
> +enum ratr_table_mode_new {
> +       RATEID_IDX_BGN_40M_2SS = 0,
> +       RATEID_IDX_BGN_40M_1SS = 1,
> +       RATEID_IDX_BGN_20M_2SS_BN = 2,
> +       RATEID_IDX_BGN_20M_1SS_BN = 3,
> +       RATEID_IDX_GN_N2SS = 4,
> +       RATEID_IDX_GN_N1SS = 5,
> +       RATEID_IDX_BG = 6,
> +       RATEID_IDX_G = 7,
> +       RATEID_IDX_B = 8,
> +       RATEID_IDX_VHT_2SS = 9,
> +       RATEID_IDX_VHT_1SS = 10,
> +       RATEID_IDX_MIX1 = 11,
> +       RATEID_IDX_MIX2 = 12,
> +       RATEID_IDX_VHT_3SS = 13,
> +       RATEID_IDX_BGN_3SS = 14,
> +};
> +
> +#define RTL8XXXU_RATR_STA_INIT 0
> +#define RTL8XXXU_RATR_STA_HIGH 1
> +#define RTL8XXXU_RATR_STA_MID  2
> +#define RTL8XXXU_RATR_STA_LOW  3
> +
> +#define RTL8XXXU_NOISE_FLOOR_MIN       -100
> +#define RTL8XXXU_SNR_THRESH_HIGH       50
> +#define RTL8XXXU_SNR_THRESH_LOW        20
> +
>  struct rtl8xxxu_priv {
>         struct ieee80211_hw *hw;
>         struct usb_device *udev;
> @@ -1291,6 +1333,13 @@ struct rtl8xxxu_priv {
>         u8 pi_enabled:1;
>         u8 no_pape:1;
>         u8 int_buf[USB_INTR_CONTENT_LENGTH];
> +       u8 rssi_level;
> +       /*
> +        * Only one virtual interface permitted because only STA mode
> +        * is supported and no iface_combinations are provided.
> +        */
> +       struct ieee80211_vif *vif;
> +       struct delayed_work ra_watchdog;
>  };
>
>  struct rtl8xxxu_rx_urb {
> @@ -1326,7 +1375,7 @@ struct rtl8xxxu_fileops {
>         void (*set_tx_power) (struct rtl8xxxu_priv *priv, int channel,
>                               bool ht40);
>         void (*update_rate_mask) (struct rtl8xxxu_priv *priv,
> -                                 u32 ramask, int sgi);
> +                                 u32 ramask, u8 rateid, int sgi);
>         void (*report_connect) (struct rtl8xxxu_priv *priv,
>                                 u8 macid, bool connect);
>         void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
> @@ -1411,9 +1460,9 @@ void rtl8xxxu_gen2_config_channel(struct ieee80211_hw *hw);
>  void rtl8xxxu_gen1_usb_quirks(struct rtl8xxxu_priv *priv);
>  void rtl8xxxu_gen2_usb_quirks(struct rtl8xxxu_priv *priv);
>  void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv,
> -                              u32 ramask, int sgi);
> +                              u32 ramask, u8 rateid, int sgi);
>  void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
> -                                   u32 ramask, int sgi);
> +                                   u32 ramask, u8 rateid, int sgi);
>  void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv,
>                                   u8 macid, bool connect);
>  void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> index c6c41fb962ff..a6f358b9e447 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> @@ -4304,7 +4304,8 @@ static void rtl8xxxu_sw_scan_complete(struct ieee80211_hw *hw,
>         rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
>  }
>
> -void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv, u32 ramask, int sgi)
> +void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv,
> +                              u32 ramask, u8 rateid, int sgi)
>  {
>         struct h2c_cmd h2c;
>
> @@ -4324,7 +4325,7 @@ void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv, u32 ramask, int sgi)
>  }
>
>  void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
> -                                   u32 ramask, int sgi)
> +                                   u32 ramask, u8 rateid, int sgi)
>  {
>         struct h2c_cmd h2c;
>         u8 bw = 0;
> @@ -4338,7 +4339,7 @@ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
>         h2c.b_macid_cfg.ramask3 = (ramask >> 24) & 0xff;
>
>         h2c.ramask.arg = 0x80;
> -       h2c.b_macid_cfg.data1 = 0;
> +       h2c.b_macid_cfg.data1 = rateid;
>         if (sgi)
>                 h2c.b_macid_cfg.data1 |= BIT(7);
>
> @@ -4478,6 +4479,40 @@ static void rtl8xxxu_set_basic_rates(struct rtl8xxxu_priv *priv, u32 rate_cfg)
>         rtl8xxxu_write8(priv, REG_INIRTS_RATE_SEL, rate_idx);
>  }
>
> +static u16
> +rtl8xxxu_wireless_mode(struct ieee80211_hw *hw, struct ieee80211_sta *sta)
> +{
> +       u16 network_type = WIRELESS_MODE_UNKNOWN;
> +       u32 rate_mask;
> +
> +       rate_mask = (sta->supp_rates[0] & 0xfff) |
> +                   (sta->ht_cap.mcs.rx_mask[0] << 12) |
> +                   (sta->ht_cap.mcs.rx_mask[0] << 20);
> +
> +       if (hw->conf.chandef.chan->band == NL80211_BAND_5GHZ) {
> +               if (sta->vht_cap.vht_supported)
> +                       network_type = WIRELESS_MODE_AC;
> +               else if (sta->ht_cap.ht_supported)
> +                       network_type = WIRELESS_MODE_N_5G;
> +
> +               network_type |= WIRELESS_MODE_A;
> +       } else {
> +               if (sta->vht_cap.vht_supported)
> +                       network_type = WIRELESS_MODE_AC;
> +               else if (sta->ht_cap.ht_supported)
> +                       network_type = WIRELESS_MODE_N_24G;
> +
> +               if (sta->supp_rates[0] <= 0xf)
> +                       network_type |= WIRELESS_MODE_B;
> +               else if (sta->supp_rates[0] & 0xf)
> +                       network_type |= (WIRELESS_MODE_B | WIRELESS_MODE_G);
> +               else
> +                       network_type |= WIRELESS_MODE_G;
> +       }
> +
> +       return network_type;
> +}
> +
>  static void
>  rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
>                           struct ieee80211_bss_conf *bss_conf, u32 changed)
> @@ -4520,7 +4555,10 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
>                                 sgi = 1;
>                         rcu_read_unlock();
>
> -                       priv->fops->update_rate_mask(priv, ramask, sgi);
> +                       priv->vif = vif;
> +                       priv->rssi_level = RTL8XXXU_RATR_STA_INIT;
> +
> +                       priv->fops->update_rate_mask(priv, ramask, 0, sgi);
>
>                         rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);
>
> @@ -5464,6 +5502,10 @@ static int rtl8xxxu_add_interface(struct ieee80211_hw *hw,
>
>         switch (vif->type) {
>         case NL80211_IFTYPE_STATION:
> +               if (!priv->vif)
> +                       priv->vif = vif;
> +               else
> +                       return -EOPNOTSUPP;
>                 rtl8xxxu_stop_tx_beacon(priv);
>
>                 val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
> @@ -5487,6 +5529,9 @@ static void rtl8xxxu_remove_interface(struct ieee80211_hw *hw,
>         struct rtl8xxxu_priv *priv = hw->priv;
>
>         dev_dbg(&priv->udev->dev, "%s\n", __func__);
> +
> +       if (priv->vif)
> +               priv->vif = NULL;
>  }
>
>  static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed)
> @@ -5772,6 +5817,177 @@ rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
>         return 0;
>  }
>
> +static u8 rtl8xxxu_signal_to_snr(int signal)
> +{
> +       if (signal < RTL8XXXU_NOISE_FLOOR_MIN)
> +               signal = RTL8XXXU_NOISE_FLOOR_MIN;
> +       else if (signal > 0)
> +               signal = 0;
> +       return (u8)(signal - RTL8XXXU_NOISE_FLOOR_MIN);
> +}
> +
> +static void rtl8xxxu_refresh_rate_mask(struct rtl8xxxu_priv *priv,
> +                                      int signal, struct ieee80211_sta *sta)
> +{
> +       struct ieee80211_hw *hw = priv->hw;
> +       u16 wireless_mode;
> +       u8 rssi_level, ratr_idx;
> +       u8 txbw_40mhz;
> +       u8 snr, snr_thresh_high, snr_thresh_low;
> +       u8 go_up_gap = 5;
> +
> +       rssi_level = priv->rssi_level;
> +       snr = rtl8xxxu_signal_to_snr(signal);
> +       snr_thresh_high = RTL8XXXU_SNR_THRESH_HIGH;
> +       snr_thresh_low = RTL8XXXU_SNR_THRESH_LOW;
> +       txbw_40mhz = (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) ? 1 : 0;
> +
> +       switch (rssi_level) {
> +       case RTL8XXXU_RATR_STA_MID:
> +               snr_thresh_high += go_up_gap;
> +               break;
> +       case RTL8XXXU_RATR_STA_LOW:
> +               snr_thresh_high += go_up_gap;
> +               snr_thresh_low += go_up_gap;
> +               break;
> +       default:
> +               break;
> +       }
> +
> +       if (snr > snr_thresh_high)
> +               rssi_level = RTL8XXXU_RATR_STA_HIGH;
> +       else if (snr > snr_thresh_low)
> +               rssi_level = RTL8XXXU_RATR_STA_MID;
> +       else
> +               rssi_level = RTL8XXXU_RATR_STA_LOW;
> +
> +       if (rssi_level != priv->rssi_level) {
> +               int sgi = 0;
> +               u32 rate_bitmap = 0;
> +
> +               rcu_read_lock();
> +               rate_bitmap = (sta->supp_rates[0] & 0xfff) |
> +                               (sta->ht_cap.mcs.rx_mask[0] << 12) |
> +                               (sta->ht_cap.mcs.rx_mask[1] << 20);
> +               if (sta->ht_cap.cap &
> +                   (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20))
> +                       sgi = 1;
> +               rcu_read_unlock();
> +
> +               wireless_mode = rtl8xxxu_wireless_mode(hw, sta);
> +               switch (wireless_mode) {
> +               case WIRELESS_MODE_B:
> +                       ratr_idx = RATEID_IDX_B;
> +                       if (rate_bitmap & 0x0000000c)
> +                               rate_bitmap &= 0x0000000d;
> +                       else
> +                               rate_bitmap &= 0x0000000f;
> +                       break;
> +               case WIRELESS_MODE_A:
> +               case WIRELESS_MODE_G:
> +                       ratr_idx = RATEID_IDX_G;
> +                       if (rssi_level == RTL8XXXU_RATR_STA_HIGH)
> +                               rate_bitmap &= 0x00000f00;
> +                       else
> +                               rate_bitmap &= 0x00000ff0;
> +                       break;
> +               case (WIRELESS_MODE_B | WIRELESS_MODE_G):
> +                       ratr_idx = RATEID_IDX_BG;
> +                       if (rssi_level == RTL8XXXU_RATR_STA_HIGH)
> +                               rate_bitmap &= 0x00000f00;
> +                       else if (rssi_level == RTL8XXXU_RATR_STA_MID)
> +                               rate_bitmap &= 0x00000ff0;
> +                       else
> +                               rate_bitmap &= 0x00000ff5;
> +                       break;
> +               case WIRELESS_MODE_N_24G:
> +               case WIRELESS_MODE_N_5G:
> +               case (WIRELESS_MODE_G | WIRELESS_MODE_N_24G):
> +               case (WIRELESS_MODE_A | WIRELESS_MODE_N_5G):
> +                       if (priv->tx_paths == 2 && priv->rx_paths == 2)
> +                               ratr_idx = RATEID_IDX_GN_N2SS;
> +                       else
> +                               ratr_idx = RATEID_IDX_GN_N1SS;
> +               case (WIRELESS_MODE_B | WIRELESS_MODE_G | WIRELESS_MODE_N_24G):
> +               case (WIRELESS_MODE_B | WIRELESS_MODE_N_24G):
> +                       if (txbw_40mhz) {
> +                               if (priv->tx_paths == 2 && priv->rx_paths == 2)
> +                                       ratr_idx = RATEID_IDX_BGN_40M_2SS;
> +                               else
> +                                       ratr_idx = RATEID_IDX_BGN_40M_1SS;
> +                       } else {
> +                               if (priv->tx_paths == 2 && priv->rx_paths == 2)
> +                                       ratr_idx = RATEID_IDX_BGN_20M_2SS_BN;
> +                               else
> +                                       ratr_idx = RATEID_IDX_BGN_20M_1SS_BN;
> +                       }
> +
> +                       if (priv->tx_paths == 2 && priv->rx_paths == 2) {
> +                               if (rssi_level == RTL8XXXU_RATR_STA_HIGH) {
> +                                       rate_bitmap &= 0x0f8f0000;
> +                               } else if (rssi_level == RTL8XXXU_RATR_STA_MID) {
> +                                       rate_bitmap &= 0x0f8ff000;
> +                               } else {
> +                                       if (txbw_40mhz)
> +                                               rate_bitmap &= 0x0f8ff015;
> +                                       else
> +                                               rate_bitmap &= 0x0f8ff005;
> +                               }
> +                       } else {
> +                               if (rssi_level == RTL8XXXU_RATR_STA_HIGH) {
> +                                       rate_bitmap &= 0x000f0000;
> +                               } else if (rssi_level == RTL8XXXU_RATR_STA_MID) {
> +                                       rate_bitmap &= 0x000ff000;
> +                               } else {
> +                                       if (txbw_40mhz)
> +                                               rate_bitmap &= 0x000ff015;
> +                                       else
> +                                               rate_bitmap &= 0x000ff005;
> +                               }
> +                       }
> +                       break;
> +               default:
> +                       ratr_idx = RATEID_IDX_BGN_40M_2SS;
> +                       rate_bitmap &= 0x0fffffff;
> +                       break;
> +               }
> +
> +               priv->rssi_level = rssi_level;
> +               priv->fops->update_rate_mask(priv, rate_bitmap, ratr_idx, sgi);
> +       }
> +}
> +
> +static void rtl8xxxu_watchdog_callback(struct work_struct *work)
> +{
> +       struct ieee80211_vif *vif;
> +       struct rtl8xxxu_priv *priv;
> +
> +       priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work);
> +       vif = priv->vif;
> +
> +       if (vif && vif->type == NL80211_IFTYPE_STATION) {
> +               int signal;
> +               struct ieee80211_sta *sta;
> +
> +               rcu_read_lock();
> +               sta = ieee80211_find_sta(vif, vif->bss_conf.bssid);
> +               if (!sta) {
> +                       struct device *dev = &priv->udev->dev;
> +
> +                       dev_info(dev, "%s: no sta found\n", __func__);
> +                       rcu_read_unlock();
> +                       goto out;
> +               }
> +               rcu_read_unlock();
> +
> +               signal = ieee80211_ave_rssi(vif);
> +               rtl8xxxu_refresh_rate_mask(priv, signal, sta);
> +       }
> +
> +out:
> +       schedule_delayed_work(&priv->ra_watchdog, 2 * HZ);
> +}
> +
>  static int rtl8xxxu_start(struct ieee80211_hw *hw)
>  {
>         struct rtl8xxxu_priv *priv = hw->priv;
> @@ -5828,6 +6044,8 @@ static int rtl8xxxu_start(struct ieee80211_hw *hw)
>
>                 ret = rtl8xxxu_submit_rx_urb(priv, rx_urb);
>         }
> +
> +       schedule_delayed_work(&priv->ra_watchdog, 2 * HZ);
>  exit:
>         /*
>          * Accept all data and mgmt frames
> @@ -5879,6 +6097,8 @@ static void rtl8xxxu_stop(struct ieee80211_hw *hw)
>         if (priv->usb_interrupts)
>                 rtl8xxxu_write32(priv, REG_USB_HIMR, 0);
>
> +       cancel_delayed_work_sync(&priv->ra_watchdog);
> +
>         rtl8xxxu_free_rx_resources(priv);
>         rtl8xxxu_free_tx_resources(priv);
>  }
> @@ -6051,6 +6271,7 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
>         INIT_LIST_HEAD(&priv->rx_urb_pending_list);
>         spin_lock_init(&priv->rx_urb_lock);
>         INIT_WORK(&priv->rx_urb_wq, rtl8xxxu_rx_urb_work);
> +       INIT_DELAYED_WORK(&priv->ra_watchdog, rtl8xxxu_watchdog_callback);
>
>         usb_set_intfdata(interface, hw);
>
> --
> 2.20.1
>

^ permalink raw reply

* Re: [PING 2] [PATCH v5 1/7] nfc: pn533: i2c: "pn532" as dt compatible string
From: Lars Poeschel @ 2019-08-12  7:40 UTC (permalink / raw)
  To: Johan Hovold
  Cc: devicetree, Samuel Ortiz, open list:NFC SUBSYSTEM, open list,
	netdev
In-Reply-To: <20190805124236.GG3574@localhost>

On Mon, Aug 05, 2019 at 02:42:36PM +0200, Johan Hovold wrote:
> You may want to resend this series to netdev now. David Miller will be
> picking up NFC patches directly from there.

Thank you very much for this information. Johannes Berg did reach out to
me already.
Rebase, test and resend is queued up for one of my next free timeslots.

Thanks again,
Lars

^ permalink raw reply

* Re: [PATCH] `iwlist scan` fails with many networks available
From: Johannes Berg @ 2019-08-11  6:25 UTC (permalink / raw)
  To: James Nylen, David S. Miller, linux-wireless, netdev,
	linux-kernel
In-Reply-To: <CABVa4NhutjvHPbyaxNeVpJjf-RMJdwEX-Yjk4bkqLC1DN3oXPA@mail.gmail.com>

On Sun, 2019-08-11 at 02:08 +0000, James Nylen wrote:
> In 5.x it's still possible for `ieee80211_scan_results` (`iwlist
> scan`) to fail when too many wireless networks are available.  This
> code path is used by `wicd`.
> 
> Previously: https://lkml.org/lkml/2017/4/2/192

This has been known for probably a decade or longer. I don't know why
'wicd' still insists on using wext, unless it's no longer maintained at
all. nl80211 doesn't have this problem at all, and I think gives more
details about the networks found too.

> I've been applying this updated patch to my own kernels since 2017 with
> no issues.  I am sure it is not the ideal way to solve this problem, but
> I'm making my fix available in case it helps others.

I don't think silently dropping data is a good solution.

I suppose we could consider applying a workaround like this if it has a
condition checking that the buffer passed in is the maximum possible
buffer (65535 bytes, due to iw_point::length being u16), but below that
-E2BIG serves well-written implementations as an indicator that they
need to retry with a bigger buffer.

> Please advise on next steps or if this is a dead end.

I think wireless extensions are in fact a dead end and all software
(even 'wicd', which seems to be the lone holdout) should migrate to
nl80211 instead.

johannes


^ permalink raw reply

* [PATCH] `iwlist scan` fails with many networks available
From: James Nylen @ 2019-08-11  2:08 UTC (permalink / raw)
  To: Johannes Berg, David S. Miller, linux-wireless, netdev,
	linux-kernel
In-Reply-To: <CABVa4NgWMkJuyB1P5fwQEYHwqBRiySE+fGQpMKt8zbp+xJ8+rw@mail.gmail.com>

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

In 5.x it's still possible for `ieee80211_scan_results` (`iwlist
scan`) to fail when too many wireless networks are available.  This
code path is used by `wicd`.

Previously: https://lkml.org/lkml/2017/4/2/192

I've been applying this updated patch to my own kernels since 2017 with
no issues.  I am sure it is not the ideal way to solve this problem, but
I'm making my fix available in case it helps others.

Please advise on next steps or if this is a dead end.

[-- Attachment #2: wireless-scan-less-e2big.diff --]
[-- Type: text/plain, Size: 1993 bytes --]

commit 8e80dcb0df71ac8f5d3640bcdb1bba9c7693d63a
Author: James Nylen <jnylen@gmail.com>
Date:   Wed Apr 26 14:38:58 2017 +0200

    Hack: Make `ieee80211_scan_results` (`iwlist scan`) return less E2BIG
    
    See: https://lkml.org/lkml/2017/4/2/192
    
    (and branch `jcn/hack/wireless-scan-no-e2big`)
    
    This should really be done with a bigger limit inside the `iwlist` code
    instead, if possible (or even better: modify `wicd` to use `iw scan`
    instead).

diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 21be56b3128e..08fa9cb68f59 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1699,6 +1699,7 @@ static int ieee80211_scan_results(struct cfg80211_registered_device *rdev,
 				  struct iw_request_info *info,
 				  char *buf, size_t len)
 {
+	char *maybe_current_ev;
 	char *current_ev = buf;
 	char *end_buf = buf + len;
 	struct cfg80211_internal_bss *bss;
@@ -1709,14 +1710,29 @@ static int ieee80211_scan_results(struct cfg80211_registered_device *rdev,
 
 	list_for_each_entry(bss, &rdev->bss_list, list) {
 		if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
-			err = -E2BIG;
+			// Buffer too small to hold another BSS.  Only report
+			// an error if we have not yet reached the maximum
+			// buffer size that `iwlist` can handle.
+			if (len < 0xFFFF) {
+				err = -E2BIG;
+			}
 			break;
 		}
-		current_ev = ieee80211_bss(&rdev->wiphy, info, bss,
-					   current_ev, end_buf);
-		if (IS_ERR(current_ev)) {
-			err = PTR_ERR(current_ev);
+		maybe_current_ev = ieee80211_bss(&rdev->wiphy, info, bss,
+					         current_ev, end_buf);
+		if (IS_ERR(maybe_current_ev)) {
+			err = PTR_ERR(maybe_current_ev);
+			if (err == -E2BIG) {
+				// Last BSS failed to copy into buffer.  As
+				// above, only report an error if `iwlist` will
+				// retry again with a larger buffer.
+				if (len >= 0xFFFF) {
+					err = 0;
+				}
+			}
 			break;
+		} else {
+			current_ev = maybe_current_ev;
 		}
 	}
 	spin_unlock_bh(&rdev->bss_lock);

^ permalink raw reply related

* Re: [Linux Realtek Wi-Fi support] rtl8192ee related bug
From: Larry Finger @ 2019-08-10 19:45 UTC (permalink / raw)
  To: Sergey Kharitonov; +Cc: linux-wireless
In-Reply-To: <CAHmv74wNOM1QKUPp2Vax2Z+-JyoFC81WHVZ+XbYgiRMUGxCFUQ@mail.gmail.com>

On 8/10/19 1:13 PM, Sergey Kharitonov wrote:
> Dear Mr. Finger!
> Thank you for paying attention to the problem. I've just posted an
> updated information to that bug before receiving this message.
> 
> I get these results
> ~]$ ping 192.168.88.1
> PING 192.168.88.1 (192.168.88.1) 56(84) bytes of data.
> 64 bytes from 192.168.88.1: icmp_seq=1 ttl=64 time=0.746 ms
> 64 bytes from 192.168.88.1: icmp_seq=2 ttl=64 time=0.868 ms
> 64 bytes from 192.168.88.1: icmp_seq=3 ttl=64 time=0.853 ms
> 64 bytes from 192.168.88.1: icmp_seq=4 ttl=64 time=0.868 ms
> 64 bytes from 192.168.88.1: icmp_seq=5 ttl=64 time=0.818 ms
> 64 bytes from 192.168.88.1: icmp_seq=6 ttl=64 time=0.844 ms
> 64 bytes from 192.168.88.1: icmp_seq=7 ttl=64 time=0.841 ms
> 64 bytes from 192.168.88.1: icmp_seq=8 ttl=64 time=0.913 ms
> 64 bytes from 192.168.88.1: icmp_seq=9 ttl=64 time=0.844 ms
> 64 bytes from 192.168.88.1: icmp_seq=10 ttl=64 time=0.886 ms
> ^C
> --- 192.168.88.1 ping statistics ---
> 10 packets transmitted, 10 received, 0% packet loss, time 387ms
> rtt min/avg/max/mdev = 0.746/0.848/0.913/0.044 ms
> 
> with a driver from rtl8192ee_revised.tar.bz2 file in
> https://github.com/lwfinger/rtlwifi_new/tree/extended repository built
> against Linux 4.19.65-1-lts ArchLinux current LTS kernel.
> 
> Connection speed and stability on a heavy load are also perfect.
> 
> Hope this info would help solving current rtl8192ee problem.
> 
> Please let me know if any additional info is needed.

That driver is totally different from the one in the kernel. It comes from the 
group that writes the combined drivers for Windows, FreeBSD, and Linux. The 
coding there is  completely inappropriate for inclusion in the kernel. I'm glad 
that it works for you.

I will use its PCI communications to see what it does differently from the 
kernel version, and I will extract the embedded firmware in that driver and try 
it with the kernel driver.

Larry




^ permalink raw reply

* Re: [Linux Realtek Wi-Fi support] rtl8192ee related bug
From: Sergey Kharitonov @ 2019-08-10 18:13 UTC (permalink / raw)
  To: Larry Finger; +Cc: linux-wireless
In-Reply-To: <9172166a-eb77-a508-ba54-08fdf96912fc@lwfinger.net>

Dear Mr. Finger!
Thank you for paying attention to the problem. I've just posted an
updated information to that bug before receiving this message.

I get these results
~]$ ping 192.168.88.1
PING 192.168.88.1 (192.168.88.1) 56(84) bytes of data.
64 bytes from 192.168.88.1: icmp_seq=1 ttl=64 time=0.746 ms
64 bytes from 192.168.88.1: icmp_seq=2 ttl=64 time=0.868 ms
64 bytes from 192.168.88.1: icmp_seq=3 ttl=64 time=0.853 ms
64 bytes from 192.168.88.1: icmp_seq=4 ttl=64 time=0.868 ms
64 bytes from 192.168.88.1: icmp_seq=5 ttl=64 time=0.818 ms
64 bytes from 192.168.88.1: icmp_seq=6 ttl=64 time=0.844 ms
64 bytes from 192.168.88.1: icmp_seq=7 ttl=64 time=0.841 ms
64 bytes from 192.168.88.1: icmp_seq=8 ttl=64 time=0.913 ms
64 bytes from 192.168.88.1: icmp_seq=9 ttl=64 time=0.844 ms
64 bytes from 192.168.88.1: icmp_seq=10 ttl=64 time=0.886 ms
^C
--- 192.168.88.1 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 387ms
rtt min/avg/max/mdev = 0.746/0.848/0.913/0.044 ms

with a driver from rtl8192ee_revised.tar.bz2 file in
https://github.com/lwfinger/rtlwifi_new/tree/extended repository built
against Linux 4.19.65-1-lts ArchLinux current LTS kernel.

Connection speed and stability on a heavy load are also perfect.

Hope this info would help solving current rtl8192ee problem.

Please let me know if any additional info is needed.

Best regards,
Sergey Kharitonov

On Sat, Aug 10, 2019 at 9:16 PM Larry Finger <Larry.Finger@lwfinger.net> wrote:
>
> On 8/9/19 12:25 AM, Sergey Kharitonov wrote:
> > Dear Linux-Wireless,
> > Some time ago a bug was reported
> > https://bugzilla.kernel.org/show_bug.cgi?id=202943 related to
> > rtl8192ee, the essence of which is high ping latency (even to the
> > access point) without downloading something. If you generate a network
> > load with a background download or just ping -i 0.001 -s 512.... the
> > latency stabilizes and stays low.
> > I tested my TP-Link TL-WN881ND v2 adapters (I got two of them in my
> > PCs plugged in different motherboards (ASUS and MSI)) and the problem
> > still persists in kernel 5.2.6 (archlinux current default). Just to
> > mention, I tested with different module options and also two available
> > firmwares I found (rtlwifi/rtl8192eefw.bin and
> > rtlwifi/rtl8192eefw_new.bin).
> > Would you please take some time to look at the bug? I can provide any
> > additional information needed.
> > Please let me know if we can make rtl8192ee driver better.
>
> Sergey,
>
> I have plans to make some improvements on the driver, and I will investigate
> your issue.
>
> I do handle the issues on the drivers I have posted at GitHub.com under the user
> lwfinger, and I follow this list, but I do not look at the kernel bugzilla for
> Realtek wifi issues.
>
> Larry
>

^ permalink raw reply

* Re: [Linux Realtek Wi-Fi support] rtl8192ee related bug
From: Larry Finger @ 2019-08-10 17:16 UTC (permalink / raw)
  To: Sergey Kharitonov, linux-wireless
In-Reply-To: <CAHmv74wK2NYuj2JuDUz-og5w+e=H1=ef9eCSMTbO6otaYQatKg@mail.gmail.com>

On 8/9/19 12:25 AM, Sergey Kharitonov wrote:
> Dear Linux-Wireless,
> Some time ago a bug was reported
> https://bugzilla.kernel.org/show_bug.cgi?id=202943 related to
> rtl8192ee, the essence of which is high ping latency (even to the
> access point) without downloading something. If you generate a network
> load with a background download or just ping -i 0.001 -s 512.... the
> latency stabilizes and stays low.
> I tested my TP-Link TL-WN881ND v2 adapters (I got two of them in my
> PCs plugged in different motherboards (ASUS and MSI)) and the problem
> still persists in kernel 5.2.6 (archlinux current default). Just to
> mention, I tested with different module options and also two available
> firmwares I found (rtlwifi/rtl8192eefw.bin and
> rtlwifi/rtl8192eefw_new.bin).
> Would you please take some time to look at the bug? I can provide any
> additional information needed.
> Please let me know if we can make rtl8192ee driver better.

Sergey,

I have plans to make some improvements on the driver, and I will investigate 
your issue.

I do handle the issues on the drivers I have posted at GitHub.com under the user 
lwfinger, and I follow this list, but I do not look at the kernel bugzilla for 
Realtek wifi issues.

Larry


^ permalink raw reply

* Re: [PATCHv6 3/9] nl80211: Add netlink attribute for AMPDU aggregation enable/disable
From: Tamizh chelvam @ 2019-08-10 12:41 UTC (permalink / raw)
  To: Johannes Berg; +Cc: ath10k, linux-wireless
In-Reply-To: <1077c62701b31cfcb4436e6b13be64ade6b1ae1b.camel@sipsolutions.net>

On 2019-07-31 14:58, Johannes Berg wrote:
> On Tue, 2019-06-18 at 10:57 +0530, Tamizh chelvam wrote:
>> 
>> +		if (!wiphy_ext_feature_isset(&rdev->wiphy,
>> +				NL80211_EXT_FEATURE_PER_TID_AMPDU_CTRL)) {
>> +			NL_SET_ERR_MSG_ATTR(extack,
>> +					    attrs[NL80211_TID_ATTR_CONFIG_AMPDU_CTRL],
>> +					    "TID specific configuration not "
>> +					    "supported");
>> +			return -ENOTSUPP;
>> +		}
>> +
>> +		if (peer && !wiphy_ext_feature_isset(&rdev->wiphy,
>> +				NL80211_EXT_FEATURE_PER_STA_AMPDU_CTRL)) {
>> +			NL_SET_ERR_MSG_ATTR(extack,
>> +					    attrs[NL80211_TID_ATTR_CONFIG_AMPDU_CTRL],
>> +					    "peer specfic TID configuration not "
>> +					    "supported");
>> +			return -ENOTSUPP;
>> +		}
> 
> I think you should probably make this be a function to which you pass
> the attribute pointer and feature flags.
> 
> err = nl80211_check_tid_config_supported(extack,
> 					 attrs[NL80211_TID_ATTR_CONFIG_AMPDU_CTRL],
> 					 NL80211_EXT_FEATURE_PER_TID_AMPDU_CTRL,
> 					 NL80211_EXT_FEATURE_PER_STA_AMPDU_CTRL);
> 
> since you have this code a lot?
> 
Sure, I will make that change in the next version of patchset.

Thanks,
Tamizh.

^ permalink raw reply

* Re: [PATCHv6 1/9] nl80211: New netlink command for TID specific configuration
From: Tamizh chelvam @ 2019-08-10 12:40 UTC (permalink / raw)
  To: Johannes Berg; +Cc: ath10k, linux-wireless
In-Reply-To: <ea1f9969b52fed2da8b0e88ed8b06527bfc272aa.camel@sipsolutions.net>

On 2019-07-31 14:55, Johannes Berg wrote:
> On Tue, 2019-06-18 at 10:57 +0530, Tamizh chelvam wrote:
>> 
>>  /**
>> + * enum nl80211_tid_config - TID config state
>> + * @NL80211_TID_CONFIG_DEFAULT: Default config for the TID
>> + * @NL80211_TID_CONFIG_ENABLE: Enable config for the TID
>> + * NL80211_TID_CONFIG_DISABLE: Disable config for the TID
>> + */
>> +enum nl80211_tid_config {
>> +	NL80211_TID_CONFIG_DEFAULT,
>> +	NL80211_TID_CONFIG_ENABLE,
>> +	NL80211_TID_CONFIG_DISABLE,
>> +};
> 
> Hmm. Looking at this in more detail in patch 3, I don't understand.
> 
> How is DEFAULT different from "attribute not present", i.e. "no
> changes"?
> 
This DEFAULT is used to notify the driver to use default configuration 
value of driver/vif.
This will be used when the attribute is not present.

^ permalink raw reply

* Re: [PATCHv6 2/9] nl80211: Add new netlink attribute for TID speicific retry count
From: Tamizh chelvam @ 2019-08-10 12:06 UTC (permalink / raw)
  To: Johannes Berg; +Cc: ath10k, linux-wireless
In-Reply-To: <6351a05f5c205db47740116b4bec5a6476317792.camel@sipsolutions.net>

On 2019-07-31 14:54, Johannes Berg wrote:
> ^^ there's a typo in the subject
> 
I will fix it in next version.
>> @@ -3951,6 +3957,7 @@ enum wiphy_flags {
>>  	WIPHY_FLAG_SUPPORTS_5_10_MHZ		= BIT(22),
>>  	WIPHY_FLAG_HAS_CHANNEL_SWITCH		= BIT(23),
>>  	WIPHY_FLAG_HAS_STATIC_WEP		= BIT(24),
>> +	WIPHY_FLAG_HAS_MAX_DATA_RETRY_COUNT	= BIT(25),
> 
> This is never used, so that doesn't make sense? You probably want to
> advertise the max_data_retry_count value contingent on this flag (*) in
> some attribute, so that userspace can also detect the presence/absence
> of the flag for the feature?
> 
> (*) doesn't really need to be contingent on the flag - could just be
> contingent on max_data_retry_count being non-zero and then you don't
> need the flag.
> 
Sure, I will remove this flag.

>> + * @NL80211_ATTR_MAX_RETRY_COUNT: The upper limit for the retry count
>> + *	configuration that the driver can accept.
>>   *
>>   * @NUM_NL80211_ATTR: total number of nl80211_attrs available
>>   * @NL80211_ATTR_MAX: highest attribute number currently defined
>> @@ -2823,6 +2825,7 @@ enum nl80211_attrs {
>>  	NL80211_ATTR_TWT_RESPONDER,
>> 
>>  	NL80211_ATTR_TID_CONFIG,
>> +	NL80211_ATTR_MAX_RETRY_COUNT,
> 
> You already have the attribute, but again, aren't using it.
> 
I will use this in nl80211_get_wiphy to notify userspace.

>> + * @NL80211_EXT_FEATURE_PER_TID_RETRY_CONFIG: Driver supports per TID 
>> data retry
>> + *	count functionality.
>> + * @NL80211_EXT_FEATURE_PER_STA_RETRY_CONFIG: Driver supports STA 
>> specific
>> + *	data retry count functionality.
> 
> and if you have these you don't need the WIPHY_FLAG anyway?
> 
Sure.
>> +	[NL80211_TID_ATTR_CONFIG_RETRY] = { .type = NLA_FLAG },
>> +	[NL80211_TID_ATTR_CONFIG_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 0),
>> +	[NL80211_TID_ATTR_CONFIG_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 0),
> 
> min of 0 doesn't make sense, maybe you meant 1? otherwise just don't 
> set
> anything here.
> 
The min value changed to 0 from 1 as per the previous discussions, since 
this is a retry count and not a tx count.
Or Shall I remove this min value to avoid the confusion ?
> 
>> +					    "TID specific configuration not "
>> +					    "supported");
> 
> This applies to all the patches - please don't break strings across
> multiple lines, even if they cross 80 columns. Even checkpatch won't
> give you any warning on this.
> 
Yeah, sure.
>> +		tid_conf->tid_conf_mask |= IEEE80211_TID_CONF_RETRY;
>> +		if (attrs[NL80211_TID_ATTR_CONFIG_RETRY_SHORT]) {
>> +			tid_conf->retry_short =
>> +			nla_get_u8(attrs[NL80211_TID_ATTR_CONFIG_RETRY_SHORT]);
>> +			if (tid_conf->retry_short >
>> +					rdev->wiphy.max_data_retry_count)
>> +				return -EINVAL;
>> +		} else {
>> +			tid_conf->retry_short = -1;
>> +
> 
> I guess you should document that -1 means no changes? Not sure how the
> IEEE80211_TID_CONF_RETRY comes in, you're always setting it, so that's
> useless - better remove that and document that -1 means no changes?
> 
The value -1 is to notify the driver to use default value by removing 
peer specific retry count.

Thanks,
Tamizh.


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox