mac80211: brcmfmac: backport 5.0 & 5.1 important changes/fixes
This backports the most important brcmfmac commits that: 1) Fix some bugs 2) Help debugging bugs Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
		| @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk | ||||
| PKG_NAME:=mac80211 | ||||
|  | ||||
| PKG_VERSION:=2017-11-01 | ||||
| PKG_RELEASE:=9 | ||||
| PKG_RELEASE:=10 | ||||
| PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources | ||||
| PKG_HASH:=8437ab7886b988c8152e7a4db30b7f41009e49a3b2cb863edd05da1ecd7eb05a | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,34 @@ | ||||
| From e966a79c2f761a696dec9cfb0e2d4aa977bf78cb Mon Sep 17 00:00:00 2001 | ||||
| From: Colin Ian King <colin.king@canonical.com> | ||||
| Date: Tue, 16 Oct 2018 18:43:42 +0100 | ||||
| Subject: [PATCH] brcmfmac: fix spelling mistake "Retreiving" -> "Retrieving" | ||||
|  | ||||
| Trivial fix to spelling mistake in brcmf_err error message. | ||||
|  | ||||
| Signed-off-by: Colin Ian King <colin.king@canonical.com> | ||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 4 ++-- | ||||
|  1 file changed, 2 insertions(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||
| @@ -214,7 +214,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i | ||||
|  	err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, | ||||
|  				       sizeof(ifp->mac_addr)); | ||||
|  	if (err < 0) { | ||||
| -		brcmf_err("Retreiving cur_etheraddr failed, %d\n", err); | ||||
| +		brcmf_err("Retrieving cur_etheraddr failed, %d\n", err); | ||||
|  		goto done; | ||||
|  	} | ||||
|  	memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN); | ||||
| @@ -269,7 +269,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i | ||||
|  	strcpy(buf, "ver"); | ||||
|  	err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf)); | ||||
|  	if (err < 0) { | ||||
| -		brcmf_err("Retreiving version information failed, %d\n", | ||||
| +		brcmf_err("Retrieving version information failed, %d\n", | ||||
|  			  err); | ||||
|  		goto done; | ||||
|  	} | ||||
| @@ -0,0 +1,110 @@ | ||||
| From b72c51a58e6d63ef673ac96b8ab5bc98799c5f7b Mon Sep 17 00:00:00 2001 | ||||
| From: Lyude Paul <lyude@redhat.com> | ||||
| Date: Sat, 24 Nov 2018 17:57:05 -0500 | ||||
| Subject: [PATCH] brcmfmac: Fix out of bounds memory access during fw load | ||||
|  | ||||
| I ended up tracking down some rather nasty issues with f2fs (and other | ||||
| filesystem modules) constantly crashing on my kernel down to a | ||||
| combination of out of bounds memory accesses, one of which was coming | ||||
| from brcmfmac during module load: | ||||
|  | ||||
| [   30.891382] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac4356-sdio for chip BCM4356/2 | ||||
| [   30.894437] ================================================================== | ||||
| [   30.901581] BUG: KASAN: global-out-of-bounds in brcmf_fw_alloc_request+0x42c/0x480 [brcmfmac] | ||||
| [   30.909935] Read of size 1 at addr ffff2000024865df by task kworker/6:2/387 | ||||
| [   30.916805] | ||||
| [   30.918261] CPU: 6 PID: 387 Comm: kworker/6:2 Tainted: G           O      4.20.0-rc3Lyude-Test+ #19 | ||||
| [   30.927251] Hardware name: amlogic khadas-vim2/khadas-vim2, BIOS 2018.07-rc2-armbian 09/11/2018 | ||||
| [   30.935964] Workqueue: events brcmf_driver_register [brcmfmac] | ||||
| [   30.941641] Call trace: | ||||
| [   30.944058]  dump_backtrace+0x0/0x3e8 | ||||
| [   30.947676]  show_stack+0x14/0x20 | ||||
| [   30.950968]  dump_stack+0x130/0x1c4 | ||||
| [   30.954406]  print_address_description+0x60/0x25c | ||||
| [   30.959066]  kasan_report+0x1b4/0x368 | ||||
| [   30.962683]  __asan_report_load1_noabort+0x18/0x20 | ||||
| [   30.967547]  brcmf_fw_alloc_request+0x42c/0x480 [brcmfmac] | ||||
| [   30.967639]  brcmf_sdio_probe+0x163c/0x2050 [brcmfmac] | ||||
| [   30.978035]  brcmf_ops_sdio_probe+0x598/0xa08 [brcmfmac] | ||||
| [   30.983254]  sdio_bus_probe+0x190/0x398 | ||||
| [   30.983270]  really_probe+0x2a0/0xa70 | ||||
| [   30.983296]  driver_probe_device+0x1b4/0x2d8 | ||||
| [   30.994901]  __driver_attach+0x200/0x280 | ||||
| [   30.994914]  bus_for_each_dev+0x10c/0x1a8 | ||||
| [   30.994925]  driver_attach+0x38/0x50 | ||||
| [   30.994935]  bus_add_driver+0x330/0x608 | ||||
| [   30.994953]  driver_register+0x140/0x388 | ||||
| [   31.013965]  sdio_register_driver+0x74/0xa0 | ||||
| [   31.014076]  brcmf_sdio_register+0x14/0x60 [brcmfmac] | ||||
| [   31.023177]  brcmf_driver_register+0xc/0x18 [brcmfmac] | ||||
| [   31.023209]  process_one_work+0x654/0x1080 | ||||
| [   31.032266]  worker_thread+0x4f0/0x1308 | ||||
| [   31.032286]  kthread+0x2a8/0x320 | ||||
| [   31.039254]  ret_from_fork+0x10/0x1c | ||||
| [   31.039269] | ||||
| [   31.044226] The buggy address belongs to the variable: | ||||
| [   31.044351]  brcmf_firmware_path+0x11f/0xfffffffffffd3b40 [brcmfmac] | ||||
| [   31.055601] | ||||
| [   31.057031] Memory state around the buggy address: | ||||
| [   31.061800]  ffff200002486480: 04 fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 | ||||
| [   31.068983]  ffff200002486500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||||
| [   31.068993] >ffff200002486580: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00 | ||||
| [   31.068999]                                                     ^ | ||||
| [   31.069017]  ffff200002486600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||||
| [   31.096521]  ffff200002486680: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa | ||||
| [   31.096528] ================================================================== | ||||
| [   31.096533] Disabling lock debugging due to kernel taint | ||||
|  | ||||
| It appears that when trying to determine the length of the string in the | ||||
| alternate firmware path, we make the mistake of not handling the case | ||||
| where the firmware path is empty correctly. Since strlen(mp_path) can | ||||
| return 0, we'll end up accessing mp_path[-1] when the firmware_path | ||||
| isn't provided through the module arguments. | ||||
|  | ||||
| So, fix this by just setting the end char to '\0' by default, and only | ||||
| changing it if we have a non-zero length. Additionally, use strnlen() | ||||
| with BRCMF_FW_ALTPATH_LEN instead of strlen() just to be extra safe. | ||||
|  | ||||
| Fixes: 2baa3aaee27f ("brcmfmac: introduce brcmf_fw_alloc_request() function") | ||||
| Cc: Hante Meuleman <hante.meuleman@broadcom.com> | ||||
| Cc: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||
| Cc: Franky Lin <franky.lin@broadcom.com> | ||||
| Cc: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Cc: Kalle Valo <kvalo@codeaurora.org> | ||||
| Cc: Arend Van Spriel <arend.vanspriel@broadcom.com> | ||||
| Cc: Himanshu Jha <himanshujha199640@gmail.com> | ||||
| Cc: Dan Haab <dhaab@luxul.com> | ||||
| Cc: Jia-Shyr Chuang <saint.chuang@cypress.com> | ||||
| Cc: Ian Molton <ian@mnementh.co.uk> | ||||
| Cc: <stable@vger.kernel.org> # v4.17+ | ||||
| Signed-off-by: Lyude Paul <lyude@redhat.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/firmware.c   | 8 ++++++-- | ||||
|  1 file changed, 6 insertions(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | ||||
| @@ -633,8 +633,9 @@ brcmf_fw_alloc_request(u32 chip, u32 chi | ||||
|  	struct brcmf_fw_request *fwreq; | ||||
|  	char chipname[12]; | ||||
|  	const char *mp_path; | ||||
| +	size_t mp_path_len; | ||||
|  	u32 i, j; | ||||
| -	char end; | ||||
| +	char end = '\0'; | ||||
|  	size_t reqsz; | ||||
|   | ||||
|  	for (i = 0; i < table_size; i++) { | ||||
| @@ -659,7 +660,10 @@ brcmf_fw_alloc_request(u32 chip, u32 chi | ||||
|  		   mapping_table[i].fw_base, chipname); | ||||
|   | ||||
|  	mp_path = brcmf_mp_global.firmware_path; | ||||
| -	end = mp_path[strlen(mp_path) - 1]; | ||||
| +	mp_path_len = strnlen(mp_path, BRCMF_FW_ALTPATH_LEN); | ||||
| +	if (mp_path_len) | ||||
| +		end = mp_path[mp_path_len - 1]; | ||||
| + | ||||
|  	fwreq->n_items = n_fwnames; | ||||
|   | ||||
|  	for (j = 0; j < n_fwnames; j++) { | ||||
| @@ -0,0 +1,68 @@ | ||||
| From 8c892df41500469729e0d662816300196e4f463d Mon Sep 17 00:00:00 2001 | ||||
| From: Stijn Tintel <stijn@linux-ipv6.be> | ||||
| Date: Tue, 4 Dec 2018 20:29:05 +0200 | ||||
| Subject: [PATCH] brcmfmac: fix roamoff=1 modparam | ||||
|  | ||||
| When the update_connect_param callback is set, nl80211 expects the flag | ||||
| WIPHY_FLAG_SUPPORTS_FW_ROAM to be set as well. However, this flag is | ||||
| only set when modparam roamoff=0, while the callback is set | ||||
| unconditionally. Since commit 7f9a3e150ec7 this causes a warning in | ||||
| wiphy_register, which breaks brcmfmac. | ||||
|  | ||||
| Disable the update_connect_param callback when roamoff=0 to fix this. | ||||
|  | ||||
| Fixes: 7f9a3e150ec7 ("nl80211: Update ERP info using NL80211_CMD_UPDATE_CONNECT_PARAMS") | ||||
| Cc: Stable <stable@vger.kernel.org> # 4.19+ | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c   | 11 +++++++++-- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.h   |  2 +- | ||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/core.c   |  2 +- | ||||
|  3 files changed, 11 insertions(+), 4 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -5189,10 +5189,17 @@ static struct cfg80211_ops brcmf_cfg8021 | ||||
|  	.del_pmk = brcmf_cfg80211_del_pmk, | ||||
|  }; | ||||
|   | ||||
| -struct cfg80211_ops *brcmf_cfg80211_get_ops(void) | ||||
| +struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings) | ||||
|  { | ||||
| -	return kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops), | ||||
| +	struct cfg80211_ops *ops; | ||||
| + | ||||
| +	ops = kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops), | ||||
|  		       GFP_KERNEL); | ||||
| + | ||||
| +	if (ops && settings->roamoff) | ||||
| +		ops->update_connect_params = NULL; | ||||
| + | ||||
| +	return ops; | ||||
|  } | ||||
|   | ||||
|  struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | ||||
| @@ -404,7 +404,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 | ||||
|  void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); | ||||
|  s32 brcmf_cfg80211_up(struct net_device *ndev); | ||||
|  s32 brcmf_cfg80211_down(struct net_device *ndev); | ||||
| -struct cfg80211_ops *brcmf_cfg80211_get_ops(void); | ||||
| +struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings); | ||||
|  enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); | ||||
|   | ||||
|  struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -1151,7 +1151,7 @@ int brcmf_attach(struct device *dev, str | ||||
|   | ||||
|  	brcmf_dbg(TRACE, "Enter\n"); | ||||
|   | ||||
| -	ops = brcmf_cfg80211_get_ops(); | ||||
| +	ops = brcmf_cfg80211_get_ops(settings); | ||||
|  	if (!ops) | ||||
|  		return -ENOMEM; | ||||
|   | ||||
| @@ -0,0 +1,41 @@ | ||||
| From 861cb5eb467f5e38dce1aabe4e8db379255bd89b Mon Sep 17 00:00:00 2001 | ||||
| From: Stefan Wahren <stefan.wahren@i2se.com> | ||||
| Date: Wed, 12 Dec 2018 20:20:06 +0100 | ||||
| Subject: [PATCH] brcmfmac: Fix access point mode | ||||
|  | ||||
| Since commit 1204aa17f3b4 ("brcmfmac: set WIPHY_FLAG_HAVE_AP_SME flag") | ||||
| the Raspberry Pi 3 A+ (BCM43455) isn't able to operate in AP mode with | ||||
| hostapd (device_ap_sme=1 use_monitor=0): | ||||
|  | ||||
| brcmfmac: brcmf_cfg80211_stop_ap: setting AP mode failed -52 | ||||
|  | ||||
| So add the missing mgmt_stypes for AP mode to fix this. | ||||
|  | ||||
| Fixes: 1204aa17f3b4 ("brcmfmac: set WIPHY_FLAG_HAVE_AP_SME flag") | ||||
| Suggested-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com> | ||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c    | 10 ++++++++++ | ||||
|  1 file changed, 10 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -6303,6 +6303,16 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = | ||||
|  		.tx = 0xffff, | ||||
|  		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) | | ||||
|  		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | ||||
| +	}, | ||||
| +	[NL80211_IFTYPE_AP] = { | ||||
| +		.tx = 0xffff, | ||||
| +		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | | ||||
| +		      BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | | ||||
| +		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | | ||||
| +		      BIT(IEEE80211_STYPE_DISASSOC >> 4) | | ||||
| +		      BIT(IEEE80211_STYPE_AUTH >> 4) | | ||||
| +		      BIT(IEEE80211_STYPE_DEAUTH >> 4) | | ||||
| +		      BIT(IEEE80211_STYPE_ACTION >> 4) | ||||
|  	} | ||||
|  }; | ||||
|   | ||||
| @@ -0,0 +1,104 @@ | ||||
| From 5cc898fbcb352b764f8d51c16e10e2eb0056173d Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Wed, 6 Feb 2019 12:28:15 +0100 | ||||
| Subject: [PATCH] brcmfmac: modify __brcmf_err() to take bus as a parameter | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| So far __brcmf_err() was using pr_err() which didn't allow identifying | ||||
| device that was affected by an error. It's crucial for systems with more | ||||
| than 1 device supported by brcmfmac (a common case for home routers). | ||||
|  | ||||
| This change allows passing struct brcmf_bus to the __brcmf_err(). That | ||||
| struct has been agreed to be the most common one. It allows accessing | ||||
| struct device easily & using dev_err() printing helper. | ||||
|  | ||||
| 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> | ||||
| --- | ||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/common.c    | 7 +++++-- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 8 +++++--- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/tracepoint.c    | 9 +++++++-- | ||||
|  3 files changed, 17 insertions(+), 7 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||
| @@ -350,7 +350,7 @@ done: | ||||
|  } | ||||
|   | ||||
|  #ifndef CPTCFG_BRCM_TRACING | ||||
| -void __brcmf_err(const char *func, const char *fmt, ...) | ||||
| +void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...) | ||||
|  { | ||||
|  	struct va_format vaf; | ||||
|  	va_list args; | ||||
| @@ -359,7 +359,10 @@ void __brcmf_err(const char *func, const | ||||
|   | ||||
|  	vaf.fmt = fmt; | ||||
|  	vaf.va = &args; | ||||
| -	pr_err("%s: %pV", func, &vaf); | ||||
| +	if (bus) | ||||
| +		dev_err(bus->dev, "%s: %pV", func, &vaf); | ||||
| +	else | ||||
| +		pr_err("%s: %pV", func, &vaf); | ||||
|   | ||||
|  	va_end(args); | ||||
|  } | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | ||||
| @@ -45,8 +45,10 @@ | ||||
|  #undef pr_fmt | ||||
|  #define pr_fmt(fmt)		KBUILD_MODNAME ": " fmt | ||||
|   | ||||
| -__printf(2, 3) | ||||
| -void __brcmf_err(const char *func, const char *fmt, ...); | ||||
| +struct brcmf_bus; | ||||
| + | ||||
| +__printf(3, 4) | ||||
| +void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...); | ||||
|  /* Macro for error messages. When debugging / tracing the driver all error | ||||
|   * messages are important to us. | ||||
|   */ | ||||
| @@ -55,7 +57,7 @@ void __brcmf_err(const char *func, const | ||||
|  		if (IS_ENABLED(CPTCFG_BRCMDBG) ||			\ | ||||
|  		    IS_ENABLED(CPTCFG_BRCM_TRACING) ||			\ | ||||
|  		    net_ratelimit())					\ | ||||
| -			__brcmf_err(__func__, fmt, ##__VA_ARGS__);	\ | ||||
| +			__brcmf_err(NULL, __func__, fmt, ##__VA_ARGS__);\ | ||||
|  	} while (0) | ||||
|   | ||||
|  #if defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c | ||||
| @@ -14,14 +14,16 @@ | ||||
|   * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|   */ | ||||
|   | ||||
| +#include <linux/device.h> | ||||
|  #include <linux/module.h> /* bug in tracepoint.h, it should include this */ | ||||
|   | ||||
|  #ifndef __CHECKER__ | ||||
|  #define CREATE_TRACE_POINTS | ||||
| +#include "bus.h" | ||||
|  #include "tracepoint.h" | ||||
|  #include "debug.h" | ||||
|   | ||||
| -void __brcmf_err(const char *func, const char *fmt, ...) | ||||
| +void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...) | ||||
|  { | ||||
|  	struct va_format vaf = { | ||||
|  		.fmt = fmt, | ||||
| @@ -30,7 +32,10 @@ void __brcmf_err(const char *func, const | ||||
|   | ||||
|  	va_start(args, fmt); | ||||
|  	vaf.va = &args; | ||||
| -	pr_err("%s: %pV", func, &vaf); | ||||
| +	if (bus) | ||||
| +		dev_err(bus->dev, "%s: %pV", func, &vaf); | ||||
| +	else | ||||
| +		pr_err("%s: %pV", func, &vaf); | ||||
|  	trace_brcmf_err(func, &vaf); | ||||
|  	va_end(args); | ||||
|  } | ||||
| @@ -0,0 +1,266 @@ | ||||
| From 8602e62441aba276cafd68034b72162fbc5ca0a6 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Wed, 6 Feb 2019 12:28:16 +0100 | ||||
| Subject: [PATCH] brcmfmac: pass bus to the __brcmf_err() in pcie.c | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| This enables dev_err() usage (instead of pr_err()) in the __brcmf_err(). | ||||
| It makes error messages more meaningful and is important for debugging | ||||
| errors/bugs on systems with multiple brcmfmac supported devices. | ||||
|  | ||||
| All bus files should follow & get updated similarly (soon). | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/debug.h       |  2 + | ||||
|  .../broadcom/brcm80211/brcmfmac/pcie.c        | 59 +++++++++++-------- | ||||
|  2 files changed, 38 insertions(+), 23 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | ||||
| @@ -52,6 +52,7 @@ void __brcmf_err(struct brcmf_bus *bus, | ||||
|  /* Macro for error messages. When debugging / tracing the driver all error | ||||
|   * messages are important to us. | ||||
|   */ | ||||
| +#ifndef brcmf_err | ||||
|  #define brcmf_err(fmt, ...)						\ | ||||
|  	do {								\ | ||||
|  		if (IS_ENABLED(CPTCFG_BRCMDBG) ||			\ | ||||
| @@ -59,6 +60,7 @@ void __brcmf_err(struct brcmf_bus *bus, | ||||
|  		    net_ratelimit())					\ | ||||
|  			__brcmf_err(NULL, __func__, fmt, ##__VA_ARGS__);\ | ||||
|  	} while (0) | ||||
| +#endif | ||||
|   | ||||
|  #if defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) | ||||
|   | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| @@ -30,6 +30,15 @@ | ||||
|  #include <brcmu_wifi.h> | ||||
|  #include <brcm_hw_ids.h> | ||||
|   | ||||
| +/* Custom brcmf_err() that takes bus arg and passes it further */ | ||||
| +#define brcmf_err(bus, fmt, ...)					\ | ||||
| +	do {								\ | ||||
| +		if (IS_ENABLED(CPTCFG_BRCMDBG) ||			\ | ||||
| +		    IS_ENABLED(CPTCFG_BRCM_TRACING) ||			\ | ||||
| +		    net_ratelimit())					\ | ||||
| +			__brcmf_err(bus, __func__, fmt, ##__VA_ARGS__);	\ | ||||
| +	} while (0) | ||||
| + | ||||
|  #include "debug.h" | ||||
|  #include "bus.h" | ||||
|  #include "commonring.h" | ||||
| @@ -531,6 +540,7 @@ static void | ||||
|  brcmf_pcie_select_core(struct brcmf_pciedev_info *devinfo, u16 coreid) | ||||
|  { | ||||
|  	const struct pci_dev *pdev = devinfo->pdev; | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); | ||||
|  	struct brcmf_core *core; | ||||
|  	u32 bar0_win; | ||||
|   | ||||
| @@ -548,7 +558,7 @@ brcmf_pcie_select_core(struct brcmf_pcie | ||||
|  			} | ||||
|  		} | ||||
|  	} else { | ||||
| -		brcmf_err("Unsupported core selected %x\n", coreid); | ||||
| +		brcmf_err(bus, "Unsupported core selected %x\n", coreid); | ||||
|  	} | ||||
|  } | ||||
|   | ||||
| @@ -848,9 +858,8 @@ static irqreturn_t brcmf_pcie_isr_thread | ||||
|   | ||||
|  static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo) | ||||
|  { | ||||
| -	struct pci_dev *pdev; | ||||
| - | ||||
| -	pdev = devinfo->pdev; | ||||
| +	struct pci_dev *pdev = devinfo->pdev; | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); | ||||
|   | ||||
|  	brcmf_pcie_intr_disable(devinfo); | ||||
|   | ||||
| @@ -861,7 +870,7 @@ static int brcmf_pcie_request_irq(struct | ||||
|  				 brcmf_pcie_isr_thread, IRQF_SHARED, | ||||
|  				 "brcmf_pcie_intr", devinfo)) { | ||||
|  		pci_disable_msi(pdev); | ||||
| -		brcmf_err("Failed to request IRQ %d\n", pdev->irq); | ||||
| +		brcmf_err(bus, "Failed to request IRQ %d\n", pdev->irq); | ||||
|  		return -EIO; | ||||
|  	} | ||||
|  	devinfo->irq_allocated = true; | ||||
| @@ -871,15 +880,14 @@ static int brcmf_pcie_request_irq(struct | ||||
|   | ||||
|  static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo) | ||||
|  { | ||||
| -	struct pci_dev *pdev; | ||||
| +	struct pci_dev *pdev = devinfo->pdev; | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); | ||||
|  	u32 status; | ||||
|  	u32 count; | ||||
|   | ||||
|  	if (!devinfo->irq_allocated) | ||||
|  		return; | ||||
|   | ||||
| -	pdev = devinfo->pdev; | ||||
| - | ||||
|  	brcmf_pcie_intr_disable(devinfo); | ||||
|  	free_irq(pdev->irq, devinfo); | ||||
|  	pci_disable_msi(pdev); | ||||
| @@ -891,7 +899,7 @@ static void brcmf_pcie_release_irq(struc | ||||
|  		count++; | ||||
|  	} | ||||
|  	if (devinfo->in_irq) | ||||
| -		brcmf_err("Still in IRQ (processing) !!!\n"); | ||||
| +		brcmf_err(bus, "Still in IRQ (processing) !!!\n"); | ||||
|   | ||||
|  	status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); | ||||
|  	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status); | ||||
| @@ -1102,6 +1110,7 @@ static void brcmf_pcie_release_ringbuffe | ||||
|   | ||||
|  static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo) | ||||
|  { | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); | ||||
|  	struct brcmf_pcie_ringbuf *ring; | ||||
|  	struct brcmf_pcie_ringbuf *rings; | ||||
|  	u32 d2h_w_idx_ptr; | ||||
| @@ -1254,7 +1263,7 @@ static int brcmf_pcie_init_ringbuffers(s | ||||
|  	return 0; | ||||
|   | ||||
|  fail: | ||||
| -	brcmf_err("Allocating ring buffers failed\n"); | ||||
| +	brcmf_err(bus, "Allocating ring buffers failed\n"); | ||||
|  	brcmf_pcie_release_ringbuffers(devinfo); | ||||
|  	return -ENOMEM; | ||||
|  } | ||||
| @@ -1277,6 +1286,7 @@ brcmf_pcie_release_scratchbuffers(struct | ||||
|   | ||||
|  static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo) | ||||
|  { | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); | ||||
|  	u64 address; | ||||
|  	u32 addr; | ||||
|   | ||||
| @@ -1316,7 +1326,7 @@ static int brcmf_pcie_init_scratchbuffer | ||||
|  	return 0; | ||||
|   | ||||
|  fail: | ||||
| -	brcmf_err("Allocating scratch buffers failed\n"); | ||||
| +	brcmf_err(bus, "Allocating scratch buffers failed\n"); | ||||
|  	brcmf_pcie_release_scratchbuffers(devinfo); | ||||
|  	return -ENOMEM; | ||||
|  } | ||||
| @@ -1437,6 +1447,7 @@ static int | ||||
|  brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo, | ||||
|  			       u32 sharedram_addr) | ||||
|  { | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); | ||||
|  	struct brcmf_pcie_shared_info *shared; | ||||
|  	u32 addr; | ||||
|   | ||||
| @@ -1448,7 +1459,8 @@ brcmf_pcie_init_share_ram_info(struct br | ||||
|  	brcmf_dbg(PCIE, "PCIe protocol version %d\n", shared->version); | ||||
|  	if ((shared->version > BRCMF_PCIE_MAX_SHARED_VERSION) || | ||||
|  	    (shared->version < BRCMF_PCIE_MIN_SHARED_VERSION)) { | ||||
| -		brcmf_err("Unsupported PCIE version %d\n", shared->version); | ||||
| +		brcmf_err(bus, "Unsupported PCIE version %d\n", | ||||
| +			  shared->version); | ||||
|  		return -EINVAL; | ||||
|  	} | ||||
|   | ||||
| @@ -1490,6 +1502,7 @@ static int brcmf_pcie_download_fw_nvram( | ||||
|  					const struct firmware *fw, void *nvram, | ||||
|  					u32 nvram_len) | ||||
|  { | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); | ||||
|  	u32 sharedram_addr; | ||||
|  	u32 sharedram_addr_written; | ||||
|  	u32 loop_counter; | ||||
| @@ -1544,7 +1557,7 @@ static int brcmf_pcie_download_fw_nvram( | ||||
|  		loop_counter--; | ||||
|  	} | ||||
|  	if (sharedram_addr == sharedram_addr_written) { | ||||
| -		brcmf_err("FW failed to initialize\n"); | ||||
| +		brcmf_err(bus, "FW failed to initialize\n"); | ||||
|  		return -ENODEV; | ||||
|  	} | ||||
|  	brcmf_dbg(PCIE, "Shared RAM addr: 0x%08x\n", sharedram_addr); | ||||
| @@ -1555,16 +1568,15 @@ static int brcmf_pcie_download_fw_nvram( | ||||
|   | ||||
|  static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo) | ||||
|  { | ||||
| -	struct pci_dev *pdev; | ||||
| +	struct pci_dev *pdev = devinfo->pdev; | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); | ||||
|  	int err; | ||||
|  	phys_addr_t  bar0_addr, bar1_addr; | ||||
|  	ulong bar1_size; | ||||
|   | ||||
| -	pdev = devinfo->pdev; | ||||
| - | ||||
|  	err = pci_enable_device(pdev); | ||||
|  	if (err) { | ||||
| -		brcmf_err("pci_enable_device failed err=%d\n", err); | ||||
| +		brcmf_err(bus, "pci_enable_device failed err=%d\n", err); | ||||
|  		return err; | ||||
|  	} | ||||
|   | ||||
| @@ -1577,7 +1589,7 @@ static int brcmf_pcie_get_resource(struc | ||||
|  	/* read Bar-1 mapped memory range */ | ||||
|  	bar1_size = pci_resource_len(pdev, 2); | ||||
|  	if ((bar1_size == 0) || (bar1_addr == 0)) { | ||||
| -		brcmf_err("BAR1 Not enabled, device size=%ld, addr=%#016llx\n", | ||||
| +		brcmf_err(bus, "BAR1 Not enabled, device size=%ld, addr=%#016llx\n", | ||||
|  			  bar1_size, (unsigned long long)bar1_addr); | ||||
|  		return -EINVAL; | ||||
|  	} | ||||
| @@ -1586,7 +1598,7 @@ static int brcmf_pcie_get_resource(struc | ||||
|  	devinfo->tcm = ioremap_nocache(bar1_addr, bar1_size); | ||||
|   | ||||
|  	if (!devinfo->regs || !devinfo->tcm) { | ||||
| -		brcmf_err("ioremap() failed (%p,%p)\n", devinfo->regs, | ||||
| +		brcmf_err(bus, "ioremap() failed (%p,%p)\n", devinfo->regs, | ||||
|  			  devinfo->tcm); | ||||
|  		return -EINVAL; | ||||
|  	} | ||||
| @@ -1873,7 +1885,7 @@ fail_bus: | ||||
|  	kfree(bus->msgbuf); | ||||
|  	kfree(bus); | ||||
|  fail: | ||||
| -	brcmf_err("failed %x:%x\n", pdev->vendor, pdev->device); | ||||
| +	brcmf_err(NULL, "failed %x:%x\n", pdev->vendor, pdev->device); | ||||
|  	brcmf_pcie_release_resource(devinfo); | ||||
|  	if (devinfo->ci) | ||||
|  		brcmf_chip_detach(devinfo->ci); | ||||
| @@ -1947,7 +1959,7 @@ static int brcmf_pcie_pm_enter_D3(struct | ||||
|  	wait_event_timeout(devinfo->mbdata_resp_wait, devinfo->mbdata_completed, | ||||
|  			   BRCMF_PCIE_MBDATA_TIMEOUT); | ||||
|  	if (!devinfo->mbdata_completed) { | ||||
| -		brcmf_err("Timeout on response for entering D3 substate\n"); | ||||
| +		brcmf_err(bus, "Timeout on response for entering D3 substate\n"); | ||||
|  		brcmf_bus_change_state(bus, BRCMF_BUS_UP); | ||||
|  		return -EIO; | ||||
|  	} | ||||
| @@ -1993,7 +2005,7 @@ cleanup: | ||||
|   | ||||
|  	err = brcmf_pcie_probe(pdev, NULL); | ||||
|  	if (err) | ||||
| -		brcmf_err("probe after resume failed, err=%d\n", err); | ||||
| +		brcmf_err(bus, "probe after resume failed, err=%d\n", err); | ||||
|   | ||||
|  	return err; | ||||
|  } | ||||
| @@ -2065,7 +2077,8 @@ void brcmf_pcie_register(void) | ||||
|  	brcmf_dbg(PCIE, "Enter\n"); | ||||
|  	err = pci_register_driver(&brcmf_pciedrvr); | ||||
|  	if (err) | ||||
| -		brcmf_err("PCIE driver registration failed, err=%d\n", err); | ||||
| +		brcmf_err(NULL, "PCIE driver registration failed, err=%d\n", | ||||
| +			  err); | ||||
|  } | ||||
|   | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,143 @@ | ||||
| From e665988be29ccea3584528967b432a5cfd801ca4 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Fri, 8 Feb 2019 07:42:30 +0100 | ||||
| Subject: [PATCH] brcmfmac: support monitor frames with the hardware/ucode | ||||
|  header | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| So far there were two monitor frame formats: | ||||
| 1) 802.11 frames (with frame (sub)type & all addresses) | ||||
| 2) 802.11 frames with the radiotap header | ||||
|  | ||||
| Testing the latest FullMAC firmwares for 4366b1/4366c0 resulted in | ||||
| discovering a new format being used. It seems (almost?) identical to the | ||||
| one known from ucode used in SoftMAC devices which is most likely the | ||||
| same codebase anyway. | ||||
|  | ||||
| While new firmwares will /announce/ radiotap header support using the | ||||
| "rtap" fw capability string it seems no string was added for the new | ||||
| ucode header format. | ||||
|  | ||||
| All above means that: | ||||
| 1) We need new format support when dealing with a received frame | ||||
| 2) A new feature bit & mapping quirks have to be added manually | ||||
|  | ||||
| As for now only an empty radiotap is being created. Adding support for | ||||
| extracting some info (band, channel, signal, etc.) is planned for the | ||||
| future. | ||||
|  | ||||
| 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/core.c        | 55 +++++++++++++++++++ | ||||
|  .../broadcom/brcm80211/brcmfmac/feature.c     |  4 ++ | ||||
|  .../broadcom/brcm80211/brcmfmac/feature.h     |  4 +- | ||||
|  3 files changed, 62 insertions(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -43,6 +43,36 @@ | ||||
|   | ||||
|  #define BRCMF_BSSIDX_INVALID			-1 | ||||
|   | ||||
| +#define	RXS_PBPRES				BIT(2) | ||||
| + | ||||
| +#define	D11_PHY_HDR_LEN				6 | ||||
| + | ||||
| +struct d11rxhdr_le { | ||||
| +	__le16 RxFrameSize; | ||||
| +	u16 PAD; | ||||
| +	__le16 PhyRxStatus_0; | ||||
| +	__le16 PhyRxStatus_1; | ||||
| +	__le16 PhyRxStatus_2; | ||||
| +	__le16 PhyRxStatus_3; | ||||
| +	__le16 PhyRxStatus_4; | ||||
| +	__le16 PhyRxStatus_5; | ||||
| +	__le16 RxStatus1; | ||||
| +	__le16 RxStatus2; | ||||
| +	__le16 RxTSFTime; | ||||
| +	__le16 RxChan; | ||||
| +	u8 unknown[12]; | ||||
| +} __packed; | ||||
| + | ||||
| +struct wlc_d11rxhdr { | ||||
| +	struct d11rxhdr_le rxhdr; | ||||
| +	__le32 tsf_l; | ||||
| +	s8 rssi; | ||||
| +	s8 rxpwr0; | ||||
| +	s8 rxpwr1; | ||||
| +	s8 do_rssi_ma; | ||||
| +	s8 rxpwr[4]; | ||||
| +} __packed; | ||||
| + | ||||
|  char *brcmf_ifname(struct brcmf_if *ifp) | ||||
|  { | ||||
|  	if (!ifp) | ||||
| @@ -409,6 +439,31 @@ void brcmf_netif_mon_rx(struct brcmf_if | ||||
|  { | ||||
|  	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_RADIOTAP)) { | ||||
|  		/* Do nothing */ | ||||
| +	} else if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR)) { | ||||
| +		struct wlc_d11rxhdr *wlc_rxhdr = (struct wlc_d11rxhdr *)skb->data; | ||||
| +		struct ieee80211_radiotap_header *radiotap; | ||||
| +		unsigned int offset; | ||||
| +		u16 RxStatus1; | ||||
| + | ||||
| +		RxStatus1 = le16_to_cpu(wlc_rxhdr->rxhdr.RxStatus1); | ||||
| + | ||||
| +		offset = sizeof(struct wlc_d11rxhdr); | ||||
| +		/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU | ||||
| +		 * subframes | ||||
| +		 */ | ||||
| +		if (RxStatus1 & RXS_PBPRES) | ||||
| +			offset += 2; | ||||
| +		offset += D11_PHY_HDR_LEN; | ||||
| + | ||||
| +		skb_pull(skb, offset); | ||||
| + | ||||
| +		/* TODO: use RX header to fill some radiotap data */ | ||||
| +		radiotap = skb_push(skb, sizeof(*radiotap)); | ||||
| +		memset(radiotap, 0, sizeof(*radiotap)); | ||||
| +		radiotap->it_len = cpu_to_le16(sizeof(*radiotap)); | ||||
| + | ||||
| +		/* TODO: 4 bytes with receive status? */ | ||||
| +		skb->len -= 4; | ||||
|  	} else { | ||||
|  		struct ieee80211_radiotap_header *radiotap; | ||||
|   | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | ||||
| @@ -103,6 +103,10 @@ static const struct brcmf_feat_fwfeat br | ||||
|  	{ "01-6cb8e269", BIT(BRCMF_FEAT_MONITOR) }, | ||||
|  	/* brcmfmac4366b-pcie.bin from linux-firmware.git commit 52442afee990 */ | ||||
|  	{ "01-c47a91a4", BIT(BRCMF_FEAT_MONITOR) }, | ||||
| +	/* brcmfmac4366b-pcie.bin from linux-firmware.git commit 211de1679a68 */ | ||||
| +	{ "01-801fb449", BIT(BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR) }, | ||||
| +	/* brcmfmac4366c-pcie.bin from linux-firmware.git commit 211de1679a68 */ | ||||
| +	{ "01-d2cbb8fd", BIT(BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR) }, | ||||
|  }; | ||||
|   | ||||
|  static void brcmf_feat_firmware_overrides(struct brcmf_pub *drv) | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h | ||||
| @@ -35,6 +35,7 @@ | ||||
|   * FWSUP: Firmware supplicant. | ||||
|   * 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 | ||||
|   */ | ||||
|  #define BRCMF_FEAT_LIST \ | ||||
|  	BRCMF_FEAT_DEF(MBSS) \ | ||||
| @@ -52,7 +53,8 @@ | ||||
|  	BRCMF_FEAT_DEF(GSCAN) \ | ||||
|  	BRCMF_FEAT_DEF(FWSUP) \ | ||||
|  	BRCMF_FEAT_DEF(MONITOR) \ | ||||
| -	BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) | ||||
| +	BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) \ | ||||
| +	BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) | ||||
|   | ||||
|  /* | ||||
|   * Quirks: | ||||
| @@ -0,0 +1,67 @@ | ||||
| From c988b78244df8216902e20de536434e2f474a37e Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Fri, 8 Feb 2019 15:24:39 +0100 | ||||
| Subject: [PATCH] brcmfmac: print firmware reported ring status errors | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| Firmware is capable of reporting ring status. It's used e.g. to signal | ||||
| some problem with a specific ring setup. This patch adds support for | ||||
| printing ring & error number which may be useful for debugging setup | ||||
| issues. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/msgbuf.c      | 25 +++++++++++++++++++ | ||||
|  1 file changed, 25 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| @@ -134,6 +134,14 @@ struct msgbuf_completion_hdr { | ||||
|  	__le16				flow_ring_id; | ||||
|  }; | ||||
|   | ||||
| +/* Data struct for the MSGBUF_TYPE_RING_STATUS */ | ||||
| +struct msgbuf_ring_status { | ||||
| +	struct msgbuf_common_hdr	msg; | ||||
| +	struct msgbuf_completion_hdr	compl_hdr; | ||||
| +	__le16				write_idx; | ||||
| +	__le32				rsvd0[5]; | ||||
| +}; | ||||
| + | ||||
|  struct msgbuf_rx_event { | ||||
|  	struct msgbuf_common_hdr	msg; | ||||
|  	struct msgbuf_completion_hdr	compl_hdr; | ||||
| @@ -1180,6 +1188,19 @@ brcmf_msgbuf_process_rx_complete(struct | ||||
|  	brcmf_netif_rx(ifp, skb); | ||||
|  } | ||||
|   | ||||
| +static void brcmf_msgbuf_process_ring_status(struct brcmf_msgbuf *msgbuf, | ||||
| +					     void *buf) | ||||
| +{ | ||||
| +	struct msgbuf_ring_status *ring_status = buf; | ||||
| +	int err; | ||||
| + | ||||
| +	err = le16_to_cpu(ring_status->compl_hdr.status); | ||||
| +	if (err) { | ||||
| +		int ring = le16_to_cpu(ring_status->compl_hdr.flow_ring_id); | ||||
| + | ||||
| +		brcmf_err("Firmware reported ring %d error: %d\n", ring, err); | ||||
| +	} | ||||
| +} | ||||
|   | ||||
|  static void | ||||
|  brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf, | ||||
| @@ -1241,6 +1262,10 @@ static void brcmf_msgbuf_process_msgtype | ||||
|   | ||||
|  	msg = (struct msgbuf_common_hdr *)buf; | ||||
|  	switch (msg->msgtype) { | ||||
| +	case MSGBUF_TYPE_RING_STATUS: | ||||
| +		brcmf_dbg(MSGBUF, "MSGBUF_TYPE_RING_STATUS\n"); | ||||
| +		brcmf_msgbuf_process_ring_status(msgbuf, buf); | ||||
| +		break; | ||||
|  	case MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT: | ||||
|  		brcmf_dbg(MSGBUF, "MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT\n"); | ||||
|  		brcmf_msgbuf_process_flow_ring_create_response(msgbuf, buf); | ||||
| @@ -0,0 +1,42 @@ | ||||
| From f4e183293b871c96c0220dcc549d5ca4c72628ad Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Mon, 11 Feb 2019 23:04:53 +0100 | ||||
| Subject: [PATCH] brcmfmac: improve code handling bandwidth of firmware | ||||
|  reported channels | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| 1) Use switch to simplify/improve the code & avoid some duplication | ||||
| 2) Add warning for unsupported values | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 13 ++++++++++--- | ||||
|  1 file changed, 10 insertions(+), 3 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -6036,11 +6036,18 @@ static int brcmf_construct_chaninfo(stru | ||||
|  		/* assuming the chanspecs order is HT20, | ||||
|  		 * HT40 upper, HT40 lower, and VHT80. | ||||
|  		 */ | ||||
| -		if (ch.bw == BRCMU_CHAN_BW_80) { | ||||
| +		switch (ch.bw) { | ||||
| +		case BRCMU_CHAN_BW_80: | ||||
|  			channel->flags &= ~IEEE80211_CHAN_NO_80MHZ; | ||||
| -		} else if (ch.bw == BRCMU_CHAN_BW_40) { | ||||
| +			break; | ||||
| +		case BRCMU_CHAN_BW_40: | ||||
|  			brcmf_update_bw40_channel_flag(channel, &ch); | ||||
| -		} else { | ||||
| +			break; | ||||
| +		default: | ||||
| +			wiphy_warn(wiphy, "Firmware reported unsupported bandwidth %d\n", | ||||
| +				   ch.bw); | ||||
| +			/* fall through */ | ||||
| +		case BRCMU_CHAN_BW_20: | ||||
|  			/* enable the channel and disable other bandwidths | ||||
|  			 * for now as mentioned order assure they are enabled | ||||
|  			 * for subsequent chanspecs. | ||||
| @@ -0,0 +1,30 @@ | ||||
| From 30519cbe339a45bd11a57ca8ece07f4f6a1cda2e Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Mon, 11 Feb 2019 23:04:54 +0100 | ||||
| Subject: [PATCH] brcmfmac: support firmware reporting 160 MHz channels | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| So far 160 MHz channels were treated as 20 MHz ones which was breaking | ||||
| support for 40/80 MHz due to the brcmf_construct_chaninfo() logic and | ||||
| its assumptions. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 +++ | ||||
|  1 file changed, 3 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -6037,6 +6037,9 @@ static int brcmf_construct_chaninfo(stru | ||||
|  		 * HT40 upper, HT40 lower, and VHT80. | ||||
|  		 */ | ||||
|  		switch (ch.bw) { | ||||
| +		case BRCMU_CHAN_BW_160: | ||||
| +			channel->flags &= ~IEEE80211_CHAN_NO_160MHZ; | ||||
| +			break; | ||||
|  		case BRCMU_CHAN_BW_80: | ||||
|  			channel->flags &= ~IEEE80211_CHAN_NO_80MHZ; | ||||
|  			break; | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,38 @@ | ||||
| From e0a8ef4d7b4315bc4c1641fb3f3a7dfdfa6627b8 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Wed, 20 Feb 2019 11:30:47 +0100 | ||||
| Subject: [PATCH] brcmfmac: add basic validation of shared RAM address | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| While experimenting with firmware loading I ended up in a state of | ||||
| firmware reporting shared RAM address 0x04000001. It was causing: | ||||
| [   94.448015] Unable to handle kernel paging request at virtual address cd680001 | ||||
| due to reading out of the mapped memory. | ||||
|  | ||||
| This patch adds some basic validation to avoid kernel crashes due to the | ||||
| unexpected firmware behavior. | ||||
|  | ||||
| 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 | 6 ++++++ | ||||
|  1 file changed, 6 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| @@ -1560,6 +1560,12 @@ static int brcmf_pcie_download_fw_nvram( | ||||
|  		brcmf_err(bus, "FW failed to initialize\n"); | ||||
|  		return -ENODEV; | ||||
|  	} | ||||
| +	if (sharedram_addr < devinfo->ci->rambase || | ||||
| +	    sharedram_addr >= devinfo->ci->rambase + devinfo->ci->ramsize) { | ||||
| +		brcmf_err(bus, "Invalid shared RAM address 0x%08x\n", | ||||
| +			  sharedram_addr); | ||||
| +		return -ENODEV; | ||||
| +	} | ||||
|  	brcmf_dbg(PCIE, "Shared RAM addr: 0x%08x\n", sharedram_addr); | ||||
|   | ||||
|  	return (brcmf_pcie_init_share_ram_info(devinfo, sharedram_addr)); | ||||
| @@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -1347,6 +1347,7 @@ int __init brcmf_core_init(void) | ||||
| @@ -1406,6 +1406,7 @@ int __init brcmf_core_init(void) | ||||
|  { | ||||
|  	if (!schedule_work(&brcmf_driver_work)) | ||||
|  		return -EBUSY; | ||||
|   | ||||
| @@ -10,12 +10,11 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -614,9 +614,37 @@ static struct wireless_dev *brcmf_cfg802 | ||||
|  						     enum nl80211_iftype type, | ||||
|  						     struct vif_params *params) | ||||
|  { | ||||
| +	struct net_device *dev; | ||||
| @@ -620,8 +620,36 @@ static struct wireless_dev *brcmf_cfg802 | ||||
|  	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | ||||
|  	struct brcmf_pub *drvr = cfg->pub; | ||||
|  	struct wireless_dev *wdev; | ||||
| +	struct net_device *dev; | ||||
|  	int err; | ||||
|   | ||||
| +	/* | ||||
|   | ||||
| @@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org> | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -2725,6 +2725,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip | ||||
| @@ -2774,6 +2774,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip | ||||
|  	 * preference in cfg struct to apply this to | ||||
|  	 * FW later while initializing the dongle | ||||
|  	 */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Rafał Miłecki
					Rafał Miłecki