From 66d0992cde3e0c5a0e81d2a92dd9da0fde8ca01a Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Wed, 14 Nov 2018 15:52:08 +0800 Subject: [PATCH] mac80211: fix spurious disconnections with powersave clients --- package/kernel/mac80211/Makefile | 4 +- ...-authentication-messages-for-late-ac.patch | 27 +++ ...ve-debug-log-after-buffer-increments.patch | 88 +++++++++ ...ck-da-enabled-first-in-sampling-rout.patch | 33 ++++ ...k-dynack-make-ewma-estimation-faster.patch | 139 ++++++++++++++ ...ath9k-dynack-remove-experimental-tag.patch | 22 +++ ...mfmac-add-CYW89342-mini-PCIe-device.patch} | 0 ...01-brcmfmac-fix-wrong-strnchr-usage.patch} | 0 ...-proper-support-of-160MHz-bandwidth.patch} | 0 ...-buffer-for-obtaining-firmware-capa.patch} | 0 ...set-but-not-used-variables-sfdoff-an.patch | 57 ++++++ ...reduce-timeout-for-action-frame-scan.patch | 67 +++++++ ...l-timeout-waiting-for-action-frame-o.patch | 79 ++++++++ ...fix-decoding-channel-info-for-160-MH.patch | 41 ++++ ...ve-firmware-loading-code-duplication.patch | 102 ++++++++++ ...recursion-from-firmware-load-error-h.patch | 126 ++++++++++++ ...port-for-first-trying-to-get-a-board.patch | 77 ++++++++ ...rd_type-used-for-nvram-file-selectio.patch | 77 ++++++++ ...rd_type-from-DMI-on-x86-based-machin.patch | 179 ++++++++++++++++++ ...cmfmac-Cleanup-brcmf_fw_request_done.patch | 41 ++++ ...port-for-getting-nvram-contents-from.patch | 132 +++++++++++++ ...-ccode-from-EFI-nvram-when-necessary.patch | 97 ++++++++++ ...elling-mistake-Retreiving-Retrieving.patch | 34 ++++ ...print-invalid-chanspec-when-WARN-ing.patch | 83 ++++++++ ...-register-wiphy-s-during-module_init.patch | 30 +-- ...-in-driver-tables-with-country-codes.patch | 6 +- ...tx-status-for-PS-stations-in-ieee802.patch | 26 +++ 27 files changed, 1549 insertions(+), 18 deletions(-) create mode 100644 package/kernel/mac80211/patches/ath/553-ath9k-dynack-use-authentication-messages-for-late-ac.patch create mode 100644 package/kernel/mac80211/patches/ath/554-ath9k-dynack-move-debug-log-after-buffer-increments.patch create mode 100644 package/kernel/mac80211/patches/ath/555-ath9k-dynack-check-da-enabled-first-in-sampling-rout.patch create mode 100644 package/kernel/mac80211/patches/ath/556-ath9k-dynack-make-ewma-estimation-faster.patch create mode 100644 package/kernel/mac80211/patches/ath/557-ath9k-dynack-remove-experimental-tag.patch rename package/kernel/mac80211/patches/brcm/{342-0001-brcmfmac-add-CYW89342-mini-PCIe-device.patch => 300-v4.20-0001-brcmfmac-add-CYW89342-mini-PCIe-device.patch} (100%) rename package/kernel/mac80211/patches/brcm/{344-0001-brcmfmac-fix-wrong-strnchr-usage.patch => 302-v4.20-0001-brcmfmac-fix-wrong-strnchr-usage.patch} (100%) rename package/kernel/mac80211/patches/brcm/{345-0001-brcmfmac-fix-for-proper-support-of-160MHz-bandwidth.patch => 304-v4.20-0001-brcmfmac-fix-for-proper-support-of-160MHz-bandwidth.patch} (100%) rename package/kernel/mac80211/patches/brcm/{345-0002-brcmfmac-increase-buffer-for-obtaining-firmware-capa.patch => 304-v4.20-0002-brcmfmac-increase-buffer-for-obtaining-firmware-capa.patch} (100%) create mode 100644 package/kernel/mac80211/patches/brcm/305-v4.20-0001-brcmfmac-remove-set-but-not-used-variables-sfdoff-an.patch create mode 100644 package/kernel/mac80211/patches/brcm/306-v4.20-0001-brcmfmac-reduce-timeout-for-action-frame-scan.patch create mode 100644 package/kernel/mac80211/patches/brcm/306-v4.20-0002-brcmfmac-fix-full-timeout-waiting-for-action-frame-o.patch create mode 100644 package/kernel/mac80211/patches/brcm/307-v4.20-0001-brcmutil-really-fix-decoding-channel-info-for-160-MH.patch create mode 100644 package/kernel/mac80211/patches/brcm/320-v4.21-0001-brcmfmac-Remove-firmware-loading-code-duplication.patch create mode 100644 package/kernel/mac80211/patches/brcm/320-v4.21-0002-brcmfmac-Remove-recursion-from-firmware-load-error-h.patch create mode 100644 package/kernel/mac80211/patches/brcm/320-v4.21-0003-brcmfmac-Add-support-for-first-trying-to-get-a-board.patch create mode 100644 package/kernel/mac80211/patches/brcm/320-v4.21-0004-brcmfmac-Set-board_type-used-for-nvram-file-selectio.patch create mode 100644 package/kernel/mac80211/patches/brcm/320-v4.21-0005-brcmfmac-Set-board_type-from-DMI-on-x86-based-machin.patch create mode 100644 package/kernel/mac80211/patches/brcm/320-v4.21-0006-brcmfmac-Cleanup-brcmf_fw_request_done.patch create mode 100644 package/kernel/mac80211/patches/brcm/321-v4.21-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch create mode 100644 package/kernel/mac80211/patches/brcm/321-v4.21-0002-brcmfmac-Fix-ccode-from-EFI-nvram-when-necessary.patch create mode 100644 package/kernel/mac80211/patches/brcm/322-v4.21-0001-brcmfmac-fix-spelling-mistake-Retreiving-Retrieving.patch create mode 100644 package/kernel/mac80211/patches/brcm/323-v4.21-0001-brcmutil-print-invalid-chanspec-when-WARN-ing.patch create mode 100644 package/kernel/mac80211/patches/subsys/379-mac80211-ignore-tx-status-for-PS-stations-in-ieee802.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 9e6a8f0e5..c322202b4 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=4.19-rc5-1 -PKG_RELEASE:=2 +PKG_RELEASE:=1 PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v4.19-rc5/ PKG_HASH:=5b61e64ea79d22bbac9e8612d5d5485974f223de00d4ec250b0faf4b7baf9957 @@ -208,7 +208,7 @@ endef define KernelPackage/hermes-pcmcia $(call KernelPackage/mac80211/Default) TITLE:=Hermes based PCMCIA adaptors - DEPENDS:=@PCMCIA_SUPPORT +kmod-hermes + DEPENDS:=@PCMCIA_SUPPORT +kmod-hermes +kmod-pcmcia-core FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco_cs.ko AUTOLOAD:=$(call AutoProbe,orinoco_cs) endef diff --git a/package/kernel/mac80211/patches/ath/553-ath9k-dynack-use-authentication-messages-for-late-ac.patch b/package/kernel/mac80211/patches/ath/553-ath9k-dynack-use-authentication-messages-for-late-ac.patch new file mode 100644 index 000000000..831c53476 --- /dev/null +++ b/package/kernel/mac80211/patches/ath/553-ath9k-dynack-use-authentication-messages-for-late-ac.patch @@ -0,0 +1,27 @@ +From: Lorenzo Bianconi +Date: Fri, 2 Nov 2018 21:49:55 +0100 +Subject: [PATCH] ath9k: dynack: use authentication messages for 'late' ack + +In order to properly support dynack in ad-hoc mode running +wpa_supplicant, take into account authentication frames for +'late ack' detection. This patch has been tested on devices +mounted on offshore high-voltage stations connected through +~24Km link + +Reported-by: Koen Vandeputte +Tested-by: Koen Vandeputte +Signed-off-by: Lorenzo Bianconi +--- + +--- a/drivers/net/wireless/ath/ath9k/dynack.c ++++ b/drivers/net/wireless/ath/ath9k/dynack.c +@@ -187,7 +187,8 @@ void ath_dynack_sample_tx_ts(struct ath_ + /* late ACK */ + if (ts->ts_status & ATH9K_TXERR_XRETRY) { + if (ieee80211_is_assoc_req(hdr->frame_control) || +- ieee80211_is_assoc_resp(hdr->frame_control)) { ++ ieee80211_is_assoc_resp(hdr->frame_control) || ++ ieee80211_is_auth(hdr->frame_control)) { + ath_dbg(common, DYNACK, "late ack\n"); + ath9k_hw_setslottime(ah, (LATEACK_TO - 3) / 2); + ath9k_hw_set_ack_timeout(ah, LATEACK_TO); diff --git a/package/kernel/mac80211/patches/ath/554-ath9k-dynack-move-debug-log-after-buffer-increments.patch b/package/kernel/mac80211/patches/ath/554-ath9k-dynack-move-debug-log-after-buffer-increments.patch new file mode 100644 index 000000000..a1d612660 --- /dev/null +++ b/package/kernel/mac80211/patches/ath/554-ath9k-dynack-move-debug-log-after-buffer-increments.patch @@ -0,0 +1,88 @@ +From: Lorenzo Bianconi +Date: Fri, 2 Nov 2018 21:49:56 +0100 +Subject: [PATCH] ath9k: dynack: move debug log after buffer increments + +Move debug log in ath_dynack_sample_tx_ts and ath_dynack_sample_ack_ts +after timestamp buffer head/tail increments in order to make debugging +more user friendly + +Tested-by: Koen Vandeputte +Signed-off-by: Lorenzo Bianconi +--- + +--- a/drivers/net/wireless/ath/ath9k/dynack.c ++++ b/drivers/net/wireless/ath/ath9k/dynack.c +@@ -171,11 +171,12 @@ static void ath_dynack_compute_to(struct + void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb, + struct ath_tx_status *ts) + { +- u8 ridx; + struct ieee80211_hdr *hdr; + struct ath_dynack *da = &ah->dynack; + struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ u32 dur = ts->duration; ++ u8 ridx; + + if ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !da->enabled) + return; +@@ -203,14 +204,13 @@ void ath_dynack_sample_tx_ts(struct ath_ + ridx = ts->ts_rateindex; + + da->st_rbf.ts[da->st_rbf.t_rb].tstamp = ts->ts_tstamp; +- da->st_rbf.ts[da->st_rbf.t_rb].dur = ts->duration; + ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_dest, hdr->addr1); + ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_src, hdr->addr2); + + if (!(info->status.rates[ridx].flags & IEEE80211_TX_RC_MCS)) { +- u32 phy, sifs; + const struct ieee80211_rate *rate; + struct ieee80211_tx_rate *rates = info->status.rates; ++ u32 phy; + + rate = &common->sbands[info->band].bitrates[rates[ridx].idx]; + if (info->band == NL80211_BAND_2GHZ && +@@ -219,19 +219,18 @@ void ath_dynack_sample_tx_ts(struct ath_ + else + phy = WLAN_RC_PHY_OFDM; + +- sifs = ath_dynack_get_sifs(ah, phy); +- da->st_rbf.ts[da->st_rbf.t_rb].dur -= sifs; ++ dur -= ath_dynack_get_sifs(ah, phy); + } +- +- ath_dbg(common, DYNACK, "{%pM} tx sample %u [dur %u][h %u-t %u]\n", +- hdr->addr1, da->st_rbf.ts[da->st_rbf.t_rb].tstamp, +- da->st_rbf.ts[da->st_rbf.t_rb].dur, da->st_rbf.h_rb, +- (da->st_rbf.t_rb + 1) % ATH_DYN_BUF); ++ da->st_rbf.ts[da->st_rbf.t_rb].dur = dur; + + INCR(da->st_rbf.t_rb, ATH_DYN_BUF); + if (da->st_rbf.t_rb == da->st_rbf.h_rb) + INCR(da->st_rbf.h_rb, ATH_DYN_BUF); + ++ ath_dbg(common, DYNACK, "{%pM} tx sample %u [dur %u][h %u-t %u]\n", ++ hdr->addr1, ts->ts_tstamp, dur, da->st_rbf.h_rb, ++ da->st_rbf.t_rb); ++ + ath_dynack_compute_to(ah); + + spin_unlock_bh(&da->qlock); +@@ -258,14 +257,13 @@ void ath_dynack_sample_ack_ts(struct ath + spin_lock_bh(&da->qlock); + da->ack_rbf.tstamp[da->ack_rbf.t_rb] = ts; + +- ath_dbg(common, DYNACK, "rx sample %u [h %u-t %u]\n", +- da->ack_rbf.tstamp[da->ack_rbf.t_rb], +- da->ack_rbf.h_rb, (da->ack_rbf.t_rb + 1) % ATH_DYN_BUF); +- + INCR(da->ack_rbf.t_rb, ATH_DYN_BUF); + if (da->ack_rbf.t_rb == da->ack_rbf.h_rb) + INCR(da->ack_rbf.h_rb, ATH_DYN_BUF); + ++ ath_dbg(common, DYNACK, "rx sample %u [h %u-t %u]\n", ++ ts, da->ack_rbf.h_rb, da->ack_rbf.t_rb); ++ + ath_dynack_compute_to(ah); + + spin_unlock_bh(&da->qlock); diff --git a/package/kernel/mac80211/patches/ath/555-ath9k-dynack-check-da-enabled-first-in-sampling-rout.patch b/package/kernel/mac80211/patches/ath/555-ath9k-dynack-check-da-enabled-first-in-sampling-rout.patch new file mode 100644 index 000000000..cc5cdf923 --- /dev/null +++ b/package/kernel/mac80211/patches/ath/555-ath9k-dynack-check-da-enabled-first-in-sampling-rout.patch @@ -0,0 +1,33 @@ +From: Lorenzo Bianconi +Date: Fri, 2 Nov 2018 21:49:57 +0100 +Subject: [PATCH] ath9k: dynack: check da->enabled first in sampling + routines + +Check da->enabled flag first in ath_dynack_sample_tx_ts and +ath_dynack_sample_ack_ts routines in order to avoid useless +processing + +Tested-by: Koen Vandeputte +Signed-off-by: Lorenzo Bianconi +--- + +--- a/drivers/net/wireless/ath/ath9k/dynack.c ++++ b/drivers/net/wireless/ath/ath9k/dynack.c +@@ -178,7 +178,7 @@ void ath_dynack_sample_tx_ts(struct ath_ + u32 dur = ts->duration; + u8 ridx; + +- if ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !da->enabled) ++ if (!da->enabled || (info->flags & IEEE80211_TX_CTL_NO_ACK)) + return; + + spin_lock_bh(&da->qlock); +@@ -251,7 +251,7 @@ void ath_dynack_sample_ack_ts(struct ath + struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + +- if (!ath_dynack_bssidmask(ah, hdr->addr1) || !da->enabled) ++ if (!da->enabled || !ath_dynack_bssidmask(ah, hdr->addr1)) + return; + + spin_lock_bh(&da->qlock); diff --git a/package/kernel/mac80211/patches/ath/556-ath9k-dynack-make-ewma-estimation-faster.patch b/package/kernel/mac80211/patches/ath/556-ath9k-dynack-make-ewma-estimation-faster.patch new file mode 100644 index 000000000..aaae8babc --- /dev/null +++ b/package/kernel/mac80211/patches/ath/556-ath9k-dynack-make-ewma-estimation-faster.patch @@ -0,0 +1,139 @@ +From: Lorenzo Bianconi +Date: Fri, 2 Nov 2018 21:49:58 +0100 +Subject: [PATCH] ath9k: dynack: make ewma estimation faster + +In order to make propagation time estimation faster, +use current sample as ewma output value during 'late ack' +tracking + +Tested-by: Koen Vandeputte +Signed-off-by: Lorenzo Bianconi +--- + +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -274,7 +274,7 @@ struct ath_node { + #endif + u8 key_idx[4]; + +- u32 ackto; ++ int ackto; + struct list_head list; + }; + +--- a/drivers/net/wireless/ath/ath9k/dynack.c ++++ b/drivers/net/wireless/ath/ath9k/dynack.c +@@ -29,9 +29,13 @@ + * ath_dynack_ewma - EWMA (Exponentially Weighted Moving Average) calculation + * + */ +-static inline u32 ath_dynack_ewma(u32 old, u32 new) ++static inline int ath_dynack_ewma(int old, int new) + { +- return (new * (EWMA_DIV - EWMA_LEVEL) + old * EWMA_LEVEL) / EWMA_DIV; ++ if (old > 0) ++ return (new * (EWMA_DIV - EWMA_LEVEL) + ++ old * EWMA_LEVEL) / EWMA_DIV; ++ else ++ return new; + } + + /** +@@ -82,10 +86,10 @@ static inline bool ath_dynack_bssidmask( + */ + static void ath_dynack_compute_ackto(struct ath_hw *ah) + { +- struct ath_node *an; +- u32 to = 0; +- struct ath_dynack *da = &ah->dynack; + struct ath_common *common = ath9k_hw_common(ah); ++ struct ath_dynack *da = &ah->dynack; ++ struct ath_node *an; ++ int to = 0; + + list_for_each_entry(an, &da->nodes, list) + if (an->ackto > to) +@@ -144,7 +148,8 @@ static void ath_dynack_compute_to(struct + an->ackto = ath_dynack_ewma(an->ackto, + ackto); + ath_dbg(ath9k_hw_common(ah), DYNACK, +- "%pM to %u\n", dst, an->ackto); ++ "%pM to %d [%u]\n", dst, ++ an->ackto, ackto); + if (time_is_before_jiffies(da->lto)) { + ath_dynack_compute_ackto(ah); + da->lto = jiffies + COMPUTE_TO; +@@ -166,10 +171,12 @@ static void ath_dynack_compute_to(struct + * @ah: ath hw + * @skb: socket buffer + * @ts: tx status info ++ * @sta: station pointer + * + */ + void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb, +- struct ath_tx_status *ts) ++ struct ath_tx_status *ts, ++ struct ieee80211_sta *sta) + { + struct ieee80211_hdr *hdr; + struct ath_dynack *da = &ah->dynack; +@@ -191,9 +198,16 @@ void ath_dynack_sample_tx_ts(struct ath_ + ieee80211_is_assoc_resp(hdr->frame_control) || + ieee80211_is_auth(hdr->frame_control)) { + ath_dbg(common, DYNACK, "late ack\n"); ++ + ath9k_hw_setslottime(ah, (LATEACK_TO - 3) / 2); + ath9k_hw_set_ack_timeout(ah, LATEACK_TO); + ath9k_hw_set_cts_timeout(ah, LATEACK_TO); ++ if (sta) { ++ struct ath_node *an; ++ ++ an = (struct ath_node *)sta->drv_priv; ++ an->ackto = -1; ++ } + da->lto = jiffies + LATEACK_DELAY; + } + +--- a/drivers/net/wireless/ath/ath9k/dynack.h ++++ b/drivers/net/wireless/ath/ath9k/dynack.h +@@ -86,7 +86,8 @@ void ath_dynack_node_deinit(struct ath_h + void ath_dynack_init(struct ath_hw *ah); + void ath_dynack_sample_ack_ts(struct ath_hw *ah, struct sk_buff *skb, u32 ts); + void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb, +- struct ath_tx_status *ts); ++ struct ath_tx_status *ts, ++ struct ieee80211_sta *sta); + #else + static inline void ath_dynack_init(struct ath_hw *ah) {} + static inline void ath_dynack_node_init(struct ath_hw *ah, +@@ -97,7 +98,8 @@ static inline void ath_dynack_sample_ack + struct sk_buff *skb, u32 ts) {} + static inline void ath_dynack_sample_tx_ts(struct ath_hw *ah, + struct sk_buff *skb, +- struct ath_tx_status *ts) {} ++ struct ath_tx_status *ts, ++ struct ieee80211_sta *sta) {} + #endif + + #endif /* DYNACK_H */ +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -629,7 +629,7 @@ static void ath_tx_complete_aggr(struct + if (bf == bf->bf_lastbf) + ath_dynack_sample_tx_ts(sc->sc_ah, + bf->bf_mpdu, +- ts); ++ ts, sta); + } + + ath_tx_complete_buf(sc, bf, txq, &bf_head, sta, ts, +@@ -773,7 +773,8 @@ static void ath_tx_process_buffer(struct + memcpy(info->control.rates, bf->rates, + sizeof(info->control.rates)); + ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); +- ath_dynack_sample_tx_ts(sc->sc_ah, bf->bf_mpdu, ts); ++ ath_dynack_sample_tx_ts(sc->sc_ah, bf->bf_mpdu, ts, ++ sta); + } + ath_tx_complete_buf(sc, bf, txq, bf_head, sta, ts, txok); + } else diff --git a/package/kernel/mac80211/patches/ath/557-ath9k-dynack-remove-experimental-tag.patch b/package/kernel/mac80211/patches/ath/557-ath9k-dynack-remove-experimental-tag.patch new file mode 100644 index 000000000..2e4cffd1f --- /dev/null +++ b/package/kernel/mac80211/patches/ath/557-ath9k-dynack-remove-experimental-tag.patch @@ -0,0 +1,22 @@ +From: Lorenzo Bianconi +Date: Fri, 2 Nov 2018 21:49:59 +0100 +Subject: [PATCH] ath9k: dynack: remove 'experimental' tag + +Remove experimental tag from dynack Kconfig entry since it has +been tested on outdoor 25Km links + +Tested-by: Koen Vandeputte +Signed-off-by: Lorenzo Bianconi +--- + +--- a/drivers/net/wireless/ath/ath9k/Kconfig ++++ b/drivers/net/wireless/ath/ath9k/Kconfig +@@ -132,7 +132,7 @@ config ATH9K_DFS_CERTIFIED + except increase code size. + + config ATH9K_DYNACK +- bool "Atheros ath9k ACK timeout estimation algorithm (EXPERIMENTAL)" ++ bool "Atheros ath9k ACK timeout estimation algorithm" + depends on ATH9K + default n + ---help--- diff --git a/package/kernel/mac80211/patches/brcm/342-0001-brcmfmac-add-CYW89342-mini-PCIe-device.patch b/package/kernel/mac80211/patches/brcm/300-v4.20-0001-brcmfmac-add-CYW89342-mini-PCIe-device.patch similarity index 100% rename from package/kernel/mac80211/patches/brcm/342-0001-brcmfmac-add-CYW89342-mini-PCIe-device.patch rename to package/kernel/mac80211/patches/brcm/300-v4.20-0001-brcmfmac-add-CYW89342-mini-PCIe-device.patch diff --git a/package/kernel/mac80211/patches/brcm/344-0001-brcmfmac-fix-wrong-strnchr-usage.patch b/package/kernel/mac80211/patches/brcm/302-v4.20-0001-brcmfmac-fix-wrong-strnchr-usage.patch similarity index 100% rename from package/kernel/mac80211/patches/brcm/344-0001-brcmfmac-fix-wrong-strnchr-usage.patch rename to package/kernel/mac80211/patches/brcm/302-v4.20-0001-brcmfmac-fix-wrong-strnchr-usage.patch diff --git a/package/kernel/mac80211/patches/brcm/345-0001-brcmfmac-fix-for-proper-support-of-160MHz-bandwidth.patch b/package/kernel/mac80211/patches/brcm/304-v4.20-0001-brcmfmac-fix-for-proper-support-of-160MHz-bandwidth.patch similarity index 100% rename from package/kernel/mac80211/patches/brcm/345-0001-brcmfmac-fix-for-proper-support-of-160MHz-bandwidth.patch rename to package/kernel/mac80211/patches/brcm/304-v4.20-0001-brcmfmac-fix-for-proper-support-of-160MHz-bandwidth.patch diff --git a/package/kernel/mac80211/patches/brcm/345-0002-brcmfmac-increase-buffer-for-obtaining-firmware-capa.patch b/package/kernel/mac80211/patches/brcm/304-v4.20-0002-brcmfmac-increase-buffer-for-obtaining-firmware-capa.patch similarity index 100% rename from package/kernel/mac80211/patches/brcm/345-0002-brcmfmac-increase-buffer-for-obtaining-firmware-capa.patch rename to package/kernel/mac80211/patches/brcm/304-v4.20-0002-brcmfmac-increase-buffer-for-obtaining-firmware-capa.patch diff --git a/package/kernel/mac80211/patches/brcm/305-v4.20-0001-brcmfmac-remove-set-but-not-used-variables-sfdoff-an.patch b/package/kernel/mac80211/patches/brcm/305-v4.20-0001-brcmfmac-remove-set-but-not-used-variables-sfdoff-an.patch new file mode 100644 index 000000000..192ed1a77 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/305-v4.20-0001-brcmfmac-remove-set-but-not-used-variables-sfdoff-an.patch @@ -0,0 +1,57 @@ +From a8254fa4ba60b85829b6e5ede6564f81cd70d59f Mon Sep 17 00:00:00 2001 +From: YueHaibing +Date: Tue, 11 Sep 2018 11:24:04 +0800 +Subject: [PATCH] brcmfmac: remove set but not used variables 'sfdoff' and + 'pad_size' + +Fixes gcc '-Wunused-but-set-variable' warning: + +drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c: In function 'brcmf_sdio_rxglom': +drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:1466:11: warning: + variable 'sfdoff' set but not used [-Wunused-but-set-variable] + +drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c: In function 'brcmf_sdio_bus_preinit': +drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:3408:7: warning: + variable 'pad_size' set but not used [-Wunused-but-set-variable] + +Signed-off-by: YueHaibing +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -1463,7 +1463,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf + struct sk_buff *pfirst, *pnext; + + int errcode; +- u8 doff, sfdoff; ++ u8 doff; + + struct brcmf_sdio_hdrinfo rd_new; + +@@ -1597,7 +1597,6 @@ static u8 brcmf_sdio_rxglom(struct brcmf + + /* Remove superframe header, remember offset */ + skb_pull(pfirst, rd_new.dat_offset); +- sfdoff = rd_new.dat_offset; + num = 0; + + /* Validate all the subframe headers */ +@@ -3405,7 +3404,6 @@ static int brcmf_sdio_bus_preinit(struct + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct brcmf_sdio *bus = sdiodev->bus; + struct brcmf_core *core = bus->sdio_core; +- uint pad_size; + u32 value; + int err; + +@@ -3448,7 +3446,6 @@ static int brcmf_sdio_bus_preinit(struct + if (sdiodev->sg_support) { + bus->txglom = false; + value = 1; +- pad_size = bus->sdiodev->func2->cur_blksize << 1; + err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom", + &value, sizeof(u32)); + if (err < 0) { diff --git a/package/kernel/mac80211/patches/brcm/306-v4.20-0001-brcmfmac-reduce-timeout-for-action-frame-scan.patch b/package/kernel/mac80211/patches/brcm/306-v4.20-0001-brcmfmac-reduce-timeout-for-action-frame-scan.patch new file mode 100644 index 000000000..a71c1aee0 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/306-v4.20-0001-brcmfmac-reduce-timeout-for-action-frame-scan.patch @@ -0,0 +1,67 @@ +From edb6d6885bef82d1eac432dbeca9fbf4ec349d7e Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +Date: Thu, 27 Sep 2018 14:59:44 +0000 +Subject: [PATCH] brcmfmac: reduce timeout for action frame scan + +Finding a common channel to send an action frame out is required for +some action types. Since a loop with several scan retry is used to find +the channel, a short wait time could be considered for each attempt. +This patch reduces the wait time from 1500 to 450 msec for each action +frame scan. + +This patch fixes the WFA p2p certification 5.1.20 failure caused by the +long action frame send time. + +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -74,7 +74,7 @@ + #define P2P_AF_MAX_WAIT_TIME msecs_to_jiffies(2000) + #define P2P_INVALID_CHANNEL -1 + #define P2P_CHANNEL_SYNC_RETRY 5 +-#define P2P_AF_FRM_SCAN_MAX_WAIT msecs_to_jiffies(1500) ++#define P2P_AF_FRM_SCAN_MAX_WAIT msecs_to_jiffies(450) + #define P2P_DEFAULT_SLEEP_TIME_VSDB 200 + + /* WiFi P2P Public Action Frame OUI Subtypes */ +@@ -1134,7 +1134,6 @@ static s32 brcmf_p2p_af_searching_channe + { + struct afx_hdl *afx_hdl = &p2p->afx_hdl; + struct brcmf_cfg80211_vif *pri_vif; +- unsigned long duration; + s32 retry; + + brcmf_dbg(TRACE, "Enter\n"); +@@ -1150,7 +1149,6 @@ static s32 brcmf_p2p_af_searching_channe + * pending action frame tx is cancelled. + */ + retry = 0; +- duration = msecs_to_jiffies(P2P_AF_FRM_SCAN_MAX_WAIT); + while ((retry < P2P_CHANNEL_SYNC_RETRY) && + (afx_hdl->peer_chan == P2P_INVALID_CHANNEL)) { + afx_hdl->is_listen = false; +@@ -1158,7 +1156,8 @@ static s32 brcmf_p2p_af_searching_channe + retry); + /* search peer on peer's listen channel */ + schedule_work(&afx_hdl->afx_work); +- wait_for_completion_timeout(&afx_hdl->act_frm_scan, duration); ++ wait_for_completion_timeout(&afx_hdl->act_frm_scan, ++ P2P_AF_FRM_SCAN_MAX_WAIT); + if ((afx_hdl->peer_chan != P2P_INVALID_CHANNEL) || + (!test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, + &p2p->status))) +@@ -1171,7 +1170,7 @@ static s32 brcmf_p2p_af_searching_channe + afx_hdl->is_listen = true; + schedule_work(&afx_hdl->afx_work); + wait_for_completion_timeout(&afx_hdl->act_frm_scan, +- duration); ++ P2P_AF_FRM_SCAN_MAX_WAIT); + } + if ((afx_hdl->peer_chan != P2P_INVALID_CHANNEL) || + (!test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, diff --git a/package/kernel/mac80211/patches/brcm/306-v4.20-0002-brcmfmac-fix-full-timeout-waiting-for-action-frame-o.patch b/package/kernel/mac80211/patches/brcm/306-v4.20-0002-brcmfmac-fix-full-timeout-waiting-for-action-frame-o.patch new file mode 100644 index 000000000..ef2d0934f --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/306-v4.20-0002-brcmfmac-fix-full-timeout-waiting-for-action-frame-o.patch @@ -0,0 +1,79 @@ +From fbf07000960d9c8a13fdc17c6de0230d681c7543 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +Date: Thu, 27 Sep 2018 14:59:49 +0000 +Subject: [PATCH] brcmfmac: fix full timeout waiting for action frame + on-channel tx + +The driver sends an action frame down and waits for a completion signal +triggered by the received BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE event +to continue the process. However, the action frame could be transmitted +either on the current channel or on an off channel. For the on-channel +case, only BRCMF_E_ACTION_FRAME_COMPLETE event will be received when +the frame is transmitted, which make the driver always wait a full +timeout duration. This patch has the completion signal be triggered by +receiving the BRCMF_E_ACTION_FRAME_COMPLETE event for the on-channel +case. + +This change fixes WFA p2p certification 5.1.19 failure. + +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 17 +++++++++++++++-- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h | 2 ++ + 2 files changed, 17 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -1457,10 +1457,12 @@ int brcmf_p2p_notify_action_tx_complete( + return 0; + + if (e->event_code == BRCMF_E_ACTION_FRAME_COMPLETE) { +- if (e->status == BRCMF_E_STATUS_SUCCESS) ++ if (e->status == BRCMF_E_STATUS_SUCCESS) { + set_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, + &p2p->status); +- else { ++ if (!p2p->wait_for_offchan_complete) ++ complete(&p2p->send_af_done); ++ } else { + set_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status); + /* If there is no ack, we don't need to wait for + * WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE event +@@ -1511,6 +1513,17 @@ static s32 brcmf_p2p_tx_action_frame(str + p2p->af_sent_channel = le32_to_cpu(af_params->channel); + p2p->af_tx_sent_jiffies = jiffies; + ++ if (test_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status) && ++ p2p->af_sent_channel == ++ ieee80211_frequency_to_channel(p2p->remain_on_channel.center_freq)) ++ p2p->wait_for_offchan_complete = false; ++ else ++ p2p->wait_for_offchan_complete = true; ++ ++ brcmf_dbg(TRACE, "Waiting for %s tx completion event\n", ++ (p2p->wait_for_offchan_complete) ? ++ "off-channel" : "on-channel"); ++ + timeout = wait_for_completion_timeout(&p2p->send_af_done, + P2P_AF_MAX_WAIT_TIME); + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h +@@ -124,6 +124,7 @@ struct afx_hdl { + * @gon_req_action: about to send go negotiation requets frame. + * @block_gon_req_tx: drop tx go negotiation requets frame. + * @p2pdev_dynamically: is p2p device if created by module param or supplicant. ++ * @wait_for_offchan_complete: wait for off-channel tx completion event. + */ + struct brcmf_p2p_info { + struct brcmf_cfg80211_info *cfg; +@@ -144,6 +145,7 @@ struct brcmf_p2p_info { + bool gon_req_action; + bool block_gon_req_tx; + bool p2pdev_dynamically; ++ bool wait_for_offchan_complete; + }; + + s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced); diff --git a/package/kernel/mac80211/patches/brcm/307-v4.20-0001-brcmutil-really-fix-decoding-channel-info-for-160-MH.patch b/package/kernel/mac80211/patches/brcm/307-v4.20-0001-brcmutil-really-fix-decoding-channel-info-for-160-MH.patch new file mode 100644 index 000000000..154664c85 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/307-v4.20-0001-brcmutil-really-fix-decoding-channel-info-for-160-MH.patch @@ -0,0 +1,41 @@ +From 3401d42c7ea2d064d15c66698ff8eb96553179ce Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 26 Oct 2018 12:50:39 +0200 +Subject: [PATCH] brcmutil: really fix decoding channel info for 160 MHz + bandwidth +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Previous commit /adding/ support for 160 MHz chanspecs was incomplete. +It didn't set bandwidth info and didn't extract control channel info. As +the result it was also using uninitialized "sb" var. + +This change has been tested for two chanspecs found to be reported by +some devices/firmwares: +1) 60/160 (0xee32) + Before: chnum:50 control_ch_num:36 + After: chnum:50 control_ch_num:60 +2) 120/160 (0xed72) + Before: chnum:114 control_ch_num:100 + After: chnum:114 control_ch_num:120 + +Fixes: 330994e8e8ec ("brcmfmac: fix for proper support of 160MHz bandwidth") +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c +@@ -193,6 +193,9 @@ static void brcmu_d11ac_decchspec(struct + } + break; + case BRCMU_CHSPEC_D11AC_BW_160: ++ ch->bw = BRCMU_CHAN_BW_160; ++ ch->sb = brcmu_maskget16(ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK, ++ BRCMU_CHSPEC_D11AC_SB_SHIFT); + switch (ch->sb) { + case BRCMU_CHAN_SB_LLL: + ch->control_ch_num -= CH_70MHZ_APART; diff --git a/package/kernel/mac80211/patches/brcm/320-v4.21-0001-brcmfmac-Remove-firmware-loading-code-duplication.patch b/package/kernel/mac80211/patches/brcm/320-v4.21-0001-brcmfmac-Remove-firmware-loading-code-duplication.patch new file mode 100644 index 000000000..eca15a516 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/320-v4.21-0001-brcmfmac-Remove-firmware-loading-code-duplication.patch @@ -0,0 +1,102 @@ +From a1a3b762163868ad07a4499a73df324f40d5ab0b Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 10 Oct 2018 13:00:58 +0200 +Subject: [PATCH] brcmfmac: Remove firmware-loading code duplication + +brcmf_fw_request_next_item and brcmf_fw_request_done both have identical +code to complete the fw-request depending on the item-type. + +This commit adds a new brcmf_fw_complete_request helper removing this code +duplication. + +Signed-off-by: Hans de Goede +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/firmware.c | 62 +++++++++++----------- + 1 file changed, 31 insertions(+), 31 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -504,6 +504,34 @@ fail: + return -ENOENT; + } + ++static int brcmf_fw_complete_request(const struct firmware *fw, ++ struct brcmf_fw *fwctx) ++{ ++ struct brcmf_fw_item *cur = &fwctx->req->items[fwctx->curpos]; ++ int ret = 0; ++ ++ brcmf_dbg(TRACE, "firmware %s %sfound\n", cur->path, fw ? "" : "not "); ++ ++ switch (cur->type) { ++ case BRCMF_FW_TYPE_NVRAM: ++ ret = brcmf_fw_request_nvram_done(fw, fwctx); ++ break; ++ case BRCMF_FW_TYPE_BINARY: ++ if (fw) ++ cur->binary = fw; ++ else ++ ret = -ENOENT; ++ break; ++ default: ++ /* something fishy here so bail out early */ ++ brcmf_err("unknown fw type: %d\n", cur->type); ++ release_firmware(fw); ++ ret = -EINVAL; ++ } ++ ++ return (cur->flags & BRCMF_FW_REQF_OPTIONAL) ? 0 : ret; ++} ++ + static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async) + { + struct brcmf_fw_item *cur; +@@ -525,15 +553,7 @@ static int brcmf_fw_request_next_item(st + if (ret < 0) { + brcmf_fw_request_done(NULL, fwctx); + } else if (!async && fw) { +- brcmf_dbg(TRACE, "firmware %s %sfound\n", cur->path, +- fw ? "" : "not "); +- if (cur->type == BRCMF_FW_TYPE_BINARY) +- cur->binary = fw; +- else if (cur->type == BRCMF_FW_TYPE_NVRAM) +- brcmf_fw_request_nvram_done(fw, fwctx); +- else +- release_firmware(fw); +- ++ brcmf_fw_complete_request(fw, fwctx); + return -EAGAIN; + } + return 0; +@@ -547,28 +567,8 @@ static void brcmf_fw_request_done(const + + cur = &fwctx->req->items[fwctx->curpos]; + +- brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path, +- fw ? "" : "not "); +- +- if (!fw) +- ret = -ENOENT; +- +- switch (cur->type) { +- case BRCMF_FW_TYPE_NVRAM: +- ret = brcmf_fw_request_nvram_done(fw, fwctx); +- break; +- case BRCMF_FW_TYPE_BINARY: +- cur->binary = fw; +- break; +- default: +- /* something fishy here so bail out early */ +- brcmf_err("unknown fw type: %d\n", cur->type); +- release_firmware(fw); +- ret = -EINVAL; +- goto fail; +- } +- +- if (ret < 0 && !(cur->flags & BRCMF_FW_REQF_OPTIONAL)) ++ ret = brcmf_fw_complete_request(fw, fwctx); ++ if (ret < 0) + goto fail; + + do { diff --git a/package/kernel/mac80211/patches/brcm/320-v4.21-0002-brcmfmac-Remove-recursion-from-firmware-load-error-h.patch b/package/kernel/mac80211/patches/brcm/320-v4.21-0002-brcmfmac-Remove-recursion-from-firmware-load-error-h.patch new file mode 100644 index 000000000..f3da1df54 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/320-v4.21-0002-brcmfmac-Remove-recursion-from-firmware-load-error-h.patch @@ -0,0 +1,126 @@ +From 5b587496dc63595b71265d986ce69728c2724370 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 10 Oct 2018 13:00:59 +0200 +Subject: [PATCH] brcmfmac: Remove recursion from firmware load error handling + +Before this commit brcmf_fw_request_done would call +brcmf_fw_request_next_item to load the next item, which on an error would +call brcmf_fw_request_done, which if the error is recoverable (*) will +then continue calling brcmf_fw_request_next_item for the next item again +which on an error will call brcmf_fw_request_done again... + +This does not blow up because we only have a limited number of items so +we never recurse too deep. But the recursion is still quite ugly and +frankly is giving me a headache, so lets fix this. + +This commit fixes this by removing brcmf_fw_request_next_item and by +making brcmf_fw_get_firmwares and brcmf_fw_request_done directly call +firmware_request_nowait resp. firmware_request themselves. + +*) brcmf_fw_request_nvram_done fallback path succeeds or + BRCMF_FW_REQF_OPTIONAL is set + +Signed-off-by: Hans de Goede +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/firmware.c | 65 +++++++--------------- + 1 file changed, 19 insertions(+), 46 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -532,33 +532,6 @@ static int brcmf_fw_complete_request(con + return (cur->flags & BRCMF_FW_REQF_OPTIONAL) ? 0 : ret; + } + +-static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async) +-{ +- struct brcmf_fw_item *cur; +- const struct firmware *fw = NULL; +- int ret; +- +- cur = &fwctx->req->items[fwctx->curpos]; +- +- brcmf_dbg(TRACE, "%srequest for %s\n", async ? "async " : "", +- cur->path); +- +- if (async) +- ret = request_firmware_nowait(THIS_MODULE, true, cur->path, +- fwctx->dev, GFP_KERNEL, fwctx, +- brcmf_fw_request_done); +- else +- ret = request_firmware(&fw, cur->path, fwctx->dev); +- +- if (ret < 0) { +- brcmf_fw_request_done(NULL, fwctx); +- } else if (!async && fw) { +- brcmf_fw_complete_request(fw, fwctx); +- return -EAGAIN; +- } +- return 0; +-} +- + static void brcmf_fw_request_done(const struct firmware *fw, void *ctx) + { + struct brcmf_fw *fwctx = ctx; +@@ -568,26 +541,19 @@ static void brcmf_fw_request_done(const + cur = &fwctx->req->items[fwctx->curpos]; + + ret = brcmf_fw_complete_request(fw, fwctx); +- if (ret < 0) +- goto fail; +- +- do { +- if (++fwctx->curpos == fwctx->req->n_items) { +- ret = 0; +- goto done; +- } + +- ret = brcmf_fw_request_next_item(fwctx, false); +- } while (ret == -EAGAIN); +- +- return; ++ while (ret == 0 && ++fwctx->curpos < fwctx->req->n_items) { ++ cur = &fwctx->req->items[fwctx->curpos]; ++ request_firmware(&fw, cur->path, fwctx->dev); ++ ret = brcmf_fw_complete_request(fw, ctx); ++ } + +-fail: +- brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret, +- dev_name(fwctx->dev), cur->path); +- brcmf_fw_free_request(fwctx->req); +- fwctx->req = NULL; +-done: ++ if (ret) { ++ brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret, ++ dev_name(fwctx->dev), cur->path); ++ brcmf_fw_free_request(fwctx->req); ++ fwctx->req = NULL; ++ } + fwctx->done(fwctx->dev, ret, fwctx->req); + kfree(fwctx); + } +@@ -611,7 +577,9 @@ int brcmf_fw_get_firmwares(struct device + void (*fw_cb)(struct device *dev, int err, + struct brcmf_fw_request *req)) + { ++ struct brcmf_fw_item *first = &req->items[0]; + struct brcmf_fw *fwctx; ++ int ret; + + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev)); + if (!fw_cb) +@@ -628,7 +596,12 @@ int brcmf_fw_get_firmwares(struct device + fwctx->req = req; + fwctx->done = fw_cb; + +- brcmf_fw_request_next_item(fwctx, true); ++ ret = request_firmware_nowait(THIS_MODULE, true, first->path, ++ fwctx->dev, GFP_KERNEL, fwctx, ++ brcmf_fw_request_done); ++ if (ret < 0) ++ brcmf_fw_request_done(NULL, fwctx); ++ + return 0; + } + diff --git a/package/kernel/mac80211/patches/brcm/320-v4.21-0003-brcmfmac-Add-support-for-first-trying-to-get-a-board.patch b/package/kernel/mac80211/patches/brcm/320-v4.21-0003-brcmfmac-Add-support-for-first-trying-to-get-a-board.patch new file mode 100644 index 000000000..727dcbe85 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/320-v4.21-0003-brcmfmac-Add-support-for-first-trying-to-get-a-board.patch @@ -0,0 +1,77 @@ +From eae8e50669e15002b195177212a6e25afbe7cf4d Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 10 Oct 2018 13:01:00 +0200 +Subject: [PATCH] brcmfmac: Add support for first trying to get a board + specific nvram file + +The nvram files which some brcmfmac chips need are board-specific. To be +able to distribute these as part of linux-firmware, so that devices with +such a wifi chip will work OOTB, multiple (one per board) versions must +co-exist under /lib/firmware. + +This commit adds support for callers of the brcmfmac/firmware.c code to +pass in a board_type parameter through the request structure. + +If that parameter is set then the code will first try to load +chipmodel.board_type.txt before falling back to the old chipmodel.txt name. + +Signed-off-by: Hans de Goede +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/firmware.c | 27 +++++++++++++++++++++- + .../broadcom/brcm80211/brcmfmac/firmware.h | 1 + + 2 files changed, 27 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -532,6 +532,31 @@ static int brcmf_fw_complete_request(con + return (cur->flags & BRCMF_FW_REQF_OPTIONAL) ? 0 : ret; + } + ++static int brcmf_fw_request_firmware(const struct firmware **fw, ++ struct brcmf_fw *fwctx) ++{ ++ struct brcmf_fw_item *cur = &fwctx->req->items[fwctx->curpos]; ++ int ret; ++ ++ /* nvram files are board-specific, first try a board-specific path */ ++ if (cur->type == BRCMF_FW_TYPE_NVRAM && fwctx->req->board_type) { ++ char alt_path[BRCMF_FW_NAME_LEN]; ++ ++ strlcpy(alt_path, cur->path, BRCMF_FW_NAME_LEN); ++ /* strip .txt at the end */ ++ alt_path[strlen(alt_path) - 4] = 0; ++ strlcat(alt_path, ".", BRCMF_FW_NAME_LEN); ++ strlcat(alt_path, fwctx->req->board_type, BRCMF_FW_NAME_LEN); ++ strlcat(alt_path, ".txt", BRCMF_FW_NAME_LEN); ++ ++ ret = request_firmware(fw, alt_path, fwctx->dev); ++ if (ret == 0) ++ return ret; ++ } ++ ++ return request_firmware(fw, cur->path, fwctx->dev); ++} ++ + static void brcmf_fw_request_done(const struct firmware *fw, void *ctx) + { + struct brcmf_fw *fwctx = ctx; +@@ -544,7 +569,7 @@ static void brcmf_fw_request_done(const + + while (ret == 0 && ++fwctx->curpos < fwctx->req->n_items) { + cur = &fwctx->req->items[fwctx->curpos]; +- request_firmware(&fw, cur->path, fwctx->dev); ++ brcmf_fw_request_firmware(&fw, fwctx); + ret = brcmf_fw_complete_request(fw, ctx); + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h +@@ -70,6 +70,7 @@ struct brcmf_fw_request { + u16 domain_nr; + u16 bus_nr; + u32 n_items; ++ const char *board_type; + struct brcmf_fw_item items[0]; + }; + diff --git a/package/kernel/mac80211/patches/brcm/320-v4.21-0004-brcmfmac-Set-board_type-used-for-nvram-file-selectio.patch b/package/kernel/mac80211/patches/brcm/320-v4.21-0004-brcmfmac-Set-board_type-used-for-nvram-file-selectio.patch new file mode 100644 index 000000000..a33ceaa21 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/320-v4.21-0004-brcmfmac-Set-board_type-used-for-nvram-file-selectio.patch @@ -0,0 +1,77 @@ +From 0ad4b55b2f29784f93875e6231bf57cd233624a2 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 10 Oct 2018 13:01:01 +0200 +Subject: [PATCH] brcmfmac: Set board_type used for nvram file selection to + machine-compatible + +For of/devicetree using machines, set the board_type used for nvram file +selection to the first string listed in the top-level's node compatible +string, aka the machine-compatible as used by of_machine_is_compatible(). + +The board_type setting is used to load the board-specific nvram file with +a board-specific name so that we can ship files for each supported board +in linux-firmware. + +Signed-off-by: Hans de Goede +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h | 1 + + drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c | 11 ++++++++++- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 1 + + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 1 + + 4 files changed, 13 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -59,6 +59,7 @@ struct brcmf_mp_device { + bool iapp; + bool ignore_probe_fail; + struct brcmfmac_pd_cc *country_codes; ++ const char *board_type; + union { + struct brcmfmac_sdio_pd sdio; + } bus; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +@@ -27,11 +27,20 @@ void brcmf_of_probe(struct device *dev, + struct brcmf_mp_device *settings) + { + struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio; +- struct device_node *np = dev->of_node; ++ struct device_node *root, *np = dev->of_node; ++ struct property *prop; + int irq; + u32 irqf; + u32 val; + ++ /* Set board-type to the first string of the machine compatible prop */ ++ root = of_find_node_by_path("/"); ++ if (root) { ++ prop = of_find_property(root, "compatible", NULL); ++ settings->board_type = of_prop_next_string(prop, NULL); ++ of_node_put(root); ++ } ++ + if (!np || bus_type != BRCMF_BUSTYPE_SDIO || + !of_device_is_compatible(np, "brcm,bcm4329-fmac")) + return; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1785,6 +1785,7 @@ brcmf_pcie_prepare_fw_request(struct brc + fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY; + fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; + fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL; ++ fwreq->board_type = devinfo->settings->board_type; + /* NVRAM reserves PCI domain 0 for Broadcom's SDK faked bus */ + fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus) + 1; + fwreq->bus_nr = devinfo->pdev->bus->number; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -4174,6 +4174,7 @@ brcmf_sdio_prepare_fw_request(struct brc + + fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY; + fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; ++ fwreq->board_type = bus->sdiodev->settings->board_type; + + return fwreq; + } diff --git a/package/kernel/mac80211/patches/brcm/320-v4.21-0005-brcmfmac-Set-board_type-from-DMI-on-x86-based-machin.patch b/package/kernel/mac80211/patches/brcm/320-v4.21-0005-brcmfmac-Set-board_type-from-DMI-on-x86-based-machin.patch new file mode 100644 index 000000000..25426e3f1 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/320-v4.21-0005-brcmfmac-Set-board_type-from-DMI-on-x86-based-machin.patch @@ -0,0 +1,179 @@ +From bd1e82bb420adf4ad7cd468d8a482cde622dd69d Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 10 Oct 2018 13:01:02 +0200 +Subject: [PATCH] brcmfmac: Set board_type from DMI on x86 based machines + +For x86 based machines, set the board_type used for nvram file selection +based on the DMI sys-vendor and product-name strings. + +Since on some models these strings are too generic, this commit also adds +a quirk table overriding the strings for models listed in that table. + +The board_type setting is used to load the board-specific nvram file with +a board-specific name so that we can ship files for each supported board +in linux-firmware. + +Signed-off-by: Hans de Goede +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/Makefile | 2 + + .../wireless/broadcom/brcm80211/brcmfmac/common.c | 3 +- + .../wireless/broadcom/brcm80211/brcmfmac/common.h | 7 ++ + .../net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | 116 +++++++++++++++++++++ + 4 files changed, 127 insertions(+), 1 deletion(-) + create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile +@@ -54,3 +54,5 @@ brcmfmac-$(CPTCFG_BRCM_TRACING) += \ + tracepoint.o + brcmfmac-$(CONFIG_OF) += \ + of.o ++brcmfmac-$(CONFIG_DMI) += \ ++ dmi.o +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -448,8 +448,9 @@ struct brcmf_mp_device *brcmf_get_module + } + } + if (!found) { +- /* No platform data for this device, try OF (Open Firwmare) */ ++ /* No platform data for this device, try OF and DMI data */ + brcmf_of_probe(dev, bus_type, settings); ++ brcmf_dmi_probe(settings, chip, chiprev); + } + return settings; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -75,4 +75,11 @@ void brcmf_release_module_param(struct b + /* Sets dongle media info (drv_version, mac address). */ + int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); + ++#ifdef CONFIG_DMI ++void brcmf_dmi_probe(struct brcmf_mp_device *settings, u32 chip, u32 chiprev); ++#else ++static inline void ++brcmf_dmi_probe(struct brcmf_mp_device *settings, u32 chip, u32 chiprev) {} ++#endif ++ + #endif /* BRCMFMAC_COMMON_H */ +--- /dev/null ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +@@ -0,0 +1,116 @@ ++/* ++ * Copyright 2018 Hans de Goede ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include ++#include ++#include "core.h" ++#include "common.h" ++#include "brcm_hw_ids.h" ++ ++/* The DMI data never changes so we can use a static buf for this */ ++static char dmi_board_type[128]; ++ ++struct brcmf_dmi_data { ++ u32 chip; ++ u32 chiprev; ++ const char *board_type; ++}; ++ ++/* NOTE: Please keep all entries sorted alphabetically */ ++ ++static const struct brcmf_dmi_data gpd_win_pocket_data = { ++ BRCM_CC_4356_CHIP_ID, 2, "gpd-win-pocket" ++}; ++ ++static const struct brcmf_dmi_data jumper_ezpad_mini3_data = { ++ BRCM_CC_43430_CHIP_ID, 0, "jumper-ezpad-mini3" ++}; ++ ++static const struct brcmf_dmi_data meegopad_t08_data = { ++ BRCM_CC_43340_CHIP_ID, 2, "meegopad-t08" ++}; ++ ++static const struct dmi_system_id dmi_platform_data[] = { ++ { ++ /* Match for the GPDwin which unfortunately uses somewhat ++ * generic dmi strings, which is why we test for 4 strings. ++ * Comparing against 23 other byt/cht boards, board_vendor ++ * and board_name are unique to the GPDwin, where as only one ++ * other board has the same board_serial and 3 others have ++ * the same default product_name. Also the GPDwin is the ++ * only device to have both board_ and product_name not set. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), ++ DMI_MATCH(DMI_BOARD_NAME, "Default string"), ++ DMI_MATCH(DMI_BOARD_SERIAL, "Default string"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), ++ }, ++ .driver_data = (void *)&gpd_win_pocket_data, ++ }, ++ { ++ /* Jumper EZpad mini3 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "CherryTrail"), ++ /* jumperx.T87.KFBNEEA02 with the version-nr dropped */ ++ DMI_MATCH(DMI_BIOS_VERSION, "jumperx.T87.KFBNEEA"), ++ }, ++ .driver_data = (void *)&jumper_ezpad_mini3_data, ++ }, ++ { ++ /* Meegopad T08 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Default string"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), ++ DMI_MATCH(DMI_BOARD_NAME, "T3 MRD"), ++ DMI_MATCH(DMI_BOARD_VERSION, "V1.1"), ++ }, ++ .driver_data = (void *)&meegopad_t08_data, ++ }, ++ {} ++}; ++ ++void brcmf_dmi_probe(struct brcmf_mp_device *settings, u32 chip, u32 chiprev) ++{ ++ const struct dmi_system_id *match; ++ const struct brcmf_dmi_data *data; ++ const char *sys_vendor; ++ const char *product_name; ++ ++ /* Some models have DMI strings which are too generic, e.g. ++ * "Default string", we use a quirk table for these. ++ */ ++ for (match = dmi_first_match(dmi_platform_data); ++ match; ++ match = dmi_first_match(match + 1)) { ++ data = match->driver_data; ++ ++ if (data->chip == chip && data->chiprev == chiprev) { ++ settings->board_type = data->board_type; ++ return; ++ } ++ } ++ ++ /* Not found in the quirk-table, use sys_vendor-product_name */ ++ sys_vendor = dmi_get_system_info(DMI_SYS_VENDOR); ++ product_name = dmi_get_system_info(DMI_PRODUCT_NAME); ++ if (sys_vendor && product_name) { ++ snprintf(dmi_board_type, sizeof(dmi_board_type), "%s-%s", ++ sys_vendor, product_name); ++ settings->board_type = dmi_board_type; ++ } ++} diff --git a/package/kernel/mac80211/patches/brcm/320-v4.21-0006-brcmfmac-Cleanup-brcmf_fw_request_done.patch b/package/kernel/mac80211/patches/brcm/320-v4.21-0006-brcmfmac-Cleanup-brcmf_fw_request_done.patch new file mode 100644 index 000000000..211e9e4a9 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/320-v4.21-0006-brcmfmac-Cleanup-brcmf_fw_request_done.patch @@ -0,0 +1,41 @@ +From 55e491edbf14b2da5419c2a319ea3b1d6368d9a2 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 10 Oct 2018 13:01:03 +0200 +Subject: [PATCH] brcmfmac: Cleanup brcmf_fw_request_done() + +The "cur" variable is now only used for a debug print and we already +print the same info from brcmf_fw_complete_request(), so the debug print +does not provide any extra info and we can remove it. + +Signed-off-by: Hans de Goede +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -560,22 +560,16 @@ static int brcmf_fw_request_firmware(con + static void brcmf_fw_request_done(const struct firmware *fw, void *ctx) + { + struct brcmf_fw *fwctx = ctx; +- struct brcmf_fw_item *cur; +- int ret = 0; +- +- cur = &fwctx->req->items[fwctx->curpos]; ++ int ret; + + ret = brcmf_fw_complete_request(fw, fwctx); + + while (ret == 0 && ++fwctx->curpos < fwctx->req->n_items) { +- cur = &fwctx->req->items[fwctx->curpos]; + brcmf_fw_request_firmware(&fw, fwctx); + ret = brcmf_fw_complete_request(fw, ctx); + } + + if (ret) { +- brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret, +- dev_name(fwctx->dev), cur->path); + brcmf_fw_free_request(fwctx->req); + fwctx->req = NULL; + } diff --git a/package/kernel/mac80211/patches/brcm/321-v4.21-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch b/package/kernel/mac80211/patches/brcm/321-v4.21-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch new file mode 100644 index 000000000..88e5c6773 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/321-v4.21-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch @@ -0,0 +1,132 @@ +From ce2e6db554fad444fa0b3904fc3015336e0ef765 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 11 Oct 2018 11:51:06 +0200 +Subject: [PATCH] brcmfmac: Add support for getting nvram contents from EFI + variables + +Various X86 laptops with a SDIO attached brcmfmac wifi chip, store the +nvram contents in a special EFI variable. This commit adds support for +getting nvram directly from this EFI variable, without the user needing +to manually copy it. + +This makes Wifi / Bluetooth work out of the box on these devices instead of +requiring manual setup. + +This has been tested on the following models: Acer Iconia Tab8 w1-810, +Acer One 10, Asus T100CHI, Asus T100HA, Asus T100TA, Asus T200TA and a +Lenovo Mixx 2 8. + +Tested-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/firmware.c | 63 +++++++++++++++++++--- + 1 file changed, 57 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -14,6 +14,7 @@ + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + ++#include + #include + #include + #include +@@ -445,6 +446,51 @@ struct brcmf_fw { + + static void brcmf_fw_request_done(const struct firmware *fw, void *ctx); + ++#ifdef CONFIG_EFI ++static u8 *brcmf_fw_nvram_from_efi(size_t *data_len_ret) ++{ ++ const u16 name[] = { 'n', 'v', 'r', 'a', 'm', 0 }; ++ struct efivar_entry *nvram_efivar; ++ unsigned long data_len = 0; ++ u8 *data = NULL; ++ int err; ++ ++ nvram_efivar = kzalloc(sizeof(*nvram_efivar), GFP_KERNEL); ++ if (!nvram_efivar) ++ return NULL; ++ ++ memcpy(&nvram_efivar->var.VariableName, name, sizeof(name)); ++ nvram_efivar->var.VendorGuid = EFI_GUID(0x74b00bd9, 0x805a, 0x4d61, ++ 0xb5, 0x1f, 0x43, 0x26, ++ 0x81, 0x23, 0xd1, 0x13); ++ ++ err = efivar_entry_size(nvram_efivar, &data_len); ++ if (err) ++ goto fail; ++ ++ data = kmalloc(data_len, GFP_KERNEL); ++ if (!data) ++ goto fail; ++ ++ err = efivar_entry_get(nvram_efivar, NULL, &data_len, data); ++ if (err) ++ goto fail; ++ ++ brcmf_info("Using nvram EFI variable\n"); ++ ++ kfree(nvram_efivar); ++ *data_len_ret = data_len; ++ return data; ++ ++fail: ++ kfree(data); ++ kfree(nvram_efivar); ++ return NULL; ++} ++#else ++static u8 *brcmf_fw_nvram_from_efi(size_t *data_len) { return NULL; } ++#endif ++ + static void brcmf_fw_free_request(struct brcmf_fw_request *req) + { + struct brcmf_fw_item *item; +@@ -463,11 +509,12 @@ static int brcmf_fw_request_nvram_done(c + { + struct brcmf_fw *fwctx = ctx; + struct brcmf_fw_item *cur; ++ bool free_bcm47xx_nvram = false; ++ bool kfree_nvram = false; + u32 nvram_length = 0; + void *nvram = NULL; + u8 *data = NULL; + size_t data_len; +- bool raw_nvram; + + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); + +@@ -476,12 +523,13 @@ static int brcmf_fw_request_nvram_done(c + if (fw && fw->data) { + data = (u8 *)fw->data; + data_len = fw->size; +- raw_nvram = false; + } else { +- data = bcm47xx_nvram_get_contents(&data_len); +- if (!data && !(cur->flags & BRCMF_FW_REQF_OPTIONAL)) ++ if ((data = bcm47xx_nvram_get_contents(&data_len))) ++ free_bcm47xx_nvram = true; ++ else if ((data = brcmf_fw_nvram_from_efi(&data_len))) ++ kfree_nvram = true; ++ else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) + goto fail; +- raw_nvram = true; + } + + if (data) +@@ -489,8 +537,11 @@ static int brcmf_fw_request_nvram_done(c + fwctx->req->domain_nr, + fwctx->req->bus_nr); + +- if (raw_nvram) ++ if (free_bcm47xx_nvram) + bcm47xx_nvram_release_contents(data); ++ if (kfree_nvram) ++ kfree(data); ++ + release_firmware(fw); + if (!nvram && !(cur->flags & BRCMF_FW_REQF_OPTIONAL)) + goto fail; diff --git a/package/kernel/mac80211/patches/brcm/321-v4.21-0002-brcmfmac-Fix-ccode-from-EFI-nvram-when-necessary.patch b/package/kernel/mac80211/patches/brcm/321-v4.21-0002-brcmfmac-Fix-ccode-from-EFI-nvram-when-necessary.patch new file mode 100644 index 000000000..c2fd620d6 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/321-v4.21-0002-brcmfmac-Fix-ccode-from-EFI-nvram-when-necessary.patch @@ -0,0 +1,97 @@ +From 29ec3394f0bd85c22674ab6693d92da5e2324610 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 11 Oct 2018 11:51:07 +0200 +Subject: [PATCH] brcmfmac: Fix ccode from EFI nvram when necessary + +In some cases the EFI-var stored nvram contains "ccode=ALL" or "ccode=XV" +to specify "worldwide" compatible settings, but these 2 ccode-s do not work +properly. + +I've tested the different known "worldwide" ccode-s used in various nvram +sources with the latest firmwares from linux-firmware for various brcmfmac +models, here is a simplified (*) table with what each setting results in: + +ALL: 12-14 disab, U-NII-1, U-NII-2 no-IR/radar, U-NII-3 +XV: 12-14 no-IR, disables all 5G channels +XY: 12-13 enab, 14 disab, U-NII-1 enab, U-NII-2 no-IR/radar, U-NII-3 disab +X2: 12-13 no-IR, 14 dis, U-NII-1 no-IR, U-NII-2 no-IR/radar, U-NII-3 no-IR + +Where 12,13,14 are 2.4G channels 12-14 and U-NII-1/2/3 are the 3 different +5G channel groups. no-IR is no-Initiate-Radiation, we will never send on +these channels without first having received valid wifi traffic there. + +This immediately shows that both ALL and XV are not as worldwide as we want +them to be. ALL causes channels 12 and 13 to not be available and XV causes +all 5GHz channels to not be available. Also ALL unconditionally enables the +U-NII-1 and U-NII-3 5G groups, while we really should be using no-IR for +these. + +This commit replace XV and ALL with X2, which allows usage of chan 12-13 +and 5G channels, but only after receiving valid wifi traffic there first. + +Note that this configure the firmware's channel limits, the kernels own +regulatory restrictions based on e.g. regulatory info received from the +access-point, will be applied on top of this. + +This fixes channels 12+13 not working on the Asus T200TA and the Lenovo +Mixx 2 8 and 5G channels not working on the Asus T100HA. + +This has been tested on the following models: Acer Iconia Tab8 w1-810, +Acer One 10, Asus T100CHI, Asus T100HA, Asus T100TA, Asus T200TA and a +Lenovo Mixx 2 8. + +*) There are some exceptions to this table: +1) On really old firmware e.g. linux-firmware's 2011 brcmfmac4330-sdio.bin + ALL really means all, unconditionally enabling everything +2) The exact meaning might be influenced by setting the regrev nvram var. + Specifically using ccode=XV + regrev=1 on brcmfmac43241b4 leads to: + 12-14 no-ir, U-NII-1 no-ir, U-NII-2 no-ir/radar, U-NII-3 no-ir + But only on the brcmfmac43241b4 and not on e.g. the brcmfmac43340 + +Tested-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/firmware.c | 24 ++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -447,6 +447,29 @@ struct brcmf_fw { + static void brcmf_fw_request_done(const struct firmware *fw, void *ctx); + + #ifdef CONFIG_EFI ++/* In some cases the EFI-var stored nvram contains "ccode=ALL" or "ccode=XV" ++ * to specify "worldwide" compatible settings, but these 2 ccode-s do not work ++ * properly. "ccode=ALL" causes channels 12 and 13 to not be available, ++ * "ccode=XV" causes all 5GHz channels to not be available. So we replace both ++ * with "ccode=X2" which allows channels 12+13 and 5Ghz channels in ++ * no-Initiate-Radiation mode. This means that we will never send on these ++ * channels without first having received valid wifi traffic on the channel. ++ */ ++static void brcmf_fw_fix_efi_nvram_ccode(char *data, unsigned long data_len) ++{ ++ char *ccode; ++ ++ ccode = strnstr((char *)data, "ccode=ALL", data_len); ++ if (!ccode) ++ ccode = strnstr((char *)data, "ccode=XV\r", data_len); ++ if (!ccode) ++ return; ++ ++ ccode[6] = 'X'; ++ ccode[7] = '2'; ++ ccode[8] = '\r'; ++} ++ + static u8 *brcmf_fw_nvram_from_efi(size_t *data_len_ret) + { + const u16 name[] = { 'n', 'v', 'r', 'a', 'm', 0 }; +@@ -476,6 +499,7 @@ static u8 *brcmf_fw_nvram_from_efi(size_ + if (err) + goto fail; + ++ brcmf_fw_fix_efi_nvram_ccode(data, data_len); + brcmf_info("Using nvram EFI variable\n"); + + kfree(nvram_efivar); diff --git a/package/kernel/mac80211/patches/brcm/322-v4.21-0001-brcmfmac-fix-spelling-mistake-Retreiving-Retrieving.patch b/package/kernel/mac80211/patches/brcm/322-v4.21-0001-brcmfmac-fix-spelling-mistake-Retreiving-Retrieving.patch new file mode 100644 index 000000000..c1aea25cb --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/322-v4.21-0001-brcmfmac-fix-spelling-mistake-Retreiving-Retrieving.patch @@ -0,0 +1,34 @@ +From e966a79c2f761a696dec9cfb0e2d4aa977bf78cb Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Tue, 16 Oct 2018 18:43:42 +0100 +Subject: [PATCH] brcmfmac: fix spelling mistake "Retreiving" -> "Retrieving" + +Trivial fix to spelling mistake in brcmf_err error message. + +Signed-off-by: Colin Ian King +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -214,7 +214,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, + sizeof(ifp->mac_addr)); + if (err < 0) { +- brcmf_err("Retreiving cur_etheraddr failed, %d\n", err); ++ brcmf_err("Retrieving cur_etheraddr failed, %d\n", err); + goto done; + } + memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN); +@@ -269,7 +269,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + strcpy(buf, "ver"); + err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf)); + if (err < 0) { +- brcmf_err("Retreiving version information failed, %d\n", ++ brcmf_err("Retrieving version information failed, %d\n", + err); + goto done; + } diff --git a/package/kernel/mac80211/patches/brcm/323-v4.21-0001-brcmutil-print-invalid-chanspec-when-WARN-ing.patch b/package/kernel/mac80211/patches/brcm/323-v4.21-0001-brcmutil-print-invalid-chanspec-when-WARN-ing.patch new file mode 100644 index 000000000..566336cbc --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/323-v4.21-0001-brcmutil-print-invalid-chanspec-when-WARN-ing.patch @@ -0,0 +1,83 @@ +From ae5848cb4511bbbfe0306fcdbe5d9a95cd9546a9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 26 Oct 2018 13:22:32 +0200 +Subject: [PATCH] brcmutil: print invalid chanspec when WARN-ing +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On one of my devices I got WARNINGs when brcmfmac tried to decode +chanspec. I couldn't tell if it was some unsupported format or just a +malformed value passed by a firmware. + +Print chanspec value so it's possible to debug a possible problem. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c +@@ -128,7 +128,7 @@ static void brcmu_d11n_decchspec(struct + } + break; + default: +- WARN_ON_ONCE(1); ++ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec); + break; + } + +@@ -140,7 +140,7 @@ static void brcmu_d11n_decchspec(struct + ch->band = BRCMU_CHAN_BAND_2G; + break; + default: +- WARN_ON_ONCE(1); ++ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec); + break; + } + } +@@ -167,7 +167,7 @@ static void brcmu_d11ac_decchspec(struct + ch->sb = BRCMU_CHAN_SB_U; + ch->control_ch_num += CH_10MHZ_APART; + } else { +- WARN_ON_ONCE(1); ++ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec); + } + break; + case BRCMU_CHSPEC_D11AC_BW_80: +@@ -188,7 +188,7 @@ static void brcmu_d11ac_decchspec(struct + ch->control_ch_num += CH_30MHZ_APART; + break; + default: +- WARN_ON_ONCE(1); ++ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec); + break; + } + break; +@@ -222,13 +222,13 @@ static void brcmu_d11ac_decchspec(struct + ch->control_ch_num += CH_70MHZ_APART; + break; + default: +- WARN_ON_ONCE(1); ++ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec); + break; + } + break; + case BRCMU_CHSPEC_D11AC_BW_8080: + default: +- WARN_ON_ONCE(1); ++ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec); + break; + } + +@@ -240,7 +240,7 @@ static void brcmu_d11ac_decchspec(struct + ch->band = BRCMU_CHAN_BAND_2G; + break; + default: +- WARN_ON_ONCE(1); ++ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec); + break; + } + } diff --git a/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch index e70738322..574fcb40d 100644 --- a/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch +++ b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch @@ -23,7 +23,7 @@ Signed-off-by: Rafał Miłecki } --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c -@@ -441,6 +441,7 @@ struct brcmf_fw { +@@ -442,6 +442,7 @@ struct brcmf_fw { struct brcmf_fw_request *req; u32 curpos; void (*done)(struct device *dev, int err, struct brcmf_fw_request *req); @@ -31,33 +31,37 @@ Signed-off-by: Rafał Miłecki }; static void brcmf_fw_request_done(const struct firmware *fw, void *ctx); -@@ -589,6 +590,8 @@ fail: - fwctx->req = NULL; - done: +@@ -649,6 +650,8 @@ static void brcmf_fw_request_done(const + fwctx->req = NULL; + } fwctx->done(fwctx->dev, ret, fwctx->req); + if (fwctx->completion) + complete(fwctx->completion); kfree(fwctx); } -@@ -612,6 +615,8 @@ int brcmf_fw_get_firmwares(struct device - struct brcmf_fw_request *req)) +@@ -673,6 +676,7 @@ int brcmf_fw_get_firmwares(struct device { + struct brcmf_fw_item *first = &req->items[0]; struct brcmf_fw *fwctx; + struct completion completion; -+ int err; + int ret; brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev)); - if (!fw_cb) -@@ -628,7 +633,14 @@ int brcmf_fw_get_firmwares(struct device +@@ -689,6 +693,9 @@ int brcmf_fw_get_firmwares(struct device + fwctx->dev = dev; fwctx->req = req; fwctx->done = fw_cb; - ++ + init_completion(&completion); + fwctx->completion = &completion; -+ - brcmf_fw_request_next_item(fwctx, true); -+ + + ret = request_firmware_nowait(THIS_MODULE, true, first->path, + fwctx->dev, GFP_KERNEL, fwctx, +@@ -696,6 +703,9 @@ int brcmf_fw_get_firmwares(struct device + if (ret < 0) + brcmf_fw_request_done(NULL, fwctx); + + wait_for_completion_timeout(fwctx->completion, msecs_to_jiffies(5000)); + fwctx->completion = NULL; + diff --git a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch b/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch index e7551c3a7..5bb701581 100644 --- a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch +++ b/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch @@ -49,9 +49,9 @@ Signed-off-by: Rafał Miłecki void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, struct brcmf_mp_device *settings) { -@@ -32,6 +62,8 @@ void brcmf_of_probe(struct device *dev, - u32 irqf; - u32 val; +@@ -41,6 +71,8 @@ void brcmf_of_probe(struct device *dev, + of_node_put(root); + } + brcmf_of_probe_cc(dev, settings); + diff --git a/package/kernel/mac80211/patches/subsys/379-mac80211-ignore-tx-status-for-PS-stations-in-ieee802.patch b/package/kernel/mac80211/patches/subsys/379-mac80211-ignore-tx-status-for-PS-stations-in-ieee802.patch new file mode 100644 index 000000000..a4176363b --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/379-mac80211-ignore-tx-status-for-PS-stations-in-ieee802.patch @@ -0,0 +1,26 @@ +From: Felix Fietkau +Date: Tue, 13 Nov 2018 20:29:03 +0100 +Subject: [PATCH] mac80211: ignore tx status for PS stations in + ieee80211_tx_status_ext + +Make it behave like regular ieee80211_tx_status calls, except for the lack of +filtered frame processing. +This fixes spurious low-ack triggered disconnections with powersave clients +connected to an AP. + +Fixes: f027c2aca0cf4 ("mac80211: add ieee80211_tx_status_noskb") +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -987,6 +987,8 @@ void ieee80211_tx_status_ext(struct ieee + /* Track when last TDLS packet was ACKed */ + if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH)) + sta->status_stats.last_tdls_pkt_time = jiffies; ++ } else if (test_sta_flag(sta, WLAN_STA_PS_STA)) { ++ return; + } else { + ieee80211_lost_packet(sta, info); + }