From 77024a9d953d394b02226367357b0570c52b9119 Mon Sep 17 00:00:00 2001 From: Koen Vandeputte Date: Tue, 4 Sep 2018 15:09:48 +0200 Subject: [PATCH] mac80211: backport upstream fixes 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 --- ...-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 00000000000..ad282f98925 --- /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?= +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 +Tested-by: Ben Greear +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: Johannes Berg +--- + +--- 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 00000000000..e7b279af55e --- /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 +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 +Signed-off-by: Johannes Berg +--- + +--- 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 00000000000..66993839eef --- /dev/null +++ b/package/kernel/mac80211/patches/384-mac80211-avoid-kernel-panic-when-building-AMSDU-from.patch @@ -0,0 +1,102 @@ +From: Sara Sharon +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 +Reviewed-by: Lorenzo Bianconi +Signed-off-by: Johannes Berg +--- + +--- 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 00000000000..f4b14506a62 --- /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 +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 +Signed-off-by: Jouni Malinen +Signed-off-by: Johannes Berg +--- + +--- 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 00000000000..1d889022516 --- /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 +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 +[reword commit message to be more precise] +Signed-off-by: Johannes Berg +--- + +--- 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 00000000000..47942116bc8 --- /dev/null +++ b/package/kernel/mac80211/patches/387-mac80211-always-account-for-A-MSDU-header-changes.patch @@ -0,0 +1,51 @@ +From: Johannes Berg +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 +Acked-by: Lorenzo Bianconi +Signed-off-by: Johannes Berg +--- + +--- 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 00000000000..455fa298311 --- /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 +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 +Signed-off-by: Johannes Berg +--- + +--- 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 00000000000..8437aad6a62 --- /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 +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 +Signed-off-by: Johannes Berg +--- + +--- 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 00000000000..db2aa0443f7 --- /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 +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 ---| + +-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 +Signed-off-by: Luca Coelho +Signed-off-by: Johannes Berg +--- + +--- 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 00000000000..aa8db32e72e --- /dev/null +++ b/package/kernel/mac80211/patches/391-mac80211-Fix-station-bandwidth-setting-after-channel.patch @@ -0,0 +1,96 @@ +From: Ilan Peer +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 +Signed-off-by: Luca Coelho +Signed-off-by: Johannes Berg +--- + +--- 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 00000000000..74dd3d3775a --- /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 +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 +Signed-off-by: Luca Coelho +Signed-off-by: Johannes Berg +--- + +--- 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 00000000000..fb5b282d1d7 --- /dev/null +++ b/package/kernel/mac80211/patches/393-mac80211-shorten-the-IBSS-debug-messages.patch @@ -0,0 +1,74 @@ +From: Emmanuel Grumbach +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 +Signed-off-by: Luca Coelho +Signed-off-by: Johannes Berg +--- + +--- 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 19f0ff2ae97..b815f5f22a6 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 4d45ed8e328..ea57d111440 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 #include #include -@@ -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.30.2