mac80211: rebase ontop of v4.18.5
Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
		| @@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk | |||||||
|  |  | ||||||
| PKG_NAME:=mac80211 | PKG_NAME:=mac80211 | ||||||
|  |  | ||||||
| PKG_VERSION:=2017-11-01 | PKG_VERSION:=v4.18.5 | ||||||
| PKG_RELEASE:=9 | PKG_RELEASE:=1 | ||||||
| PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources | PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources | ||||||
| PKG_HASH:=8437ab7886b988c8152e7a4db30b7f41009e49a3b2cb863edd05da1ecd7eb05a | PKG_HASH:=9c13660e98b9397260266f98c9db76bdad2b48462cb376b5862dfbd18369edf2 | ||||||
|  |  | ||||||
| PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz | PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz | ||||||
| PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) | PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) | ||||||
| @@ -1116,7 +1116,7 @@ endef | |||||||
| define KernelPackage/mt7601u | define KernelPackage/mt7601u | ||||||
|   $(call KernelPackage/mac80211/Default) |   $(call KernelPackage/mac80211/Default) | ||||||
|   TITLE:=MT7601U-based USB dongles Wireless Driver |   TITLE:=MT7601U-based USB dongles Wireless Driver | ||||||
|   DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT @USB_SUPPORT +kmod-usb-core +mt7601u-firmware |   DEPENDS+= @BROKEN +kmod-mac80211 +@DRIVER_11N_SUPPORT @USB_SUPPORT +kmod-usb-core +mt7601u-firmware | ||||||
|   FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mediatek/mt7601u/mt7601u.ko |   FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mediatek/mt7601u/mt7601u.ko | ||||||
|   AUTOLOAD:=$(call AutoProbe,mt7601u) |   AUTOLOAD:=$(call AutoProbe,mt7601u) | ||||||
| endef | endef | ||||||
| @@ -1839,6 +1839,26 @@ ifeq ($(strip $(CONFIG_EXTERNAL_KERNEL_TREE)),"") | |||||||
|   endif |   endif | ||||||
| endif | endif | ||||||
|  |  | ||||||
|  | define Build/Patch | ||||||
|  | 	$(if $(QUILT),rm -rf $(PKG_BUILD_DIR)/patches; mkdir -p $(PKG_BUILD_DIR)/patches) | ||||||
|  | 	$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/) | ||||||
|  | 	$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/) | ||||||
|  | 	$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/) | ||||||
|  | 	$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) | ||||||
|  | 	$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) | ||||||
|  | 	$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/) | ||||||
|  | 	$(if $(QUILT),touch $(PKG_BUILD_DIR)/.quilt_used) | ||||||
|  | endef | ||||||
|  |  | ||||||
|  | define Quilt/Refresh/Package | ||||||
|  | 	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/) | ||||||
|  | 	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/) | ||||||
|  | 	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/) | ||||||
|  | 	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) | ||||||
|  | 	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) | ||||||
|  | 	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/) | ||||||
|  | endef | ||||||
|  |  | ||||||
| define Build/Compile | define Build/Compile | ||||||
| 	$(SH_FUNC) var2file "$(call shvar,mac80211_config)" $(PKG_BUILD_DIR)/.config | 	$(SH_FUNC) var2file "$(call shvar,mac80211_config)" $(PKG_BUILD_DIR)/.config | ||||||
| 	$(MAKE) $(MAKE_OPTS) allnoconfig | 	$(MAKE) $(MAKE_OPTS) allnoconfig | ||||||
|   | |||||||
| @@ -1,11 +0,0 @@ | |||||||
| --- a/backport-include/linux/verification.h |  | ||||||
| +++ b/backport-include/linux/verification.h |  | ||||||
| @@ -1,7 +1,7 @@ |  | ||||||
|  #ifndef __BP_VERIFICATION_H |  | ||||||
|  #define __BP_VERIFICATION_H |  | ||||||
|  #include <linux/version.h> |  | ||||||
| -#ifndef CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION |  | ||||||
| +#if LINUX_VERSION_IS_GEQ(4,7,0) && !defined(CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION) |  | ||||||
|  #include_next <linux/verification.h> |  | ||||||
|  #else |  | ||||||
|  #include <linux/key.h> |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
| --- a/compat/backport-4.12.c |  | ||||||
| +++ b/compat/backport-4.12.c |  | ||||||
| @@ -224,6 +224,7 @@ int bp_extack_genl_register_family(struc |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	/* copy this since the family might access it directly */ |  | ||||||
| +	family->id = copy->family.id; |  | ||||||
|  	family->attrbuf = copy->family.attrbuf; |  | ||||||
|  	family->mcgrp_offset = copy->family.mcgrp_offset; |  | ||||||
|   |  | ||||||
| @@ -1,34 +0,0 @@ | |||||||
| --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c |  | ||||||
| +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c |  | ||||||
| @@ -11506,6 +11506,15 @@ static const struct attribute_group ipw_ |  | ||||||
|  	.attrs = ipw_sysfs_entries, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +#if LINUX_VERSION_IS_LESS(4,10,0) |  | ||||||
| +static int __change_mtu(struct net_device *ndev, int new_mtu){ |  | ||||||
| +	if (new_mtu < 68 || new_mtu > LIBIPW_DATA_LEN) |  | ||||||
| +		return -EINVAL; |  | ||||||
| +	ndev->mtu = new_mtu; |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
|  #ifdef CPTCFG_IPW2200_PROMISCUOUS |  | ||||||
|  static int ipw_prom_open(struct net_device *dev) |  | ||||||
|  { |  | ||||||
| @@ -11554,15 +11563,6 @@ static netdev_tx_t ipw_prom_hard_start_x |  | ||||||
|  	return NETDEV_TX_OK; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -#if LINUX_VERSION_IS_LESS(4,10,0) |  | ||||||
| -static int __change_mtu(struct net_device *ndev, int new_mtu){ |  | ||||||
| -	if (new_mtu < 68 || new_mtu > LIBIPW_DATA_LEN) |  | ||||||
| -		return -EINVAL; |  | ||||||
| -	ndev->mtu = new_mtu; |  | ||||||
| -	return 0; |  | ||||||
| -} |  | ||||||
| -#endif |  | ||||||
| - |  | ||||||
|  static const struct net_device_ops ipw_prom_netdev_ops = { |  | ||||||
|  #if LINUX_VERSION_IS_LESS(4,10,0) |  | ||||||
|  	.ndo_change_mtu = __change_mtu, |  | ||||||
| @@ -1,47 +0,0 @@ | |||||||
| --- a/drivers/net/wireless/ath/ath10k/Kconfig |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/Kconfig |  | ||||||
| @@ -65,6 +65,12 @@ config ATH10K_TRACING |  | ||||||
|  	---help--- |  | ||||||
|  	  Select this to ath10k use tracing infrastructure. |  | ||||||
|   |  | ||||||
| +config ATH10K_THERMAL |  | ||||||
| +	bool "Atheros ath10k thermal monitoring support" |  | ||||||
| +	depends on THERMAL |  | ||||||
| +	---help--- |  | ||||||
| +	  Select this to ath10k use hwmon for thermal measurement. |  | ||||||
| + |  | ||||||
|  config ATH10K_DFS_CERTIFIED |  | ||||||
|  	bool "Atheros DFS support for certified platforms" |  | ||||||
|  	depends on ATH10K && CFG80211_CERTIFICATION_ONUS |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/Makefile |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/Makefile |  | ||||||
| @@ -17,7 +17,7 @@ ath10k_core-y += mac.o \ |  | ||||||
|  ath10k_core-$(CPTCFG_ATH10K_DEBUGFS) += spectral.o |  | ||||||
|  ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o |  | ||||||
|  ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o |  | ||||||
| -ath10k_core-$(CONFIG_THERMAL) += thermal.o |  | ||||||
| +ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o |  | ||||||
|  ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o |  | ||||||
|  ath10k_core-$(CONFIG_PM) += wow.o |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/thermal.h |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/thermal.h |  | ||||||
| @@ -36,7 +36,7 @@ struct ath10k_thermal { |  | ||||||
|  	int temperature; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| -#if IS_REACHABLE(CONFIG_THERMAL) |  | ||||||
| +#if IS_REACHABLE(CPTCFG_ATH10K_THERMAL) |  | ||||||
|  int ath10k_thermal_register(struct ath10k *ar); |  | ||||||
|  void ath10k_thermal_unregister(struct ath10k *ar); |  | ||||||
|  void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); |  | ||||||
| --- a/local-symbols |  | ||||||
| +++ b/local-symbols |  | ||||||
| @@ -139,6 +139,7 @@ ATH10K_SDIO= |  | ||||||
|  ATH10K_USB= |  | ||||||
|  ATH10K_DEBUG= |  | ||||||
|  ATH10K_DEBUGFS= |  | ||||||
| +ATH10K_THERMAL= |  | ||||||
|  ATH10K_TRACING= |  | ||||||
|  ATH10K_DFS_CERTIFIED= |  | ||||||
|  WCN36XX= |  | ||||||
| @@ -1,111 +0,0 @@ | |||||||
| From d06f26c5c8a41f246a9c40862a77a55725cedbd3 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Sven Eckelmann <sven.eckelmann@openmesh.com> |  | ||||||
| Date: Fri, 8 Dec 2017 11:37:42 +0100 |  | ||||||
| Subject: ath10k: search DT for qcom,ath10k-calibration-variant |  | ||||||
|  |  | ||||||
| Board Data File (BDF) is loaded upon driver boot-up procedure. The right |  | ||||||
| board data file is identified on QCA4019 using bus, bmi-chip-id and |  | ||||||
| bmi-board-id. |  | ||||||
|  |  | ||||||
| The problem, however, can occur when the (default) board data file cannot |  | ||||||
| fulfill with the vendor requirements and it is necessary to use a different |  | ||||||
| board data file. |  | ||||||
|  |  | ||||||
| This problem was solved for SMBIOS by adding a special SMBIOS type 0xF8. |  | ||||||
| Something similar has to be provided for systems without SMBIOS but with |  | ||||||
| device trees. No solution was specified by QCA and therefore a new one has |  | ||||||
| to be found for ath10k. |  | ||||||
|  |  | ||||||
| The device tree requires addition strings to define the variant name |  | ||||||
|  |  | ||||||
|     wifi@a000000 { |  | ||||||
|     	status = "okay"; |  | ||||||
|     	qcom,ath10k-calibration-variant = "RT-AC58U"; |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     wifi@a800000 { |  | ||||||
|     	status = "okay"; |  | ||||||
|     	qcom,ath10k-calibration-variant = "RT-AC58U"; |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
| This would create the boarddata identifiers for the board-2.bin search |  | ||||||
|  |  | ||||||
|  *  bus=ahb,bmi-chip-id=0,bmi-board-id=16,variant=RT-AC58U |  | ||||||
|  *  bus=ahb,bmi-chip-id=0,bmi-board-id=17,variant=RT-AC58U |  | ||||||
|  |  | ||||||
| Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/ath/ath10k/core.c | 40 ++++++++++++++++++++++++++++------ |  | ||||||
|  1 file changed, 33 insertions(+), 7 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/core.c |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/core.c |  | ||||||
| @@ -860,6 +860,28 @@ static int ath10k_core_check_smbios(stru |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static int ath10k_core_check_dt(struct ath10k *ar) |  | ||||||
| +{ |  | ||||||
| +	struct device_node *node; |  | ||||||
| +	const char *variant = NULL; |  | ||||||
| + |  | ||||||
| +	node = ar->dev->of_node; |  | ||||||
| +	if (!node) |  | ||||||
| +		return -ENOENT; |  | ||||||
| + |  | ||||||
| +	of_property_read_string(node, "qcom,ath10k-calibration-variant", |  | ||||||
| +				&variant); |  | ||||||
| +	if (!variant) |  | ||||||
| +		return -ENODATA; |  | ||||||
| + |  | ||||||
| +	if (strscpy(ar->id.bdf_ext, variant, sizeof(ar->id.bdf_ext)) < 0) |  | ||||||
| +		ath10k_dbg(ar, ATH10K_DBG_BOOT, |  | ||||||
| +			   "bdf variant string is longer than the buffer can accommodate (variant: %s)\n", |  | ||||||
| +			    variant); |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static int ath10k_download_and_run_otp(struct ath10k *ar) |  | ||||||
|  { |  | ||||||
|  	u32 result, address = ar->hw_params.patch_load_addr; |  | ||||||
| @@ -1231,19 +1253,19 @@ static int ath10k_core_create_board_name |  | ||||||
|  	/* strlen(',variant=') + strlen(ar->id.bdf_ext) */ |  | ||||||
|  	char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 }; |  | ||||||
|   |  | ||||||
| +	if (ar->id.bdf_ext[0] != '\0') |  | ||||||
| +		scnprintf(variant, sizeof(variant), ",variant=%s", |  | ||||||
| +			  ar->id.bdf_ext); |  | ||||||
| + |  | ||||||
|  	if (ar->id.bmi_ids_valid) { |  | ||||||
|  		scnprintf(name, name_len, |  | ||||||
| -			  "bus=%s,bmi-chip-id=%d,bmi-board-id=%d", |  | ||||||
| +			  "bus=%s,bmi-chip-id=%d,bmi-board-id=%d%s", |  | ||||||
|  			  ath10k_bus_str(ar->hif.bus), |  | ||||||
|  			  ar->id.bmi_chip_id, |  | ||||||
| -			  ar->id.bmi_board_id); |  | ||||||
| +			  ar->id.bmi_board_id, variant); |  | ||||||
|  		goto out; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	if (ar->id.bdf_ext[0] != '\0') |  | ||||||
| -		scnprintf(variant, sizeof(variant), ",variant=%s", |  | ||||||
| -			  ar->id.bdf_ext); |  | ||||||
| - |  | ||||||
|  	scnprintf(name, name_len, |  | ||||||
|  		  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s", |  | ||||||
|  		  ath10k_bus_str(ar->hif.bus), |  | ||||||
| @@ -2343,7 +2365,11 @@ static int ath10k_core_probe_fw(struct a |  | ||||||
|   |  | ||||||
|  	ret = ath10k_core_check_smbios(ar); |  | ||||||
|  	if (ret) |  | ||||||
| -		ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not set.\n"); |  | ||||||
| +		ath10k_dbg(ar, ATH10K_DBG_BOOT, "SMBIOS bdf variant name not set.\n"); |  | ||||||
| + |  | ||||||
| +	ret = ath10k_core_check_dt(ar); |  | ||||||
| +	if (ret) |  | ||||||
| +		ath10k_dbg(ar, ATH10K_DBG_BOOT, "DT bdf variant name not set.\n"); |  | ||||||
|   |  | ||||||
|  	ret = ath10k_core_fetch_board_file(ar); |  | ||||||
|  	if (ret) { |  | ||||||
| @@ -1,36 +0,0 @@ | |||||||
| From 606204bb863fa3b0bb54929d79b4dc46338f9180 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Sathishkumar Muruganandam <murugana@codeaurora.org> |  | ||||||
| Date: Tue, 27 Mar 2018 11:26:46 +0300 |  | ||||||
| Subject: [PATCH] ath10k: suppress "Unknown eventid: 36925" warnings |  | ||||||
|  |  | ||||||
| FW has Smart Logging feature enabled by default for detecting failures |  | ||||||
| and processing FATAL_CONDITION_EVENTID (36925 - 0x903D) back to host. |  | ||||||
|  |  | ||||||
| Since ath10k doesn't implement the Smart Logging and FATAL CONDITION |  | ||||||
| EVENT processing yet, suppressing the unknown event ID warning by moving |  | ||||||
| this under ATH10K_DBG_WMI. |  | ||||||
|  |  | ||||||
| Simulated the same issue by having associated STA powered off when |  | ||||||
| ping flood was running from AP backbone. This triggerd STA KICKOUT |  | ||||||
| in AP followed by FATAL CONDITION event 36925. |  | ||||||
|  |  | ||||||
| Issue was reproduced and verified in below DUT |  | ||||||
| ------------------------------------------------ |  | ||||||
| AP mode of OpenWRT QCA9984 running 6.0.8 with FW ver 10.4-3.5.3-00053 |  | ||||||
|  |  | ||||||
| Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/ath/ath10k/wmi.c | 1 + |  | ||||||
|  1 file changed, 1 insertion(+) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/wmi.c |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/wmi.c |  | ||||||
| @@ -5462,6 +5462,7 @@ static void ath10k_wmi_10_4_op_rx(struct |  | ||||||
|  	case WMI_10_4_WOW_WAKEUP_HOST_EVENTID: |  | ||||||
|  	case WMI_10_4_PEER_RATECODE_LIST_EVENTID: |  | ||||||
|  	case WMI_10_4_WDS_PEER_EVENTID: |  | ||||||
| +	case WMI_10_4_DEBUG_FATAL_CONDITION_EVENTID: |  | ||||||
|  		ath10k_dbg(ar, ATH10K_DBG_WMI, |  | ||||||
|  			   "received event id %d not implemented\n", id); |  | ||||||
|  		break; |  | ||||||
| @@ -1,45 +0,0 @@ | |||||||
| From patchwork Mon May 28 11:25:06 2018 |  | ||||||
| Content-Type: text/plain; charset="utf-8" |  | ||||||
| MIME-Version: 1.0 |  | ||||||
| Content-Transfer-Encoding: 7bit |  | ||||||
| Subject: Revert "rt2800: use TXOP_BACKOFF for probe frames" |  | ||||||
| From: Stanislaw Gruszka <sgruszka@redhat.com> |  | ||||||
| X-Patchwork-Id: 10431861 |  | ||||||
| Message-Id: <1527506706-6488-1-git-send-email-sgruszka@redhat.com> |  | ||||||
| To: linux-wireless@vger.kernel.org |  | ||||||
| Date: Mon, 28 May 2018 13:25:06 +0200 |  | ||||||
|  |  | ||||||
| This reverts commit fb47ada8dc3c30c8e7b415da155742b49536c61e. |  | ||||||
|  |  | ||||||
| In some situations when we set TXOP_BACKOFF, the probe frame is |  | ||||||
| not sent at all. What it worse then sending probe frame as part |  | ||||||
| of AMPDU and can degrade 11n performance to 11g rates. |  | ||||||
|  |  | ||||||
| Cc: stable@vger.kernel.org |  | ||||||
| Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 7 +++---- |  | ||||||
|  1 file changed, 3 insertions(+), 4 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c |  | ||||||
| +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c |  | ||||||
| @@ -372,16 +372,15 @@ static void rt2x00queue_create_tx_descri |  | ||||||
|   |  | ||||||
|  	/* |  | ||||||
|  	 * Determine IFS values |  | ||||||
| -	 * - Use TXOP_BACKOFF for probe and management frames except beacons |  | ||||||
| +	 * - Use TXOP_BACKOFF for management frames except beacons |  | ||||||
|  	 * - Use TXOP_SIFS for fragment bursts |  | ||||||
|  	 * - Use TXOP_HTTXOP for everything else |  | ||||||
|  	 * |  | ||||||
|  	 * Note: rt2800 devices won't use CTS protection (if used) |  | ||||||
|  	 * for frames not transmitted with TXOP_HTTXOP |  | ||||||
|  	 */ |  | ||||||
| -	if ((ieee80211_is_mgmt(hdr->frame_control) && |  | ||||||
| -	     !ieee80211_is_beacon(hdr->frame_control)) || |  | ||||||
| -	    (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) |  | ||||||
| +	if (ieee80211_is_mgmt(hdr->frame_control) && |  | ||||||
| +	    !ieee80211_is_beacon(hdr->frame_control)) |  | ||||||
|  		txdesc->u.ht.txop = TXOP_BACKOFF; |  | ||||||
|  	else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)) |  | ||||||
|  		txdesc->u.ht.txop = TXOP_SIFS; |  | ||||||
| @@ -1,237 +0,0 @@ | |||||||
| From: Thomas Hebb <tommyhebb@gmail.com> |  | ||||||
| Subject: [PATCH] ath10k: search all IEs for variant before falling back |  | ||||||
| Date: Wed, 21 Feb 2018 11:43:39 -0500 |  | ||||||
|  |  | ||||||
| commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file |  | ||||||
| extension") added a feature to ath10k that allows Board Data File |  | ||||||
| (BDF) conflicts between multiple devices that use the same device IDs |  | ||||||
| but have different calibration requirements to be resolved by allowing |  | ||||||
| a "variant" string to be stored in SMBIOS [and later device tree, added |  | ||||||
| by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration- |  | ||||||
| variant")] that gets appended to the ID stored in board-2.bin. |  | ||||||
|  |  | ||||||
| This original patch had a regression, however. Namely that devices with |  | ||||||
| a variant present in SMBIOS that didn't need custom BDFs could no longer |  | ||||||
| find the default BDF, which has no variant appended. The patch was |  | ||||||
| reverted and re-applied with a fix for this issue in commit 1657b8f84ed9 |  | ||||||
| ("search SMBIOS for OEM board file extension"). |  | ||||||
|  |  | ||||||
| But the fix to fall back to a default BDF introduced another issue: the |  | ||||||
| driver currently parses IEs in board-2.bin one by one, and for each one |  | ||||||
| it first checks to see if it matches the ID with the variant appended. |  | ||||||
| If it doesn't, it checks to see if it matches the "fallback" ID with no |  | ||||||
| variant. If a matching BDF is found at any point during this search, the |  | ||||||
| search is terminated and that BDF is used. The issue is that it's very |  | ||||||
| possible (and is currently the case for board-2.bin files present in the |  | ||||||
| ath10k-firmware repository) for the default BDF to occur in an earlier |  | ||||||
| IE than the variant-specific BDF. In this case, the current code will |  | ||||||
| happily choose the default BDF even though a better-matching BDF is |  | ||||||
| present later in the file. |  | ||||||
|  |  | ||||||
| This patch fixes the issue by first searching the entire file for the ID |  | ||||||
| with variant, and searching for the fallback ID only if that search |  | ||||||
| fails. It also includes some code cleanup in the area, as |  | ||||||
| ath10k_core_fetch_board_data_api_n() no longer does its own string |  | ||||||
| mangling to remove the variant from an ID, instead leaving that job to a |  | ||||||
| new flag passed to ath10k_core_create_board_name(). |  | ||||||
|  |  | ||||||
| I've tested this patch on a QCA4019 and verified that the driver behaves |  | ||||||
| correctly for 1) both fallback and variant BDFs present, 2) only fallback |  | ||||||
| BDF present, and 3) no matching BDFs present. |  | ||||||
|  |  | ||||||
| Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension") |  | ||||||
| Signed-off-by: Thomas Hebb <tommyhebb@gmail.com> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/ath/ath10k/core.c | 134 ++++++++++++++++++--------------- |  | ||||||
|  1 file changed, 72 insertions(+), 62 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/core.c |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/core.c |  | ||||||
| @@ -1132,14 +1132,61 @@ out: |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static int ath10k_core_search_bd(struct ath10k *ar, |  | ||||||
| +				 const char *boardname, |  | ||||||
| +				 const u8 *data, |  | ||||||
| +				 size_t len) |  | ||||||
| +{ |  | ||||||
| +	size_t ie_len; |  | ||||||
| +	struct ath10k_fw_ie *hdr; |  | ||||||
| +	int ret = -ENOENT, ie_id; |  | ||||||
| + |  | ||||||
| +	while (len > sizeof(struct ath10k_fw_ie)) { |  | ||||||
| +		hdr = (struct ath10k_fw_ie *)data; |  | ||||||
| +		ie_id = le32_to_cpu(hdr->id); |  | ||||||
| +		ie_len = le32_to_cpu(hdr->len); |  | ||||||
| + |  | ||||||
| +		len -= sizeof(*hdr); |  | ||||||
| +		data = hdr->data; |  | ||||||
| + |  | ||||||
| +		if (len < ALIGN(ie_len, 4)) { |  | ||||||
| +			ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n", |  | ||||||
| +				   ie_id, ie_len, len); |  | ||||||
| +			return -EINVAL; |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
| +		switch (ie_id) { |  | ||||||
| +		case ATH10K_BD_IE_BOARD: |  | ||||||
| +			ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len, |  | ||||||
| +							    boardname); |  | ||||||
| +			if (ret == -ENOENT) |  | ||||||
| +				/* no match found, continue */ |  | ||||||
| +				break; |  | ||||||
| + |  | ||||||
| +			/* either found or error, so stop searching */ |  | ||||||
| +			goto out; |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
| +		/* jump over the padding */ |  | ||||||
| +		ie_len = ALIGN(ie_len, 4); |  | ||||||
| + |  | ||||||
| +		len -= ie_len; |  | ||||||
| +		data += ie_len; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +out: |  | ||||||
| +	/* return result of parse_bd_ie_board() or -ENOENT */ |  | ||||||
| +	return ret; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar, |  | ||||||
|  					      const char *boardname, |  | ||||||
| +					      const char *fallback_boardname, |  | ||||||
|  					      const char *filename) |  | ||||||
|  { |  | ||||||
| -	size_t len, magic_len, ie_len; |  | ||||||
| -	struct ath10k_fw_ie *hdr; |  | ||||||
| +	size_t len, magic_len; |  | ||||||
|  	const u8 *data; |  | ||||||
| -	int ret, ie_id; |  | ||||||
| +	int ret; |  | ||||||
|   |  | ||||||
|  	ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar, |  | ||||||
|  							ar->hw_params.fw.dir, |  | ||||||
| @@ -1177,69 +1224,23 @@ static int ath10k_core_fetch_board_data_ |  | ||||||
|  	data += magic_len; |  | ||||||
|  	len -= magic_len; |  | ||||||
|   |  | ||||||
| -	while (len > sizeof(struct ath10k_fw_ie)) { |  | ||||||
| -		hdr = (struct ath10k_fw_ie *)data; |  | ||||||
| -		ie_id = le32_to_cpu(hdr->id); |  | ||||||
| -		ie_len = le32_to_cpu(hdr->len); |  | ||||||
| - |  | ||||||
| -		len -= sizeof(*hdr); |  | ||||||
| -		data = hdr->data; |  | ||||||
| - |  | ||||||
| -		if (len < ALIGN(ie_len, 4)) { |  | ||||||
| -			ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n", |  | ||||||
| -				   ie_id, ie_len, len); |  | ||||||
| -			ret = -EINVAL; |  | ||||||
| -			goto err; |  | ||||||
| -		} |  | ||||||
| +	/* attempt to find boardname in the IE list */ |  | ||||||
| +	ret = ath10k_core_search_bd(ar, boardname, data, len); |  | ||||||
|   |  | ||||||
| -		switch (ie_id) { |  | ||||||
| -		case ATH10K_BD_IE_BOARD: |  | ||||||
| -			ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len, |  | ||||||
| -							    boardname); |  | ||||||
| -			if (ret == -ENOENT && ar->id.bdf_ext[0] != '\0') { |  | ||||||
| -				/* try default bdf if variant was not found */ |  | ||||||
| -				char *s, *v = ",variant="; |  | ||||||
| -				char boardname2[100]; |  | ||||||
| - |  | ||||||
| -				strlcpy(boardname2, boardname, |  | ||||||
| -					sizeof(boardname2)); |  | ||||||
| - |  | ||||||
| -				s = strstr(boardname2, v); |  | ||||||
| -				if (s) |  | ||||||
| -					*s = '\0';  /* strip ",variant=%s" */ |  | ||||||
| - |  | ||||||
| -				ret = ath10k_core_parse_bd_ie_board(ar, data, |  | ||||||
| -								    ie_len, |  | ||||||
| -								    boardname2); |  | ||||||
| -			} |  | ||||||
| +	/* if we didn't find it and have a fallback name, try that */ |  | ||||||
| +	if (ret == -ENOENT && fallback_boardname) |  | ||||||
| +		ret = ath10k_core_search_bd(ar, fallback_boardname, data, len); |  | ||||||
|   |  | ||||||
| -			if (ret == -ENOENT) |  | ||||||
| -				/* no match found, continue */ |  | ||||||
| -				break; |  | ||||||
| -			else if (ret) |  | ||||||
| -				/* there was an error, bail out */ |  | ||||||
| -				goto err; |  | ||||||
| - |  | ||||||
| -			/* board data found */ |  | ||||||
| -			goto out; |  | ||||||
| -		} |  | ||||||
| - |  | ||||||
| -		/* jump over the padding */ |  | ||||||
| -		ie_len = ALIGN(ie_len, 4); |  | ||||||
| - |  | ||||||
| -		len -= ie_len; |  | ||||||
| -		data += ie_len; |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
| -out: |  | ||||||
| -	if (!ar->normal_mode_fw.board_data || !ar->normal_mode_fw.board_len) { |  | ||||||
| +	if (ret == -ENOENT) { |  | ||||||
|  		ath10k_err(ar, |  | ||||||
|  			   "failed to fetch board data for %s from %s/%s\n", |  | ||||||
|  			   boardname, ar->hw_params.fw.dir, filename); |  | ||||||
|  		ret = -ENODATA; |  | ||||||
| -		goto err; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	if (ret) |  | ||||||
| +		goto err; |  | ||||||
| + |  | ||||||
|  	return 0; |  | ||||||
|   |  | ||||||
|  err: |  | ||||||
| @@ -1248,12 +1249,12 @@ err: |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static int ath10k_core_create_board_name(struct ath10k *ar, char *name, |  | ||||||
| -					 size_t name_len) |  | ||||||
| +					 size_t name_len, bool with_variant) |  | ||||||
|  { |  | ||||||
|  	/* strlen(',variant=') + strlen(ar->id.bdf_ext) */ |  | ||||||
|  	char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 }; |  | ||||||
|   |  | ||||||
| -	if (ar->id.bdf_ext[0] != '\0') |  | ||||||
| +	if (with_variant && ar->id.bdf_ext[0] != '\0') |  | ||||||
|  		scnprintf(variant, sizeof(variant), ",variant=%s", |  | ||||||
|  			  ar->id.bdf_ext); |  | ||||||
|   |  | ||||||
| @@ -1279,17 +1280,26 @@ out: |  | ||||||
|   |  | ||||||
|  static int ath10k_core_fetch_board_file(struct ath10k *ar) |  | ||||||
|  { |  | ||||||
| -	char boardname[100]; |  | ||||||
| +	char boardname[100], fallback_boardname[100]; |  | ||||||
|  	int ret; |  | ||||||
|   |  | ||||||
| -	ret = ath10k_core_create_board_name(ar, boardname, sizeof(boardname)); |  | ||||||
| +	ret = ath10k_core_create_board_name(ar, boardname, |  | ||||||
| +					    sizeof(boardname), true); |  | ||||||
|  	if (ret) { |  | ||||||
|  		ath10k_err(ar, "failed to create board name: %d", ret); |  | ||||||
|  		return ret; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	ret = ath10k_core_create_board_name(ar, fallback_boardname, |  | ||||||
| +					    sizeof(boardname), false); |  | ||||||
| +	if (ret) { |  | ||||||
| +		ath10k_err(ar, "failed to create fallback board name: %d", ret); |  | ||||||
| +		return ret; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	ar->bd_api = 2; |  | ||||||
|  	ret = ath10k_core_fetch_board_data_api_n(ar, boardname, |  | ||||||
| +						 fallback_boardname, |  | ||||||
|  						 ATH10K_BOARD_API2_FILE); |  | ||||||
|  	if (!ret) |  | ||||||
|  		goto success; |  | ||||||
| @@ -1,72 +0,0 @@ | |||||||
| From: Brian Norris <briannorris@chromium.org> |  | ||||||
| Date: Thu, 19 Oct 2017 11:45:19 -0700 |  | ||||||
| Subject: [PATCH] ath10k: fix build errors with !CONFIG_PM |  | ||||||
|  |  | ||||||
| Build errors have been reported with CONFIG_PM=n: |  | ||||||
|  |  | ||||||
| drivers/net/wireless/ath/ath10k/pci.c:3416:8: error: implicit |  | ||||||
| declaration of function 'ath10k_pci_suspend' |  | ||||||
| [-Werror=implicit-function-declaration] |  | ||||||
|  |  | ||||||
| drivers/net/wireless/ath/ath10k/pci.c:3428:8: error: implicit |  | ||||||
| declaration of function 'ath10k_pci_resume' |  | ||||||
| [-Werror=implicit-function-declaration] |  | ||||||
|  |  | ||||||
| These are caused by the combination of the following two commits: |  | ||||||
|  |  | ||||||
| 6af1de2e4ec4 ("ath10k: mark PM functions as __maybe_unused") |  | ||||||
| 96378bd2c6cd ("ath10k: fix core PCI suspend when WoWLAN is supported but |  | ||||||
| disabled") |  | ||||||
|  |  | ||||||
| Both build fine on their own. |  | ||||||
|  |  | ||||||
| But now that ath10k_pci_pm_{suspend,resume}() is compiled |  | ||||||
| unconditionally, we should also compile ath10k_pci_{suspend,resume}() |  | ||||||
| unconditionally. |  | ||||||
|  |  | ||||||
| And drop the #ifdef around ath10k_pci_hif_{suspend,resume}() too; they |  | ||||||
| are trivial (empty), so we're not saving much space by compiling them |  | ||||||
| out. And the alternatives would be to sprinkle more __maybe_unused, or |  | ||||||
| spread the #ifdef's further. |  | ||||||
|  |  | ||||||
| Build tested with the following combinations: |  | ||||||
| CONFIG_PM=y && CONFIG_PM_SLEEP=y |  | ||||||
| CONFIG_PM=y && CONFIG_PM_SLEEP=n |  | ||||||
| CONFIG_PM=n |  | ||||||
|  |  | ||||||
| Fixes: 96378bd2c6cd ("ath10k: fix core PCI suspend when WoWLAN is supported but disabled") |  | ||||||
| Fixes: 096ad2a15fd8 ("Merge branch 'ath-next'") |  | ||||||
| Signed-off-by: Brian Norris <briannorris@chromium.org> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/pci.c |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/pci.c |  | ||||||
| @@ -2577,8 +2577,6 @@ void ath10k_pci_hif_power_down(struct at |  | ||||||
|  	 */ |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -#ifdef CONFIG_PM |  | ||||||
| - |  | ||||||
|  static int ath10k_pci_hif_suspend(struct ath10k *ar) |  | ||||||
|  { |  | ||||||
|  	/* Nothing to do; the important stuff is in the driver suspend. */ |  | ||||||
| @@ -2627,7 +2625,6 @@ static int ath10k_pci_resume(struct ath1 |  | ||||||
|   |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
| -#endif |  | ||||||
|   |  | ||||||
|  static bool ath10k_pci_validate_cal(void *data, size_t size) |  | ||||||
|  { |  | ||||||
| @@ -2782,10 +2779,8 @@ static const struct ath10k_hif_ops ath10 |  | ||||||
|  	.power_down		= ath10k_pci_hif_power_down, |  | ||||||
|  	.read32			= ath10k_pci_read32, |  | ||||||
|  	.write32		= ath10k_pci_write32, |  | ||||||
| -#ifdef CONFIG_PM |  | ||||||
|  	.suspend		= ath10k_pci_hif_suspend, |  | ||||||
|  	.resume			= ath10k_pci_hif_resume, |  | ||||||
| -#endif |  | ||||||
|  	.fetch_cal_eeprom	= ath10k_pci_hif_fetch_cal_eeprom, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| @@ -1,37 +0,0 @@ | |||||||
| From: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| Date: Mon, 20 Nov 2017 17:01:44 +0100 |  | ||||||
| Subject: [PATCH] mac80211: properly free requested-but-not-started TX agg |  | ||||||
|  sessions |  | ||||||
|  |  | ||||||
| When deleting a station or otherwise tearing down all aggregation |  | ||||||
| sessions, make sure to delete requested but not yet started ones, |  | ||||||
| to avoid the following scenario: |  | ||||||
|  |  | ||||||
|  * session is requested, added to tid_start_tx[] |  | ||||||
|  * ieee80211_ba_session_work() runs, gets past BLOCK_BA check |  | ||||||
|  * ieee80211_sta_tear_down_BA_sessions() runs, locks &sta->ampdu_mlme.mtx, |  | ||||||
|    e.g. while deleting the station - deleting all active sessions |  | ||||||
|  * ieee80211_ba_session_work() continues since tear down flushes it, and |  | ||||||
|    calls ieee80211_tx_ba_session_handle_start() for the new session, arms |  | ||||||
|    the timer for it |  | ||||||
|  * station deletion continues to __cleanup_single_sta() and frees the |  | ||||||
|    session struct, while the timer is armed |  | ||||||
|  |  | ||||||
| Reported-by: Fengguang Wu <fengguang.wu@intel.com> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/agg-tx.c |  | ||||||
| +++ b/net/mac80211/agg-tx.c |  | ||||||
| @@ -330,6 +330,11 @@ int ___ieee80211_stop_tx_ba_session(stru |  | ||||||
|   |  | ||||||
|  	spin_lock_bh(&sta->lock); |  | ||||||
|   |  | ||||||
| +	/* free struct pending for start, if present */ |  | ||||||
| +	tid_tx = sta->ampdu_mlme.tid_start_tx[tid]; |  | ||||||
| +	kfree(tid_tx); |  | ||||||
| +	sta->ampdu_mlme.tid_start_tx[tid] = NULL; |  | ||||||
| + |  | ||||||
|  	tid_tx = rcu_dereference_protected_tid_tx(sta, tid); |  | ||||||
|  	if (!tid_tx) { |  | ||||||
|  		spin_unlock_bh(&sta->lock); |  | ||||||
| @@ -1,25 +0,0 @@ | |||||||
| From: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| Date: Thu, 4 Jan 2018 15:51:53 +0100 |  | ||||||
| Subject: [PATCH] mac80211: mesh: drop frames appearing to be from us |  | ||||||
|  |  | ||||||
| If there are multiple mesh stations with the same MAC address, |  | ||||||
| they will both get confused and start throwing warnings. |  | ||||||
|  |  | ||||||
| Obviously in this case nothing can actually work anyway, so just |  | ||||||
| drop frames that look like they're from ourselves early on. |  | ||||||
|  |  | ||||||
| Reported-by: Gui Iribarren <gui@altermundi.net> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -3632,6 +3632,8 @@ static bool ieee80211_accept_frame(struc |  | ||||||
|  		} |  | ||||||
|  		return true; |  | ||||||
|  	case NL80211_IFTYPE_MESH_POINT: |  | ||||||
| +		if (ether_addr_equal(sdata->vif.addr, hdr->addr2)) |  | ||||||
| +			return false; |  | ||||||
|  		if (multicast) |  | ||||||
|  			return true; |  | ||||||
|  		return ether_addr_equal(sdata->vif.addr, hdr->addr1); |  | ||||||
| @@ -1,60 +0,0 @@ | |||||||
| From 2fd3877b5bb7d39782c3205a1dcda02023b8514a Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Wed, 8 Nov 2017 14:36:31 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: handle FWHALT mailbox indication |  | ||||||
|  |  | ||||||
| The firmware uses a mailbox to communicate to the host what is going |  | ||||||
| on. In the driver we validate the bit received. Various people seen |  | ||||||
| the following message: |  | ||||||
|  |  | ||||||
|  brcmfmac: brcmf_sdio_hostmail: Unknown mailbox data content: 0x40012 |  | ||||||
|  |  | ||||||
| Bit 4 is cause of this message, but this actually indicates the firmware |  | ||||||
| has halted. Handle this bit by giving a more meaningful error message. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 14 ++++++++++---- |  | ||||||
|  1 file changed, 10 insertions(+), 4 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -260,10 +260,11 @@ struct rte_console { |  | ||||||
|  #define I_HMB_HOST_INT	I_HMB_SW3	/* Miscellaneous Interrupt */ |  | ||||||
|   |  | ||||||
|  /* tohostmailboxdata */ |  | ||||||
| -#define HMB_DATA_NAKHANDLED	1	/* retransmit NAK'd frame */ |  | ||||||
| -#define HMB_DATA_DEVREADY	2	/* talk to host after enable */ |  | ||||||
| -#define HMB_DATA_FC		4	/* per prio flowcontrol update flag */ |  | ||||||
| -#define HMB_DATA_FWREADY	8	/* fw ready for protocol activity */ |  | ||||||
| +#define HMB_DATA_NAKHANDLED	0x0001	/* retransmit NAK'd frame */ |  | ||||||
| +#define HMB_DATA_DEVREADY	0x0002	/* talk to host after enable */ |  | ||||||
| +#define HMB_DATA_FC		0x0004	/* per prio flowcontrol update flag */ |  | ||||||
| +#define HMB_DATA_FWREADY	0x0008	/* fw ready for protocol activity */ |  | ||||||
| +#define HMB_DATA_FWHALT		0x0010	/* firmware halted */ |  | ||||||
|   |  | ||||||
|  #define HMB_DATA_FCDATA_MASK	0xff000000 |  | ||||||
|  #define HMB_DATA_FCDATA_SHIFT	24 |  | ||||||
| @@ -1094,6 +1095,10 @@ static u32 brcmf_sdio_hostmail(struct br |  | ||||||
|  			  offsetof(struct sdpcmd_regs, tosbmailbox)); |  | ||||||
|  	bus->sdcnt.f1regdata += 2; |  | ||||||
|   |  | ||||||
| +	/* dongle indicates the firmware has halted/crashed */ |  | ||||||
| +	if (hmb_data & HMB_DATA_FWHALT) |  | ||||||
| +		brcmf_err("mailbox indicates firmware halted\n"); |  | ||||||
| + |  | ||||||
|  	/* Dongle recomposed rx frames, accept them again */ |  | ||||||
|  	if (hmb_data & HMB_DATA_NAKHANDLED) { |  | ||||||
|  		brcmf_dbg(SDIO, "Dongle reports NAK handled, expect rtx of %d\n", |  | ||||||
| @@ -1151,6 +1156,7 @@ static u32 brcmf_sdio_hostmail(struct br |  | ||||||
|  			 HMB_DATA_NAKHANDLED | |  | ||||||
|  			 HMB_DATA_FC | |  | ||||||
|  			 HMB_DATA_FWREADY | |  | ||||||
| +			 HMB_DATA_FWHALT | |  | ||||||
|  			 HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK)) |  | ||||||
|  		brcmf_err("Unknown mailbox data content: 0x%02x\n", |  | ||||||
|  			  hmb_data); |  | ||||||
| @@ -1,133 +0,0 @@ | |||||||
| From 6c219b0088158da839a5be63c5b3d96c145501d2 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Date: Wed, 8 Nov 2017 14:36:32 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: disable packet filtering in promiscuous mode |  | ||||||
|  |  | ||||||
| Disable arp and nd offload to allow all packets sending to host. |  | ||||||
|  |  | ||||||
| Reported-by: Phil Elwell <phil@raspberrypi.org> |  | ||||||
| Tested-by: Phil Elwell <phil@raspberrypi.org> |  | ||||||
| Reviewed-by: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 41 ---------------------- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.c    | 38 ++++++++++++++++++++ |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.h    |  1 + |  | ||||||
|  3 files changed, 39 insertions(+), 41 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| @@ -472,47 +472,6 @@ send_key_to_dongle(struct brcmf_if *ifp, |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static s32 |  | ||||||
| -brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable) |  | ||||||
| -{ |  | ||||||
| -	s32 err; |  | ||||||
| -	u32 mode; |  | ||||||
| - |  | ||||||
| -	if (enable) |  | ||||||
| -		mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY; |  | ||||||
| -	else |  | ||||||
| -		mode = 0; |  | ||||||
| - |  | ||||||
| -	/* Try to set and enable ARP offload feature, this may fail, then it  */ |  | ||||||
| -	/* is simply not supported and err 0 will be returned                 */ |  | ||||||
| -	err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode); |  | ||||||
| -	if (err) { |  | ||||||
| -		brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n", |  | ||||||
| -			  mode, err); |  | ||||||
| -		err = 0; |  | ||||||
| -	} else { |  | ||||||
| -		err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable); |  | ||||||
| -		if (err) { |  | ||||||
| -			brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n", |  | ||||||
| -				  enable, err); |  | ||||||
| -			err = 0; |  | ||||||
| -		} else |  | ||||||
| -			brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n", |  | ||||||
| -				  enable, mode); |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
| -	err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable); |  | ||||||
| -	if (err) { |  | ||||||
| -		brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n", |  | ||||||
| -			  enable, err); |  | ||||||
| -		err = 0; |  | ||||||
| -	} else |  | ||||||
| -		brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n", |  | ||||||
| -			  enable, mode); |  | ||||||
| - |  | ||||||
| -	return err; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
|  static void |  | ||||||
|  brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev) |  | ||||||
|  { |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| @@ -71,6 +71,43 @@ struct brcmf_if *brcmf_get_ifp(struct br |  | ||||||
|  	return ifp; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable) |  | ||||||
| +{ |  | ||||||
| +	s32 err; |  | ||||||
| +	u32 mode; |  | ||||||
| + |  | ||||||
| +	if (enable) |  | ||||||
| +		mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY; |  | ||||||
| +	else |  | ||||||
| +		mode = 0; |  | ||||||
| + |  | ||||||
| +	/* Try to set and enable ARP offload feature, this may fail, then it  */ |  | ||||||
| +	/* is simply not supported and err 0 will be returned                 */ |  | ||||||
| +	err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode); |  | ||||||
| +	if (err) { |  | ||||||
| +		brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n", |  | ||||||
| +			  mode, err); |  | ||||||
| +	} else { |  | ||||||
| +		err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable); |  | ||||||
| +		if (err) { |  | ||||||
| +			brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n", |  | ||||||
| +				  enable, err); |  | ||||||
| +		} else { |  | ||||||
| +			brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n", |  | ||||||
| +				  enable, mode); |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable); |  | ||||||
| +	if (err) { |  | ||||||
| +		brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n", |  | ||||||
| +			  enable, err); |  | ||||||
| +	} else { |  | ||||||
| +		brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n", |  | ||||||
| +			  enable, mode); |  | ||||||
| +	} |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static void _brcmf_set_multicast_list(struct work_struct *work) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_if *ifp; |  | ||||||
| @@ -134,6 +171,7 @@ static void _brcmf_set_multicast_list(st |  | ||||||
|  	if (err < 0) |  | ||||||
|  		brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n", |  | ||||||
|  			  err); |  | ||||||
| +	brcmf_configure_arp_nd_offload(ifp, !cmd_value); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  #if IS_ENABLED(CONFIG_IPV6) |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h |  | ||||||
| @@ -203,6 +203,7 @@ int brcmf_netdev_wait_pend8021x(struct b |  | ||||||
|  /* Return pointer to interface name */ |  | ||||||
|  char *brcmf_ifname(struct brcmf_if *ifp); |  | ||||||
|  struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx); |  | ||||||
| +void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable); |  | ||||||
|  int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); |  | ||||||
|  struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, |  | ||||||
|  			      bool is_p2pdev, const char *name, u8 *mac_addr); |  | ||||||
| @@ -1,133 +0,0 @@ | |||||||
| From 8c6efda22f5f9f73fc948f517424466be01ae84d Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Wed, 8 Nov 2017 14:36:33 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: cleanup brcmf_cfg80211_escan() function |  | ||||||
|  |  | ||||||
| The function brcmf_cfg80211_escan() was always called with a non-null |  | ||||||
| request parameter and null pointer for this_ssid parameter. Clean up |  | ||||||
| the function removing the dead code path. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 76 ++++------------------ |  | ||||||
|  1 file changed, 11 insertions(+), 65 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| @@ -1072,18 +1072,10 @@ brcmf_do_escan(struct brcmf_if *ifp, str |  | ||||||
|   |  | ||||||
|  static s32 |  | ||||||
|  brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif, |  | ||||||
| -		     struct cfg80211_scan_request *request, |  | ||||||
| -		     struct cfg80211_ssid *this_ssid) |  | ||||||
| +		     struct cfg80211_scan_request *request) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_if *ifp = vif->ifp; |  | ||||||
|  	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |  | ||||||
| -	struct cfg80211_ssid *ssids; |  | ||||||
| -	u32 passive_scan; |  | ||||||
| -	bool escan_req; |  | ||||||
| -	bool spec_scan; |  | ||||||
|  	s32 err; |  | ||||||
| -	struct brcmf_ssid_le ssid_le; |  | ||||||
| -	u32 SSID_len; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SCAN, "START ESCAN\n"); |  | ||||||
|   |  | ||||||
| @@ -1101,8 +1093,8 @@ brcmf_cfg80211_escan(struct wiphy *wiphy |  | ||||||
|  			  cfg->scan_status); |  | ||||||
|  		return -EAGAIN; |  | ||||||
|  	} |  | ||||||
| -	if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) { |  | ||||||
| -		brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state); |  | ||||||
| +	if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) { |  | ||||||
| +		brcmf_err("Connecting: status (%lu)\n", vif->sme_state); |  | ||||||
|  		return -EAGAIN; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| @@ -1110,63 +1102,17 @@ brcmf_cfg80211_escan(struct wiphy *wiphy |  | ||||||
|  	if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) |  | ||||||
|  		vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; |  | ||||||
|   |  | ||||||
| -	escan_req = false; |  | ||||||
| -	if (request) { |  | ||||||
| -		/* scan bss */ |  | ||||||
| -		ssids = request->ssids; |  | ||||||
| -		escan_req = true; |  | ||||||
| -	} else { |  | ||||||
| -		/* scan in ibss */ |  | ||||||
| -		/* we don't do escan in ibss */ |  | ||||||
| -		ssids = this_ssid; |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
|  	cfg->scan_request = request; |  | ||||||
|  	set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); |  | ||||||
| -	if (escan_req) { |  | ||||||
| -		cfg->escan_info.run = brcmf_run_escan; |  | ||||||
| -		err = brcmf_p2p_scan_prep(wiphy, request, vif); |  | ||||||
| -		if (err) |  | ||||||
| -			goto scan_out; |  | ||||||
| - |  | ||||||
| -		err = brcmf_do_escan(vif->ifp, request); |  | ||||||
| -		if (err) |  | ||||||
| -			goto scan_out; |  | ||||||
| -	} else { |  | ||||||
| -		brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n", |  | ||||||
| -			  ssids->ssid, ssids->ssid_len); |  | ||||||
| -		memset(&ssid_le, 0, sizeof(ssid_le)); |  | ||||||
| -		SSID_len = min_t(u8, sizeof(ssid_le.SSID), ssids->ssid_len); |  | ||||||
| -		ssid_le.SSID_len = cpu_to_le32(0); |  | ||||||
| -		spec_scan = false; |  | ||||||
| -		if (SSID_len) { |  | ||||||
| -			memcpy(ssid_le.SSID, ssids->ssid, SSID_len); |  | ||||||
| -			ssid_le.SSID_len = cpu_to_le32(SSID_len); |  | ||||||
| -			spec_scan = true; |  | ||||||
| -		} else |  | ||||||
| -			brcmf_dbg(SCAN, "Broadcast scan\n"); |  | ||||||
| - |  | ||||||
| -		passive_scan = cfg->active_scan ? 0 : 1; |  | ||||||
| -		err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, |  | ||||||
| -					    passive_scan); |  | ||||||
| -		if (err) { |  | ||||||
| -			brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err); |  | ||||||
| -			goto scan_out; |  | ||||||
| -		} |  | ||||||
| -		brcmf_scan_config_mpc(ifp, 0); |  | ||||||
| -		err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, &ssid_le, |  | ||||||
| -					     sizeof(ssid_le)); |  | ||||||
| -		if (err) { |  | ||||||
| -			if (err == -EBUSY) |  | ||||||
| -				brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n", |  | ||||||
| -					  ssid_le.SSID); |  | ||||||
| -			else |  | ||||||
| -				brcmf_err("WLC_SCAN error (%d)\n", err); |  | ||||||
| - |  | ||||||
| -			brcmf_scan_config_mpc(ifp, 1); |  | ||||||
| -			goto scan_out; |  | ||||||
| -		} |  | ||||||
| -	} |  | ||||||
| + |  | ||||||
| +	cfg->escan_info.run = brcmf_run_escan; |  | ||||||
| +	err = brcmf_p2p_scan_prep(wiphy, request, vif); |  | ||||||
| +	if (err) |  | ||||||
| +		goto scan_out; |  | ||||||
| + |  | ||||||
| +	err = brcmf_do_escan(vif->ifp, request); |  | ||||||
| +	if (err) |  | ||||||
| +		goto scan_out; |  | ||||||
|   |  | ||||||
|  	/* Arm scan timeout timer */ |  | ||||||
|  	mod_timer(&cfg->escan_timeout, jiffies + |  | ||||||
| @@ -1191,7 +1137,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, |  | ||||||
|  	if (!check_vif_up(vif)) |  | ||||||
|  		return -EIO; |  | ||||||
|   |  | ||||||
| -	err = brcmf_cfg80211_escan(wiphy, vif, request, NULL); |  | ||||||
| +	err = brcmf_cfg80211_escan(wiphy, vif, request); |  | ||||||
|   |  | ||||||
|  	if (err) |  | ||||||
|  		brcmf_err("scan error (%d)\n", err); |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| From df2d8388bc96c0f29d27d121f2a4cd054f8b3900 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Wed, 8 Nov 2017 14:36:34 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: use msecs_to_jiffies() instead of calculation using |  | ||||||
|  HZ |  | ||||||
|  |  | ||||||
| Minor cleanup using provided macro to convert milliseconds interval |  | ||||||
| to jiffies in brcmf_cfg80211_escan(). |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++-- |  | ||||||
|  1 file changed, 2 insertions(+), 2 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| @@ -1115,8 +1115,8 @@ brcmf_cfg80211_escan(struct wiphy *wiphy |  | ||||||
|  		goto scan_out; |  | ||||||
|   |  | ||||||
|  	/* Arm scan timeout timer */ |  | ||||||
| -	mod_timer(&cfg->escan_timeout, jiffies + |  | ||||||
| -			BRCMF_ESCAN_TIMER_INTERVAL_MS * HZ / 1000); |  | ||||||
| +	mod_timer(&cfg->escan_timeout, |  | ||||||
| +		  jiffies + msecs_to_jiffies(BRCMF_ESCAN_TIMER_INTERVAL_MS)); |  | ||||||
|   |  | ||||||
|  	return 0; |  | ||||||
|   |  | ||||||
| @@ -1,83 +0,0 @@ | |||||||
| From 588378f15cff285ac81c929239ccba01d7f71d50 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Wed, 8 Nov 2017 14:36:35 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: get rid of brcmf_cfg80211_escan() function |  | ||||||
|  |  | ||||||
| The function brcmf_cfg80211_escan() is only called by brcmf_cfg80211_scan() |  | ||||||
| so there is no reason to split in two function especially since the latter |  | ||||||
| does not do an awful lot. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 34 +++++++--------------- |  | ||||||
|  1 file changed, 10 insertions(+), 24 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| @@ -1071,13 +1071,16 @@ brcmf_do_escan(struct brcmf_if *ifp, str |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static s32 |  | ||||||
| -brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif, |  | ||||||
| -		     struct cfg80211_scan_request *request) |  | ||||||
| +brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |  | ||||||
| -	s32 err; |  | ||||||
| +	struct brcmf_cfg80211_vif *vif; |  | ||||||
| +	s32 err = 0; |  | ||||||
|   |  | ||||||
| -	brcmf_dbg(SCAN, "START ESCAN\n"); |  | ||||||
| +	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
| +	vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev); |  | ||||||
| +	if (!check_vif_up(vif)) |  | ||||||
| +		return -EIO; |  | ||||||
|   |  | ||||||
|  	if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { |  | ||||||
|  		brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status); |  | ||||||
| @@ -1102,6 +1105,8 @@ brcmf_cfg80211_escan(struct wiphy *wiphy |  | ||||||
|  	if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) |  | ||||||
|  		vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; |  | ||||||
|   |  | ||||||
| +	brcmf_dbg(SCAN, "START ESCAN\n"); |  | ||||||
| + |  | ||||||
|  	cfg->scan_request = request; |  | ||||||
|  	set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); |  | ||||||
|   |  | ||||||
| @@ -1121,31 +1126,12 @@ brcmf_cfg80211_escan(struct wiphy *wiphy |  | ||||||
|  	return 0; |  | ||||||
|   |  | ||||||
|  scan_out: |  | ||||||
| +	brcmf_err("scan error (%d)\n", err); |  | ||||||
|  	clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); |  | ||||||
|  	cfg->scan_request = NULL; |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static s32 |  | ||||||
| -brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) |  | ||||||
| -{ |  | ||||||
| -	struct brcmf_cfg80211_vif *vif; |  | ||||||
| -	s32 err = 0; |  | ||||||
| - |  | ||||||
| -	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
| -	vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev); |  | ||||||
| -	if (!check_vif_up(vif)) |  | ||||||
| -		return -EIO; |  | ||||||
| - |  | ||||||
| -	err = brcmf_cfg80211_escan(wiphy, vif, request); |  | ||||||
| - |  | ||||||
| -	if (err) |  | ||||||
| -		brcmf_err("scan error (%d)\n", err); |  | ||||||
| - |  | ||||||
| -	brcmf_dbg(TRACE, "Exit\n"); |  | ||||||
| -	return err; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
|  static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold) |  | ||||||
|  { |  | ||||||
|  	s32 err = 0; |  | ||||||
| @@ -1,86 +0,0 @@ | |||||||
| From bbf35414cd23a9d7230bfd7046e1e2c26020e7eb Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Wed, 8 Nov 2017 14:36:36 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: get rid of struct brcmf_cfg80211_info::active_scan |  | ||||||
|  field |  | ||||||
|  |  | ||||||
| The field struct brcmf_cfg80211_info::active_scan is set to true upon |  | ||||||
| initializing the driver instance, but it is never changed so simply |  | ||||||
| get rid of it. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 10 +--------- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h |  2 -- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c      |  5 +---- |  | ||||||
|  3 files changed, 2 insertions(+), 15 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| @@ -1043,7 +1043,6 @@ brcmf_do_escan(struct brcmf_if *ifp, str |  | ||||||
|  { |  | ||||||
|  	struct brcmf_cfg80211_info *cfg = ifp->drvr->config; |  | ||||||
|  	s32 err; |  | ||||||
| -	u32 passive_scan; |  | ||||||
|  	struct brcmf_scan_results *results; |  | ||||||
|  	struct escan_info *escan = &cfg->escan_info; |  | ||||||
|   |  | ||||||
| @@ -1051,13 +1050,7 @@ brcmf_do_escan(struct brcmf_if *ifp, str |  | ||||||
|  	escan->ifp = ifp; |  | ||||||
|  	escan->wiphy = cfg->wiphy; |  | ||||||
|  	escan->escan_state = WL_ESCAN_STATE_SCANNING; |  | ||||||
| -	passive_scan = cfg->active_scan ? 0 : 1; |  | ||||||
| -	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, |  | ||||||
| -				    passive_scan); |  | ||||||
| -	if (err) { |  | ||||||
| -		brcmf_err("error (%d)\n", err); |  | ||||||
| -		return err; |  | ||||||
| -	} |  | ||||||
| + |  | ||||||
|  	brcmf_scan_config_mpc(ifp, 0); |  | ||||||
|  	results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf; |  | ||||||
|  	results->version = 0; |  | ||||||
| @@ -5767,7 +5760,6 @@ static s32 wl_init_priv(struct brcmf_cfg |  | ||||||
|   |  | ||||||
|  	cfg->scan_request = NULL; |  | ||||||
|  	cfg->pwr_save = true; |  | ||||||
| -	cfg->active_scan = true;	/* we do active scan per default */ |  | ||||||
|  	cfg->dongle_up = false;		/* dongle is not up yet */ |  | ||||||
|  	err = brcmf_init_priv_mem(cfg); |  | ||||||
|  	if (err) |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h |  | ||||||
| @@ -283,7 +283,6 @@ struct brcmf_cfg80211_wowl { |  | ||||||
|   * @scan_status: scan activity on the dongle. |  | ||||||
|   * @pub: common driver information. |  | ||||||
|   * @channel: current channel. |  | ||||||
| - * @active_scan: current scan mode. |  | ||||||
|   * @int_escan_map: bucket map for which internal e-scan is done. |  | ||||||
|   * @ibss_starter: indicates this sta is ibss starter. |  | ||||||
|   * @pwr_save: indicate whether dongle to support power save mode. |  | ||||||
| @@ -316,7 +315,6 @@ struct brcmf_cfg80211_info { |  | ||||||
|  	unsigned long scan_status; |  | ||||||
|  	struct brcmf_pub *pub; |  | ||||||
|  	u32 channel; |  | ||||||
| -	bool active_scan; |  | ||||||
|  	u32 int_escan_map; |  | ||||||
|  	bool ibss_starter; |  | ||||||
|  	bool pwr_save; |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  | ||||||
| @@ -692,10 +692,7 @@ static s32 brcmf_p2p_escan(struct brcmf_ |  | ||||||
|   |  | ||||||
|  	/* determine the scan engine parameters */ |  | ||||||
|  	sparams->bss_type = DOT11_BSSTYPE_ANY; |  | ||||||
| -	if (p2p->cfg->active_scan) |  | ||||||
| -		sparams->scan_type = 0; |  | ||||||
| -	else |  | ||||||
| -		sparams->scan_type = 1; |  | ||||||
| +	sparams->scan_type = BRCMF_SCANTYPE_ACTIVE; |  | ||||||
|   |  | ||||||
|  	eth_broadcast_addr(sparams->bssid); |  | ||||||
|  	sparams->home_time = cpu_to_le32(P2PAPI_SCAN_HOME_TIME_MS); |  | ||||||
| @@ -1,55 +0,0 @@ | |||||||
| From bd99a3013bdc00f8fc7534c657b39616792b4467 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Wed, 8 Nov 2017 14:36:37 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: move configuration of probe request IEs |  | ||||||
|  |  | ||||||
| The configuration of the IEs for probe requests was done in a P2P |  | ||||||
| related function, which is not very obvious. Moving it to |  | ||||||
| .scan callback function, ie. brcmf_cfg80211_scan(). |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +++++ |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c      | 6 ++---- |  | ||||||
|  2 files changed, 7 insertions(+), 4 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| @@ -1108,6 +1108,11 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, |  | ||||||
|  	if (err) |  | ||||||
|  		goto scan_out; |  | ||||||
|   |  | ||||||
| +	err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG, |  | ||||||
| +				    request->ie, request->ie_len); |  | ||||||
| +	if (err) |  | ||||||
| +		goto scan_out; |  | ||||||
| + |  | ||||||
|  	err = brcmf_do_escan(vif->ifp, request); |  | ||||||
|  	if (err) |  | ||||||
|  		goto scan_out; |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  | ||||||
| @@ -881,7 +881,7 @@ int brcmf_p2p_scan_prep(struct wiphy *wi |  | ||||||
|  { |  | ||||||
|  	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |  | ||||||
|  	struct brcmf_p2p_info *p2p = &cfg->p2p; |  | ||||||
| -	int err = 0; |  | ||||||
| +	int err; |  | ||||||
|   |  | ||||||
|  	if (brcmf_p2p_scan_is_p2p_request(request)) { |  | ||||||
|  		/* find my listen channel */ |  | ||||||
| @@ -904,9 +904,7 @@ int brcmf_p2p_scan_prep(struct wiphy *wi |  | ||||||
|  		/* override .run_escan() callback. */ |  | ||||||
|  		cfg->escan_info.run = brcmf_p2p_run_escan; |  | ||||||
|  	} |  | ||||||
| -	err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG, |  | ||||||
| -				    request->ie, request->ie_len); |  | ||||||
| -	return err; |  | ||||||
| +	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| @@ -1,434 +0,0 @@ | |||||||
| From fdd0bd88ceaecf729db103ac8836af5805dd2dc1 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Chung-Hsien Hsu <stanley.hsu@cypress.com> |  | ||||||
| Date: Fri, 10 Nov 2017 17:27:15 +0800 |  | ||||||
| Subject: [PATCH] brcmfmac: add CLM download support |  | ||||||
|  |  | ||||||
| The firmware for brcmfmac devices includes information regarding |  | ||||||
| regulatory constraints. For certain devices this information is kept |  | ||||||
| separately in a binary form that needs to be downloaded to the device. |  | ||||||
| This patch adds support to download this so-called CLM blob file. It |  | ||||||
| uses the same naming scheme as the other firmware files with extension |  | ||||||
| of .clm_blob. |  | ||||||
|  |  | ||||||
| The CLM blob file is optional. If the file does not exist, the download |  | ||||||
| process will be bypassed. It will not affect the driver loading. |  | ||||||
|  |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  10 ++ |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/common.c  | 157 +++++++++++++++++++++ |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.c    |   2 + |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.h    |   2 + |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/fwil_types.h       |  31 ++++ |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/pcie.c    |  19 +++ |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    |  19 +++ |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  18 +++ |  | ||||||
|  8 files changed, 258 insertions(+) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  | ||||||
| @@ -71,6 +71,7 @@ struct brcmf_bus_dcmd { |  | ||||||
|   * @wowl_config: specify if dongle is configured for wowl when going to suspend |  | ||||||
|   * @get_ramsize: obtain size of device memory. |  | ||||||
|   * @get_memdump: obtain device memory dump in provided buffer. |  | ||||||
| + * @get_fwname: obtain firmware name. |  | ||||||
|   * |  | ||||||
|   * This structure provides an abstract interface towards the |  | ||||||
|   * bus specific driver. For control messages to common driver |  | ||||||
| @@ -87,6 +88,8 @@ struct brcmf_bus_ops { |  | ||||||
|  	void (*wowl_config)(struct device *dev, bool enabled); |  | ||||||
|  	size_t (*get_ramsize)(struct device *dev); |  | ||||||
|  	int (*get_memdump)(struct device *dev, void *data, size_t len); |  | ||||||
| +	int (*get_fwname)(struct device *dev, uint chip, uint chiprev, |  | ||||||
| +			  unsigned char *fw_name); |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|   |  | ||||||
| @@ -224,6 +227,13 @@ int brcmf_bus_get_memdump(struct brcmf_b |  | ||||||
|  	return bus->ops->get_memdump(bus->dev, data, len); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static inline |  | ||||||
| +int brcmf_bus_get_fwname(struct brcmf_bus *bus, uint chip, uint chiprev, |  | ||||||
| +			 unsigned char *fw_name) |  | ||||||
| +{ |  | ||||||
| +	return bus->ops->get_fwname(bus->dev, chip, chiprev, fw_name); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  /* |  | ||||||
|   * interface functions from common layer |  | ||||||
|   */ |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| @@ -18,6 +18,7 @@ |  | ||||||
|  #include <linux/string.h> |  | ||||||
|  #include <linux/netdevice.h> |  | ||||||
|  #include <linux/module.h> |  | ||||||
| +#include <linux/firmware.h> |  | ||||||
|  #include <brcmu_wifi.h> |  | ||||||
|  #include <brcmu_utils.h> |  | ||||||
|  #include "core.h" |  | ||||||
| @@ -28,6 +29,7 @@ |  | ||||||
|  #include "tracepoint.h" |  | ||||||
|  #include "common.h" |  | ||||||
|  #include "of.h" |  | ||||||
| +#include "firmware.h" |  | ||||||
|   |  | ||||||
|  MODULE_AUTHOR("Broadcom Corporation"); |  | ||||||
|  MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); |  | ||||||
| @@ -104,12 +106,140 @@ void brcmf_c_set_joinpref_default(struct |  | ||||||
|  		brcmf_err("Set join_pref error (%d)\n", err); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static int brcmf_c_download(struct brcmf_if *ifp, u16 flag, |  | ||||||
| +			    struct brcmf_dload_data_le *dload_buf, |  | ||||||
| +			    u32 len) |  | ||||||
| +{ |  | ||||||
| +	s32 err; |  | ||||||
| + |  | ||||||
| +	flag |= (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT); |  | ||||||
| +	dload_buf->flag = cpu_to_le16(flag); |  | ||||||
| +	dload_buf->dload_type = cpu_to_le16(DL_TYPE_CLM); |  | ||||||
| +	dload_buf->len = cpu_to_le32(len); |  | ||||||
| +	dload_buf->crc = cpu_to_le32(0); |  | ||||||
| +	len = sizeof(*dload_buf) + len - 1; |  | ||||||
| + |  | ||||||
| +	err = brcmf_fil_iovar_data_set(ifp, "clmload", dload_buf, len); |  | ||||||
| + |  | ||||||
| +	return err; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name) |  | ||||||
| +{ |  | ||||||
| +	struct brcmf_bus *bus = ifp->drvr->bus_if; |  | ||||||
| +	struct brcmf_rev_info *ri = &ifp->drvr->revinfo; |  | ||||||
| +	u8 fw_name[BRCMF_FW_NAME_LEN]; |  | ||||||
| +	u8 *ptr; |  | ||||||
| +	size_t len; |  | ||||||
| +	s32 err; |  | ||||||
| + |  | ||||||
| +	memset(fw_name, 0, BRCMF_FW_NAME_LEN); |  | ||||||
| +	err = brcmf_bus_get_fwname(bus, ri->chipnum, ri->chiprev, fw_name); |  | ||||||
| +	if (err) { |  | ||||||
| +		brcmf_err("get firmware name failed (%d)\n", err); |  | ||||||
| +		goto done; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	/* generate CLM blob file name */ |  | ||||||
| +	ptr = strrchr(fw_name, '.'); |  | ||||||
| +	if (!ptr) { |  | ||||||
| +		err = -ENOENT; |  | ||||||
| +		goto done; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	len = ptr - fw_name + 1; |  | ||||||
| +	if (len + strlen(".clm_blob") > BRCMF_FW_NAME_LEN) { |  | ||||||
| +		err = -E2BIG; |  | ||||||
| +	} else { |  | ||||||
| +		strlcpy(clm_name, fw_name, len); |  | ||||||
| +		strlcat(clm_name, ".clm_blob", BRCMF_FW_NAME_LEN); |  | ||||||
| +	} |  | ||||||
| +done: |  | ||||||
| +	return err; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) |  | ||||||
| +{ |  | ||||||
| +	struct device *dev = ifp->drvr->bus_if->dev; |  | ||||||
| +	struct brcmf_dload_data_le *chunk_buf; |  | ||||||
| +	const struct firmware *clm = NULL; |  | ||||||
| +	u8 clm_name[BRCMF_FW_NAME_LEN]; |  | ||||||
| +	u32 chunk_len; |  | ||||||
| +	u32 datalen; |  | ||||||
| +	u32 cumulative_len; |  | ||||||
| +	u16 dl_flag = DL_BEGIN; |  | ||||||
| +	u32 status; |  | ||||||
| +	s32 err; |  | ||||||
| + |  | ||||||
| +	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
| + |  | ||||||
| +	memset(clm_name, 0, BRCMF_FW_NAME_LEN); |  | ||||||
| +	err = brcmf_c_get_clm_name(ifp, clm_name); |  | ||||||
| +	if (err) { |  | ||||||
| +		brcmf_err("get CLM blob file name failed (%d)\n", err); |  | ||||||
| +		return err; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	err = request_firmware(&clm, clm_name, dev); |  | ||||||
| +	if (err) { |  | ||||||
| +		if (err == -ENOENT) { |  | ||||||
| +			brcmf_dbg(INFO, "continue with CLM data currently present in firmware\n"); |  | ||||||
| +			return 0; |  | ||||||
| +		} |  | ||||||
| +		brcmf_err("request CLM blob file failed (%d)\n", err); |  | ||||||
| +		return err; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL); |  | ||||||
| +	if (!chunk_buf) { |  | ||||||
| +		err = -ENOMEM; |  | ||||||
| +		goto done; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	datalen = clm->size; |  | ||||||
| +	cumulative_len = 0; |  | ||||||
| +	do { |  | ||||||
| +		if (datalen > MAX_CHUNK_LEN) { |  | ||||||
| +			chunk_len = MAX_CHUNK_LEN; |  | ||||||
| +		} else { |  | ||||||
| +			chunk_len = datalen; |  | ||||||
| +			dl_flag |= DL_END; |  | ||||||
| +		} |  | ||||||
| +		memcpy(chunk_buf->data, clm->data + cumulative_len, chunk_len); |  | ||||||
| + |  | ||||||
| +		err = brcmf_c_download(ifp, dl_flag, chunk_buf, chunk_len); |  | ||||||
| + |  | ||||||
| +		dl_flag &= ~DL_BEGIN; |  | ||||||
| + |  | ||||||
| +		cumulative_len += chunk_len; |  | ||||||
| +		datalen -= chunk_len; |  | ||||||
| +	} while ((datalen > 0) && (err == 0)); |  | ||||||
| + |  | ||||||
| +	if (err) { |  | ||||||
| +		brcmf_err("clmload (%zu byte file) failed (%d); ", |  | ||||||
| +			  clm->size, err); |  | ||||||
| +		/* Retrieve clmload_status and print */ |  | ||||||
| +		err = brcmf_fil_iovar_int_get(ifp, "clmload_status", &status); |  | ||||||
| +		if (err) |  | ||||||
| +			brcmf_err("get clmload_status failed (%d)\n", err); |  | ||||||
| +		else |  | ||||||
| +			brcmf_dbg(INFO, "clmload_status=%d\n", status); |  | ||||||
| +		err = -EIO; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	kfree(chunk_buf); |  | ||||||
| +done: |  | ||||||
| +	release_firmware(clm); |  | ||||||
| +	return err; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) |  | ||||||
|  { |  | ||||||
|  	s8 eventmask[BRCMF_EVENTING_MASK_LEN]; |  | ||||||
|  	u8 buf[BRCMF_DCMD_SMLEN]; |  | ||||||
|  	struct brcmf_rev_info_le revinfo; |  | ||||||
|  	struct brcmf_rev_info *ri; |  | ||||||
| +	char *clmver; |  | ||||||
|  	char *ptr; |  | ||||||
|  	s32 err; |  | ||||||
|   |  | ||||||
| @@ -148,6 +278,13 @@ int brcmf_c_preinit_dcmds(struct brcmf_i |  | ||||||
|  	} |  | ||||||
|  	ri->result = err; |  | ||||||
|   |  | ||||||
| +	/* Do any CLM downloading */ |  | ||||||
| +	err = brcmf_c_process_clm_blob(ifp); |  | ||||||
| +	if (err < 0) { |  | ||||||
| +		brcmf_err("download CLM blob file failed, %d\n", err); |  | ||||||
| +		goto done; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	/* query for 'ver' to get version info from firmware */ |  | ||||||
|  	memset(buf, 0, sizeof(buf)); |  | ||||||
|  	strcpy(buf, "ver"); |  | ||||||
| @@ -167,6 +304,26 @@ int brcmf_c_preinit_dcmds(struct brcmf_i |  | ||||||
|  	ptr = strrchr(buf, ' ') + 1; |  | ||||||
|  	strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver)); |  | ||||||
|   |  | ||||||
| +	/* Query for 'clmver' to get CLM version info from firmware */ |  | ||||||
| +	memset(buf, 0, sizeof(buf)); |  | ||||||
| +	err = brcmf_fil_iovar_data_get(ifp, "clmver", buf, sizeof(buf)); |  | ||||||
| +	if (err) { |  | ||||||
| +		brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err); |  | ||||||
| +	} else { |  | ||||||
| +		clmver = (char *)buf; |  | ||||||
| +		/* store CLM version for adding it to revinfo debugfs file */ |  | ||||||
| +		memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver)); |  | ||||||
| + |  | ||||||
| +		/* Replace all newline/linefeed characters with space |  | ||||||
| +		 * character |  | ||||||
| +		 */ |  | ||||||
| +		ptr = clmver; |  | ||||||
| +		while ((ptr = strnchr(ptr, '\n', sizeof(buf))) != NULL) |  | ||||||
| +			*ptr = ' '; |  | ||||||
| + |  | ||||||
| +		brcmf_dbg(INFO, "CLM version = %s\n", clmver); |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	/* set mpc */ |  | ||||||
|  	err = brcmf_fil_iovar_int_set(ifp, "mpc", 1); |  | ||||||
|  	if (err) { |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| @@ -1009,6 +1009,8 @@ static int brcmf_revinfo_read(struct seq |  | ||||||
|  	seq_printf(s, "anarev: %u\n", ri->anarev); |  | ||||||
|  	seq_printf(s, "nvramrev: %08x\n", ri->nvramrev); |  | ||||||
|   |  | ||||||
| +	seq_printf(s, "clmver: %s\n", bus_if->drvr->clmver); |  | ||||||
| + |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h |  | ||||||
| @@ -141,6 +141,8 @@ struct brcmf_pub { |  | ||||||
|  	struct notifier_block inetaddr_notifier; |  | ||||||
|  	struct notifier_block inet6addr_notifier; |  | ||||||
|  	struct brcmf_mp_device *settings; |  | ||||||
| + |  | ||||||
| +	u8 clmver[BRCMF_DCMD_SMLEN]; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  /* forward declarations */ |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h |  | ||||||
| @@ -155,6 +155,21 @@ |  | ||||||
|  #define BRCMF_MFP_CAPABLE		1 |  | ||||||
|  #define BRCMF_MFP_REQUIRED		2 |  | ||||||
|   |  | ||||||
| +/* MAX_CHUNK_LEN is the maximum length for data passing to firmware in each |  | ||||||
| + * ioctl. It is relatively small because firmware has small maximum size input |  | ||||||
| + * playload restriction for ioctls. |  | ||||||
| + */ |  | ||||||
| +#define MAX_CHUNK_LEN			1400 |  | ||||||
| + |  | ||||||
| +#define DLOAD_HANDLER_VER		1	/* Downloader version */ |  | ||||||
| +#define DLOAD_FLAG_VER_MASK		0xf000	/* Downloader version mask */ |  | ||||||
| +#define DLOAD_FLAG_VER_SHIFT		12	/* Downloader version shift */ |  | ||||||
| + |  | ||||||
| +#define DL_BEGIN			0x0002 |  | ||||||
| +#define DL_END				0x0004 |  | ||||||
| + |  | ||||||
| +#define DL_TYPE_CLM			2 |  | ||||||
| + |  | ||||||
|  /* join preference types for join_pref iovar */ |  | ||||||
|  enum brcmf_join_pref_types { |  | ||||||
|  	BRCMF_JOIN_PREF_RSSI = 1, |  | ||||||
| @@ -827,6 +842,22 @@ struct brcmf_pno_macaddr_le { |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
| + * struct brcmf_dload_data_le - data passing to firmware for downloading |  | ||||||
| + * @flag: flags related to download data. |  | ||||||
| + * @dload_type: type of download data. |  | ||||||
| + * @len: length in bytes of download data. |  | ||||||
| + * @crc: crc of download data. |  | ||||||
| + * @data: download data. |  | ||||||
| + */ |  | ||||||
| +struct brcmf_dload_data_le { |  | ||||||
| +	__le16 flag; |  | ||||||
| +	__le16 dload_type; |  | ||||||
| +	__le32 len; |  | ||||||
| +	__le32 crc; |  | ||||||
| +	u8 data[1]; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +/** |  | ||||||
|   * struct brcmf_pno_bssid_le - bssid configuration for PNO scan. |  | ||||||
|   * |  | ||||||
|   * @bssid: BSS network identifier. |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| @@ -1350,6 +1350,24 @@ static int brcmf_pcie_get_memdump(struct |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static int brcmf_pcie_get_fwname(struct device *dev, u32 chip, u32 chiprev, |  | ||||||
| +				 u8 *fw_name) |  | ||||||
| +{ |  | ||||||
| +	struct brcmf_bus *bus_if = dev_get_drvdata(dev); |  | ||||||
| +	struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie; |  | ||||||
| +	struct brcmf_pciedev_info *devinfo = buspub->devinfo; |  | ||||||
| +	int ret = 0; |  | ||||||
| + |  | ||||||
| +	if (devinfo->fw_name[0] != '\0') |  | ||||||
| +		strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN); |  | ||||||
| +	else |  | ||||||
| +		ret = brcmf_fw_map_chip_to_name(chip, chiprev, |  | ||||||
| +						brcmf_pcie_fwnames, |  | ||||||
| +						ARRAY_SIZE(brcmf_pcie_fwnames), |  | ||||||
| +						fw_name, NULL); |  | ||||||
| + |  | ||||||
| +	return ret; |  | ||||||
| +} |  | ||||||
|   |  | ||||||
|  static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { |  | ||||||
|  	.txdata = brcmf_pcie_tx, |  | ||||||
| @@ -1359,6 +1377,7 @@ static const struct brcmf_bus_ops brcmf_ |  | ||||||
|  	.wowl_config = brcmf_pcie_wowl_config, |  | ||||||
|  	.get_ramsize = brcmf_pcie_get_ramsize, |  | ||||||
|  	.get_memdump = brcmf_pcie_get_memdump, |  | ||||||
| +	.get_fwname = brcmf_pcie_get_fwname, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -3985,6 +3985,24 @@ brcmf_sdio_watchdog(unsigned long data) |  | ||||||
|  	} |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static int brcmf_sdio_get_fwname(struct device *dev, u32 chip, u32 chiprev, |  | ||||||
| +				 u8 *fw_name) |  | ||||||
| +{ |  | ||||||
| +	struct brcmf_bus *bus_if = dev_get_drvdata(dev); |  | ||||||
| +	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |  | ||||||
| +	int ret = 0; |  | ||||||
| + |  | ||||||
| +	if (sdiodev->fw_name[0] != '\0') |  | ||||||
| +		strlcpy(fw_name, sdiodev->fw_name, BRCMF_FW_NAME_LEN); |  | ||||||
| +	else |  | ||||||
| +		ret = brcmf_fw_map_chip_to_name(chip, chiprev, |  | ||||||
| +						brcmf_sdio_fwnames, |  | ||||||
| +						ARRAY_SIZE(brcmf_sdio_fwnames), |  | ||||||
| +						fw_name, NULL); |  | ||||||
| + |  | ||||||
| +	return ret; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { |  | ||||||
|  	.stop = brcmf_sdio_bus_stop, |  | ||||||
|  	.preinit = brcmf_sdio_bus_preinit, |  | ||||||
| @@ -3995,6 +4013,7 @@ static const struct brcmf_bus_ops brcmf_ |  | ||||||
|  	.wowl_config = brcmf_sdio_wowl_config, |  | ||||||
|  	.get_ramsize = brcmf_sdio_bus_get_ramsize, |  | ||||||
|  	.get_memdump = brcmf_sdio_bus_get_memdump, |  | ||||||
| +	.get_fwname = brcmf_sdio_get_fwname, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  static void brcmf_sdio_firmware_callback(struct device *dev, int err, |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| @@ -1128,12 +1128,30 @@ static void brcmf_usb_wowl_config(struct |  | ||||||
|  		device_set_wakeup_enable(devinfo->dev, false); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static int brcmf_usb_get_fwname(struct device *dev, u32 chip, u32 chiprev, |  | ||||||
| +				u8 *fw_name) |  | ||||||
| +{ |  | ||||||
| +	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |  | ||||||
| +	int ret = 0; |  | ||||||
| + |  | ||||||
| +	if (devinfo->fw_name[0] != '\0') |  | ||||||
| +		strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN); |  | ||||||
| +	else |  | ||||||
| +		ret = brcmf_fw_map_chip_to_name(chip, chiprev, |  | ||||||
| +						brcmf_usb_fwnames, |  | ||||||
| +						ARRAY_SIZE(brcmf_usb_fwnames), |  | ||||||
| +						fw_name, NULL); |  | ||||||
| + |  | ||||||
| +	return ret; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static const struct brcmf_bus_ops brcmf_usb_bus_ops = { |  | ||||||
|  	.txdata = brcmf_usb_tx, |  | ||||||
|  	.stop = brcmf_usb_down, |  | ||||||
|  	.txctl = brcmf_usb_tx_ctlpkt, |  | ||||||
|  	.rxctl = brcmf_usb_rx_ctlpkt, |  | ||||||
|  	.wowl_config = brcmf_usb_wowl_config, |  | ||||||
| +	.get_fwname = brcmf_usb_get_fwname, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo) |  | ||||||
| @@ -1,37 +0,0 @@ | |||||||
| From 5c3de777bdaf48bd0cfb43097c0d0fb85056cab7 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Sat, 25 Nov 2017 21:39:25 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: change driver unbind order of the sdio function |  | ||||||
|  devices |  | ||||||
|  |  | ||||||
| In the function brcmf_sdio_firmware_callback() the driver is |  | ||||||
| unbound from the sdio function devices in the error path. |  | ||||||
| However, the order in which it is done resulted in a use-after-free |  | ||||||
| issue (see brcmf_ops_sdio_remove() in bcmsdh.c). Hence change |  | ||||||
| the order and first unbind sdio function #2 device and then |  | ||||||
| unbind sdio function #1 device. |  | ||||||
|  |  | ||||||
| Cc: stable@vger.kernel.org # v4.12.x |  | ||||||
| Fixes: 7a51461fc2da ("brcmfmac: unbind all devices upon failure in firmware callback") |  | ||||||
| Reported-by: Stefan Wahren <stefan.wahren@i2se.com> |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +- |  | ||||||
|  1 file changed, 1 insertion(+), 1 deletion(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -4121,8 +4121,8 @@ release: |  | ||||||
|  	sdio_release_host(sdiodev->func[1]); |  | ||||||
|  fail: |  | ||||||
|  	brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err); |  | ||||||
| -	device_release_driver(dev); |  | ||||||
|  	device_release_driver(&sdiodev->func[2]->dev); |  | ||||||
| +	device_release_driver(dev); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) |  | ||||||
| @@ -1,33 +0,0 @@ | |||||||
| From 51ef7925e10688c57186d438e784532e063492e4 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |  | ||||||
| Date: Thu, 23 Nov 2017 17:57:04 +0200 |  | ||||||
| Subject: [PATCH] brcmfmac: Avoid build error with make W=1 |  | ||||||
|  |  | ||||||
| When I run make W=1 on gcc (Debian 7.2.0-16) 7.2.0 I got an error for |  | ||||||
| the first run, all next ones are okay. |  | ||||||
|  |  | ||||||
|   CC [M]  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.o |  | ||||||
| drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:2078: error: Cannot parse struct or union! |  | ||||||
| scripts/Makefile.build:310: recipe for target 'drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.o' failed |  | ||||||
|  |  | ||||||
| Seems like something happened with W=1 and wrong kernel doc format. |  | ||||||
| As a quick fix remove dubious /** in the code. |  | ||||||
|  |  | ||||||
| Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |  | ||||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +- |  | ||||||
|  1 file changed, 1 insertion(+), 1 deletion(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -2070,7 +2070,7 @@ static int brcmf_sdio_txpkt_hdalign(stru |  | ||||||
|  	return head_pad; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -/** |  | ||||||
| +/* |  | ||||||
|   * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for |  | ||||||
|   * bus layer usage. |  | ||||||
|   */ |  | ||||||
| @@ -1,40 +0,0 @@ | |||||||
| From cc124d5cc8d81985c3511892d7a6d546552ff754 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Wright Feng <wright.feng@cypress.com> |  | ||||||
| Date: Tue, 16 Jan 2018 17:26:50 +0800 |  | ||||||
| Subject: [PATCH] brcmfmac: fix CLM load error for legacy chips when user |  | ||||||
|  helper is enabled |  | ||||||
|  |  | ||||||
| For legacy chips without CLM blob files, kernel with user helper function |  | ||||||
| returns -EAGAIN when we request_firmware(), and then driver got failed |  | ||||||
| when bringing up legacy chips. We expect the CLM blob file for legacy chip |  | ||||||
| is not existence in firmware path, but the -ENOENT error is transferred to |  | ||||||
| -EAGAIN in firmware_class.c with user helper. |  | ||||||
| Because of that, we continue with CLM data currently present in firmware |  | ||||||
| if getting error from doing request_firmware(). |  | ||||||
|  |  | ||||||
| Cc: stable@vger.kernel.org # v4.15.y |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Wright Feng <wright.feng@cypress.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 9 +++------ |  | ||||||
|  1 file changed, 3 insertions(+), 6 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| @@ -182,12 +182,9 @@ static int brcmf_c_process_clm_blob(stru |  | ||||||
|   |  | ||||||
|  	err = request_firmware(&clm, clm_name, dev); |  | ||||||
|  	if (err) { |  | ||||||
| -		if (err == -ENOENT) { |  | ||||||
| -			brcmf_dbg(INFO, "continue with CLM data currently present in firmware\n"); |  | ||||||
| -			return 0; |  | ||||||
| -		} |  | ||||||
| -		brcmf_err("request CLM blob file failed (%d)\n", err); |  | ||||||
| -		return err; |  | ||||||
| +		brcmf_info("no clm_blob available(err=%d), device may have limited channels available\n", |  | ||||||
| +			   err); |  | ||||||
| +		return 0; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL); |  | ||||||
| @@ -1,103 +0,0 @@ | |||||||
| From 9df7ddc3ed25b7d3473f117a0680b9418adb5753 Mon Sep 17 00:00:00 2001 |  | ||||||
| Message-Id: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net> |  | ||||||
| From: Matthias Schiffer <mschiffer@universe-factory.net> |  | ||||||
| Date: Mon, 27 Nov 2017 18:56:22 +0100 |  | ||||||
| Subject: [PATCH 1/2] ath9k: move spectral scan support under a separate config |  | ||||||
|  symbol |  | ||||||
|  |  | ||||||
| At the moment, spectral scan support, and with it RELAY, is always enabled |  | ||||||
| with ATH9K[_HTC]_DEBUGFS. Spectral scan support is currently the only user |  | ||||||
| of RELAY in ath9k, and it unconditionally reserves a relay channel. |  | ||||||
|  |  | ||||||
| Having debugfs support in ath9k is often useful even on very small embedded |  | ||||||
| routers, where we'd rather like to avoid the code size and RAM usage of the |  | ||||||
| relay support. |  | ||||||
|  |  | ||||||
| Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/ath/ath9k/Kconfig           | 14 ++++++++++---- |  | ||||||
|  drivers/net/wireless/ath/ath9k/Makefile          |  4 ++-- |  | ||||||
|  drivers/net/wireless/ath/ath9k/common-spectral.h |  4 ++-- |  | ||||||
|  3 files changed, 14 insertions(+), 8 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath9k/Kconfig |  | ||||||
| +++ b/drivers/net/wireless/ath/ath9k/Kconfig |  | ||||||
| @@ -64,13 +64,12 @@ config ATH9K_DEBUGFS |  | ||||||
|  	depends on ATH9K && DEBUG_FS |  | ||||||
|  	select MAC80211_DEBUGFS |  | ||||||
|  	select ATH9K_COMMON_DEBUG |  | ||||||
| -	depends on RELAY |  | ||||||
|  	---help--- |  | ||||||
|  	  Say Y, if you need access to ath9k's statistics for |  | ||||||
|  	  interrupts, rate control, etc. |  | ||||||
|   |  | ||||||
| -	  Also required for changing debug message flags at run time. |  | ||||||
| -	  As well as access to the FFT/spectral data and TX99. |  | ||||||
| +	  Also required for changing debug message flags at run time and for |  | ||||||
| +	  TX99. |  | ||||||
|   |  | ||||||
|  config ATH9K_STATION_STATISTICS |  | ||||||
|  	bool "Detailed station statistics" |  | ||||||
| @@ -181,7 +180,6 @@ config ATH9K_HTC_DEBUGFS |  | ||||||
|  	bool "Atheros ath9k_htc debugging" |  | ||||||
|  	depends on ATH9K_HTC && DEBUG_FS |  | ||||||
|  	select ATH9K_COMMON_DEBUG |  | ||||||
| -	depends on RELAY |  | ||||||
|  	---help--- |  | ||||||
|  	  Say Y, if you need access to ath9k_htc's statistics. |  | ||||||
|  	  As well as access to the FFT/spectral data. |  | ||||||
| @@ -197,3 +195,11 @@ config ATH9K_HWRNG |  | ||||||
|   |  | ||||||
|  	  Say Y, feeds the entropy directly from the WiFi driver to the input |  | ||||||
|  	  pool. |  | ||||||
| + |  | ||||||
| +config ATH9K_COMMON_SPECTRAL |  | ||||||
| +	bool "Atheros ath9k/ath9k_htc spectral scan support" |  | ||||||
| +	depends on ATH9K_DEBUGFS || ATH9K_HTC_DEBUGFS |  | ||||||
| +	depends on RELAY |  | ||||||
| +	default n |  | ||||||
| +	---help--- |  | ||||||
| +	  Say Y to enable access to the FFT/spectral data via debugfs. |  | ||||||
| --- a/drivers/net/wireless/ath/ath9k/Makefile |  | ||||||
| +++ b/drivers/net/wireless/ath/ath9k/Makefile |  | ||||||
| @@ -61,8 +61,8 @@ ath9k_common-y:=	common.o \ |  | ||||||
|  			common-init.o \ |  | ||||||
|  			common-beacon.o \ |  | ||||||
|   |  | ||||||
| -ath9k_common-$(CPTCFG_ATH9K_COMMON_DEBUG) += common-debug.o \ |  | ||||||
| -					     common-spectral.o |  | ||||||
| +ath9k_common-$(CPTCFG_ATH9K_COMMON_DEBUG) += common-debug.o |  | ||||||
| +ath9k_common-$(CPTCFG_ATH9K_COMMON_SPECTRAL) += common-spectral.o |  | ||||||
|   |  | ||||||
|  ath9k_htc-y +=	htc_hst.o \ |  | ||||||
|  		hif_usb.o \ |  | ||||||
| --- a/drivers/net/wireless/ath/ath9k/common-spectral.h |  | ||||||
| +++ b/drivers/net/wireless/ath/ath9k/common-spectral.h |  | ||||||
| @@ -151,7 +151,7 @@ static inline u8 spectral_bitmap_weight( |  | ||||||
|  	return bins[0] & 0x3f; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -#ifdef CPTCFG_ATH9K_COMMON_DEBUG |  | ||||||
| +#ifdef CPTCFG_ATH9K_COMMON_SPECTRAL |  | ||||||
|  void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy); |  | ||||||
|  void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv); |  | ||||||
|   |  | ||||||
| @@ -183,6 +183,6 @@ static inline int ath_cmn_process_fft(st |  | ||||||
|  { |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
| -#endif /* CPTCFG_ATH9K_COMMON_DEBUG */ |  | ||||||
| +#endif /* CPTCFG_ATH9K_COMMON_SPECTRAL */ |  | ||||||
|   |  | ||||||
|  #endif /* SPECTRAL_H */ |  | ||||||
| --- a/local-symbols |  | ||||||
| +++ b/local-symbols |  | ||||||
| @@ -116,6 +116,7 @@ ATH9K_PCOEM= |  | ||||||
|  ATH9K_HTC= |  | ||||||
|  ATH9K_HTC_DEBUGFS= |  | ||||||
|  ATH9K_HWRNG= |  | ||||||
| +ATH9K_COMMON_SPECTRAL= |  | ||||||
|  CARL9170= |  | ||||||
|  CARL9170_LEDS= |  | ||||||
|  CARL9170_DEBUGFS= |  | ||||||
| @@ -1,91 +0,0 @@ | |||||||
| From 42e01cb9cb109fb0bb4743f6c54d6aa67ac39b61 Mon Sep 17 00:00:00 2001 |  | ||||||
| Message-Id: <42e01cb9cb109fb0bb4743f6c54d6aa67ac39b61.1515610034.git.mschiffer@universe-factory.net> |  | ||||||
| In-Reply-To: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net> |  | ||||||
| References: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net> |  | ||||||
| From: Matthias Schiffer <mschiffer@universe-factory.net> |  | ||||||
| Date: Mon, 27 Nov 2017 18:56:23 +0100 |  | ||||||
| Subject: [PATCH 2/2] ath10k: move spectral scan support under a separate |  | ||||||
|  config symbol |  | ||||||
|  |  | ||||||
| At the moment, spectral scan support, and with it RELAY, is always enabled |  | ||||||
| with ATH10K_DEBUGFS. Spectral scan support is currently the only user of |  | ||||||
| RELAY in ath10k, and it unconditionally reserves a relay channel. |  | ||||||
|  |  | ||||||
| Having debugfs support in ath10k is often useful even on very small |  | ||||||
| embedded routers, where we'd rather like to avoid the code size and RAM |  | ||||||
| usage of the relay support. While ath10k-based devices usually have more |  | ||||||
| resources than ath9k-based ones, it makes sense to keep the configuration |  | ||||||
| symmetric to ath9k, so the same base kernel without RELAY can be used for |  | ||||||
| both ath9k and ath10k hardware. |  | ||||||
|  |  | ||||||
| Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/ath/ath10k/Kconfig    | 9 ++++++++- |  | ||||||
|  drivers/net/wireless/ath/ath10k/Makefile   | 2 +- |  | ||||||
|  drivers/net/wireless/ath/ath10k/spectral.h | 4 ++-- |  | ||||||
|  3 files changed, 11 insertions(+), 4 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/Kconfig |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/Kconfig |  | ||||||
| @@ -51,12 +51,19 @@ config ATH10K_DEBUG |  | ||||||
|  config ATH10K_DEBUGFS |  | ||||||
|  	bool "Atheros ath10k debugfs support" |  | ||||||
|  	depends on ATH10K && DEBUG_FS |  | ||||||
| -	depends on RELAY |  | ||||||
|  	---help--- |  | ||||||
|  	  Enabled debugfs support |  | ||||||
|   |  | ||||||
|  	  If unsure, say Y to make it easier to debug problems. |  | ||||||
|   |  | ||||||
| +config ATH10K_SPECTRAL |  | ||||||
| +	bool "Atheros ath10k spectral scan support" |  | ||||||
| +	depends on ATH10K_DEBUGFS |  | ||||||
| +	depends on RELAY |  | ||||||
| +	default n |  | ||||||
| +	---help--- |  | ||||||
| +	  Say Y to enable access to the FFT/spectral data via debugfs. |  | ||||||
| + |  | ||||||
|  config ATH10K_TRACING |  | ||||||
|  	depends on !KERNEL_3_4 |  | ||||||
|  	bool "Atheros ath10k tracing support" |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/Makefile |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/Makefile |  | ||||||
| @@ -14,7 +14,7 @@ ath10k_core-y += mac.o \ |  | ||||||
|  		 p2p.o \ |  | ||||||
|  		 swap.o |  | ||||||
|   |  | ||||||
| -ath10k_core-$(CPTCFG_ATH10K_DEBUGFS) += spectral.o |  | ||||||
| +ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += spectral.o |  | ||||||
|  ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o |  | ||||||
|  ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o |  | ||||||
|  ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/spectral.h |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/spectral.h |  | ||||||
| @@ -44,7 +44,7 @@ enum ath10k_spectral_mode { |  | ||||||
|  	SPECTRAL_MANUAL, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| -#ifdef CPTCFG_ATH10K_DEBUGFS |  | ||||||
| +#ifdef CPTCFG_ATH10K_SPECTRAL |  | ||||||
|   |  | ||||||
|  int ath10k_spectral_process_fft(struct ath10k *ar, |  | ||||||
|  				struct wmi_phyerr_ev_arg *phyerr, |  | ||||||
| @@ -85,6 +85,6 @@ static inline void ath10k_spectral_destr |  | ||||||
|  { |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -#endif /* CPTCFG_ATH10K_DEBUGFS */ |  | ||||||
| +#endif /* CPTCFG_ATH10K_SPECTRAL */ |  | ||||||
|   |  | ||||||
|  #endif /* SPECTRAL_H */ |  | ||||||
| --- a/local-symbols |  | ||||||
| +++ b/local-symbols |  | ||||||
| @@ -140,6 +140,7 @@ ATH10K_SDIO= |  | ||||||
|  ATH10K_USB= |  | ||||||
|  ATH10K_DEBUG= |  | ||||||
|  ATH10K_DEBUGFS= |  | ||||||
| +ATH10K_SPECTRAL= |  | ||||||
|  ATH10K_THERMAL= |  | ||||||
|  ATH10K_TRACING= |  | ||||||
|  ATH10K_DFS_CERTIFIED= |  | ||||||
| @@ -1,25 +0,0 @@ | |||||||
| From: Felix Fietkau <nbd@nbd.name> |  | ||||||
| Date: Wed, 17 Jan 2018 11:11:17 +0100 |  | ||||||
| Subject: [PATCH] ath9k: discard undersized packets |  | ||||||
|  |  | ||||||
| Sometimes the hardware will push small packets that trigger a WARN_ON |  | ||||||
| in mac80211. Discard them early to avoid this issue. |  | ||||||
|  |  | ||||||
| Reported-by: Stijn Tintel <stijn@linux-ipv6.be> |  | ||||||
| Signed-off-by: Felix Fietkau <nbd@nbd.name> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath9k/recv.c |  | ||||||
| +++ b/drivers/net/wireless/ath/ath9k/recv.c |  | ||||||
| @@ -826,9 +826,9 @@ static int ath9k_rx_skb_preprocess(struc |  | ||||||
|  	sc->rx.discard_next = false; |  | ||||||
|   |  | ||||||
|  	/* |  | ||||||
| -	 * Discard zero-length packets. |  | ||||||
| +	 * Discard zero-length packets and packets smaller than an ACK |  | ||||||
|  	 */ |  | ||||||
| -	if (!rx_stats->rs_datalen) { |  | ||||||
| +	if (rx_stats->rs_datalen < 10) { |  | ||||||
|  		RX_STAT_INC(rx_len_err); |  | ||||||
|  		goto corrupt; |  | ||||||
|  	} |  | ||||||
| @@ -1,39 +0,0 @@ | |||||||
| From 1fd3ae124d5e675f57cf7e3c601fb8f7712e0329 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Mon, 13 Nov 2017 21:35:38 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Fix parameter order in brcmf_sdiod_f0_writeb() |  | ||||||
|  |  | ||||||
| All the other IO functions are the other way round in this |  | ||||||
| driver. Make this one match. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 ++++---- |  | ||||||
|  1 file changed, 4 insertions(+), 4 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -230,8 +230,8 @@ void brcmf_sdiod_change_state(struct brc |  | ||||||
|  	sdiodev->state = state; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, |  | ||||||
| -					uint regaddr, u8 byte) |  | ||||||
| +static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte, |  | ||||||
| +					uint regaddr) |  | ||||||
|  { |  | ||||||
|  	int err_ret; |  | ||||||
|   |  | ||||||
| @@ -269,8 +269,8 @@ static int brcmf_sdiod_request_data(stru |  | ||||||
|  			if (fn) |  | ||||||
|  				sdio_writeb(func, *(u8 *)data, addr, &ret); |  | ||||||
|  			else |  | ||||||
| -				ret = brcmf_sdiod_f0_writeb(func, addr, |  | ||||||
| -							    *(u8 *)data); |  | ||||||
| +				ret = brcmf_sdiod_f0_writeb(func, *(u8 *)data, |  | ||||||
| +							    addr); |  | ||||||
|  		} else { |  | ||||||
|  			if (fn) |  | ||||||
|  				*(u8 *)data = sdio_readb(func, addr, &ret); |  | ||||||
| @@ -1,105 +0,0 @@ | |||||||
| From 1e6f676f43aa4270ebc5cff8e32a55f72362e042 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Mon, 13 Nov 2017 21:35:39 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Register sizes on hardware are not dependent on |  | ||||||
|  compiler types |  | ||||||
|  |  | ||||||
| The 4 IO functions in this patch are incorrect as they use compiler types |  | ||||||
| to determine how many bytes to send to the hardware. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 22 +++++++++++----------- |  | ||||||
|  1 file changed, 11 insertions(+), 11 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -264,7 +264,7 @@ static int brcmf_sdiod_request_data(stru |  | ||||||
|  	func = sdiodev->func[fn]; |  | ||||||
|   |  | ||||||
|  	switch (regsz) { |  | ||||||
| -	case sizeof(u8): |  | ||||||
| +	case 1: |  | ||||||
|  		if (write) { |  | ||||||
|  			if (fn) |  | ||||||
|  				sdio_writeb(func, *(u8 *)data, addr, &ret); |  | ||||||
| @@ -278,13 +278,13 @@ static int brcmf_sdiod_request_data(stru |  | ||||||
|  				*(u8 *)data = sdio_f0_readb(func, addr, &ret); |  | ||||||
|  		} |  | ||||||
|  		break; |  | ||||||
| -	case sizeof(u16): |  | ||||||
| +	case 2: |  | ||||||
|  		if (write) |  | ||||||
|  			sdio_writew(func, *(u16 *)data, addr, &ret); |  | ||||||
|  		else |  | ||||||
|  			*(u16 *)data = sdio_readw(func, addr, &ret); |  | ||||||
|  		break; |  | ||||||
| -	case sizeof(u32): |  | ||||||
| +	case 4: |  | ||||||
|  		if (write) |  | ||||||
|  			sdio_writel(func, *(u32 *)data, addr, &ret); |  | ||||||
|  		else |  | ||||||
| @@ -368,7 +368,7 @@ brcmf_sdiod_set_sbaddr_window(struct brc |  | ||||||
|  	for (i = 0; i < 3; i++) { |  | ||||||
|  		err = brcmf_sdiod_regrw_helper(sdiodev, |  | ||||||
|  					       SBSDIO_FUNC1_SBADDRLOW + i, |  | ||||||
| -					       sizeof(u8), &addr[i], true); |  | ||||||
| +					       1, &addr[i], true); |  | ||||||
|  		if (err) { |  | ||||||
|  			brcmf_err("failed at addr: 0x%0x\n", |  | ||||||
|  				  SBSDIO_FUNC1_SBADDRLOW + i); |  | ||||||
| @@ -407,7 +407,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr:0x%08x\n", addr); |  | ||||||
| -	retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, |  | ||||||
| +	retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data, |  | ||||||
|  					  false); |  | ||||||
|  	brcmf_dbg(SDIO, "data:0x%02x\n", data); |  | ||||||
|   |  | ||||||
| @@ -423,10 +423,10 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_ |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr:0x%08x\n", addr); |  | ||||||
| -	retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr); |  | ||||||
| +	retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr); |  | ||||||
|  	if (retval) |  | ||||||
|  		goto done; |  | ||||||
| -	retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, |  | ||||||
| +	retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data, |  | ||||||
|  					  false); |  | ||||||
|  	brcmf_dbg(SDIO, "data:0x%08x\n", data); |  | ||||||
|   |  | ||||||
| @@ -443,7 +443,7 @@ void brcmf_sdiod_regwb(struct brcmf_sdio |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data); |  | ||||||
| -	retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, |  | ||||||
| +	retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data, |  | ||||||
|  					  true); |  | ||||||
|  	if (ret) |  | ||||||
|  		*ret = retval; |  | ||||||
| @@ -455,10 +455,10 @@ void brcmf_sdiod_regwl(struct brcmf_sdio |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); |  | ||||||
| -	retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr); |  | ||||||
| +	retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr); |  | ||||||
|  	if (retval) |  | ||||||
|  		goto done; |  | ||||||
| -	retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, |  | ||||||
| +	retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data, |  | ||||||
|  					  true); |  | ||||||
|   |  | ||||||
|  done: |  | ||||||
| @@ -876,7 +876,7 @@ int brcmf_sdiod_abort(struct brcmf_sdio_ |  | ||||||
|   |  | ||||||
|  	/* issue abort cmd52 command through F0 */ |  | ||||||
|  	brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT, |  | ||||||
| -				 sizeof(t_func), &t_func, true); |  | ||||||
| +				 1, &t_func, true); |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "Exit\n"); |  | ||||||
|  	return 0; |  | ||||||
| @@ -1,179 +0,0 @@ | |||||||
| From 0fcc9fe0048422d66bb906eaa73cc75e11ff7345 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Mon, 13 Nov 2017 21:35:40 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Split brcmf_sdiod_regrw_helper() up. |  | ||||||
|  |  | ||||||
| This large function is concealing a LOT of obscure logic about |  | ||||||
| how the hardware functions. Time to split it up. |  | ||||||
|  |  | ||||||
| This first patch splits the function into two pieces - read and write, |  | ||||||
| doing away with the rw flag in the process. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 94 +++++++++++++++++----- |  | ||||||
|  1 file changed, 73 insertions(+), 21 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -302,8 +302,8 @@ static int brcmf_sdiod_request_data(stru |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, |  | ||||||
| -				   u8 regsz, void *data, bool write) |  | ||||||
| +static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, |  | ||||||
| +				 u8 regsz, void *data) |  | ||||||
|  { |  | ||||||
|  	u8 func; |  | ||||||
|  	s32 retry = 0; |  | ||||||
| @@ -324,13 +324,66 @@ static int brcmf_sdiod_regrw_helper(stru |  | ||||||
|  		func = SDIO_FUNC_1; |  | ||||||
|   |  | ||||||
|  	do { |  | ||||||
| -		if (!write) |  | ||||||
| -			memset(data, 0, regsz); |  | ||||||
|  		/* for retry wait for 1 ms till bus get settled down */ |  | ||||||
|  		if (retry) |  | ||||||
|  			usleep_range(1000, 2000); |  | ||||||
| + |  | ||||||
| +		ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz, |  | ||||||
| +					       data, true); |  | ||||||
| + |  | ||||||
| +	} while (ret != 0 && ret != -ENOMEDIUM && |  | ||||||
| +		 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); |  | ||||||
| + |  | ||||||
| +	if (ret == -ENOMEDIUM) { |  | ||||||
| +		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); |  | ||||||
| +	} else if (ret != 0) { |  | ||||||
| +		/* |  | ||||||
| +		 * SleepCSR register access can fail when |  | ||||||
| +		 * waking up the device so reduce this noise |  | ||||||
| +		 * in the logs. |  | ||||||
| +		 */ |  | ||||||
| +		if (addr != SBSDIO_FUNC1_SLEEPCSR) |  | ||||||
| +			brcmf_err("failed to write data F%d@0x%05x, err: %d\n", |  | ||||||
| +				  func, addr, ret); |  | ||||||
| +		else |  | ||||||
| +			brcmf_dbg(SDIO, "failed to write data F%d@0x%05x, err: %d\n", |  | ||||||
| +				  func, addr, ret); |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	return ret; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, |  | ||||||
| +				u8 regsz, void *data) |  | ||||||
| +{ |  | ||||||
| +	u8 func; |  | ||||||
| +	s32 retry = 0; |  | ||||||
| +	int ret; |  | ||||||
| + |  | ||||||
| +	if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) |  | ||||||
| +		return -ENOMEDIUM; |  | ||||||
| + |  | ||||||
| +	/* |  | ||||||
| +	 * figure out how to read the register based on address range |  | ||||||
| +	 * 0x00 ~ 0x7FF: function 0 CCCR and FBR |  | ||||||
| +	 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers |  | ||||||
| +	 * The rest: function 1 silicon backplane core registers |  | ||||||
| +	 */ |  | ||||||
| +	if ((addr & ~REG_F0_REG_MASK) == 0) |  | ||||||
| +		func = SDIO_FUNC_0; |  | ||||||
| +	else |  | ||||||
| +		func = SDIO_FUNC_1; |  | ||||||
| + |  | ||||||
| +	do { |  | ||||||
| +		memset(data, 0, regsz); |  | ||||||
| + |  | ||||||
| +		/* for retry wait for 1 ms till bus get settled down */ |  | ||||||
| +		if (retry) |  | ||||||
| +			usleep_range(1000, 2000); |  | ||||||
| + |  | ||||||
|  		ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz, |  | ||||||
| -					       data, write); |  | ||||||
| +					       data, false); |  | ||||||
| + |  | ||||||
|  	} while (ret != 0 && ret != -ENOMEDIUM && |  | ||||||
|  		 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); |  | ||||||
|   |  | ||||||
| @@ -343,12 +396,13 @@ static int brcmf_sdiod_regrw_helper(stru |  | ||||||
|  		 * in the logs. |  | ||||||
|  		 */ |  | ||||||
|  		if (addr != SBSDIO_FUNC1_SLEEPCSR) |  | ||||||
| -			brcmf_err("failed to %s data F%d@0x%05x, err: %d\n", |  | ||||||
| -				  write ? "write" : "read", func, addr, ret); |  | ||||||
| +			brcmf_err("failed to read data F%d@0x%05x, err: %d\n", |  | ||||||
| +				  func, addr, ret); |  | ||||||
|  		else |  | ||||||
| -			brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n", |  | ||||||
| -				  write ? "write" : "read", func, addr, ret); |  | ||||||
| +			brcmf_dbg(SDIO, "failed to read data F%d@0x%05x, err: %d\n", |  | ||||||
| +				  func, addr, ret); |  | ||||||
|  	} |  | ||||||
| + |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -366,13 +420,11 @@ brcmf_sdiod_set_sbaddr_window(struct brc |  | ||||||
|  	addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; |  | ||||||
|   |  | ||||||
|  	for (i = 0; i < 3; i++) { |  | ||||||
| -		err = brcmf_sdiod_regrw_helper(sdiodev, |  | ||||||
| -					       SBSDIO_FUNC1_SBADDRLOW + i, |  | ||||||
| -					       1, &addr[i], true); |  | ||||||
| +		brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, addr[i], |  | ||||||
| +				  &err); |  | ||||||
|  		if (err) { |  | ||||||
|  			brcmf_err("failed at addr: 0x%0x\n", |  | ||||||
|  				  SBSDIO_FUNC1_SBADDRLOW + i); |  | ||||||
| -			break; |  | ||||||
|  		} |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| @@ -407,8 +459,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr:0x%08x\n", addr); |  | ||||||
| -	retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data, |  | ||||||
| -					  false); |  | ||||||
| +	retval = brcmf_sdiod_reg_read(sdiodev, addr, 1, &data); |  | ||||||
|  	brcmf_dbg(SDIO, "data:0x%02x\n", data); |  | ||||||
|   |  | ||||||
|  	if (ret) |  | ||||||
| @@ -426,8 +477,9 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_ |  | ||||||
|  	retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr); |  | ||||||
|  	if (retval) |  | ||||||
|  		goto done; |  | ||||||
| -	retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data, |  | ||||||
| -					  false); |  | ||||||
| + |  | ||||||
| +	retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, &data); |  | ||||||
| + |  | ||||||
|  	brcmf_dbg(SDIO, "data:0x%08x\n", data); |  | ||||||
|   |  | ||||||
|  done: |  | ||||||
| @@ -443,8 +495,8 @@ void brcmf_sdiod_regwb(struct brcmf_sdio |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data); |  | ||||||
| -	retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data, |  | ||||||
| -					  true); |  | ||||||
| +	retval = brcmf_sdiod_reg_write(sdiodev, addr, 1, &data); |  | ||||||
| + |  | ||||||
|  	if (ret) |  | ||||||
|  		*ret = retval; |  | ||||||
|  } |  | ||||||
| @@ -458,8 +510,8 @@ void brcmf_sdiod_regwl(struct brcmf_sdio |  | ||||||
|  	retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr); |  | ||||||
|  	if (retval) |  | ||||||
|  		goto done; |  | ||||||
| -	retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data, |  | ||||||
| -					  true); |  | ||||||
| + |  | ||||||
| +	retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, &data); |  | ||||||
|   |  | ||||||
|  done: |  | ||||||
|  	if (ret) |  | ||||||
| @@ -1,62 +0,0 @@ | |||||||
| From b9b0d290bc0c90a5a262bc89c9d995988ea98669 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Mon, 13 Nov 2017 21:35:41 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Clean up brcmf_sdiod_set_sbaddr_window() |  | ||||||
|  |  | ||||||
| This function sets the address of the IO window used for |  | ||||||
| SDIO accesses onto the backplane of the chip. |  | ||||||
|  |  | ||||||
| It currently uses 3 separate masks despite the full mask being |  | ||||||
| defined in the code already. Remove the separate masks and clean up. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c   | 17 +++++------------ |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  3 --- |  | ||||||
|  2 files changed, 5 insertions(+), 15 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -410,23 +410,16 @@ static int |  | ||||||
|  brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) |  | ||||||
|  { |  | ||||||
|  	int err = 0, i; |  | ||||||
| -	u8 addr[3]; |  | ||||||
| +	u32 addr; |  | ||||||
|   |  | ||||||
|  	if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) |  | ||||||
|  		return -ENOMEDIUM; |  | ||||||
|   |  | ||||||
| -	addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; |  | ||||||
| -	addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK; |  | ||||||
| -	addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; |  | ||||||
| +	addr = (address & SBSDIO_SBWINDOW_MASK) >> 8; |  | ||||||
|   |  | ||||||
| -	for (i = 0; i < 3; i++) { |  | ||||||
| -		brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, addr[i], |  | ||||||
| -				  &err); |  | ||||||
| -		if (err) { |  | ||||||
| -			brcmf_err("failed at addr: 0x%0x\n", |  | ||||||
| -				  SBSDIO_FUNC1_SBADDRLOW + i); |  | ||||||
| -		} |  | ||||||
| -	} |  | ||||||
| +	for (i = 0 ; i < 3 && !err ; i++, addr >>= 8) |  | ||||||
| +		brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, |  | ||||||
| +				  addr & 0xff, &err); |  | ||||||
|   |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| @@ -133,9 +133,6 @@ |  | ||||||
|   |  | ||||||
|  /* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */ |  | ||||||
|   |  | ||||||
| -#define SBSDIO_SBADDRLOW_MASK		0x80	/* Valid bits in SBADDRLOW */ |  | ||||||
| -#define SBSDIO_SBADDRMID_MASK		0xff	/* Valid bits in SBADDRMID */ |  | ||||||
| -#define SBSDIO_SBADDRHIGH_MASK		0xffU	/* Valid bits in SBADDRHIGH */ |  | ||||||
|  /* Address bits from SBADDR regs */ |  | ||||||
|  #define SBSDIO_SBWINDOW_MASK		0xffff8000 |  | ||||||
|   |  | ||||||
| @@ -1,91 +0,0 @@ | |||||||
| From ea243e9077b3545f20d93884e91c50ac0719685a Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Mon, 13 Nov 2017 21:35:42 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Remove dead IO code |  | ||||||
|  |  | ||||||
| The value passed to brcmf_sdiod_addrprep() is *always* 4 |  | ||||||
| remove this parameter and the unused code to handle it. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 18 ++++++++---------- |  | ||||||
|  1 file changed, 8 insertions(+), 10 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -425,7 +425,7 @@ brcmf_sdiod_set_sbaddr_window(struct brc |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static int |  | ||||||
| -brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr) |  | ||||||
| +brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr) |  | ||||||
|  { |  | ||||||
|  	uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
|  	int err = 0; |  | ||||||
| @@ -439,9 +439,7 @@ brcmf_sdiod_addrprep(struct brcmf_sdio_d |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	*addr &= SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
| - |  | ||||||
| -	if (width == 4) |  | ||||||
| -		*addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
| +	*addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
|   |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
| @@ -467,7 +465,7 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_ |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr:0x%08x\n", addr); |  | ||||||
| -	retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr); |  | ||||||
| +	retval = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
|  	if (retval) |  | ||||||
|  		goto done; |  | ||||||
|   |  | ||||||
| @@ -500,7 +498,7 @@ void brcmf_sdiod_regwl(struct brcmf_sdio |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); |  | ||||||
| -	retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr); |  | ||||||
| +	retval = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
|  	if (retval) |  | ||||||
|  		goto done; |  | ||||||
|   |  | ||||||
| @@ -736,7 +734,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len); |  | ||||||
|   |  | ||||||
| -	err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); |  | ||||||
| +	err = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
|  	if (err) |  | ||||||
|  		goto done; |  | ||||||
|   |  | ||||||
| @@ -757,7 +755,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_ |  | ||||||
|  	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", |  | ||||||
|  		  addr, pktq->qlen); |  | ||||||
|   |  | ||||||
| -	err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); |  | ||||||
| +	err = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
|  	if (err) |  | ||||||
|  		goto done; |  | ||||||
|   |  | ||||||
| @@ -801,7 +799,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sd |  | ||||||
|   |  | ||||||
|  	memcpy(mypkt->data, buf, nbytes); |  | ||||||
|   |  | ||||||
| -	err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); |  | ||||||
| +	err = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
|   |  | ||||||
|  	if (!err) |  | ||||||
|  		err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr, |  | ||||||
| @@ -821,7 +819,7 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen); |  | ||||||
|   |  | ||||||
| -	err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); |  | ||||||
| +	err = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
|  	if (err) |  | ||||||
|  		return err; |  | ||||||
|   |  | ||||||
| @@ -1,61 +0,0 @@ | |||||||
| From 4a3338ba2a7421db2260159cca5a27bd2ee36d00 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Mon, 13 Nov 2017 21:35:43 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Remove bandaid for SleepCSR |  | ||||||
|  |  | ||||||
| Register access code is not the place for band-aid fixes like this. |  | ||||||
| If this is a genuine problem, it should be fixed further up in the driver |  | ||||||
| stack. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 28 +--------------------- |  | ||||||
|  1 file changed, 1 insertion(+), 27 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -334,21 +334,8 @@ static int brcmf_sdiod_reg_write(struct |  | ||||||
|  	} while (ret != 0 && ret != -ENOMEDIUM && |  | ||||||
|  		 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); |  | ||||||
|   |  | ||||||
| -	if (ret == -ENOMEDIUM) { |  | ||||||
| +	if (ret == -ENOMEDIUM) |  | ||||||
|  		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); |  | ||||||
| -	} else if (ret != 0) { |  | ||||||
| -		/* |  | ||||||
| -		 * SleepCSR register access can fail when |  | ||||||
| -		 * waking up the device so reduce this noise |  | ||||||
| -		 * in the logs. |  | ||||||
| -		 */ |  | ||||||
| -		if (addr != SBSDIO_FUNC1_SLEEPCSR) |  | ||||||
| -			brcmf_err("failed to write data F%d@0x%05x, err: %d\n", |  | ||||||
| -				  func, addr, ret); |  | ||||||
| -		else |  | ||||||
| -			brcmf_dbg(SDIO, "failed to write data F%d@0x%05x, err: %d\n", |  | ||||||
| -				  func, addr, ret); |  | ||||||
| -	} |  | ||||||
|   |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
| @@ -389,19 +376,6 @@ static int brcmf_sdiod_reg_read(struct b |  | ||||||
|   |  | ||||||
|  	if (ret == -ENOMEDIUM) |  | ||||||
|  		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); |  | ||||||
| -	else if (ret != 0) { |  | ||||||
| -		/* |  | ||||||
| -		 * SleepCSR register access can fail when |  | ||||||
| -		 * waking up the device so reduce this noise |  | ||||||
| -		 * in the logs. |  | ||||||
| -		 */ |  | ||||||
| -		if (addr != SBSDIO_FUNC1_SLEEPCSR) |  | ||||||
| -			brcmf_err("failed to read data F%d@0x%05x, err: %d\n", |  | ||||||
| -				  func, addr, ret); |  | ||||||
| -		else |  | ||||||
| -			brcmf_dbg(SDIO, "failed to read data F%d@0x%05x, err: %d\n", |  | ||||||
| -				  func, addr, ret); |  | ||||||
| -	} |  | ||||||
|   |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
| @@ -1,344 +0,0 @@ | |||||||
| From 993a98a42e6e790fd0d2bf7d55a031513c7ba7dc Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Mon, 13 Nov 2017 21:35:44 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Remove brcmf_sdiod_request_data() |  | ||||||
|  |  | ||||||
| This function is obfuscating how IO works on this chip. Remove it |  | ||||||
| and push its logic into brcmf_sdiod_reg_{read,write}(). |  | ||||||
|  |  | ||||||
| Handling of -ENOMEDIUM is altered, but as that's pretty much broken anyway |  | ||||||
| we can ignore that. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 237 ++++++++------------- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.h    |   2 +- |  | ||||||
|  2 files changed, 87 insertions(+), 152 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -230,6 +230,43 @@ void brcmf_sdiod_change_state(struct brc |  | ||||||
|  	sdiodev->state = state; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static int brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, |  | ||||||
| +					 u32 address) |  | ||||||
| +{ |  | ||||||
| +	int err = 0, i; |  | ||||||
| +	u32 addr; |  | ||||||
| + |  | ||||||
| +	if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) |  | ||||||
| +		return -ENOMEDIUM; |  | ||||||
| + |  | ||||||
| +	addr = (address & SBSDIO_SBWINDOW_MASK) >> 8; |  | ||||||
| + |  | ||||||
| +	for (i = 0 ; i < 3 && !err ; i++, addr >>= 8) |  | ||||||
| +		brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, |  | ||||||
| +				  addr & 0xff, &err); |  | ||||||
| + |  | ||||||
| +	return err; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr) |  | ||||||
| +{ |  | ||||||
| +	uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
| +	int err = 0; |  | ||||||
| + |  | ||||||
| +	if (bar0 != sdiodev->sbwad) { |  | ||||||
| +		err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0); |  | ||||||
| +		if (err) |  | ||||||
| +			return err; |  | ||||||
| + |  | ||||||
| +		sdiodev->sbwad = bar0; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	*addr &= SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
| +	*addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte, |  | ||||||
|  					uint regaddr) |  | ||||||
|  { |  | ||||||
| @@ -249,173 +286,84 @@ static inline int brcmf_sdiod_f0_writeb( |  | ||||||
|  	return err_ret; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn, |  | ||||||
| -				    u32 addr, u8 regsz, void *data, bool write) |  | ||||||
| -{ |  | ||||||
| -	struct sdio_func *func; |  | ||||||
| -	int ret = -EINVAL; |  | ||||||
| - |  | ||||||
| -	brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", |  | ||||||
| -		  write, fn, addr, regsz); |  | ||||||
| - |  | ||||||
| -	/* only allow byte access on F0 */ |  | ||||||
| -	if (WARN_ON(regsz > 1 && !fn)) |  | ||||||
| -		return -EINVAL; |  | ||||||
| -	func = sdiodev->func[fn]; |  | ||||||
| - |  | ||||||
| -	switch (regsz) { |  | ||||||
| -	case 1: |  | ||||||
| -		if (write) { |  | ||||||
| -			if (fn) |  | ||||||
| -				sdio_writeb(func, *(u8 *)data, addr, &ret); |  | ||||||
| -			else |  | ||||||
| -				ret = brcmf_sdiod_f0_writeb(func, *(u8 *)data, |  | ||||||
| -							    addr); |  | ||||||
| -		} else { |  | ||||||
| -			if (fn) |  | ||||||
| -				*(u8 *)data = sdio_readb(func, addr, &ret); |  | ||||||
| -			else |  | ||||||
| -				*(u8 *)data = sdio_f0_readb(func, addr, &ret); |  | ||||||
| -		} |  | ||||||
| -		break; |  | ||||||
| -	case 2: |  | ||||||
| -		if (write) |  | ||||||
| -			sdio_writew(func, *(u16 *)data, addr, &ret); |  | ||||||
| -		else |  | ||||||
| -			*(u16 *)data = sdio_readw(func, addr, &ret); |  | ||||||
| -		break; |  | ||||||
| -	case 4: |  | ||||||
| -		if (write) |  | ||||||
| -			sdio_writel(func, *(u32 *)data, addr, &ret); |  | ||||||
| -		else |  | ||||||
| -			*(u32 *)data = sdio_readl(func, addr, &ret); |  | ||||||
| -		break; |  | ||||||
| -	default: |  | ||||||
| -		brcmf_err("invalid size: %d\n", regsz); |  | ||||||
| -		break; |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
| -	if (ret) |  | ||||||
| -		brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n", |  | ||||||
| -			  write ? "write" : "read", fn, addr, ret); |  | ||||||
| - |  | ||||||
| -	return ret; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
|  static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, |  | ||||||
|  				 u8 regsz, void *data) |  | ||||||
|  { |  | ||||||
| -	u8 func; |  | ||||||
| -	s32 retry = 0; |  | ||||||
|  	int ret; |  | ||||||
|   |  | ||||||
| -	if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) |  | ||||||
| -		return -ENOMEDIUM; |  | ||||||
| - |  | ||||||
|  	/* |  | ||||||
|  	 * figure out how to read the register based on address range |  | ||||||
|  	 * 0x00 ~ 0x7FF: function 0 CCCR and FBR |  | ||||||
|  	 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers |  | ||||||
|  	 * The rest: function 1 silicon backplane core registers |  | ||||||
| +	 * f0 writes must be bytewise |  | ||||||
|  	 */ |  | ||||||
| -	if ((addr & ~REG_F0_REG_MASK) == 0) |  | ||||||
| -		func = SDIO_FUNC_0; |  | ||||||
| -	else |  | ||||||
| -		func = SDIO_FUNC_1; |  | ||||||
| - |  | ||||||
| -	do { |  | ||||||
| -		/* for retry wait for 1 ms till bus get settled down */ |  | ||||||
| -		if (retry) |  | ||||||
| -			usleep_range(1000, 2000); |  | ||||||
|   |  | ||||||
| -		ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz, |  | ||||||
| -					       data, true); |  | ||||||
| - |  | ||||||
| -	} while (ret != 0 && ret != -ENOMEDIUM && |  | ||||||
| -		 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); |  | ||||||
| +	if ((addr & ~REG_F0_REG_MASK) == 0) { |  | ||||||
| +		if (WARN_ON(regsz > 1)) |  | ||||||
| +			return -EINVAL; |  | ||||||
| +		ret = brcmf_sdiod_f0_writeb(sdiodev->func[0], |  | ||||||
| +					    *(u8 *)data, addr); |  | ||||||
| +	} else { |  | ||||||
| +		switch (regsz) { |  | ||||||
| +		case 1: |  | ||||||
| +			sdio_writeb(sdiodev->func[1], *(u8 *)data, addr, &ret); |  | ||||||
| +			break; |  | ||||||
| +		case 4: |  | ||||||
| +			ret = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
| +			if (ret) |  | ||||||
| +				goto done; |  | ||||||
|   |  | ||||||
| -	if (ret == -ENOMEDIUM) |  | ||||||
| -		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); |  | ||||||
| +			sdio_writel(sdiodev->func[1], *(u32 *)data, addr, &ret); |  | ||||||
| +			break; |  | ||||||
| +		default: |  | ||||||
| +			WARN(1, "Invalid reg size\n"); |  | ||||||
| +			ret = -EINVAL; |  | ||||||
| +			break; |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
|   |  | ||||||
| +done: |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, |  | ||||||
|  				u8 regsz, void *data) |  | ||||||
|  { |  | ||||||
| -	u8 func; |  | ||||||
| -	s32 retry = 0; |  | ||||||
|  	int ret; |  | ||||||
|   |  | ||||||
| -	if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) |  | ||||||
| -		return -ENOMEDIUM; |  | ||||||
| - |  | ||||||
|  	/* |  | ||||||
|  	 * figure out how to read the register based on address range |  | ||||||
|  	 * 0x00 ~ 0x7FF: function 0 CCCR and FBR |  | ||||||
|  	 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers |  | ||||||
|  	 * The rest: function 1 silicon backplane core registers |  | ||||||
| +	 * f0 reads must be bytewise |  | ||||||
|  	 */ |  | ||||||
| -	if ((addr & ~REG_F0_REG_MASK) == 0) |  | ||||||
| -		func = SDIO_FUNC_0; |  | ||||||
| -	else |  | ||||||
| -		func = SDIO_FUNC_1; |  | ||||||
| - |  | ||||||
| -	do { |  | ||||||
| -		memset(data, 0, regsz); |  | ||||||
| - |  | ||||||
| -		/* for retry wait for 1 ms till bus get settled down */ |  | ||||||
| -		if (retry) |  | ||||||
| -			usleep_range(1000, 2000); |  | ||||||
| - |  | ||||||
| -		ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz, |  | ||||||
| -					       data, false); |  | ||||||
| - |  | ||||||
| -	} while (ret != 0 && ret != -ENOMEDIUM && |  | ||||||
| -		 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); |  | ||||||
| - |  | ||||||
| -	if (ret == -ENOMEDIUM) |  | ||||||
| -		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); |  | ||||||
| - |  | ||||||
| -	return ret; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
| -static int |  | ||||||
| -brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) |  | ||||||
| -{ |  | ||||||
| -	int err = 0, i; |  | ||||||
| -	u32 addr; |  | ||||||
| - |  | ||||||
| -	if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) |  | ||||||
| -		return -ENOMEDIUM; |  | ||||||
| - |  | ||||||
| -	addr = (address & SBSDIO_SBWINDOW_MASK) >> 8; |  | ||||||
| - |  | ||||||
| -	for (i = 0 ; i < 3 && !err ; i++, addr >>= 8) |  | ||||||
| -		brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, |  | ||||||
| -				  addr & 0xff, &err); |  | ||||||
| - |  | ||||||
| -	return err; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
| -static int |  | ||||||
| -brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr) |  | ||||||
| -{ |  | ||||||
| -	uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
| -	int err = 0; |  | ||||||
| - |  | ||||||
| -	if (bar0 != sdiodev->sbwad) { |  | ||||||
| -		err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0); |  | ||||||
| -		if (err) |  | ||||||
| -			return err; |  | ||||||
| +	if ((addr & ~REG_F0_REG_MASK) == 0) { |  | ||||||
| +		if (WARN_ON(regsz > 1)) |  | ||||||
| +			return -EINVAL; |  | ||||||
| +		*(u8 *)data = sdio_f0_readb(sdiodev->func[0], addr, &ret); |  | ||||||
| +	} else { |  | ||||||
| +		switch (regsz) { |  | ||||||
| +		case 1: |  | ||||||
| +			*(u8 *)data = sdio_readb(sdiodev->func[1], addr, &ret); |  | ||||||
| +			break; |  | ||||||
| +		case 4: |  | ||||||
| +			ret = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
| +			if (ret) |  | ||||||
| +				goto done; |  | ||||||
|   |  | ||||||
| -		sdiodev->sbwad = bar0; |  | ||||||
| +			*(u32 *)data = sdio_readl(sdiodev->func[1], addr, &ret); |  | ||||||
| +			break; |  | ||||||
| +		default: |  | ||||||
| +			WARN(1, "Invalid reg size\n"); |  | ||||||
| +			ret = -EINVAL; |  | ||||||
| +			break; |  | ||||||
| +		} |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	*addr &= SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
| -	*addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
| - |  | ||||||
| -	return 0; |  | ||||||
| +done: |  | ||||||
| +	return ret; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) |  | ||||||
| @@ -439,15 +387,9 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_ |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr:0x%08x\n", addr); |  | ||||||
| -	retval = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
| -	if (retval) |  | ||||||
| -		goto done; |  | ||||||
| - |  | ||||||
|  	retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, &data); |  | ||||||
| - |  | ||||||
|  	brcmf_dbg(SDIO, "data:0x%08x\n", data); |  | ||||||
|   |  | ||||||
| -done: |  | ||||||
|  	if (ret) |  | ||||||
|  		*ret = retval; |  | ||||||
|   |  | ||||||
| @@ -472,13 +414,8 @@ void brcmf_sdiod_regwl(struct brcmf_sdio |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); |  | ||||||
| -	retval = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
| -	if (retval) |  | ||||||
| -		goto done; |  | ||||||
| - |  | ||||||
|  	retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, &data); |  | ||||||
|   |  | ||||||
| -done: |  | ||||||
|  	if (ret) |  | ||||||
|  		*ret = retval; |  | ||||||
|  } |  | ||||||
| @@ -886,14 +823,12 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev |  | ||||||
|  	return bcmerror; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn) |  | ||||||
| +int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn) |  | ||||||
|  { |  | ||||||
| -	char t_func = (char)fn; |  | ||||||
|  	brcmf_dbg(SDIO, "Enter\n"); |  | ||||||
|   |  | ||||||
|  	/* issue abort cmd52 command through F0 */ |  | ||||||
| -	brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT, |  | ||||||
| -				 1, &t_func, true); |  | ||||||
| +	brcmf_sdiod_reg_write(sdiodev, SDIO_CCCR_ABORT, 1, &fn); |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "Exit\n"); |  | ||||||
|  	return 0; |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| @@ -339,7 +339,7 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_ |  | ||||||
|  		      u8 *data, uint size); |  | ||||||
|   |  | ||||||
|  /* Issue an abort to the specified function */ |  | ||||||
| -int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn); |  | ||||||
| +int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn); |  | ||||||
|  void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev); |  | ||||||
|  void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev, |  | ||||||
|  			      enum brcmf_sdiod_state state); |  | ||||||
| @@ -1,28 +0,0 @@ | |||||||
| From 3508a056a1f45d95c874fc9af8748bf4229432b6 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Mon, 13 Nov 2017 21:35:45 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Fix asymmetric IO functions. |  | ||||||
|  |  | ||||||
| Unlikely to be a problem, but brcmf_sdiod_regrl() is |  | ||||||
| not symmetric with brcmf_sdiod_regrb() in initializing |  | ||||||
| the data value on stack. Fix that. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| [arend: reword the commit message a bit] |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 +- |  | ||||||
|  1 file changed, 1 insertion(+), 1 deletion(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -383,7 +383,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d |  | ||||||
|   |  | ||||||
|  u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) |  | ||||||
|  { |  | ||||||
| -	u32 data = 0; |  | ||||||
| +	u32 data; |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr:0x%08x\n", addr); |  | ||||||
| @@ -1,53 +0,0 @@ | |||||||
| From 12e3e74e2820e11d91ee44fd3a190cd80d109faa Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Mon, 13 Nov 2017 21:35:46 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Remove noisy debugging. |  | ||||||
|  |  | ||||||
| If you need debugging this low level, you're doing something wrong. |  | ||||||
| Remove these noisy debug statements so the code is more readable. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 6 ------ |  | ||||||
|  1 file changed, 6 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -371,9 +371,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d |  | ||||||
|  	u8 data; |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
| -	brcmf_dbg(SDIO, "addr:0x%08x\n", addr); |  | ||||||
|  	retval = brcmf_sdiod_reg_read(sdiodev, addr, 1, &data); |  | ||||||
| -	brcmf_dbg(SDIO, "data:0x%02x\n", data); |  | ||||||
|   |  | ||||||
|  	if (ret) |  | ||||||
|  		*ret = retval; |  | ||||||
| @@ -386,9 +384,7 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_ |  | ||||||
|  	u32 data; |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
| -	brcmf_dbg(SDIO, "addr:0x%08x\n", addr); |  | ||||||
|  	retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, &data); |  | ||||||
| -	brcmf_dbg(SDIO, "data:0x%08x\n", data); |  | ||||||
|   |  | ||||||
|  	if (ret) |  | ||||||
|  		*ret = retval; |  | ||||||
| @@ -401,7 +397,6 @@ void brcmf_sdiod_regwb(struct brcmf_sdio |  | ||||||
|  { |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
| -	brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data); |  | ||||||
|  	retval = brcmf_sdiod_reg_write(sdiodev, addr, 1, &data); |  | ||||||
|   |  | ||||||
|  	if (ret) |  | ||||||
| @@ -413,7 +408,6 @@ void brcmf_sdiod_regwl(struct brcmf_sdio |  | ||||||
|  { |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
| -	brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); |  | ||||||
|  	retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, &data); |  | ||||||
|   |  | ||||||
|  	if (ret) |  | ||||||
| @@ -1,58 +0,0 @@ | |||||||
| From dd8a2d49e4ed321ab8e7b679499c3a98ccc5ca24 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Mon, 13 Nov 2017 21:35:47 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Rename bcmerror to err |  | ||||||
|  |  | ||||||
| Trivial cleanup of nasty variable name |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 14 +++++++------- |  | ||||||
|  1 file changed, 7 insertions(+), 7 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -746,7 +746,7 @@ int |  | ||||||
|  brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, |  | ||||||
|  		  u8 *data, uint size) |  | ||||||
|  { |  | ||||||
| -	int bcmerror = 0; |  | ||||||
| +	int err = 0; |  | ||||||
|  	struct sk_buff *pkt; |  | ||||||
|  	u32 sdaddr; |  | ||||||
|  	uint dsize; |  | ||||||
| @@ -771,8 +771,8 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev |  | ||||||
|  	/* Do the transfer(s) */ |  | ||||||
|  	while (size) { |  | ||||||
|  		/* Set the backplane window to include the start address */ |  | ||||||
| -		bcmerror = brcmf_sdiod_set_sbaddr_window(sdiodev, address); |  | ||||||
| -		if (bcmerror) |  | ||||||
| +		err = brcmf_sdiod_set_sbaddr_window(sdiodev, address); |  | ||||||
| +		if (err) |  | ||||||
|  			break; |  | ||||||
|   |  | ||||||
|  		brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n", |  | ||||||
| @@ -785,9 +785,9 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev |  | ||||||
|  		skb_put(pkt, dsize); |  | ||||||
|  		if (write) |  | ||||||
|  			memcpy(pkt->data, data, dsize); |  | ||||||
| -		bcmerror = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write, |  | ||||||
| -					      sdaddr, pkt); |  | ||||||
| -		if (bcmerror) { |  | ||||||
| +		err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write, sdaddr, |  | ||||||
| +					 pkt); |  | ||||||
| +		if (err) { |  | ||||||
|  			brcmf_err("membytes transfer failed\n"); |  | ||||||
|  			break; |  | ||||||
|  		} |  | ||||||
| @@ -814,7 +814,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev |  | ||||||
|   |  | ||||||
|  	sdio_release_host(sdiodev->func[1]); |  | ||||||
|   |  | ||||||
| -	return bcmerror; |  | ||||||
| +	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn) |  | ||||||
| @@ -1,143 +0,0 @@ | |||||||
| From 8f13c87ccc495e30de5f58bbda967f6edd5bec53 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Fri, 8 Dec 2017 13:10:26 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Split brcmf_sdiod_buffrw function up. |  | ||||||
|  |  | ||||||
| This function needs to be split up into separate read / write variants |  | ||||||
| for clarity. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 67 +++++++++++++++------- |  | ||||||
|  1 file changed, 45 insertions(+), 22 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -414,8 +414,8 @@ void brcmf_sdiod_regwl(struct brcmf_sdio |  | ||||||
|  		*ret = retval; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, |  | ||||||
| -			     bool write, u32 addr, struct sk_buff *pkt) |  | ||||||
| +static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev, uint fn, |  | ||||||
| +				 u32 addr, struct sk_buff *pkt) |  | ||||||
|  { |  | ||||||
|  	unsigned int req_sz; |  | ||||||
|  	int err; |  | ||||||
| @@ -424,18 +424,36 @@ static int brcmf_sdiod_buffrw(struct brc |  | ||||||
|  	req_sz = pkt->len + 3; |  | ||||||
|  	req_sz &= (uint)~3; |  | ||||||
|   |  | ||||||
| -	if (write) |  | ||||||
| -		err = sdio_memcpy_toio(sdiodev->func[fn], addr, |  | ||||||
| -				       ((u8 *)(pkt->data)), req_sz); |  | ||||||
| -	else if (fn == 1) |  | ||||||
| -		err = sdio_memcpy_fromio(sdiodev->func[fn], ((u8 *)(pkt->data)), |  | ||||||
| -					 addr, req_sz); |  | ||||||
| +	if (fn == 1) |  | ||||||
| +		err = sdio_memcpy_fromio(sdiodev->func[fn], |  | ||||||
| +					 ((u8 *)(pkt->data)), addr, req_sz); |  | ||||||
|  	else |  | ||||||
|  		/* function 2 read is FIFO operation */ |  | ||||||
| -		err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, |  | ||||||
| -				  req_sz); |  | ||||||
| +		err = sdio_readsb(sdiodev->func[fn], |  | ||||||
| +				  ((u8 *)(pkt->data)), addr, req_sz); |  | ||||||
| + |  | ||||||
| +	if (err == -ENOMEDIUM) |  | ||||||
| +		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); |  | ||||||
| + |  | ||||||
| +	return err; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev, uint fn, |  | ||||||
| +				  u32 addr, struct sk_buff *pkt) |  | ||||||
| +{ |  | ||||||
| +	unsigned int req_sz; |  | ||||||
| +	int err; |  | ||||||
| + |  | ||||||
| +	/* Single skb use the standard mmc interface */ |  | ||||||
| +	req_sz = pkt->len + 3; |  | ||||||
| +	req_sz &= (uint)~3; |  | ||||||
| + |  | ||||||
| +	err = sdio_memcpy_toio(sdiodev->func[fn], addr, |  | ||||||
| +			       ((u8 *)(pkt->data)), req_sz); |  | ||||||
| + |  | ||||||
|  	if (err == -ENOMEDIUM) |  | ||||||
|  		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); |  | ||||||
| + |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -643,7 +661,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd |  | ||||||
|  	if (err) |  | ||||||
|  		goto done; |  | ||||||
|   |  | ||||||
| -	err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, pkt); |  | ||||||
| +	err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt); |  | ||||||
|   |  | ||||||
|  done: |  | ||||||
|  	return err; |  | ||||||
| @@ -665,14 +683,14 @@ int brcmf_sdiod_recv_chain(struct brcmf_ |  | ||||||
|  		goto done; |  | ||||||
|   |  | ||||||
|  	if (pktq->qlen == 1) |  | ||||||
| -		err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, |  | ||||||
| -					 pktq->next); |  | ||||||
| +		err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, |  | ||||||
| +					    pktq->next); |  | ||||||
|  	else if (!sdiodev->sg_support) { |  | ||||||
|  		glom_skb = brcmu_pkt_buf_get_skb(totlen); |  | ||||||
|  		if (!glom_skb) |  | ||||||
|  			return -ENOMEM; |  | ||||||
| -		err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, |  | ||||||
| -					 glom_skb); |  | ||||||
| +		err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, |  | ||||||
| +					    glom_skb); |  | ||||||
|  		if (err) |  | ||||||
|  			goto done; |  | ||||||
|   |  | ||||||
| @@ -707,8 +725,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sd |  | ||||||
|  	err = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
|   |  | ||||||
|  	if (!err) |  | ||||||
| -		err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr, |  | ||||||
| -					 mypkt); |  | ||||||
| +		err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt); |  | ||||||
|   |  | ||||||
|  	brcmu_pkt_buf_free_skb(mypkt); |  | ||||||
|  	return err; |  | ||||||
| @@ -730,8 +747,8 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd |  | ||||||
|   |  | ||||||
|  	if (pktq->qlen == 1 || !sdiodev->sg_support) |  | ||||||
|  		skb_queue_walk(pktq, skb) { |  | ||||||
| -			err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, |  | ||||||
| -						 addr, skb); |  | ||||||
| +			err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, |  | ||||||
| +						     addr, skb); |  | ||||||
|  			if (err) |  | ||||||
|  				break; |  | ||||||
|  		} |  | ||||||
| @@ -783,10 +800,16 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev |  | ||||||
|  		sdaddr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
|   |  | ||||||
|  		skb_put(pkt, dsize); |  | ||||||
| -		if (write) |  | ||||||
| + |  | ||||||
| +		if (write) { |  | ||||||
|  			memcpy(pkt->data, data, dsize); |  | ||||||
| -		err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write, sdaddr, |  | ||||||
| -					 pkt); |  | ||||||
| +			err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_1, |  | ||||||
| +						     sdaddr, pkt); |  | ||||||
| +		} else { |  | ||||||
| +			err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_1, |  | ||||||
| +						    sdaddr, pkt); |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
|  		if (err) { |  | ||||||
|  			brcmf_err("membytes transfer failed\n"); |  | ||||||
|  			break; |  | ||||||
| @@ -1,34 +0,0 @@ | |||||||
| From 6e24dd012bfda479d0046f7995058f167e1923bc Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Fri, 8 Dec 2017 13:10:27 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: whitespace fixes in brcmf_sdiod_send_buf() |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| [arend: mention function in patch subject] |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 3 ++- |  | ||||||
|  1 file changed, 2 insertions(+), 1 deletion(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -714,6 +714,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sd |  | ||||||
|  	int err; |  | ||||||
|   |  | ||||||
|  	mypkt = brcmu_pkt_buf_get_skb(nbytes); |  | ||||||
| + |  | ||||||
|  	if (!mypkt) { |  | ||||||
|  		brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n", |  | ||||||
|  			  nbytes); |  | ||||||
| @@ -728,8 +729,8 @@ int brcmf_sdiod_send_buf(struct brcmf_sd |  | ||||||
|  		err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt); |  | ||||||
|   |  | ||||||
|  	brcmu_pkt_buf_free_skb(mypkt); |  | ||||||
| -	return err; |  | ||||||
|   |  | ||||||
| +	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev, |  | ||||||
| @@ -1,36 +0,0 @@ | |||||||
| From a7323378dcf1f10a98f47b744e6f65e6fd671d84 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Fri, 8 Dec 2017 13:10:28 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Clarify if using braces. |  | ||||||
|  |  | ||||||
| Whilst this if () statement is technically correct, it lacks clarity. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 5 +++-- |  | ||||||
|  1 file changed, 3 insertions(+), 2 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -746,16 +746,17 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd |  | ||||||
|  	if (err) |  | ||||||
|  		return err; |  | ||||||
|   |  | ||||||
| -	if (pktq->qlen == 1 || !sdiodev->sg_support) |  | ||||||
| +	if (pktq->qlen == 1 || !sdiodev->sg_support) { |  | ||||||
|  		skb_queue_walk(pktq, skb) { |  | ||||||
|  			err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, |  | ||||||
|  						     addr, skb); |  | ||||||
|  			if (err) |  | ||||||
|  				break; |  | ||||||
|  		} |  | ||||||
| -	else |  | ||||||
| +	} else { |  | ||||||
|  		err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, true, addr, |  | ||||||
|  					    pktq); |  | ||||||
| +	} |  | ||||||
|   |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
| @@ -1,831 +0,0 @@ | |||||||
| From 71bd508d7ded8c504ef05d1b4befecfe25e54cb1 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Fri, 8 Dec 2017 13:10:29 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Rename / replace old IO functions with simpler |  | ||||||
|  ones. |  | ||||||
|  |  | ||||||
| Primarily this patch removes: |  | ||||||
|  |  | ||||||
| brcmf_sdiod_f0_writeb() |  | ||||||
| brcmf_sdiod_reg_write() |  | ||||||
| brcmf_sdiod_reg_read() |  | ||||||
|  |  | ||||||
| Since we no longer use the quirky method of deciding which function to |  | ||||||
| address via the address being accessed, take the opportunity to rename |  | ||||||
| some IO functions more in line with common kernel code. We also convert |  | ||||||
| those that map directly to sdio_{read,write}*() to macros. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 169 +++---------------- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 186 ++++++++++----------- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.h    |  28 +++- |  | ||||||
|  3 files changed, 138 insertions(+), 245 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -137,27 +137,27 @@ int brcmf_sdiod_intr_register(struct brc |  | ||||||
|  		if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) { |  | ||||||
|  			/* assign GPIO to SDIO core */ |  | ||||||
|  			addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol); |  | ||||||
| -			gpiocontrol = brcmf_sdiod_regrl(sdiodev, addr, &ret); |  | ||||||
| +			gpiocontrol = brcmf_sdiod_readl(sdiodev, addr, &ret); |  | ||||||
|  			gpiocontrol |= 0x2; |  | ||||||
| -			brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol, &ret); |  | ||||||
| +			brcmf_sdiod_writel(sdiodev, addr, gpiocontrol, &ret); |  | ||||||
|   |  | ||||||
| -			brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_SELECT, 0xf, |  | ||||||
| -					  &ret); |  | ||||||
| -			brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret); |  | ||||||
| -			brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret); |  | ||||||
| +			brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_SELECT, |  | ||||||
| +					   0xf, &ret); |  | ||||||
| +			brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret); |  | ||||||
| +			brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret); |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
|  		/* must configure SDIO_CCCR_IENx to enable irq */ |  | ||||||
| -		data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, &ret); |  | ||||||
| +		data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, &ret); |  | ||||||
|  		data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; |  | ||||||
| -		brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); |  | ||||||
| +		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret); |  | ||||||
|   |  | ||||||
|  		/* redirect, configure and enable io for interrupt signal */ |  | ||||||
|  		data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; |  | ||||||
|  		if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) |  | ||||||
|  			data |= SDIO_SEPINT_ACT_HI; |  | ||||||
| -		brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); |  | ||||||
| - |  | ||||||
| +		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, |  | ||||||
| +				     data, &ret); |  | ||||||
|  		sdio_release_host(sdiodev->func[1]); |  | ||||||
|  	} else { |  | ||||||
|  		brcmf_dbg(SDIO, "Entering\n"); |  | ||||||
| @@ -183,8 +183,8 @@ void brcmf_sdiod_intr_unregister(struct |  | ||||||
|   |  | ||||||
|  		pdata = &sdiodev->settings->bus.sdio; |  | ||||||
|  		sdio_claim_host(sdiodev->func[1]); |  | ||||||
| -		brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); |  | ||||||
| -		brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); |  | ||||||
| +		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); |  | ||||||
| +		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, 0, NULL); |  | ||||||
|  		sdio_release_host(sdiodev->func[1]); |  | ||||||
|   |  | ||||||
|  		sdiodev->oob_irq_requested = false; |  | ||||||
| @@ -242,8 +242,8 @@ static int brcmf_sdiod_set_sbaddr_window |  | ||||||
|  	addr = (address & SBSDIO_SBWINDOW_MASK) >> 8; |  | ||||||
|   |  | ||||||
|  	for (i = 0 ; i < 3 && !err ; i++, addr >>= 8) |  | ||||||
| -		brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, |  | ||||||
| -				  addr & 0xff, &err); |  | ||||||
| +		brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, |  | ||||||
| +				   addr & 0xff, &err); |  | ||||||
|   |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
| @@ -267,124 +267,15 @@ static int brcmf_sdiod_addrprep(struct b |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte, |  | ||||||
| -					uint regaddr) |  | ||||||
| -{ |  | ||||||
| -	int err_ret; |  | ||||||
| - |  | ||||||
| -	/* |  | ||||||
| -	 * Can only directly write to some F0 registers. |  | ||||||
| -	 * Handle CCCR_IENx and CCCR_ABORT command |  | ||||||
| -	 * as a special case. |  | ||||||
| -	 */ |  | ||||||
| -	if ((regaddr == SDIO_CCCR_ABORT) || |  | ||||||
| -	    (regaddr == SDIO_CCCR_IENx)) |  | ||||||
| -		sdio_writeb(func, byte, regaddr, &err_ret); |  | ||||||
| -	else |  | ||||||
| -		sdio_f0_writeb(func, byte, regaddr, &err_ret); |  | ||||||
| - |  | ||||||
| -	return err_ret; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
| -static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, |  | ||||||
| -				 u8 regsz, void *data) |  | ||||||
| -{ |  | ||||||
| -	int ret; |  | ||||||
| - |  | ||||||
| -	/* |  | ||||||
| -	 * figure out how to read the register based on address range |  | ||||||
| -	 * 0x00 ~ 0x7FF: function 0 CCCR and FBR |  | ||||||
| -	 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers |  | ||||||
| -	 * The rest: function 1 silicon backplane core registers |  | ||||||
| -	 * f0 writes must be bytewise |  | ||||||
| -	 */ |  | ||||||
| - |  | ||||||
| -	if ((addr & ~REG_F0_REG_MASK) == 0) { |  | ||||||
| -		if (WARN_ON(regsz > 1)) |  | ||||||
| -			return -EINVAL; |  | ||||||
| -		ret = brcmf_sdiod_f0_writeb(sdiodev->func[0], |  | ||||||
| -					    *(u8 *)data, addr); |  | ||||||
| -	} else { |  | ||||||
| -		switch (regsz) { |  | ||||||
| -		case 1: |  | ||||||
| -			sdio_writeb(sdiodev->func[1], *(u8 *)data, addr, &ret); |  | ||||||
| -			break; |  | ||||||
| -		case 4: |  | ||||||
| -			ret = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
| -			if (ret) |  | ||||||
| -				goto done; |  | ||||||
| - |  | ||||||
| -			sdio_writel(sdiodev->func[1], *(u32 *)data, addr, &ret); |  | ||||||
| -			break; |  | ||||||
| -		default: |  | ||||||
| -			WARN(1, "Invalid reg size\n"); |  | ||||||
| -			ret = -EINVAL; |  | ||||||
| -			break; |  | ||||||
| -		} |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
| -done: |  | ||||||
| -	return ret; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
| -static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, |  | ||||||
| -				u8 regsz, void *data) |  | ||||||
| -{ |  | ||||||
| -	int ret; |  | ||||||
| - |  | ||||||
| -	/* |  | ||||||
| -	 * figure out how to read the register based on address range |  | ||||||
| -	 * 0x00 ~ 0x7FF: function 0 CCCR and FBR |  | ||||||
| -	 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers |  | ||||||
| -	 * The rest: function 1 silicon backplane core registers |  | ||||||
| -	 * f0 reads must be bytewise |  | ||||||
| -	 */ |  | ||||||
| -	if ((addr & ~REG_F0_REG_MASK) == 0) { |  | ||||||
| -		if (WARN_ON(regsz > 1)) |  | ||||||
| -			return -EINVAL; |  | ||||||
| -		*(u8 *)data = sdio_f0_readb(sdiodev->func[0], addr, &ret); |  | ||||||
| -	} else { |  | ||||||
| -		switch (regsz) { |  | ||||||
| -		case 1: |  | ||||||
| -			*(u8 *)data = sdio_readb(sdiodev->func[1], addr, &ret); |  | ||||||
| -			break; |  | ||||||
| -		case 4: |  | ||||||
| -			ret = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
| -			if (ret) |  | ||||||
| -				goto done; |  | ||||||
| - |  | ||||||
| -			*(u32 *)data = sdio_readl(sdiodev->func[1], addr, &ret); |  | ||||||
| -			break; |  | ||||||
| -		default: |  | ||||||
| -			WARN(1, "Invalid reg size\n"); |  | ||||||
| -			ret = -EINVAL; |  | ||||||
| -			break; |  | ||||||
| -		} |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
| -done: |  | ||||||
| -	return ret; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
| -u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) |  | ||||||
| +u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) |  | ||||||
|  { |  | ||||||
| -	u8 data; |  | ||||||
| +	u32 data = 0; |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
| -	retval = brcmf_sdiod_reg_read(sdiodev, addr, 1, &data); |  | ||||||
| - |  | ||||||
| -	if (ret) |  | ||||||
| -		*ret = retval; |  | ||||||
| - |  | ||||||
| -	return data; |  | ||||||
| -} |  | ||||||
| +	retval = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
|   |  | ||||||
| -u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) |  | ||||||
| -{ |  | ||||||
| -	u32 data; |  | ||||||
| -	int retval; |  | ||||||
| - |  | ||||||
| -	retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, &data); |  | ||||||
| +	if (!retval) |  | ||||||
| +		data = sdio_readl(sdiodev->func[1], addr, &retval); |  | ||||||
|   |  | ||||||
|  	if (ret) |  | ||||||
|  		*ret = retval; |  | ||||||
| @@ -392,23 +283,15 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_ |  | ||||||
|  	return data; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, |  | ||||||
| -		      u8 data, int *ret) |  | ||||||
| +void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr, |  | ||||||
| +			u32 data, int *ret) |  | ||||||
|  { |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
| -	retval = brcmf_sdiod_reg_write(sdiodev, addr, 1, &data); |  | ||||||
| - |  | ||||||
| -	if (ret) |  | ||||||
| -		*ret = retval; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
| -void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, |  | ||||||
| -		      u32 data, int *ret) |  | ||||||
| -{ |  | ||||||
| -	int retval; |  | ||||||
| +	retval = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
|   |  | ||||||
| -	retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, &data); |  | ||||||
| +	if (!retval) |  | ||||||
| +		sdio_writel(sdiodev->func[1], data, addr, &retval); |  | ||||||
|   |  | ||||||
|  	if (ret) |  | ||||||
|  		*ret = retval; |  | ||||||
| @@ -846,8 +729,8 @@ int brcmf_sdiod_abort(struct brcmf_sdio_ |  | ||||||
|  { |  | ||||||
|  	brcmf_dbg(SDIO, "Enter\n"); |  | ||||||
|   |  | ||||||
| -	/* issue abort cmd52 command through F0 */ |  | ||||||
| -	brcmf_sdiod_reg_write(sdiodev, SDIO_CCCR_ABORT, 1, &fn); |  | ||||||
| +	/* Issue abort cmd52 command through F0 */ |  | ||||||
| +	brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, fn, NULL); |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "Exit\n"); |  | ||||||
|  	return 0; |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -669,7 +669,7 @@ static int r_sdreg32(struct brcmf_sdio * |  | ||||||
|  	int ret; |  | ||||||
|   |  | ||||||
|  	core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); |  | ||||||
| -	*regvar = brcmf_sdiod_regrl(bus->sdiodev, core->base + offset, &ret); |  | ||||||
| +	*regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, &ret); |  | ||||||
|   |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
| @@ -680,7 +680,7 @@ static int w_sdreg32(struct brcmf_sdio * |  | ||||||
|  	int ret; |  | ||||||
|   |  | ||||||
|  	core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); |  | ||||||
| -	brcmf_sdiod_regwl(bus->sdiodev, core->base + reg_offset, regval, &ret); |  | ||||||
| +	brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, &ret); |  | ||||||
|   |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
| @@ -697,8 +697,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio |  | ||||||
|   |  | ||||||
|  	wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); |  | ||||||
|  	/* 1st KSO write goes to AOS wake up core if device is asleep  */ |  | ||||||
| -	brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, |  | ||||||
| -			  wr_val, &err); |  | ||||||
| +	brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err); |  | ||||||
|   |  | ||||||
|  	if (on) { |  | ||||||
|  		/* device WAKEUP through KSO: |  | ||||||
| @@ -724,7 +723,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio |  | ||||||
|  		 * just one write attempt may fail, |  | ||||||
|  		 * read it back until it matches written value |  | ||||||
|  		 */ |  | ||||||
| -		rd_val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, |  | ||||||
| +		rd_val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, |  | ||||||
|  					   &err); |  | ||||||
|  		if (!err) { |  | ||||||
|  			if ((rd_val & bmask) == cmp_val) |  | ||||||
| @@ -734,9 +733,11 @@ brcmf_sdio_kso_control(struct brcmf_sdio |  | ||||||
|  		/* bail out upon subsequent access errors */ |  | ||||||
|  		if (err && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS)) |  | ||||||
|  			break; |  | ||||||
| + |  | ||||||
|  		udelay(KSO_WAIT_US); |  | ||||||
| -		brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, |  | ||||||
| -				  wr_val, &err); |  | ||||||
| +		brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, |  | ||||||
| +				   &err); |  | ||||||
| + |  | ||||||
|  	} while (try_cnt++ < MAX_KSO_ATTEMPTS); |  | ||||||
|   |  | ||||||
|  	if (try_cnt > 2) |  | ||||||
| @@ -772,15 +773,15 @@ static int brcmf_sdio_htclk(struct brcmf |  | ||||||
|  		clkreq = |  | ||||||
|  		    bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; |  | ||||||
|   |  | ||||||
| -		brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| -				  clkreq, &err); |  | ||||||
| +		brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| +				   clkreq, &err); |  | ||||||
|  		if (err) { |  | ||||||
|  			brcmf_err("HT Avail request error: %d\n", err); |  | ||||||
|  			return -EBADE; |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
|  		/* Check current status */ |  | ||||||
| -		clkctl = brcmf_sdiod_regrb(bus->sdiodev, |  | ||||||
| +		clkctl = brcmf_sdiod_readb(bus->sdiodev, |  | ||||||
|  					   SBSDIO_FUNC1_CHIPCLKCSR, &err); |  | ||||||
|  		if (err) { |  | ||||||
|  			brcmf_err("HT Avail read error: %d\n", err); |  | ||||||
| @@ -790,35 +791,34 @@ static int brcmf_sdio_htclk(struct brcmf |  | ||||||
|  		/* Go to pending and await interrupt if appropriate */ |  | ||||||
|  		if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { |  | ||||||
|  			/* Allow only clock-available interrupt */ |  | ||||||
| -			devctl = brcmf_sdiod_regrb(bus->sdiodev, |  | ||||||
| +			devctl = brcmf_sdiod_readb(bus->sdiodev, |  | ||||||
|  						   SBSDIO_DEVICE_CTL, &err); |  | ||||||
|  			if (err) { |  | ||||||
| -				brcmf_err("Devctl error setting CA: %d\n", |  | ||||||
| -					  err); |  | ||||||
| +				brcmf_err("Devctl error setting CA: %d\n", err); |  | ||||||
|  				return -EBADE; |  | ||||||
|  			} |  | ||||||
|   |  | ||||||
|  			devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; |  | ||||||
| -			brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, |  | ||||||
| -					  devctl, &err); |  | ||||||
| +			brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL, |  | ||||||
| +					   devctl, &err); |  | ||||||
|  			brcmf_dbg(SDIO, "CLKCTL: set PENDING\n"); |  | ||||||
|  			bus->clkstate = CLK_PENDING; |  | ||||||
|   |  | ||||||
|  			return 0; |  | ||||||
|  		} else if (bus->clkstate == CLK_PENDING) { |  | ||||||
|  			/* Cancel CA-only interrupt filter */ |  | ||||||
| -			devctl = brcmf_sdiod_regrb(bus->sdiodev, |  | ||||||
| +			devctl = brcmf_sdiod_readb(bus->sdiodev, |  | ||||||
|  						   SBSDIO_DEVICE_CTL, &err); |  | ||||||
|  			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; |  | ||||||
| -			brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, |  | ||||||
| -					  devctl, &err); |  | ||||||
| +			brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL, |  | ||||||
| +					   devctl, &err); |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
|  		/* Otherwise, wait here (polling) for HT Avail */ |  | ||||||
|  		timeout = jiffies + |  | ||||||
|  			  msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000); |  | ||||||
|  		while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { |  | ||||||
| -			clkctl = brcmf_sdiod_regrb(bus->sdiodev, |  | ||||||
| +			clkctl = brcmf_sdiod_readb(bus->sdiodev, |  | ||||||
|  						   SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
|  						   &err); |  | ||||||
|  			if (time_after(jiffies, timeout)) |  | ||||||
| @@ -852,16 +852,16 @@ static int brcmf_sdio_htclk(struct brcmf |  | ||||||
|   |  | ||||||
|  		if (bus->clkstate == CLK_PENDING) { |  | ||||||
|  			/* Cancel CA-only interrupt filter */ |  | ||||||
| -			devctl = brcmf_sdiod_regrb(bus->sdiodev, |  | ||||||
| +			devctl = brcmf_sdiod_readb(bus->sdiodev, |  | ||||||
|  						   SBSDIO_DEVICE_CTL, &err); |  | ||||||
|  			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; |  | ||||||
| -			brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, |  | ||||||
| -					  devctl, &err); |  | ||||||
| +			brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL, |  | ||||||
| +					   devctl, &err); |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
|  		bus->clkstate = CLK_SDONLY; |  | ||||||
| -		brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| -				  clkreq, &err); |  | ||||||
| +		brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| +				   clkreq, &err); |  | ||||||
|  		brcmf_dbg(SDIO, "CLKCTL: turned OFF\n"); |  | ||||||
|  		if (err) { |  | ||||||
|  			brcmf_err("Failed access turning clock off: %d\n", |  | ||||||
| @@ -951,14 +951,14 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio * |  | ||||||
|   |  | ||||||
|  		/* Going to sleep */ |  | ||||||
|  		if (sleep) { |  | ||||||
| -			clkcsr = brcmf_sdiod_regrb(bus->sdiodev, |  | ||||||
| +			clkcsr = brcmf_sdiod_readb(bus->sdiodev, |  | ||||||
|  						   SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
|  						   &err); |  | ||||||
|  			if ((clkcsr & SBSDIO_CSR_MASK) == 0) { |  | ||||||
|  				brcmf_dbg(SDIO, "no clock, set ALP\n"); |  | ||||||
| -				brcmf_sdiod_regwb(bus->sdiodev, |  | ||||||
| -						  SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| -						  SBSDIO_ALP_AVAIL_REQ, &err); |  | ||||||
| +				brcmf_sdiod_writeb(bus->sdiodev, |  | ||||||
| +						   SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| +						   SBSDIO_ALP_AVAIL_REQ, &err); |  | ||||||
|  			} |  | ||||||
|  			err = brcmf_sdio_kso_control(bus, false); |  | ||||||
|  		} else { |  | ||||||
| @@ -1178,16 +1178,16 @@ static void brcmf_sdio_rxfail(struct brc |  | ||||||
|  	if (abort) |  | ||||||
|  		brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2); |  | ||||||
|   |  | ||||||
| -	brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, |  | ||||||
| -			  SFC_RF_TERM, &err); |  | ||||||
| +	brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, |  | ||||||
| +			   &err); |  | ||||||
|  	bus->sdcnt.f1regdata++; |  | ||||||
|   |  | ||||||
|  	/* Wait until the packet has been flushed (device/FIFO stable) */ |  | ||||||
|  	for (lastrbc = retries = 0xffff; retries > 0; retries--) { |  | ||||||
| -		hi = brcmf_sdiod_regrb(bus->sdiodev, |  | ||||||
| -				       SBSDIO_FUNC1_RFRAMEBCHI, &err); |  | ||||||
| -		lo = brcmf_sdiod_regrb(bus->sdiodev, |  | ||||||
| -				       SBSDIO_FUNC1_RFRAMEBCLO, &err); |  | ||||||
| +		hi = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCHI, |  | ||||||
| +				       &err); |  | ||||||
| +		lo = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCLO, |  | ||||||
| +				       &err); |  | ||||||
|  		bus->sdcnt.f1regdata += 2; |  | ||||||
|   |  | ||||||
|  		if ((hi == 0) && (lo == 0)) |  | ||||||
| @@ -1229,12 +1229,12 @@ static void brcmf_sdio_txfail(struct brc |  | ||||||
|  	bus->sdcnt.tx_sderrs++; |  | ||||||
|   |  | ||||||
|  	brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2); |  | ||||||
| -	brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); |  | ||||||
| +	brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); |  | ||||||
|  	bus->sdcnt.f1regdata++; |  | ||||||
|   |  | ||||||
|  	for (i = 0; i < 3; i++) { |  | ||||||
| -		hi = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL); |  | ||||||
| -		lo = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL); |  | ||||||
| +		hi = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL); |  | ||||||
| +		lo = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL); |  | ||||||
|  		bus->sdcnt.f1regdata += 2; |  | ||||||
|  		if ((hi == 0) && (lo == 0)) |  | ||||||
|  			break; |  | ||||||
| @@ -2446,11 +2446,11 @@ static void brcmf_sdio_bus_stop(struct d |  | ||||||
|  		bus->hostintmask = 0; |  | ||||||
|   |  | ||||||
|  		/* Force backplane clocks to assure F2 interrupt propagates */ |  | ||||||
| -		saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| +		saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
|  					    &err); |  | ||||||
|  		if (!err) |  | ||||||
| -			brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| -					  (saveclk | SBSDIO_FORCE_HT), &err); |  | ||||||
| +			brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| +					   (saveclk | SBSDIO_FORCE_HT), &err); |  | ||||||
|  		if (err) |  | ||||||
|  			brcmf_err("Failed to force clock for F2: err %d\n", |  | ||||||
|  				  err); |  | ||||||
| @@ -2509,7 +2509,7 @@ static int brcmf_sdio_intr_rstatus(struc |  | ||||||
|  	buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); |  | ||||||
|  	addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus); |  | ||||||
|   |  | ||||||
| -	val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret); |  | ||||||
| +	val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret); |  | ||||||
|  	bus->sdcnt.f1regdata++; |  | ||||||
|  	if (ret != 0) |  | ||||||
|  		return ret; |  | ||||||
| @@ -2519,7 +2519,7 @@ static int brcmf_sdio_intr_rstatus(struc |  | ||||||
|   |  | ||||||
|  	/* Clear interrupts */ |  | ||||||
|  	if (val) { |  | ||||||
| -		brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret); |  | ||||||
| +		brcmf_sdiod_writel(bus->sdiodev, addr, val, &ret); |  | ||||||
|  		bus->sdcnt.f1regdata++; |  | ||||||
|  		atomic_or(val, &bus->intstatus); |  | ||||||
|  	} |  | ||||||
| @@ -2545,23 +2545,23 @@ static void brcmf_sdio_dpc(struct brcmf_ |  | ||||||
|   |  | ||||||
|  #ifdef DEBUG |  | ||||||
|  		/* Check for inconsistent device control */ |  | ||||||
| -		devctl = brcmf_sdiod_regrb(bus->sdiodev, |  | ||||||
| -					   SBSDIO_DEVICE_CTL, &err); |  | ||||||
| +		devctl = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_DEVICE_CTL, |  | ||||||
| +					   &err); |  | ||||||
|  #endif				/* DEBUG */ |  | ||||||
|   |  | ||||||
|  		/* Read CSR, if clock on switch to AVAIL, else ignore */ |  | ||||||
| -		clkctl = brcmf_sdiod_regrb(bus->sdiodev, |  | ||||||
| +		clkctl = brcmf_sdiod_readb(bus->sdiodev, |  | ||||||
|  					   SBSDIO_FUNC1_CHIPCLKCSR, &err); |  | ||||||
|   |  | ||||||
|  		brcmf_dbg(SDIO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", |  | ||||||
|  			  devctl, clkctl); |  | ||||||
|   |  | ||||||
|  		if (SBSDIO_HTAV(clkctl)) { |  | ||||||
| -			devctl = brcmf_sdiod_regrb(bus->sdiodev, |  | ||||||
| +			devctl = brcmf_sdiod_readb(bus->sdiodev, |  | ||||||
|  						   SBSDIO_DEVICE_CTL, &err); |  | ||||||
|  			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; |  | ||||||
| -			brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, |  | ||||||
| -					  devctl, &err); |  | ||||||
| +			brcmf_sdiod_writeb(bus->sdiodev, |  | ||||||
| +					   SBSDIO_DEVICE_CTL, devctl, &err); |  | ||||||
|  			bus->clkstate = CLK_AVAIL; |  | ||||||
|  		} |  | ||||||
|  	} |  | ||||||
| @@ -3347,31 +3347,31 @@ static void brcmf_sdio_sr_init(struct br |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
|   |  | ||||||
| -	val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err); |  | ||||||
| +	val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err); |  | ||||||
|  	if (err) { |  | ||||||
|  		brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n"); |  | ||||||
|  		return; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT; |  | ||||||
| -	brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err); |  | ||||||
| +	brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err); |  | ||||||
|  	if (err) { |  | ||||||
|  		brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n"); |  | ||||||
|  		return; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	/* Add CMD14 Support */ |  | ||||||
| -	brcmf_sdiod_regwb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP, |  | ||||||
| -			  (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | |  | ||||||
| -			   SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT), |  | ||||||
| -			  &err); |  | ||||||
| +	brcmf_sdiod_func0_wb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP, |  | ||||||
| +			     (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | |  | ||||||
| +			      SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT), |  | ||||||
| +			     &err); |  | ||||||
|  	if (err) { |  | ||||||
|  		brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n"); |  | ||||||
|  		return; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| -			  SBSDIO_FORCE_HT, &err); |  | ||||||
| +	brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| +			   SBSDIO_FORCE_HT, &err); |  | ||||||
|  	if (err) { |  | ||||||
|  		brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n"); |  | ||||||
|  		return; |  | ||||||
| @@ -3394,7 +3394,7 @@ static int brcmf_sdio_kso_init(struct br |  | ||||||
|  	if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) |  | ||||||
|  		return 0; |  | ||||||
|   |  | ||||||
| -	val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err); |  | ||||||
| +	val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err); |  | ||||||
|  	if (err) { |  | ||||||
|  		brcmf_err("error reading SBSDIO_FUNC1_SLEEPCSR\n"); |  | ||||||
|  		return err; |  | ||||||
| @@ -3403,8 +3403,8 @@ static int brcmf_sdio_kso_init(struct br |  | ||||||
|  	if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) { |  | ||||||
|  		val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN << |  | ||||||
|  			SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); |  | ||||||
| -		brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, |  | ||||||
| -				  val, &err); |  | ||||||
| +		brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, |  | ||||||
| +				   val, &err); |  | ||||||
|  		if (err) { |  | ||||||
|  			brcmf_err("error writing SBSDIO_FUNC1_SLEEPCSR\n"); |  | ||||||
|  			return err; |  | ||||||
| @@ -3565,9 +3565,9 @@ static void brcmf_sdio_bus_watchdog(stru |  | ||||||
|  				u8 devpend; |  | ||||||
|   |  | ||||||
|  				sdio_claim_host(bus->sdiodev->func[1]); |  | ||||||
| -				devpend = brcmf_sdiod_regrb(bus->sdiodev, |  | ||||||
| -							    SDIO_CCCR_INTx, |  | ||||||
| -							    NULL); |  | ||||||
| +				devpend = brcmf_sdiod_func0_rb(bus->sdiodev, |  | ||||||
| +							       SDIO_CCCR_INTx, |  | ||||||
| +							       NULL); |  | ||||||
|  				sdio_release_host(bus->sdiodev->func[1]); |  | ||||||
|  				intstatus = devpend & (INTR_STATUS_FUNC1 | |  | ||||||
|  						       INTR_STATUS_FUNC2); |  | ||||||
| @@ -3705,12 +3705,12 @@ brcmf_sdio_drivestrengthinit(struct brcm |  | ||||||
|  			} |  | ||||||
|  		} |  | ||||||
|  		addr = CORE_CC_REG(pmu->base, chipcontrol_addr); |  | ||||||
| -		brcmf_sdiod_regwl(sdiodev, addr, 1, NULL); |  | ||||||
| -		cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL); |  | ||||||
| +		brcmf_sdiod_writel(sdiodev, addr, 1, NULL); |  | ||||||
| +		cc_data_temp = brcmf_sdiod_readl(sdiodev, addr, NULL); |  | ||||||
|  		cc_data_temp &= ~str_mask; |  | ||||||
|  		drivestrength_sel <<= str_shift; |  | ||||||
|  		cc_data_temp |= drivestrength_sel; |  | ||||||
| -		brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL); |  | ||||||
| +		brcmf_sdiod_writel(sdiodev, addr, cc_data_temp, NULL); |  | ||||||
|   |  | ||||||
|  		brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n", |  | ||||||
|  			  str_tab[i].strength, drivestrength, cc_data_temp); |  | ||||||
| @@ -3725,7 +3725,7 @@ static int brcmf_sdio_buscoreprep(void * |  | ||||||
|   |  | ||||||
|  	/* Try forcing SDIO core to do ALPAvail request only */ |  | ||||||
|  	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; |  | ||||||
| -	brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); |  | ||||||
| +	brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); |  | ||||||
|  	if (err) { |  | ||||||
|  		brcmf_err("error writing for HT off\n"); |  | ||||||
|  		return err; |  | ||||||
| @@ -3733,8 +3733,7 @@ static int brcmf_sdio_buscoreprep(void * |  | ||||||
|   |  | ||||||
|  	/* If register supported, wait for ALPAvail and then force ALP */ |  | ||||||
|  	/* This may take up to 15 milliseconds */ |  | ||||||
| -	clkval = brcmf_sdiod_regrb(sdiodev, |  | ||||||
| -				   SBSDIO_FUNC1_CHIPCLKCSR, NULL); |  | ||||||
| +	clkval = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, NULL); |  | ||||||
|   |  | ||||||
|  	if ((clkval & ~SBSDIO_AVBITS) != clkset) { |  | ||||||
|  		brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n", |  | ||||||
| @@ -3742,10 +3741,11 @@ static int brcmf_sdio_buscoreprep(void * |  | ||||||
|  		return -EACCES; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev, |  | ||||||
| -					      SBSDIO_FUNC1_CHIPCLKCSR, NULL)), |  | ||||||
| -			!SBSDIO_ALPAV(clkval)), |  | ||||||
| -			PMU_MAX_TRANSITION_DLY); |  | ||||||
| +	SPINWAIT(((clkval = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| +					      NULL)), |  | ||||||
| +		 !SBSDIO_ALPAV(clkval)), |  | ||||||
| +		 PMU_MAX_TRANSITION_DLY); |  | ||||||
| + |  | ||||||
|  	if (!SBSDIO_ALPAV(clkval)) { |  | ||||||
|  		brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n", |  | ||||||
|  			  clkval); |  | ||||||
| @@ -3753,11 +3753,11 @@ static int brcmf_sdio_buscoreprep(void * |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; |  | ||||||
| -	brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); |  | ||||||
| +	brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); |  | ||||||
|  	udelay(65); |  | ||||||
|   |  | ||||||
|  	/* Also, disable the extra SDIO pull-ups */ |  | ||||||
| -	brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); |  | ||||||
| +	brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); |  | ||||||
|   |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
| @@ -3772,7 +3772,7 @@ static void brcmf_sdio_buscore_activate( |  | ||||||
|  	/* clear all interrupts */ |  | ||||||
|  	core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV); |  | ||||||
|  	reg_addr = core->base + offsetof(struct sdpcmd_regs, intstatus); |  | ||||||
| -	brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); |  | ||||||
| +	brcmf_sdiod_writel(sdiodev, reg_addr, 0xFFFFFFFF, NULL); |  | ||||||
|   |  | ||||||
|  	if (rstvec) |  | ||||||
|  		/* Write reset vector to address 0 */ |  | ||||||
| @@ -3785,7 +3785,7 @@ static u32 brcmf_sdio_buscore_read32(voi |  | ||||||
|  	struct brcmf_sdio_dev *sdiodev = ctx; |  | ||||||
|  	u32 val, rev; |  | ||||||
|   |  | ||||||
| -	val = brcmf_sdiod_regrl(sdiodev, addr, NULL); |  | ||||||
| +	val = brcmf_sdiod_readl(sdiodev, addr, NULL); |  | ||||||
|  	if ((sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 || |  | ||||||
|  	     sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) && |  | ||||||
|  	    addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { |  | ||||||
| @@ -3802,7 +3802,7 @@ static void brcmf_sdio_buscore_write32(v |  | ||||||
|  { |  | ||||||
|  	struct brcmf_sdio_dev *sdiodev = ctx; |  | ||||||
|   |  | ||||||
| -	brcmf_sdiod_regwl(sdiodev, addr, val, NULL); |  | ||||||
| +	brcmf_sdiod_writel(sdiodev, addr, val, NULL); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = { |  | ||||||
| @@ -3826,18 +3826,18 @@ brcmf_sdio_probe_attach(struct brcmf_sdi |  | ||||||
|  	sdio_claim_host(sdiodev->func[1]); |  | ||||||
|   |  | ||||||
|  	pr_debug("F1 signature read @0x18000000=0x%4x\n", |  | ||||||
| -		 brcmf_sdiod_regrl(sdiodev, SI_ENUM_BASE, NULL)); |  | ||||||
| +		 brcmf_sdiod_readl(sdiodev, SI_ENUM_BASE, NULL)); |  | ||||||
|   |  | ||||||
|  	/* |  | ||||||
|  	 * Force PLL off until brcmf_chip_attach() |  | ||||||
|  	 * programs PLL control regs |  | ||||||
|  	 */ |  | ||||||
|   |  | ||||||
| -	brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| -			  BRCMF_INIT_CLKCTL1, &err); |  | ||||||
| +	brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, BRCMF_INIT_CLKCTL1, |  | ||||||
| +			   &err); |  | ||||||
|  	if (!err) |  | ||||||
| -		clkctl = brcmf_sdiod_regrb(sdiodev, |  | ||||||
| -					   SBSDIO_FUNC1_CHIPCLKCSR, &err); |  | ||||||
| +		clkctl = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| +					   &err); |  | ||||||
|   |  | ||||||
|  	if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) { |  | ||||||
|  		brcmf_err("ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n", |  | ||||||
| @@ -3897,25 +3897,25 @@ brcmf_sdio_probe_attach(struct brcmf_sdi |  | ||||||
|  	brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength); |  | ||||||
|   |  | ||||||
|  	/* Set card control so an SDIO card reset does a WLAN backplane reset */ |  | ||||||
| -	reg_val = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err); |  | ||||||
| +	reg_val = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err); |  | ||||||
|  	if (err) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
|  	reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET; |  | ||||||
|   |  | ||||||
| -	brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); |  | ||||||
| +	brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); |  | ||||||
|  	if (err) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
|  	/* set PMUControl so a backplane reset does PMU state reload */ |  | ||||||
|  	reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol); |  | ||||||
| -	reg_val = brcmf_sdiod_regrl(sdiodev, reg_addr, &err); |  | ||||||
| +	reg_val = brcmf_sdiod_readl(sdiodev, reg_addr, &err); |  | ||||||
|  	if (err) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
|  	reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT); |  | ||||||
|   |  | ||||||
| -	brcmf_sdiod_regwl(sdiodev, reg_addr, reg_val, &err); |  | ||||||
| +	brcmf_sdiod_writel(sdiodev, reg_addr, reg_val, &err); |  | ||||||
|  	if (err) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
| @@ -4055,10 +4055,10 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  		goto release; |  | ||||||
|   |  | ||||||
|  	/* Force clocks on backplane to be sure F2 interrupt propagates */ |  | ||||||
| -	saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); |  | ||||||
| +	saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); |  | ||||||
|  	if (!err) { |  | ||||||
| -		brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| -				  (saveclk | SBSDIO_FORCE_HT), &err); |  | ||||||
| +		brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| +				   (saveclk | SBSDIO_FORCE_HT), &err); |  | ||||||
|  	} |  | ||||||
|  	if (err) { |  | ||||||
|  		brcmf_err("Failed to force clock for F2: err %d\n", err); |  | ||||||
| @@ -4080,7 +4080,7 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  		w_sdreg32(bus, bus->hostintmask, |  | ||||||
|  			  offsetof(struct sdpcmd_regs, hostintmask)); |  | ||||||
|   |  | ||||||
| -		brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK, 8, &err); |  | ||||||
| +		brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err); |  | ||||||
|  	} else { |  | ||||||
|  		/* Disable F2 again */ |  | ||||||
|  		sdio_disable_func(sdiodev->func[SDIO_FUNC_2]); |  | ||||||
| @@ -4091,8 +4091,8 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  		brcmf_sdio_sr_init(bus); |  | ||||||
|  	} else { |  | ||||||
|  		/* Restore previous clock setting */ |  | ||||||
| -		brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| -				  saveclk, &err); |  | ||||||
| +		brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| +				   saveclk, &err); |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	if (err == 0) { |  | ||||||
| @@ -4225,7 +4225,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru |  | ||||||
|  	bus->rxflow = false; |  | ||||||
|   |  | ||||||
|  	/* Done with backplane-dependent accesses, can drop clock... */ |  | ||||||
| -	brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); |  | ||||||
| +	brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); |  | ||||||
|   |  | ||||||
|  	sdio_release_host(bus->sdiodev->func[1]); |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| @@ -50,6 +50,7 @@ |  | ||||||
|  #define SBSDIO_NUM_FUNCTION		3 |  | ||||||
|   |  | ||||||
|  /* function 0 vendor specific CCCR registers */ |  | ||||||
| + |  | ||||||
|  #define SDIO_CCCR_BRCM_CARDCAP			0xf0 |  | ||||||
|  #define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT	0x02 |  | ||||||
|  #define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT	0x04 |  | ||||||
| @@ -131,8 +132,6 @@ |  | ||||||
|  /* with b15, maps to 32-bit SB access */ |  | ||||||
|  #define SBSDIO_SB_ACCESS_2_4B_FLAG	0x08000 |  | ||||||
|   |  | ||||||
| -/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */ |  | ||||||
| - |  | ||||||
|  /* Address bits from SBADDR regs */ |  | ||||||
|  #define SBSDIO_SBWINDOW_MASK		0xffff8000 |  | ||||||
|   |  | ||||||
| @@ -293,13 +292,24 @@ struct sdpcmd_regs { |  | ||||||
|  int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev); |  | ||||||
|  void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev); |  | ||||||
|   |  | ||||||
| -/* sdio device register access interface */ |  | ||||||
| -u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); |  | ||||||
| -u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); |  | ||||||
| -void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 data, |  | ||||||
| -		       int *ret); |  | ||||||
| -void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, |  | ||||||
| -		       int *ret); |  | ||||||
| +/* SDIO device register access interface */ |  | ||||||
| +/* Accessors for SDIO Function 0 */ |  | ||||||
| +#define brcmf_sdiod_func0_rb(sdiodev, addr, r) \ |  | ||||||
| +	sdio_readb((sdiodev)->func[0], (addr), (r)) |  | ||||||
| + |  | ||||||
| +#define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \ |  | ||||||
| +	sdio_writeb((sdiodev)->func[0], (v), (addr), (ret)) |  | ||||||
| + |  | ||||||
| +/* Accessors for SDIO Function 1 */ |  | ||||||
| +#define brcmf_sdiod_readb(sdiodev, addr, r) \ |  | ||||||
| +	sdio_readb((sdiodev)->func[1], (addr), (r)) |  | ||||||
| + |  | ||||||
| +#define brcmf_sdiod_writeb(sdiodev, addr, v, ret) \ |  | ||||||
| +	sdio_writeb((sdiodev)->func[1], (v), (addr), (ret)) |  | ||||||
| + |  | ||||||
| +u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); |  | ||||||
| +void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, |  | ||||||
| +			int *ret); |  | ||||||
|   |  | ||||||
|  /* Buffer transfer to/from device (client) core via cmd53. |  | ||||||
|   *   fn:       function number |  | ||||||
| @@ -1,59 +0,0 @@ | |||||||
| From eeef8a5da781e11746347b3cd9f1942be48ebaf0 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Fri, 8 Dec 2017 13:10:30 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Tidy register definitions a little |  | ||||||
|  |  | ||||||
| Trivial tidy of register definitions. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  4 ++-- |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 19 ++++++++++--------- |  | ||||||
|  2 files changed, 12 insertions(+), 11 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -153,9 +153,9 @@ int brcmf_sdiod_intr_register(struct brc |  | ||||||
|  		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret); |  | ||||||
|   |  | ||||||
|  		/* redirect, configure and enable io for interrupt signal */ |  | ||||||
| -		data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; |  | ||||||
| +		data = SDIO_CCCR_BRCM_SEPINT_MASK | SDIO_CCCR_BRCM_SEPINT_OE; |  | ||||||
|  		if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) |  | ||||||
| -			data |= SDIO_SEPINT_ACT_HI; |  | ||||||
| +			data |= SDIO_CCCR_BRCM_SEPINT_ACT_HI; |  | ||||||
|  		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, |  | ||||||
|  				     data, &ret); |  | ||||||
|  		sdio_release_host(sdiodev->func[1]); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| @@ -52,16 +52,17 @@ |  | ||||||
|  /* function 0 vendor specific CCCR registers */ |  | ||||||
|   |  | ||||||
|  #define SDIO_CCCR_BRCM_CARDCAP			0xf0 |  | ||||||
| -#define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT	0x02 |  | ||||||
| -#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT	0x04 |  | ||||||
| -#define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC	0x08 |  | ||||||
| -#define SDIO_CCCR_BRCM_CARDCTRL		0xf1 |  | ||||||
| -#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET	0x02 |  | ||||||
| -#define SDIO_CCCR_BRCM_SEPINT			0xf2 |  | ||||||
| +#define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT	BIT(1) |  | ||||||
| +#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT	BIT(2) |  | ||||||
| +#define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC	BIT(3) |  | ||||||
| + |  | ||||||
| +#define SDIO_CCCR_BRCM_CARDCTRL			0xf1 |  | ||||||
| +#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET	BIT(1) |  | ||||||
|   |  | ||||||
| -#define  SDIO_SEPINT_MASK		0x01 |  | ||||||
| -#define  SDIO_SEPINT_OE			0x02 |  | ||||||
| -#define  SDIO_SEPINT_ACT_HI		0x04 |  | ||||||
| +#define SDIO_CCCR_BRCM_SEPINT			0xf2 |  | ||||||
| +#define SDIO_CCCR_BRCM_SEPINT_MASK		BIT(0) |  | ||||||
| +#define SDIO_CCCR_BRCM_SEPINT_OE		BIT(1) |  | ||||||
| +#define SDIO_CCCR_BRCM_SEPINT_ACT_HI		BIT(2) |  | ||||||
|   |  | ||||||
|  /* function 1 miscellaneous registers */ |  | ||||||
|   |  | ||||||
| @@ -1,190 +0,0 @@ | |||||||
| From a7c3aa1509e243a09c5b1660c8702d792ca76aed Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Fri, 8 Dec 2017 13:10:31 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Remove brcmf_sdiod_addrprep() |  | ||||||
|  |  | ||||||
| This function has become trivial enough that it may as well be pushed into |  | ||||||
| its callers, which has the side-benefit of clarifying what's going on. |  | ||||||
|  |  | ||||||
| Remove it, and rename brcmf_sdiod_set_sbaddr_window() to |  | ||||||
| brcmf_sdiod_set_backplane_window() as it's easier to understand. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 84 ++++++++++++---------- |  | ||||||
|  1 file changed, 46 insertions(+), 38 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -230,41 +230,25 @@ void brcmf_sdiod_change_state(struct brc |  | ||||||
|  	sdiodev->state = state; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, |  | ||||||
| -					 u32 address) |  | ||||||
| +static int brcmf_sdiod_set_backplane_window(struct brcmf_sdio_dev *sdiodev, |  | ||||||
| +					    u32 addr) |  | ||||||
|  { |  | ||||||
| +	u32 v, bar0 = addr & SBSDIO_SBWINDOW_MASK; |  | ||||||
|  	int err = 0, i; |  | ||||||
| -	u32 addr; |  | ||||||
|   |  | ||||||
| -	if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) |  | ||||||
| -		return -ENOMEDIUM; |  | ||||||
| +	if (bar0 == sdiodev->sbwad) |  | ||||||
| +		return 0; |  | ||||||
|   |  | ||||||
| -	addr = (address & SBSDIO_SBWINDOW_MASK) >> 8; |  | ||||||
| +	v = bar0 >> 8; |  | ||||||
|   |  | ||||||
| -	for (i = 0 ; i < 3 && !err ; i++, addr >>= 8) |  | ||||||
| +	for (i = 0 ; i < 3 && !err ; i++, v >>= 8) |  | ||||||
|  		brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, |  | ||||||
| -				   addr & 0xff, &err); |  | ||||||
| - |  | ||||||
| -	return err; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
| -static int brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr) |  | ||||||
| -{ |  | ||||||
| -	uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
| -	int err = 0; |  | ||||||
| - |  | ||||||
| -	if (bar0 != sdiodev->sbwad) { |  | ||||||
| -		err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0); |  | ||||||
| -		if (err) |  | ||||||
| -			return err; |  | ||||||
| +				   v & 0xff, &err); |  | ||||||
|   |  | ||||||
| +	if (!err) |  | ||||||
|  		sdiodev->sbwad = bar0; |  | ||||||
| -	} |  | ||||||
|   |  | ||||||
| -	*addr &= SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
| -	*addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
| - |  | ||||||
| -	return 0; |  | ||||||
| +	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) |  | ||||||
| @@ -272,11 +256,16 @@ u32 brcmf_sdiod_readl(struct brcmf_sdio_ |  | ||||||
|  	u32 data = 0; |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
| -	retval = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
| +	retval = brcmf_sdiod_set_backplane_window(sdiodev, addr); |  | ||||||
| +	if (retval) |  | ||||||
| +		goto out; |  | ||||||
| + |  | ||||||
| +	addr &= SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
| +	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
|   |  | ||||||
| -	if (!retval) |  | ||||||
| -		data = sdio_readl(sdiodev->func[1], addr, &retval); |  | ||||||
| +	data = sdio_readl(sdiodev->func[1], addr, &retval); |  | ||||||
|   |  | ||||||
| +out: |  | ||||||
|  	if (ret) |  | ||||||
|  		*ret = retval; |  | ||||||
|   |  | ||||||
| @@ -288,11 +277,16 @@ void brcmf_sdiod_writel(struct brcmf_sdi |  | ||||||
|  { |  | ||||||
|  	int retval; |  | ||||||
|   |  | ||||||
| -	retval = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
| +	retval = brcmf_sdiod_set_backplane_window(sdiodev, addr); |  | ||||||
| +	if (retval) |  | ||||||
| +		goto out; |  | ||||||
|   |  | ||||||
| -	if (!retval) |  | ||||||
| -		sdio_writel(sdiodev->func[1], data, addr, &retval); |  | ||||||
| +	addr &= SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
| +	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
|   |  | ||||||
| +	sdio_writel(sdiodev->func[1], data, addr, &retval); |  | ||||||
| + |  | ||||||
| +out: |  | ||||||
|  	if (ret) |  | ||||||
|  		*ret = retval; |  | ||||||
|  } |  | ||||||
| @@ -540,10 +534,13 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len); |  | ||||||
|   |  | ||||||
| -	err = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
| +	err = brcmf_sdiod_set_backplane_window(sdiodev, addr); |  | ||||||
|  	if (err) |  | ||||||
|  		goto done; |  | ||||||
|   |  | ||||||
| +	addr &= SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
| +	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
| + |  | ||||||
|  	err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt); |  | ||||||
|   |  | ||||||
|  done: |  | ||||||
| @@ -561,10 +558,13 @@ int brcmf_sdiod_recv_chain(struct brcmf_ |  | ||||||
|  	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", |  | ||||||
|  		  addr, pktq->qlen); |  | ||||||
|   |  | ||||||
| -	err = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
| +	err = brcmf_sdiod_set_backplane_window(sdiodev, addr); |  | ||||||
|  	if (err) |  | ||||||
|  		goto done; |  | ||||||
|   |  | ||||||
| +	addr &= SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
| +	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
| + |  | ||||||
|  	if (pktq->qlen == 1) |  | ||||||
|  		err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, |  | ||||||
|  					    pktq->next); |  | ||||||
| @@ -606,7 +606,12 @@ int brcmf_sdiod_send_buf(struct brcmf_sd |  | ||||||
|   |  | ||||||
|  	memcpy(mypkt->data, buf, nbytes); |  | ||||||
|   |  | ||||||
| -	err = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
| +	err = brcmf_sdiod_set_backplane_window(sdiodev, addr); |  | ||||||
| +	if (err) |  | ||||||
| +		return err; |  | ||||||
| + |  | ||||||
| +	addr &= SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
| +	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
|   |  | ||||||
|  	if (!err) |  | ||||||
|  		err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt); |  | ||||||
| @@ -625,10 +630,13 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen); |  | ||||||
|   |  | ||||||
| -	err = brcmf_sdiod_addrprep(sdiodev, &addr); |  | ||||||
| +	err = brcmf_sdiod_set_backplane_window(sdiodev, addr); |  | ||||||
|  	if (err) |  | ||||||
|  		return err; |  | ||||||
|   |  | ||||||
| +	addr &= SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
| +	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
| + |  | ||||||
|  	if (pktq->qlen == 1 || !sdiodev->sg_support) { |  | ||||||
|  		skb_queue_walk(pktq, skb) { |  | ||||||
|  			err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, |  | ||||||
| @@ -673,7 +681,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev |  | ||||||
|  	/* Do the transfer(s) */ |  | ||||||
|  	while (size) { |  | ||||||
|  		/* Set the backplane window to include the start address */ |  | ||||||
| -		err = brcmf_sdiod_set_sbaddr_window(sdiodev, address); |  | ||||||
| +		err = brcmf_sdiod_set_backplane_window(sdiodev, address); |  | ||||||
|  		if (err) |  | ||||||
|  			break; |  | ||||||
|   |  | ||||||
| @@ -716,7 +724,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev |  | ||||||
|  	dev_kfree_skb(pkt); |  | ||||||
|   |  | ||||||
|  	/* Return the window to backplane enumeration space for core access */ |  | ||||||
| -	if (brcmf_sdiod_set_sbaddr_window(sdiodev, sdiodev->sbwad)) |  | ||||||
| +	if (brcmf_sdiod_set_backplane_window(sdiodev, sdiodev->sbwad)) |  | ||||||
|  		brcmf_err("FAILED to set window back to 0x%x\n", |  | ||||||
|  			  sdiodev->sbwad); |  | ||||||
|   |  | ||||||
| @@ -1,32 +0,0 @@ | |||||||
| From c900072bd6faff089aa4fb7b19136a2a0fe3baf0 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Fri, 8 Dec 2017 13:10:32 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: remove unnecessary call to |  | ||||||
|  brcmf_sdiod_set_backplane_window() |  | ||||||
|  |  | ||||||
| All functions that might require the window address changing call |  | ||||||
| brcmf_sdiod_set_backplane_window() prior to access. Thus resetting |  | ||||||
| the window is not required. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| [arend: corrected the driver prefix in the subject] |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 5 ----- |  | ||||||
|  1 file changed, 5 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -723,11 +723,6 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev |  | ||||||
|   |  | ||||||
|  	dev_kfree_skb(pkt); |  | ||||||
|   |  | ||||||
| -	/* Return the window to backplane enumeration space for core access */ |  | ||||||
| -	if (brcmf_sdiod_set_backplane_window(sdiodev, sdiodev->sbwad)) |  | ||||||
| -		brcmf_err("FAILED to set window back to 0x%x\n", |  | ||||||
| -			  sdiodev->sbwad); |  | ||||||
| - |  | ||||||
|  	sdio_release_host(sdiodev->func[1]); |  | ||||||
|   |  | ||||||
|  	return err; |  | ||||||
| @@ -1,134 +0,0 @@ | |||||||
| From e4c05fc3c0a6c79376f72f17d08014477e962ada Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Fri, 8 Dec 2017 13:10:33 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Cleanup offsetof() |  | ||||||
|  |  | ||||||
| Create a macro to make the code a bit more readable, whilst we're stuck |  | ||||||
| with using struct element offsets as register offsets. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| [arend: rename macro to SD_REG] |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 35 +++++++++------------- |  | ||||||
|  1 file changed, 14 insertions(+), 21 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -161,6 +161,8 @@ struct rte_console { |  | ||||||
|   |  | ||||||
|  #define CORE_BUS_REG(base, field) \ |  | ||||||
|  		(base + offsetof(struct sdpcmd_regs, field)) |  | ||||||
| +#define SD_REG(field) \ |  | ||||||
| +		(offsetof(struct sdpcmd_regs, field)) |  | ||||||
|   |  | ||||||
|  /* SDIO function 1 register CHIPCLKCSR */ |  | ||||||
|  /* Force ALP request to backplane */ |  | ||||||
| @@ -1087,12 +1089,10 @@ static u32 brcmf_sdio_hostmail(struct br |  | ||||||
|  	brcmf_dbg(SDIO, "Enter\n"); |  | ||||||
|   |  | ||||||
|  	/* Read mailbox data and ack that we did so */ |  | ||||||
| -	ret = r_sdreg32(bus, &hmb_data, |  | ||||||
| -			offsetof(struct sdpcmd_regs, tohostmailboxdata)); |  | ||||||
| +	ret = r_sdreg32(bus, &hmb_data,	SD_REG(tohostmailboxdata)); |  | ||||||
|   |  | ||||||
|  	if (ret == 0) |  | ||||||
| -		w_sdreg32(bus, SMB_INT_ACK, |  | ||||||
| -			  offsetof(struct sdpcmd_regs, tosbmailbox)); |  | ||||||
| +		w_sdreg32(bus, SMB_INT_ACK, SD_REG(tosbmailbox)); |  | ||||||
|  	bus->sdcnt.f1regdata += 2; |  | ||||||
|   |  | ||||||
|  	/* dongle indicates the firmware has halted/crashed */ |  | ||||||
| @@ -1207,8 +1207,7 @@ static void brcmf_sdio_rxfail(struct brc |  | ||||||
|   |  | ||||||
|  	if (rtx) { |  | ||||||
|  		bus->sdcnt.rxrtx++; |  | ||||||
| -		err = w_sdreg32(bus, SMB_NAK, |  | ||||||
| -				offsetof(struct sdpcmd_regs, tosbmailbox)); |  | ||||||
| +		err = w_sdreg32(bus, SMB_NAK, SD_REG(tosbmailbox)); |  | ||||||
|   |  | ||||||
|  		bus->sdcnt.f1regdata++; |  | ||||||
|  		if (err == 0) |  | ||||||
| @@ -2333,9 +2332,7 @@ static uint brcmf_sdio_sendfromq(struct |  | ||||||
|  		if (!bus->intr) { |  | ||||||
|  			/* Check device status, signal pending interrupt */ |  | ||||||
|  			sdio_claim_host(bus->sdiodev->func[1]); |  | ||||||
| -			ret = r_sdreg32(bus, &intstatus, |  | ||||||
| -					offsetof(struct sdpcmd_regs, |  | ||||||
| -						 intstatus)); |  | ||||||
| +			ret = r_sdreg32(bus, &intstatus, SD_REG(intstatus)); |  | ||||||
|  			sdio_release_host(bus->sdiodev->func[1]); |  | ||||||
|  			bus->sdcnt.f2txdata++; |  | ||||||
|  			if (ret != 0) |  | ||||||
| @@ -2441,7 +2438,7 @@ static void brcmf_sdio_bus_stop(struct d |  | ||||||
|  		brcmf_sdio_bus_sleep(bus, false, false); |  | ||||||
|   |  | ||||||
|  		/* Disable and clear interrupts at the chip level also */ |  | ||||||
| -		w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask)); |  | ||||||
| +		w_sdreg32(bus, 0, SD_REG(hostintmask)); |  | ||||||
|  		local_hostintmask = bus->hostintmask; |  | ||||||
|  		bus->hostintmask = 0; |  | ||||||
|   |  | ||||||
| @@ -2460,8 +2457,7 @@ static void brcmf_sdio_bus_stop(struct d |  | ||||||
|  		sdio_disable_func(sdiodev->func[SDIO_FUNC_2]); |  | ||||||
|   |  | ||||||
|  		/* Clear any pending interrupts now that F2 is disabled */ |  | ||||||
| -		w_sdreg32(bus, local_hostintmask, |  | ||||||
| -			  offsetof(struct sdpcmd_regs, intstatus)); |  | ||||||
| +		w_sdreg32(bus, local_hostintmask, SD_REG(intstatus)); |  | ||||||
|   |  | ||||||
|  		sdio_release_host(sdiodev->func[1]); |  | ||||||
|  	} |  | ||||||
| @@ -2507,7 +2503,7 @@ static int brcmf_sdio_intr_rstatus(struc |  | ||||||
|  	int ret; |  | ||||||
|   |  | ||||||
|  	buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); |  | ||||||
| -	addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus); |  | ||||||
| +	addr = buscore->base + SD_REG(intstatus); |  | ||||||
|   |  | ||||||
|  	val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret); |  | ||||||
|  	bus->sdcnt.f1regdata++; |  | ||||||
| @@ -2584,11 +2580,9 @@ static void brcmf_sdio_dpc(struct brcmf_ |  | ||||||
|  	 */ |  | ||||||
|  	if (intstatus & I_HMB_FC_CHANGE) { |  | ||||||
|  		intstatus &= ~I_HMB_FC_CHANGE; |  | ||||||
| -		err = w_sdreg32(bus, I_HMB_FC_CHANGE, |  | ||||||
| -				offsetof(struct sdpcmd_regs, intstatus)); |  | ||||||
| +		err = w_sdreg32(bus, I_HMB_FC_CHANGE, SD_REG(intstatus)); |  | ||||||
|   |  | ||||||
| -		err = r_sdreg32(bus, &newstatus, |  | ||||||
| -				offsetof(struct sdpcmd_regs, intstatus)); |  | ||||||
| +		err = r_sdreg32(bus, &newstatus, SD_REG(intstatus)); |  | ||||||
|  		bus->sdcnt.f1regdata += 2; |  | ||||||
|  		atomic_set(&bus->fcstate, |  | ||||||
|  			   !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE))); |  | ||||||
| @@ -3771,7 +3765,7 @@ static void brcmf_sdio_buscore_activate( |  | ||||||
|   |  | ||||||
|  	/* clear all interrupts */ |  | ||||||
|  	core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV); |  | ||||||
| -	reg_addr = core->base + offsetof(struct sdpcmd_regs, intstatus); |  | ||||||
| +	reg_addr = core->base + SD_REG(intstatus); |  | ||||||
|  	brcmf_sdiod_writel(sdiodev, reg_addr, 0xFFFFFFFF, NULL); |  | ||||||
|   |  | ||||||
|  	if (rstvec) |  | ||||||
| @@ -4067,7 +4061,7 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|   |  | ||||||
|  	/* Enable function 2 (frame transfers) */ |  | ||||||
|  	w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, |  | ||||||
| -		  offsetof(struct sdpcmd_regs, tosbmailboxdata)); |  | ||||||
| +		  SD_REG(tosbmailboxdata)); |  | ||||||
|  	err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]); |  | ||||||
|   |  | ||||||
|   |  | ||||||
| @@ -4077,8 +4071,7 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  	if (!err) { |  | ||||||
|  		/* Set up the interrupt mask and enable interrupts */ |  | ||||||
|  		bus->hostintmask = HOSTINTMASK; |  | ||||||
| -		w_sdreg32(bus, bus->hostintmask, |  | ||||||
| -			  offsetof(struct sdpcmd_regs, hostintmask)); |  | ||||||
| +		w_sdreg32(bus, bus->hostintmask, SD_REG(hostintmask)); |  | ||||||
|   |  | ||||||
|  		brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err); |  | ||||||
|  	} else { |  | ||||||
| @@ -1,26 +0,0 @@ | |||||||
| From 5cfe38f1f8d3c6b98e15b8cfde05028a3c79930b Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Fri, 8 Dec 2017 13:10:34 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Remove unused macro. |  | ||||||
|  |  | ||||||
| This macro is used exactly nowhere in the code. Delete it. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 -- |  | ||||||
|  1 file changed, 2 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -159,8 +159,6 @@ struct rte_console { |  | ||||||
|  /* manfid tuple length, include tuple, link bytes */ |  | ||||||
|  #define SBSDIO_CIS_MANFID_TUPLE_LEN	6 |  | ||||||
|   |  | ||||||
| -#define CORE_BUS_REG(base, field) \ |  | ||||||
| -		(base + offsetof(struct sdpcmd_regs, field)) |  | ||||||
|  #define SD_REG(field) \ |  | ||||||
|  		(offsetof(struct sdpcmd_regs, field)) |  | ||||||
|   |  | ||||||
| @@ -1,128 +0,0 @@ | |||||||
| From 21a10846d09db3c5e3bdfb0be0fc7aa9fdc7000a Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Fri, 8 Dec 2017 13:10:35 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Remove repeated calls to brcmf_chip_get_core() |  | ||||||
|  |  | ||||||
| There is no need to repeatdly call brcmf_chip_get_core(), which |  | ||||||
| traverses a list of cores every time its called (including during |  | ||||||
| register access code!). |  | ||||||
|  |  | ||||||
| Call it once, and store a pointer to the core structure. The existing |  | ||||||
| code does nto keep track of users of the cores anyway, and even so, this |  | ||||||
| will allow for easier refcounting in future. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 25 +++++++++++++--------- |  | ||||||
|  1 file changed, 15 insertions(+), 10 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -436,6 +436,7 @@ struct brcmf_sdio_count { |  | ||||||
|  struct brcmf_sdio { |  | ||||||
|  	struct brcmf_sdio_dev *sdiodev;	/* sdio device handler */ |  | ||||||
|  	struct brcmf_chip *ci;	/* Chip info struct */ |  | ||||||
| +	struct brcmf_core *sdio_core; /* sdio core info struct */ |  | ||||||
|   |  | ||||||
|  	u32 hostintmask;	/* Copy of Host Interrupt Mask */ |  | ||||||
|  	atomic_t intstatus;	/* Intstatus bits (events) pending */ |  | ||||||
| @@ -665,10 +666,9 @@ static bool data_ok(struct brcmf_sdio *b |  | ||||||
|   */ |  | ||||||
|  static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_core *core; |  | ||||||
| +	struct brcmf_core *core = bus->sdio_core; |  | ||||||
|  	int ret; |  | ||||||
|   |  | ||||||
| -	core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); |  | ||||||
|  	*regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, &ret); |  | ||||||
|   |  | ||||||
|  	return ret; |  | ||||||
| @@ -676,10 +676,9 @@ static int r_sdreg32(struct brcmf_sdio * |  | ||||||
|   |  | ||||||
|  static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_core *core; |  | ||||||
| +	struct brcmf_core *core = bus->sdio_core; |  | ||||||
|  	int ret; |  | ||||||
|   |  | ||||||
| -	core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); |  | ||||||
|  	brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, &ret); |  | ||||||
|   |  | ||||||
|  	return ret; |  | ||||||
| @@ -2495,12 +2494,11 @@ static inline void brcmf_sdio_clrintr(st |  | ||||||
|   |  | ||||||
|  static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_core *buscore; |  | ||||||
| +	struct brcmf_core *buscore = bus->sdio_core; |  | ||||||
|  	u32 addr; |  | ||||||
|  	unsigned long val; |  | ||||||
|  	int ret; |  | ||||||
|   |  | ||||||
| -	buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); |  | ||||||
|  	addr = buscore->base + SD_REG(intstatus); |  | ||||||
|   |  | ||||||
|  	val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret); |  | ||||||
| @@ -3377,13 +3375,14 @@ static void brcmf_sdio_sr_init(struct br |  | ||||||
|  /* enable KSO bit */ |  | ||||||
|  static int brcmf_sdio_kso_init(struct brcmf_sdio *bus) |  | ||||||
|  { |  | ||||||
| +	struct brcmf_core *core = bus->sdio_core; |  | ||||||
|  	u8 val; |  | ||||||
|  	int err = 0; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
|   |  | ||||||
|  	/* KSO bit added in SDIO core rev 12 */ |  | ||||||
| -	if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) |  | ||||||
| +	if (core->rev < 12) |  | ||||||
|  		return 0; |  | ||||||
|   |  | ||||||
|  	val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err); |  | ||||||
| @@ -3412,6 +3411,7 @@ static int brcmf_sdio_bus_preinit(struct |  | ||||||
|  	struct brcmf_bus *bus_if = dev_get_drvdata(dev); |  | ||||||
|  	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |  | ||||||
|  	struct brcmf_sdio *bus = sdiodev->bus; |  | ||||||
| +	struct brcmf_core *core = bus->sdio_core; |  | ||||||
|  	uint pad_size; |  | ||||||
|  	u32 value; |  | ||||||
|  	int err; |  | ||||||
| @@ -3420,7 +3420,7 @@ static int brcmf_sdio_bus_preinit(struct |  | ||||||
|  	 * a device perspective, ie. bus:txglom affects the |  | ||||||
|  	 * bus transfers from device to host. |  | ||||||
|  	 */ |  | ||||||
| -	if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) { |  | ||||||
| +	if (core->rev < 12) { |  | ||||||
|  		/* for sdio core rev < 12, disable txgloming */ |  | ||||||
|  		value = 0; |  | ||||||
|  		err = brcmf_iovar_data_set(dev, "bus:txglom", &value, |  | ||||||
| @@ -3758,11 +3758,10 @@ static void brcmf_sdio_buscore_activate( |  | ||||||
|  					u32 rstvec) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_sdio_dev *sdiodev = ctx; |  | ||||||
| -	struct brcmf_core *core; |  | ||||||
| +	struct brcmf_core *core = sdiodev->bus->sdio_core; |  | ||||||
|  	u32 reg_addr; |  | ||||||
|   |  | ||||||
|  	/* clear all interrupts */ |  | ||||||
| -	core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV); |  | ||||||
|  	reg_addr = core->base + SD_REG(intstatus); |  | ||||||
|  	brcmf_sdiod_writel(sdiodev, reg_addr, 0xFFFFFFFF, NULL); |  | ||||||
|   |  | ||||||
| @@ -3843,6 +3842,12 @@ brcmf_sdio_probe_attach(struct brcmf_sdi |  | ||||||
|  		bus->ci = NULL; |  | ||||||
|  		goto fail; |  | ||||||
|  	} |  | ||||||
| + |  | ||||||
| +	/* Pick up the SDIO core info struct from chip.c */ |  | ||||||
| +	bus->sdio_core   = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); |  | ||||||
| +	if (!bus->sdio_core) |  | ||||||
| +		goto fail; |  | ||||||
| + |  | ||||||
|  	sdiodev->settings = brcmf_get_module_param(sdiodev->dev, |  | ||||||
|  						   BRCMF_BUSTYPE_SDIO, |  | ||||||
|  						   bus->ci->chip, |  | ||||||
| @@ -1,44 +0,0 @@ | |||||||
| From 7762bb134e3b40e8ee2611365775b7432190a9c7 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Wright Feng <wright.feng@cypress.com> |  | ||||||
| Date: Mon, 11 Dec 2017 15:38:21 +0800 |  | ||||||
| Subject: [PATCH] brcmfmac: enlarge buffer size of caps to 512 bytes |  | ||||||
|  |  | ||||||
| The buffer size of return of cap iovar is greater than 256 bytes in some |  | ||||||
| firmwares. For instance, the return size of cap iovar is 271 bytes in 4373 |  | ||||||
| 13.10.246.79 firmare. It makes feature capability parsing failed because |  | ||||||
| caps buffer is default value. |  | ||||||
| So we enlarge caps buffer size to 512 bytes and add the error print for |  | ||||||
| cap iovar error. |  | ||||||
|  |  | ||||||
| Signed-off-by: Wright Feng <wright.feng@cypress.com> |  | ||||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 12 +++++++++--- |  | ||||||
|  1 file changed, 9 insertions(+), 3 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c |  | ||||||
| @@ -130,13 +130,19 @@ static void brcmf_feat_iovar_data_set(st |  | ||||||
|  	} |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +#define MAX_CAPS_BUFFER_SIZE	512 |  | ||||||
|  static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp) |  | ||||||
|  { |  | ||||||
| -	char caps[256]; |  | ||||||
| +	char caps[MAX_CAPS_BUFFER_SIZE]; |  | ||||||
|  	enum brcmf_feat_id id; |  | ||||||
| -	int i; |  | ||||||
| +	int i, err; |  | ||||||
| + |  | ||||||
| +	err = brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps)); |  | ||||||
| +	if (err) { |  | ||||||
| +		brcmf_err("could not get firmware cap (%d)\n", err); |  | ||||||
| +		return; |  | ||||||
| +	} |  | ||||||
|   |  | ||||||
| -	brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps)); |  | ||||||
|  	brcmf_dbg(INFO, "[ %s]\n", caps); |  | ||||||
|   |  | ||||||
|  	for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) { |  | ||||||
| @@ -1,227 +0,0 @@ | |||||||
| From 3d110df8f74781354051e4bb1e3e97fa368b2f80 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Tue, 19 Dec 2017 13:47:07 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Remove {r,w}_sdreg32 |  | ||||||
|  |  | ||||||
| Remove yet another IO function from the code and replace with one |  | ||||||
| that already exists. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| [arend: keep address calculation, ie. (base + offset) in one line] |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 88 +++++++++++----------- |  | ||||||
|  1 file changed, 42 insertions(+), 46 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -660,30 +660,6 @@ static bool data_ok(struct brcmf_sdio *b |  | ||||||
|  	       ((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -/* |  | ||||||
| - * Reads a register in the SDIO hardware block. This block occupies a series of |  | ||||||
| - * adresses on the 32 bit backplane bus. |  | ||||||
| - */ |  | ||||||
| -static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset) |  | ||||||
| -{ |  | ||||||
| -	struct brcmf_core *core = bus->sdio_core; |  | ||||||
| -	int ret; |  | ||||||
| - |  | ||||||
| -	*regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, &ret); |  | ||||||
| - |  | ||||||
| -	return ret; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
| -static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset) |  | ||||||
| -{ |  | ||||||
| -	struct brcmf_core *core = bus->sdio_core; |  | ||||||
| -	int ret; |  | ||||||
| - |  | ||||||
| -	brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, &ret); |  | ||||||
| - |  | ||||||
| -	return ret; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
|  static int |  | ||||||
|  brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on) |  | ||||||
|  { |  | ||||||
| @@ -1078,6 +1054,8 @@ static void brcmf_sdio_get_console_addr( |  | ||||||
|   |  | ||||||
|  static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus) |  | ||||||
|  { |  | ||||||
| +	struct brcmf_sdio_dev *sdiod = bus->sdiodev; |  | ||||||
| +	struct brcmf_core *core = bus->sdio_core; |  | ||||||
|  	u32 intstatus = 0; |  | ||||||
|  	u32 hmb_data; |  | ||||||
|  	u8 fcbits; |  | ||||||
| @@ -1086,10 +1064,14 @@ static u32 brcmf_sdio_hostmail(struct br |  | ||||||
|  	brcmf_dbg(SDIO, "Enter\n"); |  | ||||||
|   |  | ||||||
|  	/* Read mailbox data and ack that we did so */ |  | ||||||
| -	ret = r_sdreg32(bus, &hmb_data,	SD_REG(tohostmailboxdata)); |  | ||||||
| +	hmb_data = brcmf_sdiod_readl(sdiod, |  | ||||||
| +				     core->base + SD_REG(tohostmailboxdata), |  | ||||||
| +				     &ret); |  | ||||||
| + |  | ||||||
| +	if (!ret) |  | ||||||
| +		brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailbox), |  | ||||||
| +				   SMB_INT_ACK, &ret); |  | ||||||
|   |  | ||||||
| -	if (ret == 0) |  | ||||||
| -		w_sdreg32(bus, SMB_INT_ACK, SD_REG(tosbmailbox)); |  | ||||||
|  	bus->sdcnt.f1regdata += 2; |  | ||||||
|   |  | ||||||
|  	/* dongle indicates the firmware has halted/crashed */ |  | ||||||
| @@ -1163,6 +1145,8 @@ static u32 brcmf_sdio_hostmail(struct br |  | ||||||
|   |  | ||||||
|  static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) |  | ||||||
|  { |  | ||||||
| +	struct brcmf_sdio_dev *sdiod = bus->sdiodev; |  | ||||||
| +	struct brcmf_core *core = bus->sdio_core; |  | ||||||
|  	uint retries = 0; |  | ||||||
|  	u16 lastrbc; |  | ||||||
|  	u8 hi, lo; |  | ||||||
| @@ -1204,7 +1188,8 @@ static void brcmf_sdio_rxfail(struct brc |  | ||||||
|   |  | ||||||
|  	if (rtx) { |  | ||||||
|  		bus->sdcnt.rxrtx++; |  | ||||||
| -		err = w_sdreg32(bus, SMB_NAK, SD_REG(tosbmailbox)); |  | ||||||
| +		brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailbox), |  | ||||||
| +				   SMB_NAK, &err); |  | ||||||
|   |  | ||||||
|  		bus->sdcnt.f1regdata++; |  | ||||||
|  		if (err == 0) |  | ||||||
| @@ -2291,6 +2276,7 @@ static uint brcmf_sdio_sendfromq(struct |  | ||||||
|  { |  | ||||||
|  	struct sk_buff *pkt; |  | ||||||
|  	struct sk_buff_head pktq; |  | ||||||
| +	u32 intstat_addr = bus->sdio_core->base + SD_REG(intstatus); |  | ||||||
|  	u32 intstatus = 0; |  | ||||||
|  	int ret = 0, prec_out, i; |  | ||||||
|  	uint cnt = 0; |  | ||||||
| @@ -2329,7 +2315,8 @@ static uint brcmf_sdio_sendfromq(struct |  | ||||||
|  		if (!bus->intr) { |  | ||||||
|  			/* Check device status, signal pending interrupt */ |  | ||||||
|  			sdio_claim_host(bus->sdiodev->func[1]); |  | ||||||
| -			ret = r_sdreg32(bus, &intstatus, SD_REG(intstatus)); |  | ||||||
| +			intstatus = brcmf_sdiod_readl(bus->sdiodev, |  | ||||||
| +						      intstat_addr, &ret); |  | ||||||
|  			sdio_release_host(bus->sdiodev->func[1]); |  | ||||||
|  			bus->sdcnt.f2txdata++; |  | ||||||
|  			if (ret != 0) |  | ||||||
| @@ -2413,12 +2400,13 @@ static int brcmf_sdio_tx_ctrlframe(struc |  | ||||||
|   |  | ||||||
|  static void brcmf_sdio_bus_stop(struct device *dev) |  | ||||||
|  { |  | ||||||
| -	u32 local_hostintmask; |  | ||||||
| -	u8 saveclk; |  | ||||||
| -	int err; |  | ||||||
|  	struct brcmf_bus *bus_if = dev_get_drvdata(dev); |  | ||||||
|  	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |  | ||||||
|  	struct brcmf_sdio *bus = sdiodev->bus; |  | ||||||
| +	struct brcmf_core *core = bus->sdio_core; |  | ||||||
| +	u32 local_hostintmask; |  | ||||||
| +	u8 saveclk; |  | ||||||
| +	int err; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
|   |  | ||||||
| @@ -2435,7 +2423,9 @@ static void brcmf_sdio_bus_stop(struct d |  | ||||||
|  		brcmf_sdio_bus_sleep(bus, false, false); |  | ||||||
|   |  | ||||||
|  		/* Disable and clear interrupts at the chip level also */ |  | ||||||
| -		w_sdreg32(bus, 0, SD_REG(hostintmask)); |  | ||||||
| +		brcmf_sdiod_writel(sdiodev, core->base + SD_REG(hostintmask), |  | ||||||
| +				   0, NULL); |  | ||||||
| + |  | ||||||
|  		local_hostintmask = bus->hostintmask; |  | ||||||
|  		bus->hostintmask = 0; |  | ||||||
|   |  | ||||||
| @@ -2454,7 +2444,8 @@ static void brcmf_sdio_bus_stop(struct d |  | ||||||
|  		sdio_disable_func(sdiodev->func[SDIO_FUNC_2]); |  | ||||||
|   |  | ||||||
|  		/* Clear any pending interrupts now that F2 is disabled */ |  | ||||||
| -		w_sdreg32(bus, local_hostintmask, SD_REG(intstatus)); |  | ||||||
| +		brcmf_sdiod_writel(sdiodev, core->base + SD_REG(intstatus), |  | ||||||
| +				   local_hostintmask, NULL); |  | ||||||
|   |  | ||||||
|  		sdio_release_host(sdiodev->func[1]); |  | ||||||
|  	} |  | ||||||
| @@ -2521,7 +2512,9 @@ static int brcmf_sdio_intr_rstatus(struc |  | ||||||
|   |  | ||||||
|  static void brcmf_sdio_dpc(struct brcmf_sdio *bus) |  | ||||||
|  { |  | ||||||
| +	struct brcmf_sdio_dev *sdiod = bus->sdiodev; |  | ||||||
|  	u32 newstatus = 0; |  | ||||||
| +	u32 intstat_addr = bus->sdio_core->base + SD_REG(intstatus); |  | ||||||
|  	unsigned long intstatus; |  | ||||||
|  	uint txlimit = bus->txbound;	/* Tx frames to send before resched */ |  | ||||||
|  	uint framecnt;			/* Temporary counter of tx/rx frames */ |  | ||||||
| @@ -2576,9 +2569,10 @@ static void brcmf_sdio_dpc(struct brcmf_ |  | ||||||
|  	 */ |  | ||||||
|  	if (intstatus & I_HMB_FC_CHANGE) { |  | ||||||
|  		intstatus &= ~I_HMB_FC_CHANGE; |  | ||||||
| -		err = w_sdreg32(bus, I_HMB_FC_CHANGE, SD_REG(intstatus)); |  | ||||||
| +		brcmf_sdiod_writel(sdiod, intstat_addr, I_HMB_FC_CHANGE, &err); |  | ||||||
| + |  | ||||||
| +		newstatus = brcmf_sdiod_readl(sdiod, intstat_addr, &err); |  | ||||||
|   |  | ||||||
| -		err = r_sdreg32(bus, &newstatus, SD_REG(intstatus)); |  | ||||||
|  		bus->sdcnt.f1regdata += 2; |  | ||||||
|  		atomic_set(&bus->fcstate, |  | ||||||
|  			   !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE))); |  | ||||||
| @@ -4017,22 +4011,21 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  					 const struct firmware *code, |  | ||||||
|  					 void *nvram, u32 nvram_len) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_bus *bus_if; |  | ||||||
| -	struct brcmf_sdio_dev *sdiodev; |  | ||||||
| -	struct brcmf_sdio *bus; |  | ||||||
| +	struct brcmf_bus *bus_if = dev_get_drvdata(dev); |  | ||||||
| +	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |  | ||||||
| +	struct brcmf_sdio *bus = sdiodev->bus; |  | ||||||
| +	struct brcmf_sdio_dev *sdiod = bus->sdiodev; |  | ||||||
| +	struct brcmf_core *core = bus->sdio_core; |  | ||||||
|  	u8 saveclk; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); |  | ||||||
| -	bus_if = dev_get_drvdata(dev); |  | ||||||
| -	sdiodev = bus_if->bus_priv.sdio; |  | ||||||
| + |  | ||||||
|  	if (err) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
|  	if (!bus_if->drvr) |  | ||||||
|  		return; |  | ||||||
|   |  | ||||||
| -	bus = sdiodev->bus; |  | ||||||
| - |  | ||||||
|  	/* try to download image and nvram to the dongle */ |  | ||||||
|  	bus->alp_only = true; |  | ||||||
|  	err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len); |  | ||||||
| @@ -4063,8 +4056,9 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	/* Enable function 2 (frame transfers) */ |  | ||||||
| -	w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, |  | ||||||
| -		  SD_REG(tosbmailboxdata)); |  | ||||||
| +	brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailboxdata), |  | ||||||
| +			   SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, NULL); |  | ||||||
| + |  | ||||||
|  	err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]); |  | ||||||
|   |  | ||||||
|   |  | ||||||
| @@ -4074,7 +4068,9 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  	if (!err) { |  | ||||||
|  		/* Set up the interrupt mask and enable interrupts */ |  | ||||||
|  		bus->hostintmask = HOSTINTMASK; |  | ||||||
| -		w_sdreg32(bus, bus->hostintmask, SD_REG(hostintmask)); |  | ||||||
| +		brcmf_sdiod_writel(sdiod, core->base + SD_REG(hostintmask), |  | ||||||
| +				   bus->hostintmask, NULL); |  | ||||||
| + |  | ||||||
|   |  | ||||||
|  		brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err); |  | ||||||
|  	} else { |  | ||||||
| @@ -1,33 +0,0 @@ | |||||||
| From dbda7dacb79a377e8ed9d38ce0e4a58b70aa9060 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Tue, 19 Dec 2017 13:47:08 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Rename buscore to core for consistency |  | ||||||
|  |  | ||||||
| Avoid confusion with unrelated _buscore labels. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| [arend: only do the rename] |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 ++-- |  | ||||||
|  1 file changed, 2 insertions(+), 2 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -2485,12 +2485,12 @@ static inline void brcmf_sdio_clrintr(st |  | ||||||
|   |  | ||||||
|  static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_core *buscore = bus->sdio_core; |  | ||||||
| +	struct brcmf_core *core = bus->sdio_core; |  | ||||||
|  	u32 addr; |  | ||||||
|  	unsigned long val; |  | ||||||
|  	int ret; |  | ||||||
|   |  | ||||||
| -	addr = buscore->base + SD_REG(intstatus); |  | ||||||
| +	addr = core->base + SD_REG(intstatus); |  | ||||||
|   |  | ||||||
|  	val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret); |  | ||||||
|  	bus->sdcnt.f1regdata++; |  | ||||||
| @@ -1,82 +0,0 @@ | |||||||
| From 874bb8e49b7c6368f8ff9f2566c7bd06a2249be0 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Tue, 19 Dec 2017 13:47:09 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: stabilise the value of ->sbwad in use for some xfer |  | ||||||
|  routines. |  | ||||||
|  |  | ||||||
| The IO functions operate within the Chipcommon IO window. Explicitly |  | ||||||
| set this, rather than relying on the last initialisation IO access to |  | ||||||
| leave it set to the right value by chance. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 ++++---- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c   | 5 +++++ |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 1 + |  | ||||||
|  3 files changed, 10 insertions(+), 4 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -529,7 +529,7 @@ int brcmf_sdiod_recv_buf(struct brcmf_sd |  | ||||||
|   |  | ||||||
|  int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt) |  | ||||||
|  { |  | ||||||
| -	u32 addr = sdiodev->sbwad; |  | ||||||
| +	u32 addr = sdiodev->cc_core->base; |  | ||||||
|  	int err = 0; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len); |  | ||||||
| @@ -552,7 +552,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_ |  | ||||||
|  { |  | ||||||
|  	struct sk_buff *glom_skb = NULL; |  | ||||||
|  	struct sk_buff *skb; |  | ||||||
| -	u32 addr = sdiodev->sbwad; |  | ||||||
| +	u32 addr = sdiodev->cc_core->base; |  | ||||||
|  	int err = 0; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", |  | ||||||
| @@ -593,7 +593,7 @@ done: |  | ||||||
|  int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes) |  | ||||||
|  { |  | ||||||
|  	struct sk_buff *mypkt; |  | ||||||
| -	u32 addr = sdiodev->sbwad; |  | ||||||
| +	u32 addr = sdiodev->cc_core->base; |  | ||||||
|  	int err; |  | ||||||
|   |  | ||||||
|  	mypkt = brcmu_pkt_buf_get_skb(nbytes); |  | ||||||
| @@ -625,7 +625,7 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd |  | ||||||
|  			 struct sk_buff_head *pktq) |  | ||||||
|  { |  | ||||||
|  	struct sk_buff *skb; |  | ||||||
| -	u32 addr = sdiodev->sbwad; |  | ||||||
| +	u32 addr = sdiodev->cc_core->base; |  | ||||||
|  	int err; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -3842,6 +3842,11 @@ brcmf_sdio_probe_attach(struct brcmf_sdi |  | ||||||
|  	if (!bus->sdio_core) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
| +	/* Pick up the CHIPCOMMON core info struct, for bulk IO in bcmsdh.c */ |  | ||||||
| +	sdiodev->cc_core = brcmf_chip_get_core(bus->ci, BCMA_CORE_CHIPCOMMON); |  | ||||||
| +	if (!sdiodev->cc_core) |  | ||||||
| +		goto fail; |  | ||||||
| + |  | ||||||
|  	sdiodev->settings = brcmf_get_module_param(sdiodev->dev, |  | ||||||
|  						   BRCMF_BUSTYPE_SDIO, |  | ||||||
|  						   bus->ci->chip, |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| @@ -178,6 +178,7 @@ struct brcmf_sdio_dev { |  | ||||||
|  	struct sdio_func *func[SDIO_MAX_FUNCS]; |  | ||||||
|  	u8 num_funcs;			/* Supported funcs on client */ |  | ||||||
|  	u32 sbwad;			/* Save backplane window address */ |  | ||||||
| +	struct brcmf_core *cc_core;	/* chipcommon core info struct */ |  | ||||||
|  	struct brcmf_sdio *bus; |  | ||||||
|  	struct device *dev; |  | ||||||
|  	struct brcmf_bus *bus_if; |  | ||||||
| @@ -1,45 +0,0 @@ | |||||||
| From 508422f3695bf66f7b85fb4723c22f5166003ec6 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Tue, 19 Dec 2017 13:47:10 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Correctly handle accesses to SDIO func0 |  | ||||||
|  |  | ||||||
| Rather than workaround the restrictions on func0 addressing in the |  | ||||||
| driver, set MMC_QUIRK_LENIENT_FN0 |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 ++++ |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 4 ++-- |  | ||||||
|  2 files changed, 6 insertions(+), 2 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -995,6 +995,10 @@ static int brcmf_ops_sdio_probe(struct s |  | ||||||
|  	brcmf_dbg(SDIO, "Function#: %d\n", func->num); |  | ||||||
|   |  | ||||||
|  	dev = &func->dev; |  | ||||||
| + |  | ||||||
| +	/* Set MMC_QUIRK_LENIENT_FN0 for this card */ |  | ||||||
| +	func->card->quirks |= MMC_QUIRK_LENIENT_FN0; |  | ||||||
| + |  | ||||||
|  	/* prohibit ACPI power management for this device */ |  | ||||||
|  	brcmf_sdiod_acpi_set_power_manageable(dev, 0); |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| @@ -297,10 +297,10 @@ void brcmf_sdiod_intr_unregister(struct |  | ||||||
|  /* SDIO device register access interface */ |  | ||||||
|  /* Accessors for SDIO Function 0 */ |  | ||||||
|  #define brcmf_sdiod_func0_rb(sdiodev, addr, r) \ |  | ||||||
| -	sdio_readb((sdiodev)->func[0], (addr), (r)) |  | ||||||
| +	sdio_f0_readb((sdiodev)->func[0], (addr), (r)) |  | ||||||
|   |  | ||||||
|  #define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \ |  | ||||||
| -	sdio_writeb((sdiodev)->func[0], (v), (addr), (ret)) |  | ||||||
| +	sdio_f0_writeb((sdiodev)->func[0], (v), (addr), (ret)) |  | ||||||
|   |  | ||||||
|  /* Accessors for SDIO Function 1 */ |  | ||||||
|  #define brcmf_sdiod_readb(sdiodev, addr, r) \ |  | ||||||
| @@ -1,111 +0,0 @@ | |||||||
| From 99d7b6fdfc8c24052c92c720330d31ca1332f996 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Tue, 19 Dec 2017 13:47:11 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Remove func0 from function array |  | ||||||
|  |  | ||||||
| func0 is not provided by the mmc stack as a function when probing. |  | ||||||
| Instead providing specific access functions to read/write it. |  | ||||||
|  |  | ||||||
| This prepares for a patch to remove the actual array entry itself. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| [arend: rephrased the commit message] |  | ||||||
| [arend: removed unrelated comment for which separate patch is warranted] |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  5 +---- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c   |  7 ++++--- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 13 ++++++------- |  | ||||||
|  3 files changed, 11 insertions(+), 14 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -1022,8 +1022,7 @@ static int brcmf_ops_sdio_probe(struct s |  | ||||||
|  	/* store refs to functions used. mmc_card does |  | ||||||
|  	 * not hold the F0 function pointer. |  | ||||||
|  	 */ |  | ||||||
| -	sdiodev->func[0] = kmemdup(func, sizeof(*func), GFP_KERNEL); |  | ||||||
| -	sdiodev->func[0]->num = 0; |  | ||||||
| +	sdiodev->func[0] = NULL; |  | ||||||
|  	sdiodev->func[1] = func->card->sdio_func[0]; |  | ||||||
|  	sdiodev->func[2] = func; |  | ||||||
|   |  | ||||||
| @@ -1049,7 +1048,6 @@ static int brcmf_ops_sdio_probe(struct s |  | ||||||
|  fail: |  | ||||||
|  	dev_set_drvdata(&func->dev, NULL); |  | ||||||
|  	dev_set_drvdata(&sdiodev->func[1]->dev, NULL); |  | ||||||
| -	kfree(sdiodev->func[0]); |  | ||||||
|  	kfree(sdiodev); |  | ||||||
|  	kfree(bus_if); |  | ||||||
|  	return err; |  | ||||||
| @@ -1082,7 +1080,6 @@ static void brcmf_ops_sdio_remove(struct |  | ||||||
|  		dev_set_drvdata(&sdiodev->func[2]->dev, NULL); |  | ||||||
|   |  | ||||||
|  		kfree(bus_if); |  | ||||||
| -		kfree(sdiodev->func[0]); |  | ||||||
|  		kfree(sdiodev); |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -3771,9 +3771,10 @@ static u32 brcmf_sdio_buscore_read32(voi |  | ||||||
|  	u32 val, rev; |  | ||||||
|   |  | ||||||
|  	val = brcmf_sdiod_readl(sdiodev, addr, NULL); |  | ||||||
| -	if ((sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 || |  | ||||||
| -	     sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) && |  | ||||||
| -	    addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { |  | ||||||
| + |  | ||||||
| +	if ((sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 || |  | ||||||
| +	     sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339) && |  | ||||||
| +	     addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { |  | ||||||
|  		rev = (val & CID_REV_MASK) >> CID_REV_SHIFT; |  | ||||||
|  		if (rev >= 2) { |  | ||||||
|  			val &= ~CID_ID_MASK; |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| @@ -21,7 +21,9 @@ |  | ||||||
|  #include <linux/firmware.h> |  | ||||||
|  #include "firmware.h" |  | ||||||
|   |  | ||||||
| -#define SDIO_FUNC_0		0 |  | ||||||
| +/* Maximum number of I/O funcs */ |  | ||||||
| +#define NUM_SDIO_FUNCS	3 |  | ||||||
| + |  | ||||||
|  #define SDIO_FUNC_1		1 |  | ||||||
|  #define SDIO_FUNC_2		2 |  | ||||||
|   |  | ||||||
| @@ -39,9 +41,6 @@ |  | ||||||
|  #define INTR_STATUS_FUNC1	0x2 |  | ||||||
|  #define INTR_STATUS_FUNC2	0x4 |  | ||||||
|   |  | ||||||
| -/* Maximum number of I/O funcs */ |  | ||||||
| -#define SDIOD_MAX_IOFUNCS	7 |  | ||||||
| - |  | ||||||
|  /* mask of register map */ |  | ||||||
|  #define REG_F0_REG_MASK		0x7FF |  | ||||||
|  #define REG_F1_MISC_MASK	0x1FFFF |  | ||||||
| @@ -175,7 +174,7 @@ struct brcmf_sdio; |  | ||||||
|  struct brcmf_sdiod_freezer; |  | ||||||
|   |  | ||||||
|  struct brcmf_sdio_dev { |  | ||||||
| -	struct sdio_func *func[SDIO_MAX_FUNCS]; |  | ||||||
| +	struct sdio_func *func[NUM_SDIO_FUNCS]; |  | ||||||
|  	u8 num_funcs;			/* Supported funcs on client */ |  | ||||||
|  	u32 sbwad;			/* Save backplane window address */ |  | ||||||
|  	struct brcmf_core *cc_core;	/* chipcommon core info struct */ |  | ||||||
| @@ -297,10 +296,10 @@ void brcmf_sdiod_intr_unregister(struct |  | ||||||
|  /* SDIO device register access interface */ |  | ||||||
|  /* Accessors for SDIO Function 0 */ |  | ||||||
|  #define brcmf_sdiod_func0_rb(sdiodev, addr, r) \ |  | ||||||
| -	sdio_f0_readb((sdiodev)->func[0], (addr), (r)) |  | ||||||
| +	sdio_f0_readb((sdiodev)->func[1], (addr), (r)) |  | ||||||
|   |  | ||||||
|  #define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \ |  | ||||||
| -	sdio_f0_writeb((sdiodev)->func[0], (v), (addr), (ret)) |  | ||||||
| +	sdio_f0_writeb((sdiodev)->func[1], (v), (addr), (ret)) |  | ||||||
|   |  | ||||||
|  /* Accessors for SDIO Function 1 */ |  | ||||||
|  #define brcmf_sdiod_readb(sdiodev, addr, r) \ |  | ||||||
| @@ -1,40 +0,0 @@ | |||||||
| From bcadaaa097c7ec103fe75f9da41f8fe52693b644 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Tue, 19 Dec 2017 13:47:12 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: More efficient and slightly easier to read fixup |  | ||||||
|  for 4339 chips |  | ||||||
|  |  | ||||||
| Its more efficient to test the register we're interested in first, |  | ||||||
| potentially avoiding two more comparisons, and therefore always avoiding |  | ||||||
| one comparison per call on all other chips. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| [arend: fix some checkpatch warnings] |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 ++++--- |  | ||||||
|  1 file changed, 4 insertions(+), 3 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -3772,15 +3772,16 @@ static u32 brcmf_sdio_buscore_read32(voi |  | ||||||
|   |  | ||||||
|  	val = brcmf_sdiod_readl(sdiodev, addr, NULL); |  | ||||||
|   |  | ||||||
| -	if ((sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 || |  | ||||||
| -	     sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339) && |  | ||||||
| -	     addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { |  | ||||||
| +	if (addr == CORE_CC_REG(SI_ENUM_BASE, chipid) && |  | ||||||
| +	    (sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339 || |  | ||||||
| +	     sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339)) { |  | ||||||
|  		rev = (val & CID_REV_MASK) >> CID_REV_SHIFT; |  | ||||||
|  		if (rev >= 2) { |  | ||||||
|  			val &= ~CID_ID_MASK; |  | ||||||
|  			val |= BRCM_CC_4339_CHIP_ID; |  | ||||||
|  		} |  | ||||||
|  	} |  | ||||||
| + |  | ||||||
|  	return val; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -1,347 +0,0 @@ | |||||||
| From 00eb62cfc5f806b003fe5d54c8b5fe9a9665482f Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Tue, 19 Dec 2017 13:47:13 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Replace function index with function pointer |  | ||||||
|  |  | ||||||
| In preparation for removing the function array, remove all code that |  | ||||||
| refers to function by index and replace with pointers to the function |  | ||||||
| itself. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| [arend: replace BUG() with WARN() macro] |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 85 ++++++++++++---------- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 15 ++-- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.h    |  6 +- |  | ||||||
|  3 files changed, 56 insertions(+), 50 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -291,8 +291,9 @@ out: |  | ||||||
|  		*ret = retval; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev, uint fn, |  | ||||||
| -				 u32 addr, struct sk_buff *pkt) |  | ||||||
| +static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev, |  | ||||||
| +				 struct sdio_func *func, u32 addr, |  | ||||||
| +				 struct sk_buff *pkt) |  | ||||||
|  { |  | ||||||
|  	unsigned int req_sz; |  | ||||||
|  	int err; |  | ||||||
| @@ -301,13 +302,19 @@ static int brcmf_sdiod_buff_read(struct |  | ||||||
|  	req_sz = pkt->len + 3; |  | ||||||
|  	req_sz &= (uint)~3; |  | ||||||
|   |  | ||||||
| -	if (fn == 1) |  | ||||||
| -		err = sdio_memcpy_fromio(sdiodev->func[fn], |  | ||||||
| -					 ((u8 *)(pkt->data)), addr, req_sz); |  | ||||||
| -	else |  | ||||||
| -		/* function 2 read is FIFO operation */ |  | ||||||
| -		err = sdio_readsb(sdiodev->func[fn], |  | ||||||
| -				  ((u8 *)(pkt->data)), addr, req_sz); |  | ||||||
| +	switch (func->num) { |  | ||||||
| +	case 1: |  | ||||||
| +		err = sdio_memcpy_fromio(func, ((u8 *)(pkt->data)), addr, |  | ||||||
| +					 req_sz); |  | ||||||
| +		break; |  | ||||||
| +	case 2: |  | ||||||
| +		err = sdio_readsb(func, ((u8 *)(pkt->data)), addr, req_sz); |  | ||||||
| +		break; |  | ||||||
| +	default: |  | ||||||
| +		/* bail out as things are really fishy here */ |  | ||||||
| +		WARN(1, "invalid sdio function number: %d\n", func->num); |  | ||||||
| +		err = -ENOMEDIUM; |  | ||||||
| +	}; |  | ||||||
|   |  | ||||||
|  	if (err == -ENOMEDIUM) |  | ||||||
|  		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); |  | ||||||
| @@ -315,8 +322,9 @@ static int brcmf_sdiod_buff_read(struct |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev, uint fn, |  | ||||||
| -				  u32 addr, struct sk_buff *pkt) |  | ||||||
| +static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev, |  | ||||||
| +				  struct sdio_func *func, u32 addr, |  | ||||||
| +				  struct sk_buff *pkt) |  | ||||||
|  { |  | ||||||
|  	unsigned int req_sz; |  | ||||||
|  	int err; |  | ||||||
| @@ -325,8 +333,7 @@ static int brcmf_sdiod_buff_write(struct |  | ||||||
|  	req_sz = pkt->len + 3; |  | ||||||
|  	req_sz &= (uint)~3; |  | ||||||
|   |  | ||||||
| -	err = sdio_memcpy_toio(sdiodev->func[fn], addr, |  | ||||||
| -			       ((u8 *)(pkt->data)), req_sz); |  | ||||||
| +	err = sdio_memcpy_toio(func, addr, ((u8 *)(pkt->data)), req_sz); |  | ||||||
|   |  | ||||||
|  	if (err == -ENOMEDIUM) |  | ||||||
|  		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); |  | ||||||
| @@ -337,7 +344,7 @@ static int brcmf_sdiod_buff_write(struct |  | ||||||
|  /** |  | ||||||
|   * brcmf_sdiod_sglist_rw - SDIO interface function for block data access |  | ||||||
|   * @sdiodev: brcmfmac sdio device |  | ||||||
| - * @fn: SDIO function number |  | ||||||
| + * @func: SDIO function |  | ||||||
|   * @write: direction flag |  | ||||||
|   * @addr: dongle memory address as source/destination |  | ||||||
|   * @pkt: skb pointer |  | ||||||
| @@ -346,7 +353,8 @@ static int brcmf_sdiod_buff_write(struct |  | ||||||
|   * stack for block data access. It assumes that the skb passed down by the |  | ||||||
|   * caller has already been padded and aligned. |  | ||||||
|   */ |  | ||||||
| -static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, |  | ||||||
| +static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, |  | ||||||
| +				 struct sdio_func *func, |  | ||||||
|  				 bool write, u32 addr, |  | ||||||
|  				 struct sk_buff_head *pktlist) |  | ||||||
|  { |  | ||||||
| @@ -372,7 +380,7 @@ static int brcmf_sdiod_sglist_rw(struct |  | ||||||
|  		req_sz = 0; |  | ||||||
|  		skb_queue_walk(pktlist, pkt_next) |  | ||||||
|  			req_sz += pkt_next->len; |  | ||||||
| -		req_sz = ALIGN(req_sz, sdiodev->func[fn]->cur_blksize); |  | ||||||
| +		req_sz = ALIGN(req_sz, func->cur_blksize); |  | ||||||
|  		while (req_sz > PAGE_SIZE) { |  | ||||||
|  			pkt_next = brcmu_pkt_buf_get_skb(PAGE_SIZE); |  | ||||||
|  			if (pkt_next == NULL) { |  | ||||||
| @@ -391,7 +399,7 @@ static int brcmf_sdiod_sglist_rw(struct |  | ||||||
|  		target_list = &local_list; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	func_blk_sz = sdiodev->func[fn]->cur_blksize; |  | ||||||
| +	func_blk_sz = func->cur_blksize; |  | ||||||
|  	max_req_sz = sdiodev->max_request_size; |  | ||||||
|  	max_seg_cnt = min_t(unsigned short, sdiodev->max_segment_count, |  | ||||||
|  			    target_list->qlen); |  | ||||||
| @@ -408,10 +416,10 @@ static int brcmf_sdiod_sglist_rw(struct |  | ||||||
|  	mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; |  | ||||||
|  	mmc_cmd.opcode = SD_IO_RW_EXTENDED; |  | ||||||
|  	mmc_cmd.arg = write ? 1<<31 : 0;	/* write flag  */ |  | ||||||
| -	mmc_cmd.arg |= (fn & 0x7) << 28;	/* SDIO func num */ |  | ||||||
| -	mmc_cmd.arg |= 1<<27;			/* block mode */ |  | ||||||
| +	mmc_cmd.arg |= (func->num & 0x7) << 28;	/* SDIO func num */ |  | ||||||
| +	mmc_cmd.arg |= 1 << 27;			/* block mode */ |  | ||||||
|  	/* for function 1 the addr will be incremented */ |  | ||||||
| -	mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0; |  | ||||||
| +	mmc_cmd.arg |= (func->num == 1) ? 1 << 26 : 0; |  | ||||||
|  	mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; |  | ||||||
|  	mmc_req.cmd = &mmc_cmd; |  | ||||||
|  	mmc_req.data = &mmc_dat; |  | ||||||
| @@ -457,11 +465,11 @@ static int brcmf_sdiod_sglist_rw(struct |  | ||||||
|  		mmc_cmd.arg |= (addr & 0x1FFFF) << 9;	/* address */ |  | ||||||
|  		mmc_cmd.arg |= mmc_dat.blocks & 0x1FF;	/* block count */ |  | ||||||
|  		/* incrementing addr for function 1 */ |  | ||||||
| -		if (fn == 1) |  | ||||||
| +		if (func->num == 1) |  | ||||||
|  			addr += req_sz; |  | ||||||
|   |  | ||||||
| -		mmc_set_data_timeout(&mmc_dat, sdiodev->func[fn]->card); |  | ||||||
| -		mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req); |  | ||||||
| +		mmc_set_data_timeout(&mmc_dat, func->card); |  | ||||||
| +		mmc_wait_for_req(func->card->host, &mmc_req); |  | ||||||
|   |  | ||||||
|  		ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; |  | ||||||
|  		if (ret == -ENOMEDIUM) { |  | ||||||
| @@ -541,7 +549,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd |  | ||||||
|  	addr &= SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
|  	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
|   |  | ||||||
| -	err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt); |  | ||||||
| +	err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr, pkt); |  | ||||||
|   |  | ||||||
|  done: |  | ||||||
|  	return err; |  | ||||||
| @@ -566,13 +574,13 @@ int brcmf_sdiod_recv_chain(struct brcmf_ |  | ||||||
|  	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
|   |  | ||||||
|  	if (pktq->qlen == 1) |  | ||||||
| -		err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, |  | ||||||
| +		err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr, |  | ||||||
|  					    pktq->next); |  | ||||||
|  	else if (!sdiodev->sg_support) { |  | ||||||
|  		glom_skb = brcmu_pkt_buf_get_skb(totlen); |  | ||||||
|  		if (!glom_skb) |  | ||||||
|  			return -ENOMEM; |  | ||||||
| -		err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, |  | ||||||
| +		err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr, |  | ||||||
|  					    glom_skb); |  | ||||||
|  		if (err) |  | ||||||
|  			goto done; |  | ||||||
| @@ -582,8 +590,8 @@ int brcmf_sdiod_recv_chain(struct brcmf_ |  | ||||||
|  			skb_pull(glom_skb, skb->len); |  | ||||||
|  		} |  | ||||||
|  	} else |  | ||||||
| -		err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, false, addr, |  | ||||||
| -					    pktq); |  | ||||||
| +		err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func[2], false, |  | ||||||
| +					    addr, pktq); |  | ||||||
|   |  | ||||||
|  done: |  | ||||||
|  	brcmu_pkt_buf_free_skb(glom_skb); |  | ||||||
| @@ -614,7 +622,8 @@ int brcmf_sdiod_send_buf(struct brcmf_sd |  | ||||||
|  	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
|   |  | ||||||
|  	if (!err) |  | ||||||
| -		err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt); |  | ||||||
| +		err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[2], addr, |  | ||||||
| +					     mypkt); |  | ||||||
|   |  | ||||||
|  	brcmu_pkt_buf_free_skb(mypkt); |  | ||||||
|   |  | ||||||
| @@ -639,14 +648,14 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd |  | ||||||
|   |  | ||||||
|  	if (pktq->qlen == 1 || !sdiodev->sg_support) { |  | ||||||
|  		skb_queue_walk(pktq, skb) { |  | ||||||
| -			err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, |  | ||||||
| +			err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[2], |  | ||||||
|  						     addr, skb); |  | ||||||
|  			if (err) |  | ||||||
|  				break; |  | ||||||
|  		} |  | ||||||
|  	} else { |  | ||||||
| -		err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, true, addr, |  | ||||||
| -					    pktq); |  | ||||||
| +		err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func[2], true, |  | ||||||
| +					    addr, pktq); |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	return err; |  | ||||||
| @@ -696,10 +705,10 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev |  | ||||||
|   |  | ||||||
|  		if (write) { |  | ||||||
|  			memcpy(pkt->data, data, dsize); |  | ||||||
| -			err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_1, |  | ||||||
| +			err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[1], |  | ||||||
|  						     sdaddr, pkt); |  | ||||||
|  		} else { |  | ||||||
| -			err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_1, |  | ||||||
| +			err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[1], |  | ||||||
|  						    sdaddr, pkt); |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
| @@ -728,12 +737,12 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn) |  | ||||||
| +int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, struct sdio_func *func) |  | ||||||
|  { |  | ||||||
|  	brcmf_dbg(SDIO, "Enter\n"); |  | ||||||
|   |  | ||||||
|  	/* Issue abort cmd52 command through F0 */ |  | ||||||
| -	brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, fn, NULL); |  | ||||||
| +	brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, func->num, NULL); |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "Exit\n"); |  | ||||||
|  	return 0; |  | ||||||
| @@ -1105,7 +1114,7 @@ static int brcmf_ops_sdio_suspend(struct |  | ||||||
|   |  | ||||||
|  	func = container_of(dev, struct sdio_func, dev); |  | ||||||
|  	brcmf_dbg(SDIO, "Enter: F%d\n", func->num); |  | ||||||
| -	if (func->num != SDIO_FUNC_1) |  | ||||||
| +	if (func->num != 1) |  | ||||||
|  		return 0; |  | ||||||
|   |  | ||||||
|   |  | ||||||
| @@ -1134,7 +1143,7 @@ static int brcmf_ops_sdio_resume(struct |  | ||||||
|  	struct sdio_func *func = container_of(dev, struct sdio_func, dev); |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SDIO, "Enter: F%d\n", func->num); |  | ||||||
| -	if (func->num != SDIO_FUNC_2) |  | ||||||
| +	if (func->num != 2) |  | ||||||
|  		return 0; |  | ||||||
|   |  | ||||||
|  	brcmf_sdiod_freezer_off(sdiodev); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -1157,7 +1157,7 @@ static void brcmf_sdio_rxfail(struct brc |  | ||||||
|  		  rtx ? ", send NAK" : ""); |  | ||||||
|   |  | ||||||
|  	if (abort) |  | ||||||
| -		brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2); |  | ||||||
| +		brcmf_sdiod_abort(bus->sdiodev, bus->sdiodev->func[2]); |  | ||||||
|   |  | ||||||
|  	brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, |  | ||||||
|  			   &err); |  | ||||||
| @@ -1209,7 +1209,7 @@ static void brcmf_sdio_txfail(struct brc |  | ||||||
|  	brcmf_err("sdio error, abort command and terminate frame\n"); |  | ||||||
|  	bus->sdcnt.tx_sderrs++; |  | ||||||
|   |  | ||||||
| -	brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2); |  | ||||||
| +	brcmf_sdiod_abort(sdiodev, sdiodev->func[2]); |  | ||||||
|  	brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); |  | ||||||
|  	bus->sdcnt.f1regdata++; |  | ||||||
|   |  | ||||||
| @@ -2072,7 +2072,7 @@ static int brcmf_sdio_txpkt_prep_sg(stru |  | ||||||
|  	int ntail, ret; |  | ||||||
|   |  | ||||||
|  	sdiodev = bus->sdiodev; |  | ||||||
| -	blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize; |  | ||||||
| +	blksize = sdiodev->func[2]->cur_blksize; |  | ||||||
|  	/* sg entry alignment should be a divisor of block size */ |  | ||||||
|  	WARN_ON(blksize % bus->sgentry_align); |  | ||||||
|   |  | ||||||
| @@ -2441,7 +2441,7 @@ static void brcmf_sdio_bus_stop(struct d |  | ||||||
|   |  | ||||||
|  		/* Turn off the bus (F2), free any pending packets */ |  | ||||||
|  		brcmf_dbg(INTR, "disable SDIO interrupts\n"); |  | ||||||
| -		sdio_disable_func(sdiodev->func[SDIO_FUNC_2]); |  | ||||||
| +		sdio_disable_func(sdiodev->func[2]); |  | ||||||
|   |  | ||||||
|  		/* Clear any pending interrupts now that F2 is disabled */ |  | ||||||
|  		brcmf_sdiod_writel(sdiodev, core->base + SD_REG(intstatus), |  | ||||||
| @@ -4066,8 +4066,7 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  	brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailboxdata), |  | ||||||
|  			   SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, NULL); |  | ||||||
|   |  | ||||||
| -	err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]); |  | ||||||
| - |  | ||||||
| +	err = sdio_enable_func(sdiodev->func[2]); |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(INFO, "enable F2: err=%d\n", err); |  | ||||||
|   |  | ||||||
| @@ -4082,7 +4081,7 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  		brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err); |  | ||||||
|  	} else { |  | ||||||
|  		/* Disable F2 again */ |  | ||||||
| -		sdio_disable_func(sdiodev->func[SDIO_FUNC_2]); |  | ||||||
| +		sdio_disable_func(sdiodev->func[2]); |  | ||||||
|  		goto release; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| @@ -4219,7 +4218,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru |  | ||||||
|  	sdio_claim_host(bus->sdiodev->func[1]); |  | ||||||
|   |  | ||||||
|  	/* Disable F2 to clear any intermediate frame state on the dongle */ |  | ||||||
| -	sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]); |  | ||||||
| +	sdio_disable_func(bus->sdiodev->func[2]); |  | ||||||
|   |  | ||||||
|  	bus->rxflow = false; |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| @@ -45,9 +45,6 @@ |  | ||||||
|  #define REG_F0_REG_MASK		0x7FF |  | ||||||
|  #define REG_F1_MISC_MASK	0x1FFFF |  | ||||||
|   |  | ||||||
| -/* as of sdiod rev 0, supports 3 functions */ |  | ||||||
| -#define SBSDIO_NUM_FUNCTION		3 |  | ||||||
| - |  | ||||||
|  /* function 0 vendor specific CCCR registers */ |  | ||||||
|   |  | ||||||
|  #define SDIO_CCCR_BRCM_CARDCAP			0xf0 |  | ||||||
| @@ -350,7 +347,8 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_ |  | ||||||
|  		      u8 *data, uint size); |  | ||||||
|   |  | ||||||
|  /* Issue an abort to the specified function */ |  | ||||||
| -int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn); |  | ||||||
| +int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, struct sdio_func *func); |  | ||||||
| + |  | ||||||
|  void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev); |  | ||||||
|  void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev, |  | ||||||
|  			      enum brcmf_sdiod_state state); |  | ||||||
| @@ -1,53 +0,0 @@ | |||||||
| From 9c3438ed215adba7025268ee1f0b6f7a2af12316 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Date: Tue, 19 Dec 2017 13:47:14 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Clean up interrupt macros |  | ||||||
|  |  | ||||||
| Make it more obvious that this code acually enables interrupts, and |  | ||||||
| provide nice definitions for the bits in the register. |  | ||||||
|  |  | ||||||
| Signed-off-by: Ian Molton <ian@mnementh.co.uk> |  | ||||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 3 ++- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 8 +++++--- |  | ||||||
|  2 files changed, 7 insertions(+), 4 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -149,7 +149,8 @@ int brcmf_sdiod_intr_register(struct brc |  | ||||||
|   |  | ||||||
|  		/* must configure SDIO_CCCR_IENx to enable irq */ |  | ||||||
|  		data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, &ret); |  | ||||||
| -		data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; |  | ||||||
| +		data |= SDIO_CCCR_IEN_FUNC1 | SDIO_CCCR_IEN_FUNC2 | |  | ||||||
| +			SDIO_CCCR_IEN_FUNC0; |  | ||||||
|  		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret); |  | ||||||
|   |  | ||||||
|  		/* redirect, configure and enable io for interrupt signal */ |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  | ||||||
| @@ -24,9 +24,6 @@ |  | ||||||
|  /* Maximum number of I/O funcs */ |  | ||||||
|  #define NUM_SDIO_FUNCS	3 |  | ||||||
|   |  | ||||||
| -#define SDIO_FUNC_1		1 |  | ||||||
| -#define SDIO_FUNC_2		2 |  | ||||||
| - |  | ||||||
|  #define SDIOD_FBR_SIZE		0x100 |  | ||||||
|   |  | ||||||
|  /* io_en */ |  | ||||||
| @@ -52,6 +49,11 @@ |  | ||||||
|  #define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT	BIT(2) |  | ||||||
|  #define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC	BIT(3) |  | ||||||
|   |  | ||||||
| +/* Interrupt enable bits for each function */ |  | ||||||
| +#define SDIO_CCCR_IEN_FUNC0			BIT(0) |  | ||||||
| +#define SDIO_CCCR_IEN_FUNC1			BIT(1) |  | ||||||
| +#define SDIO_CCCR_IEN_FUNC2			BIT(2) |  | ||||||
| + |  | ||||||
|  #define SDIO_CCCR_BRCM_CARDCTRL			0xf1 |  | ||||||
|  #define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET	BIT(1) |  | ||||||
|   |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| From e3720dad99859251a8b0fe2807275a8afcfb560d Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Double Lo <double.lo@cypress.com> |  | ||||||
| Date: Tue, 19 Dec 2017 14:56:44 +0800 |  | ||||||
| Subject: [PATCH] brcmfmac: Support 43455 save-restore (SR) feature if FW |  | ||||||
|  include -sr |  | ||||||
|  |  | ||||||
| This patch will add 43455 into the save-restore(SR) capable chip list, so |  | ||||||
| the SR engine will be enabled with 43455 FW which built-in the -sr |  | ||||||
| function. |  | ||||||
|  |  | ||||||
| Signed-off-by: Double Lo <double.lo@cypress.com> |  | ||||||
| Signed-off-by: Wright Feng <wright.feng@cypress.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 1 + |  | ||||||
|  1 file changed, 1 insertion(+) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c |  | ||||||
| @@ -1338,6 +1338,7 @@ bool brcmf_chip_sr_capable(struct brcmf_ |  | ||||||
|  	switch (pub->chip) { |  | ||||||
|  	case BRCM_CC_4354_CHIP_ID: |  | ||||||
|  	case BRCM_CC_4356_CHIP_ID: |  | ||||||
| +	case BRCM_CC_4345_CHIP_ID: |  | ||||||
|  		/* explicitly check SR engine enable bit */ |  | ||||||
|  		pmu_cc3_mask = BIT(2); |  | ||||||
|  		/* fall-through */ |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,31 +0,0 @@ | |||||||
| From 32adbcaa5df49f1977441f7a4bf180a0bcfe9966 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Tue, 9 Jan 2018 13:22:53 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: add comment block in brcmf_sdio_buscore_read() |  | ||||||
|  |  | ||||||
| In brcmf_sdio_buscore_read() there is some special handling upon |  | ||||||
| register access to chipid register of the chipcommon core. Add |  | ||||||
| comment explaining why it is done here. |  | ||||||
|  |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 +++++++ |  | ||||||
|  1 file changed, 7 insertions(+) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -3772,6 +3772,13 @@ static u32 brcmf_sdio_buscore_read32(voi |  | ||||||
|   |  | ||||||
|  	val = brcmf_sdiod_readl(sdiodev, addr, NULL); |  | ||||||
|   |  | ||||||
| +	/* |  | ||||||
| +	 * this is a bit of special handling if reading the chipcommon chipid |  | ||||||
| +	 * register. The 4339 is a next-gen of the 4335. It uses the same |  | ||||||
| +	 * SDIO device id as 4335 and the chipid register returns 4335 as well. |  | ||||||
| +	 * It can be identified as 4339 by looking at the chip revision. It |  | ||||||
| +	 * is corrected here so the chip.c module has the right info. |  | ||||||
| +	 */ |  | ||||||
|  	if (addr == CORE_CC_REG(SI_ENUM_BASE, chipid) && |  | ||||||
|  	    (sdiodev->func1->device == SDIO_DEVICE_ID_BROADCOM_4339 || |  | ||||||
|  	     sdiodev->func1->device == SDIO_DEVICE_ID_BROADCOM_4335_4339)) { |  | ||||||
| @@ -1,137 +0,0 @@ | |||||||
| From 378f6a16043e5d3346301fc618f503e97aea335b Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Tue, 9 Jan 2018 13:22:54 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: rename brcmf_sdiod_buff_{read,write}() functions |  | ||||||
|  |  | ||||||
| Rename functions to brcmf_sdio_skbuff_{read,write}() as we pass an |  | ||||||
| skbuff to this function. |  | ||||||
|  |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 48 +++++++++++----------- |  | ||||||
|  1 file changed, 24 insertions(+), 24 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  | ||||||
| @@ -292,24 +292,24 @@ out: |  | ||||||
|  		*ret = retval; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev, |  | ||||||
| -				 struct sdio_func *func, u32 addr, |  | ||||||
| -				 struct sk_buff *pkt) |  | ||||||
| +static int brcmf_sdiod_skbuff_read(struct brcmf_sdio_dev *sdiodev, |  | ||||||
| +				   struct sdio_func *func, u32 addr, |  | ||||||
| +				   struct sk_buff *skb) |  | ||||||
|  { |  | ||||||
|  	unsigned int req_sz; |  | ||||||
|  	int err; |  | ||||||
|   |  | ||||||
|  	/* Single skb use the standard mmc interface */ |  | ||||||
| -	req_sz = pkt->len + 3; |  | ||||||
| +	req_sz = skb->len + 3; |  | ||||||
|  	req_sz &= (uint)~3; |  | ||||||
|   |  | ||||||
|  	switch (func->num) { |  | ||||||
|  	case 1: |  | ||||||
| -		err = sdio_memcpy_fromio(func, ((u8 *)(pkt->data)), addr, |  | ||||||
| +		err = sdio_memcpy_fromio(func, ((u8 *)(skb->data)), addr, |  | ||||||
|  					 req_sz); |  | ||||||
|  		break; |  | ||||||
|  	case 2: |  | ||||||
| -		err = sdio_readsb(func, ((u8 *)(pkt->data)), addr, req_sz); |  | ||||||
| +		err = sdio_readsb(func, ((u8 *)(skb->data)), addr, req_sz); |  | ||||||
|  		break; |  | ||||||
|  	default: |  | ||||||
|  		/* bail out as things are really fishy here */ |  | ||||||
| @@ -323,18 +323,18 @@ static int brcmf_sdiod_buff_read(struct |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev, |  | ||||||
| -				  struct sdio_func *func, u32 addr, |  | ||||||
| -				  struct sk_buff *pkt) |  | ||||||
| +static int brcmf_sdiod_skbuff_write(struct brcmf_sdio_dev *sdiodev, |  | ||||||
| +				    struct sdio_func *func, u32 addr, |  | ||||||
| +				    struct sk_buff *skb) |  | ||||||
|  { |  | ||||||
|  	unsigned int req_sz; |  | ||||||
|  	int err; |  | ||||||
|   |  | ||||||
|  	/* Single skb use the standard mmc interface */ |  | ||||||
| -	req_sz = pkt->len + 3; |  | ||||||
| +	req_sz = skb->len + 3; |  | ||||||
|  	req_sz &= (uint)~3; |  | ||||||
|   |  | ||||||
| -	err = sdio_memcpy_toio(func, addr, ((u8 *)(pkt->data)), req_sz); |  | ||||||
| +	err = sdio_memcpy_toio(func, addr, ((u8 *)(skb->data)), req_sz); |  | ||||||
|   |  | ||||||
|  	if (err == -ENOMEDIUM) |  | ||||||
|  		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); |  | ||||||
| @@ -550,7 +550,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd |  | ||||||
|  	addr &= SBSDIO_SB_OFT_ADDR_MASK; |  | ||||||
|  	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
|   |  | ||||||
| -	err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func2, addr, pkt); |  | ||||||
| +	err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func2, addr, pkt); |  | ||||||
|   |  | ||||||
|  done: |  | ||||||
|  	return err; |  | ||||||
| @@ -575,14 +575,14 @@ int brcmf_sdiod_recv_chain(struct brcmf_ |  | ||||||
|  	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
|   |  | ||||||
|  	if (pktq->qlen == 1) |  | ||||||
| -		err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func2, addr, |  | ||||||
| -					    pktq->next); |  | ||||||
| +		err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func2, addr, |  | ||||||
| +					      pktq->next); |  | ||||||
|  	else if (!sdiodev->sg_support) { |  | ||||||
|  		glom_skb = brcmu_pkt_buf_get_skb(totlen); |  | ||||||
|  		if (!glom_skb) |  | ||||||
|  			return -ENOMEM; |  | ||||||
| -		err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func2, addr, |  | ||||||
| -					    glom_skb); |  | ||||||
| +		err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func2, addr, |  | ||||||
| +					      glom_skb); |  | ||||||
|  		if (err) |  | ||||||
|  			goto done; |  | ||||||
|   |  | ||||||
| @@ -623,8 +623,8 @@ int brcmf_sdiod_send_buf(struct brcmf_sd |  | ||||||
|  	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; |  | ||||||
|   |  | ||||||
|  	if (!err) |  | ||||||
| -		err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func2, addr, |  | ||||||
| -					     mypkt); |  | ||||||
| +		err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func2, addr, |  | ||||||
| +					       mypkt); |  | ||||||
|   |  | ||||||
|  	brcmu_pkt_buf_free_skb(mypkt); |  | ||||||
|   |  | ||||||
| @@ -649,8 +649,8 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd |  | ||||||
|   |  | ||||||
|  	if (pktq->qlen == 1 || !sdiodev->sg_support) { |  | ||||||
|  		skb_queue_walk(pktq, skb) { |  | ||||||
| -			err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func2, |  | ||||||
| -						     addr, skb); |  | ||||||
| +			err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func2, |  | ||||||
| +						       addr, skb); |  | ||||||
|  			if (err) |  | ||||||
|  				break; |  | ||||||
|  		} |  | ||||||
| @@ -706,11 +706,11 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev |  | ||||||
|   |  | ||||||
|  		if (write) { |  | ||||||
|  			memcpy(pkt->data, data, dsize); |  | ||||||
| -			err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func1, |  | ||||||
| -						     sdaddr, pkt); |  | ||||||
| +			err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func1, |  | ||||||
| +						       sdaddr, pkt); |  | ||||||
|  		} else { |  | ||||||
| -			err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func1, |  | ||||||
| -						    sdaddr, pkt); |  | ||||||
| +			err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func1, |  | ||||||
| +						      sdaddr, pkt); |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
|  		if (err) { |  | ||||||
| @@ -1,59 +0,0 @@ | |||||||
| From b7acadaf038740c43515dc1548f43d01cc92823a Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Himanshu Jha <himanshujha199640@gmail.com> |  | ||||||
| Date: Tue, 9 Jan 2018 02:15:31 +0530 |  | ||||||
| Subject: [PATCH] brcmfmac: Use zeroing memory allocator than allocator/memset |  | ||||||
|  |  | ||||||
| Use dma_zalloc_coherent for allocating zeroed |  | ||||||
| memory and remove unnecessary memset function. |  | ||||||
|  |  | ||||||
| Generated-by: scripts/coccinelle/api/alloc/kzalloc-simple.cocci |  | ||||||
|  |  | ||||||
| Suggested-by: Luis R. Rodriguez <mcgrof@kernel.org> |  | ||||||
| Signed-off-by: Himanshu Jha <himanshujha199640@gmail.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/pcie.c  | 20 ++++++++++---------- |  | ||||||
|  1 file changed, 10 insertions(+), 10 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| @@ -1251,14 +1251,14 @@ static int brcmf_pcie_init_scratchbuffer |  | ||||||
|  	u64 address; |  | ||||||
|  	u32 addr; |  | ||||||
|   |  | ||||||
| -	devinfo->shared.scratch = dma_alloc_coherent(&devinfo->pdev->dev, |  | ||||||
| -		BRCMF_DMA_D2H_SCRATCH_BUF_LEN, |  | ||||||
| -		&devinfo->shared.scratch_dmahandle, GFP_KERNEL); |  | ||||||
| +	devinfo->shared.scratch = |  | ||||||
| +		dma_zalloc_coherent(&devinfo->pdev->dev, |  | ||||||
| +					BRCMF_DMA_D2H_SCRATCH_BUF_LEN, |  | ||||||
| +					&devinfo->shared.scratch_dmahandle, |  | ||||||
| +					GFP_KERNEL); |  | ||||||
|  	if (!devinfo->shared.scratch) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
| -	memset(devinfo->shared.scratch, 0, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); |  | ||||||
| - |  | ||||||
|  	addr = devinfo->shared.tcm_base_address + |  | ||||||
|  	       BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET; |  | ||||||
|  	address = (u64)devinfo->shared.scratch_dmahandle; |  | ||||||
| @@ -1268,14 +1268,14 @@ static int brcmf_pcie_init_scratchbuffer |  | ||||||
|  	       BRCMF_SHARED_DMA_SCRATCH_LEN_OFFSET; |  | ||||||
|  	brcmf_pcie_write_tcm32(devinfo, addr, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); |  | ||||||
|   |  | ||||||
| -	devinfo->shared.ringupd = dma_alloc_coherent(&devinfo->pdev->dev, |  | ||||||
| -		BRCMF_DMA_D2H_RINGUPD_BUF_LEN, |  | ||||||
| -		&devinfo->shared.ringupd_dmahandle, GFP_KERNEL); |  | ||||||
| +	devinfo->shared.ringupd = |  | ||||||
| +		dma_zalloc_coherent(&devinfo->pdev->dev, |  | ||||||
| +					BRCMF_DMA_D2H_RINGUPD_BUF_LEN, |  | ||||||
| +					&devinfo->shared.ringupd_dmahandle, |  | ||||||
| +					GFP_KERNEL); |  | ||||||
|  	if (!devinfo->shared.ringupd) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
| -	memset(devinfo->shared.ringupd, 0, BRCMF_DMA_D2H_RINGUPD_BUF_LEN); |  | ||||||
| - |  | ||||||
|  	addr = devinfo->shared.tcm_base_address + |  | ||||||
|  	       BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET; |  | ||||||
|  	address = (u64)devinfo->shared.ringupd_dmahandle; |  | ||||||
| @@ -1,26 +0,0 @@ | |||||||
| From: Felix Fietkau <nbd@nbd.name> |  | ||||||
| Date: Fri, 9 Feb 2018 19:46:54 +0100 |  | ||||||
| Subject: [PATCH] mac80211: round IEEE80211_TX_STATUS_HEADROOM up to multiple |  | ||||||
|  of 4 |  | ||||||
|  |  | ||||||
| This ensures that mac80211 allocated management frames are properly |  | ||||||
| aligned, which makes copying them more efficient. |  | ||||||
| For instance, mt76 uses iowrite32_copy to copy beacon frames to beacon |  | ||||||
| template memory on the chip. |  | ||||||
| Misaligned 32-bit accesses cause CPU exceptions on MIPS and should be |  | ||||||
| avoided. |  | ||||||
|  |  | ||||||
| Signed-off-by: Felix Fietkau <nbd@nbd.name> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/include/net/mac80211.h |  | ||||||
| +++ b/include/net/mac80211.h |  | ||||||
| @@ -4145,7 +4145,7 @@ void ieee80211_sta_uapsd_trigger(struct |  | ||||||
|   * The TX headroom reserved by mac80211 for its own tx_status functions. |  | ||||||
|   * This is enough for the radiotap header. |  | ||||||
|   */ |  | ||||||
| -#define IEEE80211_TX_STATUS_HEADROOM	14 |  | ||||||
| +#define IEEE80211_TX_STATUS_HEADROOM	ALIGN(14, 4) |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
|   * ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| From: Felix Fietkau <nbd@nbd.name> |  | ||||||
| Date: Fri, 23 Feb 2018 09:59:35 +0100 |  | ||||||
| Subject: [PATCH] mac80211: drop frames with unexpected DS bits from |  | ||||||
|  fast-rx to slow path |  | ||||||
|  |  | ||||||
| Fixes rx for 4-addr packets in AP mode |  | ||||||
|  |  | ||||||
| Signed-off-by: Felix Fietkau <nbd@nbd.name> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -3928,7 +3928,7 @@ static bool ieee80211_invoke_fast_rx(str |  | ||||||
|  	if ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FROMDS | |  | ||||||
|  					      IEEE80211_FCTL_TODS)) != |  | ||||||
|  	    fast_rx->expected_ds_bits) |  | ||||||
| -		goto drop; |  | ||||||
| +		return false; |  | ||||||
|   |  | ||||||
|  	/* assign the key to drop unencrypted frames (later) |  | ||||||
|  	 * and strip the IV/MIC if necessary |  | ||||||
| @@ -1,25 +0,0 @@ | |||||||
| From: Felix Fietkau <nbd@nbd.name> |  | ||||||
| Date: Fri, 23 Feb 2018 10:00:22 +0100 |  | ||||||
| Subject: [PATCH] mac80211: support AP 4-addr mode fast-rx |  | ||||||
|  |  | ||||||
| Signed-off-by: Felix Fietkau <nbd@nbd.name> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -3774,6 +3774,15 @@ void ieee80211_check_fast_rx(struct sta_ |  | ||||||
|  			!(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && |  | ||||||
|  			(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || |  | ||||||
|  			 !sdata->u.vlan.sta); |  | ||||||
| + |  | ||||||
| +		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && |  | ||||||
| +		    sdata->u.vlan.sta) { |  | ||||||
| +			fastrx.expected_ds_bits |= |  | ||||||
| +				cpu_to_le16(IEEE80211_FCTL_FROMDS); |  | ||||||
| +			fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4); |  | ||||||
| +			fastrx.internal_forward = 0; |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
|  		break; |  | ||||||
|  	default: |  | ||||||
|  		goto clear; |  | ||||||
| @@ -1,53 +0,0 @@ | |||||||
| From: Felix Fietkau <nbd@nbd.name> |  | ||||||
| Date: Fri, 23 Feb 2018 10:01:53 +0100 |  | ||||||
| Subject: [PATCH] mac80211: support fast-rx with incompatible PS |  | ||||||
|  capabilities when PS is disabled |  | ||||||
|  |  | ||||||
| When powersave is disabled for the interface, we can do fast-rx anyway. |  | ||||||
|  |  | ||||||
| Signed-off-by: Felix Fietkau <nbd@nbd.name> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/cfg.c |  | ||||||
| +++ b/net/mac80211/cfg.c |  | ||||||
| @@ -2658,6 +2658,7 @@ static int ieee80211_set_power_mgmt(stru |  | ||||||
|   |  | ||||||
|  	ieee80211_recalc_ps(local); |  | ||||||
|  	ieee80211_recalc_ps_vif(sdata); |  | ||||||
| +	ieee80211_check_fast_rx_iface(sdata); |  | ||||||
|   |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -3741,12 +3741,7 @@ void ieee80211_check_fast_rx(struct sta_ |  | ||||||
|  		/* 4-addr is harder to deal with, later maybe */ |  | ||||||
|  		if (sdata->u.mgd.use_4addr) |  | ||||||
|  			goto clear; |  | ||||||
| -		/* software powersave is a huge mess, avoid all of it */ |  | ||||||
| -		if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK)) |  | ||||||
| -			goto clear; |  | ||||||
| -		if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) && |  | ||||||
| -		    !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS)) |  | ||||||
| -			goto clear; |  | ||||||
| + |  | ||||||
|  		if (sta->sta.tdls) { |  | ||||||
|  			fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1); |  | ||||||
|  			fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2); |  | ||||||
| @@ -3758,6 +3753,16 @@ void ieee80211_check_fast_rx(struct sta_ |  | ||||||
|  			fastrx.expected_ds_bits = |  | ||||||
|  				cpu_to_le16(IEEE80211_FCTL_FROMDS); |  | ||||||
|  		} |  | ||||||
| + |  | ||||||
| +		if (!sdata->u.mgd.powersave) |  | ||||||
| +		    break; |  | ||||||
| + |  | ||||||
| +		/* software powersave is a huge mess, avoid all of it */ |  | ||||||
| +		if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK)) |  | ||||||
| +			goto clear; |  | ||||||
| +		if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) && |  | ||||||
| +		    !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS)) |  | ||||||
| +			goto clear; |  | ||||||
|  		break; |  | ||||||
|  	case NL80211_IFTYPE_AP_VLAN: |  | ||||||
|  	case NL80211_IFTYPE_AP: |  | ||||||
| @@ -1,34 +0,0 @@ | |||||||
| From: Felix Fietkau <nbd@nbd.name> |  | ||||||
| Date: Fri, 23 Feb 2018 10:05:08 +0100 |  | ||||||
| Subject: [PATCH] mac80211: support station 4-addr mode fast-rx |  | ||||||
|  |  | ||||||
| Signed-off-by: Felix Fietkau <nbd@nbd.name> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -3738,10 +3738,6 @@ void ieee80211_check_fast_rx(struct sta_ |  | ||||||
|   |  | ||||||
|  	switch (sdata->vif.type) { |  | ||||||
|  	case NL80211_IFTYPE_STATION: |  | ||||||
| -		/* 4-addr is harder to deal with, later maybe */ |  | ||||||
| -		if (sdata->u.mgd.use_4addr) |  | ||||||
| -			goto clear; |  | ||||||
| - |  | ||||||
|  		if (sta->sta.tdls) { |  | ||||||
|  			fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1); |  | ||||||
|  			fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2); |  | ||||||
| @@ -3754,6 +3750,13 @@ void ieee80211_check_fast_rx(struct sta_ |  | ||||||
|  				cpu_to_le16(IEEE80211_FCTL_FROMDS); |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
| +		if (sdata->u.mgd.use_4addr && !sta->sta.tdls) { |  | ||||||
| +			fastrx.expected_ds_bits |= |  | ||||||
| +				cpu_to_le16(IEEE80211_FCTL_TODS); |  | ||||||
| +			fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3); |  | ||||||
| +			fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4); |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
|  		if (!sdata->u.mgd.powersave) |  | ||||||
|  		    break; |  | ||||||
|   |  | ||||||
| @@ -1,256 +0,0 @@ | |||||||
| From: Felix Fietkau <nbd@nbd.name> |  | ||||||
| Date: Mon, 26 Feb 2018 22:09:29 +0100 |  | ||||||
| Subject: [PATCH] mac80211: support A-MSDU in fast-rx |  | ||||||
|  |  | ||||||
| Only works if the IV was stripped from packets. Create a smaller |  | ||||||
| variant of ieee80211_rx_h_amsdu, which bypasses checks already done |  | ||||||
| within the fast-rx context. |  | ||||||
|  |  | ||||||
| Signed-off-by: Felix Fietkau <nbd@nbd.name> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -2358,39 +2358,17 @@ ieee80211_deliver_skb(struct ieee80211_r |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static ieee80211_rx_result debug_noinline |  | ||||||
| -ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) |  | ||||||
| +__ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset) |  | ||||||
|  { |  | ||||||
|  	struct net_device *dev = rx->sdata->dev; |  | ||||||
|  	struct sk_buff *skb = rx->skb; |  | ||||||
|  	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |  | ||||||
|  	__le16 fc = hdr->frame_control; |  | ||||||
|  	struct sk_buff_head frame_list; |  | ||||||
| -	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); |  | ||||||
|  	struct ethhdr ethhdr; |  | ||||||
|  	const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source; |  | ||||||
|   |  | ||||||
| -	if (unlikely(!ieee80211_is_data(fc))) |  | ||||||
| -		return RX_CONTINUE; |  | ||||||
| - |  | ||||||
| -	if (unlikely(!ieee80211_is_data_present(fc))) |  | ||||||
| -		return RX_DROP_MONITOR; |  | ||||||
| - |  | ||||||
| -	if (!(status->rx_flags & IEEE80211_RX_AMSDU)) |  | ||||||
| -		return RX_CONTINUE; |  | ||||||
| - |  | ||||||
|  	if (unlikely(ieee80211_has_a4(hdr->frame_control))) { |  | ||||||
| -		switch (rx->sdata->vif.type) { |  | ||||||
| -		case NL80211_IFTYPE_AP_VLAN: |  | ||||||
| -			if (!rx->sdata->u.vlan.sta) |  | ||||||
| -				return RX_DROP_UNUSABLE; |  | ||||||
| -			break; |  | ||||||
| -		case NL80211_IFTYPE_STATION: |  | ||||||
| -			if (!rx->sdata->u.mgd.use_4addr) |  | ||||||
| -				return RX_DROP_UNUSABLE; |  | ||||||
| -			break; |  | ||||||
| -		default: |  | ||||||
| -			return RX_DROP_UNUSABLE; |  | ||||||
| -		} |  | ||||||
|  		check_da = NULL; |  | ||||||
|  		check_sa = NULL; |  | ||||||
|  	} else switch (rx->sdata->vif.type) { |  | ||||||
| @@ -2410,15 +2388,13 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx |  | ||||||
|  			break; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	if (is_multicast_ether_addr(hdr->addr1)) |  | ||||||
| -		return RX_DROP_UNUSABLE; |  | ||||||
| - |  | ||||||
|  	skb->dev = dev; |  | ||||||
|  	__skb_queue_head_init(&frame_list); |  | ||||||
|   |  | ||||||
|  	if (ieee80211_data_to_8023_exthdr(skb, ðhdr, |  | ||||||
|  					  rx->sdata->vif.addr, |  | ||||||
| -					  rx->sdata->vif.type)) |  | ||||||
| +					  rx->sdata->vif.type, |  | ||||||
| +					  data_offset)) |  | ||||||
|  		return RX_DROP_UNUSABLE; |  | ||||||
|   |  | ||||||
|  	ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, |  | ||||||
| @@ -2440,6 +2416,44 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx |  | ||||||
|  	return RX_QUEUED; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static ieee80211_rx_result debug_noinline |  | ||||||
| +ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) |  | ||||||
| +{ |  | ||||||
| +	struct sk_buff *skb = rx->skb; |  | ||||||
| +	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |  | ||||||
| +	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |  | ||||||
| +	__le16 fc = hdr->frame_control; |  | ||||||
| + |  | ||||||
| +	if (!(status->rx_flags & IEEE80211_RX_AMSDU)) |  | ||||||
| +		return RX_CONTINUE; |  | ||||||
| + |  | ||||||
| +	if (unlikely(!ieee80211_is_data(fc))) |  | ||||||
| +		return RX_CONTINUE; |  | ||||||
| + |  | ||||||
| +	if (unlikely(!ieee80211_is_data_present(fc))) |  | ||||||
| +		return RX_DROP_MONITOR; |  | ||||||
| + |  | ||||||
| +	if (unlikely(ieee80211_has_a4(hdr->frame_control))) { |  | ||||||
| +		switch (rx->sdata->vif.type) { |  | ||||||
| +		case NL80211_IFTYPE_AP_VLAN: |  | ||||||
| +			if (!rx->sdata->u.vlan.sta) |  | ||||||
| +				return RX_DROP_UNUSABLE; |  | ||||||
| +			break; |  | ||||||
| +		case NL80211_IFTYPE_STATION: |  | ||||||
| +			if (!rx->sdata->u.mgd.use_4addr) |  | ||||||
| +				return RX_DROP_UNUSABLE; |  | ||||||
| +			break; |  | ||||||
| +		default: |  | ||||||
| +			return RX_DROP_UNUSABLE; |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	if (is_multicast_ether_addr(hdr->addr1)) |  | ||||||
| +		return RX_DROP_UNUSABLE; |  | ||||||
| + |  | ||||||
| +	return __ieee80211_rx_h_amsdu(rx, 0); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  #ifdef CPTCFG_MAC80211_MESH |  | ||||||
|  static ieee80211_rx_result |  | ||||||
|  ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) |  | ||||||
| @@ -3889,7 +3903,8 @@ static bool ieee80211_invoke_fast_rx(str |  | ||||||
|  	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |  | ||||||
|  	struct sta_info *sta = rx->sta; |  | ||||||
|  	int orig_len = skb->len; |  | ||||||
| -	int snap_offs = ieee80211_hdrlen(hdr->frame_control); |  | ||||||
| +	int hdrlen = ieee80211_hdrlen(hdr->frame_control); |  | ||||||
| +	int snap_offs = hdrlen; |  | ||||||
|  	struct { |  | ||||||
|  		u8 snap[sizeof(rfc1042_header)]; |  | ||||||
|  		__be16 proto; |  | ||||||
| @@ -3920,10 +3935,6 @@ static bool ieee80211_invoke_fast_rx(str |  | ||||||
|  	    (status->flag & FAST_RX_CRYPT_FLAGS) != FAST_RX_CRYPT_FLAGS) |  | ||||||
|  		return false; |  | ||||||
|   |  | ||||||
| -	/* we don't deal with A-MSDU deaggregation here */ |  | ||||||
| -	if (status->rx_flags & IEEE80211_RX_AMSDU) |  | ||||||
| -		return false; |  | ||||||
| - |  | ||||||
|  	if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) |  | ||||||
|  		return false; |  | ||||||
|   |  | ||||||
| @@ -3955,21 +3966,24 @@ static bool ieee80211_invoke_fast_rx(str |  | ||||||
|  		snap_offs += IEEE80211_CCMP_HDR_LEN; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) |  | ||||||
| -		goto drop; |  | ||||||
| -	payload = (void *)(skb->data + snap_offs); |  | ||||||
| +	if (!(status->rx_flags & IEEE80211_RX_AMSDU)) { |  | ||||||
| +		if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) |  | ||||||
| +			goto drop; |  | ||||||
|   |  | ||||||
| -	if (!ether_addr_equal(payload->snap, fast_rx->rfc1042_hdr)) |  | ||||||
| -		return false; |  | ||||||
| +		payload = (void *)(skb->data + snap_offs); |  | ||||||
|   |  | ||||||
| -	/* Don't handle these here since they require special code. |  | ||||||
| -	 * Accept AARP and IPX even though they should come with a |  | ||||||
| -	 * bridge-tunnel header - but if we get them this way then |  | ||||||
| -	 * there's little point in discarding them. |  | ||||||
| -	 */ |  | ||||||
| -	if (unlikely(payload->proto == cpu_to_be16(ETH_P_TDLS) || |  | ||||||
| -		     payload->proto == fast_rx->control_port_protocol)) |  | ||||||
| -		return false; |  | ||||||
| +		if (!ether_addr_equal(payload->snap, fast_rx->rfc1042_hdr)) |  | ||||||
| +			return false; |  | ||||||
| + |  | ||||||
| +		/* Don't handle these here since they require special code. |  | ||||||
| +		 * Accept AARP and IPX even though they should come with a |  | ||||||
| +		 * bridge-tunnel header - but if we get them this way then |  | ||||||
| +		 * there's little point in discarding them. |  | ||||||
| +		 */ |  | ||||||
| +		if (unlikely(payload->proto == cpu_to_be16(ETH_P_TDLS) || |  | ||||||
| +			     payload->proto == fast_rx->control_port_protocol)) |  | ||||||
| +			return false; |  | ||||||
| +	} |  | ||||||
|   |  | ||||||
|  	/* after this point, don't punt to the slowpath! */ |  | ||||||
|   |  | ||||||
| @@ -3983,12 +3997,6 @@ static bool ieee80211_invoke_fast_rx(str |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	/* statistics part of ieee80211_rx_h_sta_process() */ |  | ||||||
| -	stats->last_rx = jiffies; |  | ||||||
| -	stats->last_rate = sta_stats_encode_rate(status); |  | ||||||
| - |  | ||||||
| -	stats->fragments++; |  | ||||||
| -	stats->packets++; |  | ||||||
| - |  | ||||||
|  	if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { |  | ||||||
|  		stats->last_signal = status->signal; |  | ||||||
|  		if (!fast_rx->uses_rss) |  | ||||||
| @@ -4017,6 +4025,20 @@ static bool ieee80211_invoke_fast_rx(str |  | ||||||
|  	if (rx->key && !ieee80211_has_protected(hdr->frame_control)) |  | ||||||
|  		goto drop; |  | ||||||
|   |  | ||||||
| +	if (status->rx_flags & IEEE80211_RX_AMSDU) { |  | ||||||
| +		if (__ieee80211_rx_h_amsdu(rx, snap_offs - hdrlen) != |  | ||||||
| +		    RX_QUEUED) |  | ||||||
| +			goto drop; |  | ||||||
| + |  | ||||||
| +		return true; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	stats->last_rx = jiffies; |  | ||||||
| +	stats->last_rate = sta_stats_encode_rate(status); |  | ||||||
| + |  | ||||||
| +	stats->fragments++; |  | ||||||
| +	stats->packets++; |  | ||||||
| + |  | ||||||
|  	/* do the header conversion - first grab the addresses */ |  | ||||||
|  	ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs); |  | ||||||
|  	ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs); |  | ||||||
| --- a/include/net/cfg80211.h |  | ||||||
| +++ b/include/net/cfg80211.h |  | ||||||
| @@ -4331,10 +4331,12 @@ unsigned int ieee80211_get_mesh_hdrlen(s |  | ||||||
|   *	of it being pushed into the SKB |  | ||||||
|   * @addr: the device MAC address |  | ||||||
|   * @iftype: the virtual interface type |  | ||||||
| + * @data_offset: offset of payload after the 802.11 header |  | ||||||
|   * Return: 0 on success. Non-zero on error. |  | ||||||
|   */ |  | ||||||
|  int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, |  | ||||||
| -				  const u8 *addr, enum nl80211_iftype iftype); |  | ||||||
| +				  const u8 *addr, enum nl80211_iftype iftype, |  | ||||||
| +				  u8 data_offset); |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
|   * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3 |  | ||||||
| @@ -4346,7 +4348,7 @@ int ieee80211_data_to_8023_exthdr(struct |  | ||||||
|  static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, |  | ||||||
|  					 enum nl80211_iftype iftype) |  | ||||||
|  { |  | ||||||
| -	return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype); |  | ||||||
| +	return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
| --- a/net/wireless/util.c |  | ||||||
| +++ b/net/wireless/util.c |  | ||||||
| @@ -419,7 +419,8 @@ unsigned int ieee80211_get_mesh_hdrlen(s |  | ||||||
|  EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); |  | ||||||
|   |  | ||||||
|  int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, |  | ||||||
| -				  const u8 *addr, enum nl80211_iftype iftype) |  | ||||||
| +				  const u8 *addr, enum nl80211_iftype iftype, |  | ||||||
| +				  u8 data_offset) |  | ||||||
|  { |  | ||||||
|  	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |  | ||||||
|  	struct { |  | ||||||
| @@ -433,7 +434,7 @@ int ieee80211_data_to_8023_exthdr(struct |  | ||||||
|  	if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) |  | ||||||
|  		return -1; |  | ||||||
|   |  | ||||||
| -	hdrlen = ieee80211_hdrlen(hdr->frame_control); |  | ||||||
| +	hdrlen = ieee80211_hdrlen(hdr->frame_control) + data_offset; |  | ||||||
|  	if (skb->len < hdrlen + 8) |  | ||||||
|  		return -1; |  | ||||||
|   |  | ||||||
| @@ -1,68 +0,0 @@ | |||||||
| From 5242a5444e0b6464d7455beb55d936dd192b5e9d Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Mon, 22 Jan 2018 21:46:39 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: assure bcdc dcmd api does not return value > 0 |  | ||||||
|  |  | ||||||
| The protocol layer api defines callbacks for dongle commands. |  | ||||||
| Although not really well documented these should only return an |  | ||||||
| error code in case of an error, or 0 upon success. In the bcdc |  | ||||||
| protocol it can return value above 0 and we carry a fix in the |  | ||||||
| caller of the protocol layer api. This patch makes it adhere to |  | ||||||
| the intent of the api as described above. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 6 +++++- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c | 8 +++----- |  | ||||||
|  2 files changed, 8 insertions(+), 6 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c |  | ||||||
| @@ -211,6 +211,8 @@ retry: |  | ||||||
|  		memcpy(buf, info, len); |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	ret = 0; |  | ||||||
| + |  | ||||||
|  	/* Check the ERROR flag */ |  | ||||||
|  	if (flags & BCDC_DCMD_ERROR) |  | ||||||
|  		ret = le32_to_cpu(msg->status); |  | ||||||
| @@ -225,7 +227,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_p |  | ||||||
|  { |  | ||||||
|  	struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; |  | ||||||
|  	struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg; |  | ||||||
| -	int ret = 0; |  | ||||||
| +	int ret; |  | ||||||
|  	u32 flags, id; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); |  | ||||||
| @@ -249,6 +251,8 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_p |  | ||||||
|  		goto done; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	ret = 0; |  | ||||||
| + |  | ||||||
|  	/* Check the ERROR flag */ |  | ||||||
|  	if (flags & BCDC_DCMD_ERROR) |  | ||||||
|  		ret = le32_to_cpu(msg->status); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c |  | ||||||
| @@ -121,11 +121,9 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, |  | ||||||
|  	else |  | ||||||
|  		err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len); |  | ||||||
|   |  | ||||||
| -	if (err >= 0) |  | ||||||
| -		return 0; |  | ||||||
| - |  | ||||||
| -	brcmf_dbg(FIL, "Failed: %s (%d)\n", |  | ||||||
| -		  brcmf_fil_get_errstr((u32)(-err)), err); |  | ||||||
| +	if (err) |  | ||||||
| +		brcmf_dbg(FIL, "Failed: %s (%d)\n", |  | ||||||
| +			  brcmf_fil_get_errstr((u32)(-err)), err); |  | ||||||
|   |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
| @@ -1,186 +0,0 @@ | |||||||
| From b69c1df47281ad47bd2037a42b98f5c7115b7fd5 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Mon, 22 Jan 2018 21:46:40 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: separate firmware errors from i/o errors |  | ||||||
|  |  | ||||||
| When using the firmware api it can fail simply because firmware does |  | ||||||
| not like the request or it fails due to issues in the host interface. |  | ||||||
| Currently, there is only a single error code which is confusing. So |  | ||||||
| adding a parameter to pass the firmware error separately and in case |  | ||||||
| of a firmware error always return -EBADE to user-space. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c  | 11 ++++++----- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c  | 16 +++++++++++----- |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c    | 10 ++++++---- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | 14 ++++++++------ |  | ||||||
|  4 files changed, 31 insertions(+), 20 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c |  | ||||||
| @@ -165,7 +165,7 @@ static int brcmf_proto_bcdc_cmplt(struct |  | ||||||
|   |  | ||||||
|  static int |  | ||||||
|  brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, |  | ||||||
| -			    void *buf, uint len) |  | ||||||
| +			    void *buf, uint len, int *fwerr) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; |  | ||||||
|  	struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg; |  | ||||||
| @@ -175,6 +175,7 @@ brcmf_proto_bcdc_query_dcmd(struct brcmf |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); |  | ||||||
|   |  | ||||||
| +	*fwerr = 0; |  | ||||||
|  	ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false); |  | ||||||
|  	if (ret < 0) { |  | ||||||
|  		brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n", |  | ||||||
| @@ -215,15 +216,14 @@ retry: |  | ||||||
|   |  | ||||||
|  	/* Check the ERROR flag */ |  | ||||||
|  	if (flags & BCDC_DCMD_ERROR) |  | ||||||
| -		ret = le32_to_cpu(msg->status); |  | ||||||
| - |  | ||||||
| +		*fwerr = le32_to_cpu(msg->status); |  | ||||||
|  done: |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static int |  | ||||||
|  brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, |  | ||||||
| -			  void *buf, uint len) |  | ||||||
| +			  void *buf, uint len, int *fwerr) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; |  | ||||||
|  	struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg; |  | ||||||
| @@ -232,6 +232,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_p |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); |  | ||||||
|   |  | ||||||
| +	*fwerr = 0; |  | ||||||
|  	ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, true); |  | ||||||
|  	if (ret < 0) |  | ||||||
|  		goto done; |  | ||||||
| @@ -255,7 +256,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_p |  | ||||||
|   |  | ||||||
|  	/* Check the ERROR flag */ |  | ||||||
|  	if (flags & BCDC_DCMD_ERROR) |  | ||||||
| -		ret = le32_to_cpu(msg->status); |  | ||||||
| +		*fwerr = le32_to_cpu(msg->status); |  | ||||||
|   |  | ||||||
|  done: |  | ||||||
|  	return ret; |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c |  | ||||||
| @@ -107,7 +107,7 @@ static s32 |  | ||||||
|  brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_pub *drvr = ifp->drvr; |  | ||||||
| -	s32 err; |  | ||||||
| +	s32 err, fwerr; |  | ||||||
|   |  | ||||||
|  	if (drvr->bus_if->state != BRCMF_BUS_UP) { |  | ||||||
|  		brcmf_err("bus is down. we have nothing to do.\n"); |  | ||||||
| @@ -117,14 +117,20 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, |  | ||||||
|  	if (data != NULL) |  | ||||||
|  		len = min_t(uint, len, BRCMF_DCMD_MAXLEN); |  | ||||||
|  	if (set) |  | ||||||
| -		err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd, data, len); |  | ||||||
| +		err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd, |  | ||||||
| +					   data, len, &fwerr); |  | ||||||
|  	else |  | ||||||
| -		err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len); |  | ||||||
| +		err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, |  | ||||||
| +					     data, len, &fwerr); |  | ||||||
|   |  | ||||||
| -	if (err) |  | ||||||
| +	if (err) { |  | ||||||
|  		brcmf_dbg(FIL, "Failed: %s (%d)\n", |  | ||||||
|  			  brcmf_fil_get_errstr((u32)(-err)), err); |  | ||||||
| - |  | ||||||
| +	} else if (fwerr < 0) { |  | ||||||
| +		brcmf_dbg(FIL, "Firmware error: %s (%d)\n", |  | ||||||
| +			  brcmf_fil_get_errstr((u32)(-fwerr)), fwerr); |  | ||||||
| +		err = -EBADE; |  | ||||||
| +	} |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c |  | ||||||
| @@ -477,7 +477,7 @@ static void brcmf_msgbuf_ioctl_resp_wake |  | ||||||
|   |  | ||||||
|   |  | ||||||
|  static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx, |  | ||||||
| -				   uint cmd, void *buf, uint len) |  | ||||||
| +				   uint cmd, void *buf, uint len, int *fwerr) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd; |  | ||||||
|  	struct sk_buff *skb = NULL; |  | ||||||
| @@ -485,6 +485,7 @@ static int brcmf_msgbuf_query_dcmd(struc |  | ||||||
|  	int err; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(MSGBUF, "ifidx=%d, cmd=%d, len=%d\n", ifidx, cmd, len); |  | ||||||
| +	*fwerr = 0; |  | ||||||
|  	msgbuf->ctl_completed = false; |  | ||||||
|  	err = brcmf_msgbuf_tx_ioctl(drvr, ifidx, cmd, buf, len); |  | ||||||
|  	if (err) |  | ||||||
| @@ -508,14 +509,15 @@ static int brcmf_msgbuf_query_dcmd(struc |  | ||||||
|  	} |  | ||||||
|  	brcmu_pkt_buf_free_skb(skb); |  | ||||||
|   |  | ||||||
| -	return msgbuf->ioctl_resp_status; |  | ||||||
| +	*fwerr = msgbuf->ioctl_resp_status; |  | ||||||
| +	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
|  static int brcmf_msgbuf_set_dcmd(struct brcmf_pub *drvr, int ifidx, |  | ||||||
| -				 uint cmd, void *buf, uint len) |  | ||||||
| +				 uint cmd, void *buf, uint len, int *fwerr) |  | ||||||
|  { |  | ||||||
| -	return brcmf_msgbuf_query_dcmd(drvr, ifidx, cmd, buf, len); |  | ||||||
| +	return brcmf_msgbuf_query_dcmd(drvr, ifidx, cmd, buf, len, fwerr); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h |  | ||||||
| @@ -30,9 +30,9 @@ struct brcmf_proto { |  | ||||||
|  	int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, |  | ||||||
|  		       struct sk_buff *skb, struct brcmf_if **ifp); |  | ||||||
|  	int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, |  | ||||||
| -			  void *buf, uint len); |  | ||||||
| +			  void *buf, uint len, int *fwerr); |  | ||||||
|  	int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, |  | ||||||
| -			uint len); |  | ||||||
| +			uint len, int *fwerr); |  | ||||||
|  	int (*tx_queue_data)(struct brcmf_pub *drvr, int ifidx, |  | ||||||
|  			     struct sk_buff *skb); |  | ||||||
|  	int (*txdata)(struct brcmf_pub *drvr, int ifidx, u8 offset, |  | ||||||
| @@ -71,14 +71,16 @@ static inline int brcmf_proto_hdrpull(st |  | ||||||
|  	return drvr->proto->hdrpull(drvr, do_fws, skb, ifp); |  | ||||||
|  } |  | ||||||
|  static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx, |  | ||||||
| -					 uint cmd, void *buf, uint len) |  | ||||||
| +					 uint cmd, void *buf, uint len, |  | ||||||
| +					 int *fwerr) |  | ||||||
|  { |  | ||||||
| -	return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len); |  | ||||||
| +	return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len,fwerr); |  | ||||||
|  } |  | ||||||
|  static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx, |  | ||||||
| -				       uint cmd, void *buf, uint len) |  | ||||||
| +				       uint cmd, void *buf, uint len, |  | ||||||
| +				       int *fwerr) |  | ||||||
|  { |  | ||||||
| -	return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len); |  | ||||||
| +	return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len, fwerr); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static inline int brcmf_proto_tx_queue_data(struct brcmf_pub *drvr, int ifidx, |  | ||||||
| @@ -1,92 +0,0 @@ | |||||||
| From 933897342d0714ae1c10729cbaeecea0c6178db5 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Wed, 28 Feb 2018 21:15:19 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: add possibility to obtain firmware error |  | ||||||
|  |  | ||||||
| The feature module needs to evaluate the actual firmware error return |  | ||||||
| upon a control command. This adds a flag to struct brcmf_if that the |  | ||||||
| caller can set. This flag is checked to determine the error code that |  | ||||||
| needs to be returned. |  | ||||||
|  |  | ||||||
| Fixes: b69c1df47281 ("brcmfmac: separate firmware errors from i/o errors") |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h    |  2 ++ |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 10 ++++++++++ |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c    |  3 +++ |  | ||||||
|  3 files changed, 15 insertions(+) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h |  | ||||||
| @@ -181,6 +181,7 @@ enum brcmf_netif_stop_reason { |  | ||||||
|   * @netif_stop_lock: spinlock for update netif_stop from multiple sources. |  | ||||||
|   * @pend_8021x_cnt: tracks outstanding number of 802.1x frames. |  | ||||||
|   * @pend_8021x_wait: used for signalling change in count. |  | ||||||
| + * @fwil_fwerr: flag indicating fwil layer should return firmware error codes. |  | ||||||
|   */ |  | ||||||
|  struct brcmf_if { |  | ||||||
|  	struct brcmf_pub *drvr; |  | ||||||
| @@ -198,6 +199,7 @@ struct brcmf_if { |  | ||||||
|  	wait_queue_head_t pend_8021x_wait; |  | ||||||
|  	struct in6_addr ipv6_addr_tbl[NDOL_MAX_ENTRIES]; |  | ||||||
|  	u8 ipv6addr_idx; |  | ||||||
| +	bool fwil_fwerr; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c |  | ||||||
| @@ -104,6 +104,9 @@ static void brcmf_feat_iovar_int_get(str |  | ||||||
|  	u32 data; |  | ||||||
|  	int err; |  | ||||||
|   |  | ||||||
| +	/* we need to know firmware error */ |  | ||||||
| +	ifp->fwil_fwerr = true; |  | ||||||
| + |  | ||||||
|  	err = brcmf_fil_iovar_int_get(ifp, name, &data); |  | ||||||
|  	if (err == 0) { |  | ||||||
|  		brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]); |  | ||||||
| @@ -112,6 +115,8 @@ static void brcmf_feat_iovar_int_get(str |  | ||||||
|  		brcmf_dbg(TRACE, "%s feature check failed: %d\n", |  | ||||||
|  			  brcmf_feat_names[id], err); |  | ||||||
|  	} |  | ||||||
| + |  | ||||||
| +	ifp->fwil_fwerr = false; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp, |  | ||||||
| @@ -120,6 +125,9 @@ static void brcmf_feat_iovar_data_set(st |  | ||||||
|  { |  | ||||||
|  	int err; |  | ||||||
|   |  | ||||||
| +	/* we need to know firmware error */ |  | ||||||
| +	ifp->fwil_fwerr = true; |  | ||||||
| + |  | ||||||
|  	err = brcmf_fil_iovar_data_set(ifp, name, data, len); |  | ||||||
|  	if (err != -BRCMF_FW_UNSUPPORTED) { |  | ||||||
|  		brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]); |  | ||||||
| @@ -128,6 +136,8 @@ static void brcmf_feat_iovar_data_set(st |  | ||||||
|  		brcmf_dbg(TRACE, "%s feature check failed: %d\n", |  | ||||||
|  			  brcmf_feat_names[id], err); |  | ||||||
|  	} |  | ||||||
| + |  | ||||||
| +	ifp->fwil_fwerr = false; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  #define MAX_CAPS_BUFFER_SIZE	512 |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c |  | ||||||
| @@ -131,6 +131,9 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, |  | ||||||
|  			  brcmf_fil_get_errstr((u32)(-fwerr)), fwerr); |  | ||||||
|  		err = -EBADE; |  | ||||||
|  	} |  | ||||||
| +	if (ifp->fwil_fwerr) |  | ||||||
| +		return fwerr; |  | ||||||
| + |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -1,64 +0,0 @@ | |||||||
| From 455f3e76cfc0d893585a5f358b9ddbe9c1e1e53b Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Wed, 28 Feb 2018 21:15:20 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: fix P2P_DEVICE ethernet address generation |  | ||||||
|  |  | ||||||
| The firmware has a requirement that the P2P_DEVICE address should |  | ||||||
| be different from the address of the primary interface. When not |  | ||||||
| specified by user-space, the driver generates the MAC address for |  | ||||||
| the P2P_DEVICE interface using the MAC address of the primary |  | ||||||
| interface and setting the locally administered bit. However, the MAC |  | ||||||
| address of the primary interface may already have that bit set causing |  | ||||||
| the creation of the P2P_DEVICE interface to fail with -EBUSY. Fix this |  | ||||||
| by using a random address instead to determine the P2P_DEVICE address. |  | ||||||
|  |  | ||||||
| Cc: stable@vger.kernel.org # 3.10.y |  | ||||||
| Reported-by: Hans de Goede <hdegoede@redhat.com> |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 24 ++++++++++------------ |  | ||||||
|  1 file changed, 11 insertions(+), 13 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  | ||||||
| @@ -462,25 +462,23 @@ static int brcmf_p2p_set_firmware(struct |  | ||||||
|   * @dev_addr: optional device address. |  | ||||||
|   * |  | ||||||
|   * P2P needs mac addresses for P2P device and interface. If no device |  | ||||||
| - * address it specified, these are derived from the primary net device, ie. |  | ||||||
| - * the permanent ethernet address of the device. |  | ||||||
| + * address it specified, these are derived from a random ethernet |  | ||||||
| + * address. |  | ||||||
|   */ |  | ||||||
|  static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; |  | ||||||
| -	bool local_admin = false; |  | ||||||
| +	bool random_addr = false; |  | ||||||
|   |  | ||||||
| -	if (!dev_addr || is_zero_ether_addr(dev_addr)) { |  | ||||||
| -		dev_addr = pri_ifp->mac_addr; |  | ||||||
| -		local_admin = true; |  | ||||||
| -	} |  | ||||||
| +	if (!dev_addr || is_zero_ether_addr(dev_addr)) |  | ||||||
| +		random_addr = true; |  | ||||||
|   |  | ||||||
| -	/* Generate the P2P Device Address.  This consists of the device's |  | ||||||
| -	 * primary MAC address with the locally administered bit set. |  | ||||||
| +	/* Generate the P2P Device Address obtaining a random ethernet |  | ||||||
| +	 * address with the locally administered bit set. |  | ||||||
|  	 */ |  | ||||||
| -	memcpy(p2p->dev_addr, dev_addr, ETH_ALEN); |  | ||||||
| -	if (local_admin) |  | ||||||
| -		p2p->dev_addr[0] |= 0x02; |  | ||||||
| +	if (random_addr) |  | ||||||
| +		eth_random_addr(p2p->dev_addr); |  | ||||||
| +	else |  | ||||||
| +		memcpy(p2p->dev_addr, dev_addr, ETH_ALEN); |  | ||||||
|   |  | ||||||
|  	/* Generate the P2P Interface Address.  If the discovery and connection |  | ||||||
|  	 * BSSCFGs need to simultaneously co-exist, then this address must be |  | ||||||
| @@ -1,157 +0,0 @@ | |||||||
| From 1259055170287a350cad453e9eac139c81609860 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> |  | ||||||
| Date: Thu, 15 Mar 2018 08:29:09 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: drop Inter-Access Point Protocol packets by default |  | ||||||
| MIME-Version: 1.0 |  | ||||||
| Content-Type: text/plain; charset=UTF-8 |  | ||||||
| Content-Transfer-Encoding: 8bit |  | ||||||
|  |  | ||||||
| Testing brcmfmac with more recent firmwares resulted in AP interfaces |  | ||||||
| not working in some specific setups. Debugging resulted in discovering |  | ||||||
| support for IAPP in Broadcom's firmwares. |  | ||||||
|  |  | ||||||
| Older firmwares were only generating 802.11f frames. Newer ones like: |  | ||||||
| 1) 10.10 (TOB) (r663589) |  | ||||||
| 2) 10.10.122.20 (r683106) |  | ||||||
| for 4366b1 and 4366c0 respectively seem to also /respect/ 802.11f frames |  | ||||||
| in the Tx path by performing a STA disassociation. |  | ||||||
|  |  | ||||||
| This obsoleted standard and its implementation is something that: |  | ||||||
| 1) Most people don't need / want to use |  | ||||||
| 2) Can allow local DoS attacks |  | ||||||
| 3) Breaks AP interfaces in some specific bridge setups |  | ||||||
|  |  | ||||||
| To solve issues it can cause this commit modifies brcmfmac to drop IAPP |  | ||||||
| packets. If affects: |  | ||||||
| 1) Rx path: driver won't be sending these unwanted packets up. |  | ||||||
| 2) Tx path: driver will reject packets that would trigger STA |  | ||||||
|    disassociation perfromed by a firmware (possible local DoS attack). |  | ||||||
|  |  | ||||||
| It appears there are some Broadcom's clients/users who care about this |  | ||||||
| feature despite the drawbacks. They can switch it on using a new module |  | ||||||
| param. |  | ||||||
|  |  | ||||||
| This change results in only two more comparisons (check for module param |  | ||||||
| and check for Ethernet packet length) for 99.9% of packets. Its overhead |  | ||||||
| should be very minimal. |  | ||||||
|  |  | ||||||
| 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> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/common.c  |  5 ++ |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/common.h  |  1 + |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.c    | 57 ++++++++++++++++++++++ |  | ||||||
|  3 files changed, 63 insertions(+) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| @@ -75,6 +75,10 @@ static int brcmf_roamoff; |  | ||||||
|  module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR); |  | ||||||
|  MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine"); |  | ||||||
|   |  | ||||||
| +static int brcmf_iapp_enable; |  | ||||||
| +module_param_named(iapp, brcmf_iapp_enable, int, 0); |  | ||||||
| +MODULE_PARM_DESC(iapp, "Enable partial support for the obsoleted Inter-Access Point Protocol"); |  | ||||||
| + |  | ||||||
|  #ifdef DEBUG |  | ||||||
|  /* always succeed brcmf_bus_started() */ |  | ||||||
|  static int brcmf_ignore_probe_fail; |  | ||||||
| @@ -441,6 +445,7 @@ struct brcmf_mp_device *brcmf_get_module |  | ||||||
|  	settings->feature_disable = brcmf_feature_disable; |  | ||||||
|  	settings->fcmode = brcmf_fcmode; |  | ||||||
|  	settings->roamoff = !!brcmf_roamoff; |  | ||||||
| +	settings->iapp = !!brcmf_iapp_enable; |  | ||||||
|  #ifdef DEBUG |  | ||||||
|  	settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; |  | ||||||
|  #endif |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h |  | ||||||
| @@ -58,6 +58,7 @@ struct brcmf_mp_device { |  | ||||||
|  	unsigned int	feature_disable; |  | ||||||
|  	int		fcmode; |  | ||||||
|  	bool		roamoff; |  | ||||||
| +	bool		iapp; |  | ||||||
|  	bool		ignore_probe_fail; |  | ||||||
|  	struct brcmfmac_pd_cc *country_codes; |  | ||||||
|  	union { |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| @@ -230,6 +230,37 @@ static void brcmf_netdev_set_multicast_l |  | ||||||
|  	schedule_work(&ifp->multicast_work); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +/** |  | ||||||
| + * brcmf_skb_is_iapp - checks if skb is an IAPP packet |  | ||||||
| + * |  | ||||||
| + * @skb: skb to check |  | ||||||
| + */ |  | ||||||
| +static bool brcmf_skb_is_iapp(struct sk_buff *skb) |  | ||||||
| +{ |  | ||||||
| +	static const u8 iapp_l2_update_packet[6] __aligned(2) = { |  | ||||||
| +		0x00, 0x01, 0xaf, 0x81, 0x01, 0x00, |  | ||||||
| +	}; |  | ||||||
| +	unsigned char *eth_data; |  | ||||||
| +#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) |  | ||||||
| +	const u16 *a, *b; |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
| +	if (skb->len - skb->mac_len != 6 || |  | ||||||
| +	    !is_multicast_ether_addr(eth_hdr(skb)->h_dest)) |  | ||||||
| +		return false; |  | ||||||
| + |  | ||||||
| +	eth_data = skb_mac_header(skb) + ETH_HLEN; |  | ||||||
| +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) |  | ||||||
| +	return !(((*(const u32 *)eth_data) ^ (*(const u32 *)iapp_l2_update_packet)) | |  | ||||||
| +		 ((*(const u16 *)(eth_data + 4)) ^ (*(const u16 *)(iapp_l2_update_packet + 4)))); |  | ||||||
| +#else |  | ||||||
| +	a = (const u16 *)eth_data; |  | ||||||
| +	b = (const u16 *)iapp_l2_update_packet; |  | ||||||
| + |  | ||||||
| +	return !((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])); |  | ||||||
| +#endif |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, |  | ||||||
|  					   struct net_device *ndev) |  | ||||||
|  { |  | ||||||
| @@ -250,6 +281,23 @@ static netdev_tx_t brcmf_netdev_start_xm |  | ||||||
|  		goto done; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	/* Some recent Broadcom's firmwares disassociate STA when they receive |  | ||||||
| +	 * an 802.11f ADD frame. This behavior can lead to a local DoS security |  | ||||||
| +	 * issue. Attacker may trigger disassociation of any STA by sending a |  | ||||||
| +	 * proper Ethernet frame to the wireless interface. |  | ||||||
| +	 * |  | ||||||
| +	 * Moreover this feature may break AP interfaces in some specific |  | ||||||
| +	 * setups. This applies e.g. to the bridge with hairpin mode enabled and |  | ||||||
| +	 * IFLA_BRPORT_MCAST_TO_UCAST set. IAPP packet generated by a firmware |  | ||||||
| +	 * will get passed back to the wireless interface and cause immediate |  | ||||||
| +	 * disassociation of a just-connected STA. |  | ||||||
| +	 */ |  | ||||||
| +	if (!drvr->settings->iapp && brcmf_skb_is_iapp(skb)) { |  | ||||||
| +		dev_kfree_skb(skb); |  | ||||||
| +		ret = -EINVAL; |  | ||||||
| +		goto done; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	/* Make sure there's enough writeable headroom */ |  | ||||||
|  	if (skb_headroom(skb) < drvr->hdrlen || skb_header_cloned(skb)) { |  | ||||||
|  		head_delta = max_t(int, drvr->hdrlen - skb_headroom(skb), 0); |  | ||||||
| @@ -325,6 +373,15 @@ void brcmf_txflowblock_if(struct brcmf_i |  | ||||||
|   |  | ||||||
|  void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) |  | ||||||
|  { |  | ||||||
| +	/* Most of Broadcom's firmwares send 802.11f ADD frame every time a new |  | ||||||
| +	 * STA connects to the AP interface. This is an obsoleted standard most |  | ||||||
| +	 * users don't use, so don't pass these frames up unless requested. |  | ||||||
| +	 */ |  | ||||||
| +	if (!ifp->drvr->settings->iapp && brcmf_skb_is_iapp(skb)) { |  | ||||||
| +		brcmu_pkt_buf_free_skb(skb); |  | ||||||
| +		return; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	if (skb->pkt_type == PACKET_MULTICAST) |  | ||||||
|  		ifp->ndev->stats.multicast++; |  | ||||||
|   |  | ||||||
| @@ -1,29 +0,0 @@ | |||||||
| From 9b9322db5c5a1917a66c71fe47c3848a9a31227e Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Stefan Wahren <stefan.wahren@i2se.com> |  | ||||||
| Date: Wed, 14 Mar 2018 20:02:59 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: Fix check for ISO3166 code |  | ||||||
|  |  | ||||||
| The commit "regulatory: add NUL to request alpha2" increases the length of |  | ||||||
| alpha2 to 3. This causes a regression on brcmfmac, because |  | ||||||
| brcmf_cfg80211_reg_notifier() expect valid ISO3166 codes in the complete |  | ||||||
| array. So fix this accordingly. |  | ||||||
|  |  | ||||||
| Fixes: 657308f73e67 ("regulatory: add NUL to request alpha2") |  | ||||||
| Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com> |  | ||||||
| Acked-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +- |  | ||||||
|  1 file changed, 1 insertion(+), 1 deletion(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| @@ -6803,7 +6803,7 @@ static void brcmf_cfg80211_reg_notifier( |  | ||||||
|  		return; |  | ||||||
|   |  | ||||||
|  	/* ignore non-ISO3166 country codes */ |  | ||||||
| -	for (i = 0; i < sizeof(req->alpha2); i++) |  | ||||||
| +	for (i = 0; i < 2; i++) |  | ||||||
|  		if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') { |  | ||||||
|  			brcmf_err("not an ISO3166 code (0x%02x 0x%02x)\n", |  | ||||||
|  				  req->alpha2[0], req->alpha2[1]); |  | ||||||
| @@ -1,45 +0,0 @@ | |||||||
| From da472385a29f1fddcac7cfa0499482704310bd16 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Tue, 20 Feb 2018 00:14:18 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: move brcmf_bus_preinit() call just after changing |  | ||||||
|  bus state |  | ||||||
|  |  | ||||||
| Moving the brcmf_bus_preinit() call allows the bus code to do some |  | ||||||
| required initialization before handling firmware control messages. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 3 --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c   | 5 +++++ |  | ||||||
|  2 files changed, 5 insertions(+), 3 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| @@ -369,9 +369,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_i |  | ||||||
|   |  | ||||||
|  	/* Enable tx beamforming, errors can be ignored (not supported) */ |  | ||||||
|  	(void)brcmf_fil_iovar_int_set(ifp, "txbf", 1); |  | ||||||
| - |  | ||||||
| -	/* do bus specific preinit here */ |  | ||||||
| -	err = brcmf_bus_preinit(ifp->drvr->bus_if); |  | ||||||
|  done: |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| @@ -1091,6 +1091,11 @@ int brcmf_bus_started(struct device *dev |  | ||||||
|  	/* signal bus ready */ |  | ||||||
|  	brcmf_bus_change_state(bus_if, BRCMF_BUS_UP); |  | ||||||
|   |  | ||||||
| +	/* do bus specific preinit here */ |  | ||||||
| +	ret = brcmf_bus_preinit(ifp->drvr->bus_if); |  | ||||||
| +	if (ret < 0) |  | ||||||
| +		goto fail; |  | ||||||
| + |  | ||||||
|  	/* Bus is ready, do any initialization */ |  | ||||||
|  	ret = brcmf_c_preinit_dcmds(ifp); |  | ||||||
|  	if (ret < 0) |  | ||||||
| @@ -1,69 +0,0 @@ | |||||||
| From 4b5adc736828dc25ca33e263ad8c0b9dcd3bf325 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Tue, 20 Feb 2018 00:14:19 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: move allocation of control rx buffer to |  | ||||||
|  brcmf_sdio_bus_preinit() |  | ||||||
|  |  | ||||||
| Allocate the control rx buffer needed for firmware control interface |  | ||||||
| during brcmf_sdio_bus_preinit(). This relies on common layer setting |  | ||||||
| struct brcmf_bus::maxctl during brcmf_attach(). By moving the allocation |  | ||||||
| we can move brcmf_attach() in subsequent change. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 26 ++++++++++------------ |  | ||||||
|  1 file changed, 12 insertions(+), 14 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -1707,7 +1707,6 @@ brcmf_sdio_read_control(struct brcmf_sdi |  | ||||||
|  	int sdret; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
| - |  | ||||||
|  	if (bus->rxblen) |  | ||||||
|  		buf = vzalloc(bus->rxblen); |  | ||||||
|  	if (!buf) |  | ||||||
| @@ -3411,6 +3410,18 @@ static int brcmf_sdio_bus_preinit(struct |  | ||||||
|  	u32 value; |  | ||||||
|  	int err; |  | ||||||
|   |  | ||||||
| +	/* maxctl provided by common layer */ |  | ||||||
| +	if (WARN_ON(!bus_if->maxctl)) |  | ||||||
| +		return -EINVAL; |  | ||||||
| + |  | ||||||
| +	/* Allocate control receive buffer */ |  | ||||||
| +	bus_if->maxctl += bus->roundup; |  | ||||||
| +	value = roundup((bus_if->maxctl + SDPCM_HDRLEN), ALIGNMENT); |  | ||||||
| +	value += bus->head_align; |  | ||||||
| +	bus->rxbuf = kmalloc(value, GFP_ATOMIC); |  | ||||||
| +	if (bus->rxbuf) |  | ||||||
| +		bus->rxblen = value; |  | ||||||
| + |  | ||||||
|  	/* the commands below use the terms tx and rx from |  | ||||||
|  	 * a device perspective, ie. bus:txglom affects the |  | ||||||
|  	 * bus transfers from device to host. |  | ||||||
| @@ -4209,19 +4220,6 @@ struct brcmf_sdio *brcmf_sdio_probe(stru |  | ||||||
|  	bus->blocksize = bus->sdiodev->func2->cur_blksize; |  | ||||||
|  	bus->roundup = min(max_roundup, bus->blocksize); |  | ||||||
|   |  | ||||||
| -	/* Allocate buffers */ |  | ||||||
| -	if (bus->sdiodev->bus_if->maxctl) { |  | ||||||
| -		bus->sdiodev->bus_if->maxctl += bus->roundup; |  | ||||||
| -		bus->rxblen = |  | ||||||
| -		    roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN), |  | ||||||
| -			    ALIGNMENT) + bus->head_align; |  | ||||||
| -		bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); |  | ||||||
| -		if (!(bus->rxbuf)) { |  | ||||||
| -			brcmf_err("rxbuf allocation failed\n"); |  | ||||||
| -			goto fail; |  | ||||||
| -		} |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
|  	sdio_claim_host(bus->sdiodev->func1); |  | ||||||
|   |  | ||||||
|  	/* Disable F2 to clear any intermediate frame state on the dongle */ |  | ||||||
| @@ -1,106 +0,0 @@ | |||||||
| From 262f2b53f67936b59cc8dfc6f3899ab8905bf1ed Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Tue, 20 Feb 2018 00:14:20 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: call brcmf_attach() just before calling |  | ||||||
|  brcmf_bus_started() |  | ||||||
|  |  | ||||||
| Now we can move brcmf_attach() until after the firmware has been downloaded |  | ||||||
| to the device. Make the call just before brcmf_bus_started(). |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.c    |  6 ++++ |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 34 +++++++++++----------- |  | ||||||
|  2 files changed, 23 insertions(+), 17 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| @@ -1268,6 +1268,12 @@ void brcmf_bus_change_state(struct brcmf |  | ||||||
|  	int ifidx; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(TRACE, "%d -> %d\n", bus->state, state); |  | ||||||
| + |  | ||||||
| +	if (!drvr) { |  | ||||||
| +		brcmf_dbg(INFO, "ignoring transition, bus not attached yet\n"); |  | ||||||
| +		return; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	bus->state = state; |  | ||||||
|   |  | ||||||
|  	if (state == BRCMF_BUS_UP) { |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -4048,9 +4048,6 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  	if (err) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
| -	if (!bus_if->drvr) |  | ||||||
| -		return; |  | ||||||
| - |  | ||||||
|  	/* try to download image and nvram to the dongle */ |  | ||||||
|  	bus->alp_only = true; |  | ||||||
|  	err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len); |  | ||||||
| @@ -4126,11 +4123,28 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|   |  | ||||||
|  	sdio_release_host(sdiodev->func1); |  | ||||||
|   |  | ||||||
| +	/* Assign bus interface call back */ |  | ||||||
| +	sdiodev->bus_if->dev = sdiodev->dev; |  | ||||||
| +	sdiodev->bus_if->ops = &brcmf_sdio_bus_ops; |  | ||||||
| +	sdiodev->bus_if->chip = bus->ci->chip; |  | ||||||
| +	sdiodev->bus_if->chiprev = bus->ci->chiprev; |  | ||||||
| + |  | ||||||
| +	/* Attach to the common layer, reserve hdr space */ |  | ||||||
| +	err = brcmf_attach(sdiodev->dev, sdiodev->settings); |  | ||||||
| +	if (err != 0) { |  | ||||||
| +		brcmf_err("brcmf_attach failed\n"); |  | ||||||
| +		goto fail; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	brcmf_sdio_debugfs_create(bus); |  | ||||||
| + |  | ||||||
|  	err = brcmf_bus_started(dev); |  | ||||||
|  	if (err != 0) { |  | ||||||
|  		brcmf_err("dongle is not responding\n"); |  | ||||||
|  		goto fail; |  | ||||||
|  	} |  | ||||||
| + |  | ||||||
| +	/* ready */ |  | ||||||
|  	return; |  | ||||||
|   |  | ||||||
|  release: |  | ||||||
| @@ -4200,22 +4214,9 @@ struct brcmf_sdio *brcmf_sdio_probe(stru |  | ||||||
|  	bus->dpc_triggered = false; |  | ||||||
|  	bus->dpc_running = false; |  | ||||||
|   |  | ||||||
| -	/* Assign bus interface call back */ |  | ||||||
| -	bus->sdiodev->bus_if->dev = bus->sdiodev->dev; |  | ||||||
| -	bus->sdiodev->bus_if->ops = &brcmf_sdio_bus_ops; |  | ||||||
| -	bus->sdiodev->bus_if->chip = bus->ci->chip; |  | ||||||
| -	bus->sdiodev->bus_if->chiprev = bus->ci->chiprev; |  | ||||||
| - |  | ||||||
|  	/* default sdio bus header length for tx packet */ |  | ||||||
|  	bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN; |  | ||||||
|   |  | ||||||
| -	/* Attach to the common layer, reserve hdr space */ |  | ||||||
| -	ret = brcmf_attach(bus->sdiodev->dev, bus->sdiodev->settings); |  | ||||||
| -	if (ret != 0) { |  | ||||||
| -		brcmf_err("brcmf_attach failed\n"); |  | ||||||
| -		goto fail; |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
|  	/* Query the F2 block size, set roundup accordingly */ |  | ||||||
|  	bus->blocksize = bus->sdiodev->func2->cur_blksize; |  | ||||||
|  	bus->roundup = min(max_roundup, bus->blocksize); |  | ||||||
| @@ -4240,7 +4241,6 @@ struct brcmf_sdio *brcmf_sdio_probe(stru |  | ||||||
|  	/* SR state */ |  | ||||||
|  	bus->sr_enabled = false; |  | ||||||
|   |  | ||||||
| -	brcmf_sdio_debugfs_create(bus); |  | ||||||
|  	brcmf_dbg(INFO, "completed!!\n"); |  | ||||||
|   |  | ||||||
|  	ret = brcmf_fw_map_chip_to_name(bus->ci->chip, bus->ci->chiprev, |  | ||||||
| @@ -1,41 +0,0 @@ | |||||||
| From a7f4a80c0070b673d4a4ce94b99979ea6d0c6296 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Tue, 20 Feb 2018 00:14:21 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: usb: call brcmf_usb_up() during brcmf_bus_preinit() |  | ||||||
|  |  | ||||||
| By calling brcmf_usb_up() during brcmf_bus_preinit() it does not need |  | ||||||
| to be called in brcmf_usb_bus_setup(). |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 7 ++----- |  | ||||||
|  1 file changed, 2 insertions(+), 5 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| @@ -1146,8 +1146,9 @@ static int brcmf_usb_get_fwname(struct d |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static const struct brcmf_bus_ops brcmf_usb_bus_ops = { |  | ||||||
| -	.txdata = brcmf_usb_tx, |  | ||||||
| +	.preinit = brcmf_usb_up, |  | ||||||
|  	.stop = brcmf_usb_down, |  | ||||||
| +	.txdata = brcmf_usb_tx, |  | ||||||
|  	.txctl = brcmf_usb_tx_ctlpkt, |  | ||||||
|  	.rxctl = brcmf_usb_rx_ctlpkt, |  | ||||||
|  	.wowl_config = brcmf_usb_wowl_config, |  | ||||||
| @@ -1165,10 +1166,6 @@ static int brcmf_usb_bus_setup(struct br |  | ||||||
|  		return ret; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	ret = brcmf_usb_up(devinfo->dev); |  | ||||||
| -	if (ret) |  | ||||||
| -		goto fail; |  | ||||||
| - |  | ||||||
|  	ret = brcmf_bus_started(devinfo->dev); |  | ||||||
|  	if (ret) |  | ||||||
|  		goto fail; |  | ||||||
| @@ -1,130 +0,0 @@ | |||||||
| From 0542503c4c164c65cd1567b0f2b3f887af6c81eb Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Tue, 20 Feb 2018 00:14:22 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: move brcmf_attach() function in core.c |  | ||||||
|  |  | ||||||
| Moving the function in preparation of subsequent patch. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.c    | 98 +++++++++++----------- |  | ||||||
|  1 file changed, 49 insertions(+), 49 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| @@ -992,55 +992,6 @@ static int brcmf_inet6addr_changed(struc |  | ||||||
|  } |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| -int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) |  | ||||||
| -{ |  | ||||||
| -	struct brcmf_pub *drvr = NULL; |  | ||||||
| -	int ret = 0; |  | ||||||
| -	int i; |  | ||||||
| - |  | ||||||
| -	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
| - |  | ||||||
| -	/* Allocate primary brcmf_info */ |  | ||||||
| -	drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC); |  | ||||||
| -	if (!drvr) |  | ||||||
| -		return -ENOMEM; |  | ||||||
| - |  | ||||||
| -	for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) |  | ||||||
| -		drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; |  | ||||||
| - |  | ||||||
| -	mutex_init(&drvr->proto_block); |  | ||||||
| - |  | ||||||
| -	/* Link to bus module */ |  | ||||||
| -	drvr->hdrlen = 0; |  | ||||||
| -	drvr->bus_if = dev_get_drvdata(dev); |  | ||||||
| -	drvr->bus_if->drvr = drvr; |  | ||||||
| -	drvr->settings = settings; |  | ||||||
| - |  | ||||||
| -	/* attach debug facilities */ |  | ||||||
| -	brcmf_debug_attach(drvr); |  | ||||||
| - |  | ||||||
| -	/* Attach and link in the protocol */ |  | ||||||
| -	ret = brcmf_proto_attach(drvr); |  | ||||||
| -	if (ret != 0) { |  | ||||||
| -		brcmf_err("brcmf_prot_attach failed\n"); |  | ||||||
| -		goto fail; |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
| -	/* Attach to events important for core code */ |  | ||||||
| -	brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG, |  | ||||||
| -			    brcmf_psm_watchdog_notify); |  | ||||||
| - |  | ||||||
| -	/* attach firmware event handler */ |  | ||||||
| -	brcmf_fweh_attach(drvr); |  | ||||||
| - |  | ||||||
| -	return ret; |  | ||||||
| - |  | ||||||
| -fail: |  | ||||||
| -	brcmf_detach(dev); |  | ||||||
| - |  | ||||||
| -	return ret; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
|  static int brcmf_revinfo_read(struct seq_file *s, void *data) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_bus *bus_if = dev_get_drvdata(s->private); |  | ||||||
| @@ -1170,6 +1121,55 @@ fail: |  | ||||||
|   |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
| + |  | ||||||
| +int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) |  | ||||||
| +{ |  | ||||||
| +	struct brcmf_pub *drvr = NULL; |  | ||||||
| +	int ret = 0; |  | ||||||
| +	int i; |  | ||||||
| + |  | ||||||
| +	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
| + |  | ||||||
| +	/* Allocate primary brcmf_info */ |  | ||||||
| +	drvr = kzalloc(sizeof(*drvr), GFP_ATOMIC); |  | ||||||
| +	if (!drvr) |  | ||||||
| +		return -ENOMEM; |  | ||||||
| + |  | ||||||
| +	for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) |  | ||||||
| +		drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; |  | ||||||
| + |  | ||||||
| +	mutex_init(&drvr->proto_block); |  | ||||||
| + |  | ||||||
| +	/* Link to bus module */ |  | ||||||
| +	drvr->hdrlen = 0; |  | ||||||
| +	drvr->bus_if = dev_get_drvdata(dev); |  | ||||||
| +	drvr->bus_if->drvr = drvr; |  | ||||||
| +	drvr->settings = settings; |  | ||||||
| + |  | ||||||
| +	/* attach debug facilities */ |  | ||||||
| +	brcmf_debug_attach(drvr); |  | ||||||
| + |  | ||||||
| +	/* Attach and link in the protocol */ |  | ||||||
| +	ret = brcmf_proto_attach(drvr); |  | ||||||
| +	if (ret != 0) { |  | ||||||
| +		brcmf_err("brcmf_prot_attach failed\n"); |  | ||||||
| +		goto fail; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	/* Attach to events important for core code */ |  | ||||||
| +	brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG, |  | ||||||
| +			    brcmf_psm_watchdog_notify); |  | ||||||
| + |  | ||||||
| +	/* attach firmware event handler */ |  | ||||||
| +	brcmf_fweh_attach(drvr); |  | ||||||
| + |  | ||||||
| +	return ret; |  | ||||||
| + |  | ||||||
| +fail: |  | ||||||
| +	brcmf_detach(dev); |  | ||||||
| + |  | ||||||
| +	return ret; |  | ||||||
| +} |  | ||||||
|   |  | ||||||
|  void brcmf_bus_add_txhdrlen(struct device *dev, uint len) |  | ||||||
|  { |  | ||||||
| @@ -1,190 +0,0 @@ | |||||||
| From de2a3027f6f15e2f6558dc4d178282ccc1f054db Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Tue, 20 Feb 2018 00:14:23 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: remove brcmf_bus_started() from bus api |  | ||||||
|  |  | ||||||
| No longer needed to call this in bus layer so make it static and call |  | ||||||
| it in the last phase of brcmf_attach() instead. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  1 - |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.c    | 14 +++++++---- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/pcie.c    | 20 +--------------- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 10 ++------ |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 28 ++++------------------ |  | ||||||
|  5 files changed, 16 insertions(+), 57 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  | ||||||
| @@ -253,7 +253,6 @@ void brcmf_dev_reset(struct device *dev) |  | ||||||
|  /* Configure the "global" bus state used by upper layers */ |  | ||||||
|  void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state); |  | ||||||
|   |  | ||||||
| -int brcmf_bus_started(struct device *dev); |  | ||||||
|  s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len); |  | ||||||
|  void brcmf_bus_add_txhdrlen(struct device *dev, uint len); |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| @@ -1022,11 +1022,10 @@ static int brcmf_revinfo_read(struct seq |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -int brcmf_bus_started(struct device *dev) |  | ||||||
| +static int brcmf_bus_started(struct brcmf_pub *drvr) |  | ||||||
|  { |  | ||||||
|  	int ret = -1; |  | ||||||
| -	struct brcmf_bus *bus_if = dev_get_drvdata(dev); |  | ||||||
| -	struct brcmf_pub *drvr = bus_if->drvr; |  | ||||||
| +	struct brcmf_bus *bus_if = drvr->bus_if; |  | ||||||
|  	struct brcmf_if *ifp; |  | ||||||
|  	struct brcmf_if *p2p_ifp; |  | ||||||
|   |  | ||||||
| @@ -1043,7 +1042,7 @@ int brcmf_bus_started(struct device *dev |  | ||||||
|  	brcmf_bus_change_state(bus_if, BRCMF_BUS_UP); |  | ||||||
|   |  | ||||||
|  	/* do bus specific preinit here */ |  | ||||||
| -	ret = brcmf_bus_preinit(ifp->drvr->bus_if); |  | ||||||
| +	ret = brcmf_bus_preinit(bus_if); |  | ||||||
|  	if (ret < 0) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
| @@ -1163,7 +1162,12 @@ int brcmf_attach(struct device *dev, str |  | ||||||
|  	/* attach firmware event handler */ |  | ||||||
|  	brcmf_fweh_attach(drvr); |  | ||||||
|   |  | ||||||
| -	return ret; |  | ||||||
| +	ret = brcmf_bus_started(drvr); |  | ||||||
| +	if (ret != 0) { |  | ||||||
| +		brcmf_err("dongle is not responding: err=%d\n", ret); |  | ||||||
| +		goto fail; |  | ||||||
| +	} |  | ||||||
| +	return 0; |  | ||||||
|   |  | ||||||
|  fail: |  | ||||||
|  	brcmf_detach(dev); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| @@ -1581,24 +1581,6 @@ static void brcmf_pcie_release_resource( |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| -static int brcmf_pcie_attach_bus(struct brcmf_pciedev_info *devinfo) |  | ||||||
| -{ |  | ||||||
| -	int ret; |  | ||||||
| - |  | ||||||
| -	/* Attach to the common driver interface */ |  | ||||||
| -	ret = brcmf_attach(&devinfo->pdev->dev, devinfo->settings); |  | ||||||
| -	if (ret) { |  | ||||||
| -		brcmf_err("brcmf_attach failed\n"); |  | ||||||
| -	} else { |  | ||||||
| -		ret = brcmf_bus_started(&devinfo->pdev->dev); |  | ||||||
| -		if (ret) |  | ||||||
| -			brcmf_err("dongle is not responding\n"); |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
| -	return ret; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
| - |  | ||||||
|  static u32 brcmf_pcie_buscore_prep_addr(const struct pci_dev *pdev, u32 addr) |  | ||||||
|  { |  | ||||||
|  	u32 ret_addr; |  | ||||||
| @@ -1735,7 +1717,7 @@ static void brcmf_pcie_setup(struct devi |  | ||||||
|  	init_waitqueue_head(&devinfo->mbdata_resp_wait); |  | ||||||
|   |  | ||||||
|  	brcmf_pcie_intr_enable(devinfo); |  | ||||||
| -	if (brcmf_pcie_attach_bus(devinfo) == 0) |  | ||||||
| +	if (brcmf_attach(&devinfo->pdev->dev, devinfo->settings) == 0) |  | ||||||
|  		return; |  | ||||||
|   |  | ||||||
|  	brcmf_pcie_bus_console_read(devinfo); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -3422,6 +3422,8 @@ static int brcmf_sdio_bus_preinit(struct |  | ||||||
|  	if (bus->rxbuf) |  | ||||||
|  		bus->rxblen = value; |  | ||||||
|   |  | ||||||
| +	brcmf_sdio_debugfs_create(bus); |  | ||||||
| + |  | ||||||
|  	/* the commands below use the terms tx and rx from |  | ||||||
|  	 * a device perspective, ie. bus:txglom affects the |  | ||||||
|  	 * bus transfers from device to host. |  | ||||||
| @@ -4136,14 +4138,6 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  		goto fail; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	brcmf_sdio_debugfs_create(bus); |  | ||||||
| - |  | ||||||
| -	err = brcmf_bus_started(dev); |  | ||||||
| -	if (err != 0) { |  | ||||||
| -		brcmf_err("dongle is not responding\n"); |  | ||||||
| -		goto fail; |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
|  	/* ready */ |  | ||||||
|  	return; |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| @@ -1155,27 +1155,6 @@ static const struct brcmf_bus_ops brcmf_ |  | ||||||
|  	.get_fwname = brcmf_usb_get_fwname, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| -static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo) |  | ||||||
| -{ |  | ||||||
| -	int ret; |  | ||||||
| - |  | ||||||
| -	/* Attach to the common driver interface */ |  | ||||||
| -	ret = brcmf_attach(devinfo->dev, devinfo->settings); |  | ||||||
| -	if (ret) { |  | ||||||
| -		brcmf_err("brcmf_attach failed\n"); |  | ||||||
| -		return ret; |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
| -	ret = brcmf_bus_started(devinfo->dev); |  | ||||||
| -	if (ret) |  | ||||||
| -		goto fail; |  | ||||||
| - |  | ||||||
| -	return 0; |  | ||||||
| -fail: |  | ||||||
| -	brcmf_detach(devinfo->dev); |  | ||||||
| -	return ret; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
|  static void brcmf_usb_probe_phase2(struct device *dev, int ret, |  | ||||||
|  				   const struct firmware *fw, |  | ||||||
|  				   void *nvram, u32 nvlen) |  | ||||||
| @@ -1203,7 +1182,8 @@ static void brcmf_usb_probe_phase2(struc |  | ||||||
|  	if (ret) |  | ||||||
|  		goto error; |  | ||||||
|   |  | ||||||
| -	ret = brcmf_usb_bus_setup(devinfo); |  | ||||||
| +	/* Attach to the common driver interface */ |  | ||||||
| +	ret = brcmf_attach(devinfo->dev, devinfo->settings); |  | ||||||
|  	if (ret) |  | ||||||
|  		goto error; |  | ||||||
|   |  | ||||||
| @@ -1253,7 +1233,7 @@ static int brcmf_usb_probe_cb(struct brc |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	if (!brcmf_usb_dlneeded(devinfo)) { |  | ||||||
| -		ret = brcmf_usb_bus_setup(devinfo); |  | ||||||
| +		ret = brcmf_attach(devinfo->dev, devinfo->settings); |  | ||||||
|  		if (ret) |  | ||||||
|  			goto fail; |  | ||||||
|  		/* we are done */ |  | ||||||
| @@ -1456,7 +1436,7 @@ static int brcmf_usb_resume(struct usb_i |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(USB, "Enter\n"); |  | ||||||
|  	if (!devinfo->wowl_enabled) |  | ||||||
| -		return brcmf_usb_bus_setup(devinfo); |  | ||||||
| +		return brcmf_attach(devinfo->dev, devinfo->settings); |  | ||||||
|   |  | ||||||
|  	devinfo->bus_pub.state = BRCMFMAC_USB_STATE_UP; |  | ||||||
|  	brcmf_usb_rx_fill_all(devinfo); |  | ||||||
| @@ -1,64 +0,0 @@ | |||||||
| From d678296bfb9a630d0000222fc21f4ed0d0d65332 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Tue, 20 Feb 2018 00:14:24 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: change log level for some low-level sdio functions |  | ||||||
|  |  | ||||||
| Reducing the number of trace level messages in sdio code giving |  | ||||||
| them sdio log level instead. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 10 +++++----- |  | ||||||
|  1 file changed, 5 insertions(+), 5 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -1706,7 +1706,7 @@ brcmf_sdio_read_control(struct brcmf_sdi |  | ||||||
|  	u8 *buf = NULL, *rbuf; |  | ||||||
|  	int sdret; |  | ||||||
|   |  | ||||||
| -	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
| +	brcmf_dbg(SDIO, "Enter\n"); |  | ||||||
|  	if (bus->rxblen) |  | ||||||
|  		buf = vzalloc(bus->rxblen); |  | ||||||
|  	if (!buf) |  | ||||||
| @@ -1809,7 +1809,7 @@ static uint brcmf_sdio_readframes(struct |  | ||||||
|  	struct brcmf_sdio_hdrinfo *rd = &bus->cur_read, rd_new; |  | ||||||
|  	u8 head_read = 0; |  | ||||||
|   |  | ||||||
| -	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
| +	brcmf_dbg(SDIO, "Enter\n"); |  | ||||||
|   |  | ||||||
|  	/* Not finished unless we encounter no more frames indication */ |  | ||||||
|  	bus->rxpending = true; |  | ||||||
| @@ -2344,7 +2344,7 @@ static int brcmf_sdio_tx_ctrlframe(struc |  | ||||||
|  	struct brcmf_sdio_hdrinfo hd_info = {0}; |  | ||||||
|  	int ret; |  | ||||||
|   |  | ||||||
| -	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
| +	brcmf_dbg(SDIO, "Enter\n"); |  | ||||||
|   |  | ||||||
|  	/* Back the pointer to make room for bus header */ |  | ||||||
|  	frame -= bus->tx_hdrlen; |  | ||||||
| @@ -2520,7 +2520,7 @@ static void brcmf_sdio_dpc(struct brcmf_ |  | ||||||
|  	uint framecnt;			/* Temporary counter of tx/rx frames */ |  | ||||||
|  	int err = 0; |  | ||||||
|   |  | ||||||
| -	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
| +	brcmf_dbg(SDIO, "Enter\n"); |  | ||||||
|   |  | ||||||
|  	sdio_claim_host(bus->sdiodev->func1); |  | ||||||
|   |  | ||||||
| @@ -2605,7 +2605,7 @@ static void brcmf_sdio_dpc(struct brcmf_ |  | ||||||
|   |  | ||||||
|  	/* Would be active due to wake-wlan in gSPI */ |  | ||||||
|  	if (intstatus & I_CHIPACTIVE) { |  | ||||||
| -		brcmf_dbg(INFO, "Dongle reports CHIPACTIVE\n"); |  | ||||||
| +		brcmf_dbg(SDIO, "Dongle reports CHIPACTIVE\n"); |  | ||||||
|  		intstatus &= ~I_CHIPACTIVE; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| @@ -1,126 +0,0 @@ | |||||||
| From 2d6edad4b2da1991f74e7b02053eeb4a043b887f Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Tue, 20 Feb 2018 00:14:25 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: remove duplicate pointer variable from |  | ||||||
|  brcmf_sdio_firmware_callback() |  | ||||||
|  |  | ||||||
| In brcmf_sdio_firmware_callback() two pointer variables were used |  | ||||||
| pointing to the same construct. Get rid of sdiodev variable. |  | ||||||
|  |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 37 +++++++++++----------- |  | ||||||
|  1 file changed, 18 insertions(+), 19 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -4039,9 +4039,8 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  					 void *nvram, u32 nvram_len) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_bus *bus_if = dev_get_drvdata(dev); |  | ||||||
| -	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |  | ||||||
| -	struct brcmf_sdio *bus = sdiodev->bus; |  | ||||||
| -	struct brcmf_sdio_dev *sdiod = bus->sdiodev; |  | ||||||
| +	struct brcmf_sdio_dev *sdiod = bus_if->bus_priv.sdio; |  | ||||||
| +	struct brcmf_sdio *bus = sdiod->bus; |  | ||||||
|  	struct brcmf_core *core = bus->sdio_core; |  | ||||||
|  	u8 saveclk; |  | ||||||
|   |  | ||||||
| @@ -4061,7 +4060,7 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  	bus->sdcnt.tickcnt = 0; |  | ||||||
|  	brcmf_sdio_wd_timer(bus, true); |  | ||||||
|   |  | ||||||
| -	sdio_claim_host(sdiodev->func1); |  | ||||||
| +	sdio_claim_host(sdiod->func1); |  | ||||||
|   |  | ||||||
|  	/* Make sure backplane clock is on, needed to generate F2 interrupt */ |  | ||||||
|  	brcmf_sdio_clkctl(bus, CLK_AVAIL, false); |  | ||||||
| @@ -4069,9 +4068,9 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  		goto release; |  | ||||||
|   |  | ||||||
|  	/* Force clocks on backplane to be sure F2 interrupt propagates */ |  | ||||||
| -	saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); |  | ||||||
| +	saveclk = brcmf_sdiod_readb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR, &err); |  | ||||||
|  	if (!err) { |  | ||||||
| -		brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| +		brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
|  				   (saveclk | SBSDIO_FORCE_HT), &err); |  | ||||||
|  	} |  | ||||||
|  	if (err) { |  | ||||||
| @@ -4083,7 +4082,7 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  	brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailboxdata), |  | ||||||
|  			   SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, NULL); |  | ||||||
|   |  | ||||||
| -	err = sdio_enable_func(sdiodev->func2); |  | ||||||
| +	err = sdio_enable_func(sdiod->func2); |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(INFO, "enable F2: err=%d\n", err); |  | ||||||
|   |  | ||||||
| @@ -4095,10 +4094,10 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  				   bus->hostintmask, NULL); |  | ||||||
|   |  | ||||||
|   |  | ||||||
| -		brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err); |  | ||||||
| +		brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK, 8, &err); |  | ||||||
|  	} else { |  | ||||||
|  		/* Disable F2 again */ |  | ||||||
| -		sdio_disable_func(sdiodev->func2); |  | ||||||
| +		sdio_disable_func(sdiod->func2); |  | ||||||
|  		goto release; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| @@ -4106,7 +4105,7 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  		brcmf_sdio_sr_init(bus); |  | ||||||
|  	} else { |  | ||||||
|  		/* Restore previous clock setting */ |  | ||||||
| -		brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
| +		brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR, |  | ||||||
|  				   saveclk, &err); |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| @@ -4114,7 +4113,7 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  		/* Allow full data communication using DPC from now on. */ |  | ||||||
|  		brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA); |  | ||||||
|   |  | ||||||
| -		err = brcmf_sdiod_intr_register(sdiodev); |  | ||||||
| +		err = brcmf_sdiod_intr_register(sdiod); |  | ||||||
|  		if (err != 0) |  | ||||||
|  			brcmf_err("intr register failed:%d\n", err); |  | ||||||
|  	} |  | ||||||
| @@ -4123,16 +4122,16 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  	if (err != 0) |  | ||||||
|  		brcmf_sdio_clkctl(bus, CLK_NONE, false); |  | ||||||
|   |  | ||||||
| -	sdio_release_host(sdiodev->func1); |  | ||||||
| +	sdio_release_host(sdiod->func1); |  | ||||||
|   |  | ||||||
|  	/* Assign bus interface call back */ |  | ||||||
| -	sdiodev->bus_if->dev = sdiodev->dev; |  | ||||||
| -	sdiodev->bus_if->ops = &brcmf_sdio_bus_ops; |  | ||||||
| -	sdiodev->bus_if->chip = bus->ci->chip; |  | ||||||
| -	sdiodev->bus_if->chiprev = bus->ci->chiprev; |  | ||||||
| +	sdiod->bus_if->dev = sdiod->dev; |  | ||||||
| +	sdiod->bus_if->ops = &brcmf_sdio_bus_ops; |  | ||||||
| +	sdiod->bus_if->chip = bus->ci->chip; |  | ||||||
| +	sdiod->bus_if->chiprev = bus->ci->chiprev; |  | ||||||
|   |  | ||||||
|  	/* Attach to the common layer, reserve hdr space */ |  | ||||||
| -	err = brcmf_attach(sdiodev->dev, sdiodev->settings); |  | ||||||
| +	err = brcmf_attach(sdiod->dev, sdiod->settings); |  | ||||||
|  	if (err != 0) { |  | ||||||
|  		brcmf_err("brcmf_attach failed\n"); |  | ||||||
|  		goto fail; |  | ||||||
| @@ -4142,10 +4141,10 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  	return; |  | ||||||
|   |  | ||||||
|  release: |  | ||||||
| -	sdio_release_host(sdiodev->func1); |  | ||||||
| +	sdio_release_host(sdiod->func1); |  | ||||||
|  fail: |  | ||||||
|  	brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err); |  | ||||||
| -	device_release_driver(&sdiodev->func2->dev); |  | ||||||
| +	device_release_driver(&sdiod->func2->dev); |  | ||||||
|  	device_release_driver(dev); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| From 64d1519edc959f5b8f86a66a51c40971c215e4ec Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| Date: Mon, 19 Feb 2018 13:30:45 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: reject too long PSK |  | ||||||
|  |  | ||||||
| nl80211 already allows specifying 48 bytes, but brcmfmac |  | ||||||
| only supports 32. Reject keys that are too long. |  | ||||||
|  |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 +++ |  | ||||||
|  1 file changed, 3 insertions(+) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| @@ -5125,6 +5125,9 @@ static int brcmf_cfg80211_set_pmk(struct |  | ||||||
|  	if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X)) |  | ||||||
|  		return -EINVAL; |  | ||||||
|   |  | ||||||
| +	if (conf->pmk_len > BRCMF_WSEC_MAX_PSK_LEN) |  | ||||||
| +		return -ERANGE; |  | ||||||
| + |  | ||||||
|  	return brcmf_set_pmk(ifp, conf->pmk, conf->pmk_len); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| From 1170f6d1be6a39e1a115a2c0f50923eb4ce2a7ec Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 22 Mar 2018 21:28:20 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: do not convert linux error to firmware error string |  | ||||||
|  |  | ||||||
| In case of a linux error brcmf_fil_cmd_data() blurts an error message |  | ||||||
| in which the error code is translated to an error string. However, it |  | ||||||
| maps it to a firmware error string which should not happen. Simply |  | ||||||
| print only the numeric error code and be done with it. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c | 3 +-- |  | ||||||
|  1 file changed, 1 insertion(+), 2 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c |  | ||||||
| @@ -124,8 +124,7 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, |  | ||||||
|  					     data, len, &fwerr); |  | ||||||
|   |  | ||||||
|  	if (err) { |  | ||||||
| -		brcmf_dbg(FIL, "Failed: %s (%d)\n", |  | ||||||
| -			  brcmf_fil_get_errstr((u32)(-err)), err); |  | ||||||
| +		brcmf_dbg(FIL, "Failed: error=%d\n", err); |  | ||||||
|  	} else if (fwerr < 0) { |  | ||||||
|  		brcmf_dbg(FIL, "Firmware error: %s (%d)\n", |  | ||||||
|  			  brcmf_fil_get_errstr((u32)(-fwerr)), fwerr); |  | ||||||
| @@ -1,203 +0,0 @@ | |||||||
| From 756a2b390874d274f2f615921318ef0856ff9313 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 22 Mar 2018 21:28:21 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: use brcmf_chip_name() to store name in revinfo |  | ||||||
|  |  | ||||||
| The chip id can either be four or five digits. For the chip name either |  | ||||||
| the hexadecimal value needs to be taken (four digits) or the decimal |  | ||||||
| value (five digits). The function brcmf_chip_name() does this conversion |  | ||||||
| so use it to store the name in driver revision info. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/chip.c    |  9 +++++---- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/chip.h    |  3 ++- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/common.c  | 23 ++++++++++++++++------ |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.c    | 10 +--------- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.h    |  3 +-- |  | ||||||
|  5 files changed, 26 insertions(+), 22 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c |  | ||||||
| @@ -464,12 +464,12 @@ static void brcmf_chip_ai_resetcore(stru |  | ||||||
|  	ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static char *brcmf_chip_name(uint chipid, char *buf, uint len) |  | ||||||
| +char *brcmf_chip_name(u32 id, u32 rev, char *buf, uint len) |  | ||||||
|  { |  | ||||||
|  	const char *fmt; |  | ||||||
|   |  | ||||||
| -	fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x"; |  | ||||||
| -	snprintf(buf, len, fmt, chipid); |  | ||||||
| +	fmt = ((id > 0xa000) || (id < 0x4000)) ? "BCM%d/%u" : "BCM%x/%u"; |  | ||||||
| +	snprintf(buf, len, fmt, id, rev); |  | ||||||
|  	return buf; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -924,7 +924,8 @@ static int brcmf_chip_recognition(struct |  | ||||||
|  	ci->pub.chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; |  | ||||||
|  	socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT; |  | ||||||
|   |  | ||||||
| -	brcmf_chip_name(ci->pub.chip, ci->pub.name, sizeof(ci->pub.name)); |  | ||||||
| +	brcmf_chip_name(ci->pub.chip, ci->pub.chiprev, |  | ||||||
| +			ci->pub.name, sizeof(ci->pub.name)); |  | ||||||
|  	brcmf_dbg(INFO, "found %s chip: BCM%s, rev=%d\n", |  | ||||||
|  		  socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name, |  | ||||||
|  		  ci->pub.chiprev); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h |  | ||||||
| @@ -45,7 +45,7 @@ struct brcmf_chip { |  | ||||||
|  	u32 rambase; |  | ||||||
|  	u32 ramsize; |  | ||||||
|  	u32 srsize; |  | ||||||
| -	char name[8]; |  | ||||||
| +	char name[12]; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
| @@ -93,5 +93,6 @@ void brcmf_chip_resetcore(struct brcmf_c |  | ||||||
|  void brcmf_chip_set_passive(struct brcmf_chip *ci); |  | ||||||
|  bool brcmf_chip_set_active(struct brcmf_chip *ci, u32 rstvec); |  | ||||||
|  bool brcmf_chip_sr_capable(struct brcmf_chip *pub); |  | ||||||
| +char *brcmf_chip_name(u32 chipid, u32 chiprev, char *buf, uint len); |  | ||||||
|   |  | ||||||
|  #endif /* BRCMF_AXIDMP_H */ |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| @@ -30,6 +30,7 @@ |  | ||||||
|  #include "common.h" |  | ||||||
|  #include "of.h" |  | ||||||
|  #include "firmware.h" |  | ||||||
| +#include "chip.h" |  | ||||||
|   |  | ||||||
|  MODULE_AUTHOR("Broadcom Corporation"); |  | ||||||
|  MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); |  | ||||||
| @@ -131,14 +132,13 @@ static int brcmf_c_download(struct brcmf |  | ||||||
|  static int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_bus *bus = ifp->drvr->bus_if; |  | ||||||
| -	struct brcmf_rev_info *ri = &ifp->drvr->revinfo; |  | ||||||
|  	u8 fw_name[BRCMF_FW_NAME_LEN]; |  | ||||||
|  	u8 *ptr; |  | ||||||
|  	size_t len; |  | ||||||
|  	s32 err; |  | ||||||
|   |  | ||||||
|  	memset(fw_name, 0, BRCMF_FW_NAME_LEN); |  | ||||||
| -	err = brcmf_bus_get_fwname(bus, ri->chipnum, ri->chiprev, fw_name); |  | ||||||
| +	err = brcmf_bus_get_fwname(bus, bus->chip, bus->chiprev, fw_name); |  | ||||||
|  	if (err) { |  | ||||||
|  		brcmf_err("get firmware name failed (%d)\n", err); |  | ||||||
|  		goto done; |  | ||||||
| @@ -238,6 +238,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i |  | ||||||
|  { |  | ||||||
|  	s8 eventmask[BRCMF_EVENTING_MASK_LEN]; |  | ||||||
|  	u8 buf[BRCMF_DCMD_SMLEN]; |  | ||||||
| +	struct brcmf_bus *bus; |  | ||||||
|  	struct brcmf_rev_info_le revinfo; |  | ||||||
|  	struct brcmf_rev_info *ri; |  | ||||||
|  	char *clmver; |  | ||||||
| @@ -253,16 +254,18 @@ int brcmf_c_preinit_dcmds(struct brcmf_i |  | ||||||
|  	} |  | ||||||
|  	memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac)); |  | ||||||
|   |  | ||||||
| +	bus = ifp->drvr->bus_if; |  | ||||||
| +	ri = &ifp->drvr->revinfo; |  | ||||||
| + |  | ||||||
|  	err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_REVINFO, |  | ||||||
|  				     &revinfo, sizeof(revinfo)); |  | ||||||
| -	ri = &ifp->drvr->revinfo; |  | ||||||
|  	if (err < 0) { |  | ||||||
|  		brcmf_err("retrieving revision info failed, %d\n", err); |  | ||||||
| +		strlcpy(ri->chipname, "UNKNOWN", sizeof(ri->chipname)); |  | ||||||
|  	} else { |  | ||||||
|  		ri->vendorid = le32_to_cpu(revinfo.vendorid); |  | ||||||
|  		ri->deviceid = le32_to_cpu(revinfo.deviceid); |  | ||||||
|  		ri->radiorev = le32_to_cpu(revinfo.radiorev); |  | ||||||
| -		ri->chiprev = le32_to_cpu(revinfo.chiprev); |  | ||||||
|  		ri->corerev = le32_to_cpu(revinfo.corerev); |  | ||||||
|  		ri->boardid = le32_to_cpu(revinfo.boardid); |  | ||||||
|  		ri->boardvendor = le32_to_cpu(revinfo.boardvendor); |  | ||||||
| @@ -270,15 +273,23 @@ int brcmf_c_preinit_dcmds(struct brcmf_i |  | ||||||
|  		ri->driverrev = le32_to_cpu(revinfo.driverrev); |  | ||||||
|  		ri->ucoderev = le32_to_cpu(revinfo.ucoderev); |  | ||||||
|  		ri->bus = le32_to_cpu(revinfo.bus); |  | ||||||
| -		ri->chipnum = le32_to_cpu(revinfo.chipnum); |  | ||||||
|  		ri->phytype = le32_to_cpu(revinfo.phytype); |  | ||||||
|  		ri->phyrev = le32_to_cpu(revinfo.phyrev); |  | ||||||
|  		ri->anarev = le32_to_cpu(revinfo.anarev); |  | ||||||
|  		ri->chippkg = le32_to_cpu(revinfo.chippkg); |  | ||||||
|  		ri->nvramrev = le32_to_cpu(revinfo.nvramrev); |  | ||||||
| + |  | ||||||
| +		if (!bus->chip) { |  | ||||||
| +			bus->chip = le32_to_cpu(revinfo.chipnum); |  | ||||||
| +			bus->chiprev = le32_to_cpu(revinfo.chiprev); |  | ||||||
| +		} |  | ||||||
|  	} |  | ||||||
|  	ri->result = err; |  | ||||||
|   |  | ||||||
| +	if (bus->chip) |  | ||||||
| +		brcmf_chip_name(bus->chip, bus->chiprev, |  | ||||||
| +				ri->chipname, sizeof(ri->chipname)); |  | ||||||
| + |  | ||||||
|  	/* Do any CLM downloading */ |  | ||||||
|  	err = brcmf_c_process_clm_blob(ifp); |  | ||||||
|  	if (err < 0) { |  | ||||||
| @@ -299,7 +310,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i |  | ||||||
|  	strsep(&ptr, "\n"); |  | ||||||
|   |  | ||||||
|  	/* Print fw version info */ |  | ||||||
| -	brcmf_info("Firmware version = %s\n", buf); |  | ||||||
| +	brcmf_info("Firmware: %s %s\n", ri->chipname, buf); |  | ||||||
|   |  | ||||||
|  	/* locate firmware version number for ethtool */ |  | ||||||
|  	ptr = strrchr(buf, ' ') + 1; |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| @@ -1002,8 +1002,7 @@ static int brcmf_revinfo_read(struct seq |  | ||||||
|  	seq_printf(s, "vendorid: 0x%04x\n", ri->vendorid); |  | ||||||
|  	seq_printf(s, "deviceid: 0x%04x\n", ri->deviceid); |  | ||||||
|  	seq_printf(s, "radiorev: %s\n", brcmu_dotrev_str(ri->radiorev, drev)); |  | ||||||
| -	seq_printf(s, "chipnum: %u (%x)\n", ri->chipnum, ri->chipnum); |  | ||||||
| -	seq_printf(s, "chiprev: %u\n", ri->chiprev); |  | ||||||
| +	seq_printf(s, "chip: %s\n", ri->chipname); |  | ||||||
|  	seq_printf(s, "chippkg: %u\n", ri->chippkg); |  | ||||||
|  	seq_printf(s, "corerev: %u\n", ri->corerev); |  | ||||||
|  	seq_printf(s, "boardid: 0x%04x\n", ri->boardid); |  | ||||||
| @@ -1053,13 +1052,6 @@ static int brcmf_bus_started(struct brcm |  | ||||||
|   |  | ||||||
|  	brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); |  | ||||||
|   |  | ||||||
| -	/* assure we have chipid before feature attach */ |  | ||||||
| -	if (!bus_if->chip) { |  | ||||||
| -		bus_if->chip = drvr->revinfo.chipnum; |  | ||||||
| -		bus_if->chiprev = drvr->revinfo.chiprev; |  | ||||||
| -		brcmf_dbg(INFO, "firmware revinfo: chip %x (%d) rev %d\n", |  | ||||||
| -			  bus_if->chip, bus_if->chip, bus_if->chiprev); |  | ||||||
| -	} |  | ||||||
|  	brcmf_feat_attach(drvr); |  | ||||||
|   |  | ||||||
|  	ret = brcmf_proto_init_done(drvr); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h |  | ||||||
| @@ -87,7 +87,6 @@ struct brcmf_rev_info { |  | ||||||
|  	u32 vendorid; |  | ||||||
|  	u32 deviceid; |  | ||||||
|  	u32 radiorev; |  | ||||||
| -	u32 chiprev; |  | ||||||
|  	u32 corerev; |  | ||||||
|  	u32 boardid; |  | ||||||
|  	u32 boardvendor; |  | ||||||
| @@ -95,7 +94,7 @@ struct brcmf_rev_info { |  | ||||||
|  	u32 driverrev; |  | ||||||
|  	u32 ucoderev; |  | ||||||
|  	u32 bus; |  | ||||||
| -	u32 chipnum; |  | ||||||
| +	char chipname[12]; |  | ||||||
|  	u32 phytype; |  | ||||||
|  	u32 phyrev; |  | ||||||
|  	u32 anarev; |  | ||||||
| @@ -1,69 +0,0 @@ | |||||||
| From c88cfa075de356ddf40c668896b2126340f19ba4 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 22 Mar 2018 21:28:22 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: use brcmf_chip_name() for consistency |  | ||||||
|  |  | ||||||
| When logging the chip id/revision information make use of |  | ||||||
| brcmf_chip_name() so it is always the same. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c     | 5 ++--- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 7 +++++-- |  | ||||||
|  2 files changed, 7 insertions(+), 5 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c |  | ||||||
| @@ -926,9 +926,8 @@ static int brcmf_chip_recognition(struct |  | ||||||
|   |  | ||||||
|  	brcmf_chip_name(ci->pub.chip, ci->pub.chiprev, |  | ||||||
|  			ci->pub.name, sizeof(ci->pub.name)); |  | ||||||
| -	brcmf_dbg(INFO, "found %s chip: BCM%s, rev=%d\n", |  | ||||||
| -		  socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name, |  | ||||||
| -		  ci->pub.chiprev); |  | ||||||
| +	brcmf_dbg(INFO, "found %s chip: %s\n", |  | ||||||
| +		  socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name); |  | ||||||
|   |  | ||||||
|  	if (socitype == SOCI_SB) { |  | ||||||
|  		if (ci->pub.chip != BRCM_CC_4329_CHIP_ID) { |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| @@ -25,6 +25,7 @@ |  | ||||||
|  #include "firmware.h" |  | ||||||
|  #include "core.h" |  | ||||||
|  #include "common.h" |  | ||||||
| +#include "chip.h" |  | ||||||
|   |  | ||||||
|  #define BRCMF_FW_MAX_NVRAM_SIZE			64000 |  | ||||||
|  #define BRCMF_FW_NVRAM_DEVPATH_LEN		19	/* devpath0=pcie/1/4/ */ |  | ||||||
| @@ -567,6 +568,7 @@ int brcmf_fw_map_chip_to_name(u32 chip, |  | ||||||
|  			      u32 table_size, char fw_name[BRCMF_FW_NAME_LEN], |  | ||||||
|  			      char nvram_name[BRCMF_FW_NAME_LEN]) |  | ||||||
|  { |  | ||||||
| +	char chipname[12]; |  | ||||||
|  	u32 i; |  | ||||||
|  	char end; |  | ||||||
|   |  | ||||||
| @@ -581,6 +583,8 @@ int brcmf_fw_map_chip_to_name(u32 chip, |  | ||||||
|  		return -ENODEV; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname)); |  | ||||||
| + |  | ||||||
|  	/* check if firmware path is provided by module parameter */ |  | ||||||
|  	if (brcmf_mp_global.firmware_path[0] != '\0') { |  | ||||||
|  		strlcpy(fw_name, brcmf_mp_global.firmware_path, |  | ||||||
| @@ -601,8 +605,7 @@ int brcmf_fw_map_chip_to_name(u32 chip, |  | ||||||
|  	if ((nvram_name) && (mapping_table[i].nvram)) |  | ||||||
|  		strlcat(nvram_name, mapping_table[i].nvram, BRCMF_FW_NAME_LEN); |  | ||||||
|   |  | ||||||
| -	brcmf_info("using %s for chip %#08x(%d) rev %#08x\n", |  | ||||||
| -		   fw_name, chip, chip, chiprev); |  | ||||||
| +	brcmf_info("using %s for chip %s\n", fw_name, chipname); |  | ||||||
|   |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
| @@ -1,452 +0,0 @@ | |||||||
| From 856d5a011c86b59f6564be4508912fb1d866adfc Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 22 Mar 2018 21:28:23 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: allocate struct brcmf_pub instance using |  | ||||||
|  wiphy_new() |  | ||||||
|  |  | ||||||
| Rework the driver so the wiphy instance holds the main driver information |  | ||||||
| in its private buffer. Previously it held struct brcmf_cfg80211_info |  | ||||||
| instance so a bit of reorg was needed. This was done so that the wiphy |  | ||||||
| name or its parent device can be shown in debug output. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/btcoex.c  |  2 +- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 86 ++++++++++------------ |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/cfg80211.h         | 17 +++-- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/common.c  |  2 + |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.c    | 27 +++++-- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.h    |  1 + |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  2 +- |  | ||||||
|  7 files changed, 76 insertions(+), 61 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c |  | ||||||
| @@ -462,7 +462,7 @@ static void brcmf_btcoex_dhcp_end(struct |  | ||||||
|  int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif, |  | ||||||
|  			  enum brcmf_btcoex_mode mode, u16 duration) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_cfg80211_info *cfg = wiphy_priv(vif->wdev.wiphy); |  | ||||||
| +	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); |  | ||||||
|  	struct brcmf_btcoex_info *btci = cfg->btcoex; |  | ||||||
|  	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| @@ -753,7 +753,7 @@ s32 brcmf_notify_escan_complete(struct b |  | ||||||
|  static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy, |  | ||||||
|  				       struct wireless_dev *wdev) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); |  | ||||||
| +	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |  | ||||||
|  	struct net_device *ndev = wdev->netdev; |  | ||||||
|  	struct brcmf_if *ifp = netdev_priv(ndev); |  | ||||||
|  	int ret; |  | ||||||
| @@ -786,7 +786,7 @@ err_unarm: |  | ||||||
|  static |  | ||||||
|  int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); |  | ||||||
| +	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |  | ||||||
|  	struct net_device *ndev = wdev->netdev; |  | ||||||
|   |  | ||||||
|  	if (ndev && ndev == cfg_to_ndev(cfg)) |  | ||||||
| @@ -831,7 +831,7 @@ brcmf_cfg80211_change_iface(struct wiphy |  | ||||||
|  			 enum nl80211_iftype type, |  | ||||||
|  			 struct vif_params *params) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); |  | ||||||
| +	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |  | ||||||
|  	struct brcmf_if *ifp = netdev_priv(ndev); |  | ||||||
|  	struct brcmf_cfg80211_vif *vif = ifp->vif; |  | ||||||
|  	s32 infra = 0; |  | ||||||
| @@ -2127,17 +2127,15 @@ static s32 |  | ||||||
|  brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, |  | ||||||
|  			    s32 *dbm) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |  | ||||||
| -	struct net_device *ndev = cfg_to_ndev(cfg); |  | ||||||
| -	struct brcmf_if *ifp = netdev_priv(ndev); |  | ||||||
| +	struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev); |  | ||||||
|  	s32 qdbm = 0; |  | ||||||
|  	s32 err; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
| -	if (!check_vif_up(ifp->vif)) |  | ||||||
| +	if (!check_vif_up(vif)) |  | ||||||
|  		return -EIO; |  | ||||||
|   |  | ||||||
| -	err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &qdbm); |  | ||||||
| +	err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm); |  | ||||||
|  	if (err) { |  | ||||||
|  		brcmf_err("error (%d)\n", err); |  | ||||||
|  		goto done; |  | ||||||
| @@ -3359,7 +3357,7 @@ brcmf_cfg80211_sched_scan_start(struct w |  | ||||||
|  				struct cfg80211_sched_scan_request *req) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_if *ifp = netdev_priv(ndev); |  | ||||||
| -	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); |  | ||||||
| +	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n", |  | ||||||
|  		  req->n_match_sets, req->n_ssids); |  | ||||||
| @@ -5191,6 +5189,12 @@ static struct cfg80211_ops brcmf_cfg8021 |  | ||||||
|  	.del_pmk = brcmf_cfg80211_del_pmk, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +struct cfg80211_ops *brcmf_cfg80211_get_ops(void) |  | ||||||
| +{ |  | ||||||
| +	return kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops), |  | ||||||
| +		       GFP_KERNEL); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, |  | ||||||
|  					   enum nl80211_iftype type) |  | ||||||
|  { |  | ||||||
| @@ -5898,7 +5902,7 @@ static void brcmf_update_bw40_channel_fl |  | ||||||
|  static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, |  | ||||||
|  				    u32 bw_cap[]) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); |  | ||||||
| +	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); |  | ||||||
|  	struct ieee80211_supported_band *band; |  | ||||||
|  	struct ieee80211_channel *channel; |  | ||||||
|  	struct wiphy *wiphy; |  | ||||||
| @@ -6013,7 +6017,7 @@ fail_pbuf: |  | ||||||
|   |  | ||||||
|  static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); |  | ||||||
| +	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); |  | ||||||
|  	struct ieee80211_supported_band *band; |  | ||||||
|  	struct brcmf_fil_bwcap_le band_bwcap; |  | ||||||
|  	struct brcmf_chanspec_list *list; |  | ||||||
| @@ -6198,10 +6202,10 @@ static void brcmf_update_vht_cap(struct |  | ||||||
|  	} |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_setup_wiphybands(struct wiphy *wiphy) |  | ||||||
| +static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); |  | ||||||
| -	struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); |  | ||||||
| +	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); |  | ||||||
| +	struct wiphy *wiphy; |  | ||||||
|  	u32 nmode = 0; |  | ||||||
|  	u32 vhtmode = 0; |  | ||||||
|  	u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT }; |  | ||||||
| @@ -6795,8 +6799,8 @@ static s32 brcmf_translate_country_code( |  | ||||||
|  static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, |  | ||||||
|  					struct regulatory_request *req) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); |  | ||||||
| -	struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); |  | ||||||
| +	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |  | ||||||
| +	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); |  | ||||||
|  	struct brcmf_fil_country_le ccreq; |  | ||||||
|  	s32 err; |  | ||||||
|  	int i; |  | ||||||
| @@ -6831,7 +6835,7 @@ static void brcmf_cfg80211_reg_notifier( |  | ||||||
|  		brcmf_err("Firmware rejected country setting\n"); |  | ||||||
|  		return; |  | ||||||
|  	} |  | ||||||
| -	brcmf_setup_wiphybands(wiphy); |  | ||||||
| +	brcmf_setup_wiphybands(cfg); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static void brcmf_free_wiphy(struct wiphy *wiphy) |  | ||||||
| @@ -6858,17 +6862,15 @@ static void brcmf_free_wiphy(struct wiph |  | ||||||
|  	if (wiphy->wowlan != &brcmf_wowlan_support) |  | ||||||
|  		kfree(wiphy->wowlan); |  | ||||||
|  #endif |  | ||||||
| -	wiphy_free(wiphy); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, |  | ||||||
| -						  struct device *busdev, |  | ||||||
| +						  struct cfg80211_ops *ops, |  | ||||||
|  						  bool p2pdev_forced) |  | ||||||
|  { |  | ||||||
| +	struct wiphy *wiphy = drvr->wiphy; |  | ||||||
|  	struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev; |  | ||||||
|  	struct brcmf_cfg80211_info *cfg; |  | ||||||
| -	struct wiphy *wiphy; |  | ||||||
| -	struct cfg80211_ops *ops; |  | ||||||
|  	struct brcmf_cfg80211_vif *vif; |  | ||||||
|  	struct brcmf_if *ifp; |  | ||||||
|  	s32 err = 0; |  | ||||||
| @@ -6880,26 +6882,13 @@ struct brcmf_cfg80211_info *brcmf_cfg802 |  | ||||||
|  		return NULL; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	ops = kmemdup(&brcmf_cfg80211_ops, sizeof(*ops), GFP_KERNEL); |  | ||||||
| -	if (!ops) |  | ||||||
| -		return NULL; |  | ||||||
| - |  | ||||||
| -	ifp = netdev_priv(ndev); |  | ||||||
| -#ifdef CONFIG_PM |  | ||||||
| -	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) |  | ||||||
| -		ops->set_rekey_data = brcmf_cfg80211_set_rekey_data; |  | ||||||
| -#endif |  | ||||||
| -	wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info)); |  | ||||||
| -	if (!wiphy) { |  | ||||||
| +	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); |  | ||||||
| +	if (!cfg) { |  | ||||||
|  		brcmf_err("Could not allocate wiphy device\n"); |  | ||||||
| -		goto ops_out; |  | ||||||
| +		return NULL; |  | ||||||
|  	} |  | ||||||
| -	memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN); |  | ||||||
| -	set_wiphy_dev(wiphy, busdev); |  | ||||||
|   |  | ||||||
| -	cfg = wiphy_priv(wiphy); |  | ||||||
|  	cfg->wiphy = wiphy; |  | ||||||
| -	cfg->ops = ops; |  | ||||||
|  	cfg->pub = drvr; |  | ||||||
|  	init_vif_event(&cfg->vif_event); |  | ||||||
|  	INIT_LIST_HEAD(&cfg->vif_list); |  | ||||||
| @@ -6908,6 +6897,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 |  | ||||||
|  	if (IS_ERR(vif)) |  | ||||||
|  		goto wiphy_out; |  | ||||||
|   |  | ||||||
| +	ifp = netdev_priv(ndev); |  | ||||||
|  	vif->ifp = ifp; |  | ||||||
|  	vif->wdev.netdev = ndev; |  | ||||||
|  	ndev->ieee80211_ptr = &vif->wdev; |  | ||||||
| @@ -6934,6 +6924,11 @@ struct brcmf_cfg80211_info *brcmf_cfg802 |  | ||||||
|  	if (err < 0) |  | ||||||
|  		goto priv_out; |  | ||||||
|   |  | ||||||
| +	/* regulatory notifer below needs access to cfg so |  | ||||||
| +	 * assign it now. |  | ||||||
| +	 */ |  | ||||||
| +	drvr->config = cfg; |  | ||||||
| + |  | ||||||
|  	brcmf_dbg(INFO, "Registering custom regulatory\n"); |  | ||||||
|  	wiphy->reg_notifier = brcmf_cfg80211_reg_notifier; |  | ||||||
|  	wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; |  | ||||||
| @@ -6947,13 +6942,17 @@ struct brcmf_cfg80211_info *brcmf_cfg802 |  | ||||||
|  		cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap; |  | ||||||
|  		*cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; |  | ||||||
|  	} |  | ||||||
| +#ifdef CONFIG_PM |  | ||||||
| +	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) |  | ||||||
| +		ops->set_rekey_data = brcmf_cfg80211_set_rekey_data; |  | ||||||
| +#endif |  | ||||||
|  	err = wiphy_register(wiphy); |  | ||||||
|  	if (err < 0) { |  | ||||||
|  		brcmf_err("Could not register wiphy device (%d)\n", err); |  | ||||||
|  		goto priv_out; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	err = brcmf_setup_wiphybands(wiphy); |  | ||||||
| +	err = brcmf_setup_wiphybands(cfg); |  | ||||||
|  	if (err) { |  | ||||||
|  		brcmf_err("Setting wiphy bands failed (%d)\n", err); |  | ||||||
|  		goto wiphy_unreg_out; |  | ||||||
| @@ -6970,12 +6969,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 |  | ||||||
|  		else |  | ||||||
|  			*cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |  | ||||||
|  	} |  | ||||||
| -	/* p2p might require that "if-events" get processed by fweh. So |  | ||||||
| -	 * activate the already registered event handlers now and activate |  | ||||||
| -	 * the rest when initialization has completed. drvr->config needs to |  | ||||||
| -	 * be assigned before activating events. |  | ||||||
| -	 */ |  | ||||||
| -	drvr->config = cfg; |  | ||||||
| + |  | ||||||
|  	err = brcmf_fweh_activate_events(ifp); |  | ||||||
|  	if (err) { |  | ||||||
|  		brcmf_err("FWEH activation failed (%d)\n", err); |  | ||||||
| @@ -7043,8 +7037,7 @@ priv_out: |  | ||||||
|  	ifp->vif = NULL; |  | ||||||
|  wiphy_out: |  | ||||||
|  	brcmf_free_wiphy(wiphy); |  | ||||||
| -ops_out: |  | ||||||
| -	kfree(ops); |  | ||||||
| +	kfree(cfg); |  | ||||||
|  	return NULL; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -7059,4 +7052,5 @@ void brcmf_cfg80211_detach(struct brcmf_ |  | ||||||
|  	kfree(cfg->ops); |  | ||||||
|  	wl_deinit_priv(cfg); |  | ||||||
|  	brcmf_free_wiphy(cfg->wiphy); |  | ||||||
| +	kfree(cfg); |  | ||||||
|  } |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h |  | ||||||
| @@ -355,20 +355,24 @@ static inline struct wiphy *cfg_to_wiphy |  | ||||||
|   |  | ||||||
|  static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w) |  | ||||||
|  { |  | ||||||
| -	return (struct brcmf_cfg80211_info *)(wiphy_priv(w)); |  | ||||||
| +	struct brcmf_pub *drvr = wiphy_priv(w); |  | ||||||
| +	return drvr->config; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd) |  | ||||||
|  { |  | ||||||
| -	return (struct brcmf_cfg80211_info *)(wdev_priv(wd)); |  | ||||||
| +	return wiphy_to_cfg(wd->wiphy); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline struct brcmf_cfg80211_vif *wdev_to_vif(struct wireless_dev *wdev) |  | ||||||
| +{ |  | ||||||
| +	return container_of(wdev, struct brcmf_cfg80211_vif, wdev); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static inline |  | ||||||
|  struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_cfg80211_vif *vif; |  | ||||||
| -	vif = list_first_entry(&cfg->vif_list, struct brcmf_cfg80211_vif, list); |  | ||||||
| -	return vif->wdev.netdev; |  | ||||||
| +	return brcmf_get_ifp(cfg->pub, 0)->ndev; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev) |  | ||||||
| @@ -395,11 +399,12 @@ brcmf_cfg80211_connect_info *cfg_to_conn |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, |  | ||||||
| -						  struct device *busdev, |  | ||||||
| +						  struct cfg80211_ops *ops, |  | ||||||
|  						  bool p2pdev_forced); |  | ||||||
|  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); |  | ||||||
|  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/common.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| @@ -252,6 +252,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i |  | ||||||
|  		brcmf_err("Retreiving cur_etheraddr failed, %d\n", err); |  | ||||||
|  		goto done; |  | ||||||
|  	} |  | ||||||
| +	memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN); |  | ||||||
|  	memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac)); |  | ||||||
|   |  | ||||||
|  	bus = ifp->drvr->bus_if; |  | ||||||
| @@ -279,6 +280,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i |  | ||||||
|  		ri->chippkg = le32_to_cpu(revinfo.chippkg); |  | ||||||
|  		ri->nvramrev = le32_to_cpu(revinfo.nvramrev); |  | ||||||
|   |  | ||||||
| +		/* use revinfo if not known yet */ |  | ||||||
|  		if (!bus->chip) { |  | ||||||
|  			bus->chip = le32_to_cpu(revinfo.chipnum); |  | ||||||
|  			bus->chiprev = le32_to_cpu(revinfo.chiprev); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| @@ -1021,7 +1021,7 @@ static int brcmf_revinfo_read(struct seq |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_bus_started(struct brcmf_pub *drvr) |  | ||||||
| +static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops) |  | ||||||
|  { |  | ||||||
|  	int ret = -1; |  | ||||||
|  	struct brcmf_bus *bus_if = drvr->bus_if; |  | ||||||
| @@ -1060,7 +1060,7 @@ static int brcmf_bus_started(struct brcm |  | ||||||
|   |  | ||||||
|  	brcmf_proto_add_if(drvr, ifp); |  | ||||||
|   |  | ||||||
| -	drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev, |  | ||||||
| +	drvr->config = brcmf_cfg80211_attach(drvr, ops, |  | ||||||
|  					     drvr->settings->p2p_enable); |  | ||||||
|  	if (drvr->config == NULL) { |  | ||||||
|  		ret = -ENOMEM; |  | ||||||
| @@ -1115,17 +1115,26 @@ fail: |  | ||||||
|   |  | ||||||
|  int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) |  | ||||||
|  { |  | ||||||
| +	struct wiphy *wiphy; |  | ||||||
| +	struct cfg80211_ops *ops; |  | ||||||
|  	struct brcmf_pub *drvr = NULL; |  | ||||||
|  	int ret = 0; |  | ||||||
|  	int i; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
|   |  | ||||||
| -	/* Allocate primary brcmf_info */ |  | ||||||
| -	drvr = kzalloc(sizeof(*drvr), GFP_ATOMIC); |  | ||||||
| -	if (!drvr) |  | ||||||
| +	ops = brcmf_cfg80211_get_ops(); |  | ||||||
| +	if (!ops) |  | ||||||
|  		return -ENOMEM; |  | ||||||
|   |  | ||||||
| +	wiphy = wiphy_new(ops, sizeof(*drvr)); |  | ||||||
| +	if (!wiphy) |  | ||||||
| +		return -ENOMEM; |  | ||||||
| + |  | ||||||
| +	set_wiphy_dev(wiphy, dev); |  | ||||||
| +	drvr = wiphy_priv(wiphy); |  | ||||||
| +	drvr->wiphy = wiphy; |  | ||||||
| + |  | ||||||
|  	for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) |  | ||||||
|  		drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; |  | ||||||
|   |  | ||||||
| @@ -1154,15 +1163,18 @@ int brcmf_attach(struct device *dev, str |  | ||||||
|  	/* attach firmware event handler */ |  | ||||||
|  	brcmf_fweh_attach(drvr); |  | ||||||
|   |  | ||||||
| -	ret = brcmf_bus_started(drvr); |  | ||||||
| +	ret = brcmf_bus_started(drvr, ops); |  | ||||||
|  	if (ret != 0) { |  | ||||||
|  		brcmf_err("dongle is not responding: err=%d\n", ret); |  | ||||||
|  		goto fail; |  | ||||||
|  	} |  | ||||||
| + |  | ||||||
| +	drvr->config->ops = ops; |  | ||||||
|  	return 0; |  | ||||||
|   |  | ||||||
|  fail: |  | ||||||
|  	brcmf_detach(dev); |  | ||||||
| +	kfree(ops); |  | ||||||
|   |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
| @@ -1220,6 +1232,7 @@ void brcmf_detach(struct device *dev) |  | ||||||
|  		brcmf_remove_interface(drvr->iflist[i], false); |  | ||||||
|   |  | ||||||
|  	brcmf_cfg80211_detach(drvr->config); |  | ||||||
| +	drvr->config = NULL; |  | ||||||
|   |  | ||||||
|  	brcmf_bus_stop(drvr->bus_if); |  | ||||||
|   |  | ||||||
| @@ -1227,7 +1240,7 @@ void brcmf_detach(struct device *dev) |  | ||||||
|   |  | ||||||
|  	brcmf_debug_detach(drvr); |  | ||||||
|  	bus_if->drvr = NULL; |  | ||||||
| -	kfree(drvr); |  | ||||||
| +	wiphy_free(drvr->wiphy); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len) |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h |  | ||||||
| @@ -107,6 +107,7 @@ struct brcmf_pub { |  | ||||||
|  	/* Linkage ponters */ |  | ||||||
|  	struct brcmf_bus *bus_if; |  | ||||||
|  	struct brcmf_proto *proto; |  | ||||||
| +	struct wiphy *wiphy; |  | ||||||
|  	struct brcmf_cfg80211_info *config; |  | ||||||
|   |  | ||||||
|  	/* Internal brcmf items */ |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  | ||||||
| @@ -2229,7 +2229,7 @@ fail: |  | ||||||
|   */ |  | ||||||
|  int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); |  | ||||||
| +	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |  | ||||||
|  	struct brcmf_p2p_info *p2p = &cfg->p2p; |  | ||||||
|  	struct brcmf_cfg80211_vif *vif; |  | ||||||
|  	enum nl80211_iftype iftype; |  | ||||||
| @@ -1,349 +0,0 @@ | |||||||
| From 34789d0cf682c643862792750a06c31ccf016cbc Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 22 Mar 2018 21:28:24 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: use wiphy debugfs dir entry |  | ||||||
|  |  | ||||||
| The driver used to create a brcmfmac dir entry at the top level |  | ||||||
| debugfs mount point. This moves the debugfs entries into the |  | ||||||
| wiphy debugfs dir entry. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcdc.c    |  6 ++++ |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/common.c  |  5 --- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.c    | 11 +++--- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/debug.c   | 42 ++-------------------- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/debug.h   | 17 --------- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/feature.c |  3 ++ |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/feature.h |  7 ++++ |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/fwsignal.c         | 11 +++--- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/fwsignal.h         |  1 + |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/msgbuf.c  |  8 +++-- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/proto.c   |  3 +- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/proto.h   |  7 ++++ |  | ||||||
|  12 files changed, 47 insertions(+), 74 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c |  | ||||||
| @@ -445,6 +445,11 @@ brcmf_proto_bcdc_init_done(struct brcmf_ |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static void brcmf_proto_bcdc_debugfs_create(struct brcmf_pub *drvr) |  | ||||||
| +{ |  | ||||||
| +	brcmf_fws_debugfs_create(drvr); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_bcdc *bcdc; |  | ||||||
| @@ -472,6 +477,7 @@ int brcmf_proto_bcdc_attach(struct brcmf |  | ||||||
|  	drvr->proto->del_if = brcmf_proto_bcdc_del_if; |  | ||||||
|  	drvr->proto->reset_if = brcmf_proto_bcdc_reset_if; |  | ||||||
|  	drvr->proto->init_done = brcmf_proto_bcdc_init_done; |  | ||||||
| +	drvr->proto->debugfs_create = brcmf_proto_bcdc_debugfs_create; |  | ||||||
|  	drvr->proto->pd = bcdc; |  | ||||||
|   |  | ||||||
|  	drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| @@ -529,9 +529,6 @@ static int __init brcmfmac_module_init(v |  | ||||||
|  { |  | ||||||
|  	int err; |  | ||||||
|   |  | ||||||
| -	/* Initialize debug system first */ |  | ||||||
| -	brcmf_debugfs_init(); |  | ||||||
| - |  | ||||||
|  	/* Get the platform data (if available) for our devices */ |  | ||||||
|  	err = platform_driver_probe(&brcmf_pd, brcmf_common_pd_probe); |  | ||||||
|  	if (err == -ENODEV) |  | ||||||
| @@ -543,7 +540,6 @@ static int __init brcmfmac_module_init(v |  | ||||||
|  	/* Continue the initialization by registering the different busses */ |  | ||||||
|  	err = brcmf_core_init(); |  | ||||||
|  	if (err) { |  | ||||||
| -		brcmf_debugfs_exit(); |  | ||||||
|  		if (brcmfmac_pdata) |  | ||||||
|  			platform_driver_unregister(&brcmf_pd); |  | ||||||
|  	} |  | ||||||
| @@ -556,7 +552,6 @@ static void __exit brcmfmac_module_exit( |  | ||||||
|  	brcmf_core_exit(); |  | ||||||
|  	if (brcmfmac_pdata) |  | ||||||
|  		platform_driver_unregister(&brcmf_pd); |  | ||||||
| -	brcmf_debugfs_exit(); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  module_init(brcmfmac_module_init); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| @@ -1050,8 +1050,6 @@ static int brcmf_bus_started(struct brcm |  | ||||||
|  	if (ret < 0) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
| -	brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); |  | ||||||
| - |  | ||||||
|  	brcmf_feat_attach(drvr); |  | ||||||
|   |  | ||||||
|  	ret = brcmf_proto_init_done(drvr); |  | ||||||
| @@ -1094,6 +1092,11 @@ static int brcmf_bus_started(struct brcm |  | ||||||
|  #endif |  | ||||||
|  #endif /* CONFIG_INET */ |  | ||||||
|   |  | ||||||
| +	/* populate debugfs */ |  | ||||||
| +	brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); |  | ||||||
| +	brcmf_feat_debugfs_create(drvr); |  | ||||||
| +	brcmf_proto_debugfs_create(drvr); |  | ||||||
| + |  | ||||||
|  	return 0; |  | ||||||
|   |  | ||||||
|  fail: |  | ||||||
| @@ -1146,9 +1149,6 @@ int brcmf_attach(struct device *dev, str |  | ||||||
|  	drvr->bus_if->drvr = drvr; |  | ||||||
|  	drvr->settings = settings; |  | ||||||
|   |  | ||||||
| -	/* attach debug facilities */ |  | ||||||
| -	brcmf_debug_attach(drvr); |  | ||||||
| - |  | ||||||
|  	/* Attach and link in the protocol */ |  | ||||||
|  	ret = brcmf_proto_attach(drvr); |  | ||||||
|  	if (ret != 0) { |  | ||||||
| @@ -1238,7 +1238,6 @@ void brcmf_detach(struct device *dev) |  | ||||||
|   |  | ||||||
|  	brcmf_proto_detach(drvr); |  | ||||||
|   |  | ||||||
| -	brcmf_debug_detach(drvr); |  | ||||||
|  	bus_if->drvr = NULL; |  | ||||||
|  	wiphy_free(drvr->wiphy); |  | ||||||
|  } |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c |  | ||||||
| @@ -25,8 +25,6 @@ |  | ||||||
|  #include "fweh.h" |  | ||||||
|  #include "debug.h" |  | ||||||
|   |  | ||||||
| -static struct dentry *root_folder; |  | ||||||
| - |  | ||||||
|  int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, |  | ||||||
|  			       size_t len) |  | ||||||
|  { |  | ||||||
| @@ -54,44 +52,9 @@ int brcmf_debug_create_memdump(struct br |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -void brcmf_debugfs_init(void) |  | ||||||
| -{ |  | ||||||
| -	root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL); |  | ||||||
| -	if (IS_ERR(root_folder)) |  | ||||||
| -		root_folder = NULL; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
| -void brcmf_debugfs_exit(void) |  | ||||||
| -{ |  | ||||||
| -	if (!root_folder) |  | ||||||
| -		return; |  | ||||||
| - |  | ||||||
| -	debugfs_remove_recursive(root_folder); |  | ||||||
| -	root_folder = NULL; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
| -int brcmf_debug_attach(struct brcmf_pub *drvr) |  | ||||||
| -{ |  | ||||||
| -	struct device *dev = drvr->bus_if->dev; |  | ||||||
| - |  | ||||||
| -	if (!root_folder) |  | ||||||
| -		return -ENODEV; |  | ||||||
| - |  | ||||||
| -	drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); |  | ||||||
| -	return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); |  | ||||||
| -} |  | ||||||
| - |  | ||||||
| -void brcmf_debug_detach(struct brcmf_pub *drvr) |  | ||||||
| -{ |  | ||||||
| -	brcmf_fweh_unregister(drvr, BRCMF_E_PSM_WATCHDOG); |  | ||||||
| - |  | ||||||
| -	if (!IS_ERR_OR_NULL(drvr->dbgfs_dir)) |  | ||||||
| -		debugfs_remove_recursive(drvr->dbgfs_dir); |  | ||||||
| -} |  | ||||||
| - |  | ||||||
|  struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) |  | ||||||
|  { |  | ||||||
| -	return drvr->dbgfs_dir; |  | ||||||
| +	return drvr->wiphy->debugfsdir; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, |  | ||||||
| @@ -99,7 +62,8 @@ int brcmf_debugfs_add_entry(struct brcmf |  | ||||||
|  { |  | ||||||
|  	struct dentry *e; |  | ||||||
|   |  | ||||||
| +	WARN(!drvr->wiphy->debugfsdir, "wiphy not (yet) registered\n"); |  | ||||||
|  	e = debugfs_create_devm_seqfile(drvr->bus_if->dev, fn, |  | ||||||
| -					drvr->dbgfs_dir, read_fn); |  | ||||||
| +					drvr->wiphy->debugfsdir, read_fn); |  | ||||||
|  	return PTR_ERR_OR_ZERO(e); |  | ||||||
|  } |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h |  | ||||||
| @@ -113,29 +113,12 @@ extern int brcmf_msg_level; |  | ||||||
|  struct brcmf_bus; |  | ||||||
|  struct brcmf_pub; |  | ||||||
|  #ifdef DEBUG |  | ||||||
| -void brcmf_debugfs_init(void); |  | ||||||
| -void brcmf_debugfs_exit(void); |  | ||||||
| -int brcmf_debug_attach(struct brcmf_pub *drvr); |  | ||||||
| -void brcmf_debug_detach(struct brcmf_pub *drvr); |  | ||||||
|  struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr); |  | ||||||
|  int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, |  | ||||||
|  			    int (*read_fn)(struct seq_file *seq, void *data)); |  | ||||||
|  int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, |  | ||||||
|  			       size_t len); |  | ||||||
|  #else |  | ||||||
| -static inline void brcmf_debugfs_init(void) |  | ||||||
| -{ |  | ||||||
| -} |  | ||||||
| -static inline void brcmf_debugfs_exit(void) |  | ||||||
| -{ |  | ||||||
| -} |  | ||||||
| -static inline int brcmf_debug_attach(struct brcmf_pub *drvr) |  | ||||||
| -{ |  | ||||||
| -	return 0; |  | ||||||
| -} |  | ||||||
| -static inline void brcmf_debug_detach(struct brcmf_pub *drvr) |  | ||||||
| -{ |  | ||||||
| -} |  | ||||||
|  static inline |  | ||||||
|  int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, |  | ||||||
|  			    int (*read_fn)(struct seq_file *seq, void *data)) |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c |  | ||||||
| @@ -228,7 +228,10 @@ void brcmf_feat_attach(struct brcmf_pub |  | ||||||
|  		/* no quirks */ |  | ||||||
|  		break; |  | ||||||
|  	} |  | ||||||
| +} |  | ||||||
|   |  | ||||||
| +void brcmf_feat_debugfs_create(struct brcmf_pub *drvr) |  | ||||||
| +{ |  | ||||||
|  	brcmf_debugfs_add_entry(drvr, "features", brcmf_feat_debugfs_read); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h |  | ||||||
| @@ -90,6 +90,13 @@ enum brcmf_feat_quirk { |  | ||||||
|  void brcmf_feat_attach(struct brcmf_pub *drvr); |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
| + * brcmf_feat_debugfs_create() - create debugfs entries. |  | ||||||
| + * |  | ||||||
| + * @drvr: driver instance. |  | ||||||
| + */ |  | ||||||
| +void brcmf_feat_debugfs_create(struct brcmf_pub *drvr); |  | ||||||
| + |  | ||||||
| +/** |  | ||||||
|   * brcmf_feat_is_enabled() - query feature. |  | ||||||
|   * |  | ||||||
|   * @ifp: interface instance. |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c |  | ||||||
| @@ -2399,10 +2399,6 @@ struct brcmf_fws_info *brcmf_fws_attach( |  | ||||||
|  	brcmu_pktq_init(&fws->desc.other.psq, BRCMF_FWS_PSQ_PREC_COUNT, |  | ||||||
|  			BRCMF_FWS_PSQ_LEN); |  | ||||||
|   |  | ||||||
| -	/* create debugfs file for statistics */ |  | ||||||
| -	brcmf_debugfs_add_entry(drvr, "fws_stats", |  | ||||||
| -				brcmf_debugfs_fws_stats_read); |  | ||||||
| - |  | ||||||
|  	brcmf_dbg(INFO, "%s bdcv2 tlv signaling [%x]\n", |  | ||||||
|  		  fws->fw_signals ? "enabled" : "disabled", tlv); |  | ||||||
|  	return fws; |  | ||||||
| @@ -2429,6 +2425,13 @@ void brcmf_fws_detach(struct brcmf_fws_i |  | ||||||
|  	kfree(fws); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +void brcmf_fws_debugfs_create(struct brcmf_pub *drvr) |  | ||||||
| +{ |  | ||||||
| +	/* create debugfs file for statistics */ |  | ||||||
| +	brcmf_debugfs_add_entry(drvr, "fws_stats", |  | ||||||
| +				brcmf_debugfs_fws_stats_read); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws) |  | ||||||
|  { |  | ||||||
|  	return !fws->avoid_queueing; |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h |  | ||||||
| @@ -20,6 +20,7 @@ |  | ||||||
|   |  | ||||||
|  struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr); |  | ||||||
|  void brcmf_fws_detach(struct brcmf_fws_info *fws); |  | ||||||
| +void brcmf_fws_debugfs_create(struct brcmf_pub *drvr); |  | ||||||
|  bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws); |  | ||||||
|  bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); |  | ||||||
|  void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c |  | ||||||
| @@ -1418,6 +1418,11 @@ static int brcmf_msgbuf_stats_read(struc |  | ||||||
|  } |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +static void brcmf_msgbuf_debugfs_create(struct brcmf_pub *drvr) |  | ||||||
| +{ |  | ||||||
| +	brcmf_debugfs_add_entry(drvr, "msgbuf_stats", brcmf_msgbuf_stats_read); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_bus_msgbuf *if_msgbuf; |  | ||||||
| @@ -1472,6 +1477,7 @@ int brcmf_proto_msgbuf_attach(struct brc |  | ||||||
|  	drvr->proto->delete_peer = brcmf_msgbuf_delete_peer; |  | ||||||
|  	drvr->proto->add_tdls_peer = brcmf_msgbuf_add_tdls_peer; |  | ||||||
|  	drvr->proto->rxreorder = brcmf_msgbuf_rxreorder; |  | ||||||
| +	drvr->proto->debugfs_create = brcmf_msgbuf_debugfs_create; |  | ||||||
|  	drvr->proto->pd = msgbuf; |  | ||||||
|   |  | ||||||
|  	init_waitqueue_head(&msgbuf->ioctl_resp_wait); |  | ||||||
| @@ -1525,8 +1531,6 @@ int brcmf_proto_msgbuf_attach(struct brc |  | ||||||
|  	spin_lock_init(&msgbuf->flowring_work_lock); |  | ||||||
|  	INIT_LIST_HEAD(&msgbuf->work_queue); |  | ||||||
|   |  | ||||||
| -	brcmf_debugfs_add_entry(drvr, "msgbuf_stats", brcmf_msgbuf_stats_read); |  | ||||||
| - |  | ||||||
|  	return 0; |  | ||||||
|   |  | ||||||
|  fail: |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c |  | ||||||
| @@ -54,7 +54,8 @@ int brcmf_proto_attach(struct brcmf_pub |  | ||||||
|  	if (!proto->tx_queue_data || (proto->hdrpull == NULL) || |  | ||||||
|  	    (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL) || |  | ||||||
|  	    (proto->configure_addr_mode == NULL) || |  | ||||||
| -	    (proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL)) { |  | ||||||
| +	    (proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL) || |  | ||||||
| +	    (proto->debugfs_create == NULL)) { |  | ||||||
|  		brcmf_err("Not all proto handlers have been installed\n"); |  | ||||||
|  		goto fail; |  | ||||||
|  	} |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h |  | ||||||
| @@ -48,6 +48,7 @@ struct brcmf_proto { |  | ||||||
|  	void (*del_if)(struct brcmf_if *ifp); |  | ||||||
|  	void (*reset_if)(struct brcmf_if *ifp); |  | ||||||
|  	int (*init_done)(struct brcmf_pub *drvr); |  | ||||||
| +	void (*debugfs_create)(struct brcmf_pub *drvr); |  | ||||||
|  	void *pd; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| @@ -156,4 +157,10 @@ brcmf_proto_init_done(struct brcmf_pub * |  | ||||||
|  	return drvr->proto->init_done(drvr); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static inline void |  | ||||||
| +brcmf_proto_debugfs_create(struct brcmf_pub *drvr) |  | ||||||
| +{ |  | ||||||
| +	drvr->proto->debugfs_create(drvr); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  #endif /* BRCMFMAC_PROTO_H */ |  | ||||||
| @@ -1,286 +0,0 @@ | |||||||
| From 41f573dbb534f14e62a4a5411f602c970cad1d77 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 22 Mar 2018 21:28:25 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: derive firmware filenames from basename mapping |  | ||||||
|  |  | ||||||
| Instead of defining individual filenames for firmware and nvram |  | ||||||
| use a basename and derive the names from that. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/firmware.c         | 31 ++++++--- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/firmware.h         | 24 ++----- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/pcie.c    | 56 ++++++++--------- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 73 +++++++++++----------- |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 10 +-- |  | ||||||
|  5 files changed, 96 insertions(+), 98 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| @@ -563,6 +563,13 @@ int brcmf_fw_get_firmwares(struct device |  | ||||||
|  					   0); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static void brcmf_fw_get_full_name(char fw_name[BRCMF_FW_NAME_LEN], |  | ||||||
| +				   const char *fw_base, const char *extension) |  | ||||||
| +{ |  | ||||||
| +	strlcat(fw_name, fw_base, BRCMF_FW_NAME_LEN); |  | ||||||
| +	strlcat(fw_name, extension, BRCMF_FW_NAME_LEN); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev, |  | ||||||
|  			      struct brcmf_firmware_mapping mapping_table[], |  | ||||||
|  			      u32 table_size, char fw_name[BRCMF_FW_NAME_LEN], |  | ||||||
| @@ -587,25 +594,31 @@ int brcmf_fw_map_chip_to_name(u32 chip, |  | ||||||
|   |  | ||||||
|  	/* check if firmware path is provided by module parameter */ |  | ||||||
|  	if (brcmf_mp_global.firmware_path[0] != '\0') { |  | ||||||
| -		strlcpy(fw_name, brcmf_mp_global.firmware_path, |  | ||||||
| -			BRCMF_FW_NAME_LEN); |  | ||||||
| -		if ((nvram_name) && (mapping_table[i].nvram)) |  | ||||||
| +		if (fw_name) |  | ||||||
| +			strlcpy(fw_name, brcmf_mp_global.firmware_path, |  | ||||||
| +				BRCMF_FW_NAME_LEN); |  | ||||||
| +		if (nvram_name) |  | ||||||
|  			strlcpy(nvram_name, brcmf_mp_global.firmware_path, |  | ||||||
|  				BRCMF_FW_NAME_LEN); |  | ||||||
|   |  | ||||||
|  		end = brcmf_mp_global.firmware_path[ |  | ||||||
|  				strlen(brcmf_mp_global.firmware_path) - 1]; |  | ||||||
|  		if (end != '/') { |  | ||||||
| -			strlcat(fw_name, "/", BRCMF_FW_NAME_LEN); |  | ||||||
| -			if ((nvram_name) && (mapping_table[i].nvram)) |  | ||||||
| +			if (fw_name) |  | ||||||
| +				strlcat(fw_name, "/", BRCMF_FW_NAME_LEN); |  | ||||||
| +			if (nvram_name) |  | ||||||
|  				strlcat(nvram_name, "/", BRCMF_FW_NAME_LEN); |  | ||||||
|  		} |  | ||||||
|  	} |  | ||||||
| -	strlcat(fw_name, mapping_table[i].fw, BRCMF_FW_NAME_LEN); |  | ||||||
| -	if ((nvram_name) && (mapping_table[i].nvram)) |  | ||||||
| -		strlcat(nvram_name, mapping_table[i].nvram, BRCMF_FW_NAME_LEN); |  | ||||||
|   |  | ||||||
| -	brcmf_info("using %s for chip %s\n", fw_name, chipname); |  | ||||||
| +	brcmf_info("using %s for chip %s\n", |  | ||||||
| +		   mapping_table[i].fw_base, chipname); |  | ||||||
| +	if (fw_name) |  | ||||||
| +		brcmf_fw_get_full_name(fw_name, |  | ||||||
| +				       mapping_table[i].fw_base, ".bin"); |  | ||||||
| +	if (nvram_name) |  | ||||||
| +		brcmf_fw_get_full_name(nvram_name, |  | ||||||
| +				       mapping_table[i].fw_base, ".txt"); |  | ||||||
|   |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h |  | ||||||
| @@ -38,28 +38,16 @@ |  | ||||||
|  struct brcmf_firmware_mapping { |  | ||||||
|  	u32 chipid; |  | ||||||
|  	u32 revmask; |  | ||||||
| -	const char *fw; |  | ||||||
| -	const char *nvram; |  | ||||||
| +	const char *fw_base; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| -#define BRCMF_FW_NVRAM_DEF(fw_nvram_name, fw, nvram) \ |  | ||||||
| -static const char BRCM_ ## fw_nvram_name ## _FIRMWARE_NAME[] = \ |  | ||||||
| -	BRCMF_FW_DEFAULT_PATH fw; \ |  | ||||||
| -static const char BRCM_ ## fw_nvram_name ## _NVRAM_NAME[] = \ |  | ||||||
| -	BRCMF_FW_DEFAULT_PATH nvram; \ |  | ||||||
| -MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw); |  | ||||||
| - |  | ||||||
| -#define BRCMF_FW_DEF(fw_name, fw) \ |  | ||||||
| -static const char BRCM_ ## fw_name ## _FIRMWARE_NAME[] = \ |  | ||||||
| -	BRCMF_FW_DEFAULT_PATH fw; \ |  | ||||||
| -MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw) \ |  | ||||||
| - |  | ||||||
| -#define BRCMF_FW_NVRAM_ENTRY(chipid, mask, name) \ |  | ||||||
| -	{ chipid, mask, \ |  | ||||||
| -	  BRCM_ ## name ## _FIRMWARE_NAME, BRCM_ ## name ## _NVRAM_NAME } |  | ||||||
| +#define BRCMF_FW_DEF(fw_name, fw_base) \ |  | ||||||
| +static const char BRCM_ ## fw_name ## _FIRMWARE_BASENAME[] = \ |  | ||||||
| +	BRCMF_FW_DEFAULT_PATH fw_base; \ |  | ||||||
| +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw_base ".bin") |  | ||||||
|   |  | ||||||
|  #define BRCMF_FW_ENTRY(chipid, mask, name) \ |  | ||||||
| -	{ chipid, mask, BRCM_ ## name ## _FIRMWARE_NAME, NULL } |  | ||||||
| +	{ chipid, mask, BRCM_ ## name ## _FIRMWARE_BASENAME } |  | ||||||
|   |  | ||||||
|  int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev, |  | ||||||
|  			      struct brcmf_firmware_mapping mapping_table[], |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| @@ -46,36 +46,36 @@ enum brcmf_pcie_state { |  | ||||||
|  	BRCMFMAC_PCIE_STATE_UP |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| -BRCMF_FW_NVRAM_DEF(43602, "brcmfmac43602-pcie.bin", "brcmfmac43602-pcie.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4350, "brcmfmac4350-pcie.bin", "brcmfmac4350-pcie.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4350C, "brcmfmac4350c2-pcie.bin", "brcmfmac4350c2-pcie.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4356, "brcmfmac4356-pcie.bin", "brcmfmac4356-pcie.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(43570, "brcmfmac43570-pcie.bin", "brcmfmac43570-pcie.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4358, "brcmfmac4358-pcie.bin", "brcmfmac4358-pcie.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4359, "brcmfmac4359-pcie.bin", "brcmfmac4359-pcie.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4365B, "brcmfmac4365b-pcie.bin", "brcmfmac4365b-pcie.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4365C, "brcmfmac4365c-pcie.bin", "brcmfmac4365c-pcie.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4366B, "brcmfmac4366b-pcie.bin", "brcmfmac4366b-pcie.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4366C, "brcmfmac4366c-pcie.bin", "brcmfmac4366c-pcie.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4371, "brcmfmac4371-pcie.bin", "brcmfmac4371-pcie.txt"); |  | ||||||
| +BRCMF_FW_DEF(43602, "brcmfmac43602-pcie"); |  | ||||||
| +BRCMF_FW_DEF(4350, "brcmfmac4350-pcie"); |  | ||||||
| +BRCMF_FW_DEF(4350C, "brcmfmac4350c2-pcie"); |  | ||||||
| +BRCMF_FW_DEF(4356, "brcmfmac4356-pcie"); |  | ||||||
| +BRCMF_FW_DEF(43570, "brcmfmac43570-pcie"); |  | ||||||
| +BRCMF_FW_DEF(4358, "brcmfmac4358-pcie"); |  | ||||||
| +BRCMF_FW_DEF(4359, "brcmfmac4359-pcie"); |  | ||||||
| +BRCMF_FW_DEF(4365B, "brcmfmac4365b-pcie"); |  | ||||||
| +BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie"); |  | ||||||
| +BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie"); |  | ||||||
| +BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie"); |  | ||||||
| +BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); |  | ||||||
|   |  | ||||||
|  static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43465_CHIP_ID, 0xFFFFFFF0, 4366C), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFF00, 4350), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43525_CHIP_ID, 0xFFFFFFF0, 4365C), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43570_CHIP_ID, 0xFFFFFFFF, 43570), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0x0000000F, 4365B), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFF0, 4365C), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43465_CHIP_ID, 0xFFFFFFF0, 4366C), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFF00, 4350), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43525_CHIP_ID, 0xFFFFFFF0, 4365C), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43570_CHIP_ID, 0xFFFFFFFF, 43570), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4365_CHIP_ID, 0x0000000F, 4365B), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFF0, 4365C), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  #define BRCMF_PCIE_FW_UP_TIMEOUT		2000 /* msec */ |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -600,47 +600,44 @@ static const struct sdiod_drive_str sdio |  | ||||||
|  	{4,  0x1} |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| -BRCMF_FW_NVRAM_DEF(43143, "brcmfmac43143-sdio.bin", "brcmfmac43143-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(43241B0, "brcmfmac43241b0-sdio.bin", |  | ||||||
| -		   "brcmfmac43241b0-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(43241B4, "brcmfmac43241b4-sdio.bin", |  | ||||||
| -		   "brcmfmac43241b4-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(43241B5, "brcmfmac43241b5-sdio.bin", |  | ||||||
| -		   "brcmfmac43241b5-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4329, "brcmfmac4329-sdio.bin", "brcmfmac4329-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4330, "brcmfmac4330-sdio.bin", "brcmfmac4330-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4334, "brcmfmac4334-sdio.bin", "brcmfmac4334-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(43340, "brcmfmac43340-sdio.bin", "brcmfmac43340-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4335, "brcmfmac4335-sdio.bin", "brcmfmac4335-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(43362, "brcmfmac43362-sdio.bin", "brcmfmac43362-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4339, "brcmfmac4339-sdio.bin", "brcmfmac4339-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(43430A0, "brcmfmac43430a0-sdio.bin", "brcmfmac43430a0-sdio.txt"); |  | ||||||
| +BRCMF_FW_DEF(43143, "brcmfmac43143-sdio"); |  | ||||||
| +BRCMF_FW_DEF(43241B0, "brcmfmac43241b0-sdio"); |  | ||||||
| +BRCMF_FW_DEF(43241B4, "brcmfmac43241b4-sdio"); |  | ||||||
| +BRCMF_FW_DEF(43241B5, "brcmfmac43241b5-sdio"); |  | ||||||
| +BRCMF_FW_DEF(4329, "brcmfmac4329-sdio"); |  | ||||||
| +BRCMF_FW_DEF(4330, "brcmfmac4330-sdio"); |  | ||||||
| +BRCMF_FW_DEF(4334, "brcmfmac4334-sdio"); |  | ||||||
| +BRCMF_FW_DEF(43340, "brcmfmac43340-sdio"); |  | ||||||
| +BRCMF_FW_DEF(4335, "brcmfmac4335-sdio"); |  | ||||||
| +BRCMF_FW_DEF(43362, "brcmfmac43362-sdio"); |  | ||||||
| +BRCMF_FW_DEF(4339, "brcmfmac4339-sdio"); |  | ||||||
| +BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-sdio"); |  | ||||||
|  /* Note the names are not postfixed with a1 for backward compatibility */ |  | ||||||
| -BRCMF_FW_NVRAM_DEF(43430A1, "brcmfmac43430-sdio.bin", "brcmfmac43430-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(43455, "brcmfmac43455-sdio.bin", "brcmfmac43455-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4354, "brcmfmac4354-sdio.bin", "brcmfmac4354-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4356, "brcmfmac4356-sdio.bin", "brcmfmac4356-sdio.txt"); |  | ||||||
| -BRCMF_FW_NVRAM_DEF(4373, "brcmfmac4373-sdio.bin", "brcmfmac4373-sdio.txt"); |  | ||||||
| +BRCMF_FW_DEF(43430A1, "brcmfmac43430-sdio"); |  | ||||||
| +BRCMF_FW_DEF(43455, "brcmfmac43455-sdio"); |  | ||||||
| +BRCMF_FW_DEF(4354, "brcmfmac4354-sdio"); |  | ||||||
| +BRCMF_FW_DEF(4356, "brcmfmac4356-sdio"); |  | ||||||
| +BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); |  | ||||||
|   |  | ||||||
|  static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43241_CHIP_ID, 0xFFFFFFC0, 43241B5), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, 4329), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFE, 43430A1), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), |  | ||||||
| -	BRCMF_FW_NVRAM_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373) |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0xFFFFFFC0, 43241B5), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, 4329), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFE, 43430A1), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), |  | ||||||
| +	BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373) |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  static void pkt_align(struct sk_buff *p, int len, int align) |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| @@ -46,11 +46,11 @@ |  | ||||||
|  #define BRCMF_USB_CBCTL_READ		1 |  | ||||||
|  #define BRCMF_USB_MAX_PKT_SIZE		1600 |  | ||||||
|   |  | ||||||
| -BRCMF_FW_DEF(43143, "brcmfmac43143.bin"); |  | ||||||
| -BRCMF_FW_DEF(43236B, "brcmfmac43236b.bin"); |  | ||||||
| -BRCMF_FW_DEF(43242A, "brcmfmac43242a.bin"); |  | ||||||
| -BRCMF_FW_DEF(43569, "brcmfmac43569.bin"); |  | ||||||
| -BRCMF_FW_DEF(4373, "brcmfmac4373.bin"); |  | ||||||
| +BRCMF_FW_DEF(43143, "brcmfmac43143"); |  | ||||||
| +BRCMF_FW_DEF(43236B, "brcmfmac43236b"); |  | ||||||
| +BRCMF_FW_DEF(43242A, "brcmfmac43242a"); |  | ||||||
| +BRCMF_FW_DEF(43569, "brcmfmac43569"); |  | ||||||
| +BRCMF_FW_DEF(4373, "brcmfmac4373"); |  | ||||||
|   |  | ||||||
|  static struct brcmf_firmware_mapping brcmf_usb_fwnames[] = { |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), |  | ||||||
| @@ -1,574 +0,0 @@ | |||||||
| From d09ae51a4b676151edaf572bcd5f272b5532639f Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 22 Mar 2018 21:28:26 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: pass struct in brcmf_fw_get_firmwares() |  | ||||||
|  |  | ||||||
| Make the function brcmf_fw_get_firmwares() a bit more easy to extend |  | ||||||
| using a structure to pass the request parameters. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/firmware.c         | 175 ++++++++++++++------- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/firmware.h         |  43 +++-- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/pcie.c    |  38 ++++- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    |  32 +++- |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  43 ++++- |  | ||||||
|  5 files changed, 245 insertions(+), 86 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| @@ -438,18 +438,31 @@ void brcmf_fw_nvram_free(void *nvram) |  | ||||||
|   |  | ||||||
|  struct brcmf_fw { |  | ||||||
|  	struct device *dev; |  | ||||||
| -	u16 flags; |  | ||||||
| -	const struct firmware *code; |  | ||||||
| -	const char *nvram_name; |  | ||||||
| -	u16 domain_nr; |  | ||||||
| -	u16 bus_nr; |  | ||||||
| -	void (*done)(struct device *dev, int err, const struct firmware *fw, |  | ||||||
| -		     void *nvram_image, u32 nvram_len); |  | ||||||
| +	struct brcmf_fw_request *req; |  | ||||||
| +	u32 curpos; |  | ||||||
| +	void (*done)(struct device *dev, int err, struct brcmf_fw_request *req); |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +static void brcmf_fw_request_done(const struct firmware *fw, void *ctx); |  | ||||||
| + |  | ||||||
| +static void brcmf_fw_free_request(struct brcmf_fw_request *req) |  | ||||||
| +{ |  | ||||||
| +	struct brcmf_fw_item *item; |  | ||||||
| +	int i; |  | ||||||
| + |  | ||||||
| +	for (i = 0, item = &req->items[0]; i < req->n_items; i++, item++) { |  | ||||||
| +		if (item->type == BRCMF_FW_TYPE_BINARY) |  | ||||||
| +			release_firmware(item->binary); |  | ||||||
| +		else if (item->type == BRCMF_FW_TYPE_NVRAM) |  | ||||||
| +			brcmf_fw_nvram_free(item->nv_data.data); |  | ||||||
| +	} |  | ||||||
| +	kfree(req); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_fw *fwctx = ctx; |  | ||||||
| +	struct brcmf_fw_item *cur; |  | ||||||
|  	u32 nvram_length = 0; |  | ||||||
|  	void *nvram = NULL; |  | ||||||
|  	u8 *data = NULL; |  | ||||||
| @@ -457,83 +470,150 @@ static void brcmf_fw_request_nvram_done( |  | ||||||
|  	bool raw_nvram; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); |  | ||||||
| + |  | ||||||
| +	cur = &fwctx->req->items[fwctx->curpos]; |  | ||||||
| + |  | ||||||
|  	if (fw && fw->data) { |  | ||||||
|  		data = (u8 *)fw->data; |  | ||||||
|  		data_len = fw->size; |  | ||||||
|  		raw_nvram = false; |  | ||||||
|  	} else { |  | ||||||
|  		data = bcm47xx_nvram_get_contents(&data_len); |  | ||||||
| -		if (!data && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) |  | ||||||
| +		if (!data && !(cur->flags & BRCMF_FW_REQF_OPTIONAL)) |  | ||||||
|  			goto fail; |  | ||||||
|  		raw_nvram = true; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	if (data) |  | ||||||
|  		nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length, |  | ||||||
| -					     fwctx->domain_nr, fwctx->bus_nr); |  | ||||||
| +					     fwctx->req->domain_nr, |  | ||||||
| +					     fwctx->req->bus_nr); |  | ||||||
|   |  | ||||||
|  	if (raw_nvram) |  | ||||||
|  		bcm47xx_nvram_release_contents(data); |  | ||||||
|  	release_firmware(fw); |  | ||||||
| -	if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) |  | ||||||
| +	if (!nvram && !(cur->flags & BRCMF_FW_REQF_OPTIONAL)) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
| -	fwctx->done(fwctx->dev, 0, fwctx->code, nvram, nvram_length); |  | ||||||
| -	kfree(fwctx); |  | ||||||
| +	brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length); |  | ||||||
| +	cur->nv_data.data = nvram; |  | ||||||
| +	cur->nv_data.len = nvram_length; |  | ||||||
|  	return; |  | ||||||
|   |  | ||||||
|  fail: |  | ||||||
|  	brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); |  | ||||||
| -	release_firmware(fwctx->code); |  | ||||||
| -	fwctx->done(fwctx->dev, -ENOENT, NULL, NULL, 0); |  | ||||||
| +	fwctx->done(fwctx->dev, -ENOENT, NULL); |  | ||||||
| +	brcmf_fw_free_request(fwctx->req); |  | ||||||
|  	kfree(fwctx); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx) |  | ||||||
| +static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async) |  | ||||||
| +{ |  | ||||||
| +	struct brcmf_fw_item *cur; |  | ||||||
| +	const struct firmware *fw = NULL; |  | ||||||
| +	int ret; |  | ||||||
| + |  | ||||||
| +	cur = &fwctx->req->items[fwctx->curpos]; |  | ||||||
| + |  | ||||||
| +	brcmf_dbg(TRACE, "%srequest for %s\n", async ? "async " : "", |  | ||||||
| +		  cur->path); |  | ||||||
| + |  | ||||||
| +	if (async) |  | ||||||
| +		ret = request_firmware_nowait(THIS_MODULE, true, cur->path, |  | ||||||
| +					      fwctx->dev, GFP_KERNEL, fwctx, |  | ||||||
| +					      brcmf_fw_request_done); |  | ||||||
| +	else |  | ||||||
| +		ret = request_firmware(&fw, cur->path, fwctx->dev); |  | ||||||
| + |  | ||||||
| +	if (ret < 0) { |  | ||||||
| +		brcmf_fw_request_done(NULL, fwctx); |  | ||||||
| +	} else if (!async && fw) { |  | ||||||
| +		brcmf_dbg(TRACE, "firmware %s %sfound\n", cur->path, |  | ||||||
| +			  fw ? "" : "not "); |  | ||||||
| +		if (cur->type == BRCMF_FW_TYPE_BINARY) |  | ||||||
| +			cur->binary = fw; |  | ||||||
| +		else if (cur->type == BRCMF_FW_TYPE_NVRAM) |  | ||||||
| +			brcmf_fw_request_nvram_done(fw, fwctx); |  | ||||||
| +		else |  | ||||||
| +			release_firmware(fw); |  | ||||||
| + |  | ||||||
| +		return -EAGAIN; |  | ||||||
| +	} |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static void brcmf_fw_request_done(const struct firmware *fw, void *ctx) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_fw *fwctx = ctx; |  | ||||||
| +	struct brcmf_fw_item *cur; |  | ||||||
|  	int ret = 0; |  | ||||||
|   |  | ||||||
| -	brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); |  | ||||||
| -	if (!fw) { |  | ||||||
| +	cur = &fwctx->req->items[fwctx->curpos]; |  | ||||||
| + |  | ||||||
| +	brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path, |  | ||||||
| +		  fw ? "" : "not "); |  | ||||||
| + |  | ||||||
| +	if (fw) { |  | ||||||
| +		if (cur->type == BRCMF_FW_TYPE_BINARY) |  | ||||||
| +			cur->binary = fw; |  | ||||||
| +		else if (cur->type == BRCMF_FW_TYPE_NVRAM) |  | ||||||
| +			brcmf_fw_request_nvram_done(fw, fwctx); |  | ||||||
| +		else |  | ||||||
| +			release_firmware(fw); |  | ||||||
| +	} else if (cur->type == BRCMF_FW_TYPE_NVRAM) { |  | ||||||
| +		brcmf_fw_request_nvram_done(NULL, fwctx); |  | ||||||
| +	} else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) { |  | ||||||
|  		ret = -ENOENT; |  | ||||||
|  		goto fail; |  | ||||||
|  	} |  | ||||||
| -	/* only requested code so done here */ |  | ||||||
| -	if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) |  | ||||||
| -		goto done; |  | ||||||
| - |  | ||||||
| -	fwctx->code = fw; |  | ||||||
| -	ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name, |  | ||||||
| -				      fwctx->dev, GFP_KERNEL, fwctx, |  | ||||||
| -				      brcmf_fw_request_nvram_done); |  | ||||||
|   |  | ||||||
| -	/* pass NULL to nvram callback for bcm47xx fallback */ |  | ||||||
| -	if (ret) |  | ||||||
| -		brcmf_fw_request_nvram_done(NULL, fwctx); |  | ||||||
| +	do { |  | ||||||
| +		if (++fwctx->curpos == fwctx->req->n_items) { |  | ||||||
| +			ret = 0; |  | ||||||
| +			goto done; |  | ||||||
| +		} |  | ||||||
| + |  | ||||||
| +		ret = brcmf_fw_request_next_item(fwctx, false); |  | ||||||
| +	} while (ret == -EAGAIN); |  | ||||||
| + |  | ||||||
|  	return; |  | ||||||
|   |  | ||||||
|  fail: |  | ||||||
| -	brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); |  | ||||||
| +	brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret, |  | ||||||
| +		  dev_name(fwctx->dev), cur->path); |  | ||||||
| +	brcmf_fw_free_request(fwctx->req); |  | ||||||
| +	fwctx->req = NULL; |  | ||||||
|  done: |  | ||||||
| -	fwctx->done(fwctx->dev, ret, fw, NULL, 0); |  | ||||||
| +	fwctx->done(fwctx->dev, ret, fwctx->req); |  | ||||||
|  	kfree(fwctx); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, |  | ||||||
| -				const char *code, const char *nvram, |  | ||||||
| -				void (*fw_cb)(struct device *dev, int err, |  | ||||||
| -					      const struct firmware *fw, |  | ||||||
| -					      void *nvram_image, u32 nvram_len), |  | ||||||
| -				u16 domain_nr, u16 bus_nr) |  | ||||||
| +static bool brcmf_fw_request_is_valid(struct brcmf_fw_request *req) |  | ||||||
| +{ |  | ||||||
| +	struct brcmf_fw_item *item; |  | ||||||
| +	int i; |  | ||||||
| + |  | ||||||
| +	if (!req->n_items) |  | ||||||
| +		return false; |  | ||||||
| + |  | ||||||
| +	for (i = 0, item = &req->items[0]; i < req->n_items; i++, item++) { |  | ||||||
| +		if (!item->path) |  | ||||||
| +			return false; |  | ||||||
| +	} |  | ||||||
| +	return true; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req, |  | ||||||
| +			   void (*fw_cb)(struct device *dev, int err, |  | ||||||
| +					 struct brcmf_fw_request *req)) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_fw *fwctx; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev)); |  | ||||||
| -	if (!fw_cb || !code) |  | ||||||
| +	if (!fw_cb) |  | ||||||
|  		return -EINVAL; |  | ||||||
|   |  | ||||||
| -	if ((flags & BRCMF_FW_REQUEST_NVRAM) && !nvram) |  | ||||||
| +	if (!brcmf_fw_request_is_valid(req)) |  | ||||||
|  		return -EINVAL; |  | ||||||
|   |  | ||||||
|  	fwctx = kzalloc(sizeof(*fwctx), GFP_KERNEL); |  | ||||||
| @@ -541,26 +621,11 @@ int brcmf_fw_get_firmwares_pcie(struct d |  | ||||||
|  		return -ENOMEM; |  | ||||||
|   |  | ||||||
|  	fwctx->dev = dev; |  | ||||||
| -	fwctx->flags = flags; |  | ||||||
| +	fwctx->req = req; |  | ||||||
|  	fwctx->done = fw_cb; |  | ||||||
| -	if (flags & BRCMF_FW_REQUEST_NVRAM) |  | ||||||
| -		fwctx->nvram_name = nvram; |  | ||||||
| -	fwctx->domain_nr = domain_nr; |  | ||||||
| -	fwctx->bus_nr = bus_nr; |  | ||||||
| - |  | ||||||
| -	return request_firmware_nowait(THIS_MODULE, true, code, dev, |  | ||||||
| -				       GFP_KERNEL, fwctx, |  | ||||||
| -				       brcmf_fw_request_code_done); |  | ||||||
| -} |  | ||||||
|   |  | ||||||
| -int brcmf_fw_get_firmwares(struct device *dev, u16 flags, |  | ||||||
| -			   const char *code, const char *nvram, |  | ||||||
| -			   void (*fw_cb)(struct device *dev, int err, |  | ||||||
| -					 const struct firmware *fw, |  | ||||||
| -					 void *nvram_image, u32 nvram_len)) |  | ||||||
| -{ |  | ||||||
| -	return brcmf_fw_get_firmwares_pcie(dev, flags, code, nvram, fw_cb, 0, |  | ||||||
| -					   0); |  | ||||||
| +	brcmf_fw_request_next_item(fwctx, true); |  | ||||||
| +	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static void brcmf_fw_get_full_name(char fw_name[BRCMF_FW_NAME_LEN], |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h |  | ||||||
| @@ -16,10 +16,7 @@ |  | ||||||
|  #ifndef BRCMFMAC_FIRMWARE_H |  | ||||||
|  #define BRCMFMAC_FIRMWARE_H |  | ||||||
|   |  | ||||||
| -#define BRCMF_FW_REQUEST		0x000F |  | ||||||
| -#define  BRCMF_FW_REQUEST_NVRAM		0x0001 |  | ||||||
| -#define BRCMF_FW_REQ_FLAGS		0x00F0 |  | ||||||
| -#define  BRCMF_FW_REQ_NV_OPTIONAL	0x0010 |  | ||||||
| +#define BRCMF_FW_REQF_OPTIONAL		0x0001 |  | ||||||
|   |  | ||||||
|  #define	BRCMF_FW_NAME_LEN		320 |  | ||||||
|   |  | ||||||
| @@ -54,21 +51,39 @@ int brcmf_fw_map_chip_to_name(u32 chip, |  | ||||||
|  			      u32 table_size, char fw_name[BRCMF_FW_NAME_LEN], |  | ||||||
|  			      char nvram_name[BRCMF_FW_NAME_LEN]); |  | ||||||
|  void brcmf_fw_nvram_free(void *nvram); |  | ||||||
| + |  | ||||||
| +enum brcmf_fw_type { |  | ||||||
| +	BRCMF_FW_TYPE_BINARY, |  | ||||||
| +	BRCMF_FW_TYPE_NVRAM |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +struct brcmf_fw_item { |  | ||||||
| +	const char *path; |  | ||||||
| +	enum brcmf_fw_type type; |  | ||||||
| +	u16 flags; |  | ||||||
| +	union { |  | ||||||
| +		const struct firmware *binary; |  | ||||||
| +		struct { |  | ||||||
| +			void *data; |  | ||||||
| +			u32 len; |  | ||||||
| +		} nv_data; |  | ||||||
| +	}; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +struct brcmf_fw_request { |  | ||||||
| +	u16 domain_nr; |  | ||||||
| +	u16 bus_nr; |  | ||||||
| +	u32 n_items; |  | ||||||
| +	struct brcmf_fw_item items[0]; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
|  /* |  | ||||||
|   * Request firmware(s) asynchronously. When the asynchronous request |  | ||||||
|   * fails it will not use the callback, but call device_release_driver() |  | ||||||
|   * instead which will call the driver .remove() callback. |  | ||||||
|   */ |  | ||||||
| -int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, |  | ||||||
| -				const char *code, const char *nvram, |  | ||||||
| -				void (*fw_cb)(struct device *dev, int err, |  | ||||||
| -					      const struct firmware *fw, |  | ||||||
| -					      void *nvram_image, u32 nvram_len), |  | ||||||
| -				u16 domain_nr, u16 bus_nr); |  | ||||||
| -int brcmf_fw_get_firmwares(struct device *dev, u16 flags, |  | ||||||
| -			   const char *code, const char *nvram, |  | ||||||
| +int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req, |  | ||||||
|  			   void (*fw_cb)(struct device *dev, int err, |  | ||||||
| -					 const struct firmware *fw, |  | ||||||
| -					 void *nvram_image, u32 nvram_len)); |  | ||||||
| +					 struct brcmf_fw_request *req)); |  | ||||||
|   |  | ||||||
|  #endif /* BRCMFMAC_FIRMWARE_H */ |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| @@ -1651,15 +1651,19 @@ static const struct brcmf_buscore_ops br |  | ||||||
|  	.write32 = brcmf_pcie_buscore_write32, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +#define BRCMF_PCIE_FW_CODE	0 |  | ||||||
| +#define BRCMF_PCIE_FW_NVRAM	1 |  | ||||||
| + |  | ||||||
|  static void brcmf_pcie_setup(struct device *dev, int ret, |  | ||||||
| -			     const struct firmware *fw, |  | ||||||
| -			     void *nvram, u32 nvram_len) |  | ||||||
| +			     struct brcmf_fw_request *fwreq) |  | ||||||
|  { |  | ||||||
| +	const struct firmware *fw; |  | ||||||
| +	void *nvram; |  | ||||||
|  	struct brcmf_bus *bus; |  | ||||||
|  	struct brcmf_pciedev *pcie_bus_dev; |  | ||||||
|  	struct brcmf_pciedev_info *devinfo; |  | ||||||
|  	struct brcmf_commonring **flowrings; |  | ||||||
| -	u32 i; |  | ||||||
| +	u32 i, nvram_len; |  | ||||||
|   |  | ||||||
|  	/* check firmware loading result */ |  | ||||||
|  	if (ret) |  | ||||||
| @@ -1670,6 +1674,11 @@ static void brcmf_pcie_setup(struct devi |  | ||||||
|  	devinfo = pcie_bus_dev->devinfo; |  | ||||||
|  	brcmf_pcie_attach(devinfo); |  | ||||||
|   |  | ||||||
| +	fw = fwreq->items[BRCMF_PCIE_FW_CODE].binary; |  | ||||||
| +	nvram = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.data; |  | ||||||
| +	nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len; |  | ||||||
| +	kfree(fwreq); |  | ||||||
| + |  | ||||||
|  	/* Some of the firmwares have the size of the memory of the device |  | ||||||
|  	 * defined inside the firmware. This is because part of the memory in |  | ||||||
|  	 * the device is shared and the devision is determined by FW. Parse |  | ||||||
| @@ -1730,6 +1739,7 @@ static int |  | ||||||
|  brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) |  | ||||||
|  { |  | ||||||
|  	int ret; |  | ||||||
| +	struct brcmf_fw_request *fwreq; |  | ||||||
|  	struct brcmf_pciedev_info *devinfo; |  | ||||||
|  	struct brcmf_pciedev *pcie_bus_dev; |  | ||||||
|  	struct brcmf_bus *bus; |  | ||||||
| @@ -1800,12 +1810,26 @@ brcmf_pcie_probe(struct pci_dev *pdev, c |  | ||||||
|  	if (ret) |  | ||||||
|  		goto fail_bus; |  | ||||||
|   |  | ||||||
| -	ret = brcmf_fw_get_firmwares_pcie(bus->dev, BRCMF_FW_REQUEST_NVRAM | |  | ||||||
| -						    BRCMF_FW_REQ_NV_OPTIONAL, |  | ||||||
| -					  devinfo->fw_name, devinfo->nvram_name, |  | ||||||
| -					  brcmf_pcie_setup, domain_nr, bus_nr); |  | ||||||
| +	fwreq = kzalloc(sizeof(*fwreq) + 2 * sizeof(struct brcmf_fw_item), |  | ||||||
| +			GFP_KERNEL); |  | ||||||
| +	if (!fwreq) { |  | ||||||
| +		ret = -ENOMEM; |  | ||||||
| +		goto fail_bus; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	fwreq->items[BRCMF_PCIE_FW_CODE].path = devinfo->fw_name; |  | ||||||
| +	fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY; |  | ||||||
| +	fwreq->items[BRCMF_PCIE_FW_NVRAM].path = devinfo->nvram_name; |  | ||||||
| +	fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; |  | ||||||
| +	fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL; |  | ||||||
| +	fwreq->n_items = 2; |  | ||||||
| +	fwreq->domain_nr = domain_nr; |  | ||||||
| +	fwreq->bus_nr = bus_nr; |  | ||||||
| +	ret = brcmf_fw_get_firmwares(bus->dev, fwreq, brcmf_pcie_setup); |  | ||||||
|  	if (ret == 0) |  | ||||||
|  		return 0; |  | ||||||
| + |  | ||||||
| +	kfree(fwreq); |  | ||||||
|  fail_bus: |  | ||||||
|  	kfree(bus->msgbuf); |  | ||||||
|  	kfree(bus); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -4031,14 +4031,19 @@ static const struct brcmf_bus_ops brcmf_ |  | ||||||
|  	.get_fwname = brcmf_sdio_get_fwname, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +#define BRCMF_SDIO_FW_CODE	0 |  | ||||||
| +#define BRCMF_SDIO_FW_NVRAM	1 |  | ||||||
| + |  | ||||||
|  static void brcmf_sdio_firmware_callback(struct device *dev, int err, |  | ||||||
| -					 const struct firmware *code, |  | ||||||
| -					 void *nvram, u32 nvram_len) |  | ||||||
| +					 struct brcmf_fw_request *fwreq) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_bus *bus_if = dev_get_drvdata(dev); |  | ||||||
|  	struct brcmf_sdio_dev *sdiod = bus_if->bus_priv.sdio; |  | ||||||
|  	struct brcmf_sdio *bus = sdiod->bus; |  | ||||||
|  	struct brcmf_core *core = bus->sdio_core; |  | ||||||
| +	const struct firmware *code; |  | ||||||
| +	void *nvram; |  | ||||||
| +	u32 nvram_len; |  | ||||||
|  	u8 saveclk; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); |  | ||||||
| @@ -4046,6 +4051,11 @@ static void brcmf_sdio_firmware_callback |  | ||||||
|  	if (err) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
| +	code = fwreq->items[BRCMF_SDIO_FW_CODE].binary; |  | ||||||
| +	nvram = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.data; |  | ||||||
| +	nvram_len = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.len; |  | ||||||
| +	kfree(fwreq); |  | ||||||
| + |  | ||||||
|  	/* try to download image and nvram to the dongle */ |  | ||||||
|  	bus->alp_only = true; |  | ||||||
|  	err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len); |  | ||||||
| @@ -4150,6 +4160,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru |  | ||||||
|  	int ret; |  | ||||||
|  	struct brcmf_sdio *bus; |  | ||||||
|  	struct workqueue_struct *wq; |  | ||||||
| +	struct brcmf_fw_request *fwreq; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
|   |  | ||||||
| @@ -4240,11 +4251,24 @@ struct brcmf_sdio *brcmf_sdio_probe(stru |  | ||||||
|  	if (ret) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
| -	ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM, |  | ||||||
| -				     sdiodev->fw_name, sdiodev->nvram_name, |  | ||||||
| +	fwreq = kzalloc(sizeof(fwreq) + 2 * sizeof(struct brcmf_fw_item), |  | ||||||
| +			GFP_KERNEL); |  | ||||||
| +	if (!fwreq) { |  | ||||||
| +		ret = -ENOMEM; |  | ||||||
| +		goto fail; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	fwreq->items[BRCMF_SDIO_FW_CODE].path = sdiodev->fw_name; |  | ||||||
| +	fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY; |  | ||||||
| +	fwreq->items[BRCMF_SDIO_FW_NVRAM].path = sdiodev->nvram_name; |  | ||||||
| +	fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; |  | ||||||
| +	fwreq->n_items = 2; |  | ||||||
| + |  | ||||||
| +	ret = brcmf_fw_get_firmwares(sdiodev->dev, fwreq, |  | ||||||
|  				     brcmf_sdio_firmware_callback); |  | ||||||
|  	if (ret != 0) { |  | ||||||
|  		brcmf_err("async firmware request failed: %d\n", ret); |  | ||||||
| +		kfree(fwreq); |  | ||||||
|  		goto fail; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| @@ -1155,18 +1155,23 @@ static const struct brcmf_bus_ops brcmf_ |  | ||||||
|  	.get_fwname = brcmf_usb_get_fwname, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +#define BRCMF_USB_FW_CODE	0 |  | ||||||
| + |  | ||||||
|  static void brcmf_usb_probe_phase2(struct device *dev, int ret, |  | ||||||
| -				   const struct firmware *fw, |  | ||||||
| -				   void *nvram, u32 nvlen) |  | ||||||
| +				   struct brcmf_fw_request *fwreq) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_bus *bus = dev_get_drvdata(dev); |  | ||||||
|  	struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo; |  | ||||||
| +	const struct firmware *fw; |  | ||||||
|   |  | ||||||
|  	if (ret) |  | ||||||
|  		goto error; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(USB, "Start fw downloading\n"); |  | ||||||
|   |  | ||||||
| +	fw = fwreq->items[BRCMF_USB_FW_CODE].binary; |  | ||||||
| +	kfree(fwreq); |  | ||||||
| + |  | ||||||
|  	ret = check_file(fw->data); |  | ||||||
|  	if (ret < 0) { |  | ||||||
|  		brcmf_err("invalid firmware\n"); |  | ||||||
| @@ -1200,6 +1205,7 @@ static int brcmf_usb_probe_cb(struct brc |  | ||||||
|  	struct brcmf_bus *bus = NULL; |  | ||||||
|  	struct brcmf_usbdev *bus_pub = NULL; |  | ||||||
|  	struct device *dev = devinfo->dev; |  | ||||||
| +	struct brcmf_fw_request *fwreq; |  | ||||||
|  	int ret; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(USB, "Enter\n"); |  | ||||||
| @@ -1250,11 +1256,22 @@ static int brcmf_usb_probe_cb(struct brc |  | ||||||
|  	if (ret) |  | ||||||
|  		goto fail; |  | ||||||
|   |  | ||||||
| +	fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item), |  | ||||||
| +			GFP_KERNEL); |  | ||||||
| +	if (!fwreq) { |  | ||||||
| +		ret = -ENOMEM; |  | ||||||
| +		goto fail; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name; |  | ||||||
| +	fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY; |  | ||||||
| +	fwreq->n_items = 1; |  | ||||||
| + |  | ||||||
|  	/* request firmware here */ |  | ||||||
| -	ret = brcmf_fw_get_firmwares(dev, 0, devinfo->fw_name, NULL, |  | ||||||
| -				     brcmf_usb_probe_phase2); |  | ||||||
| +	ret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2); |  | ||||||
|  	if (ret) { |  | ||||||
|  		brcmf_err("firmware request failed: %d\n", ret); |  | ||||||
| +		kfree(fwreq); |  | ||||||
|  		goto fail; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| @@ -1447,11 +1464,25 @@ static int brcmf_usb_reset_resume(struct |  | ||||||
|  { |  | ||||||
|  	struct usb_device *usb = interface_to_usbdev(intf); |  | ||||||
|  	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); |  | ||||||
| +	struct brcmf_fw_request *fwreq; |  | ||||||
| +	int ret; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(USB, "Enter\n"); |  | ||||||
|   |  | ||||||
| -	return brcmf_fw_get_firmwares(&usb->dev, 0, devinfo->fw_name, NULL, |  | ||||||
| -				      brcmf_usb_probe_phase2); |  | ||||||
| +	fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item), |  | ||||||
| +			GFP_KERNEL); |  | ||||||
| +	if (!fwreq) |  | ||||||
| +		return -ENOMEM; |  | ||||||
| + |  | ||||||
| +	fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name; |  | ||||||
| +	fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY; |  | ||||||
| +	fwreq->n_items = 1; |  | ||||||
| + |  | ||||||
| +	ret = brcmf_fw_get_firmwares(&usb->dev, fwreq, brcmf_usb_probe_phase2); |  | ||||||
| +	if (ret < 0) |  | ||||||
| +		kfree(fwreq); |  | ||||||
| + |  | ||||||
| +	return ret; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  #define BRCMF_USB_DEVICE(dev_id)	\ |  | ||||||
| @@ -1,328 +0,0 @@ | |||||||
| From 2baa3aaee27f137b8db9a9224d0fe9b281d28e34 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 22 Mar 2018 21:28:27 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: introduce brcmf_fw_alloc_request() function |  | ||||||
|  |  | ||||||
| The function brcmf_fw_alloc_request() takes a list of required files |  | ||||||
| and allocated the struct brcmf_fw_request instance accordingly. The |  | ||||||
| request can be modified by the caller before being passed to the |  | ||||||
| brcmf_fw_request_firmwares() function. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/firmware.c         | 58 ++++++++++++++++++++++ |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/firmware.h         | 11 ++++ |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/pcie.c    | 58 ++++++++++++---------- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 38 ++++++++------ |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 42 +++++++++------- |  | ||||||
|  5 files changed, 147 insertions(+), 60 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| @@ -688,3 +688,61 @@ int brcmf_fw_map_chip_to_name(u32 chip, |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +struct brcmf_fw_request * |  | ||||||
| +brcmf_fw_alloc_request(u32 chip, u32 chiprev, |  | ||||||
| +		       struct brcmf_firmware_mapping mapping_table[], |  | ||||||
| +		       u32 table_size, struct brcmf_fw_name *fwnames, |  | ||||||
| +		       u32 n_fwnames) |  | ||||||
| +{ |  | ||||||
| +	struct brcmf_fw_request *fwreq; |  | ||||||
| +	char chipname[12]; |  | ||||||
| +	const char *mp_path; |  | ||||||
| +	u32 i, j; |  | ||||||
| +	char end; |  | ||||||
| +	size_t reqsz; |  | ||||||
| + |  | ||||||
| +	for (i = 0; i < table_size; i++) { |  | ||||||
| +		if (mapping_table[i].chipid == chip && |  | ||||||
| +		    mapping_table[i].revmask & BIT(chiprev)) |  | ||||||
| +			break; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	if (i == table_size) { |  | ||||||
| +		brcmf_err("Unknown chipid %d [%d]\n", chip, chiprev); |  | ||||||
| +		return NULL; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	reqsz = sizeof(*fwreq) + n_fwnames * sizeof(struct brcmf_fw_item); |  | ||||||
| +	fwreq = kzalloc(reqsz, GFP_KERNEL); |  | ||||||
| +	if (!fwreq) |  | ||||||
| +		return NULL; |  | ||||||
| + |  | ||||||
| +	brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname)); |  | ||||||
| + |  | ||||||
| +	brcmf_info("using %s for chip %s\n", |  | ||||||
| +		   mapping_table[i].fw_base, chipname); |  | ||||||
| + |  | ||||||
| +	mp_path = brcmf_mp_global.firmware_path; |  | ||||||
| +	end = mp_path[strlen(mp_path) - 1]; |  | ||||||
| +	fwreq->n_items = n_fwnames; |  | ||||||
| + |  | ||||||
| +	for (j = 0; j < n_fwnames; j++) { |  | ||||||
| +		fwreq->items[j].path = fwnames[j].path; |  | ||||||
| +		/* check if firmware path is provided by module parameter */ |  | ||||||
| +		if (brcmf_mp_global.firmware_path[0] != '\0') { |  | ||||||
| +			strlcpy(fwnames[j].path, mp_path, |  | ||||||
| +				BRCMF_FW_NAME_LEN); |  | ||||||
| + |  | ||||||
| +			if (end != '/') { |  | ||||||
| +				strlcat(fwnames[j].path, "/", |  | ||||||
| +					BRCMF_FW_NAME_LEN); |  | ||||||
| +			} |  | ||||||
| +		} |  | ||||||
| +		brcmf_fw_get_full_name(fwnames[j].path, |  | ||||||
| +				       mapping_table[i].fw_base, |  | ||||||
| +				       fwnames[j].extension); |  | ||||||
| +		fwreq->items[j].path = fwnames[j].path; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +	return fwreq; |  | ||||||
| +} |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h |  | ||||||
| @@ -77,6 +77,17 @@ struct brcmf_fw_request { |  | ||||||
|  	struct brcmf_fw_item items[0]; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +struct brcmf_fw_name { |  | ||||||
| +	const char *extension; |  | ||||||
| +	char *path; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +struct brcmf_fw_request * |  | ||||||
| +brcmf_fw_alloc_request(u32 chip, u32 chiprev, |  | ||||||
| +		       struct brcmf_firmware_mapping mapping_table[], |  | ||||||
| +		       u32 table_size, struct brcmf_fw_name *fwnames, |  | ||||||
| +		       u32 n_fwnames); |  | ||||||
| + |  | ||||||
|  /* |  | ||||||
|   * Request firmware(s) asynchronously. When the asynchronous request |  | ||||||
|   * fails it will not use the callback, but call device_release_driver() |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| @@ -1735,6 +1735,31 @@ fail: |  | ||||||
|  	device_release_driver(dev); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static struct brcmf_fw_request * |  | ||||||
| +brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo) |  | ||||||
| +{ |  | ||||||
| +	struct brcmf_fw_request *fwreq; |  | ||||||
| +	struct brcmf_fw_name fwnames[] = { |  | ||||||
| +		{ ".bin", devinfo->fw_name }, |  | ||||||
| +		{ ".txt", devinfo->nvram_name }, |  | ||||||
| +	}; |  | ||||||
| + |  | ||||||
| +	fwreq = brcmf_fw_alloc_request(devinfo->ci->chip, devinfo->ci->chiprev, |  | ||||||
| +				       brcmf_pcie_fwnames, |  | ||||||
| +				       ARRAY_SIZE(brcmf_pcie_fwnames), |  | ||||||
| +				       fwnames, ARRAY_SIZE(fwnames)); |  | ||||||
| +	if (!fwreq) |  | ||||||
| +		return NULL; |  | ||||||
| + |  | ||||||
| +	fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY; |  | ||||||
| +	fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; |  | ||||||
| +	fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL; |  | ||||||
| +	fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus); |  | ||||||
| +	fwreq->bus_nr = devinfo->pdev->bus->number; |  | ||||||
| + |  | ||||||
| +	return fwreq; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static int |  | ||||||
|  brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) |  | ||||||
|  { |  | ||||||
| @@ -1743,13 +1768,8 @@ brcmf_pcie_probe(struct pci_dev *pdev, c |  | ||||||
|  	struct brcmf_pciedev_info *devinfo; |  | ||||||
|  	struct brcmf_pciedev *pcie_bus_dev; |  | ||||||
|  	struct brcmf_bus *bus; |  | ||||||
| -	u16 domain_nr; |  | ||||||
| -	u16 bus_nr; |  | ||||||
|   |  | ||||||
| -	domain_nr = pci_domain_nr(pdev->bus) + 1; |  | ||||||
| -	bus_nr = pdev->bus->number; |  | ||||||
| -	brcmf_dbg(PCIE, "Enter %x:%x (%d/%d)\n", pdev->vendor, pdev->device, |  | ||||||
| -		  domain_nr, bus_nr); |  | ||||||
| +	brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device); |  | ||||||
|   |  | ||||||
|  	ret = -ENOMEM; |  | ||||||
|  	devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); |  | ||||||
| @@ -1803,33 +1823,19 @@ brcmf_pcie_probe(struct pci_dev *pdev, c |  | ||||||
|  	bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot); |  | ||||||
|  	dev_set_drvdata(&pdev->dev, bus); |  | ||||||
|   |  | ||||||
| -	ret = brcmf_fw_map_chip_to_name(devinfo->ci->chip, devinfo->ci->chiprev, |  | ||||||
| -					brcmf_pcie_fwnames, |  | ||||||
| -					ARRAY_SIZE(brcmf_pcie_fwnames), |  | ||||||
| -					devinfo->fw_name, devinfo->nvram_name); |  | ||||||
| -	if (ret) |  | ||||||
| -		goto fail_bus; |  | ||||||
| - |  | ||||||
| -	fwreq = kzalloc(sizeof(*fwreq) + 2 * sizeof(struct brcmf_fw_item), |  | ||||||
| -			GFP_KERNEL); |  | ||||||
| +	fwreq = brcmf_pcie_prepare_fw_request(devinfo); |  | ||||||
|  	if (!fwreq) { |  | ||||||
|  		ret = -ENOMEM; |  | ||||||
|  		goto fail_bus; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	fwreq->items[BRCMF_PCIE_FW_CODE].path = devinfo->fw_name; |  | ||||||
| -	fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY; |  | ||||||
| -	fwreq->items[BRCMF_PCIE_FW_NVRAM].path = devinfo->nvram_name; |  | ||||||
| -	fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; |  | ||||||
| -	fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL; |  | ||||||
| -	fwreq->n_items = 2; |  | ||||||
| -	fwreq->domain_nr = domain_nr; |  | ||||||
| -	fwreq->bus_nr = bus_nr; |  | ||||||
|  	ret = brcmf_fw_get_firmwares(bus->dev, fwreq, brcmf_pcie_setup); |  | ||||||
| -	if (ret == 0) |  | ||||||
| -		return 0; |  | ||||||
| +	if (ret < 0) { |  | ||||||
| +		kfree(fwreq); |  | ||||||
| +		goto fail_bus; |  | ||||||
| +	} |  | ||||||
| +	return 0; |  | ||||||
|   |  | ||||||
| -	kfree(fwreq); |  | ||||||
|  fail_bus: |  | ||||||
|  	kfree(bus->msgbuf); |  | ||||||
|  	kfree(bus); |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -4155,6 +4155,28 @@ fail: |  | ||||||
|  	device_release_driver(dev); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static struct brcmf_fw_request * |  | ||||||
| +brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus) |  | ||||||
| +{ |  | ||||||
| +	struct brcmf_fw_request *fwreq; |  | ||||||
| +	struct brcmf_fw_name fwnames[] = { |  | ||||||
| +		{ ".bin", bus->sdiodev->fw_name }, |  | ||||||
| +		{ ".txt", bus->sdiodev->nvram_name }, |  | ||||||
| +	}; |  | ||||||
| + |  | ||||||
| +	fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev, |  | ||||||
| +				       brcmf_sdio_fwnames, |  | ||||||
| +				       ARRAY_SIZE(brcmf_sdio_fwnames), |  | ||||||
| +				       fwnames, ARRAY_SIZE(fwnames)); |  | ||||||
| +	if (!fwreq) |  | ||||||
| +		return NULL; |  | ||||||
| + |  | ||||||
| +	fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY; |  | ||||||
| +	fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; |  | ||||||
| + |  | ||||||
| +	return fwreq; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) |  | ||||||
|  { |  | ||||||
|  	int ret; |  | ||||||
| @@ -4244,26 +4266,12 @@ struct brcmf_sdio *brcmf_sdio_probe(stru |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(INFO, "completed!!\n"); |  | ||||||
|   |  | ||||||
| -	ret = brcmf_fw_map_chip_to_name(bus->ci->chip, bus->ci->chiprev, |  | ||||||
| -					brcmf_sdio_fwnames, |  | ||||||
| -					ARRAY_SIZE(brcmf_sdio_fwnames), |  | ||||||
| -					sdiodev->fw_name, sdiodev->nvram_name); |  | ||||||
| -	if (ret) |  | ||||||
| -		goto fail; |  | ||||||
| - |  | ||||||
| -	fwreq = kzalloc(sizeof(fwreq) + 2 * sizeof(struct brcmf_fw_item), |  | ||||||
| -			GFP_KERNEL); |  | ||||||
| +	fwreq = brcmf_sdio_prepare_fw_request(bus); |  | ||||||
|  	if (!fwreq) { |  | ||||||
|  		ret = -ENOMEM; |  | ||||||
|  		goto fail; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	fwreq->items[BRCMF_SDIO_FW_CODE].path = sdiodev->fw_name; |  | ||||||
| -	fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY; |  | ||||||
| -	fwreq->items[BRCMF_SDIO_FW_NVRAM].path = sdiodev->nvram_name; |  | ||||||
| -	fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; |  | ||||||
| -	fwreq->n_items = 2; |  | ||||||
| - |  | ||||||
|  	ret = brcmf_fw_get_firmwares(sdiodev->dev, fwreq, |  | ||||||
|  				     brcmf_sdio_firmware_callback); |  | ||||||
|  	if (ret != 0) { |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| @@ -1200,6 +1200,27 @@ error: |  | ||||||
|  	device_release_driver(dev); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static struct brcmf_fw_request * |  | ||||||
| +brcmf_usb_prepare_fw_request(struct brcmf_usbdev_info *devinfo) |  | ||||||
| +{ |  | ||||||
| +	struct brcmf_fw_request *fwreq; |  | ||||||
| +	struct brcmf_fw_name fwnames[] = { |  | ||||||
| +		{ ".bin", devinfo->fw_name }, |  | ||||||
| +	}; |  | ||||||
| + |  | ||||||
| +	fwreq = brcmf_fw_alloc_request(devinfo->bus_pub.devid, |  | ||||||
| +				       devinfo->bus_pub.chiprev, |  | ||||||
| +				       brcmf_usb_fwnames, |  | ||||||
| +				       ARRAY_SIZE(brcmf_usb_fwnames), |  | ||||||
| +				       fwnames, ARRAY_SIZE(fwnames)); |  | ||||||
| +	if (!fwreq) |  | ||||||
| +		return NULL; |  | ||||||
| + |  | ||||||
| +	fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY; |  | ||||||
| + |  | ||||||
| +	return fwreq; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_bus *bus = NULL; |  | ||||||
| @@ -1249,24 +1270,12 @@ static int brcmf_usb_probe_cb(struct brc |  | ||||||
|  	bus->chip = bus_pub->devid; |  | ||||||
|  	bus->chiprev = bus_pub->chiprev; |  | ||||||
|   |  | ||||||
| -	ret = brcmf_fw_map_chip_to_name(bus_pub->devid, bus_pub->chiprev, |  | ||||||
| -					brcmf_usb_fwnames, |  | ||||||
| -					ARRAY_SIZE(brcmf_usb_fwnames), |  | ||||||
| -					devinfo->fw_name, NULL); |  | ||||||
| -	if (ret) |  | ||||||
| -		goto fail; |  | ||||||
| - |  | ||||||
| -	fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item), |  | ||||||
| -			GFP_KERNEL); |  | ||||||
| +	fwreq = brcmf_usb_prepare_fw_request(devinfo); |  | ||||||
|  	if (!fwreq) { |  | ||||||
|  		ret = -ENOMEM; |  | ||||||
|  		goto fail; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name; |  | ||||||
| -	fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY; |  | ||||||
| -	fwreq->n_items = 1; |  | ||||||
| - |  | ||||||
|  	/* request firmware here */ |  | ||||||
|  	ret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2); |  | ||||||
|  	if (ret) { |  | ||||||
| @@ -1469,15 +1478,10 @@ static int brcmf_usb_reset_resume(struct |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(USB, "Enter\n"); |  | ||||||
|   |  | ||||||
| -	fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item), |  | ||||||
| -			GFP_KERNEL); |  | ||||||
| +	fwreq = brcmf_usb_prepare_fw_request(devinfo); |  | ||||||
|  	if (!fwreq) |  | ||||||
|  		return -ENOMEM; |  | ||||||
|   |  | ||||||
| -	fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name; |  | ||||||
| -	fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY; |  | ||||||
| -	fwreq->n_items = 1; |  | ||||||
| - |  | ||||||
|  	ret = brcmf_fw_get_firmwares(&usb->dev, fwreq, brcmf_usb_probe_phase2); |  | ||||||
|  	if (ret < 0) |  | ||||||
|  		kfree(fwreq); |  | ||||||
| @@ -1,231 +0,0 @@ | |||||||
| From bf7a7b37f6ef5090a2bae7e7ae23cd26b741cca4 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 22 Mar 2018 21:28:28 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: add extension to .get_fwname() callbacks |  | ||||||
|  |  | ||||||
| This changes the bus layer api by having the caller provide an |  | ||||||
| extension. With this the callback can use brcmf_fw_alloc_request() |  | ||||||
| to get the needed firmware name. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  6 +-- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/common.c  | 43 +++------------------- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/pcie.c    | 27 +++++++------- |  | ||||||
|  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 26 +++++++------ |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 27 ++++++++------ |  | ||||||
|  5 files changed, 51 insertions(+), 78 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  | ||||||
| @@ -88,7 +88,7 @@ struct brcmf_bus_ops { |  | ||||||
|  	void (*wowl_config)(struct device *dev, bool enabled); |  | ||||||
|  	size_t (*get_ramsize)(struct device *dev); |  | ||||||
|  	int (*get_memdump)(struct device *dev, void *data, size_t len); |  | ||||||
| -	int (*get_fwname)(struct device *dev, uint chip, uint chiprev, |  | ||||||
| +	int (*get_fwname)(struct device *dev, const char *ext, |  | ||||||
|  			  unsigned char *fw_name); |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| @@ -228,10 +228,10 @@ int brcmf_bus_get_memdump(struct brcmf_b |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static inline |  | ||||||
| -int brcmf_bus_get_fwname(struct brcmf_bus *bus, uint chip, uint chiprev, |  | ||||||
| +int brcmf_bus_get_fwname(struct brcmf_bus *bus, const char *ext, |  | ||||||
|  			 unsigned char *fw_name) |  | ||||||
|  { |  | ||||||
| -	return bus->ops->get_fwname(bus->dev, chip, chiprev, fw_name); |  | ||||||
| +	return bus->ops->get_fwname(bus->dev, ext, fw_name); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /* |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c |  | ||||||
| @@ -129,42 +129,9 @@ static int brcmf_c_download(struct brcmf |  | ||||||
|  	return err; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name) |  | ||||||
| -{ |  | ||||||
| -	struct brcmf_bus *bus = ifp->drvr->bus_if; |  | ||||||
| -	u8 fw_name[BRCMF_FW_NAME_LEN]; |  | ||||||
| -	u8 *ptr; |  | ||||||
| -	size_t len; |  | ||||||
| -	s32 err; |  | ||||||
| - |  | ||||||
| -	memset(fw_name, 0, BRCMF_FW_NAME_LEN); |  | ||||||
| -	err = brcmf_bus_get_fwname(bus, bus->chip, bus->chiprev, fw_name); |  | ||||||
| -	if (err) { |  | ||||||
| -		brcmf_err("get firmware name failed (%d)\n", err); |  | ||||||
| -		goto done; |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
| -	/* generate CLM blob file name */ |  | ||||||
| -	ptr = strrchr(fw_name, '.'); |  | ||||||
| -	if (!ptr) { |  | ||||||
| -		err = -ENOENT; |  | ||||||
| -		goto done; |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
| -	len = ptr - fw_name + 1; |  | ||||||
| -	if (len + strlen(".clm_blob") > BRCMF_FW_NAME_LEN) { |  | ||||||
| -		err = -E2BIG; |  | ||||||
| -	} else { |  | ||||||
| -		strlcpy(clm_name, fw_name, len); |  | ||||||
| -		strlcat(clm_name, ".clm_blob", BRCMF_FW_NAME_LEN); |  | ||||||
| -	} |  | ||||||
| -done: |  | ||||||
| -	return err; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
|  static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) |  | ||||||
|  { |  | ||||||
| -	struct device *dev = ifp->drvr->bus_if->dev; |  | ||||||
| +	struct brcmf_bus *bus = ifp->drvr->bus_if; |  | ||||||
|  	struct brcmf_dload_data_le *chunk_buf; |  | ||||||
|  	const struct firmware *clm = NULL; |  | ||||||
|  	u8 clm_name[BRCMF_FW_NAME_LEN]; |  | ||||||
| @@ -177,16 +144,16 @@ static int brcmf_c_process_clm_blob(stru |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(TRACE, "Enter\n"); |  | ||||||
|   |  | ||||||
| -	memset(clm_name, 0, BRCMF_FW_NAME_LEN); |  | ||||||
| -	err = brcmf_c_get_clm_name(ifp, clm_name); |  | ||||||
| +	memset(clm_name, 0, sizeof(clm_name)); |  | ||||||
| +	err = brcmf_bus_get_fwname(bus, ".clm_blob", clm_name); |  | ||||||
|  	if (err) { |  | ||||||
|  		brcmf_err("get CLM blob file name failed (%d)\n", err); |  | ||||||
|  		return err; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	err = request_firmware(&clm, clm_name, dev); |  | ||||||
| +	err = request_firmware(&clm, clm_name, bus->dev); |  | ||||||
|  	if (err) { |  | ||||||
| -		brcmf_info("no clm_blob available(err=%d), device may have limited channels available\n", |  | ||||||
| +		brcmf_info("no clm_blob available (err=%d), device may have limited channels available\n", |  | ||||||
|  			   err); |  | ||||||
|  		return 0; |  | ||||||
|  	} |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| @@ -1350,23 +1350,24 @@ static int brcmf_pcie_get_memdump(struct |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_pcie_get_fwname(struct device *dev, u32 chip, u32 chiprev, |  | ||||||
| -				 u8 *fw_name) |  | ||||||
| +static |  | ||||||
| +int brcmf_pcie_get_fwname(struct device *dev, const char *ext, u8 *fw_name) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_bus *bus_if = dev_get_drvdata(dev); |  | ||||||
| -	struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie; |  | ||||||
| -	struct brcmf_pciedev_info *devinfo = buspub->devinfo; |  | ||||||
| -	int ret = 0; |  | ||||||
| +	struct brcmf_fw_request *fwreq; |  | ||||||
| +	struct brcmf_fw_name fwnames[] = { |  | ||||||
| +		{ ext, fw_name }, |  | ||||||
| +	}; |  | ||||||
|   |  | ||||||
| -	if (devinfo->fw_name[0] != '\0') |  | ||||||
| -		strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN); |  | ||||||
| -	else |  | ||||||
| -		ret = brcmf_fw_map_chip_to_name(chip, chiprev, |  | ||||||
| -						brcmf_pcie_fwnames, |  | ||||||
| -						ARRAY_SIZE(brcmf_pcie_fwnames), |  | ||||||
| -						fw_name, NULL); |  | ||||||
| +	fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev, |  | ||||||
| +				       brcmf_pcie_fwnames, |  | ||||||
| +				       ARRAY_SIZE(brcmf_pcie_fwnames), |  | ||||||
| +				       fwnames, ARRAY_SIZE(fwnames)); |  | ||||||
| +	if (!fwreq) |  | ||||||
| +		return -ENOMEM; |  | ||||||
|   |  | ||||||
| -	return ret; |  | ||||||
| +	kfree(fwreq); |  | ||||||
| +	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -4000,22 +4000,24 @@ brcmf_sdio_watchdog(unsigned long data) |  | ||||||
|  	} |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_sdio_get_fwname(struct device *dev, u32 chip, u32 chiprev, |  | ||||||
| -				 u8 *fw_name) |  | ||||||
| +static |  | ||||||
| +int brcmf_sdio_get_fwname(struct device *dev, const char *ext, u8 *fw_name) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_bus *bus_if = dev_get_drvdata(dev); |  | ||||||
| -	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |  | ||||||
| -	int ret = 0; |  | ||||||
| +	struct brcmf_fw_request *fwreq; |  | ||||||
| +	struct brcmf_fw_name fwnames[] = { |  | ||||||
| +		{ ext, fw_name }, |  | ||||||
| +	}; |  | ||||||
|   |  | ||||||
| -	if (sdiodev->fw_name[0] != '\0') |  | ||||||
| -		strlcpy(fw_name, sdiodev->fw_name, BRCMF_FW_NAME_LEN); |  | ||||||
| -	else |  | ||||||
| -		ret = brcmf_fw_map_chip_to_name(chip, chiprev, |  | ||||||
| -						brcmf_sdio_fwnames, |  | ||||||
| -						ARRAY_SIZE(brcmf_sdio_fwnames), |  | ||||||
| -						fw_name, NULL); |  | ||||||
| +	fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev, |  | ||||||
| +				       brcmf_sdio_fwnames, |  | ||||||
| +				       ARRAY_SIZE(brcmf_sdio_fwnames), |  | ||||||
| +				       fwnames, ARRAY_SIZE(fwnames)); |  | ||||||
| +	if (!fwreq) |  | ||||||
| +		return -ENOMEM; |  | ||||||
|   |  | ||||||
| -	return ret; |  | ||||||
| +	kfree(fwreq); |  | ||||||
| +	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| @@ -1128,21 +1128,24 @@ static void brcmf_usb_wowl_config(struct |  | ||||||
|  		device_set_wakeup_enable(devinfo->dev, false); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int brcmf_usb_get_fwname(struct device *dev, u32 chip, u32 chiprev, |  | ||||||
| -				u8 *fw_name) |  | ||||||
| +static |  | ||||||
| +int brcmf_usb_get_fwname(struct device *dev, const char *ext, u8 *fw_name) |  | ||||||
|  { |  | ||||||
| -	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |  | ||||||
| -	int ret = 0; |  | ||||||
| +	struct brcmf_bus *bus = dev_get_drvdata(dev); |  | ||||||
| +	struct brcmf_fw_request *fwreq; |  | ||||||
| +	struct brcmf_fw_name fwnames[] = { |  | ||||||
| +		{ ext, fw_name }, |  | ||||||
| +	}; |  | ||||||
|   |  | ||||||
| -	if (devinfo->fw_name[0] != '\0') |  | ||||||
| -		strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN); |  | ||||||
| -	else |  | ||||||
| -		ret = brcmf_fw_map_chip_to_name(chip, chiprev, |  | ||||||
| -						brcmf_usb_fwnames, |  | ||||||
| -						ARRAY_SIZE(brcmf_usb_fwnames), |  | ||||||
| -						fw_name, NULL); |  | ||||||
| +	fwreq = brcmf_fw_alloc_request(bus->chip, bus->chiprev, |  | ||||||
| +				       brcmf_usb_fwnames, |  | ||||||
| +				       ARRAY_SIZE(brcmf_usb_fwnames), |  | ||||||
| +				       fwnames, ARRAY_SIZE(fwnames)); |  | ||||||
| +	if (!fwreq) |  | ||||||
| +		return -ENOMEM; |  | ||||||
|   |  | ||||||
| -	return ret; |  | ||||||
| +	kfree(fwreq); |  | ||||||
| +	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static const struct brcmf_bus_ops brcmf_usb_bus_ops = { |  | ||||||
| @@ -1,92 +0,0 @@ | |||||||
| From 18c2b20e276e04476a3350b4a92c1dfad725d45d Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 22 Mar 2018 21:28:29 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: get rid of brcmf_fw_map_chip_to_name() |  | ||||||
|  |  | ||||||
| The function is no longer used so removing it. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/firmware.c         | 53 ---------------------- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/firmware.h         |  4 -- |  | ||||||
|  2 files changed, 57 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| @@ -635,59 +635,6 @@ static void brcmf_fw_get_full_name(char |  | ||||||
|  	strlcat(fw_name, extension, BRCMF_FW_NAME_LEN); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev, |  | ||||||
| -			      struct brcmf_firmware_mapping mapping_table[], |  | ||||||
| -			      u32 table_size, char fw_name[BRCMF_FW_NAME_LEN], |  | ||||||
| -			      char nvram_name[BRCMF_FW_NAME_LEN]) |  | ||||||
| -{ |  | ||||||
| -	char chipname[12]; |  | ||||||
| -	u32 i; |  | ||||||
| -	char end; |  | ||||||
| - |  | ||||||
| -	for (i = 0; i < table_size; i++) { |  | ||||||
| -		if (mapping_table[i].chipid == chip && |  | ||||||
| -		    mapping_table[i].revmask & BIT(chiprev)) |  | ||||||
| -			break; |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
| -	if (i == table_size) { |  | ||||||
| -		brcmf_err("Unknown chipid %d [%d]\n", chip, chiprev); |  | ||||||
| -		return -ENODEV; |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
| -	brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname)); |  | ||||||
| - |  | ||||||
| -	/* check if firmware path is provided by module parameter */ |  | ||||||
| -	if (brcmf_mp_global.firmware_path[0] != '\0') { |  | ||||||
| -		if (fw_name) |  | ||||||
| -			strlcpy(fw_name, brcmf_mp_global.firmware_path, |  | ||||||
| -				BRCMF_FW_NAME_LEN); |  | ||||||
| -		if (nvram_name) |  | ||||||
| -			strlcpy(nvram_name, brcmf_mp_global.firmware_path, |  | ||||||
| -				BRCMF_FW_NAME_LEN); |  | ||||||
| - |  | ||||||
| -		end = brcmf_mp_global.firmware_path[ |  | ||||||
| -				strlen(brcmf_mp_global.firmware_path) - 1]; |  | ||||||
| -		if (end != '/') { |  | ||||||
| -			if (fw_name) |  | ||||||
| -				strlcat(fw_name, "/", BRCMF_FW_NAME_LEN); |  | ||||||
| -			if (nvram_name) |  | ||||||
| -				strlcat(nvram_name, "/", BRCMF_FW_NAME_LEN); |  | ||||||
| -		} |  | ||||||
| -	} |  | ||||||
| - |  | ||||||
| -	brcmf_info("using %s for chip %s\n", |  | ||||||
| -		   mapping_table[i].fw_base, chipname); |  | ||||||
| -	if (fw_name) |  | ||||||
| -		brcmf_fw_get_full_name(fw_name, |  | ||||||
| -				       mapping_table[i].fw_base, ".bin"); |  | ||||||
| -	if (nvram_name) |  | ||||||
| -		brcmf_fw_get_full_name(nvram_name, |  | ||||||
| -				       mapping_table[i].fw_base, ".txt"); |  | ||||||
| - |  | ||||||
| -	return 0; |  | ||||||
| -} |  | ||||||
| - |  | ||||||
|  struct brcmf_fw_request * |  | ||||||
|  brcmf_fw_alloc_request(u32 chip, u32 chiprev, |  | ||||||
|  		       struct brcmf_firmware_mapping mapping_table[], |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h |  | ||||||
| @@ -46,10 +46,6 @@ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw |  | ||||||
|  #define BRCMF_FW_ENTRY(chipid, mask, name) \ |  | ||||||
|  	{ chipid, mask, BRCM_ ## name ## _FIRMWARE_BASENAME } |  | ||||||
|   |  | ||||||
| -int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev, |  | ||||||
| -			      struct brcmf_firmware_mapping mapping_table[], |  | ||||||
| -			      u32 table_size, char fw_name[BRCMF_FW_NAME_LEN], |  | ||||||
| -			      char nvram_name[BRCMF_FW_NAME_LEN]); |  | ||||||
|  void brcmf_fw_nvram_free(void *nvram); |  | ||||||
|   |  | ||||||
|  enum brcmf_fw_type { |  | ||||||
| @@ -1,44 +0,0 @@ | |||||||
| From bf291b7247e53f52a4236c0b55a5df046d6177df Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 22 Mar 2018 21:28:30 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: get rid of brcmf_fw_get_full_name() |  | ||||||
|  |  | ||||||
| The function was pretty minimal and now it is called only from one |  | ||||||
| place so just get rid of it. |  | ||||||
|  |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/firmware.c    | 14 ++++---------- |  | ||||||
|  1 file changed, 4 insertions(+), 10 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| @@ -628,13 +628,6 @@ int brcmf_fw_get_firmwares(struct device |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static void brcmf_fw_get_full_name(char fw_name[BRCMF_FW_NAME_LEN], |  | ||||||
| -				   const char *fw_base, const char *extension) |  | ||||||
| -{ |  | ||||||
| -	strlcat(fw_name, fw_base, BRCMF_FW_NAME_LEN); |  | ||||||
| -	strlcat(fw_name, extension, BRCMF_FW_NAME_LEN); |  | ||||||
| -} |  | ||||||
| - |  | ||||||
|  struct brcmf_fw_request * |  | ||||||
|  brcmf_fw_alloc_request(u32 chip, u32 chiprev, |  | ||||||
|  		       struct brcmf_firmware_mapping mapping_table[], |  | ||||||
| @@ -685,9 +678,10 @@ brcmf_fw_alloc_request(u32 chip, u32 chi |  | ||||||
|  					BRCMF_FW_NAME_LEN); |  | ||||||
|  			} |  | ||||||
|  		} |  | ||||||
| -		brcmf_fw_get_full_name(fwnames[j].path, |  | ||||||
| -				       mapping_table[i].fw_base, |  | ||||||
| -				       fwnames[j].extension); |  | ||||||
| +		strlcat(fwnames[j].path, mapping_table[i].fw_base, |  | ||||||
| +			BRCMF_FW_NAME_LEN); |  | ||||||
| +		strlcat(fwnames[j].path, fwnames[j].extension, |  | ||||||
| +			BRCMF_FW_NAME_LEN); |  | ||||||
|  		fwreq->items[j].path = fwnames[j].path; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| @@ -1,23 +0,0 @@ | |||||||
| From 48eaee3f272a5bfe6986d07c51f6975d3c2f74d1 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 22 Mar 2018 21:28:31 +0100 |  | ||||||
| Subject: [PATCH] brcmfmac: add kerneldoc for struct brcmf_bus::msgbuf |  | ||||||
|  |  | ||||||
| This field did not have kerneldoc description so adding it now. |  | ||||||
|  |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 1 + |  | ||||||
|  1 file changed, 1 insertion(+) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  | ||||||
| @@ -140,6 +140,7 @@ struct brcmf_bus_stats { |  | ||||||
|   * @always_use_fws_queue: bus wants use queue also when fwsignal is inactive. |  | ||||||
|   * @wowl_supported: is wowl supported by bus driver. |  | ||||||
|   * @chiprev: revision of the dongle chip. |  | ||||||
| + * @msgbuf: msgbuf protocol parameters provided by bus layer. |  | ||||||
|   */ |  | ||||||
|  struct brcmf_bus { |  | ||||||
|  	union { |  | ||||||
| @@ -1,81 +0,0 @@ | |||||||
| From 0b5c0305e57ca940713bcb2b202fd2b412c62f31 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Tue, 3 Apr 2018 10:18:15 +0200 |  | ||||||
| Subject: [PATCH] brcmfmac: fix firmware request processing if nvram load fails |  | ||||||
|  |  | ||||||
| When nvram loading fails a double free occurred. Fix this and reorg the |  | ||||||
| code a little. |  | ||||||
|  |  | ||||||
| Fixes: d09ae51a4b67 ("brcmfmac: pass struct in brcmf_fw_get_firmwares()") |  | ||||||
| Reported-by: Dan Carpenter <dan.carpenter@oracle.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/firmware.c         | 36 ++++++++++++---------- |  | ||||||
|  1 file changed, 20 insertions(+), 16 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| @@ -459,7 +459,7 @@ static void brcmf_fw_free_request(struct |  | ||||||
|  	kfree(req); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) |  | ||||||
| +static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) |  | ||||||
|  { |  | ||||||
|  	struct brcmf_fw *fwctx = ctx; |  | ||||||
|  	struct brcmf_fw_item *cur; |  | ||||||
| @@ -498,13 +498,10 @@ static void brcmf_fw_request_nvram_done( |  | ||||||
|  	brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length); |  | ||||||
|  	cur->nv_data.data = nvram; |  | ||||||
|  	cur->nv_data.len = nvram_length; |  | ||||||
| -	return; |  | ||||||
| +	return 0; |  | ||||||
|   |  | ||||||
|  fail: |  | ||||||
| -	brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); |  | ||||||
| -	fwctx->done(fwctx->dev, -ENOENT, NULL); |  | ||||||
| -	brcmf_fw_free_request(fwctx->req); |  | ||||||
| -	kfree(fwctx); |  | ||||||
| +	return -ENOENT; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async) |  | ||||||
| @@ -553,20 +550,27 @@ static void brcmf_fw_request_done(const |  | ||||||
|  	brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path, |  | ||||||
|  		  fw ? "" : "not "); |  | ||||||
|   |  | ||||||
| -	if (fw) { |  | ||||||
| -		if (cur->type == BRCMF_FW_TYPE_BINARY) |  | ||||||
| -			cur->binary = fw; |  | ||||||
| -		else if (cur->type == BRCMF_FW_TYPE_NVRAM) |  | ||||||
| -			brcmf_fw_request_nvram_done(fw, fwctx); |  | ||||||
| -		else |  | ||||||
| -			release_firmware(fw); |  | ||||||
| -	} else if (cur->type == BRCMF_FW_TYPE_NVRAM) { |  | ||||||
| -		brcmf_fw_request_nvram_done(NULL, fwctx); |  | ||||||
| -	} else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) { |  | ||||||
| +	if (!fw) |  | ||||||
|  		ret = -ENOENT; |  | ||||||
| + |  | ||||||
| +	switch (cur->type) { |  | ||||||
| +	case BRCMF_FW_TYPE_NVRAM: |  | ||||||
| +		ret = brcmf_fw_request_nvram_done(fw, fwctx); |  | ||||||
| +		break; |  | ||||||
| +	case BRCMF_FW_TYPE_BINARY: |  | ||||||
| +		cur->binary = fw; |  | ||||||
| +		break; |  | ||||||
| +	default: |  | ||||||
| +		/* something fishy here so bail out early */ |  | ||||||
| +		brcmf_err("unknown fw type: %d\n", cur->type); |  | ||||||
| +		release_firmware(fw); |  | ||||||
| +		ret = -EINVAL; |  | ||||||
|  		goto fail; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	if (ret < 0 && !(cur->flags & BRCMF_FW_REQF_OPTIONAL)) |  | ||||||
| +		goto fail; |  | ||||||
| + |  | ||||||
|  	do { |  | ||||||
|  		if (++fwctx->curpos == fwctx->req->n_items) { |  | ||||||
|  			ret = 0; |  | ||||||
| @@ -1,48 +0,0 @@ | |||||||
| From 1f589e2510d5df1192dca7c089103a2cbd028101 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Dan Haab <dhaab@luxul.com> |  | ||||||
| Date: Tue, 3 Apr 2018 10:21:56 +0200 |  | ||||||
| Subject: [PATCH] brcmfmac: add support for BCM4366E chipset |  | ||||||
|  |  | ||||||
| BCM4366E is a wireless chipset with a BCM43664 ChipCommon. It's |  | ||||||
| supported by the same firmware as 4366c0. |  | ||||||
|  |  | ||||||
| Signed-off-by: Dan Haab <dan.haab@luxul.com> |  | ||||||
| [arend: rebase patch and remove unnecessary definition] |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c       | 1 + |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c       | 1 + |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 1 + |  | ||||||
|  3 files changed, 3 insertions(+) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c |  | ||||||
| @@ -689,6 +689,7 @@ static u32 brcmf_chip_tcm_rambase(struct |  | ||||||
|  	case BRCM_CC_43525_CHIP_ID: |  | ||||||
|  	case BRCM_CC_4365_CHIP_ID: |  | ||||||
|  	case BRCM_CC_4366_CHIP_ID: |  | ||||||
| +	case BRCM_CC_43664_CHIP_ID: |  | ||||||
|  		return 0x200000; |  | ||||||
|  	case CY_CC_4373_CHIP_ID: |  | ||||||
|  		return 0x160000; |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| @@ -75,6 +75,7 @@ static struct brcmf_firmware_mapping brc |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFF0, 4365C), |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B), |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C), |  | ||||||
| +	BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C), |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h |  | ||||||
| @@ -57,6 +57,7 @@ |  | ||||||
|  #define BRCM_CC_43602_CHIP_ID		43602 |  | ||||||
|  #define BRCM_CC_4365_CHIP_ID		0x4365 |  | ||||||
|  #define BRCM_CC_4366_CHIP_ID		0x4366 |  | ||||||
| +#define BRCM_CC_43664_CHIP_ID		43664 |  | ||||||
|  #define BRCM_CC_4371_CHIP_ID		0x4371 |  | ||||||
|  #define CY_CC_4373_CHIP_ID		0x4373 |  | ||||||
|   |  | ||||||
| @@ -1,34 +0,0 @@ | |||||||
| From cb746e47837ad0f35c8ae28e9aacc8eb07916d2a Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 26 Apr 2018 12:16:47 +0200 |  | ||||||
| Subject: [PATCH] brcmfmac: check p2pdev mac address uniqueness |  | ||||||
|  |  | ||||||
| The mac address for p2pdev must be different from the primary interface |  | ||||||
| due to firmware requirement. Add an explicit check for this requirement |  | ||||||
| if user-space provides a mac address. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 7 +++++++ |  | ||||||
|  1 file changed, 7 insertions(+) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  | ||||||
| @@ -2073,6 +2073,13 @@ static struct wireless_dev *brcmf_p2p_cr |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; |  | ||||||
| + |  | ||||||
| +	/* firmware requires unique mac address for p2pdev interface */ |  | ||||||
| +	if (addr && ether_addr_equal(addr, pri_ifp->mac_addr)) { |  | ||||||
| +		brcmf_err("discovery vif must be different from primary interface\n"); |  | ||||||
| +		return ERR_PTR(-EINVAL); |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	brcmf_p2p_generate_bss_mac(p2p, addr); |  | ||||||
|  	brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr); |  | ||||||
|   |  | ||||||
| @@ -1,76 +0,0 @@ | |||||||
| From 7742fce4c007141617dab9bcb90034b3c0fe2347 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Date: Thu, 26 Apr 2018 12:18:35 +0200 |  | ||||||
| Subject: [PATCH] brcmfmac: reports boottime_ns while informing bss |  | ||||||
|  |  | ||||||
| Provides a timestamp in bss information so user space can see when the |  | ||||||
| bss info was updated. Since tsf is not available from the dongle events |  | ||||||
| boottime is reported instead. |  | ||||||
|  |  | ||||||
| Reported-by: Dmitry Shmidt <dimitrysh@google.com> |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 26 +++++++++++----------- |  | ||||||
|  1 file changed, 13 insertions(+), 13 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| @@ -2728,7 +2728,6 @@ static s32 brcmf_inform_single_bss(struc |  | ||||||
|  				   struct brcmf_bss_info_le *bi) |  | ||||||
|  { |  | ||||||
|  	struct wiphy *wiphy = cfg_to_wiphy(cfg); |  | ||||||
| -	struct ieee80211_channel *notify_channel; |  | ||||||
|  	struct cfg80211_bss *bss; |  | ||||||
|  	struct ieee80211_supported_band *band; |  | ||||||
|  	struct brcmu_chan ch; |  | ||||||
| @@ -2738,7 +2737,7 @@ static s32 brcmf_inform_single_bss(struc |  | ||||||
|  	u16 notify_interval; |  | ||||||
|  	u8 *notify_ie; |  | ||||||
|  	size_t notify_ielen; |  | ||||||
| -	s32 notify_signal; |  | ||||||
| +	struct cfg80211_inform_bss bss_data = { 0 }; |  | ||||||
|   |  | ||||||
|  	if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) { |  | ||||||
|  		brcmf_err("Bss info is larger than buffer. Discarding\n"); |  | ||||||
| @@ -2758,27 +2757,28 @@ static s32 brcmf_inform_single_bss(struc |  | ||||||
|  		band = wiphy->bands[NL80211_BAND_5GHZ]; |  | ||||||
|   |  | ||||||
|  	freq = ieee80211_channel_to_frequency(channel, band->band); |  | ||||||
| -	notify_channel = ieee80211_get_channel(wiphy, freq); |  | ||||||
| +	bss_data.chan = ieee80211_get_channel(wiphy, freq); |  | ||||||
| +	bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20; |  | ||||||
| +	bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime()); |  | ||||||
|   |  | ||||||
|  	notify_capability = le16_to_cpu(bi->capability); |  | ||||||
|  	notify_interval = le16_to_cpu(bi->beacon_period); |  | ||||||
|  	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); |  | ||||||
|  	notify_ielen = le32_to_cpu(bi->ie_length); |  | ||||||
| -	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100; |  | ||||||
| +	bss_data.signal = (s16)le16_to_cpu(bi->RSSI) * 100; |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID); |  | ||||||
|  	brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq); |  | ||||||
|  	brcmf_dbg(CONN, "Capability: %X\n", notify_capability); |  | ||||||
|  	brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval); |  | ||||||
| -	brcmf_dbg(CONN, "Signal: %d\n", notify_signal); |  | ||||||
| +	brcmf_dbg(CONN, "Signal: %d\n", bss_data.signal); |  | ||||||
|   |  | ||||||
| -	bss = cfg80211_inform_bss(wiphy, notify_channel, |  | ||||||
| -				  CFG80211_BSS_FTYPE_UNKNOWN, |  | ||||||
| -				  (const u8 *)bi->BSSID, |  | ||||||
| -				  0, notify_capability, |  | ||||||
| -				  notify_interval, notify_ie, |  | ||||||
| -				  notify_ielen, notify_signal, |  | ||||||
| -				  GFP_KERNEL); |  | ||||||
| +	bss = cfg80211_inform_bss_data(wiphy, &bss_data, |  | ||||||
| +				       CFG80211_BSS_FTYPE_UNKNOWN, |  | ||||||
| +				       (const u8 *)bi->BSSID, |  | ||||||
| +				       0, notify_capability, |  | ||||||
| +				       notify_interval, notify_ie, |  | ||||||
| +				       notify_ielen, GFP_KERNEL); |  | ||||||
|   |  | ||||||
|  	if (!bss) |  | ||||||
|  		return -ENOMEM; |  | ||||||
| @@ -1,43 +0,0 @@ | |||||||
| From aed14219067ab96e5eeb7730e9bceed10d9be989 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Date: Thu, 26 Apr 2018 12:16:48 +0200 |  | ||||||
| Subject: [PATCH] brcmfmac: use nl80211_band directly to get ieee80211 channel |  | ||||||
|  |  | ||||||
| The enum nl80211_band used to retrieve wiphy->bands is the same as |  | ||||||
| wiphy->bands->band which is checked by wiphy_register(). So it can be used |  | ||||||
| directly as parameter of ieee80211_channel_to_frequency(). |  | ||||||
|  |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 8 ++++---- |  | ||||||
|  1 file changed, 4 insertions(+), 4 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |  | ||||||
| @@ -2729,7 +2729,7 @@ static s32 brcmf_inform_single_bss(struc |  | ||||||
|  { |  | ||||||
|  	struct wiphy *wiphy = cfg_to_wiphy(cfg); |  | ||||||
|  	struct cfg80211_bss *bss; |  | ||||||
| -	struct ieee80211_supported_band *band; |  | ||||||
| +	enum nl80211_band band; |  | ||||||
|  	struct brcmu_chan ch; |  | ||||||
|  	u16 channel; |  | ||||||
|  	u32 freq; |  | ||||||
| @@ -2752,11 +2752,11 @@ static s32 brcmf_inform_single_bss(struc |  | ||||||
|  	channel = bi->ctl_ch; |  | ||||||
|   |  | ||||||
|  	if (channel <= CH_MAX_2G_CHANNEL) |  | ||||||
| -		band = wiphy->bands[NL80211_BAND_2GHZ]; |  | ||||||
| +		band = NL80211_BAND_2GHZ; |  | ||||||
|  	else |  | ||||||
| -		band = wiphy->bands[NL80211_BAND_5GHZ]; |  | ||||||
| +		band = NL80211_BAND_5GHZ; |  | ||||||
|   |  | ||||||
| -	freq = ieee80211_channel_to_frequency(channel, band->band); |  | ||||||
| +	freq = ieee80211_channel_to_frequency(channel, band); |  | ||||||
|  	bss_data.chan = ieee80211_get_channel(wiphy, freq); |  | ||||||
|  	bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20; |  | ||||||
|  	bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime()); |  | ||||||
| @@ -1,76 +0,0 @@ | |||||||
| From ff68c9f9c06d1fd437c8f90fc05ca28c47f7d85e Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Arend Van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Date: Thu, 26 Apr 2018 12:16:49 +0200 |  | ||||||
| Subject: [PATCH] brcmfmac: constify firmware mapping tables |  | ||||||
|  |  | ||||||
| The information in the firmware mapping does not need to be modified |  | ||||||
| so it can be static const. |  | ||||||
|  |  | ||||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> |  | ||||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> |  | ||||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 2 +- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h | 2 +- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c     | 2 +- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c     | 2 +- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c      | 2 +- |  | ||||||
|  5 files changed, 5 insertions(+), 5 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |  | ||||||
| @@ -634,7 +634,7 @@ int brcmf_fw_get_firmwares(struct device |  | ||||||
|   |  | ||||||
|  struct brcmf_fw_request * |  | ||||||
|  brcmf_fw_alloc_request(u32 chip, u32 chiprev, |  | ||||||
| -		       struct brcmf_firmware_mapping mapping_table[], |  | ||||||
| +		       const struct brcmf_firmware_mapping mapping_table[], |  | ||||||
|  		       u32 table_size, struct brcmf_fw_name *fwnames, |  | ||||||
|  		       u32 n_fwnames) |  | ||||||
|  { |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h |  | ||||||
| @@ -80,7 +80,7 @@ struct brcmf_fw_name { |  | ||||||
|   |  | ||||||
|  struct brcmf_fw_request * |  | ||||||
|  brcmf_fw_alloc_request(u32 chip, u32 chiprev, |  | ||||||
| -		       struct brcmf_firmware_mapping mapping_table[], |  | ||||||
| +		       const struct brcmf_firmware_mapping mapping_table[], |  | ||||||
|  		       u32 table_size, struct brcmf_fw_name *fwnames, |  | ||||||
|  		       u32 n_fwnames); |  | ||||||
|   |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| @@ -59,7 +59,7 @@ BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie" |  | ||||||
|  BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie"); |  | ||||||
|  BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); |  | ||||||
|   |  | ||||||
| -static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { |  | ||||||
| +static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602), |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_43465_CHIP_ID, 0xFFFFFFF0, 4366C), |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C), |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |  | ||||||
| @@ -619,7 +619,7 @@ BRCMF_FW_DEF(4354, "brcmfmac4354-sdio"); |  | ||||||
|  BRCMF_FW_DEF(4356, "brcmfmac4356-sdio"); |  | ||||||
|  BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); |  | ||||||
|   |  | ||||||
| -static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { |  | ||||||
| +static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0), |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4), |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  | ||||||
| @@ -52,7 +52,7 @@ BRCMF_FW_DEF(43242A, "brcmfmac43242a"); |  | ||||||
|  BRCMF_FW_DEF(43569, "brcmfmac43569"); |  | ||||||
|  BRCMF_FW_DEF(4373, "brcmfmac4373"); |  | ||||||
|   |  | ||||||
| -static struct brcmf_firmware_mapping brcmf_usb_fwnames[] = { |  | ||||||
| +static const struct brcmf_firmware_mapping brcmf_usb_fwnames[] = { |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_43235_CHIP_ID, 0x00000008, 43236B), |  | ||||||
|  	BRCMF_FW_ENTRY(BRCM_CC_43236_CHIP_ID, 0x00000008, 43236B), |  | ||||||
| @@ -1,74 +0,0 @@ | |||||||
| From 84ad327d18debe19b8d509059b61db445d048b02 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Date: Thu, 26 Apr 2018 12:16:50 +0200 |  | ||||||
| Subject: [PATCH] brcmfmac: add hostready indication |  | ||||||
|  |  | ||||||
| A hostready signal is introduced to inform firmware through mailbox |  | ||||||
| doorbell1 when common ring initialized or D3 exited. |  | ||||||
|  |  | ||||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Franky Lin <franky.lin@broadcom.com> |  | ||||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> |  | ||||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |  | ||||||
| --- |  | ||||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 14 ++++++++++++-- |  | ||||||
|  1 file changed, 12 insertions(+), 2 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c |  | ||||||
| @@ -105,7 +105,8 @@ static const struct brcmf_firmware_mappi |  | ||||||
|  #define BRCMF_PCIE_PCIE2REG_MAILBOXMASK		0x4C |  | ||||||
|  #define BRCMF_PCIE_PCIE2REG_CONFIGADDR		0x120 |  | ||||||
|  #define BRCMF_PCIE_PCIE2REG_CONFIGDATA		0x124 |  | ||||||
| -#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX		0x140 |  | ||||||
| +#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0	0x140 |  | ||||||
| +#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1	0x144 |  | ||||||
|   |  | ||||||
|  #define BRCMF_PCIE2_INTA			0x01 |  | ||||||
|  #define BRCMF_PCIE2_INTB			0x02 |  | ||||||
| @@ -140,6 +141,7 @@ static const struct brcmf_firmware_mappi |  | ||||||
|  #define BRCMF_PCIE_SHARED_VERSION_MASK		0x00FF |  | ||||||
|  #define BRCMF_PCIE_SHARED_DMA_INDEX		0x10000 |  | ||||||
|  #define BRCMF_PCIE_SHARED_DMA_2B_IDX		0x100000 |  | ||||||
| +#define BRCMF_PCIE_SHARED_HOSTRDY_DB1		0x10000000 |  | ||||||
|   |  | ||||||
|  #define BRCMF_PCIE_FLAGS_HTOD_SPLIT		0x4000 |  | ||||||
|  #define BRCMF_PCIE_FLAGS_DTOH_SPLIT		0x8000 |  | ||||||
| @@ -782,6 +784,12 @@ static void brcmf_pcie_intr_enable(struc |  | ||||||
|  			       BRCMF_PCIE_MB_INT_FN0_1); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static void brcmf_pcie_hostready(struct brcmf_pciedev_info *devinfo) |  | ||||||
| +{ |  | ||||||
| +	if (devinfo->shared.flags & BRCMF_PCIE_SHARED_HOSTRDY_DB1) |  | ||||||
| +		brcmf_pcie_write_reg32(devinfo, |  | ||||||
| +				       BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1, 1); |  | ||||||
| +} |  | ||||||
|   |  | ||||||
|  static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg) |  | ||||||
|  { |  | ||||||
| @@ -924,7 +932,7 @@ static int brcmf_pcie_ring_mb_ring_bell( |  | ||||||
|   |  | ||||||
|  	brcmf_dbg(PCIE, "RING !\n"); |  | ||||||
|  	/* Any arbitrary value will do, lets use 1 */ |  | ||||||
| -	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX, 1); |  | ||||||
| +	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0, 1); |  | ||||||
|   |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
| @@ -1728,6 +1736,7 @@ static void brcmf_pcie_setup(struct devi |  | ||||||
|  	init_waitqueue_head(&devinfo->mbdata_resp_wait); |  | ||||||
|   |  | ||||||
|  	brcmf_pcie_intr_enable(devinfo); |  | ||||||
| +	brcmf_pcie_hostready(devinfo); |  | ||||||
|  	if (brcmf_attach(&devinfo->pdev->dev, devinfo->settings) == 0) |  | ||||||
|  		return; |  | ||||||
|   |  | ||||||
| @@ -1950,6 +1959,7 @@ static int brcmf_pcie_pm_leave_D3(struct |  | ||||||
|  		brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); |  | ||||||
|  		brcmf_bus_change_state(bus, BRCMF_BUS_UP); |  | ||||||
|  		brcmf_pcie_intr_enable(devinfo); |  | ||||||
| +		brcmf_pcie_hostready(devinfo); |  | ||||||
|  		return 0; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	 John Crispin
					John Crispin