Linux wireless drivers development
 help / color / mirror / Atom feed
* bad values in output of 'iw event'
From: Bastian Bittorf @ 2017-02-14 15:05 UTC (permalink / raw)
  To: linux-wireless

the former patch about rate-report/unfilled values
reminded me, that i can see with recent 'wireless-testing'
strange values when watching the output of 'iw event'.
maybe something similar...:

Mon Feb 13 11:18:52 CET 2017 DEBUG: wlan1-1 (phy #1): unknown event 60
Mon Feb 13 11:18:52 CET 2017 DEBUG: wlan0: del station 64:09:80:7f:48:86
Mon Feb 13 11:18:52 CET 2017 DEBUG: wlan1: del station b0:48:7a:a5:96:2e
Mon Feb 13 11:18:52 CET 2017 DEBUG: wlan1: del station f4:ec:38:fd:74:b4
Mon Feb 13 11:18:52 CET 2017 DEBUG: wlan1: del station f4:ec:38:9d:86:36
Mon Feb 13 11:18:52 CET 2017 DEBUG: ���T (phy #0): unknown event 8
Mon Feb 13 11:18:52 CET 2017 DEBUG: ���T (phy #1): unknown event 8
Mon Feb 13 11:18:52 CET 2017 DEBUG: ���T (phy #1): unknown event 8
Mon Feb 13 11:18:53 CET 2017 DEBUG: wlan0 (phy #0): unknown event 7
Mon Feb 13 11:18:53 CET 2017 DEBUG: wlan0 (phy #0): unknown event 43
Mon Feb 13 11:18:53 CET 2017 DEBUG: wlan0: new station 64:09:80:7f:48:86
Mon Feb 13 11:18:53 CET 2017 DEBUG: wlan1 (phy #1): unknown event 7
Mon Feb 13 11:18:53 CET 2017 DEBUG: wlan1-1 (phy #1): unknown event 7
Mon Feb 13 11:18:53 CET 2017 DEBUG: wlan1 (phy #1): unknown event 43
Mon Feb 13 11:18:53 CET 2017 DEBUG: wlan1: new station f4:ec:38:fd:74:b4
Mon Feb 13 11:18:53 CET 2017 DEBUG: wlan1: new station f4:ec:38:9d:86:36
Mon Feb 13 11:18:53 CET 2017 DEBUG: wlan1: new station b0:48:7a:a5:96:2e
Mon Feb 13 11:18:54 CET 2017 DEBUG: wlan1-1 (phy #1): unknown event 60

thanks & bye, bastian

^ permalink raw reply

* [RFC 2/2] cfg80211: add support for HE MCSs
From: Johannes Berg @ 2017-02-14 15:57 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20170214155740.6465-1-johannes@sipsolutions.net>

From: Johannes Berg <johannes.berg@intel.com>

Add support for the HE MCSs in cfg80211 and also add userspace
API to nl80211 to send rate information out.

The bandwidth calculation is somewhat approximate to avoid all
the big tables that are otherwise necessary.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/cfg80211.h       | 15 +++++++--
 include/uapi/linux/nl80211.h | 42 +++++++++++++++++++++++
 net/wireless/nl80211.c       | 16 +++++++++
 net/wireless/util.c          | 80 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 151 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index c92dc03c8528..09d64d486679 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -986,12 +986,14 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
  * @RATE_INFO_FLAGS_VHT_MCS: mcs field filled with VHT MCS
  * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval
  * @RATE_INFO_FLAGS_60G: 60GHz MCS
+ * @RATE_INFO_FLAGS_HE: HE MCS information
  */
 enum rate_info_flags {
 	RATE_INFO_FLAGS_MCS			= BIT(0),
 	RATE_INFO_FLAGS_VHT_MCS			= BIT(1),
 	RATE_INFO_FLAGS_SHORT_GI		= BIT(2),
 	RATE_INFO_FLAGS_60G			= BIT(3),
+	RATE_INFO_FLAGS_HE_MCS			= BIT(4),
 };
 
 /**
@@ -1005,6 +1007,7 @@ enum rate_info_flags {
  * @RATE_INFO_BW_40: 40 MHz bandwidth
  * @RATE_INFO_BW_80: 80 MHz bandwidth
  * @RATE_INFO_BW_160: 160 MHz bandwidth
+ * @RATE_INFO_BW_HE_RU: bandwidth determined by HE RU allocation
  */
 enum rate_info_bw {
 	RATE_INFO_BW_5,
@@ -1013,6 +1016,7 @@ enum rate_info_bw {
 	RATE_INFO_BW_40,
 	RATE_INFO_BW_80,
 	RATE_INFO_BW_160,
+	RATE_INFO_BW_HE_RU,
 };
 
 /**
@@ -1021,10 +1025,14 @@ enum rate_info_bw {
  * Information about a receiving or transmitting bitrate
  *
  * @flags: bitflag of flags from &enum rate_info_flags
- * @mcs: mcs index if struct describes a 802.11n bitrate
+ * @mcs: mcs index if struct describes an HT/VHT/HE rate
  * @legacy: bitrate in 100kbit/s for 802.11abg
- * @nss: number of streams (VHT only)
+ * @nss: number of streams (VHT & HE only)
  * @bw: bandwidth (from &enum rate_info_bw)
+ * @he_gi: HE guard interval (from &enum nl80211_he_gi)
+ * @he_dcm: HE DCM value
+ * @he_ru_alloc: HE RU allocation (from &enum nl80211_he_ru_alloc,
+ *	only valid if bw is %RATE_INFO_BW_HE_RU)
  */
 struct rate_info {
 	u8 flags;
@@ -1032,6 +1040,9 @@ struct rate_info {
 	u16 legacy;
 	u8 nss;
 	u8 bw;
+	u8 he_gi;
+	u8 he_dcm;
+	u8 he_ru_alloc;
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 5ed257c4cd4e..e54b35bbfbc6 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2598,6 +2598,36 @@ struct nl80211_sta_flag_update {
 } __attribute__((packed));
 
 /**
+ * enum nl80211_he_gi - HE guard interval
+ * @NL80211_RATE_INFO_HE_GI_0_8: 0.8 usec
+ * @NL80211_RATE_INFO_HE_GI_1_6: 1.6 usec
+ * @NL80211_RATE_INFO_HE_GI_3_2: 3.2 usec
+ */
+enum nl80211_he_gi {
+	NL80211_RATE_INFO_HE_GI_0_8,
+	NL80211_RATE_INFO_HE_GI_1_6,
+	NL80211_RATE_INFO_HE_GI_3_2,
+};
+
+/**
+ * @enum nl80211_he_ru_alloc - HE RU allocation values
+ * @NL80211_RATE_INFO_HE_RU_ALLOC_26: 26-tone RU allocation
+ * @NL80211_RATE_INFO_HE_RU_ALLOC_52: 52-tone RU allocation
+ * @NL80211_RATE_INFO_HE_RU_ALLOC_106: 106-tone RU allocation
+ * @NL80211_RATE_INFO_HE_RU_ALLOC_242: 242-tone RU allocation
+ * @NL80211_RATE_INFO_HE_RU_ALLOC_484: 484-tone RU allocation
+ * @NL80211_RATE_INFO_HE_RU_ALLOC_969: 969-tone RU allocation
+ */
+enum nl80211_he_ru_alloc {
+	NL80211_RATE_INFO_HE_RU_ALLOC_26,
+	NL80211_RATE_INFO_HE_RU_ALLOC_52,
+	NL80211_RATE_INFO_HE_RU_ALLOC_106,
+	NL80211_RATE_INFO_HE_RU_ALLOC_242,
+	NL80211_RATE_INFO_HE_RU_ALLOC_484,
+	NL80211_RATE_INFO_HE_RU_ALLOC_969,
+};
+
+/**
  * enum nl80211_rate_info - bitrate information
  *
  * These attribute types are used with %NL80211_STA_INFO_TXRATE
@@ -2629,6 +2659,13 @@ struct nl80211_sta_flag_update {
  * @NL80211_RATE_INFO_5_MHZ_WIDTH: 5 MHz width - note that this is
  *	a legacy rate and will be reported as the actual bitrate, i.e.
  *	a quarter of the base (20 MHz) rate
+ * @NL80211_RATE_INFO_HE_MCS: HE MCS index (u8, 0-11)
+ * @NL80211_RATE_INFO_HE_NSS: HE NSS value (u8, 1-8)
+ * @NL80211_RATE_INFO_HE_GI: HE guard interval identifier
+ *	(u8, see &enum nl80211_he_gi)
+ * @NL80211_RATE_INFO_HE_DCM: HE DCM value (u8, 0/1)
+ * @NL80211_RATE_INFO_RU_ALLOC: HE RU allocation, if not present then
+ *	non-OFDMA was used (u8, see &enum nl80211_he_ru_alloc)
  * @__NL80211_RATE_INFO_AFTER_LAST: internal use
  */
 enum nl80211_rate_info {
@@ -2645,6 +2682,11 @@ enum nl80211_rate_info {
 	NL80211_RATE_INFO_160_MHZ_WIDTH,
 	NL80211_RATE_INFO_10_MHZ_WIDTH,
 	NL80211_RATE_INFO_5_MHZ_WIDTH,
+	NL80211_RATE_INFO_HE_MCS,
+	NL80211_RATE_INFO_HE_NSS,
+	NL80211_RATE_INFO_HE_GI,
+	NL80211_RATE_INFO_HE_DCM,
+	NL80211_RATE_INFO_HE_RU_ALLOC,
 
 	/* keep last */
 	__NL80211_RATE_INFO_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d7f8be4e321a..6b9b79b0699c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4204,6 +4204,9 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
 	case RATE_INFO_BW_160:
 		rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
 		break;
+	case RATE_INFO_BW_HE_RU:
+		rate_flg = 0;
+		WARN_ON(!(info->flags & RATE_INFO_FLAGS_HE_MCS));
 	}
 
 	if (rate_flg && nla_put_flag(msg, rate_flg))
@@ -4223,6 +4226,19 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
 		if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
 		    nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
 			return false;
+	} else if (info->flags & RATE_INFO_FLAGS_HE_MCS) {
+		if (nla_put_u8(msg, NL80211_RATE_INFO_HE_MCS, info->mcs))
+			return false;
+		if (nla_put_u8(msg, NL80211_RATE_INFO_HE_NSS, info->nss))
+			return false;
+		if (nla_put_u8(msg, NL80211_RATE_INFO_HE_GI, info->he_gi))
+			return false;
+		if (nla_put_u8(msg, NL80211_RATE_INFO_HE_DCM, info->he_dcm))
+			return false;
+		if (info->bw == RATE_INFO_BW_HE_RU &&
+		    nla_put_u8(msg, NL80211_RATE_INFO_HE_RU_ALLOC,
+			       info->he_ru_alloc))
+			return false;
 	}
 
 	nla_nest_end(msg, rate);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 23ee3d66dfe0..3061fce1b6e0 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1257,6 +1257,84 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)
 	return (bitrate + 50000) / 100000;
 }
 
+static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)
+{
+#define SCALE 2048
+	u16 mcs_divisors[12] = {
+		34133, /* 16.666666... */
+		17067, /*  8.333333... */
+		11378, /*  5.555555... */
+		 8533, /*  4.166666... */
+		 5689, /*  2.777777... */
+		 4267, /*  2.083333... */
+		 3923, /*  1.851851... */
+		 3413, /*  1.666666... */
+		 2844, /*  1.388888... */
+		 2560, /*  1.250000... */
+		 2276, /*  1.111111... */
+		 2048, /*  1.000000... */
+	};
+	u32 rates_160M[3] = { 960777777, 907400000, 816666666 };
+	u32 rates_969[3] =  { 480388888, 453700000, 408333333 };
+	u32 rates_484[3] =  { 229411111, 216666666, 195000000 };
+	u32 rates_242[3] =  { 114711111, 108333333,  97500000 };
+	u32 rates_106[3] =  {  40000000,  37777777,  34000000 };
+	u32 rates_52[3]  =  {  18820000,  17777777,  16000000 };
+	u32 rates_26[3]  =  {   9411111,   8888888,   8000000 };
+	u64 tmp;
+	u32 result;
+
+	if (WARN_ON_ONCE(rate->mcs > 11))
+		return 0;
+
+	if (WARN_ON_ONCE(rate->he_gi > NL80211_RATE_INFO_HE_GI_3_2))
+		return 0;
+	if (WARN_ON_ONCE(rate->he_ru_alloc > NL80211_RATE_INFO_HE_RU_ALLOC_969))
+		return 0;
+	if (WARN_ON_ONCE(rate->nss < 1 || rate->nss > 8))
+		return 0;
+
+	if (rate->bw == RATE_INFO_BW_160)
+		result = rates_160M[rate->he_gi];
+	else if (rate->bw == RATE_INFO_BW_80 ||
+		 (rate->bw == RATE_INFO_BW_HE_RU &&
+		  rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_969))
+		result = rates_969[rate->he_gi];
+	else if (rate->bw == RATE_INFO_BW_40 ||
+		 (rate->bw == RATE_INFO_BW_HE_RU &&
+		  rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_484))
+		result = rates_484[rate->he_gi];
+	else if (rate->bw == RATE_INFO_BW_20 ||
+		 (rate->bw == RATE_INFO_BW_HE_RU &&
+		  rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_242))
+		result = rates_242[rate->he_gi];
+	else if (rate->bw == RATE_INFO_BW_HE_RU &&
+		 rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_106)
+		result = rates_106[rate->he_gi];
+	else if (rate->bw == RATE_INFO_BW_HE_RU &&
+		 rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_52)
+		result = rates_52[rate->he_gi];
+	else if (rate->bw == RATE_INFO_BW_HE_RU &&
+		 rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_26)
+		result = rates_26[rate->he_gi];
+	else if (WARN(1, "invalid HE MCS: bw:%d, ru:%d\n",
+		      rate->bw, rate->he_ru_alloc))
+		result = 0;
+
+	/* now scale to the appropriate MCS */
+	tmp = result;
+	tmp *= SCALE;
+	do_div(tmp, mcs_divisors[rate->mcs]);
+	result = tmp;
+
+	/* and take MCS, DCM into account */
+	result = (result / 8) * rate->nss;
+	if (rate->he_dcm)
+		result /= 2;
+
+	return result;
+}
+
 u32 cfg80211_calculate_bitrate(struct rate_info *rate)
 {
 	if (rate->flags & RATE_INFO_FLAGS_MCS)
@@ -1265,6 +1343,8 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
 		return cfg80211_calculate_bitrate_60g(rate);
 	if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
 		return cfg80211_calculate_bitrate_vht(rate);
+	if (rate->flags & RATE_INFO_FLAGS_HE_MCS)
+		return cfg80211_calculate_bitrate_he(rate);
 
 	return rate->legacy;
 }
-- 
2.9.3

^ permalink raw reply related

* [RFC 1/2] cfg80211: refactor cfg80211_calculate_bitrate()
From: Johannes Berg @ 2017-02-14 15:57 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

This function contains the HT calculations, which makes no
sense - split that out into a separate function. As a side
effect, this makes the 60G flag independent from HT_MCS so
remove the MCS one from wil6210 (also deleting a duplicate
assignment.)

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 drivers/net/wireless/ath/wil6210/cfg80211.c |  3 +-
 net/wireless/util.c                         | 60 +++++++++++++++--------------
 2 files changed, 33 insertions(+), 30 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 83155b5ddbfb..79d107018eac 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -178,9 +178,8 @@ int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
 			BIT(NL80211_STA_INFO_RX_DROP_MISC) |
 			BIT(NL80211_STA_INFO_TX_FAILED);
 
-	sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
+	sinfo->txrate.flags = RATE_INFO_FLAGS_60G;
 	sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
-	sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
 	sinfo->rxrate.mcs = stats->last_mcs_rx;
 	sinfo->rx_bytes = stats->rx_bytes;
 	sinfo->rx_packets = stats->rx_packets;
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 68e5f2ecee1a..23ee3d66dfe0 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1097,6 +1097,35 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
 	return err;
 }
 
+static u32 cfg80211_calculate_bitrate_ht(struct rate_info *rate)
+{
+	int modulation, streams, bitrate;
+
+	/* the formula below does only work for MCS values smaller than 32 */
+	if (WARN_ON_ONCE(rate->mcs >= 32))
+		return 0;
+
+	modulation = rate->mcs & 7;
+	streams = (rate->mcs >> 3) + 1;
+
+	bitrate = (rate->bw == RATE_INFO_BW_40) ? 13500000 : 6500000;
+
+	if (modulation < 4)
+		bitrate *= (modulation + 1);
+	else if (modulation == 4)
+		bitrate *= (modulation + 2);
+	else
+		bitrate *= (modulation + 3);
+
+	bitrate *= streams;
+
+	if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
+		bitrate = (bitrate / 9) * 10;
+
+	/* do NOT round down here */
+	return (bitrate + 50000) / 100000;
+}
+
 static u32 cfg80211_calculate_bitrate_60g(struct rate_info *rate)
 {
 	static const u32 __mcs2bitrate[] = {
@@ -1230,39 +1259,14 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)
 
 u32 cfg80211_calculate_bitrate(struct rate_info *rate)
 {
-	int modulation, streams, bitrate;
-
-	if (!(rate->flags & RATE_INFO_FLAGS_MCS) &&
-	    !(rate->flags & RATE_INFO_FLAGS_VHT_MCS))
-		return rate->legacy;
+	if (rate->flags & RATE_INFO_FLAGS_MCS)
+		return cfg80211_calculate_bitrate_ht(rate);
 	if (rate->flags & RATE_INFO_FLAGS_60G)
 		return cfg80211_calculate_bitrate_60g(rate);
 	if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
 		return cfg80211_calculate_bitrate_vht(rate);
 
-	/* the formula below does only work for MCS values smaller than 32 */
-	if (WARN_ON_ONCE(rate->mcs >= 32))
-		return 0;
-
-	modulation = rate->mcs & 7;
-	streams = (rate->mcs >> 3) + 1;
-
-	bitrate = (rate->bw == RATE_INFO_BW_40) ? 13500000 : 6500000;
-
-	if (modulation < 4)
-		bitrate *= (modulation + 1);
-	else if (modulation == 4)
-		bitrate *= (modulation + 2);
-	else
-		bitrate *= (modulation + 3);
-
-	bitrate *= streams;
-
-	if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
-		bitrate = (bitrate / 9) * 10;
-
-	/* do NOT round down here */
-	return (bitrate + 50000) / 100000;
+	return rate->legacy;
 }
 EXPORT_SYMBOL(cfg80211_calculate_bitrate);
 
-- 
2.9.3

^ permalink raw reply related

* Re: [PATCH 06/10] rt2x00: fixup fill_tx_status for nomatch case
From: Kalle Valo @ 2017-02-14 16:32 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: linux-wireless, Helmut Schaa, Felix Fietkau
In-Reply-To: <1487076368-7020-7-git-send-email-sgruszka@redhat.com>

Stanislaw Gruszka <sgruszka@redhat.com> writes:

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

No empty commit logs, please.

-- 
Kalle Valo

^ permalink raw reply

* Re: [1/3] ath10k: remove ath10k_vif_to_arvif()
From: Kalle Valo @ 2017-02-14 17:40 UTC (permalink / raw)
  To: Amadeusz Sławiński
  Cc: ath10k, netdev, linux-wireless, linux-kernel,
	Amadeusz Sławiński
In-Reply-To: <1486030773-30600-1-git-send-email-amadeusz.slawinski@tieto.com>

Amadeusz Sławiński wrote:
> it adds unnecessary level of indirection, while we just access structure
> field
> 
> Signed-off-by: Amadeusz Sławiński <amadeusz.slawinski@tieto.com>

3 patches applied to ath-next branch of ath.git, thanks.

56ac13bfc703 ath10k: remove ath10k_vif_to_arvif()
182f1e5a626e ath10k: use size_t for len variables
6d2191135637 ath10k: fix comment

-- 
https://patchwork.kernel.org/patch/9551559/

Documentation about submitting wireless patches and checking status
from patchwork:

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

^ permalink raw reply

* Re: [v4] ath10k: fix napi crash during rmmod when probe firmware fails
From: Kalle Valo @ 2017-02-14 17:40 UTC (permalink / raw)
  To: Kalle Valo; +Cc: ath10k, linux-wireless
In-Reply-To: <148672748569.28126.12259592472689214081.stgit@potku.adurom.net>

Kalle Valo <kvalo@qca.qualcomm.com> wrote:
> This fixes the below crash when ath10k probe firmware fails, NAPI polling tries
> to access a rx ring resource which was never allocated. An easy way to
> reproduce this is easy to remove all the firmware files, load ath10k modules
> and ath10k will crash when calling 'rmmod ath10k_pci'. The fix is to call
> napi_enable() from ath10k_pci_hif_start() so that it matches with
> napi_disable() being called from ath10k_pci_hif_stop().
> 
> Big thanks to Mohammed Shafi Shajakhan who debugged this and provided first
> version of the fix. In this patch I just fix the actual problem in pci.c
> instead of having a workaround in core.c.
> 
> BUG: unable to handle kernel NULL pointer dereference at (null)
> IP:  __ath10k_htt_rx_ring_fill_n+0x19/0x230 [ath10k_core]
> __ath10k_htt_rx_ring_fill_n+0x19/0x230 [ath10k_core]
> 
> Call Trace:
> 
> [<ffffffffa113ec62>] ath10k_htt_rx_msdu_buff_replenish+0x42/0x90
> [ath10k_core]
> [<ffffffffa113f393>] ath10k_htt_txrx_compl_task+0x433/0x17d0
> [ath10k_core]
> [<ffffffff8114406d>] ? __wake_up_common+0x4d/0x80
> [<ffffffff811349ec>] ? cpu_load_update+0xdc/0x150
> [<ffffffffa119301d>] ? ath10k_pci_read32+0xd/0x10 [ath10k_pci]
> [<ffffffffa1195b17>] ath10k_pci_napi_poll+0x47/0x110 [ath10k_pci]
> [<ffffffff817863af>] net_rx_action+0x20f/0x370
> 
> Reported-by: Ben Greear <greearb@candelatech.com>
> Fixes: 3c97f5de1f28 ("ath10k: implement NAPI support")
> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>

Patch applied to ath-next branch of ath.git, thanks.

1427228d5869 ath10k: fix napi crash during rmmod when probe firmware fails

-- 
https://patchwork.kernel.org/patch/9566625/

Documentation about submitting wireless patches and checking status
from patchwork:

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

^ permalink raw reply

* Re: [v2,1/4] ath10k: fetch firmware images in a loop
From: Kalle Valo @ 2017-02-14 17:55 UTC (permalink / raw)
  To: Kalle Valo; +Cc: ath10k, linux-wireless
In-Reply-To: <148672959257.8556.14481306395015426550.stgit@potku.adurom.net>

Kalle Valo <kvalo@qca.qualcomm.com> wrote:
> From: Erik Stromdahl <erik.stromdahl@gmail.com>
> 
> To make it easier to handle minimum and maximum firmware API numbers convert
> the firmware fetch functionality to a loop. If no firmware image is found print
> an error with minimum and maximum API numbers and the name of firmware
> directory. This is needed when we switch to using request_firmware_direct()
> which doesn't print any errors anymore.
> 
> Also add a new function for creating the fw file name dynamically which makes it
> easier to add new bus support, for example SDIO and USB, later.
> 
> Signed-off-by: Erik Stromdahl <erik.stromdahl@gmail.com>
> [kvalo@qca.qualcomm.com: remove sdio/usb part, new error message, clarify commit log]
> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>

4 patches applied to ath-next branch of ath.git, thanks.

1c61bedc0a72 ath10k: fetch firmware images in a loop
310c01afae01 ath10k: add directory to board data error message
9f5bcfe93315 ath10k: silence firmware file probing warnings
7be52c03bbf7 ath10k: convert warning about non-existent OTP board id to debug message

-- 
https://patchwork.kernel.org/patch/9566667/

Documentation about submitting wireless patches and checking status
from patchwork:

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

^ permalink raw reply

* Re: ath10k: fix the garage chars in board file name creation
From: Kalle Valo @ 2017-02-14 17:57 UTC (permalink / raw)
  To: Ryan Hsu; +Cc: ath10k, linux-wireless, ryanhsu
In-Reply-To: <1486758429-18665-1-git-send-email-ryanhsu@qca.qualcomm.com>

Ryan Hsu <ryanhsu@qca.qualcomm.com> wrote:
> From: Ryan Hsu <ryanhsu@qca.qualcomm.com>
> 
> The variant[] string will be valid only if the bdf_ext is set.
> 
> The string memory needs to be null-terminated to avoid the undefined garbage
> appended by the subsequent board file name creation.
> 
> ath10k_pci 0000:04:00.0: failed to fetch board data for
> "bus=pci,vendor=168c,device=003e,subsystem-vendor=168c,subsystem-device=3363��P�����"
> from ath10k/QCA6174/hw3.0/board-2.bin
> 
> Fixes: f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file extension")
> Reported-by: Kalle Valo <kvalo@qca.qualcomm.com>
> Signed-off-by: Ryan Hsu <ryanhsu@qca.qualcomm.com>

Patch applied to ath-next branch of ath.git, thanks.

a532293fcba4 ath10k: fix the garage chars in board file name creation

-- 
https://patchwork.kernel.org/patch/9567469/

Documentation about submitting wireless patches and checking status
from patchwork:

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

^ permalink raw reply

* Re: ath6kl: Use net_device_stats from struct net_device
From: Kalle Valo @ 2017-02-14 17:57 UTC (permalink / raw)
  To: Tobias Klauser; +Cc: linux-wireless, netdev
In-Reply-To: <20170209112117.23994-1-tklauser@distanz.ch>

Tobias Klauser <tklauser@distanz.ch> wrote:
> Instead of using a private copy of struct net_device_stats in struct
> ath6kl_vif, use stats from struct net_device. Also remove the now
> unnecessary .ndo_get_stats function.
> 
> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>

Patch applied to ath-next branch of ath.git, thanks.

1235a3b66cbf ath6kl: Use net_device_stats from struct net_device

-- 
https://patchwork.kernel.org/patch/9564413/

Documentation about submitting wireless patches and checking status
from patchwork:

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

^ permalink raw reply

* Re: ath9k: clean up and fix ath_tx_count_airtime
From: Kalle Valo @ 2017-02-14 17:58 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless, kvalo, toke
In-Reply-To: <20170212132931.43510-1-nbd@nbd.name>

Felix Fietkau <nbd@nbd.name> wrote:
> ath_tx_count_airtime is doing a lot of unnecessary work:
> 
> - Redundant station lookup
> - Redundant rcu_read_lock/unlock
> - Useless memcpy of bf->rates
> - Useless NULL check of bf->bf_mpdu
> - Redundant lookup of the skb tid
> 
> Additionally, it tries to look up the mac80211 queue index from the txq,
> which fails if the frame was delivered via the power save queue.
> 
> This patch fixes all of these issues by passing down the right set of
> pointers instead of doing extra work
> 
> Cc: stable@vger.kernel.org
> Fixes: 63fefa050477 ("ath9k: Introduce airtime fairness scheduling between stations")
> Signed-off-by: Felix Fietkau <nbd@nbd.name>
> Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>

Patch applied to ath-next branch of ath.git, thanks.

a6e56d749f1b ath9k: clean up and fix ath_tx_count_airtime

-- 
https://patchwork.kernel.org/patch/9568369/

Documentation about submitting wireless patches and checking status
from patchwork:

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

^ permalink raw reply

* Re: ath9k: Access rchan::buf only with per_cpu helper
From: Kalle Valo @ 2017-02-14 17:59 UTC (permalink / raw)
  To: Sven Eckelmann
  Cc: linux-wireless, ath9k-devel, kvalo, netdev, sw, Sven Eckelmann,
	Akash Goel, Nick Kossifidis
In-Reply-To: <20170213155648.4821-1-sven@narfation.org>

Sven Eckelmann <sven@narfation.org> wrote:
> The relayfs was changed to use per CPU constructs to handle the rchan
> buffers. But the users of the rchan buffers in other parts of the kernel
> were not modified. This caused crashes like
> 
>   BUG: unable to handle kernel paging request at 00003a5198a0b910
>   IP: [<ffffffffa973cb3a>] ath_cmn_process_fft+0xea/0x610
>   PGD 0 [  179.522449]
>   Oops: 0000 [#1] SMP
>   Modules linked in:
>   CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.9.0-rc5 #1
>   [...]
>   Call Trace:
>    <IRQ> [  179.656426]  [<ffffffffa9704373>] ? ath_rx_tasklet+0x2f3/0xd10
>    [<ffffffffa9702106>] ? ath9k_tasklet+0x1b6/0x230
>    [<ffffffffa90dcbd1>] ? tasklet_action+0xf1/0x100
>    [<ffffffffa9a3cb3f>] ? __do_softirq+0xef/0x284
>    [<ffffffffa90dd22e>] ? irq_exit+0xae/0xb0
>    [<ffffffffa9a3c89f>] ? do_IRQ+0x4f/0xd0
>    [<ffffffffa9a3aa42>] ? common_interrupt+0x82/0x82
>    <EOI> [  179.703152]  [<ffffffffa9a39c1d>] ? poll_idle+0x2d/0x57
>    [<ffffffffa908c845>] ? sched_clock+0x5/0x10
>    [<ffffffffa97bc8d6>] ? cpuidle_enter_state+0xf6/0x2d0
>    [<ffffffffa911988e>] ? cpu_startup_entry+0x14e/0x230
>    [<ffffffffaa3cdf70>] ? start_kernel+0x461/0x481
>    [<ffffffffaa3cd120>] ? early_idt_handler_array+0x120/0x120
>    [<ffffffffaa3cd413>] ? x86_64_start_kernel+0x14c/0x170
>   Code: 31 db 41 be ff ff ff ff 4c 8b 26 48 8b 6e 08 49 8b 84 24 60 05 00
>         00 48 8b 00 0f b7 40 04 66 89 44 24 48 eb 11 48 8b 55 40 48 98 <48>
>         8b 3c c2 e8 ad a0 a4 ff 01 c3 41 8d 56 01 be 00 02 00 00 48
>   RIP  [<ffffffffa973cb3a>] ath_cmn_process_fft+0xea/0x610
>    RSP <ffff9b43e7003d20>
>   CR2: 00003a5198a0b910
> 
> Fixes: 017c59c042d0 ("relay: Use per CPU constructs for the relay channel buffer pointers")
> Cc: Akash Goel <akash.goel@intel.com>
> Cc: Nick Kossifidis <mickflemm@gmail.com>
> Reported-by: Mathias Kretschmer <mathias.kretschmer@fit.fraunhofer.de>
> Signed-off-by: Sven Eckelmann <sven@narfation.org>

Patch applied to ath-next branch of ath.git, thanks.

07460b92db7c ath9k: Access rchan::buf only with per_cpu helper

-- 
https://patchwork.kernel.org/patch/9570191/

Documentation about submitting wireless patches and checking status
from patchwork:

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

^ permalink raw reply

* R92SU - Realtek RTL8192SU/RTL8191SU/RTL8188SU USB Wireless Network Adapters
From: poma @ 2017-02-14 18:28 UTC (permalink / raw)
  To: Christian Lamparter
  Cc: David A. De Graaf, Larry Finger, Jes Sorensen, linux-wireless

Hello fellows!

https://github.com/chunkeey/rtl8192su/tree/master/r92su
r92su seems like the simplest and most effective replacement for r8712u.

https://bugzilla.redhat.com/show_bug.cgi?id=1421383
Christian, I can not add you there, so I'm asking here,
is there any particular reason why r92su is not already accepted in mainline?

Is there an intention to "Realtek RTL8192SU/RTL8191SU/RTL8188SU USB Wireless Network Adapters" join "RTL8XXXu USB mac80211 Wireless LAN Driver" support?

Thanks
 

^ permalink raw reply

* [PATCH] ath9k: use correct OTP register offsets for the AR9340 and AR9550
From: Christian Lamparter @ 2017-02-14 19:10 UTC (permalink / raw)
  To: linux-wireless
  Cc: Kalle Valo, QCA ath9k Development, Chris Blake, Gabor Juhos,
	stable

This patch fixes the OTP register definitions for the AR934x and AR9550
WMAC SoC.

Previously, the ath9k driver was unable to initialize the integrated
WMAC on an Aerohive AP121:

| ath: phy0: timeout (1000 us) on reg 0x30018: 0xbadc0ffe & 0x00000007 != 0x00000004
| ath: phy0: timeout (1000 us) on reg 0x30018: 0xbadc0ffe & 0x00000007 != 0x00000004
| ath: phy0: Unable to initialize hardware; initialization status: -5
| ath9k ar934x_wmac: failed to initialize device
| ath9k: probe of ar934x_wmac failed with error -5

It turns out that the AR9300_OTP_STATUS and AR9300_OTP_DATA
definitions contain a typo.

Cc: Gabor Juhos <juhosg@openwrt.org>
Cc: stable@vger.kernel.org
Fixes: add295a4afbdf5852d0 "ath9k: use correct OTP register offsets for AR9550"
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: Chris Blake <chrisrblake93@gmail.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 7dc7205dc877..bd2269c7de6b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -75,13 +75,13 @@
 #define AR9300_OTP_BASE \
 		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000)
 #define AR9300_OTP_STATUS \
-		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30018 : 0x15f18)
+		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x31018 : 0x15f18)
 #define AR9300_OTP_STATUS_TYPE		0x7
 #define AR9300_OTP_STATUS_VALID		0x4
 #define AR9300_OTP_STATUS_ACCESS_BUSY	0x2
 #define AR9300_OTP_STATUS_SM_BUSY	0x1
 #define AR9300_OTP_READ_DATA \
-		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3001c : 0x15f1c)
+		((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3101c : 0x15f1c)
 
 enum targetPowerHTRates {
 	HT_TARGET_RATE_0_8_16,
-- 
2.11.0

^ permalink raw reply related

* Re: R92SU - Realtek RTL8192SU/RTL8191SU/RTL8188SU USB Wireless Network Adapters
From: Jes Sorensen @ 2017-02-14 19:22 UTC (permalink / raw)
  To: poma, Christian Lamparter; +Cc: David A. De Graaf, Larry Finger, linux-wireless
In-Reply-To: <3255266e-5116-8e5e-bf22-db1dab02c769@gmail.com>

On 02/14/2017 01:28 PM, poma wrote:
> Hello fellows!
>
> https://github.com/chunkeey/rtl8192su/tree/master/r92su
> r92su seems like the simplest and most effective replacement for r8712u.
>
> https://bugzilla.redhat.com/show_bug.cgi?id=1421383
> Christian, I can not add you there, so I'm asking here,
> is there any particular reason why r92su is not already accepted in mainline?
>
> Is there an intention to "Realtek RTL8192SU/RTL8191SU/RTL8188SU USB Wireless Network Adapters" join "RTL8XXXu USB mac80211 Wireless LAN Driver" support?

I see no reason why SU support cannot be added to rtl8xxxu, however 
given the age of these chips and the amount of time I have to work on 
the code, it is pretty far from the top of my priority list.

If someone else is going to work on it, I am happy to work with that 
person to integrate the code.

Jes

^ permalink raw reply

* [RFC-PATCH] ath9k_htc: Adjust beacon timers for Power Save
From: Doru @ 2017-02-14 19:36 UTC (permalink / raw)
  To: linux-wireless, ath9k_htc_fw, andra.paraschiv7, costin.raiciu,
	dragos.niculescu
  Cc: Doru Gucea

From: Doru Gucea <gucea.doru@gmail.com>

Each time we receive a beacon we need to adjust the hardware
timers for next DTIM and next TBTT.

Before this commit, the Power Save behaviour was incorrect.
The scenario was:
- STA receives a beacon from AP with TIM unset;
- mac80211 layers puts the chip to sleep;
- chip is woken up by mac80211's software timer reponsible for
beacon miss after 7 * beacon_interval period.

Normally the chip should sleep at most DTIM period. This commit
configures hardware timers for waking up the chip correctly.

More details on the wiki:
https://github.com/doru91/linux-stable/wiki/Single-Interface-Power-Save

Signed-off-by: Doru Gucea <gucea.doru@gmail.com>
---
 drivers/net/wireless/ath/ath9k/htc_drv_main.c | 4 ++++
 net/mac80211/mlme.c                           | 6 ++++++
 2 files changed, 10 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 172a9ff..59a76e0 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1521,6 +1521,10 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
 	mutex_lock(&priv->mutex);
 	ath9k_htc_ps_wakeup(priv);
 
+	/* adjust beacon timers */
+	if (changed && BSS_CHANGED_BEACON_INFO)
+		ath9k_htc_beacon_config(priv, vif);
+
 	if (changed & BSS_CHANGED_ASSOC) {
 		ath_dbg(common, CONFIG, "BSS Changed ASSOC %d\n",
 			bss_conf->assoc);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index cd7e55e..ce92a39 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3536,6 +3536,12 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 			sdata->vif.bss_conf.sync_dtim_count = 0;
 	}
 
+	/* trigger hardware timers adjustment
+	 * this needs to be done before beacon filtering
+	 */
+	changed |= BSS_CHANGED_BEACON_INFO;
+	ieee80211_bss_info_change_notify(sdata, changed);
+
 	if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
 		return;
 	ifmgd->beacon_crc = ncrc;
-- 
1.9.1

^ permalink raw reply related

* Power Save for Multi-VIF
From: Gucea Doru @ 2017-02-14 19:41 UTC (permalink / raw)
  To: linux-wireless, ath9k_htc_fw; +Cc: Andra Paraschiv, Costin Raiciu, Dragos N

Hello, everyone

I try to design a Power Save Algorithm in the case of a mobile client
that has multiple virtual interfaces [1] and is connected to multiple
Access Points simultaneously. My implementation is for the Atheros
AR9271 WiFi chip.

The biggest challenge in implementing this algorithm is waking up the
WiFi chip for RX traffic. E.g.: the WiFi chip is in the sleep state
and it has to wake up in order to receive beacons from all the APs
that the client is connected to.

Reading the AR9271 datasheet [2] I noticed that the chip is equipped
with hardware timers for waking up the hardware. The registers for
programming these hardware timers are MAC_PCU_SLP1 and MAC_PCU_SLP2.
After the registers have been programmed, the RTC_FORCE_WAKE bit has
to be cleared in order to allow the card to enter sleep mode (at least
this is how is done in the existing implementation for the single VIF
scenario).

I used the logic above for programming the hardware to wake up for
beacons from multiple APs. I used a power device for measuring the
energy consumption and it seems that the WiFi card wakes up
periodically to receive beacons from multiple APs. The problem is that
after a time, out of nowhere, the WiFi card refuses to enter sleep
mode and stays just in the awake state, although the logic for
programming the hardware timers does not change.

Could someone give more details about the FORCE_WAKE signal and what
is the relation between this signal and the MAC and RTC layers? I
believe that the problem comes from here. The AR9271 datasheet just
references this signal (page 106) but it offers no details about it.

[1] https://github.com/doru91/linux-stable/wiki/Two-Interfaces-Power-Save
[2] https://wikidevi.com/wiki/Atheros_AR9271
[3] http://lxr.free-electrons.com/source/drivers/net/wireless/ath/ath9k/hw.c?v=4.9#L2068

Regards,
Doru

^ permalink raw reply

* Re: [RFC V2 1/5] nl80211: allow multiple active scheduled scan requests
From: Arend Van Spriel @ 2017-02-14 20:09 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1487077927.4705.14.camel@sipsolutions.net>

On 14-2-2017 14:12, Johannes Berg wrote:
> On Tue, 2017-02-14 at 14:07 +0100, Arend Van Spriel wrote:
> 
>>> No. But there was a size limit on how much older userspace could
>>> process before we did the splitting.
>>
>> I see. So basically adding stuff to (split_start == 0) is not wanted.
> 
> Correct.

Uhm. Now I am staring at the code there and wonder about following. Up
until (split_start == 7) I see:

		state->split_start++;
		if (state->split)
			break;

For the remaining cases the break is unconditional. Any idea how to
interpret that?
	
>> Just trying to get a clear requirement/rule here. Do we (still) know
>> the exact size limit?
> 
> No, I don't remember. It's pretty ancient versions of iw/wpa_s that
> weren't able to deal with it. There was also interaction with the
> allocations in the dump function in nl80211 code itself, but we made
> those pretty big already and userspace limits came into play iirc.

Thanks,
Arend

^ permalink raw reply

* Re: [RFC V2 1/5] nl80211: allow multiple active scheduled scan requests
From: Johannes Berg @ 2017-02-14 20:11 UTC (permalink / raw)
  To: Arend Van Spriel; +Cc: linux-wireless
In-Reply-To: <e2ec8547-4e0d-881b-5f4e-1e61d4b8b047@broadcom.com>

On Tue, 2017-02-14 at 21:09 +0100, Arend Van Spriel wrote:
> On 14-2-2017 14:12, Johannes Berg wrote:
> > On Tue, 2017-02-14 at 14:07 +0100, Arend Van Spriel wrote:
> > 
> > > > No. But there was a size limit on how much older userspace
> > > > could
> > > > process before we did the splitting.
> > > 
> > > I see. So basically adding stuff to (split_start == 0) is not
> > > wanted.
> > 
> > Correct.
> 
> Uhm. Now I am staring at the code there and wonder about following.
> Up until (split_start == 7) I see:
> 
> 		state->split_start++;
> 		if (state->split)
> 			break;
> 
> For the remaining cases the break is unconditional. Any idea how to
> interpret that?

Yeah, actually, adding stuff to anything where split_start < 7 is
therefore not wanted :-)

The thing is that we if no split is accepted by the userspace tool
(state->split is false) then we have to send everything in one big
message. This is everything until split_start == 7, I guess.

After that, there's only new stuff that such old userspace will be
unable to interpret anyway, so the break is then unconditional - old
userspace without split will never see those new capabilities, and new
userspace can deal with the split.

johannes

^ permalink raw reply

* [PATCH 1/2] mac80211: use DECLARE_EWMA for mesh_fail_avg
From: Rajkumar Manoharan @ 2017-02-14 20:27 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, rmanohar, Rajkumar Manoharan

As moving average is not considering fractional part, it
will stuck at the same level after certain state. For example
with current values, moving average stuck at 96 and it will
not move forward. Fortunately current threshold is matching
against 95%. If thresold is increased more than 96, mesh path
never be deactivated under worst case. Fix failure average
movement by using EWMA helpers.

Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
---
 net/mac80211/mesh_hwmp.c    | 21 +++++++++++++++------
 net/mac80211/mesh_pathtbl.c |  3 +++
 net/mac80211/sta_info.h     |  4 +++-
 3 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index b747c9645e43..d07ee3ca07ee 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -307,10 +307,11 @@ void ieee80211s_update_metric(struct ieee80211_local *local,
 
 	failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK);
 
-	/* moving average, scaled to 100 */
-	sta->mesh->fail_avg =
-		((80 * sta->mesh->fail_avg + 5) / 100 + 20 * failed);
-	if (sta->mesh->fail_avg > 95)
+	/* moving average, scaled to 100.
+	 * feed failure as 100 and success as 0
+	 */
+	ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, failed * 100);
+	if (ewma_mesh_fail_avg_read(&sta->mesh->fail_avg) > 95)
 		mesh_plink_broken(sta);
 }
 
@@ -325,6 +326,8 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
 	int rate, err;
 	u32 tx_time, estimated_retx;
 	u64 result;
+	unsigned long fail_avg =
+		ewma_mesh_fail_avg_read(&sta->mesh->fail_avg);
 
 	/* Try to get rate based on HW/SW RC algorithm.
 	 * Rate is returned in units of Kbps, correct this
@@ -336,7 +339,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
 	if (rate) {
 		err = 0;
 	} else {
-		if (sta->mesh->fail_avg >= 100)
+		if (fail_avg >= 100)
 			return MAX_METRIC;
 
 		sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo);
@@ -344,7 +347,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
 		if (WARN_ON(!rate))
 			return MAX_METRIC;
 
-		err = (sta->mesh->fail_avg << ARITH_SHIFT) / 100;
+		err = (fail_avg << ARITH_SHIFT) / 100;
 	}
 
 	/* bitrate is in units of 100 Kbps, while we need rate in units of
@@ -484,6 +487,9 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
 					  ?  mpath->exp_time : exp_time;
 			mesh_path_activate(mpath);
 			spin_unlock_bh(&mpath->state_lock);
+			ewma_mesh_fail_avg_init(&sta->mesh->fail_avg);
+			/* init it at a low value - 0 start is tricky */
+			ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1);
 			mesh_path_tx_pending(mpath);
 			/* draft says preq_id should be saved to, but there does
 			 * not seem to be any use for it, skipping by now
@@ -522,6 +528,9 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
 					  ?  mpath->exp_time : exp_time;
 			mesh_path_activate(mpath);
 			spin_unlock_bh(&mpath->state_lock);
+			ewma_mesh_fail_avg_init(&sta->mesh->fail_avg);
+			/* init it at a low value - 0 start is tricky */
+			ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1);
 			mesh_path_tx_pending(mpath);
 		} else
 			spin_unlock_bh(&mpath->state_lock);
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index f0e6175a9821..98a3b1c0c338 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -829,6 +829,9 @@ void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop)
 	mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID;
 	mesh_path_activate(mpath);
 	spin_unlock_bh(&mpath->state_lock);
+	ewma_mesh_fail_avg_init(&next_hop->mesh->fail_avg);
+	/* init it at a low value - 0 start is tricky */
+	ewma_mesh_fail_avg_add(&next_hop->mesh->fail_avg, 1);
 	mesh_path_tx_pending(mpath);
 }
 
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index dd06ef0b8861..d9010f29de3d 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -322,6 +322,8 @@ struct ieee80211_fast_rx {
 	struct rcu_head rcu_head;
 };
 
+DECLARE_EWMA(mesh_fail_avg, 64, 8)
+
 /**
  * struct mesh_sta - mesh STA information
  * @plink_lock: serialize access to plink fields
@@ -367,7 +369,7 @@ struct mesh_sta {
 	enum nl80211_mesh_power_mode nonpeer_pm;
 
 	/* moving percentage of failed MSDUs */
-	unsigned int fail_avg;
+	struct ewma_mesh_fail_avg fail_avg;
 };
 
 DECLARE_EWMA(signal, 1024, 8)
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/2] mac80211: fix mesh fail_avg check
From: Rajkumar Manoharan @ 2017-02-14 20:27 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, rmanohar, Rajkumar Manoharan
In-Reply-To: <1487104037-24941-1-git-send-email-rmanohar@qca.qualcomm.com>

