[OpenWrt-Devel] [PATCH] mac80211: backport upstream fixes

Koen Vandeputte koen.vandeputte at ncentric.com
Wed Sep 5 04:26:04 EDT 2018


Backport most significant upstream fixes (excl. hwsim fixes)
Refreshed all patches.

Contains important fixes for CSA (Channel Switch Announcement)
and A-MSDU frames.

Signed-off-by: Koen Vandeputte <koen.vandeputte at ncentric.com>
---
 ...-teardown-code-before-de-registering.patch |  38 +++++++
 ...x-HWMP-sequence-numbering-to-follow-.patch |  28 +++++
 ...ernel-panic-when-building-AMSDU-from.patch | 102 ++++++++++++++++++
 ..._update_ft_ies-to-validate-NL80211_A.patch |  27 +++++
 ...convert-to-A-MSDU-if-frag-subframe-l.patch |  37 +++++++
 ...ys-account-for-A-MSDU-header-changes.patch |  51 +++++++++
 ...off-by-one-issue-in-A-MSDU-max_subfr.patch |  26 +++++
 ...ype-issue-in-ieee80211_chandef_to_op.patch |  33 ++++++
 ...a-race-between-restart-and-CSA-flows.patch |  86 +++++++++++++++
 ...tion-bandwidth-setting-after-channel.patch |  96 +++++++++++++++++
 ...x-a-deauth-frame-if-the-AP-forbade-T.patch |  78 ++++++++++++++
 ...0211-shorten-the-IBSS-debug-messages.patch |  74 +++++++++++++
 .../522-mac80211_configure_antenna_gain.patch |   2 +-
 ...ilable-channels-via-DT-ieee80211-fre.patch |   9 +-
 14 files changed, 679 insertions(+), 8 deletions(-)
 create mode 100644 package/kernel/mac80211/patches/382-mac80211-Run-TXQ-teardown-code-before-de-registering.patch
 create mode 100644 package/kernel/mac80211/patches/383-mac80211-mesh-fix-HWMP-sequence-numbering-to-follow-.patch
 create mode 100644 package/kernel/mac80211/patches/384-mac80211-avoid-kernel-panic-when-building-AMSDU-from.patch
 create mode 100644 package/kernel/mac80211/patches/385-cfg80211-nl80211_update_ft_ies-to-validate-NL80211_A.patch
 create mode 100644 package/kernel/mac80211/patches/386-mac80211-do-not-convert-to-A-MSDU-if-frag-subframe-l.patch
 create mode 100644 package/kernel/mac80211/patches/387-mac80211-always-account-for-A-MSDU-header-changes.patch
 create mode 100644 package/kernel/mac80211/patches/388-mac80211-fix-an-off-by-one-issue-in-A-MSDU-max_subfr.patch
 create mode 100644 package/kernel/mac80211/patches/389-cfg80211-fix-a-type-issue-in-ieee80211_chandef_to_op.patch
 create mode 100644 package/kernel/mac80211/patches/390-mac80211-fix-a-race-between-restart-and-CSA-flows.patch
 create mode 100644 package/kernel/mac80211/patches/391-mac80211-Fix-station-bandwidth-setting-after-channel.patch
 create mode 100644 package/kernel/mac80211/patches/392-mac80211-don-t-Tx-a-deauth-frame-if-the-AP-forbade-T.patch
 create mode 100644 package/kernel/mac80211/patches/393-mac80211-shorten-the-IBSS-debug-messages.patch

