diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 29363748ec..3cc14944fe 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 -PKG_VERSION:=5.4-rc2-1 +PKG_VERSION:=5.3-rc4-1 PKG_RELEASE:=1 -PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.4-rc2/ -PKG_HASH:=b3baedc135b455f09f266cb77e73276ca21bceeb0f24bac2184cc4b97d09cdbf +PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.3-rc4/ +PKG_HASH:=b159557f1e9e3e88ee2edf60ee786cd9ffd477e386306ea249c4e9085695b932 PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) @@ -223,7 +223,7 @@ endef define KernelPackage/lib80211 $(call KernelPackage/mac80211/Default) TITLE:=802.11 Networking stack - DEPENDS:=+kmod-cfg80211 +kmod-crypto-hash +kmod-crypto-ccm + DEPENDS:=+kmod-cfg80211 +kmod-crypto-hash FILES:= \ $(PKG_BUILD_DIR)/net/wireless/lib80211.ko \ $(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_wep.ko \ diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh old mode 100755 new mode 100644 diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh old mode 100755 new mode 100644 diff --git a/package/kernel/mac80211/files/mac80211.hotplug b/package/kernel/mac80211/files/mac80211.hotplug old mode 100755 new mode 100644 diff --git a/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch b/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch index 3bb046e843..231a7cb393 100644 --- a/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch +++ b/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch @@ -37,7 +37,7 @@ void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); --- a/local-symbols +++ b/local-symbols -@@ -142,6 +142,7 @@ ATH10K_SNOC= +@@ -141,6 +141,7 @@ ATH10K_SNOC= ATH10K_DEBUG= ATH10K_DEBUGFS= ATH10K_SPECTRAL= diff --git a/package/kernel/mac80211/patches/ath/408-ath_phy_regd.patch b/package/kernel/mac80211/patches/ath/408-ath_phy_regd.patch new file mode 100644 index 0000000000..6d1dabf8ab --- /dev/null +++ b/package/kernel/mac80211/patches/ath/408-ath_phy_regd.patch @@ -0,0 +1,13 @@ +--- a/drivers/net/wireless/ath/regd.c ++++ b/drivers/net/wireless/ath/regd.c +@@ -511,6 +511,10 @@ static int __ath_reg_dyn_country(struct + + ath_reg_apply_world_flags(wiphy, request->initiator, reg); + ++ // apply regulatory to phy devices ++ if (regulatory_hint(wiphy, reg->alpha2)) ++ printk(KERN_DEBUG "ath: regulatory_hint error!\n"); ++ + return 0; + } + diff --git a/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch b/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch index 136be19894..cdc9315cd6 100644 --- a/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch +++ b/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch @@ -1,14 +1,14 @@ --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c -@@ -20,6 +20,7 @@ - #include +@@ -21,6 +21,7 @@ + #include #include #include +#include #include "../ath.h" #include "ath5k.h" #include "debug.h" -@@ -71,7 +72,7 @@ static void ath5k_pci_read_cachesize(str +@@ -72,7 +73,7 @@ static void ath5k_pci_read_cachesize(str } /* @@ -17,7 +17,7 @@ */ static bool ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) -@@ -79,6 +80,19 @@ ath5k_pci_eeprom_read(struct ath_common +@@ -80,6 +81,19 @@ ath5k_pci_eeprom_read(struct ath_common struct ath5k_hw *ah = (struct ath5k_hw *) common->ah; u32 status, timeout; @@ -37,7 +37,7 @@ /* * Initialize EEPROM access */ -@@ -122,6 +136,16 @@ static int ath5k_pci_eeprom_read_mac(str +@@ -123,6 +137,16 @@ static int ath5k_pci_eeprom_read_mac(str u16 data; int octet; diff --git a/package/kernel/mac80211/patches/ath/432-ath5k_add_pciids.patch b/package/kernel/mac80211/patches/ath/432-ath5k_add_pciids.patch index bd0e6707a5..d82f8001d4 100644 --- a/package/kernel/mac80211/patches/ath/432-ath5k_add_pciids.patch +++ b/package/kernel/mac80211/patches/ath/432-ath5k_add_pciids.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c -@@ -47,6 +47,8 @@ static const struct pci_device_id ath5k_ +@@ -48,6 +48,8 @@ static const struct pci_device_id ath5k_ { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ diff --git a/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch b/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch index 4454baeef1..9c91767587 100644 --- a/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch +++ b/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch @@ -391,9 +391,9 @@ ATH9K_CHANNEL_CONTEXT= ATH9K_PCOEM= +ATH9K_UBNTHSR= - ATH9K_PCI_NO_EEPROM= ATH9K_HTC= ATH9K_HTC_DEBUGFS= + ATH9K_HWRNG= --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -60,6 +60,19 @@ config ATH9K_AHB diff --git a/package/kernel/mac80211/patches/ath/558-ath9k-dynack-introduce-ath_dynack_set_timeout-routin.patch b/package/kernel/mac80211/patches/ath/558-ath9k-dynack-introduce-ath_dynack_set_timeout-routin.patch new file mode 100644 index 0000000000..e13a15026e --- /dev/null +++ b/package/kernel/mac80211/patches/ath/558-ath9k-dynack-introduce-ath_dynack_set_timeout-routin.patch @@ -0,0 +1,94 @@ +From 4420866ef1b602682b009e0186fbb8aefd2125be Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 20 Aug 2019 18:20:19 +0200 +Subject: [PATCH 1/4] ath9k: dynack: introduce ath_dynack_set_timeout routine + +Introduce ath_dynack_set_timeout routine to configure slottime/ack/cts +timeouts and remove duplicated code + +Tested-by: Koen Vandeputte +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/wireless/ath/ath9k/dynack.c | 37 ++++++++++++++----------- + 1 file changed, 21 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c +index f112fa5b2eac..38dbe25919f7 100644 +--- a/drivers/net/wireless/ath/ath9k/dynack.c ++++ b/drivers/net/wireless/ath/ath9k/dynack.c +@@ -78,6 +78,24 @@ static inline bool ath_dynack_bssidmask(struct ath_hw *ah, const u8 *mac) + return true; + } + ++/** ++ * ath_dynack_set_timeout - configure timeouts/slottime registers ++ * @ah: ath hw ++ * @to: timeout value ++ * ++ */ ++static void ath_dynack_set_timeout(struct ath_hw *ah, int to) ++{ ++ struct ath_common *common = ath9k_hw_common(ah); ++ int slottime = (to - 3) / 2; ++ ++ ath_dbg(common, DYNACK, "ACK timeout %u slottime %u\n", ++ to, slottime); ++ ath9k_hw_setslottime(ah, slottime); ++ ath9k_hw_set_ack_timeout(ah, to); ++ ath9k_hw_set_cts_timeout(ah, to); ++} ++ + /** + * ath_dynack_compute_ackto - compute ACK timeout as the maximum STA timeout + * @ah: ath hw +@@ -86,7 +104,6 @@ static inline bool ath_dynack_bssidmask(struct ath_hw *ah, const u8 *mac) + */ + static void ath_dynack_compute_ackto(struct ath_hw *ah) + { +- struct ath_common *common = ath9k_hw_common(ah); + struct ath_dynack *da = &ah->dynack; + struct ath_node *an; + int to = 0; +@@ -96,15 +113,8 @@ static void ath_dynack_compute_ackto(struct ath_hw *ah) + to = an->ackto; + + if (to && da->ackto != to) { +- u32 slottime; +- +- slottime = (to - 3) / 2; ++ ath_dynack_set_timeout(ah, to); + da->ackto = to; +- ath_dbg(common, DYNACK, "ACK timeout %u slottime %u\n", +- da->ackto, slottime); +- ath9k_hw_setslottime(ah, slottime); +- ath9k_hw_set_ack_timeout(ah, da->ackto); +- ath9k_hw_set_cts_timeout(ah, da->ackto); + } + } + +@@ -198,10 +208,7 @@ void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb, + 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); ++ ath_dynack_set_timeout(ah, LATEACK_TO); + if (sta) { + struct ath_node *an; + +@@ -340,9 +347,7 @@ void ath_dynack_reset(struct ath_hw *ah) + da->ack_rbf.h_rb = 0; + + /* init acktimeout */ +- ath9k_hw_setslottime(ah, (ackto - 3) / 2); +- ath9k_hw_set_ack_timeout(ah, ackto); +- ath9k_hw_set_cts_timeout(ah, ackto); ++ ath_dynack_set_timeout(ah, ackto); + } + EXPORT_SYMBOL(ath_dynack_reset); + +-- +2.17.1 + diff --git a/package/kernel/mac80211/patches/ath/559-ath9k-dynack-properly-set-last-timeout-timestamp-in-.patch b/package/kernel/mac80211/patches/ath/559-ath9k-dynack-properly-set-last-timeout-timestamp-in-.patch new file mode 100644 index 0000000000..9504af1419 --- /dev/null +++ b/package/kernel/mac80211/patches/ath/559-ath9k-dynack-properly-set-last-timeout-timestamp-in-.patch @@ -0,0 +1,32 @@ +From e5b56ce50eab31d24df6a70cf025db3acc4aa3ac Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 20 Aug 2019 18:20:20 +0200 +Subject: [PATCH 2/4] ath9k: dynack: properly set last timeout timestamp in + ath_dynack_reset + +Add compute timeout to last computation timestamp in +ath_dynack_reset in order to not run ath_dynack_compute_ackto +immediately + +Tested-by: Koen Vandeputte +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/wireless/ath/ath9k/dynack.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c +index 38dbe25919f7..398ea872751f 100644 +--- a/drivers/net/wireless/ath/ath9k/dynack.c ++++ b/drivers/net/wireless/ath/ath9k/dynack.c +@@ -338,7 +338,7 @@ void ath_dynack_reset(struct ath_hw *ah) + u32 ackto = 9 + 16 + 64; + struct ath_dynack *da = &ah->dynack; + +- da->lto = jiffies; ++ da->lto = jiffies + COMPUTE_TO; + da->ackto = ackto; + + da->st_rbf.t_rb = 0; +-- +2.17.1 + diff --git a/package/kernel/mac80211/patches/ath/560-ath9k-dynack-set-max-timeout-according-to-channel-wi.patch b/package/kernel/mac80211/patches/ath/560-ath9k-dynack-set-max-timeout-according-to-channel-wi.patch new file mode 100644 index 0000000000..f40289cca4 --- /dev/null +++ b/package/kernel/mac80211/patches/ath/560-ath9k-dynack-set-max-timeout-according-to-channel-wi.patch @@ -0,0 +1,96 @@ +From 3f737abb7d53cc80d619a3b4a30b6fa63cdc8df7 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 20 Aug 2019 18:20:21 +0200 +Subject: [PATCH 3/4] ath9k: dynack: set max timeout according to channel width + +Compute maximum configurable ackimeout/ctstimeout according to channel +width (clockrate) + +Tested-by: Koen Vandeputte +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/wireless/ath/ath9k/dynack.c | 38 +++++++++++++++++++------ + 1 file changed, 30 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c +index 398ea872751f..fe9181533de3 100644 +--- a/drivers/net/wireless/ath/ath9k/dynack.c ++++ b/drivers/net/wireless/ath/ath9k/dynack.c +@@ -20,11 +20,30 @@ + + #define COMPUTE_TO (5 * HZ) + #define LATEACK_DELAY (10 * HZ) +-#define LATEACK_TO 256 +-#define MAX_DELAY 300 + #define EWMA_LEVEL 96 + #define EWMA_DIV 128 + ++/** ++ * ath_dynack_get_max_to - set max timeout according to channel width ++ * @ah: ath hw ++ * ++ */ ++static u32 ath_dynack_get_max_to(struct ath_hw *ah) ++{ ++ const struct ath9k_channel *chan = ah->curchan; ++ ++ if (!chan) ++ return 300; ++ ++ if (IS_CHAN_HT40(chan)) ++ return 300; ++ if (IS_CHAN_HALF_RATE(chan)) ++ return 750; ++ if (IS_CHAN_QUARTER_RATE(chan)) ++ return 1500; ++ return 600; ++} ++ + /** + * ath_dynack_ewma - EWMA (Exponentially Weighted Moving Average) calculation + * +@@ -126,15 +145,16 @@ static void ath_dynack_compute_ackto(struct ath_hw *ah) + */ + static void ath_dynack_compute_to(struct ath_hw *ah) + { +- u32 ackto, ack_ts; +- u8 *dst, *src; ++ struct ath_dynack *da = &ah->dynack; ++ u32 ackto, ack_ts, max_to; + struct ieee80211_sta *sta; +- struct ath_node *an; + struct ts_info *st_ts; +- struct ath_dynack *da = &ah->dynack; ++ struct ath_node *an; ++ u8 *dst, *src; + + rcu_read_lock(); + ++ max_to = ath_dynack_get_max_to(ah); + while (da->st_rbf.h_rb != da->st_rbf.t_rb && + da->ack_rbf.h_rb != da->ack_rbf.t_rb) { + ack_ts = da->ack_rbf.tstamp[da->ack_rbf.h_rb]; +@@ -150,7 +170,7 @@ static void ath_dynack_compute_to(struct ath_hw *ah) + if (ack_ts > st_ts->tstamp + st_ts->dur) { + ackto = ack_ts - st_ts->tstamp - st_ts->dur; + +- if (ackto < MAX_DELAY) { ++ if (ackto < max_to) { + sta = ieee80211_find_sta_by_ifaddr(ah->hw, dst, + src); + if (sta) { +@@ -207,8 +227,10 @@ void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb, + if (ieee80211_is_assoc_req(hdr->frame_control) || + ieee80211_is_assoc_resp(hdr->frame_control) || + ieee80211_is_auth(hdr->frame_control)) { ++ u32 max_to = ath_dynack_get_max_to(ah); ++ + ath_dbg(common, DYNACK, "late ack\n"); +- ath_dynack_set_timeout(ah, LATEACK_TO); ++ ath_dynack_set_timeout(ah, max_to); + if (sta) { + struct ath_node *an; + +-- +2.17.1 + diff --git a/package/kernel/mac80211/patches/ath/561-ath9k-dynack-set-ackto-to-max-timeout-in-ath_dynack_.patch b/package/kernel/mac80211/patches/ath/561-ath9k-dynack-set-ackto-to-max-timeout-in-ath_dynack_.patch new file mode 100644 index 0000000000..5b75096e19 --- /dev/null +++ b/package/kernel/mac80211/patches/ath/561-ath9k-dynack-set-ackto-to-max-timeout-in-ath_dynack_.patch @@ -0,0 +1,78 @@ +From cc783bfa67e87d2e6206f7626b7bbb74d5c5f269 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Tue, 20 Aug 2019 18:20:22 +0200 +Subject: [PATCH 4/4] ath9k: dynack: set ackto to max timeout in + ath_dynack_reset + +Initialize acktimeout to the maximum configurable value in +ath_dynack_reset in order to not disconnect long distance static links +enabling dynack and even to take care of possible errors configuring +a static timeout. Moreover initialize station timeout value to the current +acktimeout value + +Tested-by: Koen Vandeputte +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/wireless/ath/ath9k/dynack.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c +index fe9181533de3..f786be04d0ac 100644 +--- a/drivers/net/wireless/ath/ath9k/dynack.c ++++ b/drivers/net/wireless/ath/ath9k/dynack.c +@@ -321,11 +321,9 @@ EXPORT_SYMBOL(ath_dynack_sample_ack_ts); + */ + void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an) + { +- /* ackto = slottime + sifs + air delay */ +- u32 ackto = 9 + 16 + 64; + struct ath_dynack *da = &ah->dynack; + +- an->ackto = ackto; ++ an->ackto = da->ackto; + + spin_lock(&da->qlock); + list_add_tail(&an->list, &da->nodes); +@@ -356,20 +354,26 @@ EXPORT_SYMBOL(ath_dynack_node_deinit); + */ + void ath_dynack_reset(struct ath_hw *ah) + { +- /* ackto = slottime + sifs + air delay */ +- u32 ackto = 9 + 16 + 64; + struct ath_dynack *da = &ah->dynack; ++ struct ath_node *an; ++ ++ spin_lock_bh(&da->qlock); + + da->lto = jiffies + COMPUTE_TO; +- da->ackto = ackto; + + da->st_rbf.t_rb = 0; + da->st_rbf.h_rb = 0; + da->ack_rbf.t_rb = 0; + da->ack_rbf.h_rb = 0; + ++ da->ackto = ath_dynack_get_max_to(ah); ++ list_for_each_entry(an, &da->nodes, list) ++ an->ackto = da->ackto; ++ + /* init acktimeout */ +- ath_dynack_set_timeout(ah, ackto); ++ ath_dynack_set_timeout(ah, da->ackto); ++ ++ spin_unlock_bh(&da->qlock); + } + EXPORT_SYMBOL(ath_dynack_reset); + +@@ -386,6 +390,8 @@ void ath_dynack_init(struct ath_hw *ah) + + spin_lock_init(&da->qlock); + INIT_LIST_HEAD(&da->nodes); ++ /* ackto = slottime + sifs + air delay */ ++ da->ackto = 9 + 16 + 64; + + ah->hw->wiphy->features |= NL80211_FEATURE_ACKTO_ESTIMATION; + } +-- +2.17.1 + diff --git a/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch index c8c207f41a..b1172cd17d 100644 --- a/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch +++ b/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -8671,6 +8671,21 @@ static int ath10k_mac_init_rd(struct ath +@@ -8669,6 +8669,21 @@ static int ath10k_mac_init_rd(struct ath return 0; } @@ -22,7 +22,7 @@ int ath10k_mac_register(struct ath10k *ar) { static const u32 cipher_suites[] = { -@@ -8997,6 +9012,12 @@ int ath10k_mac_register(struct ath10k *a +@@ -8995,6 +9010,12 @@ int ath10k_mac_register(struct ath10k *a ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; diff --git a/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch b/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch index ae0f682224..97b7550e34 100644 --- a/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch +++ b/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch @@ -114,7 +114,7 @@ v13: ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o --- a/local-symbols +++ b/local-symbols -@@ -145,6 +145,7 @@ ATH10K_DEBUG= +@@ -144,6 +144,7 @@ ATH10K_DEBUG= ATH10K_DEBUGFS= ATH10K_SPECTRAL= ATH10K_THERMAL= diff --git a/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch b/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch index 9fdbf0ce30..8922ffed81 100644 --- a/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch +++ b/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch @@ -42,7 +42,7 @@ Signed-off-by: Mathias Kresin if (ret) --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -9029,7 +9029,7 @@ int ath10k_mac_register(struct ath10k *a +@@ -9027,7 +9027,7 @@ int ath10k_mac_register(struct ath10k *a ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; #ifdef CPTCFG_MAC80211_LEDS diff --git a/package/kernel/mac80211/patches/ath/976-ath10k-Check-if-station-exists-before-forwarding-tx-.patch b/package/kernel/mac80211/patches/ath/976-ath10k-Check-if-station-exists-before-forwarding-tx-.patch index 275409b7c1..4f247e29f7 100644 --- a/package/kernel/mac80211/patches/ath/976-ath10k-Check-if-station-exists-before-forwarding-tx-.patch +++ b/package/kernel/mac80211/patches/ath/976-ath10k-Check-if-station-exists-before-forwarding-tx-.patch @@ -72,7 +72,7 @@ Signed-off-by: Hauke Mehrtens --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c -@@ -2726,7 +2726,7 @@ static void ath10k_htt_rx_tx_compl_ind(s +@@ -2639,7 +2639,7 @@ static void ath10k_htt_rx_tx_compl_ind(s spin_lock_bh(&ar->data_lock); peer = ath10k_peer_find_by_id(ar, peer_id); diff --git a/package/kernel/mac80211/patches/brcm/103-v5.4-0001-brcmfmac-add-160MHz-in-chandef_to_chanspec.patch b/package/kernel/mac80211/patches/brcm/103-v5.4-0001-brcmfmac-add-160MHz-in-chandef_to_chanspec.patch new file mode 100644 index 0000000000..0d38084e90 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/103-v5.4-0001-brcmfmac-add-160MHz-in-chandef_to_chanspec.patch @@ -0,0 +1,56 @@ +From f491645f039420fb7e14283e21b90772571c807c Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 11 Jul 2019 10:45:30 +0200 +Subject: [PATCH] brcmfmac: add 160MHz in chandef_to_chanspec() + +The function chandef_to_chanspec() was not handling 160MHz bandwidth +resulting in wrong encoding of the channel. That resulting in firmware +rejecting the provided channel specification. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 21 ++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -276,8 +276,26 @@ static u16 chandef_to_chanspec(struct br + else + ch_inf.sb = BRCMU_CHAN_SB_UU; + break; +- case NL80211_CHAN_WIDTH_80P80: + case NL80211_CHAN_WIDTH_160: ++ ch_inf.bw = BRCMU_CHAN_BW_160; ++ if (primary_offset == -70) ++ ch_inf.sb = BRCMU_CHAN_SB_LLL; ++ else if (primary_offset == -50) ++ ch_inf.sb = BRCMU_CHAN_SB_LLU; ++ else if (primary_offset == -30) ++ ch_inf.sb = BRCMU_CHAN_SB_LUL; ++ else if (primary_offset == -10) ++ ch_inf.sb = BRCMU_CHAN_SB_LUU; ++ else if (primary_offset == 10) ++ ch_inf.sb = BRCMU_CHAN_SB_ULL; ++ else if (primary_offset == 30) ++ ch_inf.sb = BRCMU_CHAN_SB_ULU; ++ else if (primary_offset == 50) ++ ch_inf.sb = BRCMU_CHAN_SB_UUL; ++ else ++ ch_inf.sb = BRCMU_CHAN_SB_UUU; ++ break; ++ case NL80211_CHAN_WIDTH_80P80: + case NL80211_CHAN_WIDTH_5: + case NL80211_CHAN_WIDTH_10: + default: +@@ -296,6 +314,7 @@ static u16 chandef_to_chanspec(struct br + } + d11inf->encchspec(&ch_inf); + ++ brcmf_dbg(TRACE, "chanspec: 0x%x\n", ch_inf.chspec); + return ch_inf.chspec; + } + diff --git a/package/kernel/mac80211/patches/brcm/103-v5.4-0002-brcmfmac-enable-DFS_OFFLOAD-extended-feature-if-supp.patch b/package/kernel/mac80211/patches/brcm/103-v5.4-0002-brcmfmac-enable-DFS_OFFLOAD-extended-feature-if-supp.patch new file mode 100644 index 0000000000..6d0756ca78 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/103-v5.4-0002-brcmfmac-enable-DFS_OFFLOAD-extended-feature-if-supp.patch @@ -0,0 +1,63 @@ +From 011a56a3336a5de9c3152c169cd52ff79b8c3f89 Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 11 Jul 2019 10:45:31 +0200 +Subject: [PATCH] brcmfmac: enable DFS_OFFLOAD extended feature if supported + +If the firmware supports 802.11h and the device can operate in 5GHz +band we can enable DFS_OFFLOAD extended feature. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +++++ + drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 1 + + drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h | 4 +++- + 3 files changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6733,6 +6733,11 @@ static int brcmf_setup_wiphy(struct wiph + } + } + ++ if (wiphy->bands[NL80211_BAND_5GHZ] && ++ brcmf_feat_is_enabled(ifp, BRCMF_FEAT_DOT11H)) ++ wiphy_ext_feature_set(wiphy, ++ NL80211_EXT_FEATURE_DFS_OFFLOAD); ++ + wiphy_read_of_freq_limits(wiphy); + + return 0; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -39,6 +39,7 @@ static const struct brcmf_feat_fwcap brc + { BRCMF_FEAT_P2P, "p2p" }, + { BRCMF_FEAT_MONITOR, "monitor" }, + { BRCMF_FEAT_MONITOR_FMT_RADIOTAP, "rtap" }, ++ { BRCMF_FEAT_DOT11H, "802.11h" } + }; + + #ifdef DEBUG +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +@@ -25,6 +25,7 @@ + * MONITOR: firmware can pass monitor packets to host. + * MONITOR_FMT_RADIOTAP: firmware provides monitor packets with radiotap header + * MONITOR_FMT_HW_RX_HDR: firmware provides monitor packets with hw/ucode header ++ * DOT11H: firmware supports 802.11h + */ + #define BRCMF_FEAT_LIST \ + BRCMF_FEAT_DEF(MBSS) \ +@@ -43,7 +44,8 @@ + BRCMF_FEAT_DEF(FWSUP) \ + BRCMF_FEAT_DEF(MONITOR) \ + BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) \ +- BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) ++ BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) \ ++ BRCMF_FEAT_DEF(DOT11H) + + /* + * Quirks: diff --git a/package/kernel/mac80211/patches/brcm/103-v5.4-0003-brcmfmac-allow-160MHz-in-custom-regulatory-rules.patch b/package/kernel/mac80211/patches/brcm/103-v5.4-0003-brcmfmac-allow-160MHz-in-custom-regulatory-rules.patch new file mode 100644 index 0000000000..3df8057ced --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/103-v5.4-0003-brcmfmac-allow-160MHz-in-custom-regulatory-rules.patch @@ -0,0 +1,34 @@ +From fa9050927fa885410055ee03c948c2252693d296 Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 11 Jul 2019 10:45:32 +0200 +Subject: [PATCH] brcmfmac: allow 160MHz in custom regulatory rules + +The driver has custom regulatory rules which had maximum bandwidth +for 5GHz channels set to 80MHz. As a consequence the driver can +not use 160MHz in AP mode even when the device supports it. So +relax the rules allowing 160MHz. After wiphy_register() the channel +flags are updated according what the device actually supports. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -189,9 +189,9 @@ static const struct ieee80211_regdomain + */ + REG_RULE(2484-10, 2484+10, 20, 6, 20, 0), + /* IEEE 802.11a, channel 36..64 */ +- REG_RULE(5150-10, 5350+10, 80, 6, 20, 0), ++ REG_RULE(5150-10, 5350+10, 160, 6, 20, 0), + /* IEEE 802.11a, channel 100..165 */ +- REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), } ++ REG_RULE(5470-10, 5850+10, 160, 6, 20, 0), } + }; + + /* Note: brcmf_cipher_suites is an array of int defining which cipher suites diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0001-Revert-brcmfmac-fix-NULL-pointer-derefence-during-US.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0001-Revert-brcmfmac-fix-NULL-pointer-derefence-during-US.patch new file mode 100644 index 0000000000..45a9a339fa --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/104-v5.4-0001-Revert-brcmfmac-fix-NULL-pointer-derefence-during-US.patch @@ -0,0 +1,168 @@ +From a84a60ccdd65278485fb495f468a5ab91a75c649 Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 11 Jul 2019 11:05:06 +0200 +Subject: [PATCH] Revert "brcmfmac: fix NULL pointer derefence during USB + disconnect" + +This reverts commit 5cdb0ef6144f47440850553579aa923c20a63f23. Subsequent +changes make rework the driver code fixing the issue differently. + +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 11 ++--------- + .../wireless/broadcom/brcm80211/brcmfmac/bcdc.h | 6 ++---- + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 4 +--- + .../broadcom/brcm80211/brcmfmac/fwsignal.c | 16 ++++------------ + .../broadcom/brcm80211/brcmfmac/fwsignal.h | 3 +-- + .../wireless/broadcom/brcm80211/brcmfmac/proto.c | 10 ++-------- + .../wireless/broadcom/brcm80211/brcmfmac/proto.h | 3 +-- + 7 files changed, 13 insertions(+), 40 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c +@@ -479,18 +479,11 @@ fail: + return -ENOMEM; + } + +-void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr) +-{ +- struct brcmf_bcdc *bcdc = drvr->proto->pd; +- +- brcmf_fws_detach_pre_delif(bcdc->fws); +-} +- +-void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr) ++void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) + { + struct brcmf_bcdc *bcdc = drvr->proto->pd; + + drvr->proto->pd = NULL; +- brcmf_fws_detach_post_delif(bcdc->fws); ++ brcmf_fws_detach(bcdc->fws); + kfree(bcdc); + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h +@@ -7,16 +7,14 @@ + + #ifdef CPTCFG_BRCMFMAC_PROTO_BCDC + int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr); +-void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr); +-void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr); ++void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr); + void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state); + void brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp, + bool success); + struct brcmf_fws_info *drvr_to_fws(struct brcmf_pub *drvr); + #else + static inline int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { return 0; } +-static void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr) {}; +-static inline void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr) {} ++static inline void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) {} + #endif + + #endif /* BRCMFMAC_BCDC_H */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1335,8 +1335,6 @@ void brcmf_detach(struct device *dev) + + brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); + +- brcmf_proto_detach_pre_delif(drvr); +- + /* make sure primary interface removed last */ + for (i = BRCMF_MAX_IFS-1; i > -1; i--) + brcmf_remove_interface(drvr->iflist[i], false); +@@ -1346,7 +1344,7 @@ void brcmf_detach(struct device *dev) + + brcmf_bus_stop(drvr->bus_if); + +- brcmf_proto_detach_post_delif(drvr); ++ brcmf_proto_detach(drvr); + + bus_if->drvr = NULL; + wiphy_free(drvr->wiphy); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +@@ -2432,25 +2432,17 @@ struct brcmf_fws_info *brcmf_fws_attach( + return fws; + + fail: +- brcmf_fws_detach_pre_delif(fws); +- brcmf_fws_detach_post_delif(fws); ++ brcmf_fws_detach(fws); + return ERR_PTR(rc); + } + +-void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws) ++void brcmf_fws_detach(struct brcmf_fws_info *fws) + { + if (!fws) + return; +- if (fws->fws_wq) { +- destroy_workqueue(fws->fws_wq); +- fws->fws_wq = NULL; +- } +-} + +-void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws) +-{ +- if (!fws) +- return; ++ if (fws->fws_wq) ++ destroy_workqueue(fws->fws_wq); + + /* cleanup */ + brcmf_fws_lock(fws); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h +@@ -7,8 +7,7 @@ + #define FWSIGNAL_H_ + + struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr); +-void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws); +-void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws); ++void brcmf_fws_detach(struct brcmf_fws_info *fws); + void brcmf_fws_debugfs_create(struct brcmf_pub *drvr); + bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws); + bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c +@@ -56,22 +56,16 @@ fail: + return -ENOMEM; + } + +-void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr) ++void brcmf_proto_detach(struct brcmf_pub *drvr) + { + brcmf_dbg(TRACE, "Enter\n"); + + if (drvr->proto) { + if (drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) +- brcmf_proto_bcdc_detach_post_delif(drvr); ++ brcmf_proto_bcdc_detach(drvr); + else if (drvr->bus_if->proto_type == BRCMF_PROTO_MSGBUF) + brcmf_proto_msgbuf_detach(drvr); + kfree(drvr->proto); + drvr->proto = NULL; + } + } +- +-void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr) +-{ +- if (drvr->proto && drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) +- brcmf_proto_bcdc_detach_pre_delif(drvr); +-} +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h +@@ -43,8 +43,7 @@ struct brcmf_proto { + + + int brcmf_proto_attach(struct brcmf_pub *drvr); +-void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr); +-void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr); ++void brcmf_proto_detach(struct brcmf_pub *drvr); + + static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, + struct sk_buff *skb, diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0002-brcmfmac-change-the-order-of-things-in-brcmf_detach.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0002-brcmfmac-change-the-order-of-things-in-brcmf_detach.patch new file mode 100644 index 0000000000..d40bf031b8 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/104-v5.4-0002-brcmfmac-change-the-order-of-things-in-brcmf_detach.patch @@ -0,0 +1,67 @@ +From 14fcfd1cc0c05ea58f47dd693fdd13f25dfe995e Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 11 Jul 2019 11:05:07 +0200 +Subject: [PATCH] brcmfmac: change the order of things in brcmf_detach() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When brcmf_detach() from the bus layer upon rmmod we can no longer +communicate. Hence we will set the bus state to DOWN and cleanup +the event and protocol layer. The network interfaces need to be +deleted before brcmf_cfg80211_detach() because the latter does the +wiphy_unregister() which issues a warning if there are still network +devices linked to the wiphy instance. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Tested-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/core.c | 27 ++++++++++--------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1328,25 +1328,26 @@ void brcmf_detach(struct device *dev) + unregister_inet6addr_notifier(&drvr->inet6addr_notifier); + #endif + +- /* stop firmware event handling */ +- brcmf_fweh_detach(drvr); +- if (drvr->config) +- brcmf_p2p_detach(&drvr->config->p2p); +- + brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); +- +- /* make sure primary interface removed last */ +- for (i = BRCMF_MAX_IFS-1; i > -1; i--) +- brcmf_remove_interface(drvr->iflist[i], false); +- +- brcmf_cfg80211_detach(drvr->config); +- drvr->config = NULL; +- + brcmf_bus_stop(drvr->bus_if); + ++ brcmf_fweh_detach(drvr); + brcmf_proto_detach(drvr); + ++ /* make sure primary interface removed last */ ++ for (i = BRCMF_MAX_IFS - 1; i > -1; i--) { ++ if (drvr->iflist[i]) ++ brcmf_del_if(drvr, drvr->iflist[i]->bsscfgidx, false); ++ } ++ ++ if (drvr->config) { ++ brcmf_p2p_detach(&drvr->config->p2p); ++ brcmf_cfg80211_detach(drvr->config); ++ drvr->config = NULL; ++ } ++ + bus_if->drvr = NULL; ++ + wiphy_free(drvr->wiphy); + } + diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0003-brcmfmac-avoid-firmware-command-in-brcmf_netdev_open.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0003-brcmfmac-avoid-firmware-command-in-brcmf_netdev_open.patch new file mode 100644 index 0000000000..4c42b2b0c9 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/104-v5.4-0003-brcmfmac-avoid-firmware-command-in-brcmf_netdev_open.patch @@ -0,0 +1,30 @@ +From c613085b74941024194e41b200601b9aa6ee388f Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 11 Jul 2019 11:05:08 +0200 +Subject: [PATCH] brcmfmac: avoid firmware command in brcmf_netdev_open() when + bus is down + +No point in sending a firmware command when bus is down so make it +conditional checking the state. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -579,7 +579,8 @@ static int brcmf_netdev_stop(struct net_ + + brcmf_cfg80211_down(ndev); + +- brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0); ++ if (ifp->drvr->bus_if->state == BRCMF_BUS_UP) ++ brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0); + + brcmf_net_setcarrier(ifp, false); + diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0004-brcmfmac-clear-events-in-brcmf_fweh_detach-will-alwa.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0004-brcmfmac-clear-events-in-brcmf_fweh_detach-will-alwa.patch new file mode 100644 index 0000000000..d796faa79f --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/104-v5.4-0004-brcmfmac-clear-events-in-brcmf_fweh_detach-will-alwa.patch @@ -0,0 +1,38 @@ +From c33330ac06fe863289643e7a13ecdb6a2502dad7 Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 11 Jul 2019 11:05:09 +0200 +Subject: [PATCH] brcmfmac: clear events in brcmf_fweh_detach() will always + fail + +Clearing firmware events in brcmf_fweh_detach() is always failing +because it is called only upon driver remove and communication +with firmware is no longer possible. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 9 --------- + 1 file changed, 9 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +@@ -303,16 +303,7 @@ void brcmf_fweh_attach(struct brcmf_pub + void brcmf_fweh_detach(struct brcmf_pub *drvr) + { + struct brcmf_fweh_info *fweh = &drvr->fweh; +- struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); +- s8 eventmask[BRCMF_EVENTING_MASK_LEN]; + +- if (ifp) { +- /* clear all events */ +- memset(eventmask, 0, BRCMF_EVENTING_MASK_LEN); +- (void)brcmf_fil_iovar_data_set(ifp, "event_msgs", +- eventmask, +- BRCMF_EVENTING_MASK_LEN); +- } + /* cancel the worker */ + cancel_work_sync(&fweh->event_work); + WARN_ON(!list_empty(&fweh->event_q)); diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0005-brcmfmac-avoid-firmware-commands-when-bus-is-down.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0005-brcmfmac-avoid-firmware-commands-when-bus-is-down.patch new file mode 100644 index 0000000000..747cf58b7b --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/104-v5.4-0005-brcmfmac-avoid-firmware-commands-when-bus-is-down.patch @@ -0,0 +1,79 @@ +From 1ac11ae949dd883854f4523ef8e3a32aabfd6256 Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 11 Jul 2019 11:05:10 +0200 +Subject: [PATCH] brcmfmac: avoid firmware commands when bus is down + +Upon rmmod a few attempts are made to inform firmware, but there is +no point as the bus is down and these will fail. Avoid them to keep +the logs clean. + +Reported-by: Stefan Wahren +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 23 +++++++++++-------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -1286,17 +1286,21 @@ static void brcmf_link_down(struct brcmf + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); + struct brcmf_pub *drvr = cfg->pub; ++ bool bus_up = drvr->bus_if->state == BRCMF_BUS_UP; + s32 err = 0; + + brcmf_dbg(TRACE, "Enter\n"); + + if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) { +- brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n"); +- err = brcmf_fil_cmd_data_set(vif->ifp, +- BRCMF_C_DISASSOC, NULL, 0); +- if (err) { +- bphy_err(drvr, "WLC_DISASSOC failed (%d)\n", err); ++ if (bus_up) { ++ brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n"); ++ err = brcmf_fil_cmd_data_set(vif->ifp, ++ BRCMF_C_DISASSOC, NULL, 0); ++ if (err) ++ bphy_err(drvr, "WLC_DISASSOC failed (%d)\n", ++ err); + } ++ + if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) || + (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) + cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0, +@@ -1306,7 +1310,8 @@ static void brcmf_link_down(struct brcmf + clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); + brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0); + if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_NONE) { +- brcmf_set_pmk(vif->ifp, NULL, 0); ++ if (bus_up) ++ brcmf_set_pmk(vif->ifp, NULL, 0); + vif->profile.use_fwsup = BRCMF_PROFILE_FWSUP_NONE; + } + brcmf_dbg(TRACE, "Exit\n"); +@@ -5004,18 +5009,16 @@ static int brcmf_cfg80211_get_channel(st + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct net_device *ndev = wdev->netdev; + struct brcmf_pub *drvr = cfg->pub; +- struct brcmf_if *ifp; + struct brcmu_chan ch; + enum nl80211_band band = 0; + enum nl80211_chan_width width = 0; + u32 chanspec; + int freq, err; + +- if (!ndev) ++ if (!ndev || drvr->bus_if->state != BRCMF_BUS_UP) + return -ENODEV; +- ifp = netdev_priv(ndev); + +- err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec); ++ err = brcmf_fil_iovar_int_get(netdev_priv(ndev), "chanspec", &chanspec); + if (err) { + bphy_err(drvr, "chanspec failed (%d)\n", err); + return err; diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0006-brcmfmac-simply-remove-flowring-if-bus-is-down.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0006-brcmfmac-simply-remove-flowring-if-bus-is-down.patch new file mode 100644 index 0000000000..040ab16a6c --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/104-v5.4-0006-brcmfmac-simply-remove-flowring-if-bus-is-down.patch @@ -0,0 +1,33 @@ +From e0bfb9601d4812719167cc4124a0d6db1e2f55e4 Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 11 Jul 2019 11:05:11 +0200 +Subject: [PATCH] brcmfmac: simply remove flowring if bus is down + +When the bus is down, eg. due to rmmod, there is no need to +attempt to inform firmware about it. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -1398,6 +1398,13 @@ void brcmf_msgbuf_delete_flowring(struct + u8 ifidx; + int err; + ++ /* no need to submit if firmware can not be reached */ ++ if (drvr->bus_if->state != BRCMF_BUS_UP) { ++ brcmf_dbg(MSGBUF, "bus down, flowring will be removed\n"); ++ brcmf_msgbuf_remove_flowring(msgbuf, flowid); ++ return; ++ } ++ + commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT]; + brcmf_commonring_lock(commonring); + ret_ptr = brcmf_commonring_reserve_for_write(commonring); diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0007-brcmfmac-remove-unnecessary-strlcpy-upon-obtaining-v.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0007-brcmfmac-remove-unnecessary-strlcpy-upon-obtaining-v.patch new file mode 100644 index 0000000000..444546aaf7 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/104-v5.4-0007-brcmfmac-remove-unnecessary-strlcpy-upon-obtaining-v.patch @@ -0,0 +1,28 @@ +From 4b11c915f00caeef3292ed0429acc579b9da762a Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 11 Jul 2019 11:05:12 +0200 +Subject: [PATCH] brcmfmac: remove unnecessary strlcpy() upon obtaining "ver" + iovar + +Recently a strcpy() was replaced by strlcpy(). However, the strcpy() +was not needed in the first place. So removing that line of code. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -258,7 +258,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + + /* query for 'ver' to get version info from firmware */ + memset(buf, 0, sizeof(buf)); +- strlcpy(buf, "ver", sizeof(buf)); + err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf)); + if (err < 0) { + bphy_err(drvr, "Retrieving version information failed, %d\n", diff --git a/package/kernel/mac80211/patches/brcm/105-v5.4-brcmfmac-don-t-net_ratelimit-CONSOLE-messages-on-fir.patch b/package/kernel/mac80211/patches/brcm/105-v5.4-brcmfmac-don-t-net_ratelimit-CONSOLE-messages-on-fir.patch new file mode 100644 index 0000000000..60f6e49210 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/105-v5.4-brcmfmac-don-t-net_ratelimit-CONSOLE-messages-on-fir.patch @@ -0,0 +1,38 @@ +From e3b1d879ccda9ffd5332777bb1beeb2cc913faa8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sun, 21 Jul 2019 21:52:17 +0200 +Subject: [PATCH] brcmfmac: don't net_ratelimit() CONSOLE messages on firmware + crash +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Firmware crash is a pretty rare event and can't happen too frequently as +it has to be followed by a hardware reinitialization and config reload. +It should be safe to don't use net_ratelimit() when it happens. + +For reporting & debugging purposes it's important to provide a complete +log as the last lines are actually the most important. This change +modifies brcmfmac to print all messages in an unlimited way in that +specific case. With this change there should be finally a backtrace of +firmware finally visible after a crash. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -794,7 +794,8 @@ static void brcmf_pcie_bus_console_read( + if (ch == '\n') { + console->log_str[console->log_idx] = 0; + if (error) +- brcmf_err(bus, "CONSOLE: %s", console->log_str); ++ __brcmf_err(bus, __func__, "CONSOLE: %s", ++ console->log_str); + else + pr_debug("CONSOLE: %s", console->log_str); + console->log_idx = 0; diff --git a/package/kernel/mac80211/patches/brcm/106-v5.4-brcmfmac-remove-set-but-not-used-variable-dtim_perio.patch b/package/kernel/mac80211/patches/brcm/106-v5.4-brcmfmac-remove-set-but-not-used-variable-dtim_perio.patch new file mode 100644 index 0000000000..da0d8d5894 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/106-v5.4-brcmfmac-remove-set-but-not-used-variable-dtim_perio.patch @@ -0,0 +1,54 @@ +From cddecd92d1ec2fd05ed1123455e7c6cf6906b5a5 Mon Sep 17 00:00:00 2001 +From: YueHaibing +Date: Wed, 24 Jul 2019 22:12:01 +0800 +Subject: [PATCH] brcmfmac: remove set but not used variable 'dtim_period' + +Fixes gcc '-Wunused-but-set-variable' warning: + +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c: In function brcmf_update_bss_info: +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:2962:5: warning: variable dtim_period set but not used [-Wunused-but-set-variable] +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c: In function brcmf_update_bss_info: +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:2961:6: warning: variable beacon_interval set but not used [-Wunused-but-set-variable] + +They are never used so can be removed. + +Reported-by: Hulk Robot +Signed-off-by: YueHaibing +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2982,8 +2982,6 @@ static s32 brcmf_update_bss_info(struct + struct brcmf_pub *drvr = cfg->pub; + struct brcmf_bss_info_le *bi; + const struct brcmf_tlv *tim; +- u16 beacon_interval; +- u8 dtim_period; + size_t ie_len; + u8 *ie; + s32 err = 0; +@@ -3007,12 +3005,9 @@ static s32 brcmf_update_bss_info(struct + + ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset); + ie_len = le32_to_cpu(bi->ie_length); +- beacon_interval = le16_to_cpu(bi->beacon_period); + + tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM); +- if (tim) +- dtim_period = tim->data[1]; +- else { ++ if (!tim) { + /* + * active scan was done so we could not get dtim + * information out of probe response. +@@ -3024,7 +3019,6 @@ static s32 brcmf_update_bss_info(struct + bphy_err(drvr, "wl dtim_assoc failed (%d)\n", err); + goto update_bss_info_out; + } +- dtim_period = (u8)var; + } + + update_bss_info_out: diff --git a/package/kernel/mac80211/patches/brcm/107-v5.4-brcmfmac-remove-redundant-assignment-to-pointer-hash.patch b/package/kernel/mac80211/patches/brcm/107-v5.4-brcmfmac-remove-redundant-assignment-to-pointer-hash.patch new file mode 100644 index 0000000000..84573af23e --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/107-v5.4-brcmfmac-remove-redundant-assignment-to-pointer-hash.patch @@ -0,0 +1,26 @@ +From 73c742bb9c9ba30871fdd5c730d5ca8b6712833a Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Fri, 9 Aug 2019 18:22:17 +0100 +Subject: [PATCH] brcmfmac: remove redundant assignment to pointer hash + +The pointer hash is being initialized with a value that is never read +and is being re-assigned a little later on. The assignment is +redundant and hence can be removed. + +Addresses-Coverity: ("Unused value") +Signed-off-by: Colin Ian King +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -1468,7 +1468,6 @@ static int brcmf_msgbuf_stats_read(struc + seq_printf(seq, "\nh2d_flowrings: depth %u\n", + BRCMF_H2D_TXFLOWRING_MAX_ITEM); + seq_puts(seq, "Active flowrings:\n"); +- hash = msgbuf->flow->hash; + for (i = 0; i < msgbuf->flow->nrofrings; i++) { + if (!msgbuf->flow->rings[i]) + continue; diff --git a/package/kernel/mac80211/patches/brcm/108-v5.4-brcmfmac-replace-strncpy-by-strscpy.patch b/package/kernel/mac80211/patches/brcm/108-v5.4-brcmfmac-replace-strncpy-by-strscpy.patch new file mode 100644 index 0000000000..5efe6a8f14 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/108-v5.4-brcmfmac-replace-strncpy-by-strscpy.patch @@ -0,0 +1,36 @@ +From 5f42b382ead278c1f6c3854765c97eb20491aa2a Mon Sep 17 00:00:00 2001 +From: Xulin Sun +Date: Fri, 23 Aug 2019 15:47:08 +0800 +Subject: [PATCH] brcmfmac: replace strncpy() by strscpy() + +The strncpy() may truncate the copied string, +replace it by the safer strscpy(). + +To avoid below compile warning with gcc 8.2: + +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:In function 'brcmf_vndr_ie': +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:4227:2: +warning: 'strncpy' output truncated before terminating nul copying 3 bytes from a string of the same length [-Wstringop-truncation] + strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Xulin Sun +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -4244,9 +4244,7 @@ next: + static u32 + brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd) + { +- +- strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1); +- iebuf[VNDR_IE_CMD_LEN - 1] = '\0'; ++ strscpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN); + + put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]); + diff --git a/package/kernel/mac80211/patches/brcm/109-v5.4-brcmfmac-get-chip-s-default-RAM-info-during-PCIe-set.patch b/package/kernel/mac80211/patches/brcm/109-v5.4-brcmfmac-get-chip-s-default-RAM-info-during-PCIe-set.patch new file mode 100644 index 0000000000..b04e78c70e --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/109-v5.4-brcmfmac-get-chip-s-default-RAM-info-during-PCIe-set.patch @@ -0,0 +1,80 @@ +From 82f93cf46d6007ffa003b2d4a2834563b6b84d21 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 29 Aug 2019 10:27:01 +0200 +Subject: [PATCH] brcmfmac: get chip's default RAM info during PCIe setup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Getting RAM info just once per driver's lifetime (during chip +recognition) is not enough as it may get adjusted later (depending on +the used firmware). Subsequent inits may load different firmwares so a +full RAM recognition is required on every PCIe setup. This is especially +important since implementing hardware reset on a firmware crash. + +Moreover calling brcmf_chip_get_raminfo() makes sure that RAM core is +up. It's important as having BCMA_CORE_SYS_MEM down on BCM4366 was +resulting in firmware failing to initialize and following error: +[ 65.657546] brcmfmac 0000:01:00.0: brcmf_pcie_download_fw_nvram: Invalid shared RAM address 0x04000001 + +This change makes brcmf_chip_get_raminfo() call during chip recognition +redundant for PCIe devices but SDIO and USB still need it and it's a +very small overhead anyway. + +Fixes: 4684997d9eea ("brcmfmac: reset PCIe bus on a firmware crash") +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 6 ++++-- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h | 1 + + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 6 ++++++ + 3 files changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -696,8 +696,10 @@ static u32 brcmf_chip_tcm_rambase(struct + return 0; + } + +-static int brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) ++int brcmf_chip_get_raminfo(struct brcmf_chip *pub) + { ++ struct brcmf_chip_priv *ci = container_of(pub, struct brcmf_chip_priv, ++ pub); + struct brcmf_core_priv *mem_core; + struct brcmf_core *mem; + +@@ -979,7 +981,7 @@ static int brcmf_chip_recognition(struct + brcmf_chip_set_passive(&ci->pub); + } + +- return brcmf_chip_get_raminfo(ci); ++ return brcmf_chip_get_raminfo(&ci->pub); + } + + static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h +@@ -69,6 +69,7 @@ struct brcmf_buscore_ops { + void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec); + }; + ++int brcmf_chip_get_raminfo(struct brcmf_chip *pub); + struct brcmf_chip *brcmf_chip_attach(void *ctx, + const struct brcmf_buscore_ops *ops); + void brcmf_chip_detach(struct brcmf_chip *chip); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1770,6 +1770,12 @@ static void brcmf_pcie_setup(struct devi + nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len; + kfree(fwreq); + ++ ret = brcmf_chip_get_raminfo(devinfo->ci); ++ if (ret) { ++ brcmf_err(bus, "Failed to get RAM info\n"); ++ goto fail; ++ } ++ + /* Some of the firmwares have the size of the memory of the device + * defined inside the firmware. This is because part of the memory in + * the device is shared and the devision is determined by FW. Parse diff --git a/package/kernel/mac80211/patches/brcm/110-v5.4-0001-brcmfmac-add-stub-version-of-brcmf_debugfs_get_devdi.patch b/package/kernel/mac80211/patches/brcm/110-v5.4-0001-brcmfmac-add-stub-version-of-brcmf_debugfs_get_devdi.patch new file mode 100644 index 0000000000..3fbf0dedd9 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/110-v5.4-0001-brcmfmac-add-stub-version-of-brcmf_debugfs_get_devdi.patch @@ -0,0 +1,31 @@ +From cb34212b1c25f7656a315f956d72696777e88340 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sun, 1 Sep 2019 13:34:35 +0200 +Subject: [PATCH] brcmfmac: add stub version of brcmf_debugfs_get_devdir() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In case of compiling driver without DEBUG expose a stub function to make +writing debug code much simpler (no extra conditions). This will allow +e.g. using debugfs_create_file() without any magic if or #ifdef. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h +@@ -121,6 +121,10 @@ int brcmf_debugfs_add_entry(struct brcmf + int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, + size_t len); + #else ++static inline struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) ++{ ++ return ERR_PTR(-ENOENT); ++} + static inline + int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, + int (*read_fn)(struct seq_file *seq, void *data)) diff --git a/package/kernel/mac80211/patches/brcm/110-v5.4-0002-brcmfmac-add-reset-debugfs-entry-for-testing-reset.patch b/package/kernel/mac80211/patches/brcm/110-v5.4-0002-brcmfmac-add-reset-debugfs-entry-for-testing-reset.patch new file mode 100644 index 0000000000..b3d01477a6 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/110-v5.4-0002-brcmfmac-add-reset-debugfs-entry-for-testing-reset.patch @@ -0,0 +1,59 @@ +From 2f8c8e62cd50d72ac68de884a09c6f5a969a269c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sun, 1 Sep 2019 13:34:36 +0200 +Subject: [PATCH] brcmfmac: add "reset" debugfs entry for testing reset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is a trivial debugfs entry for triggering reset just like in case +of firmware crash. It works by writing 1 to it: +echo 1 > reset + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/core.c | 25 +++++++++++++++++++ + 1 file changed, 25 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1107,6 +1107,29 @@ static void brcmf_core_bus_reset(struct + brcmf_bus_reset(drvr->bus_if); + } + ++static ssize_t bus_reset_write(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct brcmf_pub *drvr = file->private_data; ++ u8 value; ++ ++ if (kstrtou8_from_user(user_buf, count, 0, &value)) ++ return -EINVAL; ++ ++ if (value != 1) ++ return -EINVAL; ++ ++ schedule_work(&drvr->bus_reset); ++ ++ return count; ++} ++ ++static const struct file_operations bus_reset_fops = { ++ .open = simple_open, ++ .llseek = no_llseek, ++ .write = bus_reset_write, ++}; ++ + static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops) + { + int ret = -1; +@@ -1182,6 +1205,8 @@ static int brcmf_bus_started(struct brcm + + /* populate debugfs */ + brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); ++ debugfs_create_file("reset", 0600, brcmf_debugfs_get_devdir(drvr), drvr, ++ &bus_reset_fops); + brcmf_feat_debugfs_create(drvr); + brcmf_proto_debugfs_create(drvr); + brcmf_bus_debugfs_create(bus_if); diff --git a/package/kernel/mac80211/patches/brcm/111-v5.4-brcmfmac-use-ph-to-print-small-buffer.patch b/package/kernel/mac80211/patches/brcm/111-v5.4-brcmfmac-use-ph-to-print-small-buffer.patch new file mode 100644 index 0000000000..9576b2b5b2 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/111-v5.4-brcmfmac-use-ph-to-print-small-buffer.patch @@ -0,0 +1,58 @@ +From 0e48b86d9a8f5c695bb02c9c02f6dc7d2ec8f2e2 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Wed, 4 Sep 2019 20:50:52 +0300 +Subject: [PATCH] brcmfmac: use %*ph to print small buffer + +Use %*ph format to print small buffer as hex string. + +Signed-off-by: Andy Shevchenko +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -4222,10 +4222,8 @@ brcmf_parse_vndr_ies(const u8 *vndr_ie_b + + vndr_ies->count++; + +- brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n", +- parsed_info->vndrie.oui[0], +- parsed_info->vndrie.oui[1], +- parsed_info->vndrie.oui[2], ++ brcmf_dbg(TRACE, "** OUI %3ph, type 0x%02x\n", ++ parsed_info->vndrie.oui, + parsed_info->vndrie.oui_type); + + if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT) +@@ -4349,12 +4347,10 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c + for (i = 0; i < old_vndr_ies.count; i++) { + vndrie_info = &old_vndr_ies.ie_info[i]; + +- brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n", ++ brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%3ph\n", + vndrie_info->vndrie.id, + vndrie_info->vndrie.len, +- vndrie_info->vndrie.oui[0], +- vndrie_info->vndrie.oui[1], +- vndrie_info->vndrie.oui[2]); ++ vndrie_info->vndrie.oui); + + del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag, + vndrie_info->ie_ptr, +@@ -4386,12 +4382,10 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c + remained_buf_len -= (vndrie_info->ie_len + + VNDR_IE_VSIE_OFFSET); + +- brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n", ++ brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%3ph\n", + vndrie_info->vndrie.id, + vndrie_info->vndrie.len, +- vndrie_info->vndrie.oui[0], +- vndrie_info->vndrie.oui[1], +- vndrie_info->vndrie.oui[2]); ++ vndrie_info->vndrie.oui); + + del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag, + vndrie_info->ie_ptr, diff --git a/package/kernel/mac80211/patches/brcm/112-v5.4-0001-brcmfmac-move-cfg80211_ops-pointer-to-another-struct.patch b/package/kernel/mac80211/patches/brcm/112-v5.4-0001-brcmfmac-move-cfg80211_ops-pointer-to-another-struct.patch new file mode 100644 index 0000000000..653251feff --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/112-v5.4-0001-brcmfmac-move-cfg80211_ops-pointer-to-another-struct.patch @@ -0,0 +1,95 @@ +From ba76ff25ee64d5cfc86209d1fbb3c294b2c04412 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 3 Sep 2019 06:29:26 +0200 +Subject: [PATCH 1/3] brcmfmac: move "cfg80211_ops" pointer to another struct +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This moves "ops" pointer from "struct brcmf_cfg80211_info" to the +"struct brcmf_pub". This movement makes it possible to allocate wiphy +without attaching cfg80211 (brcmf_cfg80211_attach()). It's required for +later separation of wiphy allocation and driver initialization. + +While at it fix also an unlikely memory leak in the brcmf_attach(). + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 1 - + .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | 1 - + drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 9 ++++++--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | 1 + + 4 files changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -7202,7 +7202,6 @@ void brcmf_cfg80211_detach(struct brcmf_ + brcmf_pno_detach(cfg); + brcmf_btcoex_detach(cfg); + wiphy_unregister(cfg->wiphy); +- kfree(cfg->ops); + wl_deinit_priv(cfg); + brcmf_free_wiphy(cfg->wiphy); + kfree(cfg); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -292,7 +292,6 @@ struct brcmf_cfg80211_wowl { + */ + struct brcmf_cfg80211_info { + struct wiphy *wiphy; +- struct cfg80211_ops *ops; + struct brcmf_cfg80211_conf *conf; + struct brcmf_p2p_info p2p; + struct brcmf_btcoex_info *btcoex; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1245,12 +1245,15 @@ int brcmf_attach(struct device *dev, str + return -ENOMEM; + + wiphy = wiphy_new(ops, sizeof(*drvr)); +- if (!wiphy) ++ if (!wiphy) { ++ kfree(ops); + return -ENOMEM; ++ } + + set_wiphy_dev(wiphy, dev); + drvr = wiphy_priv(wiphy); + drvr->wiphy = wiphy; ++ drvr->ops = ops; + + for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) + drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; +@@ -1283,12 +1286,10 @@ int brcmf_attach(struct device *dev, str + goto fail; + } + +- drvr->config->ops = ops; + return 0; + + fail: + brcmf_detach(dev); +- kfree(ops); + + return ret; + } +@@ -1374,6 +1375,8 @@ void brcmf_detach(struct device *dev) + + bus_if->drvr = NULL; + ++ kfree(drvr->ops); ++ + wiphy_free(drvr->wiphy); + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -97,6 +97,7 @@ struct brcmf_pub { + struct brcmf_bus *bus_if; + struct brcmf_proto *proto; + struct wiphy *wiphy; ++ struct cfg80211_ops *ops; + struct brcmf_cfg80211_info *config; + + /* Internal brcmf items */ diff --git a/package/kernel/mac80211/patches/brcm/112-v5.4-0002-brcmfmac-split-brcmf_attach-and-brcmf_detach-functio.patch b/package/kernel/mac80211/patches/brcm/112-v5.4-0002-brcmfmac-split-brcmf_attach-and-brcmf_detach-functio.patch new file mode 100644 index 0000000000..e0b2c7dd21 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/112-v5.4-0002-brcmfmac-split-brcmf_attach-and-brcmf_detach-functio.patch @@ -0,0 +1,266 @@ +From 450914c39f88d1adada26256360dea7050ff4e83 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 3 Sep 2019 06:29:27 +0200 +Subject: [PATCH 2/3] brcmfmac: split brcmf_attach() and brcmf_detach() + functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Move code allocating/freeing wiphy out of above functions. This will +allow reinitializing the driver (e.g. on some error) without allocating +a new wiphy. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/bus.h | 4 ++- + .../broadcom/brcm80211/brcmfmac/core.c | 33 ++++++++++++++---- + .../broadcom/brcm80211/brcmfmac/pcie.c | 13 +++++-- + .../broadcom/brcm80211/brcmfmac/sdio.c | 15 ++++++-- + .../broadcom/brcm80211/brcmfmac/usb.c | 34 +++++++++++++++---- + 5 files changed, 80 insertions(+), 19 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -254,10 +254,12 @@ void brcmf_rx_frame(struct device *dev, + /* Receive async event packet from firmware. Callee disposes of rxp. */ + void brcmf_rx_event(struct device *dev, struct sk_buff *rxp); + ++int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings); + /* Indication from bus module regarding presence/insertion of dongle. */ +-int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings); ++int brcmf_attach(struct device *dev); + /* Indication from bus module regarding removal/absence of dongle */ + void brcmf_detach(struct device *dev); ++void brcmf_free(struct device *dev); + /* Indication from bus module that dongle should be reset */ + void brcmf_dev_reset(struct device *dev); + /* Request from bus module to initiate a coredump */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1230,13 +1230,11 @@ fail: + return ret; + } + +-int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) ++int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings) + { + struct wiphy *wiphy; + struct cfg80211_ops *ops; + struct brcmf_pub *drvr = NULL; +- int ret = 0; +- int i; + + brcmf_dbg(TRACE, "Enter\n"); + +@@ -1254,6 +1252,21 @@ int brcmf_attach(struct device *dev, str + drvr = wiphy_priv(wiphy); + drvr->wiphy = wiphy; + drvr->ops = ops; ++ drvr->bus_if = dev_get_drvdata(dev); ++ drvr->bus_if->drvr = drvr; ++ drvr->settings = settings; ++ ++ return 0; ++} ++ ++int brcmf_attach(struct device *dev) ++{ ++ struct brcmf_bus *bus_if = dev_get_drvdata(dev); ++ struct brcmf_pub *drvr = bus_if->drvr; ++ int ret = 0; ++ int i; ++ ++ brcmf_dbg(TRACE, "Enter\n"); + + for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) + drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; +@@ -1262,9 +1275,6 @@ int brcmf_attach(struct device *dev, str + + /* Link to bus module */ + drvr->hdrlen = 0; +- drvr->bus_if = dev_get_drvdata(dev); +- drvr->bus_if->drvr = drvr; +- drvr->settings = settings; + + /* Attach and link in the protocol */ + ret = brcmf_proto_attach(drvr); +@@ -1280,7 +1290,7 @@ int brcmf_attach(struct device *dev, str + /* attach firmware event handler */ + brcmf_fweh_attach(drvr); + +- ret = brcmf_bus_started(drvr, ops); ++ ret = brcmf_bus_started(drvr, drvr->ops); + if (ret != 0) { + bphy_err(drvr, "dongle is not responding: err=%d\n", ret); + goto fail; +@@ -1372,6 +1382,15 @@ void brcmf_detach(struct device *dev) + brcmf_cfg80211_detach(drvr->config); + drvr->config = NULL; + } ++} ++ ++void brcmf_free(struct device *dev) ++{ ++ struct brcmf_bus *bus_if = dev_get_drvdata(dev); ++ struct brcmf_pub *drvr = bus_if->drvr; ++ ++ if (!drvr) ++ return; + + bus_if->drvr = NULL; + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1430,6 +1430,7 @@ static int brcmf_pcie_reset(struct devic + brcmf_pcie_bus_console_read(devinfo, true); + + brcmf_detach(dev); ++ brcmf_free(dev); + + brcmf_pcie_release_irq(devinfo); + brcmf_pcie_release_scratchbuffers(devinfo); +@@ -1824,11 +1825,18 @@ static void brcmf_pcie_setup(struct devi + + brcmf_pcie_intr_enable(devinfo); + brcmf_pcie_hostready(devinfo); +- if (brcmf_attach(&devinfo->pdev->dev, devinfo->settings) == 0) +- return; ++ ++ ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings); ++ if (ret) ++ goto fail; ++ ret = brcmf_attach(&devinfo->pdev->dev); ++ if (ret) ++ goto fail; + + brcmf_pcie_bus_console_read(devinfo, false); + ++ return; ++ + fail: + device_release_driver(dev); + } +@@ -1971,6 +1979,7 @@ brcmf_pcie_remove(struct pci_dev *pdev) + brcmf_pcie_intr_disable(devinfo); + + brcmf_detach(&pdev->dev); ++ brcmf_free(&pdev->dev); + + kfree(bus->bus_priv.pcie); + kfree(bus->msgbuf->flowrings); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -4247,17 +4247,26 @@ static void brcmf_sdio_firmware_callback + sdiod->bus_if->chip = bus->ci->chip; + sdiod->bus_if->chiprev = bus->ci->chiprev; + ++ err = brcmf_alloc(sdiod->dev, sdiod->settings); ++ if (err) { ++ brcmf_err("brcmf_alloc failed\n"); ++ goto claim; ++ } ++ + /* Attach to the common layer, reserve hdr space */ +- err = brcmf_attach(sdiod->dev, sdiod->settings); ++ err = brcmf_attach(sdiod->dev); + if (err != 0) { + brcmf_err("brcmf_attach failed\n"); +- sdio_claim_host(sdiod->func1); +- goto checkdied; ++ goto free; + } + + /* ready */ + return; + ++free: ++ brcmf_free(sdiod->dev); ++claim: ++ sdio_claim_host(sdiod->func1); + checkdied: + brcmf_sdio_checkdied(bus); + release: +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -1178,8 +1178,12 @@ static void brcmf_usb_probe_phase2(struc + if (ret) + goto error; + ++ ret = brcmf_alloc(devinfo->dev, devinfo->settings); ++ if (ret) ++ goto error; ++ + /* Attach to the common driver interface */ +- ret = brcmf_attach(devinfo->dev, devinfo->settings); ++ ret = brcmf_attach(devinfo->dev); + if (ret) + goto error; + +@@ -1251,7 +1255,10 @@ static int brcmf_usb_probe_cb(struct brc + } + + if (!brcmf_usb_dlneeded(devinfo)) { +- ret = brcmf_attach(devinfo->dev, devinfo->settings); ++ ret = brcmf_alloc(devinfo->dev, devinfo->settings); ++ if (ret) ++ goto fail; ++ ret = brcmf_attach(devinfo->dev); + if (ret) + goto fail; + /* we are done */ +@@ -1279,6 +1286,7 @@ static int brcmf_usb_probe_cb(struct brc + + fail: + /* Release resources in reverse order */ ++ brcmf_free(devinfo->dev); + kfree(bus); + brcmf_usb_detach(devinfo); + return ret; +@@ -1292,6 +1300,7 @@ brcmf_usb_disconnect_cb(struct brcmf_usb + brcmf_dbg(USB, "Enter, bus_pub %p\n", devinfo); + + brcmf_detach(devinfo->dev); ++ brcmf_free(devinfo->dev); + kfree(devinfo->bus_pub.bus); + brcmf_usb_detach(devinfo); + } +@@ -1435,10 +1444,12 @@ static int brcmf_usb_suspend(struct usb_ + + brcmf_dbg(USB, "Enter\n"); + devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP; +- if (devinfo->wowl_enabled) ++ if (devinfo->wowl_enabled) { + brcmf_cancel_all_urbs(devinfo); +- else ++ } else { + brcmf_detach(&usb->dev); ++ brcmf_free(&usb->dev); ++ } + return 0; + } + +@@ -1451,8 +1462,19 @@ static int brcmf_usb_resume(struct usb_i + struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); + + brcmf_dbg(USB, "Enter\n"); +- if (!devinfo->wowl_enabled) +- return brcmf_attach(devinfo->dev, devinfo->settings); ++ if (!devinfo->wowl_enabled) { ++ int err; ++ ++ err = brcmf_alloc(&usb->dev, devinfo->settings); ++ if (err) ++ return err; ++ ++ err = brcmf_attach(devinfo->dev); ++ if (err) { ++ brcmf_free(devinfo->dev); ++ return err; ++ } ++ } + + devinfo->bus_pub.state = BRCMFMAC_USB_STATE_UP; + brcmf_usb_rx_fill_all(devinfo); diff --git a/package/kernel/mac80211/patches/brcm/112-v5.4-0003-brcmfmac-don-t-realloc-wiphy-during-PCIe-reset.patch b/package/kernel/mac80211/patches/brcm/112-v5.4-0003-brcmfmac-don-t-realloc-wiphy-during-PCIe-reset.patch new file mode 100644 index 0000000000..511f24dd72 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/112-v5.4-0003-brcmfmac-don-t-realloc-wiphy-during-PCIe-reset.patch @@ -0,0 +1,51 @@ +From a1f5aac1765afbeace9581afa27da34085f68e1d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 3 Sep 2019 06:29:28 +0200 +Subject: [PATCH 3/3] brcmfmac: don't realloc wiphy during PCIe reset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Providing a new wiphy on every PCIe reset was confusing and was causing +configuration problems for some users (supplicant and authenticators). +Sticking to the existing wiphy should make error recovery much simpler +and more reliable. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1430,7 +1430,6 @@ static int brcmf_pcie_reset(struct devic + brcmf_pcie_bus_console_read(devinfo, true); + + brcmf_detach(dev); +- brcmf_free(dev); + + brcmf_pcie_release_irq(devinfo); + brcmf_pcie_release_scratchbuffers(devinfo); +@@ -1826,9 +1825,6 @@ static void brcmf_pcie_setup(struct devi + brcmf_pcie_intr_enable(devinfo); + brcmf_pcie_hostready(devinfo); + +- ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings); +- if (ret) +- goto fail; + ret = brcmf_attach(&devinfo->pdev->dev); + if (ret) + goto fail; +@@ -1931,6 +1927,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, c + bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot); + dev_set_drvdata(&pdev->dev, bus); + ++ ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings); ++ if (ret) ++ goto fail_bus; ++ + fwreq = brcmf_pcie_prepare_fw_request(devinfo); + if (!fwreq) { + ret = -ENOMEM; diff --git a/package/kernel/mac80211/patches/build/050-lib80211_option.patch b/package/kernel/mac80211/patches/build/050-lib80211_option.patch index 1578286c2b..721e59661d 100644 --- a/package/kernel/mac80211/patches/build/050-lib80211_option.patch +++ b/package/kernel/mac80211/patches/build/050-lib80211_option.patch @@ -9,7 +9,7 @@ depends on m default n help -@@ -196,18 +196,18 @@ config LIB80211 +@@ -196,16 +196,16 @@ config LIB80211 Drivers should select this themselves if needed. config LIB80211_CRYPT_WEP @@ -22,8 +22,6 @@ - tristate + tristate "lib80211 CCMP support" depends on m - depends on CRYPTO_AES - depends on CRYPTO_CCM config LIB80211_CRYPT_TKIP - tristate diff --git a/package/kernel/mac80211/patches/rt2x00/010-rt2x00-clear-IV-s-on-start-to-fix-AP-mode-regression.patch b/package/kernel/mac80211/patches/rt2x00/010-rt2x00-clear-IV-s-on-start-to-fix-AP-mode-regression.patch new file mode 100644 index 0000000000..8859c0dd9e --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/010-rt2x00-clear-IV-s-on-start-to-fix-AP-mode-regression.patch @@ -0,0 +1,113 @@ +From patchwork Mon Aug 19 11:20:07 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 11100685 +X-Patchwork-Delegate: kvalo@adurom.com +Return-Path: +From: Stanislaw Gruszka +To: linux-wireless@vger.kernel.org +Subject: [PATCH 5.3] rt2x00: clear IV's on start to fix AP mode regression +Date: Mon, 19 Aug 2019 13:20:07 +0200 +Message-Id: <1566213607-6723-1-git-send-email-sgruszka@redhat.com> +Sender: linux-wireless-owner@vger.kernel.org +List-ID: +X-Mailing-List: linux-wireless@vger.kernel.org + +To do not brake HW restart we should keep initialization vectors data. +I assumed that on start the data is already initialized to zeros, but +that not true on some scenarios and we should clear it. So add +additional flag to check if we are under HW restart and clear IV's +data if we are not. + +Patch fixes AP mode regression. + +Reported-and-tested-by: Emil Karlson +Fixes: 710e6cc1595e ("rt2800: do not nullify initialization vector data") +Signed-off-by: Stanislaw Gruszka +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 9 +++++++++ + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 + + drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 13 ++++++++----- + 3 files changed, 18 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -6095,6 +6095,15 @@ static int rt2800_init_registers(struct + } + + /* ++ * Clear encryption initialization vectors on start, but keep them ++ * for watchdog reset. Otherwise we will have wrong IVs and not be ++ * able to keep connections after reset. ++ */ ++ if (!test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags)) ++ for (i = 0; i < 256; i++) ++ rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); ++ ++ /* + * Clear all beacons + */ + for (i = 0; i < 8; i++) +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -658,6 +658,7 @@ enum rt2x00_state_flags { + DEVICE_STATE_ENABLED_RADIO, + DEVICE_STATE_SCANNING, + DEVICE_STATE_FLUSHING, ++ DEVICE_STATE_RESET, + + /* + * Driver configuration +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -1256,13 +1256,14 @@ static int rt2x00lib_initialize(struct r + + int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) + { +- int retval; ++ int retval = 0; + + if (test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) { + /* + * This is special case for ieee80211_restart_hw(), otherwise + * mac80211 never call start() two times in row without stop(); + */ ++ set_bit(DEVICE_STATE_RESET, &rt2x00dev->flags); + rt2x00dev->ops->lib->pre_reset_hw(rt2x00dev); + rt2x00lib_stop(rt2x00dev); + } +@@ -1273,14 +1274,14 @@ int rt2x00lib_start(struct rt2x00_dev *r + */ + retval = rt2x00lib_load_firmware(rt2x00dev); + if (retval) +- return retval; ++ goto out; + + /* + * Initialize the device. + */ + retval = rt2x00lib_initialize(rt2x00dev); + if (retval) +- return retval; ++ goto out; + + rt2x00dev->intf_ap_count = 0; + rt2x00dev->intf_sta_count = 0; +@@ -1289,11 +1290,13 @@ int rt2x00lib_start(struct rt2x00_dev *r + /* Enable the radio */ + retval = rt2x00lib_enable_radio(rt2x00dev); + if (retval) +- return retval; ++ goto out; + + set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags); + +- return 0; ++out: ++ clear_bit(DEVICE_STATE_RESET, &rt2x00dev->flags); ++ return retval; + } + + void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev) diff --git a/package/kernel/mac80211/patches/rt2x00/011-rt2x00-clear-up-IV-s-on-key-removal.patch b/package/kernel/mac80211/patches/rt2x00/011-rt2x00-clear-up-IV-s-on-key-removal.patch new file mode 100644 index 0000000000..7f3f139e9f --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/011-rt2x00-clear-up-IV-s-on-key-removal.patch @@ -0,0 +1,55 @@ +From patchwork Fri Aug 23 12:48:03 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 11111605 +X-Patchwork-Delegate: kvalo@adurom.com +From: Stanislaw Gruszka +To: linux-wireless@vger.kernel.org +Subject: [PATCH 5.3] rt2x00: clear up IV's on key removal +Date: Fri, 23 Aug 2019 14:48:03 +0200 +Message-Id: <1566564483-31088-1-git-send-email-sgruszka@redhat.com> +Sender: linux-wireless-owner@vger.kernel.org +List-ID: +X-Mailing-List: linux-wireless@vger.kernel.org + +After looking at code I realized that my previous fix +95844124385e ("rt2x00: clear IV's on start to fix AP mode regression") +was incomplete. We can still have wrong IV's after re-keyring. +To fix that, clear up IV's also on key removal. + +Fixes: 710e6cc1595e ("rt2800: do not nullify initialization vector data") +Signed-off-by: Stanislaw Gruszka +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -1654,13 +1654,18 @@ static void rt2800_config_wcid_attr_ciph + + offset = MAC_IVEIV_ENTRY(key->hw_key_idx); + +- rt2800_register_multiread(rt2x00dev, offset, +- &iveiv_entry, sizeof(iveiv_entry)); +- if ((crypto->cipher == CIPHER_TKIP) || +- (crypto->cipher == CIPHER_TKIP_NO_MIC) || +- (crypto->cipher == CIPHER_AES)) +- iveiv_entry.iv[3] |= 0x20; +- iveiv_entry.iv[3] |= key->keyidx << 6; ++ if (crypto->cmd == SET_KEY) { ++ rt2800_register_multiread(rt2x00dev, offset, ++ &iveiv_entry, sizeof(iveiv_entry)); ++ if ((crypto->cipher == CIPHER_TKIP) || ++ (crypto->cipher == CIPHER_TKIP_NO_MIC) || ++ (crypto->cipher == CIPHER_AES)) ++ iveiv_entry.iv[3] |= 0x20; ++ iveiv_entry.iv[3] |= key->keyidx << 6; ++ } else { ++ memset(&iveiv_entry, 0, sizeof(iveiv_entry)); ++ } ++ + rt2800_register_multiwrite(rt2x00dev, offset, + &iveiv_entry, sizeof(iveiv_entry)); + } diff --git a/package/kernel/mac80211/patches/rt2x00/015-rt2x00-do-not-set-IEEE80211_TX_STAT_AMPDU_NO_BACK-on-tx-status.patch b/package/kernel/mac80211/patches/rt2x00/015-rt2x00-do-not-set-IEEE80211_TX_STAT_AMPDU_NO_BACK-on-tx-status.patch new file mode 100644 index 0000000000..a4497df475 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/015-rt2x00-do-not-set-IEEE80211_TX_STAT_AMPDU_NO_BACK-on-tx-status.patch @@ -0,0 +1,50 @@ +From patchwork Fri Aug 23 07:09:56 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 11110703 +X-Patchwork-Delegate: kvalo@adurom.com +From: Stanislaw Gruszka +To: linux-wireless@vger.kernel.org +Subject: [PATCH] rt2x00: do not set IEEE80211_TX_STAT_AMPDU_NO_BACK on tx + status +Date: Fri, 23 Aug 2019 09:09:56 +0200 +Message-Id: <1566544196-20371-1-git-send-email-sgruszka@redhat.com> +Sender: linux-wireless-owner@vger.kernel.org +List-ID: +X-Mailing-List: linux-wireless@vger.kernel.org + +According to documentation IEEE80211_TX_STAT_AMPDU_NO_BACK is suppose +to be used when we do not recive BA (BlockAck). However on rt2x00 we +use it when remote station fail to decode one or more subframes within +AMPDU (some bits are not set in BlockAck bitmap). Setting the flag result +in sent of BAR (BlockAck Request) frame and this might result of abuse +of BA session, since remote station can sent BA with incorrect +sequence numbers after receiving BAR. This problem is visible especially +when connecting two rt2800 devices. + +Previously I observed some performance benefits when using the flag +when connecting with iwlwifi devices. But currently possibly due +to reacent changes in rt2x00 removing the flag has no effect on +those test cases. + +So remove the IEEE80211_TX_STAT_AMPDU_NO_BACK. + +Signed-off-by: Stanislaw Gruszka +--- + drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -371,9 +371,6 @@ static void rt2x00lib_fill_tx_status(str + IEEE80211_TX_CTL_AMPDU; + tx_info->status.ampdu_len = 1; + tx_info->status.ampdu_ack_len = success ? 1 : 0; +- +- if (!success) +- tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; + } + + if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { diff --git a/package/kernel/mac80211/patches/rt2x00/016-rt2x00-revert-rt2800-enable-TX_PIN_CFG_LNA_PE_-bits-per-band.patch b/package/kernel/mac80211/patches/rt2x00/016-rt2x00-revert-rt2800-enable-TX_PIN_CFG_LNA_PE_-bits-per-band.patch new file mode 100644 index 0000000000..3fcf231870 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/016-rt2x00-revert-rt2800-enable-TX_PIN_CFG_LNA_PE_-bits-per-band.patch @@ -0,0 +1,70 @@ +From patchwork Thu Aug 29 11:29:59 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 11121089 +X-Patchwork-Delegate: kvalo@adurom.com +From: Stanislaw Gruszka +To: linux-wireless@vger.kernel.org +Subject: [PATCH 5.3] Revert "rt2800: enable TX_PIN_CFG_LNA_PE_ bits per band" +Date: Thu, 29 Aug 2019 13:29:59 +0200 +Message-Id: <1567078199-3645-1-git-send-email-sgruszka@redhat.com> +Sender: linux-wireless-owner@vger.kernel.org +List-ID: +X-Mailing-List: linux-wireless@vger.kernel.org + +This reverts commit 9ad3b55654455258a9463384edb40077439d879f. + +As reported by Sergey: + +"I got some problem after upgrade kernel to 5.2 version (debian testing +linux-image-5.2.0-2-amd64). 5Ghz client stopped to see AP. +Some tests with 1metre distance between client-AP: 2.4Ghz -22dBm, for +5Ghz - 53dBm !, for longer distance (8m + walls) 2.4 - 61dBm, 5Ghz not +visible." + +It was identified that rx signal level degradation was caused by +9ad3b5565445 ("rt2800: enable TX_PIN_CFG_LNA_PE_ bits per band"). +So revert this commit. + +Cc: # v5.1+ +Reported-and-tested-by: Sergey Maranchuk +Signed-off-by: Stanislaw Gruszka +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -4242,24 +4242,18 @@ static void rt2800_config_channel(struct + switch (rt2x00dev->default_ant.rx_chain_num) { + case 3: + /* Turn on tertiary LNAs */ +- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, +- rf->channel > 14); +- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, +- rf->channel <= 14); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, 1); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, 1); + /* fall-through */ + case 2: + /* Turn on secondary LNAs */ +- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, +- rf->channel > 14); +- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, +- rf->channel <= 14); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); + /* fall-through */ + case 1: + /* Turn on primary LNAs */ +- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, +- rf->channel > 14); +- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, +- rf->channel <= 14); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1); + break; + } + diff --git a/package/kernel/mac80211/patches/rt2x00/017-rt2x00-initialize-last_reset.patch b/package/kernel/mac80211/patches/rt2x00/017-rt2x00-initialize-last_reset.patch index a362340918..034bfdf757 100644 --- a/package/kernel/mac80211/patches/rt2x00/017-rt2x00-initialize-last_reset.patch +++ b/package/kernel/mac80211/patches/rt2x00/017-rt2x00-initialize-last_reset.patch @@ -24,7 +24,7 @@ Signed-off-by: Stanislaw Gruszka --- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c -@@ -555,7 +555,7 @@ static ssize_t rt2x00debug_write_restart +@@ -575,7 +575,7 @@ static ssize_t rt2x00debug_write_restart { struct rt2x00debug_intf *intf = file->private_data; struct rt2x00_dev *rt2x00dev = intf->rt2x00dev; diff --git a/package/kernel/mac80211/patches/subsys/030-mac80211_fix-scan-when-operating-on-DFS-channels-in-ETSI-domains.patch b/package/kernel/mac80211/patches/subsys/030-mac80211_fix-scan-when-operating-on-DFS-channels-in-ETSI-domains.patch index 560f8850df..7bba7176cb 100644 --- a/package/kernel/mac80211/patches/subsys/030-mac80211_fix-scan-when-operating-on-DFS-channels-in-ETSI-domains.patch +++ b/package/kernel/mac80211/patches/subsys/030-mac80211_fix-scan-when-operating-on-DFS-channels-in-ETSI-domains.patch @@ -25,7 +25,7 @@ Signed-off-by: Johannes Berg --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -5554,6 +5554,14 @@ const struct ieee80211_reg_rule *freq_re +@@ -5451,6 +5451,14 @@ const struct ieee80211_reg_rule *freq_re const char *reg_initiator_name(enum nl80211_reg_initiator initiator); /** @@ -91,7 +91,7 @@ Signed-off-by: Johannes Berg if (!ieee80211_can_scan(local, sdata)) { --- a/net/wireless/reg.c +++ b/net/wireless/reg.c -@@ -3883,6 +3883,7 @@ bool regulatory_pre_cac_allowed(struct w +@@ -3866,6 +3866,7 @@ bool regulatory_pre_cac_allowed(struct w return pre_cac_allowed; } diff --git a/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch b/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch index 5fe7616143..f5ec895f0b 100644 --- a/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch +++ b/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch @@ -476,7 +476,7 @@ } ieee80211_tx_result -@@ -1128,9 +1129,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct +@@ -1124,9 +1125,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct struct ieee80211_key *key = tx->key; struct ieee80211_mmie_16 *mmie; struct ieee80211_hdr *hdr; @@ -488,7 +488,7 @@ if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) return TX_DROP; -@@ -1176,7 +1177,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct +@@ -1172,7 +1173,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_key *key = rx->key; struct ieee80211_mmie_16 *mmie; @@ -687,7 +687,7 @@ #endif /* AES_GMAC_H */ --- a/net/mac80211/key.h +++ b/net/mac80211/key.h -@@ -88,7 +88,7 @@ struct ieee80211_key { +@@ -87,7 +87,7 @@ struct ieee80211_key { * Management frames. */ u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; diff --git a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch index 8e0fddd10a..dcc0ac4dfb 100644 --- a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch +++ b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch @@ -2,7 +2,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -1172,7 +1172,6 @@ static int ieee80211_stop_ap(struct wiph +@@ -1169,7 +1169,6 @@ static int ieee80211_stop_ap(struct wiph sdata->vif.bss_conf.ftmr_params = NULL; __sta_info_flush(sdata, true); diff --git a/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch b/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch index 02e523878e..9830602ab0 100644 --- a/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch +++ b/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch @@ -188,7 +188,7 @@ Signed-off-by: Felix Fietkau #endif /* AES_CMAC_H */ --- a/net/mac80211/key.h +++ b/net/mac80211/key.h -@@ -93,7 +93,7 @@ struct ieee80211_key { +@@ -92,7 +92,7 @@ struct ieee80211_key { } ccmp; struct { u8 rx_pn[IEEE80211_CMAC_PN_LEN]; diff --git a/package/kernel/mac80211/patches/subsys/140-tweak-TSQ-setting.patch b/package/kernel/mac80211/patches/subsys/140-tweak-TSQ-setting.patch index e56b08d0fe..449179a962 100644 --- a/package/kernel/mac80211/patches/subsys/140-tweak-TSQ-setting.patch +++ b/package/kernel/mac80211/patches/subsys/140-tweak-TSQ-setting.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4015,6 +4015,12 @@ out: +@@ -4012,6 +4012,12 @@ out: netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev) { diff --git a/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch b/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch index ab845c04e5..14ef714f68 100644 --- a/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch +++ b/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch @@ -18,7 +18,7 @@ static int ieee80211_ifa6_changed(struct notifier_block *nb, unsigned long data, void *arg) { -@@ -1264,14 +1264,14 @@ int ieee80211_register_hw(struct ieee802 +@@ -1269,14 +1269,14 @@ int ieee80211_register_hw(struct ieee802 rtnl_unlock(); @@ -35,7 +35,7 @@ local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; result = register_inet6addr_notifier(&local->ifa6_notifier); if (result) -@@ -1280,13 +1280,13 @@ int ieee80211_register_hw(struct ieee802 +@@ -1285,13 +1285,13 @@ int ieee80211_register_hw(struct ieee802 return 0; @@ -52,7 +52,7 @@ fail_ifa: #endif rtnl_lock(); -@@ -1314,10 +1314,10 @@ void ieee80211_unregister_hw(struct ieee +@@ -1319,10 +1319,10 @@ void ieee80211_unregister_hw(struct ieee tasklet_kill(&local->tx_pending_tasklet); tasklet_kill(&local->tasklet); diff --git a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch index 32f4ac07db..634c531b00 100644 --- a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch +++ b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2317,7 +2317,7 @@ static int ieee80211_scan(struct wiphy * +@@ -2319,7 +2319,7 @@ static int ieee80211_scan(struct wiphy * * the frames sent while scanning on other channel will be * lost) */ diff --git a/package/kernel/mac80211/patches/subsys/300-mac80211-optimize-skb-resizing.patch b/package/kernel/mac80211/patches/subsys/300-mac80211-optimize-skb-resizing.patch index f4b7e8a1c3..b0c527a68c 100644 --- a/package/kernel/mac80211/patches/subsys/300-mac80211-optimize-skb-resizing.patch +++ b/package/kernel/mac80211/patches/subsys/300-mac80211-optimize-skb-resizing.patch @@ -24,7 +24,7 @@ Signed-off-by: Felix Fietkau --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1782,6 +1782,9 @@ int ieee80211_tx_control_port(struct wip +@@ -1779,6 +1779,9 @@ int ieee80211_tx_control_port(struct wip const u8 *dest, __be16 proto, bool unencrypted); int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, const u8 *buf, size_t len); @@ -36,7 +36,7 @@ Signed-off-by: Felix Fietkau void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, --- a/net/mac80211/status.c +++ b/net/mac80211/status.c -@@ -815,6 +815,11 @@ void ieee80211_tx_monitor(struct ieee802 +@@ -655,6 +655,11 @@ void ieee80211_tx_monitor(struct ieee802 struct net_device *prev_dev = NULL; int rtap_len; @@ -46,11 +46,11 @@ Signed-off-by: Felix Fietkau + } + /* send frame to monitor interfaces now */ - rtap_len = ieee80211_tx_radiotap_len(info, status); + rtap_len = ieee80211_tx_radiotap_len(info); if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -1937,37 +1937,53 @@ static bool ieee80211_tx(struct ieee8021 +@@ -1936,37 +1936,53 @@ static bool ieee80211_tx(struct ieee8021 } /* device xmit handlers */ @@ -123,7 +123,7 @@ Signed-off-by: Felix Fietkau wiphy_debug(local->hw.wiphy, "failed to reallocate TX buffer\n"); return -ENOMEM; -@@ -1983,18 +1999,8 @@ void ieee80211_xmit(struct ieee80211_sub +@@ -1982,18 +1998,8 @@ void ieee80211_xmit(struct ieee80211_sub struct ieee80211_local *local = sdata->local; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr; @@ -143,7 +143,7 @@ Signed-off-by: Felix Fietkau ieee80211_free_txskb(&local->hw, skb); return; } -@@ -2775,29 +2781,13 @@ static struct sk_buff *ieee80211_build_h +@@ -2774,29 +2780,13 @@ static struct sk_buff *ieee80211_build_h } skb_pull(skb, skip_header_bytes); @@ -179,7 +179,7 @@ Signed-off-by: Felix Fietkau } if (encaps_data) -@@ -3412,7 +3402,6 @@ static bool ieee80211_xmit_fast(struct i +@@ -3411,7 +3401,6 @@ static bool ieee80211_xmit_fast(struct i struct ieee80211_local *local = sdata->local; u16 ethertype = (skb->data[12] << 8) | skb->data[13]; int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); @@ -187,7 +187,7 @@ Signed-off-by: Felix Fietkau struct ethhdr eth; struct ieee80211_tx_info *info; struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; -@@ -3464,10 +3453,7 @@ static bool ieee80211_xmit_fast(struct i +@@ -3463,10 +3452,7 @@ static bool ieee80211_xmit_fast(struct i * as the may-encrypt argument for the resize to not account for * more room than we already have in 'extra_head' */ diff --git a/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel_ht-fix-per-group-max-throughput-ra.patch b/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel_ht-fix-per-group-max-throughput-ra.patch new file mode 100644 index 0000000000..d971d84178 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel_ht-fix-per-group-max-throughput-ra.patch @@ -0,0 +1,22 @@ +From: Felix Fietkau +Date: Fri, 14 Jun 2019 21:12:04 +0200 +Subject: [PATCH] mac80211: minstrel_ht: fix per-group max throughput rate + initialization + +The group number needs to be multiplied by the number of rates per group +to get the full rate index + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -575,7 +575,7 @@ minstrel_ht_update_stats(struct minstrel + + /* (re)Initialize group rate indexes */ + for(j = 0; j < MAX_THR_RATES; j++) +- tmp_group_tp_rate[j] = group; ++ tmp_group_tp_rate[j] = MCS_GROUP_RATES * group; + + for (i = 0; i < MCS_GROUP_RATES; i++) { + if (!(mi->supported[group] & BIT(i))) diff --git a/package/kernel/mac80211/patches/subsys/311-mac80211-minstrel_ht-reduce-unnecessary-rate-probing.patch b/package/kernel/mac80211/patches/subsys/311-mac80211-minstrel_ht-reduce-unnecessary-rate-probing.patch new file mode 100644 index 0000000000..11f6ead13d --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/311-mac80211-minstrel_ht-reduce-unnecessary-rate-probing.patch @@ -0,0 +1,42 @@ +From: Felix Fietkau +Date: Wed, 5 Jun 2019 20:42:49 +0200 +Subject: [PATCH] mac80211: minstrel_ht: reduce unnecessary rate probing + attempts + +On hardware with static fallback tables (e.g. mt76x2), rate probing attempts +can be very expensive. +On such devices, avoid sampling rates slower than the per-group max throughput +rate, based on the assumption that the fallback table will take care of probing +lower rates within that group if the higher rates fail. +To make this work, this also fixes a wrong initialization in the previously +unused per-group sorted rate array. +To further reduce unnecessary probing attempts, skip duplicate attempts on +rates slower than the max throughput rate. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1059,6 +1059,21 @@ minstrel_get_sample_rate(struct minstrel + minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur) + return -1; + ++ ++ /* ++ * For devices with no configurable multi-rate retry, skip sampling ++ * below the per-group max throughput rate, and only use one sampling ++ * attempt per rate ++ */ ++ if (mp->hw->max_rates == 1 && ++ (minstrel_get_duration(mg->max_group_tp_rate[0]) < sample_dur || ++ mrs->attempts)) ++ return -1; ++ ++ /* Skip already sampled slow rates */ ++ if (sample_dur >= minstrel_get_duration(tp_rate1) && mrs->attempts) ++ return -1; ++ + /* + * Make sure that lower rates get sampled only occasionally, + * if the link is working perfectly. diff --git a/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-fix-default-max-throughput-rate.patch b/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-fix-default-max-throughput-rate.patch new file mode 100644 index 0000000000..9855c35a5d --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-fix-default-max-throughput-rate.patch @@ -0,0 +1,46 @@ +From: Felix Fietkau +Date: Fri, 14 Jun 2019 21:14:22 +0200 +Subject: [PATCH] mac80211: minstrel_ht: fix default max throughput rate + indexes + +Use the first supported rate instead of 0 (which can be invalid) + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -486,7 +486,7 @@ minstrel_ht_assign_best_tp_rates(struct + tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma; + tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); + +- if (tmp_cck_tp > tmp_mcs_tp) { ++ if (tmp_cck_tp_rate && tmp_cck_tp > tmp_mcs_tp) { + for(i = 0; i < MAX_THR_RATES; i++) { + minstrel_ht_sort_best_tp_rates(mi, tmp_cck_tp_rate[i], + tmp_mcs_tp_rate); +@@ -558,11 +558,19 @@ minstrel_ht_update_stats(struct minstrel + mi->sample_slow = 0; + mi->sample_count = 0; + +- /* Initialize global rate indexes */ +- for(j = 0; j < MAX_THR_RATES; j++){ +- tmp_mcs_tp_rate[j] = 0; +- tmp_cck_tp_rate[j] = 0; +- } ++ memset(tmp_mcs_tp_rate, 0, sizeof(tmp_mcs_tp_rate)); ++ memset(tmp_cck_tp_rate, 0, sizeof(tmp_cck_tp_rate)); ++ if (mi->supported[MINSTREL_CCK_GROUP]) ++ for (j = 0; j < ARRAY_SIZE(tmp_cck_tp_rate); j++) ++ tmp_cck_tp_rate[j] = MINSTREL_CCK_GROUP * MCS_GROUP_RATES; ++ ++ if (mi->supported[MINSTREL_VHT_GROUP_0]) ++ index = MINSTREL_VHT_GROUP_0 * MCS_GROUP_RATES; ++ else ++ index = MINSTREL_HT_GROUP_0 * MCS_GROUP_RATES; ++ ++ for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++) ++ tmp_mcs_tp_rate[j] = index; + + /* Find best rate sets within all MCS groups*/ + for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { diff --git a/package/kernel/mac80211/patches/subsys/313-mac80211-minstrel_ht-improve-rate-probing-for-device.patch b/package/kernel/mac80211/patches/subsys/313-mac80211-minstrel_ht-improve-rate-probing-for-device.patch new file mode 100644 index 0000000000..5b8e608b0a --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/313-mac80211-minstrel_ht-improve-rate-probing-for-device.patch @@ -0,0 +1,481 @@ +From: Felix Fietkau +Date: Fri, 14 Jun 2019 21:15:47 +0200 +Subject: [PATCH] mac80211: minstrel_ht: improve rate probing for devices + with static fallback + +On some devices that only support static rate fallback tables sending rate +control probing packets can be really expensive. +Probing lower rates can already hurt throughput quite a bit. What hurts even +more is the fact that on mt76x0/mt76x2, single probing packets can only be +forced by directing packets at a different internal hardware queue, which +causes some heavy reordering and extra latency. +The reordering issue is mainly problematic while pushing lots of packets to +a particular station. If there is little activity, the overhead of probing is +neglegible. + +The static fallback behavior is designed to pretty much only handle rate +control algorithms that use only a very limited set of rates on which the +algorithm switches up/down based on packet error rate. + +In order to better support that kind of hardware, this patch implements a +different approach to rate probing where it switches to a slightly higher rate, +waits for tx status feedback, then updates the stats and switches back to +the new max throughput rate. This only triggers above a packet rate of 100 +per stats interval (~50ms). +For that kind of probing, the code has to reduce the set of probing rates +a lot more compared to single packet probing, so it uses only one packet +per MCS group which is either slightly faster, or as close as possible to +the max throughput rate. +This allows switching between similar rates with different numbers of +streams. The algorithm assumes that the hardware will work its way lower +within an MCS group in case of retransmissions, so that lower rates don't +have to be probed by the high packets per second rate probing code. + +To further reduce the search space, it also does not probe rates with lower +channel bandwidth than the max throughput rate. + +At the moment, these changes will only affect mt76x0/mt76x2. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel.h ++++ b/net/mac80211/rc80211_minstrel.h +@@ -95,6 +95,7 @@ struct minstrel_sta_info { + struct minstrel_priv { + struct ieee80211_hw *hw; + bool has_mrr; ++ u32 sample_switch; + unsigned int cw_min; + unsigned int cw_max; + unsigned int max_retry; +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -18,6 +18,8 @@ + #define AVG_AMPDU_SIZE 16 + #define AVG_PKT_SIZE 1200 + ++#define SAMPLE_SWITCH_THR 100 ++ + /* Number of bits for an average sized packet */ + #define MCS_NBITS ((AVG_PKT_SIZE * AVG_AMPDU_SIZE) << 3) + +@@ -58,6 +60,7 @@ + [GROUP_IDX(_streams, _sgi, _ht40)] = { \ + .streams = _streams, \ + .shift = _s, \ ++ .bw = _ht40, \ + .flags = \ + IEEE80211_TX_RC_MCS | \ + (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ +@@ -94,6 +97,7 @@ + [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \ + .streams = _streams, \ + .shift = _s, \ ++ .bw = _bw, \ + .flags = \ + IEEE80211_TX_RC_VHT_MCS | \ + (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ +@@ -526,6 +530,133 @@ minstrel_ht_prob_rate_reduce_streams(str + } + } + ++static inline int ++minstrel_get_duration(int index) ++{ ++ const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; ++ unsigned int duration = group->duration[index % MCS_GROUP_RATES]; ++ return duration << group->shift; ++} ++ ++static bool ++minstrel_ht_probe_group(struct minstrel_ht_sta *mi, const struct mcs_group *tp_group, ++ int tp_idx, const struct mcs_group *group) ++{ ++ if (group->bw < tp_group->bw) ++ return false; ++ ++ if (group->streams == tp_group->streams) ++ return true; ++ ++ if (tp_idx < 4 && group->streams == tp_group->streams - 1) ++ return true; ++ ++ return group->streams == tp_group->streams + 1; ++} ++ ++static void ++minstrel_ht_find_probe_rates(struct minstrel_ht_sta *mi, u16 *rates, int *n_rates, ++ bool faster_rate) ++{ ++ const struct mcs_group *group, *tp_group; ++ int i, g, max_dur; ++ int tp_idx; ++ ++ tp_group = &minstrel_mcs_groups[mi->max_tp_rate[0] / MCS_GROUP_RATES]; ++ tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES; ++ ++ max_dur = minstrel_get_duration(mi->max_tp_rate[0]); ++ if (faster_rate) ++ max_dur -= max_dur / 16; ++ ++ for (g = 0; g < MINSTREL_GROUPS_NB; g++) { ++ u16 supported = mi->supported[g]; ++ ++ if (!supported) ++ continue; ++ ++ group = &minstrel_mcs_groups[g]; ++ if (!minstrel_ht_probe_group(mi, tp_group, tp_idx, group)) ++ continue; ++ ++ for (i = 0; supported; supported >>= 1, i++) { ++ int idx; ++ ++ if (!(supported & 1)) ++ continue; ++ ++ if ((group->duration[i] << group->shift) > max_dur) ++ continue; ++ ++ idx = g * MCS_GROUP_RATES + i; ++ if (idx == mi->max_tp_rate[0]) ++ continue; ++ ++ rates[(*n_rates)++] = idx; ++ break; ++ } ++ } ++} ++ ++static void ++minstrel_ht_rate_sample_switch(struct minstrel_priv *mp, ++ struct minstrel_ht_sta *mi) ++{ ++ struct minstrel_rate_stats *mrs; ++ u16 rates[MINSTREL_GROUPS_NB]; ++ int n_rates = 0; ++ int probe_rate = 0; ++ bool faster_rate; ++ int i; ++ u8 random; ++ ++ /* ++ * Use rate switching instead of probing packets for devices with ++ * little control over retry fallback behavior ++ */ ++ if (mp->hw->max_rates > 1) ++ return; ++ ++ /* ++ * If the current EWMA prob is >75%, look for a rate that's 6.25% ++ * faster than the max tp rate. ++ * If that fails, look again for a rate that is at least as fast ++ */ ++ mrs = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); ++ faster_rate = mrs->prob_ewma > MINSTREL_FRAC(75, 100); ++ minstrel_ht_find_probe_rates(mi, rates, &n_rates, faster_rate); ++ if (!n_rates && faster_rate) ++ minstrel_ht_find_probe_rates(mi, rates, &n_rates, false); ++ ++ /* If no suitable rate was found, try to pick the next one in the group */ ++ if (!n_rates) { ++ int g_idx = mi->max_tp_rate[0] / MCS_GROUP_RATES; ++ u16 supported = mi->supported[g_idx]; ++ ++ supported >>= mi->max_tp_rate[0] % MCS_GROUP_RATES; ++ for (i = 0; supported; i++) { ++ if (!(supported & 1)) ++ continue; ++ ++ probe_rate = mi->max_tp_rate[0] + i; ++ goto out; ++ } ++ ++ return; ++ } ++ ++ i = 0; ++ if (n_rates > 1) { ++ random = prandom_u32(); ++ i = random % n_rates; ++ } ++ probe_rate = rates[i]; ++ ++out: ++ mi->sample_rate = probe_rate; ++ mi->sample_mode = MINSTREL_SAMPLE_ACTIVE; ++} ++ + /* + * Update rate statistics and select new primary rates + * +@@ -536,7 +667,8 @@ minstrel_ht_prob_rate_reduce_streams(str + * higher throughput rates, even if the probablity is a bit lower + */ + static void +-minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) ++minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ++ bool sample) + { + struct minstrel_mcs_group_data *mg; + struct minstrel_rate_stats *mrs; +@@ -544,6 +676,18 @@ minstrel_ht_update_stats(struct minstrel + u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; + u16 tmp_cck_tp_rate[MAX_THR_RATES], index; + ++ mi->sample_mode = MINSTREL_SAMPLE_IDLE; ++ ++ if (sample) { ++ mi->total_packets_cur = mi->total_packets - ++ mi->total_packets_last; ++ mi->total_packets_last = mi->total_packets; ++ } ++ if (!mp->sample_switch) ++ sample = false; ++ if (mi->total_packets_cur < SAMPLE_SWITCH_THR && mp->sample_switch != 1) ++ sample = false; ++ + if (mi->ampdu_packets > 0) { + if (!ieee80211_hw_check(mp->hw, TX_STATUS_NO_AMPDU_LEN)) + mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, +@@ -630,12 +774,16 @@ minstrel_ht_update_stats(struct minstrel + /* try to sample all available rates during each interval */ + mi->sample_count *= 8; + ++ if (sample) ++ minstrel_ht_rate_sample_switch(mp, mi); ++ + #ifdef CPTCFG_MAC80211_DEBUGFS + /* use fixed index if set */ + if (mp->fixed_rate_idx != -1) { + for (i = 0; i < 4; i++) + mi->max_tp_rate[i] = mp->fixed_rate_idx; + mi->max_prob_rate = mp->fixed_rate_idx; ++ mi->sample_mode = MINSTREL_SAMPLE_IDLE; + } + #endif + +@@ -739,15 +887,17 @@ minstrel_ht_tx_status(void *priv, struct + struct minstrel_ht_sta_priv *msp = priv_sta; + struct minstrel_ht_sta *mi = &msp->ht; + struct ieee80211_tx_rate *ar = info->status.rates; +- struct minstrel_rate_stats *rate, *rate2; ++ struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL; + struct minstrel_priv *mp = priv; + bool last, update = false; ++ bool sample_status = false; + int i; + + if (!msp->is_ht) + return mac80211_minstrel.tx_status_ext(priv, sband, + &msp->legacy, st); + ++ + /* This packet was aggregated but doesn't carry status info */ + if ((info->flags & IEEE80211_TX_CTL_AMPDU) && + !(info->flags & IEEE80211_TX_STAT_AMPDU)) +@@ -773,12 +923,17 @@ minstrel_ht_tx_status(void *priv, struct + if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) + mi->sample_packets += info->status.ampdu_len; + ++ if (mi->sample_mode != MINSTREL_SAMPLE_IDLE) ++ rate_sample = minstrel_get_ratestats(mi, mi->sample_rate); ++ + last = !minstrel_ht_txstat_valid(mp, &ar[0]); + for (i = 0; !last; i++) { + last = (i == IEEE80211_TX_MAX_RATES - 1) || + !minstrel_ht_txstat_valid(mp, &ar[i + 1]); + + rate = minstrel_ht_get_stats(mp, mi, &ar[i]); ++ if (rate == rate_sample) ++ sample_status = true; + + if (last) + rate->success += info->status.ampdu_ack_len; +@@ -786,44 +941,60 @@ minstrel_ht_tx_status(void *priv, struct + rate->attempts += ar[i].count * info->status.ampdu_len; + } + +- /* +- * check for sudden death of spatial multiplexing, +- * downgrade to a lower number of streams if necessary. +- */ +- rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); +- if (rate->attempts > 30 && +- MINSTREL_FRAC(rate->success, rate->attempts) < +- MINSTREL_FRAC(20, 100)) { +- minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true); ++ switch (mi->sample_mode) { ++ case MINSTREL_SAMPLE_IDLE: ++ break; ++ ++ case MINSTREL_SAMPLE_ACTIVE: ++ if (!sample_status) ++ break; ++ ++ mi->sample_mode = MINSTREL_SAMPLE_PENDING; + update = true; +- } ++ break; ++ ++ case MINSTREL_SAMPLE_PENDING: ++ if (sample_status) ++ break; + +- rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]); +- if (rate2->attempts > 30 && +- MINSTREL_FRAC(rate2->success, rate2->attempts) < +- MINSTREL_FRAC(20, 100)) { +- minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false); + update = true; ++ minstrel_ht_update_stats(mp, mi, false); ++ break; ++ } ++ ++ ++ if (mp->hw->max_rates > 1) { ++ /* ++ * check for sudden death of spatial multiplexing, ++ * downgrade to a lower number of streams if necessary. ++ */ ++ rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); ++ if (rate->attempts > 30 && ++ MINSTREL_FRAC(rate->success, rate->attempts) < ++ MINSTREL_FRAC(20, 100)) { ++ minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true); ++ update = true; ++ } ++ ++ rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]); ++ if (rate2->attempts > 30 && ++ MINSTREL_FRAC(rate2->success, rate2->attempts) < ++ MINSTREL_FRAC(20, 100)) { ++ minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false); ++ update = true; ++ } + } + + if (time_after(jiffies, mi->last_stats_update + + (mp->update_interval / 2 * HZ) / 1000)) { + update = true; +- minstrel_ht_update_stats(mp, mi); ++ minstrel_ht_update_stats(mp, mi, true); + } + + if (update) + minstrel_ht_update_rates(mp, mi); + } + +-static inline int +-minstrel_get_duration(int index) +-{ +- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +- unsigned int duration = group->duration[index % MCS_GROUP_RATES]; +- return duration << group->shift; +-} +- + static void + minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, + int index) +@@ -988,14 +1159,18 @@ static void + minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) + { + struct ieee80211_sta_rates *rates; ++ u16 first_rate = mi->max_tp_rate[0]; + int i = 0; + ++ if (mi->sample_mode == MINSTREL_SAMPLE_ACTIVE) ++ first_rate = mi->sample_rate; ++ + rates = kzalloc(sizeof(*rates), GFP_ATOMIC); + if (!rates) + return; + + /* Start with max_tp_rate[0] */ +- minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[0]); ++ minstrel_ht_set_rate(mp, mi, rates, i++, first_rate); + + if (mp->hw->max_rates >= 3) { + /* At least 3 tx rates supported, use max_tp_rate[1] next */ +@@ -1020,6 +1195,11 @@ minstrel_get_sample_rate(struct minstrel + int tp_rate1, tp_rate2; + int sample_idx = 0; + ++ if (mp->hw->max_rates == 1 && mp->sample_switch && ++ (mi->total_packets_cur >= SAMPLE_SWITCH_THR || ++ mp->sample_switch == 1)) ++ return -1; ++ + if (mi->sample_wait > 0) { + mi->sample_wait--; + return -1; +@@ -1341,7 +1521,7 @@ minstrel_ht_update_caps(void *priv, stru + mi->supported[MINSTREL_CCK_GROUP] |= mi->cck_supported_short << 4; + + /* create an initial rate table with the lowest supported rates */ +- minstrel_ht_update_stats(mp, mi); ++ minstrel_ht_update_stats(mp, mi, true); + minstrel_ht_update_rates(mp, mi); + + return; +@@ -1459,6 +1639,8 @@ minstrel_ht_alloc(struct ieee80211_hw *h + if (!mp) + return NULL; + ++ mp->sample_switch = -1; ++ + /* contention window settings + * Just an approximation. Using the per-queue values would complicate + * the calculations and is probably unnecessary */ +@@ -1490,6 +1672,8 @@ minstrel_ht_alloc(struct ieee80211_hw *h + mp->fixed_rate_idx = (u32) -1; + debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, + &mp->fixed_rate_idx); ++ debugfs_create_u32("sample_switch", S_IRUGO | S_IWUSR, debugfsdir, ++ &mp->sample_switch); + #endif + + minstrel_ht_init_cck_rates(mp); +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -33,6 +33,7 @@ struct mcs_group { + u16 flags; + u8 streams; + u8 shift; ++ u8 bw; + u16 duration[MCS_GROUP_RATES]; + }; + +@@ -50,6 +51,12 @@ struct minstrel_mcs_group_data { + struct minstrel_rate_stats rates[MCS_GROUP_RATES]; + }; + ++enum minstrel_sample_mode { ++ MINSTREL_SAMPLE_IDLE, ++ MINSTREL_SAMPLE_ACTIVE, ++ MINSTREL_SAMPLE_PENDING, ++}; ++ + struct minstrel_ht_sta { + struct ieee80211_sta *sta; + +@@ -71,6 +78,8 @@ struct minstrel_ht_sta { + unsigned int overhead; + unsigned int overhead_rtscts; + ++ unsigned int total_packets_last; ++ unsigned int total_packets_cur; + unsigned int total_packets; + unsigned int sample_packets; + +@@ -82,6 +91,9 @@ struct minstrel_ht_sta { + u8 sample_count; + u8 sample_slow; + ++ enum minstrel_sample_mode sample_mode; ++ u16 sample_rate; ++ + /* current MCS group to be sampled */ + u8 sample_group; + diff --git a/package/kernel/mac80211/patches/subsys/314-mac80211-add-IEEE80211_KEY_FLAG_GENERATE_MMIE-to-iee.patch b/package/kernel/mac80211/patches/subsys/314-mac80211-add-IEEE80211_KEY_FLAG_GENERATE_MMIE-to-iee.patch new file mode 100644 index 0000000000..f732345842 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/314-mac80211-add-IEEE80211_KEY_FLAG_GENERATE_MMIE-to-iee.patch @@ -0,0 +1,58 @@ +From: Lorenzo Bianconi +Date: Tue, 16 Jul 2019 00:09:19 +0200 +Subject: [PATCH] mac80211: add IEEE80211_KEY_FLAG_GENERATE_MMIE to + ieee80211_key_flags + +Add IEEE80211_KEY_FLAG_GENERATE_MMIE flag to ieee80211_key_flags in order +to allow the driver to notify mac80211 to generate MMIE and that it +requires sequence number generation only. +This is a preliminary patch to add BIP_CMAC_128 hw support to mt7615 +driver + +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/dfe275f9aa0f1cc6b33085f9efd5d8447f68ad13.1563228405.git.lorenzo@kernel.org +Signed-off-by: Johannes Berg +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1702,6 +1702,9 @@ struct wireless_dev *ieee80211_vif_to_wd + * a TKIP key if it only requires MIC space. Do not set together with + * @IEEE80211_KEY_FLAG_GENERATE_MMIC on the same key. + * @IEEE80211_KEY_FLAG_NO_AUTO_TX: Key needs explicit Tx activation. ++ * @IEEE80211_KEY_FLAG_GENERATE_MMIE: This flag should be set by the driver ++ * for a AES_CMAC key to indicate that it requires sequence number ++ * generation only + */ + enum ieee80211_key_flags { + IEEE80211_KEY_FLAG_GENERATE_IV_MGMT = BIT(0), +@@ -1714,6 +1717,7 @@ enum ieee80211_key_flags { + IEEE80211_KEY_FLAG_RESERVE_TAILROOM = BIT(7), + IEEE80211_KEY_FLAG_PUT_MIC_SPACE = BIT(8), + IEEE80211_KEY_FLAG_NO_AUTO_TX = BIT(9), ++ IEEE80211_KEY_FLAG_GENERATE_MMIE = BIT(10), + }; + + /** +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -947,7 +947,8 @@ ieee80211_crypto_aes_cmac_encrypt(struct + + info = IEEE80211_SKB_CB(skb); + +- if (info->control.hw_key) ++ if (info->control.hw_key && ++ !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIE)) + return TX_CONTINUE; + + if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) +@@ -963,6 +964,9 @@ ieee80211_crypto_aes_cmac_encrypt(struct + + bip_ipn_set64(mmie->sequence_number, pn64); + ++ if (info->control.hw_key) ++ return TX_CONTINUE; ++ + bip_aad(skb, aad); + + /* diff --git a/package/kernel/mac80211/patches/subsys/315-mac80211-minstrel_ht-fix-infinite-loop-because-suppo.patch b/package/kernel/mac80211/patches/subsys/315-mac80211-minstrel_ht-fix-infinite-loop-because-suppo.patch new file mode 100644 index 0000000000..eb70d4d5d2 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/315-mac80211-minstrel_ht-fix-infinite-loop-because-suppo.patch @@ -0,0 +1,25 @@ +From: Colin Ian King +Date: Thu, 22 Aug 2019 13:20:34 +0100 +Subject: [PATCH] mac80211: minstrel_ht: fix infinite loop because supported is + not being shifted + +Currently the for-loop will spin forever if variable supported is +non-zero because supported is never changed. Fix this by adding in +the missing right shift of supported. + +Addresses-Coverity: ("Infinite loop") +Fixes: 48cb39522a9d ("mac80211: minstrel_ht: improve rate probing for devices with static fallback") +Signed-off-by: Colin Ian King +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -634,7 +634,7 @@ minstrel_ht_rate_sample_switch(struct mi + u16 supported = mi->supported[g_idx]; + + supported >>= mi->max_tp_rate[0] % MCS_GROUP_RATES; +- for (i = 0; supported; i++) { ++ for (i = 0; supported; supported >>= 1, i++) { + if (!(supported & 1)) + continue; + diff --git a/package/kernel/mac80211/patches/subsys/350-cfg80211-add-local-BSS-receive-time-to-survey-inform.patch b/package/kernel/mac80211/patches/subsys/350-cfg80211-add-local-BSS-receive-time-to-survey-inform.patch new file mode 100644 index 0000000000..af70b46fdc --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/350-cfg80211-add-local-BSS-receive-time-to-survey-inform.patch @@ -0,0 +1,77 @@ +From: Felix Fietkau +Date: Wed, 28 Aug 2019 12:13:55 +0200 +Subject: [PATCH] cfg80211: add local BSS receive time to survey information + +This is useful for checking how much airtime is being used up by other +transmissions on the channel, e.g. by calculating (time_rx - time_bss_rx) +or (time_busy - time_bss_rx - time_tx) + +Signed-off-by: Felix Fietkau +--- + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -682,6 +682,7 @@ ieee80211_chandef_max_power(struct cfg80 + * @SURVEY_INFO_TIME_RX: receive time was filled in + * @SURVEY_INFO_TIME_TX: transmit time was filled in + * @SURVEY_INFO_TIME_SCAN: scan time was filled in ++ * @SURVEY_INFO_TIME_BSS_RX: local BSS receive time was filled in + * + * Used by the driver to indicate which info in &struct survey_info + * it has filled in during the get_survey(). +@@ -695,6 +696,7 @@ enum survey_info_flags { + SURVEY_INFO_TIME_RX = BIT(5), + SURVEY_INFO_TIME_TX = BIT(6), + SURVEY_INFO_TIME_SCAN = BIT(7), ++ SURVEY_INFO_TIME_BSS_RX = BIT(8), + }; + + /** +@@ -711,6 +713,7 @@ enum survey_info_flags { + * @time_rx: amount of time the radio spent receiving data + * @time_tx: amount of time the radio spent transmitting data + * @time_scan: amount of time the radio spent for scanning ++ * @time_bss_rx: amount of time the radio spent receiving data on a local BSS + * + * Used by dump_survey() to report back per-channel survey information. + * +@@ -725,6 +728,7 @@ struct survey_info { + u64 time_rx; + u64 time_tx; + u64 time_scan; ++ u64 time_bss_rx; + u32 filled; + s8 noise; + }; +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -3836,6 +3836,8 @@ enum nl80211_user_reg_hint_type { + * @NL80211_SURVEY_INFO_TIME_SCAN: time the radio spent for scan + * (on this channel or globally) + * @NL80211_SURVEY_INFO_PAD: attribute used for padding for 64-bit alignment ++ * @NL80211_SURVEY_INFO_TIME_BSS_RX: amount of time the radio spent ++ * receiving local BSS data + * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number + * currently defined + * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use +@@ -3852,6 +3854,7 @@ enum nl80211_survey_info { + NL80211_SURVEY_INFO_TIME_TX, + NL80211_SURVEY_INFO_TIME_SCAN, + NL80211_SURVEY_INFO_PAD, ++ NL80211_SURVEY_INFO_TIME_BSS_RX, + + /* keep last */ + __NL80211_SURVEY_INFO_AFTER_LAST, +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -8694,6 +8694,10 @@ static int nl80211_send_survey(struct sk + nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN, + survey->time_scan, NL80211_SURVEY_INFO_PAD)) + goto nla_put_failure; ++ if ((survey->filled & SURVEY_INFO_TIME_BSS_RX) && ++ nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BSS_RX, ++ survey->time_bss_rx, NL80211_SURVEY_INFO_PAD)) ++ goto nla_put_failure; + + nla_nest_end(msg, infoattr); + diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch index 768cca6046..a76953933f 100644 --- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch +++ b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch @@ -1,6 +1,6 @@ --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -3447,6 +3447,7 @@ struct cfg80211_update_owe_info { +@@ -3348,6 +3348,7 @@ struct cfg80211_update_owe_info { * (as advertised by the nl80211 feature flag.) * @get_tx_power: store the current TX power into the dbm variable; * return 0 if successful @@ -8,7 +8,7 @@ * * @set_wds_peer: set the WDS peer for a WDS interface * -@@ -3759,6 +3760,7 @@ struct cfg80211_ops { +@@ -3660,6 +3661,7 @@ struct cfg80211_ops { enum nl80211_tx_power_setting type, int mbm); int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm); @@ -18,7 +18,7 @@ const u8 *addr); --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -1484,6 +1484,7 @@ enum ieee80211_smps_mode { +@@ -1476,6 +1476,7 @@ enum ieee80211_smps_mode { * * @power_level: requested transmit power (in dBm), backward compatibility * value only that is set to the minimum of all interfaces @@ -26,7 +26,7 @@ * * @chandef: the channel definition to tune to * @radar_enabled: whether radar detection is enabled -@@ -1504,6 +1505,7 @@ enum ieee80211_smps_mode { +@@ -1496,6 +1497,7 @@ enum ieee80211_smps_mode { struct ieee80211_conf { u32 flags; int power_level, dynamic_ps_timeout; @@ -36,9 +36,9 @@ u8 ps_dtim_period; --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h -@@ -2373,6 +2373,9 @@ enum nl80211_commands { - * the allowed channel bandwidth configurations. (u8 attribute) - * Defined by IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13. +@@ -2356,6 +2356,9 @@ enum nl80211_commands { + * + * @NL80211_ATTR_TWT_RESPONDER: Enable target wait time responder support. * + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce + * transmit power to stay within regulatory limits. u32, dBi. @@ -46,9 +46,9 @@ * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -2835,6 +2838,8 @@ enum nl80211_attrs { - NL80211_ATTR_WIPHY_EDMG_CHANNELS, - NL80211_ATTR_WIPHY_EDMG_BW_CONFIG, +@@ -2813,6 +2816,8 @@ enum nl80211_attrs { + + NL80211_ATTR_TWT_RESPONDER, + NL80211_ATTR_WIPHY_ANTENNA_GAIN, + @@ -57,7 +57,7 @@ __NL80211_ATTR_AFTER_LAST, --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2582,6 +2582,19 @@ static int ieee80211_get_tx_power(struct +@@ -2584,6 +2584,19 @@ static int ieee80211_get_tx_power(struct return 0; } @@ -77,7 +77,7 @@ static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, const u8 *addr) { -@@ -3995,6 +4008,7 @@ const struct cfg80211_ops mac80211_confi +@@ -3997,6 +4010,7 @@ const struct cfg80211_ops mac80211_confi .set_wiphy_params = ieee80211_set_wiphy_params, .set_tx_power = ieee80211_set_tx_power, .get_tx_power = ieee80211_get_tx_power, @@ -126,18 +126,18 @@ + local->user_antenna_gain = 0; local->hw.uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; local->hw.uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; - local->hw.max_mtu = IEEE80211_MAX_DATA_LEN; + local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -624,6 +624,7 @@ const struct nla_policy nl80211_policy[N +@@ -574,6 +574,7 @@ const struct nla_policy nl80211_policy[N + [NL80211_ATTR_SAE_PASSWORD] = { .type = NLA_BINARY, .len = SAE_PASSWORD_MAX_LEN }, [NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG }, - [NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy), + [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, }; /* policy for the key attributes */ -@@ -2988,6 +2989,20 @@ static int nl80211_set_wiphy(struct sk_b +@@ -2869,6 +2870,20 @@ static int nl80211_set_wiphy(struct sk_b if (result) return result; }