Mesh failure average never be more than 100. Only in case of
fixed path, average will be more than threshold limit (95%).
With recent EWMA changes it may go upto 99 as it is scaled to
100. It make sense to return maximum metric when average is
greater than threshold limit.

Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
---
 net/mac80211/mesh_hwmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index d07ee3ca07ee..02c30a21eb66 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -339,7 +339,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
 	if (rate) {
 		err = 0;
 	} else {
-		if (fail_avg >= 100)
+		if (fail_avg >= 95)
 			return MAX_METRIC;
 
 		sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo);
-- 
1.9.1

^ permalink raw reply related

* [PATCH] mac80211:  allow overriding station bandwidth.
From: greearb @ 2017-02-14 21:01 UTC (permalink / raw)
  To: linux-wireless; +Cc: johannes.berg, Ben Greear

From: Ben Greear <greearb@candelatech.com>

This allows one to disable VHT160 (or 80+80) on hardware
that might otherwise try to use it.  One potential reason
to do this is that at least some 160Mhz/80+80 hardware can
only do 2x2 at 160Mhz, but can do 4x4 at 80Mhz.  And, due to
driver and firmware issues, it may effectively be limitted
to 1x1 at 160Mhz for some NICs.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 include/linux/ieee80211.h |  1 +
 net/mac80211/main.c       |  1 +
 net/mac80211/vht.c        | 23 +++++++++++++++++++++++
 3 files changed, 25 insertions(+)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index a80516f..e5dc3a8 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1542,6 +1542,7 @@ struct ieee80211_vht_operation {
 #define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ		0x00000004
 #define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ	0x00000008
 #define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK			0x0000000C
+#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT			2
 #define IEEE80211_VHT_CAP_RXLDPC				0x00000010
 #define IEEE80211_VHT_CAP_SHORT_GI_80				0x00000020
 #define IEEE80211_VHT_CAP_SHORT_GI_160				0x00000040
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index ec5587d..1447b47 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -464,6 +464,7 @@ static const struct ieee80211_ht_cap mac80211_ht_capa_mod_mask = {
 static const struct ieee80211_vht_cap mac80211_vht_capa_mod_mask = {
 	.vht_cap_info =
 		cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC |
+			    IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK |
 			    IEEE80211_VHT_CAP_SHORT_GI_80 |
 			    IEEE80211_VHT_CAP_SHORT_GI_160 |
 			    IEEE80211_VHT_CAP_RXSTBC_1 |
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index 720c64c..5684e13 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -56,6 +56,29 @@ void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
 	__check_vhtcap_disable(sdata, vht_cap,
 			       IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN);
 
+	/* Allow disabling 160Mhz or 80+80 */
+	if (sdata->u.mgd.vht_capa_mask.vht_cap_info &
+	    cpu_to_le32(IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) {
+		u32 cap, n;
+
+		n = le32_to_cpu(sdata->u.mgd.vht_capa.vht_cap_info) &
+			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
+		n >>= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT;
+		cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
+		cap >>= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT;
+
+		if (n < cap) {
+			vht_cap->cap &=
+				~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
+			vht_cap->cap |=
+				n << IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT;
+
+			/* Cannot do short GI 160 if we cannot do 160 or 80+80 */
+			if (n == 0)
+				vht_cap->cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160;
+		}
+	}
+
 	/* Allow user to decrease AMPDU length exponent */
 	if (sdata->u.mgd.vht_capa_mask.vht_cap_info &
 	    cpu_to_le32(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK)) {
-- 
2.4.11

^ permalink raw reply related

* [PATCH] rt2500usb: don't mark register accesses as inline
From: Arnd Bergmann @ 2017-02-14 21:28 UTC (permalink / raw)
  To: Stanislaw Gruszka, Helmut Schaa, Kalle Valo
  Cc: Arnd Bergmann, Mathias Kresin, linux-wireless, netdev,
	linux-kernel

When CONFIG_KASAN is set, we get a rather large stack here:

drivers/net/wireless/ralink/rt2x00/rt2500usb.c: In function 'rt2500usb_set_device_state':
drivers/net/wireless/ralink/rt2x00/rt2500usb.c:1074:1: error: the frame size of 3032 bytes is larger than 100 bytes [-Werror=frame-larger-than=]

If we don't force those functions to be inline, the compiler can figure this
out better itself and not inline the functions when doing so would be harmful,
reducing the stack size to a merge 256 bytes.

Note that there is another problem that manifests in this driver, as a result
of the typecheck() macro causing even larger stack frames.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/net/wireless/ralink/rt2x00/rt2500usb.c | 19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
index 62357465fe29..0d2670a56c4c 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
  * If the csr_mutex is already held then the _lock variants must
  * be used instead.
  */
-static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
 					   const unsigned int offset,
 					   u16 *value)
 {
@@ -66,7 +66,7 @@ static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
 	*value = le16_to_cpu(reg);
 }
 
-static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
 						const unsigned int offset,
 						u16 *value)
 {
@@ -77,16 +77,7 @@ static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
 	*value = le16_to_cpu(reg);
 }
 
-static inline void rt2500usb_register_multiread(struct rt2x00_dev *rt2x00dev,
-						const unsigned int offset,
-						void *value, const u16 length)
-{
-	rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ,
-				      USB_VENDOR_REQUEST_IN, offset,
-				      value, length);
-}
-
-static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
 					    const unsigned int offset,
 					    u16 value)
 {
@@ -96,7 +87,7 @@ static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
 				      &reg, sizeof(reg));
 }
 
