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_NAME:=mac80211 | ||||||
|  |  | ||||||
| PKG_VERSION:=2017-11-01 | PKG_VERSION:=2017-11-01 | ||||||
| PKG_RELEASE:=9 | PKG_RELEASE:=10 | ||||||
| PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources | PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources | ||||||
| PKG_HASH:=8437ab7886b988c8152e7a4db30b7f41009e49a3b2cb863edd05da1ecd7eb05a | 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 | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||||
| +++ b/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)) |  	if (!schedule_work(&brcmf_driver_work)) | ||||||
|  		return -EBUSY; |  		return -EBUSY; | ||||||
|   | |||||||
| @@ -10,12 +10,11 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | |||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||||
| +++ b/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 | @@ -620,8 +620,36 @@ static struct wireless_dev *brcmf_cfg802 | ||||||
|  						     enum nl80211_iftype type, |  	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | ||||||
|  						     struct vif_params *params) |  	struct brcmf_pub *drvr = cfg->pub; | ||||||
|  { |  | ||||||
| +	struct net_device *dev; |  | ||||||
|  	struct wireless_dev *wdev; |  	struct wireless_dev *wdev; | ||||||
|  | +	struct net_device *dev; | ||||||
|  	int err; |  	int err; | ||||||
|   |   | ||||||
| +	/* | +	/* | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org> | |||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||||
| +++ b/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 |  	 * preference in cfg struct to apply this to | ||||||
|  	 * FW later while initializing the dongle |  	 * FW later while initializing the dongle | ||||||
|  	 */ |  	 */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Rafał Miłecki
					Rafał Miłecki