diff --git a/package/kernel/mac80211/patches/382-mac80211-Run-TXQ-teardown-code-before-de-registering.patch b/package/kernel/mac80211/patches/382-mac80211-Run-TXQ-teardown-code-before-de-registering.patch
new file mode 100644
index 000000000000..ad282f98925c
--- /dev/null
+++ b/package/kernel/mac80211/patches/382-mac80211-Run-TXQ-teardown-code-before-de-registering.patch
@@ -0,0 +1,38 @@
+From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke at toke.dk>
+Date: Mon, 13 Aug 2018 14:16:25 +0200
+Subject: [PATCH] mac80211: Run TXQ teardown code before de-registering
+ interfaces
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The TXQ teardown code can reference the vif data structures that are
+stored in the netdev private memory area if there are still packets on
+the queue when it is being freed. Since the TXQ teardown code is run
+after the netdevs are freed, this can lead to a use-after-free. Fix this
+by moving the TXQ teardown code to earlier in ieee80211_unregister_hw().
+
+Reported-by: Ben Greear <greearb at candelatech.com>
+Tested-by: Ben Greear <greearb at candelatech.com>
+Signed-off-by: Toke Høiland-Jørgensen <toke at toke.dk>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -1172,6 +1172,7 @@ void ieee80211_unregister_hw(struct ieee
+ #if IS_ENABLED(__disabled__CONFIG_IPV6)
+ 	unregister_inet6addr_notifier(&local->ifa6_notifier);
+ #endif
++	ieee80211_txq_teardown_flows(local);
+ 
+ 	rtnl_lock();
+ 
+@@ -1200,7 +1201,6 @@ void ieee80211_unregister_hw(struct ieee
+ 	skb_queue_purge(&local->skb_queue);
+ 	skb_queue_purge(&local->skb_queue_unreliable);
+ 	skb_queue_purge(&local->skb_queue_tdls_chsw);
+-	ieee80211_txq_teardown_flows(local);
+ 
+ 	destroy_workqueue(local->workqueue);
+ 	wiphy_unregister(local->hw.wiphy);
diff --git a/package/kernel/mac80211/patches/383-mac80211-mesh-fix-HWMP-sequence-numbering-to-follow-.patch b/package/kernel/mac80211/patches/383-mac80211-mesh-fix-HWMP-sequence-numbering-to-follow-.patch
new file mode 100644
index 000000000000..e7b279af55e9
--- /dev/null
+++ b/package/kernel/mac80211/patches/383-mac80211-mesh-fix-HWMP-sequence-numbering-to-follow-.patch
@@ -0,0 +1,28 @@
+From: Yuan-Chi Pang <fu3mo6goo at gmail.com>
+Date: Wed, 29 Aug 2018 09:30:08 +0800
+Subject: [PATCH] mac80211: mesh: fix HWMP sequence numbering to follow
+ standard
+
+IEEE 802.11-2016 14.10.8.3 HWMP sequence numbering says:
+If it is a target mesh STA, it shall update its own HWMP SN to
+maximum (current HWMP SN, target HWMP SN in the PREQ element) + 1
+immediately before it generates a PREP element in response to a
+PREQ element.
+
+Signed-off-by: Yuan-Chi Pang <fu3mo6goo at gmail.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/mac80211/mesh_hwmp.c
++++ b/net/mac80211/mesh_hwmp.c
+@@ -572,6 +572,10 @@ static void hwmp_preq_frame_process(stru
+ 		forward = false;
+ 		reply = true;
+ 		target_metric = 0;
++
++		if (SN_GT(target_sn, ifmsh->sn))
++			ifmsh->sn = target_sn;
++
+ 		if (time_after(jiffies, ifmsh->last_sn_update +
+ 					net_traversal_jiffies(sdata)) ||
+ 		    time_before(jiffies, ifmsh->last_sn_update)) {
diff --git a/package/kernel/mac80211/patches/384-mac80211-avoid-kernel-panic-when-building-AMSDU-from.patch b/package/kernel/mac80211/patches/384-mac80211-avoid-kernel-panic-when-building-AMSDU-from.patch
new file mode 100644
index 000000000000..66993839eef4
--- /dev/null
+++ b/package/kernel/mac80211/patches/384-mac80211-avoid-kernel-panic-when-building-AMSDU-from.patch
@@ -0,0 +1,102 @@
+From: Sara Sharon <sara.sharon at intel.com>
+Date: Wed, 29 Aug 2018 08:57:02 +0200
+Subject: [PATCH] mac80211: avoid kernel panic when building AMSDU from
+ non-linear SKB
+
+When building building AMSDU from non-linear SKB, we hit a
+kernel panic when trying to push the padding to the tail.
+Instead, put the padding at the head of the next subframe.
+This also fixes the A-MSDU subframes to not have the padding
+accounted in the length field and not have pad at all for
+the last subframe, both required by the spec.
+
+Fixes: 6e0456b54545 ("mac80211: add A-MSDU tx support")
+Signed-off-by: Sara Sharon <sara.sharon at intel.com>
+Reviewed-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -3064,27 +3064,18 @@ void ieee80211_clear_fast_xmit(struct st
+ }
+ 
+ static bool ieee80211_amsdu_realloc_pad(struct ieee80211_local *local,
+-					struct sk_buff *skb, int headroom,
+-					int *subframe_len)
++					struct sk_buff *skb, int headroom)
+ {
+-	int amsdu_len = *subframe_len + sizeof(struct ethhdr);
+-	int padding = (4 - amsdu_len) & 3;
+-
+-	if (skb_headroom(skb) < headroom || skb_tailroom(skb) < padding) {
++	if (skb_headroom(skb) < headroom) {
+ 		I802_DEBUG_INC(local->tx_expand_skb_head);
+ 
+-		if (pskb_expand_head(skb, headroom, padding, GFP_ATOMIC)) {
++		if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) {
+ 			wiphy_debug(local->hw.wiphy,
+ 				    "failed to reallocate TX buffer\n");
+ 			return false;
+ 		}
+ 	}
+ 
+-	if (padding) {
+-		*subframe_len += padding;
+-		skb_put_zero(skb, padding);
+-	}
+-
+ 	return true;
+ }
+ 
+@@ -3108,8 +3099,7 @@ static bool ieee80211_amsdu_prepare_head
+ 	if (info->control.flags & IEEE80211_TX_CTRL_AMSDU)
+ 		return true;
+ 
+-	if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(*amsdu_hdr),
+-					 &subframe_len))
++	if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(*amsdu_hdr)))
+ 		return false;
+ 
+ 	data = skb_push(skb, sizeof(*amsdu_hdr));
+@@ -3176,7 +3166,8 @@ static bool ieee80211_amsdu_aggregate(st
+ 	void *data;
+ 	bool ret = false;
+ 	unsigned int orig_len;
+-	int n = 1, nfrags;
++	int n = 1, nfrags, pad = 0;
++	u16 hdrlen;
+ 
+ 	if (!ieee80211_hw_check(&local->hw, TX_AMSDU))
+ 		return false;
+@@ -3228,8 +3219,19 @@ static bool ieee80211_amsdu_aggregate(st
+ 	if (max_frags && nfrags > max_frags)
+ 		goto out;
+ 
+-	if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(rfc1042_header) + 2,
+-					 &subframe_len))
++	/*
++	 * Pad out the previous subframe to a multiple of 4 by adding the
++	 * padding to the next one, that's being added. Note that head->len
++	 * is the length of the full A-MSDU, but that works since each time
++	 * we add a new subframe we pad out the previous one to a multiple
++	 * of 4 and thus it no longer matters in the next round.
++	 */
++	hdrlen = fast_tx->hdr_len - sizeof(rfc1042_header);
++	if ((head->len - hdrlen) & 3)
++		pad = 4 - ((head->len - hdrlen) & 3);
++
++	if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(rfc1042_header) +
++						     2 + pad))
+ 		goto out;
+ 
+ 	ret = true;
+@@ -3241,6 +3243,8 @@ static bool ieee80211_amsdu_aggregate(st
+ 	memcpy(data, &len, 2);
+ 	memcpy(data + 2, rfc1042_header, sizeof(rfc1042_header));
+ 
++	memset(skb_push(skb, pad), 0, pad);
++
+ 	head->len += skb->len;
+ 	head->data_len += skb->len;
+ 	*frag_tail = skb;
diff --git a/package/kernel/mac80211/patches/385-cfg80211-nl80211_update_ft_ies-to-validate-NL80211_A.patch b/package/kernel/mac80211/patches/385-cfg80211-nl80211_update_ft_ies-to-validate-NL80211_A.patch
new file mode 100644
index 000000000000..f4b14506a623
--- /dev/null
+++ b/package/kernel/mac80211/patches/385-cfg80211-nl80211_update_ft_ies-to-validate-NL80211_A.patch
@@ -0,0 +1,27 @@
+From: Arunk Khandavalli <akhandav at codeaurora.org>
+Date: Thu, 30 Aug 2018 00:40:16 +0300
+Subject: [PATCH] cfg80211: nl80211_update_ft_ies() to validate
+ NL80211_ATTR_IE
+
+nl80211_update_ft_ies() tried to validate NL80211_ATTR_IE with
+is_valid_ie_attr() before dereferencing it, but that helper function
+returns true in case of NULL pointer (i.e., attribute not included).
+This can result to dereferencing a NULL pointer. Fix that by explicitly
+checking that NL80211_ATTR_IE is included.
+
+Fixes: 355199e02b83 ("cfg80211: Extend support for IEEE 802.11r Fast BSS Transition")
+Signed-off-by: Arunk Khandavalli <akhandav at codeaurora.org>
+Signed-off-by: Jouni Malinen <jouni at codeaurora.org>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -11763,6 +11763,7 @@ static int nl80211_update_ft_ies(struct
+ 		return -EOPNOTSUPP;
+ 
+ 	if (!info->attrs[NL80211_ATTR_MDID] ||
++	    !info->attrs[NL80211_ATTR_IE] ||
+ 	    !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+ 		return -EINVAL;
+ 
diff --git a/package/kernel/mac80211/patches/386-mac80211-do-not-convert-to-A-MSDU-if-frag-subframe-l.patch b/package/kernel/mac80211/patches/386-mac80211-do-not-convert-to-A-MSDU-if-frag-subframe-l.patch
new file mode 100644
index 000000000000..1d889022516d
--- /dev/null
+++ b/package/kernel/mac80211/patches/386-mac80211-do-not-convert-to-A-MSDU-if-frag-subframe-l.patch
@@ -0,0 +1,37 @@
+From: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
+Date: Wed, 29 Aug 2018 21:03:25 +0200
+Subject: [PATCH] mac80211: do not convert to A-MSDU if frag/subframe
+ limited
+
+Do not start to aggregate packets in a A-MSDU frame (converting the
+first subframe to A-MSDU, adding the header) if max_tx_fragments or
+max_amsdu_subframes limits are already exceeded by it. In particular,
+this happens when drivers set the limit to 1 to avoid A-MSDUs at all.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
+[reword commit message to be more precise]
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -3201,9 +3201,6 @@ static bool ieee80211_amsdu_aggregate(st
+ 	if (skb->len + head->len > max_amsdu_len)
+ 		goto unlock;
+ 
+-	if (!ieee80211_amsdu_prepare_head(sdata, fast_tx, head))
+-		goto out;
+-
+ 	nfrags = 1 + skb_shinfo(skb)->nr_frags;
+ 	nfrags += 1 + skb_shinfo(head)->nr_frags;
+ 	frag_tail = &skb_shinfo(head)->frag_list;
+@@ -3219,6 +3216,9 @@ static bool ieee80211_amsdu_aggregate(st
+ 	if (max_frags && nfrags > max_frags)
+ 		goto out;
+ 
++	if (!ieee80211_amsdu_prepare_head(sdata, fast_tx, head))
++		goto out;
++
+ 	/*
+ 	 * Pad out the previous subframe to a multiple of 4 by adding the
+ 	 * padding to the next one, that's being added. Note that head->len
diff --git a/package/kernel/mac80211/patches/387-mac80211-always-account-for-A-MSDU-header-changes.patch b/package/kernel/mac80211/patches/387-mac80211-always-account-for-A-MSDU-header-changes.patch
new file mode 100644
index 000000000000..47942116bc85
--- /dev/null
+++ b/package/kernel/mac80211/patches/387-mac80211-always-account-for-A-MSDU-header-changes.patch
@@ -0,0 +1,51 @@
+From: Johannes Berg <johannes.berg at intel.com>
+Date: Thu, 30 Aug 2018 10:55:49 +0200
+Subject: [PATCH] mac80211: always account for A-MSDU header changes
+
+In the error path of changing the SKB headroom of the second
+A-MSDU subframe, we would not account for the already-changed
+length of the first frame that just got converted to be in
+A-MSDU format and thus is a bit longer now.
+
+Fix this by doing the necessary accounting.
+
+It would be possible to reorder the operations, but that would
+make the code more complex (to calculate the necessary pad),
+and the headroom expansion should not fail frequently enough
+to make that worthwhile.
+
+Fixes: 6e0456b54545 ("mac80211: add A-MSDU tx support")
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+Acked-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -3232,7 +3232,7 @@ static bool ieee80211_amsdu_aggregate(st
+ 
+ 	if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(rfc1042_header) +
+ 						     2 + pad))
+-		goto out;
++		goto out_recalc;
+ 
+ 	ret = true;
+ 	data = skb_push(skb, ETH_ALEN + 2);
+@@ -3249,11 +3249,13 @@ static bool ieee80211_amsdu_aggregate(st
+ 	head->data_len += skb->len;
+ 	*frag_tail = skb;
+ 
+-	flow->backlog += head->len - orig_len;
+-	tin->backlog_bytes += head->len - orig_len;
+-
+-	fq_recalc_backlog(fq, tin, flow);
++out_recalc:
++	if (head->len != orig_len) {
++		flow->backlog += head->len - orig_len;
++		tin->backlog_bytes += head->len - orig_len;
+ 
++		fq_recalc_backlog(fq, tin, flow);
++	}
+ out:
+ 	fq->memory_usage += head->truesize - orig_truesize;
+ 
diff --git a/package/kernel/mac80211/patches/388-mac80211-fix-an-off-by-one-issue-in-A-MSDU-max_subfr.patch b/package/kernel/mac80211/patches/388-mac80211-fix-an-off-by-one-issue-in-A-MSDU-max_subfr.patch
new file mode 100644
index 000000000000..455fa298311f
--- /dev/null
+++ b/package/kernel/mac80211/patches/388-mac80211-fix-an-off-by-one-issue-in-A-MSDU-max_subfr.patch
@@ -0,0 +1,26 @@
+From: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
+Date: Fri, 31 Aug 2018 01:04:13 +0200
+Subject: [PATCH] mac80211: fix an off-by-one issue in A-MSDU
+ max_subframe computation
+
+Initialize 'n' to 2 in order to take into account also the first
+packet in the estimation of max_subframe limit for a given A-MSDU
+since frag_tail pointer is NULL when ieee80211_amsdu_aggregate
+routine analyzes the second frame.
+
+Fixes: 6e0456b54545 ("mac80211: add A-MSDU tx support")
+Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -3166,7 +3166,7 @@ static bool ieee80211_amsdu_aggregate(st
+ 	void *data;
+ 	bool ret = false;
+ 	unsigned int orig_len;
+-	int n = 1, nfrags, pad = 0;
++	int n = 2, nfrags, pad = 0;
+ 	u16 hdrlen;
+ 
+ 	if (!ieee80211_hw_check(&local->hw, TX_AMSDU))
diff --git a/package/kernel/mac80211/patches/389-cfg80211-fix-a-type-issue-in-ieee80211_chandef_to_op.patch b/package/kernel/mac80211/patches/389-cfg80211-fix-a-type-issue-in-ieee80211_chandef_to_op.patch
new file mode 100644
index 000000000000..8437aad6a625
--- /dev/null
+++ b/package/kernel/mac80211/patches/389-cfg80211-fix-a-type-issue-in-ieee80211_chandef_to_op.patch
@@ -0,0 +1,33 @@
+From: Dan Carpenter <dan.carpenter at oracle.com>
+Date: Fri, 31 Aug 2018 11:10:55 +0300
+Subject: [PATCH] cfg80211: fix a type issue in
+ ieee80211_chandef_to_operating_class()
+
+The "chandef->center_freq1" variable is a u32 but "freq" is a u16 so we
+are truncating away the high bits.  I noticed this bug because in commit
+9cf0a0b4b64a ("cfg80211: Add support for 60GHz band channels 5 and 6")
+we made "freq <= 56160 + 2160 * 6" a valid requency when before it was
+only "freq <= 56160 + 2160 * 4" that was valid.  It introduces a static
+checker warning:
+
+    net/wireless/util.c:1571 ieee80211_chandef_to_operating_class()
+    warn: always true condition '(freq <= 56160 + 2160 * 6) => (0-u16max <= 69120)'
+
+But really we probably shouldn't have been truncating the high bits
+away to begin with.
+
+Signed-off-by: Dan Carpenter <dan.carpenter at oracle.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/wireless/util.c
++++ b/net/wireless/util.c
+@@ -1377,7 +1377,7 @@ bool ieee80211_chandef_to_operating_clas
+ 					  u8 *op_class)
+ {
+ 	u8 vht_opclass;
+-	u16 freq = chandef->center_freq1;
++	u32 freq = chandef->center_freq1;
+ 
+ 	if (freq >= 2412 && freq <= 2472) {
+ 		if (chandef->width > NL80211_CHAN_WIDTH_40)
diff --git a/package/kernel/mac80211/patches/390-mac80211-fix-a-race-between-restart-and-CSA-flows.patch b/package/kernel/mac80211/patches/390-mac80211-fix-a-race-between-restart-and-CSA-flows.patch
new file mode 100644
index 000000000000..db2aa0443f7c
--- /dev/null
+++ b/package/kernel/mac80211/patches/390-mac80211-fix-a-race-between-restart-and-CSA-flows.patch
@@ -0,0 +1,86 @@
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Date: Fri, 31 Aug 2018 11:31:06 +0300
+Subject: [PATCH] mac80211: fix a race between restart and CSA flows
+
+We hit a problem with iwlwifi that was caused by a bug in
+mac80211. A bug in iwlwifi caused the firwmare to crash in
+certain cases in channel switch. Because of that bug,
+drv_pre_channel_switch would fail and trigger the restart
+flow.
+Now we had the hw restart worker which runs on the system's
+workqueue and the csa_connection_drop_work worker that runs
+on mac80211's workqueue that can run together. This is
+obviously problematic since the restart work wants to
+reconfigure the connection, while the csa_connection_drop_work
+worker does the exact opposite: it tries to disconnect.
+
+Fix this by cancelling the csa_connection_drop_work worker
+in the restart worker.
+
+Note that this can sound racy: we could have:
+
+driver   iface_work   CSA_work   restart_work
++++++++++++++++++++++++++++++++++++++++++++++
+              |
+ <--drv_cs ---|
+<FW CRASH!>
+-CS FAILED-->
+              |                       |
+              |                 cancel_work(CSA)
+           schedule                   |
+           CSA work                   |
+                         |            |
+                        Race between those 2
+
+But this is not possible because we flush the workqueue
+in the restart worker before we cancel the CSA worker.
+That would be bullet proof if we could guarantee that
+we schedule the CSA worker only from the iface_work
+which runs on the workqueue (and not on the system's
+workqueue), but unfortunately we do have an instance
+in which we schedule the CSA work outside the context
+of the workqueue (ieee80211_chswitch_done).
+
+Note also that we should probably cancel other workers
+like beacon_connection_loss_work and possibly others
+for different types of interfaces, at the very least,
+IBSS should suffer from the exact same problem, but for
+now, do the minimum to fix the actual bug that was actually
+experienced and reproduced.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho at intel.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -255,8 +255,27 @@ static void ieee80211_restart_work(struc
+ 
+ 	flush_work(&local->radar_detected_work);
+ 	rtnl_lock();
+-	list_for_each_entry(sdata, &local->interfaces, list)
++	list_for_each_entry(sdata, &local->interfaces, list) {
++		/*
++		 * XXX: there may be more work for other vif types and even
++		 * for station mode: a good thing would be to run most of
++		 * the iface type's dependent _stop (ieee80211_mg_stop,
++		 * ieee80211_ibss_stop) etc...
++		 * For now, fix only the specific bug that was seen: race
++		 * between csa_connection_drop_work and us.
++		 */
++		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
++			/*
++			 * This worker is scheduled from the iface worker that
++			 * runs on mac80211's workqueue, so we can't be
++			 * scheduling this worker after the cancel right here.
++			 * The exception is ieee80211_chswitch_done.
++			 * Then we can have a race...
++			 */
++			cancel_work_sync(&sdata->u.mgd.csa_connection_drop_work);
++		}
+ 		flush_delayed_work(&sdata->dec_tailroom_needed_wk);
++	}
+ 	ieee80211_scan_cancel(local);
+ 
+ 	/* make sure any new ROC will consider local->in_reconfig */
diff --git a/package/kernel/mac80211/patches/391-mac80211-Fix-station-bandwidth-setting-after-channel.patch b/package/kernel/mac80211/patches/391-mac80211-Fix-station-bandwidth-setting-after-channel.patch
new file mode 100644
index 000000000000..aa8db32e72e8
--- /dev/null
+++ b/package/kernel/mac80211/patches/391-mac80211-Fix-station-bandwidth-setting-after-channel.patch
@@ -0,0 +1,96 @@
+From: Ilan Peer <ilan.peer at intel.com>
+Date: Fri, 31 Aug 2018 11:31:10 +0300
+Subject: [PATCH] mac80211: Fix station bandwidth setting after channel
+ switch
+
+When performing a channel switch flow for a managed interface, the
+flow did not update the bandwidth of the AP station and the rate
+scale algorithm. In case of a channel width downgrade, this would
+result with the rate scale algorithm using a bandwidth that does not
+match the interface channel configuration.
+
+Fix this by updating the AP station bandwidth and rate scaling algorithm
+before the actual channel change in case of a bandwidth downgrade, or
+after the actual channel change in case of a bandwidth upgrade.
+
+Signed-off-by: Ilan Peer <ilan.peer at intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho at intel.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -975,6 +975,10 @@ static void ieee80211_chswitch_work(stru
+ 	 */
+ 
+ 	if (sdata->reserved_chanctx) {
++		struct ieee80211_supported_band *sband = NULL;
++		struct sta_info *mgd_sta = NULL;
++		enum ieee80211_sta_rx_bandwidth bw = IEEE80211_STA_RX_BW_20;
++
+ 		/*
+ 		 * with multi-vif csa driver may call ieee80211_csa_finish()
+ 		 * many times while waiting for other interfaces to use their
+@@ -983,6 +987,48 @@ static void ieee80211_chswitch_work(stru
+ 		if (sdata->reserved_ready)
+ 			goto out;
+ 
++		if (sdata->vif.bss_conf.chandef.width !=
++		    sdata->csa_chandef.width) {
++			/*
++			 * For managed interface, we need to also update the AP
++			 * station bandwidth and align the rate scale algorithm
++			 * on the bandwidth change. Here we only consider the
++			 * bandwidth of the new channel definition (as channel
++			 * switch flow does not have the full HT/VHT/HE
++			 * information), assuming that if additional changes are
++			 * required they would be done as part of the processing
++			 * of the next beacon from the AP.
++			 */
++			switch (sdata->csa_chandef.width) {
++			case NL80211_CHAN_WIDTH_20_NOHT:
++			case NL80211_CHAN_WIDTH_20:
++			default:
++				bw = IEEE80211_STA_RX_BW_20;
++				break;
++			case NL80211_CHAN_WIDTH_40:
++				bw = IEEE80211_STA_RX_BW_40;
++				break;
++			case NL80211_CHAN_WIDTH_80:
++				bw = IEEE80211_STA_RX_BW_80;
++				break;
++			case NL80211_CHAN_WIDTH_80P80:
++			case NL80211_CHAN_WIDTH_160:
++				bw = IEEE80211_STA_RX_BW_160;
++				break;
++			}
++
++			mgd_sta = sta_info_get(sdata, ifmgd->bssid);
++			sband =
++				local->hw.wiphy->bands[sdata->csa_chandef.chan->band];
++		}
++
++		if (sdata->vif.bss_conf.chandef.width >
++		    sdata->csa_chandef.width) {
++			mgd_sta->sta.bandwidth = bw;
++			rate_control_rate_update(local, sband, mgd_sta,
++						 IEEE80211_RC_BW_CHANGED);
++		}
++
+ 		ret = ieee80211_vif_use_reserved_context(sdata);
+ 		if (ret) {
+ 			sdata_info(sdata,
+@@ -993,6 +1039,13 @@ static void ieee80211_chswitch_work(stru
+ 			goto out;
+ 		}
+ 
++		if (sdata->vif.bss_conf.chandef.width <
++		    sdata->csa_chandef.width) {
++			mgd_sta->sta.bandwidth = bw;
++			rate_control_rate_update(local, sband, mgd_sta,
++						 IEEE80211_RC_BW_CHANGED);
++		}
++
+ 		goto out;
+ 	}
+ 
diff --git a/package/kernel/mac80211/patches/392-mac80211-don-t-Tx-a-deauth-frame-if-the-AP-forbade-T.patch b/package/kernel/mac80211/patches/392-mac80211-don-t-Tx-a-deauth-frame-if-the-AP-forbade-T.patch
new file mode 100644
index 000000000000..74dd3d3775a3
--- /dev/null
+++ b/package/kernel/mac80211/patches/392-mac80211-don-t-Tx-a-deauth-frame-if-the-AP-forbade-T.patch
@@ -0,0 +1,78 @@
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Date: Fri, 31 Aug 2018 11:31:12 +0300
+Subject: [PATCH] mac80211: don't Tx a deauth frame if the AP forbade Tx
+
+If the driver fails to properly prepare for the channel
+switch, mac80211 will disconnect. If the CSA IE had mode
+set to 1, it means that the clients are not allowed to send
+any Tx on the current channel, and that includes the
+deauthentication frame.
+
+Make sure that we don't send the deauthentication frame in
+this case.
+
+In iwlwifi, this caused a failure to flush queues since the
+firmware already closed the queues after having parsed the
+CSA IE. Then mac80211 would wait until the deauthentication
+frame would go out (drv_flush(drop=false)) and that would
+never happen.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho at intel.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -1267,6 +1267,16 @@ ieee80211_sta_process_chanswitch(struct
+ 					 cbss->beacon_interval));
+ 	return;
+  drop_connection:
++	/*
++	 * This is just so that the disconnect flow will know that
++	 * we were trying to switch channel and failed. In case the
++	 * mode is 1 (we are not allowed to Tx), we will know not to
++	 * send a deauthentication frame. Those two fields will be
++	 * reset when the disconnection worker runs.
++	 */
++	sdata->vif.csa_active = true;
++	sdata->csa_block_tx = csa_ie.mode;
++
+ 	ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work);
+ 	mutex_unlock(&local->chanctx_mtx);
+ 	mutex_unlock(&local->mtx);
+@@ -2437,6 +2447,7 @@ static void __ieee80211_disconnect(struc
+ 	struct ieee80211_local *local = sdata->local;
+ 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ 	u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
++	bool tx;
+ 
+ 	sdata_lock(sdata);
+ 	if (!ifmgd->associated) {
+@@ -2444,6 +2455,8 @@ static void __ieee80211_disconnect(struc
+ 		return;
+ 	}
+ 
++	tx = !sdata->csa_block_tx;
++
+ 	/* AP is probably out of range (or not reachable for another reason) so
+ 	 * remove the bss struct for that AP.
+ 	 */
+@@ -2451,7 +2464,7 @@ static void __ieee80211_disconnect(struc
+ 
+ 	ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
+ 			       WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
+-			       true, frame_buf);
++			       tx, frame_buf);
+ 	mutex_lock(&local->mtx);
+ 	sdata->vif.csa_active = false;
+ 	ifmgd->csa_waiting_bcn = false;
+@@ -2462,7 +2475,7 @@ static void __ieee80211_disconnect(struc
+ 	}
+ 	mutex_unlock(&local->mtx);
+ 
+-	ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
++	ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx,
+ 				    WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
+ 
+ 	sdata_unlock(sdata);
diff --git a/package/kernel/mac80211/patches/393-mac80211-shorten-the-IBSS-debug-messages.patch b/package/kernel/mac80211/patches/393-mac80211-shorten-the-IBSS-debug-messages.patch
new file mode 100644
index 000000000000..fb5b282d1d7c
--- /dev/null
+++ b/package/kernel/mac80211/patches/393-mac80211-shorten-the-IBSS-debug-messages.patch
@@ -0,0 +1,74 @@
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Date: Fri, 31 Aug 2018 11:31:13 +0300
+Subject: [PATCH] mac80211: shorten the IBSS debug messages
+
+When tracing is enabled, all the debug messages are recorded and must
+not exceed MAX_MSG_LEN (100) columns. Longer debug messages grant the
+user with:
+
+WARNING: CPU: 3 PID: 32642 at /tmp/wifi-core-20180806094828/src/iwlwifi-stack-dev/net/mac80211/./trace_msg.h:32 trace_event_raw_event_mac80211_msg_event+0xab/0xc0 [mac80211]
+Workqueue: phy1 ieee80211_iface_work [mac80211]
+ RIP: 0010:trace_event_raw_event_mac80211_msg_event+0xab/0xc0 [mac80211]
+ Call Trace:
+  __sdata_dbg+0xbd/0x120 [mac80211]
+  ieee80211_ibss_rx_queued_mgmt+0x15f/0x510 [mac80211]
+  ieee80211_iface_work+0x21d/0x320 [mac80211]
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho at intel.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/mac80211/ibss.c
++++ b/net/mac80211/ibss.c
+@@ -947,8 +947,8 @@ static void ieee80211_rx_mgmt_deauth_ibs
+ 	if (len < IEEE80211_DEAUTH_FRAME_LEN)
+ 		return;
+ 
+-	ibss_dbg(sdata, "RX DeAuth SA=%pM DA=%pM BSSID=%pM (reason: %d)\n",
+-		 mgmt->sa, mgmt->da, mgmt->bssid, reason);
++	ibss_dbg(sdata, "RX DeAuth SA=%pM DA=%pM\n", mgmt->sa, mgmt->da);
++	ibss_dbg(sdata, "\tBSSID=%pM (reason: %d)\n", mgmt->bssid, reason);
+ 	sta_info_destroy_addr(sdata, mgmt->sa);
+ }
+ 
+@@ -966,9 +966,9 @@ static void ieee80211_rx_mgmt_auth_ibss(
+ 	auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
+ 	auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
+ 
+-	ibss_dbg(sdata,
+-		 "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n",
+-		 mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction);
++	ibss_dbg(sdata, "RX Auth SA=%pM DA=%pM\n", mgmt->sa, mgmt->da);
++	ibss_dbg(sdata, "\tBSSID=%pM (auth_transaction=%d)\n",
++		 mgmt->bssid, auth_transaction);
+ 
+ 	if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
+ 		return;
+@@ -1175,10 +1175,10 @@ static void ieee80211_rx_bss_info(struct
+ 		rx_timestamp = drv_get_tsf(local, sdata);
+ 	}
+ 
+-	ibss_dbg(sdata,
+-		 "RX beacon SA=%pM BSSID=%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n",
++	ibss_dbg(sdata, "RX beacon SA=%pM BSSID=%pM TSF=0x%llx\n",
+ 		 mgmt->sa, mgmt->bssid,
+-		 (unsigned long long)rx_timestamp,
++		 (unsigned long long)rx_timestamp);
++	ibss_dbg(sdata, "\tBCN=0x%llx diff=%lld @%lu\n",
+ 		 (unsigned long long)beacon_timestamp,
+ 		 (unsigned long long)(rx_timestamp - beacon_timestamp),
+ 		 jiffies);
+@@ -1537,9 +1537,9 @@ static void ieee80211_rx_mgmt_probe_req(
+ 
+ 	tx_last_beacon = drv_tx_last_beacon(local);
+ 
+-	ibss_dbg(sdata,
+-		 "RX ProbeReq SA=%pM DA=%pM BSSID=%pM (tx_last_beacon=%d)\n",
+-		 mgmt->sa, mgmt->da, mgmt->bssid, tx_last_beacon);
++	ibss_dbg(sdata, "RX ProbeReq SA=%pM DA=%pM\n", mgmt->sa, mgmt->da);
++	ibss_dbg(sdata, "\tBSSID=%pM (tx_last_beacon=%d)\n",
++		 mgmt->bssid, tx_last_beacon);
+ 
+ 	if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da))
+ 		return;
diff --git a/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
index 19f0ff2ae970..b815f5f22a64 100644
--- a/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
+++ b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
@@ -119,7 +119,7 @@
  	if (local->hw.conf.power_level != power) {
  		changed |= IEEE80211_CONF_CHANGE_POWER;
  		local->hw.conf.power_level = power;
-@@ -592,6 +598,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
+@@ -611,6 +617,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
  					 IEEE80211_RADIOTAP_MCS_HAVE_BW;
  	local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
  					 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
diff --git a/package/kernel/mac80211/patches/976-ath10k-Limit-available-channels-via-DT-ieee80211-fre.patch b/package/kernel/mac80211/patches/976-ath10k-Limit-available-channels-via-DT-ieee80211-fre.patch
index 4d45ed8e328a..ea57d1114408 100644
--- a/package/kernel/mac80211/patches/976-ath10k-Limit-available-channels-via-DT-ieee80211-fre.patch
+++ b/package/kernel/mac80211/patches/976-ath10k-Limit-available-channels-via-DT-ieee80211-fre.patch
@@ -19,11 +19,9 @@ Forwarded: https://patchwork.kernel.org/patch/10549245/
  drivers/net/wireless/ath/ath10k/mac.c | 2 ++
  1 file changed, 2 insertions(+)
 
-diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
-index 95243b48a179..8ed37ffd320f 100644
 --- a/drivers/net/wireless/ath/ath10k/mac.c
 +++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -18,6 +18,7 @@
+@@ -17,6 +17,7 @@
  
  #include "mac.h"
  
@@ -31,7 +29,7 @@ index 95243b48a179..8ed37ffd320f 100644
  #include <net/mac80211.h>
  #include <linux/etherdevice.h>
  #include <linux/acpi.h>
-@@ -8306,6 +8307,7 @@ int ath10k_mac_register(struct ath10k *ar)
+@@ -8230,6 +8231,7 @@ int ath10k_mac_register(struct ath10k *a
  		ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
  	}
  
@@ -39,6 +37,3 @@ index 95243b48a179..8ed37ffd320f 100644
  	ath10k_mac_setup_ht_vht_cap(ar);
  
  	ar->hw->wiphy->interface_modes =
--- 
-2.11.0
-
-- 
2.17.1


_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list