-static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
 						 const unsigned int offset,
 						 u16 value)
 {
@@ -106,7 +97,7 @@ static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
 				       &reg, sizeof(reg), REGISTER_TIMEOUT);
 }
 
-static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
 						 const unsigned int offset,
 						 void *value, const u16 length)
 {
-- 
2.9.0

^ permalink raw reply related

* [PATCH] bcma: gpio: set of_node regardless of the host type
From: Rafał Miłecki @ 2017-02-14 22:03 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, Rafał Miłecki

From: Rafał Miłecki <rafal@milecki.pl>

DT allows describing many device types, not only platform ones. If e.g.
bcma is hosted on PCI(e) and it has its of_node, let's pass it to the
GPIO subsystem. This allows GPIO code to handle more hardware details
not only for bcma on a SoC.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
 drivers/bcma/driver_gpio.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c
index 771a2a253440..7bde8d7a2816 100644
--- a/drivers/bcma/driver_gpio.c
+++ b/drivers/bcma/driver_gpio.c
@@ -185,8 +185,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
 	chip->owner		= THIS_MODULE;
 	chip->parent		= bcma_bus_get_host_dev(bus);
 #if IS_BUILTIN(CONFIG_OF)
-	if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
-		chip->of_node	= cc->core->dev.of_node;
+	chip->of_node		= cc->core->dev.of_node;
 #endif
 	switch (bus->chipinfo.id) {
 	case BCMA_CHIP_ID_BCM4707:
-- 
2.11.0

^ permalink raw reply related

* Re: [PATCH] bcma: gpio: set of_node regardless of the host type
From: Rafał Miłecki @ 2017-02-14 22:06 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless@vger.kernel.org, Rafał Miłecki
In-Reply-To: <20170214220346.10479-1-zajec5@gmail.com>

On 14 February 2017 at 23:03, Rafa=C5=82 Mi=C5=82ecki <zajec5@gmail.com> wr=
ote:
> From: Rafa=C5=82 Mi=C5=82ecki <rafal@milecki.pl>
>
> DT allows describing many device types, not only platform ones. If e.g.
> bcma is hosted on PCI(e) and it has its of_node, let's pass it to the
> GPIO subsystem. This allows GPIO code to handle more hardware details
> not only for bcma on a SoC.
>
> Signed-off-by: Rafa=C5=82 Mi=C5=82ecki <rafal@milecki.pl>

This obviously can wait for 4.12 merge window, no rush.

^ permalink raw reply

* Re: [PATCH] rt2500usb: don't mark register accesses as inline
From: Kalle Valo @ 2017-02-15  5:49 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Stanislaw Gruszka, Helmut Schaa, Mathias Kresin, linux-wireless,
	netdev, linux-kernel
In-Reply-To: <20170214212846.2809141-1-arnd@arndb.de>

Arnd Bergmann <arnd@arndb.de> writes:

> When CONFIG_KASAN is set, we get a rather large stack here:
>
> drivers/net/wireless/ralink/rt2x00/rt2500usb.c: In function 'rt2500usb_set_device_state':
> drivers/net/wireless/ralink/rt2x00/rt2500usb.c:1074:1: error: the frame size of 3032 bytes is larger than 100 bytes [-Werror=frame-larger-than=]
>
> If we don't force those functions to be inline, the compiler can figure this
> out better itself and not inline the functions when doing so would be harmful,
> reducing the stack size to a merge 256 bytes.
>
> Note that there is another problem that manifests in this driver, as a result
> of the typecheck() macro causing even larger stack frames.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>

[...]

> -static inline void rt2500usb_register_multiread(struct rt2x00_dev *rt2x00dev,
> -						const unsigned int offset,
> -						void *value, const u16 length)
> -{
> -	rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ,
> -				      USB_VENDOR_REQUEST_IN, offset,
> -				      value, length);
> -}
> -

I guess you removed this because it was not actually used anywhere? Just
checking.

-- 
Kalle Valo

^ 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