mac80211: Update to version 5.4-rc2
This updates mac80211 to backports based on kernel 5.4-rc2 ath10k-ct was updated to match the API changes and iw now uses the new nl80211.h header file. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
		| @@ -0,0 +1,41 @@ | |||||||
|  | From 5db4c4b9559f8cddd5f7f74e58c7b8f172120e6d Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Emmanuel Grumbach <emmanuel.grumbach@intel.com> | ||||||
|  | Date: Tue, 23 Jul 2019 21:00:01 +0300 | ||||||
|  | Subject: [PATCH] mac80211: pass the vif to cancel_remain_on_channel | ||||||
|  |  | ||||||
|  | This low level driver can find it useful to get the vif | ||||||
|  | when a remain on channel session is cancelled. | ||||||
|  |  | ||||||
|  | iwlwifi will need this soon. | ||||||
|  |  | ||||||
|  | Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> | ||||||
|  | Link: https://lore.kernel.org/r/20190723180001.5828-1-emmanuel.grumbach@intel.com | ||||||
|  | Signed-off-by: Johannes Berg <johannes.berg@intel.com> | ||||||
|  | --- | ||||||
|  |  drivers/net/wireless/ath/ath10k/mac.c             | 3 ++- | ||||||
|  |  10 files changed, 4 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/ath10k-4.19/mac.c | ||||||
|  | +++ b/ath10k-4.19/mac.c | ||||||
|  | @@ -7775,7 +7775,8 @@ exit: | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw) | ||||||
|  | +static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw, | ||||||
|  | +					   struct ieee80211_vif *vif) | ||||||
|  |  { | ||||||
|  |  	struct ath10k *ar = hw->priv; | ||||||
|  |   | ||||||
|  | --- a/ath10k-5.2/mac.c | ||||||
|  | +++ b/ath10k-5.2/mac.c | ||||||
|  | @@ -7883,7 +7883,8 @@ exit: | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw) | ||||||
|  | +static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw, | ||||||
|  | +					   struct ieee80211_vif *vif) | ||||||
|  |  { | ||||||
|  |  	struct ath10k *ar = hw->priv; | ||||||
|  |   | ||||||
| @@ -42,7 +42,7 @@ Signed-off-by: Mathias Kresin <dev@kresin.me> | |||||||
|  	if (ret) |  	if (ret) | ||||||
| --- a/ath10k-4.19/mac.c | --- a/ath10k-4.19/mac.c | ||||||
| +++ b/ath10k-4.19/mac.c | +++ b/ath10k-4.19/mac.c | ||||||
| @@ -9982,7 +9982,7 @@ int ath10k_mac_register(struct ath10k *a | @@ -9983,7 +9983,7 @@ int ath10k_mac_register(struct ath10k *a | ||||||
|  	wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); |  	wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); | ||||||
|   |   | ||||||
|  #ifdef CPTCFG_MAC80211_LEDS |  #ifdef CPTCFG_MAC80211_LEDS | ||||||
| @@ -79,7 +79,7 @@ Signed-off-by: Mathias Kresin <dev@kresin.me> | |||||||
|  	if (ret) |  	if (ret) | ||||||
| --- a/ath10k-5.2/mac.c | --- a/ath10k-5.2/mac.c | ||||||
| +++ b/ath10k-5.2/mac.c | +++ b/ath10k-5.2/mac.c | ||||||
| @@ -10178,7 +10178,7 @@ int ath10k_mac_register(struct ath10k *a | @@ -10179,7 +10179,7 @@ int ath10k_mac_register(struct ath10k *a | ||||||
|  	ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; |  	ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; | ||||||
|   |   | ||||||
|  #ifdef CPTCFG_MAC80211_LEDS |  #ifdef CPTCFG_MAC80211_LEDS | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ Forwarded: https://patchwork.kernel.org/patch/10549245/ | |||||||
|  #include <net/mac80211.h> |  #include <net/mac80211.h> | ||||||
|  #include <linux/etherdevice.h> |  #include <linux/etherdevice.h> | ||||||
|  #include <linux/acpi.h> |  #include <linux/acpi.h> | ||||||
| @@ -9706,6 +9707,7 @@ int ath10k_mac_register(struct ath10k *a | @@ -9707,6 +9708,7 @@ int ath10k_mac_register(struct ath10k *a | ||||||
|  		ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band; |  		ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
|   | |||||||
| @@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk | |||||||
|  |  | ||||||
| PKG_NAME:=mac80211 | PKG_NAME:=mac80211 | ||||||
|  |  | ||||||
| PKG_VERSION:=5.3.6-1 | PKG_VERSION:=5.4-rc2-1 | ||||||
| PKG_RELEASE:=1 | PKG_RELEASE:=1 | ||||||
| PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.3.6/ | PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.4-rc2/ | ||||||
| PKG_HASH:=16ded706945999543a73e2349d36b8003eeb2b097970ea1ad80344b9f56393a3 | PKG_HASH:=b3baedc135b455f09f266cb77e73276ca21bceeb0f24bac2184cc4b97d09cdbf | ||||||
|  |  | ||||||
| PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz | PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz | ||||||
| PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) | PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) | ||||||
| @@ -223,7 +223,7 @@ endef | |||||||
| define KernelPackage/lib80211 | define KernelPackage/lib80211 | ||||||
|   $(call KernelPackage/mac80211/Default) |   $(call KernelPackage/mac80211/Default) | ||||||
|   TITLE:=802.11 Networking stack |   TITLE:=802.11 Networking stack | ||||||
|   DEPENDS:=+kmod-cfg80211 +kmod-crypto-hash |   DEPENDS:=+kmod-cfg80211 +kmod-crypto-hash +kmod-crypto-ccm | ||||||
|   FILES:= \ |   FILES:= \ | ||||||
| 	$(PKG_BUILD_DIR)/net/wireless/lib80211.ko \ | 	$(PKG_BUILD_DIR)/net/wireless/lib80211.ko \ | ||||||
| 	$(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_wep.ko \ | 	$(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_wep.ko \ | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ | |||||||
|  void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); |  void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); | ||||||
| --- a/local-symbols | --- a/local-symbols | ||||||
| +++ b/local-symbols | +++ b/local-symbols | ||||||
| @@ -141,6 +141,7 @@ ATH10K_SNOC= | @@ -142,6 +142,7 @@ ATH10K_SNOC= | ||||||
|  ATH10K_DEBUG= |  ATH10K_DEBUG= | ||||||
|  ATH10K_DEBUGFS= |  ATH10K_DEBUGFS= | ||||||
|  ATH10K_SPECTRAL= |  ATH10K_SPECTRAL= | ||||||
|   | |||||||
| @@ -1,14 +1,14 @@ | |||||||
| --- a/drivers/net/wireless/ath/ath5k/pci.c | --- a/drivers/net/wireless/ath/ath5k/pci.c | ||||||
| +++ b/drivers/net/wireless/ath/ath5k/pci.c | +++ b/drivers/net/wireless/ath/ath5k/pci.c | ||||||
| @@ -21,6 +21,7 @@ | @@ -20,6 +20,7 @@ | ||||||
|  #include <linux/pci-aspm.h> |  #include <linux/pci.h> | ||||||
|  #include <linux/etherdevice.h> |  #include <linux/etherdevice.h> | ||||||
|  #include <linux/module.h> |  #include <linux/module.h> | ||||||
| +#include <linux/ath5k_platform.h> | +#include <linux/ath5k_platform.h> | ||||||
|  #include "../ath.h" |  #include "../ath.h" | ||||||
|  #include "ath5k.h" |  #include "ath5k.h" | ||||||
|  #include "debug.h" |  #include "debug.h" | ||||||
| @@ -72,7 +73,7 @@ static void ath5k_pci_read_cachesize(str | @@ -71,7 +72,7 @@ static void ath5k_pci_read_cachesize(str | ||||||
|  } |  } | ||||||
|   |   | ||||||
|  /* |  /* | ||||||
| @@ -17,7 +17,7 @@ | |||||||
|   */ |   */ | ||||||
|  static bool |  static bool | ||||||
|  ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) |  ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) | ||||||
| @@ -80,6 +81,19 @@ ath5k_pci_eeprom_read(struct ath_common | @@ -79,6 +80,19 @@ ath5k_pci_eeprom_read(struct ath_common | ||||||
|  	struct ath5k_hw *ah = (struct ath5k_hw *) common->ah; |  	struct ath5k_hw *ah = (struct ath5k_hw *) common->ah; | ||||||
|  	u32 status, timeout; |  	u32 status, timeout; | ||||||
|   |   | ||||||
| @@ -37,7 +37,7 @@ | |||||||
|  	/* |  	/* | ||||||
|  	 * Initialize EEPROM access |  	 * Initialize EEPROM access | ||||||
|  	 */ |  	 */ | ||||||
| @@ -123,6 +137,16 @@ static int ath5k_pci_eeprom_read_mac(str | @@ -122,6 +136,16 @@ static int ath5k_pci_eeprom_read_mac(str | ||||||
|  	u16 data; |  	u16 data; | ||||||
|  	int octet; |  	int octet; | ||||||
|   |   | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/drivers/net/wireless/ath/ath5k/pci.c | --- a/drivers/net/wireless/ath/ath5k/pci.c | ||||||
| +++ b/drivers/net/wireless/ath/ath5k/pci.c | +++ b/drivers/net/wireless/ath/ath5k/pci.c | ||||||
| @@ -48,6 +48,8 @@ static const struct pci_device_id ath5k_ | @@ -47,6 +47,8 @@ static const struct pci_device_id ath5k_ | ||||||
|  	{ PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ |  	{ PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ | ||||||
|  	{ PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ |  	{ PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ | ||||||
|  	{ PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ |  	{ PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ | ||||||
|   | |||||||
| @@ -391,9 +391,9 @@ | |||||||
|  ATH9K_CHANNEL_CONTEXT= |  ATH9K_CHANNEL_CONTEXT= | ||||||
|  ATH9K_PCOEM= |  ATH9K_PCOEM= | ||||||
| +ATH9K_UBNTHSR= | +ATH9K_UBNTHSR= | ||||||
|  |  ATH9K_PCI_NO_EEPROM= | ||||||
|  ATH9K_HTC= |  ATH9K_HTC= | ||||||
|  ATH9K_HTC_DEBUGFS= |  ATH9K_HTC_DEBUGFS= | ||||||
|  ATH9K_HWRNG= |  | ||||||
| --- a/drivers/net/wireless/ath/ath9k/Kconfig | --- a/drivers/net/wireless/ath/ath9k/Kconfig | ||||||
| +++ b/drivers/net/wireless/ath/ath9k/Kconfig | +++ b/drivers/net/wireless/ath/ath9k/Kconfig | ||||||
| @@ -60,6 +60,19 @@ config ATH9K_AHB | @@ -60,6 +60,19 @@ config ATH9K_AHB | ||||||
|   | |||||||
| @@ -1,89 +0,0 @@ | |||||||
| From 4420866ef1b602682b009e0186fbb8aefd2125be Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Lorenzo Bianconi <lorenzo@kernel.org> |  | ||||||
| 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 <koen.vandeputte@ncentric.com> |  | ||||||
| Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/ath/ath9k/dynack.c | 37 ++++++++++++++----------- |  | ||||||
|  1 file changed, 21 insertions(+), 16 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath9k/dynack.c |  | ||||||
| +++ b/drivers/net/wireless/ath/ath9k/dynack.c |  | ||||||
| @@ -79,6 +79,24 @@ static inline bool ath_dynack_bssidmask( |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
| + * 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( |  | ||||||
|   */ |  | ||||||
|  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(str |  | ||||||
|  			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_ |  | ||||||
|  		    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); |  | ||||||
|   |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| From e5b56ce50eab31d24df6a70cf025db3acc4aa3ac Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Lorenzo Bianconi <lorenzo@kernel.org> |  | ||||||
| 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 <koen.vandeputte@ncentric.com> |  | ||||||
| Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/ath/ath9k/dynack.c | 2 +- |  | ||||||
|  1 file changed, 1 insertion(+), 1 deletion(-) |  | ||||||
|  |  | ||||||
| --- 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; |  | ||||||
| @@ -1,92 +0,0 @@ | |||||||
| From 3f737abb7d53cc80d619a3b4a30b6fa63cdc8df7 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Lorenzo Bianconi <lorenzo@kernel.org> |  | ||||||
| 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 <koen.vandeputte@ncentric.com> |  | ||||||
| Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/ath/ath9k/dynack.c | 38 +++++++++++++++++++------ |  | ||||||
|  1 file changed, 30 insertions(+), 8 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath9k/dynack.c |  | ||||||
| +++ b/drivers/net/wireless/ath/ath9k/dynack.c |  | ||||||
| @@ -20,12 +20,31 @@ |  | ||||||
|   |  | ||||||
|  #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(str |  | ||||||
|   */ |  | ||||||
|  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 |  | ||||||
|  		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_ |  | ||||||
|  		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; |  | ||||||
|   |  | ||||||
| @@ -1,73 +0,0 @@ | |||||||
| From cc783bfa67e87d2e6206f7626b7bbb74d5c5f269 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Lorenzo Bianconi <lorenzo@kernel.org> |  | ||||||
| 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 <koen.vandeputte@ncentric.com> |  | ||||||
| Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/ath/ath9k/dynack.c | 20 +++++++++++++------- |  | ||||||
|  1 file changed, 13 insertions(+), 7 deletions(-) |  | ||||||
|  |  | ||||||
| --- 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; |  | ||||||
|  } |  | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/drivers/net/wireless/ath/ath10k/mac.c | --- a/drivers/net/wireless/ath/ath10k/mac.c | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/mac.c | +++ b/drivers/net/wireless/ath/ath10k/mac.c | ||||||
| @@ -8669,6 +8669,21 @@ static int ath10k_mac_init_rd(struct ath | @@ -8671,6 +8671,21 @@ static int ath10k_mac_init_rd(struct ath | ||||||
|  	return 0; |  	return 0; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -22,7 +22,7 @@ | |||||||
|  int ath10k_mac_register(struct ath10k *ar) |  int ath10k_mac_register(struct ath10k *ar) | ||||||
|  { |  { | ||||||
|  	static const u32 cipher_suites[] = { |  	static const u32 cipher_suites[] = { | ||||||
| @@ -8995,6 +9010,12 @@ int ath10k_mac_register(struct ath10k *a | @@ -8997,6 +9012,12 @@ int ath10k_mac_register(struct ath10k *a | ||||||
|   |   | ||||||
|  	ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; |  	ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; | ||||||
|   |   | ||||||
|   | |||||||
| @@ -114,7 +114,7 @@ v13: | |||||||
|  ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o |  ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o | ||||||
| --- a/local-symbols | --- a/local-symbols | ||||||
| +++ b/local-symbols | +++ b/local-symbols | ||||||
| @@ -144,6 +144,7 @@ ATH10K_DEBUG= | @@ -145,6 +145,7 @@ ATH10K_DEBUG= | ||||||
|  ATH10K_DEBUGFS= |  ATH10K_DEBUGFS= | ||||||
|  ATH10K_SPECTRAL= |  ATH10K_SPECTRAL= | ||||||
|  ATH10K_THERMAL= |  ATH10K_THERMAL= | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ Signed-off-by: Mathias Kresin <dev@kresin.me> | |||||||
|  	if (ret) |  	if (ret) | ||||||
| --- a/drivers/net/wireless/ath/ath10k/mac.c | --- a/drivers/net/wireless/ath/ath10k/mac.c | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/mac.c | +++ b/drivers/net/wireless/ath/ath10k/mac.c | ||||||
| @@ -9027,7 +9027,7 @@ int ath10k_mac_register(struct ath10k *a | @@ -9029,7 +9029,7 @@ int ath10k_mac_register(struct ath10k *a | ||||||
|  	ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; |  	ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; | ||||||
|   |   | ||||||
|  #ifdef CPTCFG_MAC80211_LEDS |  #ifdef CPTCFG_MAC80211_LEDS | ||||||
|   | |||||||
| @@ -72,7 +72,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> | |||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/htt_rx.c | --- a/drivers/net/wireless/ath/ath10k/htt_rx.c | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c | +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c | ||||||
| @@ -2639,7 +2639,7 @@ static void ath10k_htt_rx_tx_compl_ind(s | @@ -2726,7 +2726,7 @@ static void ath10k_htt_rx_tx_compl_ind(s | ||||||
|  		spin_lock_bh(&ar->data_lock); |  		spin_lock_bh(&ar->data_lock); | ||||||
|   |   | ||||||
|  		peer = ath10k_peer_find_by_id(ar, peer_id); |  		peer = ath10k_peer_find_by_id(ar, peer_id); | ||||||
|   | |||||||
| @@ -1,56 +0,0 @@ | |||||||
| From f491645f039420fb7e14283e21b90772571c807c Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| 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 <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../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; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -1,63 +0,0 @@ | |||||||
| From 011a56a3336a5de9c3152c169cd52ff79b8c3f89 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| 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 <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  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: |  | ||||||
| @@ -1,34 +0,0 @@ | |||||||
| From fa9050927fa885410055ee03c948c2252693d296 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| 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 <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  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 |  | ||||||
| @@ -1,168 +0,0 @@ | |||||||
| From a84a60ccdd65278485fb495f468a5ab91a75c649 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| 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 <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../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, |  | ||||||
| @@ -1,67 +0,0 @@ | |||||||
| From 14fcfd1cc0c05ea58f47dd693fdd13f25dfe995e Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| 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 <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Tested-by: Rafał Miłecki <rafal@milecki.pl> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../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); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -1,30 +0,0 @@ | |||||||
| From c613085b74941024194e41b200601b9aa6ee388f Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| 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 <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  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); |  | ||||||
|   |  | ||||||
| @@ -1,38 +0,0 @@ | |||||||
| From c33330ac06fe863289643e7a13ecdb6a2502dad7 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| 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 <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  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)); |  | ||||||
| @@ -1,79 +0,0 @@ | |||||||
| From 1ac11ae949dd883854f4523ef8e3a32aabfd6256 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| 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 <stefan.wahren@i2se.com> |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../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; |  | ||||||
| @@ -1,33 +0,0 @@ | |||||||
| From e0bfb9601d4812719167cc4124a0d6db1e2f55e4 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| 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 <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  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); |  | ||||||
| @@ -1,28 +0,0 @@ | |||||||
| From 4b11c915f00caeef3292ed0429acc579b9da762a Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| 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 <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  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", |  | ||||||
| @@ -1,38 +0,0 @@ | |||||||
| From e3b1d879ccda9ffd5332777bb1beeb2cc913faa8 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> |  | ||||||
| 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 <rafal@milecki.pl> |  | ||||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  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; |  | ||||||
| @@ -1,54 +0,0 @@ | |||||||
| From cddecd92d1ec2fd05ed1123455e7c6cf6906b5a5 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: YueHaibing <yuehaibing@huawei.com> |  | ||||||
| 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 <hulkci@huawei.com> |  | ||||||
| Signed-off-by: YueHaibing <yuehaibing@huawei.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../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: |  | ||||||
| @@ -1,26 +0,0 @@ | |||||||
| From 73c742bb9c9ba30871fdd5c730d5ca8b6712833a Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Colin Ian King <colin.king@canonical.com> |  | ||||||
| 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 <colin.king@canonical.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  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; |  | ||||||
| @@ -1,36 +0,0 @@ | |||||||
| From 5f42b382ead278c1f6c3854765c97eb20491aa2a Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Xulin Sun <xulin.sun@windriver.com> |  | ||||||
| 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 <xulin.sun@windriver.com> |  | ||||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  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]); |  | ||||||
|   |  | ||||||
| @@ -1,80 +0,0 @@ | |||||||
| From 82f93cf46d6007ffa003b2d4a2834563b6b84d21 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> |  | ||||||
| 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 <rafal@milecki.pl> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  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 |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| From cb34212b1c25f7656a315f956d72696777e88340 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> |  | ||||||
| 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 <rafal@milecki.pl> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  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)) |  | ||||||
| @@ -1,59 +0,0 @@ | |||||||
| From 2f8c8e62cd50d72ac68de884a09c6f5a969a269c Mon Sep 17 00:00:00 2001 |  | ||||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> |  | ||||||
| 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 <rafal@milecki.pl> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../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); |  | ||||||
| @@ -1,58 +0,0 @@ | |||||||
| From 0e48b86d9a8f5c695bb02c9c02f6dc7d2ec8f2e2 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |  | ||||||
| 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 <andriy.shevchenko@linux.intel.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../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, |  | ||||||
| @@ -1,95 +0,0 @@ | |||||||
| From ba76ff25ee64d5cfc86209d1fbb3c294b2c04412 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> |  | ||||||
| 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 <rafal@milecki.pl> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../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 */ |  | ||||||
| @@ -1,266 +0,0 @@ | |||||||
| From 450914c39f88d1adada26256360dea7050ff4e83 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> |  | ||||||
| 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 <rafal@milecki.pl> |  | ||||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../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); |  | ||||||
| @@ -1,51 +0,0 @@ | |||||||
| From a1f5aac1765afbeace9581afa27da34085f68e1d Mon Sep 17 00:00:00 2001 |  | ||||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> |  | ||||||
| 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 <rafal@milecki.pl> |  | ||||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  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; |  | ||||||
| @@ -9,7 +9,7 @@ | |||||||
|  	depends on m |  	depends on m | ||||||
|  	default n |  	default n | ||||||
|  	help |  	help | ||||||
| @@ -196,16 +196,16 @@ config LIB80211 | @@ -196,18 +196,18 @@ config LIB80211 | ||||||
|  	  Drivers should select this themselves if needed. |  	  Drivers should select this themselves if needed. | ||||||
|   |   | ||||||
|  config LIB80211_CRYPT_WEP |  config LIB80211_CRYPT_WEP | ||||||
| @@ -22,6 +22,8 @@ | |||||||
| -	tristate | -	tristate | ||||||
| +	tristate "lib80211 CCMP support" | +	tristate "lib80211 CCMP support" | ||||||
|  	depends on m |  	depends on m | ||||||
|  |  	depends on CRYPTO_AES | ||||||
|  |  	depends on CRYPTO_CCM | ||||||
|   |   | ||||||
|  config LIB80211_CRYPT_TKIP |  config LIB80211_CRYPT_TKIP | ||||||
| -	tristate | -	tristate | ||||||
|   | |||||||
| @@ -1,50 +0,0 @@ | |||||||
| 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 <sgruszka@redhat.com> |  | ||||||
| X-Patchwork-Id: 11110703 |  | ||||||
| X-Patchwork-Delegate: kvalo@adurom.com |  | ||||||
| From: Stanislaw Gruszka <sgruszka@redhat.com> |  | ||||||
| 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: <linux-wireless.vger.kernel.org> |  | ||||||
| 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 <sgruszka@redhat.com> |  | ||||||
| --- |  | ||||||
|  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) { |  | ||||||
| @@ -24,7 +24,7 @@ Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> | |||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c | --- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c | ||||||
| +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c | +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c | ||||||
| @@ -575,7 +575,7 @@ static ssize_t rt2x00debug_write_restart | @@ -555,7 +555,7 @@ static ssize_t rt2x00debug_write_restart | ||||||
|  { |  { | ||||||
|  	struct rt2x00debug_intf *intf =	file->private_data; |  	struct rt2x00debug_intf *intf =	file->private_data; | ||||||
|  	struct rt2x00_dev *rt2x00dev = intf->rt2x00dev; |  	struct rt2x00_dev *rt2x00dev = intf->rt2x00dev; | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  |  | ||||||
| --- a/include/net/cfg80211.h | --- a/include/net/cfg80211.h | ||||||
| +++ b/include/net/cfg80211.h | +++ b/include/net/cfg80211.h | ||||||
| @@ -5451,6 +5451,14 @@ const struct ieee80211_reg_rule *freq_re | @@ -5554,6 +5554,14 @@ const struct ieee80211_reg_rule *freq_re | ||||||
|  const char *reg_initiator_name(enum nl80211_reg_initiator initiator); |  const char *reg_initiator_name(enum nl80211_reg_initiator initiator); | ||||||
|   |   | ||||||
|  /** |  /** | ||||||
| @@ -91,7 +91,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  	if (!ieee80211_can_scan(local, sdata)) { |  	if (!ieee80211_can_scan(local, sdata)) { | ||||||
| --- a/net/wireless/reg.c | --- a/net/wireless/reg.c | ||||||
| +++ b/net/wireless/reg.c | +++ b/net/wireless/reg.c | ||||||
| @@ -3866,6 +3866,7 @@ bool regulatory_pre_cac_allowed(struct w | @@ -3883,6 +3883,7 @@ bool regulatory_pre_cac_allowed(struct w | ||||||
|   |   | ||||||
|  	return pre_cac_allowed; |  	return pre_cac_allowed; | ||||||
|  } |  } | ||||||
|   | |||||||
| @@ -476,7 +476,7 @@ | |||||||
|  } |  } | ||||||
|   |   | ||||||
|  ieee80211_tx_result |  ieee80211_tx_result | ||||||
| @@ -1124,9 +1125,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct | @@ -1128,9 +1129,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct | ||||||
|  	struct ieee80211_key *key = tx->key; |  	struct ieee80211_key *key = tx->key; | ||||||
|  	struct ieee80211_mmie_16 *mmie; |  	struct ieee80211_mmie_16 *mmie; | ||||||
|  	struct ieee80211_hdr *hdr; |  	struct ieee80211_hdr *hdr; | ||||||
| @@ -488,7 +488,7 @@ | |||||||
|   |   | ||||||
|  	if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) |  	if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) | ||||||
|  		return TX_DROP; |  		return TX_DROP; | ||||||
| @@ -1172,7 +1173,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct | @@ -1176,7 +1177,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct | ||||||
|  	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |  	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||||||
|  	struct ieee80211_key *key = rx->key; |  	struct ieee80211_key *key = rx->key; | ||||||
|  	struct ieee80211_mmie_16 *mmie; |  	struct ieee80211_mmie_16 *mmie; | ||||||
| @@ -687,7 +687,7 @@ | |||||||
|  #endif /* AES_GMAC_H */ |  #endif /* AES_GMAC_H */ | ||||||
| --- a/net/mac80211/key.h | --- a/net/mac80211/key.h | ||||||
| +++ b/net/mac80211/key.h | +++ b/net/mac80211/key.h | ||||||
| @@ -87,7 +87,7 @@ struct ieee80211_key { | @@ -88,7 +88,7 @@ struct ieee80211_key { | ||||||
|  			 * Management frames. |  			 * Management frames. | ||||||
|  			 */ |  			 */ | ||||||
|  			u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; |  			u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects | |||||||
|  |  | ||||||
| --- a/net/mac80211/cfg.c | --- a/net/mac80211/cfg.c | ||||||
| +++ b/net/mac80211/cfg.c | +++ b/net/mac80211/cfg.c | ||||||
| @@ -1169,7 +1169,6 @@ static int ieee80211_stop_ap(struct wiph | @@ -1172,7 +1172,6 @@ static int ieee80211_stop_ap(struct wiph | ||||||
|  	sdata->vif.bss_conf.ftmr_params = NULL; |  	sdata->vif.bss_conf.ftmr_params = NULL; | ||||||
|   |   | ||||||
|  	__sta_info_flush(sdata, true); |  	__sta_info_flush(sdata, true); | ||||||
|   | |||||||
| @@ -188,7 +188,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  #endif /* AES_CMAC_H */ |  #endif /* AES_CMAC_H */ | ||||||
| --- a/net/mac80211/key.h | --- a/net/mac80211/key.h | ||||||
| +++ b/net/mac80211/key.h | +++ b/net/mac80211/key.h | ||||||
| @@ -92,7 +92,7 @@ struct ieee80211_key { | @@ -93,7 +93,7 @@ struct ieee80211_key { | ||||||
|  		} ccmp; |  		} ccmp; | ||||||
|  		struct { |  		struct { | ||||||
|  			u8 rx_pn[IEEE80211_CMAC_PN_LEN]; |  			u8 rx_pn[IEEE80211_CMAC_PN_LEN]; | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/net/mac80211/tx.c | --- a/net/mac80211/tx.c | ||||||
| +++ b/net/mac80211/tx.c | +++ b/net/mac80211/tx.c | ||||||
| @@ -4012,6 +4012,12 @@ out: | @@ -4015,6 +4015,12 @@ out: | ||||||
|  netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, |  netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | ||||||
|  				       struct net_device *dev) |  				       struct net_device *dev) | ||||||
|  { |  { | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ | |||||||
|  static int ieee80211_ifa6_changed(struct notifier_block *nb, |  static int ieee80211_ifa6_changed(struct notifier_block *nb, | ||||||
|  				  unsigned long data, void *arg) |  				  unsigned long data, void *arg) | ||||||
|  { |  { | ||||||
| @@ -1269,14 +1269,14 @@ int ieee80211_register_hw(struct ieee802 | @@ -1264,14 +1264,14 @@ int ieee80211_register_hw(struct ieee802 | ||||||
|   |   | ||||||
|  	rtnl_unlock(); |  	rtnl_unlock(); | ||||||
|   |   | ||||||
| @@ -35,7 +35,7 @@ | |||||||
|  	local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; |  	local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; | ||||||
|  	result = register_inet6addr_notifier(&local->ifa6_notifier); |  	result = register_inet6addr_notifier(&local->ifa6_notifier); | ||||||
|  	if (result) |  	if (result) | ||||||
| @@ -1285,13 +1285,13 @@ int ieee80211_register_hw(struct ieee802 | @@ -1280,13 +1280,13 @@ int ieee80211_register_hw(struct ieee802 | ||||||
|   |   | ||||||
|  	return 0; |  	return 0; | ||||||
|   |   | ||||||
| @@ -52,7 +52,7 @@ | |||||||
|   fail_ifa: |   fail_ifa: | ||||||
|  #endif |  #endif | ||||||
|  	rtnl_lock(); |  	rtnl_lock(); | ||||||
| @@ -1319,10 +1319,10 @@ void ieee80211_unregister_hw(struct ieee | @@ -1314,10 +1314,10 @@ void ieee80211_unregister_hw(struct ieee | ||||||
|  	tasklet_kill(&local->tx_pending_tasklet); |  	tasklet_kill(&local->tx_pending_tasklet); | ||||||
|  	tasklet_kill(&local->tasklet); |  	tasklet_kill(&local->tasklet); | ||||||
|   |   | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/net/mac80211/cfg.c | --- a/net/mac80211/cfg.c | ||||||
| +++ b/net/mac80211/cfg.c | +++ b/net/mac80211/cfg.c | ||||||
| @@ -2314,7 +2314,7 @@ static int ieee80211_scan(struct wiphy * | @@ -2317,7 +2317,7 @@ static int ieee80211_scan(struct wiphy * | ||||||
|  		 * the  frames sent while scanning on other channel will be |  		 * the  frames sent while scanning on other channel will be | ||||||
|  		 * lost) |  		 * lost) | ||||||
|  		 */ |  		 */ | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  |  | ||||||
| --- a/net/mac80211/ieee80211_i.h | --- a/net/mac80211/ieee80211_i.h | ||||||
| +++ b/net/mac80211/ieee80211_i.h | +++ b/net/mac80211/ieee80211_i.h | ||||||
| @@ -1779,6 +1779,9 @@ int ieee80211_tx_control_port(struct wip | @@ -1782,6 +1782,9 @@ int ieee80211_tx_control_port(struct wip | ||||||
|  			      const u8 *dest, __be16 proto, bool unencrypted); |  			      const u8 *dest, __be16 proto, bool unencrypted); | ||||||
|  int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, |  int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, | ||||||
|  			      const u8 *buf, size_t len); |  			      const u8 *buf, size_t len); | ||||||
| @@ -36,7 +36,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, |  void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, | ||||||
| --- a/net/mac80211/status.c | --- a/net/mac80211/status.c | ||||||
| +++ b/net/mac80211/status.c | +++ b/net/mac80211/status.c | ||||||
| @@ -655,6 +655,11 @@ void ieee80211_tx_monitor(struct ieee802 | @@ -815,6 +815,11 @@ void ieee80211_tx_monitor(struct ieee802 | ||||||
|  	struct net_device *prev_dev = NULL; |  	struct net_device *prev_dev = NULL; | ||||||
|  	int rtap_len; |  	int rtap_len; | ||||||
|   |   | ||||||
| @@ -46,11 +46,11 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| +	} | +	} | ||||||
| + | + | ||||||
|  	/* send frame to monitor interfaces now */ |  	/* send frame to monitor interfaces now */ | ||||||
|  	rtap_len = ieee80211_tx_radiotap_len(info); |  	rtap_len = ieee80211_tx_radiotap_len(info, status); | ||||||
|  	if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { |  	if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { | ||||||
| --- a/net/mac80211/tx.c | --- a/net/mac80211/tx.c | ||||||
| +++ b/net/mac80211/tx.c | +++ b/net/mac80211/tx.c | ||||||
| @@ -1936,37 +1936,53 @@ static bool ieee80211_tx(struct ieee8021 | @@ -1937,37 +1937,53 @@ static bool ieee80211_tx(struct ieee8021 | ||||||
|  } |  } | ||||||
|   |   | ||||||
|  /* device xmit handlers */ |  /* device xmit handlers */ | ||||||
| @@ -123,7 +123,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  		wiphy_debug(local->hw.wiphy, |  		wiphy_debug(local->hw.wiphy, | ||||||
|  			    "failed to reallocate TX buffer\n"); |  			    "failed to reallocate TX buffer\n"); | ||||||
|  		return -ENOMEM; |  		return -ENOMEM; | ||||||
| @@ -1982,18 +1998,8 @@ void ieee80211_xmit(struct ieee80211_sub | @@ -1983,18 +1999,8 @@ void ieee80211_xmit(struct ieee80211_sub | ||||||
|  	struct ieee80211_local *local = sdata->local; |  	struct ieee80211_local *local = sdata->local; | ||||||
|  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||||||
|  	struct ieee80211_hdr *hdr; |  	struct ieee80211_hdr *hdr; | ||||||
| @@ -143,7 +143,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  		ieee80211_free_txskb(&local->hw, skb); |  		ieee80211_free_txskb(&local->hw, skb); | ||||||
|  		return; |  		return; | ||||||
|  	} |  	} | ||||||
| @@ -2774,29 +2780,13 @@ static struct sk_buff *ieee80211_build_h | @@ -2775,29 +2781,13 @@ static struct sk_buff *ieee80211_build_h | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
|  	skb_pull(skb, skip_header_bytes); |  	skb_pull(skb, skip_header_bytes); | ||||||
| @@ -179,7 +179,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	} |  	} | ||||||
|   |   | ||||||
|  	if (encaps_data) |  	if (encaps_data) | ||||||
| @@ -3411,7 +3401,6 @@ static bool ieee80211_xmit_fast(struct i | @@ -3412,7 +3402,6 @@ static bool ieee80211_xmit_fast(struct i | ||||||
|  	struct ieee80211_local *local = sdata->local; |  	struct ieee80211_local *local = sdata->local; | ||||||
|  	u16 ethertype = (skb->data[12] << 8) | skb->data[13]; |  	u16 ethertype = (skb->data[12] << 8) | skb->data[13]; | ||||||
|  	int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); |  	int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); | ||||||
| @@ -187,7 +187,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	struct ethhdr eth; |  	struct ethhdr eth; | ||||||
|  	struct ieee80211_tx_info *info; |  	struct ieee80211_tx_info *info; | ||||||
|  	struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; |  	struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; | ||||||
| @@ -3463,10 +3452,7 @@ static bool ieee80211_xmit_fast(struct i | @@ -3464,10 +3453,7 @@ static bool ieee80211_xmit_fast(struct i | ||||||
|  	 * as the may-encrypt argument for the resize to not account for |  	 * as the may-encrypt argument for the resize to not account for | ||||||
|  	 * more room than we already have in 'extra_head' |  	 * more room than we already have in 'extra_head' | ||||||
|  	 */ |  	 */ | ||||||
|   | |||||||
| @@ -1,22 +0,0 @@ | |||||||
| From: Felix Fietkau <nbd@nbd.name> |  | ||||||
| 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 <nbd@nbd.name> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- 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))) |  | ||||||
| @@ -1,42 +0,0 @@ | |||||||
| From: Felix Fietkau <nbd@nbd.name> |  | ||||||
| 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 <nbd@nbd.name> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- 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. |  | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| From: Felix Fietkau <nbd@nbd.name> |  | ||||||
| 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 <nbd@nbd.name> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- 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++) { |  | ||||||
| @@ -1,481 +0,0 @@ | |||||||
| From: Felix Fietkau <nbd@nbd.name> |  | ||||||
| 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 <nbd@nbd.name> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- 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; |  | ||||||
|   |  | ||||||
| @@ -1,58 +0,0 @@ | |||||||
| From: Lorenzo Bianconi <lorenzo@kernel.org> |  | ||||||
| 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 <lorenzo@kernel.org> |  | ||||||
| Link: https://lore.kernel.org/r/dfe275f9aa0f1cc6b33085f9efd5d8447f68ad13.1563228405.git.lorenzo@kernel.org |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- 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); |  | ||||||
|   |  | ||||||
|  	/* |  | ||||||
| @@ -1,25 +0,0 @@ | |||||||
| From: Colin Ian King <colin.king@canonical.com> |  | ||||||
| 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 <colin.king@canonical.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- 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; |  | ||||||
|   |  | ||||||
| @@ -1,77 +0,0 @@ | |||||||
| From: Felix Fietkau <nbd@nbd.name> |  | ||||||
| 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 <nbd@nbd.name> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- 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 |  | ||||||
| @@ -8729,6 +8729,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); |  | ||||||
|   |  | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/include/net/cfg80211.h | --- a/include/net/cfg80211.h | ||||||
| +++ b/include/net/cfg80211.h | +++ b/include/net/cfg80211.h | ||||||
| @@ -3348,6 +3348,7 @@ struct cfg80211_update_owe_info { | @@ -3447,6 +3447,7 @@ struct cfg80211_update_owe_info { | ||||||
|   *	(as advertised by the nl80211 feature flag.) |   *	(as advertised by the nl80211 feature flag.) | ||||||
|   * @get_tx_power: store the current TX power into the dbm variable; |   * @get_tx_power: store the current TX power into the dbm variable; | ||||||
|   *	return 0 if successful |   *	return 0 if successful | ||||||
| @@ -8,7 +8,7 @@ | |||||||
|   * |   * | ||||||
|   * @set_wds_peer: set the WDS peer for a WDS interface |   * @set_wds_peer: set the WDS peer for a WDS interface | ||||||
|   * |   * | ||||||
| @@ -3660,6 +3661,7 @@ struct cfg80211_ops { | @@ -3759,6 +3760,7 @@ struct cfg80211_ops { | ||||||
|  				enum nl80211_tx_power_setting type, int mbm); |  				enum nl80211_tx_power_setting type, int mbm); | ||||||
|  	int	(*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, |  	int	(*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, | ||||||
|  				int *dbm); |  				int *dbm); | ||||||
| @@ -18,7 +18,7 @@ | |||||||
|  				const u8 *addr); |  				const u8 *addr); | ||||||
| --- a/include/net/mac80211.h | --- a/include/net/mac80211.h | ||||||
| +++ b/include/net/mac80211.h | +++ b/include/net/mac80211.h | ||||||
| @@ -1476,6 +1476,7 @@ enum ieee80211_smps_mode { | @@ -1484,6 +1484,7 @@ enum ieee80211_smps_mode { | ||||||
|   * |   * | ||||||
|   * @power_level: requested transmit power (in dBm), backward compatibility |   * @power_level: requested transmit power (in dBm), backward compatibility | ||||||
|   *	value only that is set to the minimum of all interfaces |   *	value only that is set to the minimum of all interfaces | ||||||
| @@ -26,7 +26,7 @@ | |||||||
|   * |   * | ||||||
|   * @chandef: the channel definition to tune to |   * @chandef: the channel definition to tune to | ||||||
|   * @radar_enabled: whether radar detection is enabled |   * @radar_enabled: whether radar detection is enabled | ||||||
| @@ -1496,6 +1497,7 @@ enum ieee80211_smps_mode { | @@ -1504,6 +1505,7 @@ enum ieee80211_smps_mode { | ||||||
|  struct ieee80211_conf { |  struct ieee80211_conf { | ||||||
|  	u32 flags; |  	u32 flags; | ||||||
|  	int power_level, dynamic_ps_timeout; |  	int power_level, dynamic_ps_timeout; | ||||||
| @@ -36,9 +36,9 @@ | |||||||
|  	u8 ps_dtim_period; |  	u8 ps_dtim_period; | ||||||
| --- a/include/uapi/linux/nl80211.h | --- a/include/uapi/linux/nl80211.h | ||||||
| +++ b/include/uapi/linux/nl80211.h | +++ b/include/uapi/linux/nl80211.h | ||||||
| @@ -2356,6 +2356,9 @@ enum nl80211_commands { | @@ -2373,6 +2373,9 @@ enum nl80211_commands { | ||||||
|   * |   *	the allowed channel bandwidth configurations. (u8 attribute) | ||||||
|   * @NL80211_ATTR_TWT_RESPONDER: Enable target wait time responder support. |   *	Defined by IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13. | ||||||
|   * |   * | ||||||
| + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce | + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce | ||||||
| + *	transmit power to stay within regulatory limits. u32, dBi. | + *	transmit power to stay within regulatory limits. u32, dBi. | ||||||
| @@ -46,9 +46,9 @@ | |||||||
|   * @NUM_NL80211_ATTR: total number of nl80211_attrs available |   * @NUM_NL80211_ATTR: total number of nl80211_attrs available | ||||||
|   * @NL80211_ATTR_MAX: highest attribute number currently defined |   * @NL80211_ATTR_MAX: highest attribute number currently defined | ||||||
|   * @__NL80211_ATTR_AFTER_LAST: internal use |   * @__NL80211_ATTR_AFTER_LAST: internal use | ||||||
| @@ -2813,6 +2816,8 @@ enum nl80211_attrs { | @@ -2835,6 +2838,8 @@ enum nl80211_attrs { | ||||||
|   |  	NL80211_ATTR_WIPHY_EDMG_CHANNELS, | ||||||
|  	NL80211_ATTR_TWT_RESPONDER, |  	NL80211_ATTR_WIPHY_EDMG_BW_CONFIG, | ||||||
|   |   | ||||||
| +	NL80211_ATTR_WIPHY_ANTENNA_GAIN, | +	NL80211_ATTR_WIPHY_ANTENNA_GAIN, | ||||||
| + | + | ||||||
| @@ -57,7 +57,7 @@ | |||||||
|  	__NL80211_ATTR_AFTER_LAST, |  	__NL80211_ATTR_AFTER_LAST, | ||||||
| --- a/net/mac80211/cfg.c | --- a/net/mac80211/cfg.c | ||||||
| +++ b/net/mac80211/cfg.c | +++ b/net/mac80211/cfg.c | ||||||
| @@ -2579,6 +2579,19 @@ static int ieee80211_get_tx_power(struct | @@ -2582,6 +2582,19 @@ static int ieee80211_get_tx_power(struct | ||||||
|  	return 0; |  	return 0; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -77,7 +77,7 @@ | |||||||
|  static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, |  static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, | ||||||
|  				  const u8 *addr) |  				  const u8 *addr) | ||||||
|  { |  { | ||||||
| @@ -3992,6 +4005,7 @@ const struct cfg80211_ops mac80211_confi | @@ -3995,6 +4008,7 @@ const struct cfg80211_ops mac80211_confi | ||||||
|  	.set_wiphy_params = ieee80211_set_wiphy_params, |  	.set_wiphy_params = ieee80211_set_wiphy_params, | ||||||
|  	.set_tx_power = ieee80211_set_tx_power, |  	.set_tx_power = ieee80211_set_tx_power, | ||||||
|  	.get_tx_power = ieee80211_get_tx_power, |  	.get_tx_power = ieee80211_get_tx_power, | ||||||
| @@ -126,18 +126,18 @@ | |||||||
| +	local->user_antenna_gain = 0; | +	local->user_antenna_gain = 0; | ||||||
|  	local->hw.uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; |  	local->hw.uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; | ||||||
|  	local->hw.uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; |  	local->hw.uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; | ||||||
|  	local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; |  	local->hw.max_mtu = IEEE80211_MAX_DATA_LEN; | ||||||
| --- a/net/wireless/nl80211.c | --- a/net/wireless/nl80211.c | ||||||
| +++ b/net/wireless/nl80211.c | +++ b/net/wireless/nl80211.c | ||||||
| @@ -607,6 +607,7 @@ const struct nla_policy nl80211_policy[N | @@ -624,6 +624,7 @@ const struct nla_policy nl80211_policy[N | ||||||
|  	[NL80211_ATTR_SAE_PASSWORD] = { .type = NLA_BINARY, |  | ||||||
|  					.len = SAE_PASSWORD_MAX_LEN }, |  					.len = SAE_PASSWORD_MAX_LEN }, | ||||||
|  	[NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG }, |  	[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 }, | +	[NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, | ||||||
|  }; |  }; | ||||||
|   |   | ||||||
|  /* policy for the key attributes */ |  /* policy for the key attributes */ | ||||||
| @@ -2904,6 +2905,20 @@ static int nl80211_set_wiphy(struct sk_b | @@ -2988,6 +2989,20 @@ static int nl80211_set_wiphy(struct sk_b | ||||||
|  		if (result) |  		if (result) | ||||||
|  			return result; |  			return result; | ||||||
|  	} |  	} | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk | |||||||
|  |  | ||||||
| PKG_NAME:=iw | PKG_NAME:=iw | ||||||
| PKG_VERSION:=5.3 | PKG_VERSION:=5.3 | ||||||
| PKG_RELEASE:=1 | PKG_RELEASE:=2 | ||||||
|  |  | ||||||
| PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz | ||||||
| PKG_SOURCE_URL:=@KERNEL/software/network/iw | PKG_SOURCE_URL:=@KERNEL/software/network/iw | ||||||
|   | |||||||
| @@ -1,46 +1,96 @@ | |||||||
| --- a/nl80211.h | --- a/nl80211.h | ||||||
| +++ b/nl80211.h | +++ b/nl80211.h | ||||||
| @@ -657,9 +657,7 @@ | @@ -52,6 +52,11 @@ | ||||||
|   *	is used during CSA period. |  #define NL80211_MULTICAST_GROUP_NAN		"nan" | ||||||
|   * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this |  #define NL80211_MULTICAST_GROUP_TESTMODE	"testmode" | ||||||
|   *	command may be used with the corresponding cookie to cancel the wait |   | ||||||
| - *	time if it is known that it is no longer necessary.  This command is | +#define NL80211_EDMG_BW_CONFIG_MIN	4 | ||||||
| - *	also sent as an event whenever the driver has completed the off-channel | +#define NL80211_EDMG_BW_CONFIG_MAX	15 | ||||||
| - *	wait time. | +#define NL80211_EDMG_CHANNELS_MIN	1 | ||||||
| + *	time if it is known that it is no longer necessary. | +#define NL80211_EDMG_CHANNELS_MAX	0x3c /* 0b00111100 */ | ||||||
|   * @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility. | + | ||||||
|   * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame |  /** | ||||||
|   *	transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies |   * DOC: Station handling | ||||||
| @@ -2358,8 +2356,8 @@ enum nl80211_commands { |  | ||||||
|   * |   * | ||||||
|   * @NL80211_ATTR_TWT_RESPONDER: Enable target wait time responder support. | @@ -2361,6 +2366,16 @@ enum nl80211_commands { | ||||||
|  |   * @NL80211_ATTR_HE_OBSS_PD: nested attribute for OBSS Packet Detection | ||||||
|  |   *	functionality. | ||||||
|   * |   * | ||||||
| - * @NL80211_ATTR_HE_OBSS_PD: nested attribute for OBSS Packet Detection | + * @NL80211_ATTR_WIPHY_EDMG_CHANNELS: bitmap that indicates the 2.16 GHz | ||||||
| - *	functionality. | + *	channel(s) that are allowed to be used for EDMG transmissions. | ||||||
|  | + *	Defined by IEEE P802.11ay/D4.0 section 9.4.2.251. (u8 attribute) | ||||||
|  | + * @NL80211_ATTR_WIPHY_EDMG_BW_CONFIG: Channel BW Configuration subfield encodes | ||||||
|  | + *	the allowed channel bandwidth configurations. (u8 attribute) | ||||||
|  | + *	Defined by IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13. | ||||||
|  | + * | ||||||
| + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce | + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce | ||||||
| + *	transmit power to stay within regulatory limits. u32, dBi. | + *	transmit power to stay within regulatory limits. u32, dBi. | ||||||
|   * | + * | ||||||
|   * @NUM_NL80211_ATTR: total number of nl80211_attrs available |   * @NUM_NL80211_ATTR: total number of nl80211_attrs available | ||||||
|   * @NL80211_ATTR_MAX: highest attribute number currently defined |   * @NL80211_ATTR_MAX: highest attribute number currently defined | ||||||
| @@ -2818,7 +2816,7 @@ enum nl80211_attrs { |   * @__NL80211_ATTR_AFTER_LAST: internal use | ||||||
|  | @@ -2820,6 +2835,11 @@ enum nl80211_attrs { | ||||||
|   |   | ||||||
|  	NL80211_ATTR_TWT_RESPONDER, |  	NL80211_ATTR_HE_OBSS_PD, | ||||||
|   |   | ||||||
| -	NL80211_ATTR_HE_OBSS_PD, | +	NL80211_ATTR_WIPHY_EDMG_CHANNELS, | ||||||
|  | +	NL80211_ATTR_WIPHY_EDMG_BW_CONFIG, | ||||||
|  | + | ||||||
| +	NL80211_ATTR_WIPHY_ANTENNA_GAIN, | +	NL80211_ATTR_WIPHY_ANTENNA_GAIN, | ||||||
|   | + | ||||||
|  	/* add attributes here, update the policy in nl80211.c */ |  	/* add attributes here, update the policy in nl80211.c */ | ||||||
|   |   | ||||||
| @@ -3843,6 +3841,8 @@ enum nl80211_user_reg_hint_type { |  	__NL80211_ATTR_AFTER_LAST, | ||||||
|  | @@ -3201,6 +3221,8 @@ enum nl80211_sta_bss_param { | ||||||
|  |   *	sent to the station (u64, usec) | ||||||
|  |   * @NL80211_STA_INFO_AIRTIME_WEIGHT: current airtime weight for station (u16) | ||||||
|  |   * @NL80211_STA_INFO_AIRTIME_LINK_METRIC: airtime link metric for mesh station | ||||||
|  | + * @NL80211_STA_INFO_ASSOC_AT_BOOTTIME: Timestamp (CLOCK_BOOTTIME, nanoseconds) | ||||||
|  | + *	of STA's association | ||||||
|  |   * @__NL80211_STA_INFO_AFTER_LAST: internal | ||||||
|  |   * @NL80211_STA_INFO_MAX: highest possible station info attribute | ||||||
|  |   */ | ||||||
|  | @@ -3247,6 +3269,7 @@ enum nl80211_sta_info { | ||||||
|  |  	NL80211_STA_INFO_TX_DURATION, | ||||||
|  |  	NL80211_STA_INFO_AIRTIME_WEIGHT, | ||||||
|  |  	NL80211_STA_INFO_AIRTIME_LINK_METRIC, | ||||||
|  | +	NL80211_STA_INFO_ASSOC_AT_BOOTTIME, | ||||||
|  |   | ||||||
|  |  	/* keep last */ | ||||||
|  |  	__NL80211_STA_INFO_AFTER_LAST, | ||||||
|  | @@ -3428,6 +3451,12 @@ enum nl80211_band_iftype_attr { | ||||||
|  |   * @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE | ||||||
|  |   * @NL80211_BAND_ATTR_IFTYPE_DATA: nested array attribute, with each entry using | ||||||
|  |   *	attributes from &enum nl80211_band_iftype_attr | ||||||
|  | + * @NL80211_BAND_ATTR_EDMG_CHANNELS: bitmap that indicates the 2.16 GHz | ||||||
|  | + *	channel(s) that are allowed to be used for EDMG transmissions. | ||||||
|  | + *	Defined by IEEE P802.11ay/D4.0 section 9.4.2.251. | ||||||
|  | + * @NL80211_BAND_ATTR_EDMG_BW_CONFIG: Channel BW Configuration subfield encodes | ||||||
|  | + *	the allowed channel bandwidth configurations. | ||||||
|  | + *	Defined by IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13. | ||||||
|  |   * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined | ||||||
|  |   * @__NL80211_BAND_ATTR_AFTER_LAST: internal use | ||||||
|  |   */ | ||||||
|  | @@ -3445,6 +3474,9 @@ enum nl80211_band_attr { | ||||||
|  |  	NL80211_BAND_ATTR_VHT_CAPA, | ||||||
|  |  	NL80211_BAND_ATTR_IFTYPE_DATA, | ||||||
|  |   | ||||||
|  | +	NL80211_BAND_ATTR_EDMG_CHANNELS, | ||||||
|  | +	NL80211_BAND_ATTR_EDMG_BW_CONFIG, | ||||||
|  | + | ||||||
|  |  	/* keep last */ | ||||||
|  |  	__NL80211_BAND_ATTR_AFTER_LAST, | ||||||
|  |  	NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1 | ||||||
|  | @@ -3843,6 +3875,8 @@ enum nl80211_user_reg_hint_type { | ||||||
|   * @NL80211_SURVEY_INFO_TIME_SCAN: time the radio spent for scan |   * @NL80211_SURVEY_INFO_TIME_SCAN: time the radio spent for scan | ||||||
|   *	(on this channel or globally) |   *	(on this channel or globally) | ||||||
|   * @NL80211_SURVEY_INFO_PAD: attribute used for padding for 64-bit alignment |   * @NL80211_SURVEY_INFO_PAD: attribute used for padding for 64-bit alignment | ||||||
| + * @NL80211_SURVEY_INFO_TIME_BSS_RX: amount of time the radio spent | + * @NL80211_SURVEY_INFO_TIME_BSS_RX: amount of time the radio spent | ||||||
| + *	receiving local BSS data | + *	receiving frames destined to the local BSS | ||||||
|   * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number |   * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number | ||||||
|   *	currently defined |   *	currently defined | ||||||
|   * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use |   * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use | ||||||
| @@ -3859,6 +3859,7 @@ enum nl80211_survey_info { | @@ -3859,6 +3893,7 @@ enum nl80211_survey_info { | ||||||
|  	NL80211_SURVEY_INFO_TIME_TX, |  	NL80211_SURVEY_INFO_TIME_TX, | ||||||
|  	NL80211_SURVEY_INFO_TIME_SCAN, |  	NL80211_SURVEY_INFO_TIME_SCAN, | ||||||
|  	NL80211_SURVEY_INFO_PAD, |  	NL80211_SURVEY_INFO_PAD, | ||||||
| @@ -48,30 +98,19 @@ | |||||||
|   |   | ||||||
|  	/* keep last */ |  	/* keep last */ | ||||||
|  	__NL80211_SURVEY_INFO_AFTER_LAST, |  	__NL80211_SURVEY_INFO_AFTER_LAST, | ||||||
| @@ -6495,26 +6496,4 @@ enum nl80211_peer_measurement_ftm_resp { | @@ -4543,6 +4578,7 @@ enum nl80211_txrate_gi { | ||||||
|  	NL80211_PMSR_FTM_RESP_ATTR_MAX = NUM_NL80211_PMSR_FTM_RESP_ATTR - 1 |   * @NL80211_BAND_2GHZ: 2.4 GHz ISM band | ||||||
|  }; |   * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) | ||||||
|  |   * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 69.12 GHz) | ||||||
|  | + * @NL80211_BAND_6GHZ: around 6 GHz band (5.9 - 7.2 GHz) | ||||||
|  |   * @NUM_NL80211_BANDS: number of bands, avoid using this in userspace | ||||||
|  |   *	since newer kernel versions may support more bands | ||||||
|  |   */ | ||||||
|  | @@ -4550,6 +4586,7 @@ enum nl80211_band { | ||||||
|  |  	NL80211_BAND_2GHZ, | ||||||
|  |  	NL80211_BAND_5GHZ, | ||||||
|  |  	NL80211_BAND_60GHZ, | ||||||
|  | +	NL80211_BAND_6GHZ, | ||||||
|   |   | ||||||
| -/** |  	NUM_NL80211_BANDS, | ||||||
| - * enum nl80211_obss_pd_attributes - OBSS packet detection attributes |  }; | ||||||
| - * @__NL80211_HE_OBSS_PD_ATTR_INVALID: Invalid |  | ||||||
| - * |  | ||||||
| - * @NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET: the OBSS PD minimum tx power offset. |  | ||||||
| - * @NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET: the OBSS PD maximum tx power offset. |  | ||||||
| - * |  | ||||||
| - * @__NL80211_HE_OBSS_PD_ATTR_LAST: Internal |  | ||||||
| - * @NL80211_HE_OBSS_PD_ATTR_MAX: highest OBSS PD attribute. |  | ||||||
| - */ |  | ||||||
| -enum nl80211_obss_pd_attributes { |  | ||||||
| -	__NL80211_HE_OBSS_PD_ATTR_INVALID, |  | ||||||
| - |  | ||||||
| -	NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET, |  | ||||||
| -	NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET, |  | ||||||
| - |  | ||||||
| -	/* keep last */ |  | ||||||
| -	__NL80211_HE_OBSS_PD_ATTR_LAST, |  | ||||||
| -	NL80211_HE_OBSS_PD_ATTR_MAX = __NL80211_HE_OBSS_PD_ATTR_LAST - 1, |  | ||||||
| -}; |  | ||||||
| - |  | ||||||
| - |  | ||||||
|  #endif /* __LINUX_NL80211_H */ |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Hauke Mehrtens
					Hauke Mehrtens