From patchwork Fri Sep 16 16:02:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Russell King \(Oracle\)" X-Patchwork-Id: 606568 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E7BD6ECAAA1 for ; Fri, 16 Sep 2022 16:02:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229765AbiIPQCf (ORCPT ); Fri, 16 Sep 2022 12:02:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229639AbiIPQCe (ORCPT ); Fri, 16 Sep 2022 12:02:34 -0400 Received: from pandora.armlinux.org.uk (pandora.armlinux.org.uk [IPv6:2001:4d48:ad52:32c8:5054:ff:fe00:142]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2442EB5309; Fri, 16 Sep 2022 09:02:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=armlinux.org.uk; s=pandora-2019; h=Date:Sender:Message-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:Subject:Cc:To:From:References: In-Reply-To:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=vuN8zb6d1gSMbyOMfzwYTsEwMhMACez3BjzbPzroncs=; b=u9nKpqmP5jAG3qk5q+RQhhwEN2 jV+LVQl7kr6Jh5cVT5NK2CC86y458UA6WER0gb4IKYwozP75qezQjoHWH5jvGHuoz5623g7UWuMkD rif40LKPWr0tYcnj5evZG6lo9xvVjO0z7ooaw16QjM466GdcV6JYiLAp36QCEHcb0aDry+wO2/jzk MSYOYhxmCWsFPytGoEyrSAYSEF8xAiKq/thVgXHBBg4GApb2Nocb6WWKhyemp24owr+3KWKd278ON G+nZRnvhYbAt/rlYEUc4NXA2Nj+WZXbVjQ3mU5/VMOACmgR4JWoGsWIN1mxJgRR5VNnfqsGLkIVvX wO4ZgQNg==; Received: from e0022681537dd.dyn.armlinux.org.uk ([fd8f:7570:feb6:1:222:68ff:fe15:37dd]:59238 helo=rmk-PC.armlinux.org.uk) by pandora.armlinux.org.uk with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1oZDnO-0006t3-Kn; Fri, 16 Sep 2022 17:02:26 +0100 Received: from rmk by rmk-PC.armlinux.org.uk with local (Exim 4.94.2) (envelope-from ) id 1oZDnO-0077Zy-18; Fri, 16 Sep 2022 17:02:26 +0100 In-Reply-To: References: From: Russell King (Oracle) To: Arend van Spriel , Franky Lin , Hante Meuleman Cc: Alyssa Rosenzweig , asahi@lists.linux.dev, brcm80211-dev-list.pdl@broadcom.com, "David S. Miller" , devicetree@vger.kernel.org, Eric Dumazet , Hector Martin , Jakub Kicinski , Kalle Valo , Krzysztof Kozlowski , linux-arm-kernel@lists.infradead.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org, Paolo Abeni , "Rafa__ Mi__ecki" , Rob Herring , SHA-cyfmac-dev-list@infineon.com, Sven Peter , van Spriel Subject: [PATCH wireless-next v3 01/12] dt-bindings: net: bcm4329-fmac: Add Apple properties & chips MIME-Version: 1.0 MIME-Version: 1.0 Content-Disposition: inline Message-Id: Sender: Russell King Date: Fri, 16 Sep 2022 17:02:26 +0100 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Hector Martin This binding is currently used for SDIO devices, but these chips are also used as PCIe devices on DT platforms and may be represented in the DT. Re-use the existing binding and add chip compatibles used by Apple T2 and M1 platforms (the T2 ones are not known to be used in DT platforms, but we might as well document them). Then, add properties required for firmware selection and calibration on M1 machines. Reviewed-by: Linus Walleij Signed-off-by: Hector Martin Reviewed-by: Mark Kettenis Reviewed-by: Rob Herring Reviewed-by: Alvin Šipraga Signed-off-by: Russell King (Oracle) --- .../net/wireless/brcm,bcm4329-fmac.yaml | 39 +++++++++++++++++-- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml index 53b4153d9bfc..fec1cc9b9a08 100644 --- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml +++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/net/wireless/brcm,bcm4329-fmac.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Broadcom BCM4329 family fullmac wireless SDIO devices +title: Broadcom BCM4329 family fullmac wireless SDIO/PCIE devices maintainers: - Arend van Spriel @@ -41,11 +41,17 @@ title: Broadcom BCM4329 family fullmac wireless SDIO devices - cypress,cyw4373-fmac - cypress,cyw43012-fmac - const: brcm,bcm4329-fmac - - const: brcm,bcm4329-fmac + - enum: + - brcm,bcm4329-fmac + - pci14e4,43dc # BCM4355 + - pci14e4,4464 # BCM4364 + - pci14e4,4488 # BCM4377 + - pci14e4,4425 # BCM4378 + - pci14e4,4433 # BCM4387 reg: - description: SDIO function number for the device, for most cases - this will be 1. + description: SDIO function number for the device (for most cases + this will be 1) or PCI device identifier. interrupts: maxItems: 1 @@ -85,6 +91,31 @@ title: Broadcom BCM4329 family fullmac wireless SDIO devices takes precedence. type: boolean + brcm,cal-blob: + $ref: /schemas/types.yaml#/definitions/uint8-array + description: A per-device calibration blob for the Wi-Fi radio. This + should be filled in by the bootloader from platform configuration + data, if necessary, and will be uploaded to the device if present. + + brcm,board-type: + $ref: /schemas/types.yaml#/definitions/string + description: Overrides the board type, which is normally the compatible of + the root node. This can be used to decouple the overall system board or + device name from the board type for WiFi purposes, which is used to + construct firmware and NVRAM configuration filenames, allowing for + multiple devices that share the same module or characteristics for the + WiFi subsystem to share the same firmware/NVRAM files. On Apple platforms, + this should be the Apple module-instance codename prefixed by "apple,", + e.g. "apple,honshu". + + apple,antenna-sku: + $ref: /schemas/types.yaml#/definitions/string + description: Antenna SKU used to identify a specific antenna configuration + on Apple platforms. This is use to build firmware filenames, to allow + platforms with different antenna configs to have different firmware and/or + NVRAM. This would normally be filled in by the bootloader from platform + configuration data. + required: - compatible - reg From patchwork Fri Sep 16 16:02:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Russell King \(Oracle\)" X-Patchwork-Id: 606567 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F5D8C6FA82 for ; Fri, 16 Sep 2022 16:02:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230096AbiIPQCx (ORCPT ); Fri, 16 Sep 2022 12:02:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38192 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230088AbiIPQCt (ORCPT ); Fri, 16 Sep 2022 12:02:49 -0400 Received: from pandora.armlinux.org.uk (pandora.armlinux.org.uk [IPv6:2001:4d48:ad52:32c8:5054:ff:fe00:142]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 116A9B56F1; Fri, 16 Sep 2022 09:02:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=armlinux.org.uk; s=pandora-2019; h=Date:Sender:Message-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:Subject:Cc:To:From:References: In-Reply-To:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=S4LJWk4FUfZNK981aGEGsCvpbcJ/8fkAkrq/NZryMvg=; b=fQ/NXWAqSLUN6KLAlNBhSno1/L YXtTiYS5wdNnWvOSQnSQN0r39TzVVFH38YVizyVJrss/bb30PRolK6FG5pgxAzQZDjMoZH6T6kT2L EZtDGrBzqNJiFtIfRynCmZDW9Ko69zmGV8yXYwWmVSx4Rt/mhE04fwaoG69giT1Z3qOjqtydK/gzk 6ED98XH80APlsICLsCd+Vzv84QrCLbLOmS9xuWdpmjkPwvEH/vvG8XtKkXSO42+90o3E4pNMAdEuT j4wZj/XQO4fh5u8wMNrKfo2IHfrpXfjK0KgRpefIN0mXdNXo4QOcT024+mBB8/4M7LDSfZTpjQAEp /iuIG7KQ==; Received: from e0022681537dd.dyn.armlinux.org.uk ([fd8f:7570:feb6:1:222:68ff:fe15:37dd]:60452 helo=rmk-PC.armlinux.org.uk) by pandora.armlinux.org.uk with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1oZDnY-0006tW-U7; Fri, 16 Sep 2022 17:02:36 +0100 Received: from rmk by rmk-PC.armlinux.org.uk with local (Exim 4.94.2) (envelope-from ) id 1oZDnY-0077aA-8f; Fri, 16 Sep 2022 17:02:36 +0100 In-Reply-To: References: From: Russell King (Oracle) To: Arend van Spriel , Franky Lin , Hante Meuleman Cc: Alyssa Rosenzweig , asahi@lists.linux.dev, brcm80211-dev-list.pdl@broadcom.com, "David S. Miller" , devicetree@vger.kernel.org, Eric Dumazet , Hector Martin , Jakub Kicinski , Kalle Valo , Krzysztof Kozlowski , linux-arm-kernel@lists.infradead.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org, Paolo Abeni , "Rafa__ Mi__ecki" , Rob Herring , SHA-cyfmac-dev-list@infineon.com, Sven Peter Subject: [PATCH wireless-next v3 03/12] brcmfmac: pcie/sdio/usb: Get CLM blob via standard firmware mechanism MIME-Version: 1.0 MIME-Version: 1.0 Content-Disposition: inline Message-Id: Sender: Russell King Date: Fri, 16 Sep 2022 17:02:36 +0100 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Hector Martin Now that the firmware fetcher can handle per-board CLM files, load the CLM blob alongside the other firmware files and change the bus API to just return the existing blob, instead of fetching the filename. This enables per-board CLM blobs, which are required on Apple platforms. Acked-by: Linus Walleij Reviewed-by: Arend van Spriel Signed-off-by: Hector Martin Reviewed-by: Alvin Šipraga Signed-off-by: Russell King (Oracle) --- .../broadcom/brcm80211/brcmfmac/bus.h | 19 ++++++--- .../broadcom/brcm80211/brcmfmac/common.c | 12 +----- .../broadcom/brcm80211/brcmfmac/pcie.c | 39 ++++++++++++------- .../broadcom/brcm80211/brcmfmac/sdio.c | 36 ++++++++++------- .../broadcom/brcm80211/brcmfmac/sdio.h | 2 + .../broadcom/brcm80211/brcmfmac/usb.c | 23 +++-------- 6 files changed, 69 insertions(+), 62 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h index ae5af76e2568..2208ab3aa795 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h @@ -6,6 +6,8 @@ #ifndef BRCMFMAC_BUS_H #define BRCMFMAC_BUS_H +#include +#include #include "debug.h" /* IDs of the 6 default common rings of msgbuf protocol */ @@ -34,6 +36,11 @@ enum brcmf_bus_protocol_type { BRCMF_PROTO_MSGBUF }; +/* Firmware blobs that may be available */ +enum brcmf_blob_type { + BRCMF_BLOB_CLM, +}; + struct brcmf_mp_device; struct brcmf_bus_dcmd { @@ -60,7 +67,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. + * @get_blob: obtain a firmware blob. * * This structure provides an abstract interface towards the * bus specific driver. For control messages to common driver @@ -77,8 +84,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, const char *ext, - unsigned char *fw_name); + int (*get_blob)(struct device *dev, const struct firmware **fw, + enum brcmf_blob_type type); void (*debugfs_create)(struct device *dev); int (*reset)(struct device *dev); }; @@ -220,10 +227,10 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len) } static inline -int brcmf_bus_get_fwname(struct brcmf_bus *bus, const char *ext, - unsigned char *fw_name) +int brcmf_bus_get_blob(struct brcmf_bus *bus, const struct firmware **fw, + enum brcmf_blob_type type) { - return bus->ops->get_fwname(bus->dev, ext, fw_name); + return bus->ops->get_blob(bus->dev, fw, type); } static inline diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index 372deeb69477..74020fa10065 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -123,7 +123,6 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) struct brcmf_bus *bus = drvr->bus_if; 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; @@ -133,15 +132,8 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) brcmf_dbg(TRACE, "Enter\n"); - memset(clm_name, 0, sizeof(clm_name)); - err = brcmf_bus_get_fwname(bus, ".clm_blob", clm_name); - if (err) { - bphy_err(drvr, "get CLM blob file name failed (%d)\n", err); - return err; - } - - err = firmware_request_nowarn(&clm, clm_name, bus->dev); - if (err) { + err = brcmf_bus_get_blob(bus, &clm, BRCMF_BLOB_CLM); + if (err || !clm) { brcmf_info("no clm_blob available (err=%d), device may have limited channels available\n", err); return 0; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index 97f0f13dfe50..ec73d2620ec9 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -66,6 +66,7 @@ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.txt"); /* per-board firmware binaries */ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.bin"); +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.clm_blob"); static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { BRCMF_FW_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602), @@ -261,6 +262,8 @@ struct brcmf_pciedev_info { struct pci_dev *pdev; char fw_name[BRCMF_FW_NAME_LEN]; char nvram_name[BRCMF_FW_NAME_LEN]; + char clm_name[BRCMF_FW_NAME_LEN]; + const struct firmware *clm_fw; void __iomem *regs; void __iomem *tcm; u32 ram_base; @@ -1382,23 +1385,25 @@ static int brcmf_pcie_get_memdump(struct device *dev, void *data, size_t len) return 0; } -static -int brcmf_pcie_get_fwname(struct device *dev, const char *ext, u8 *fw_name) +static int brcmf_pcie_get_blob(struct device *dev, const struct firmware **fw, + enum brcmf_blob_type type) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_fw_request *fwreq; - struct brcmf_fw_name fwnames[] = { - { ext, fw_name }, - }; + struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie; + struct brcmf_pciedev_info *devinfo = buspub->devinfo; - 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; + switch (type) { + case BRCMF_BLOB_CLM: + *fw = devinfo->clm_fw; + devinfo->clm_fw = NULL; + break; + default: + return -ENOENT; + } + + if (!*fw) + return -ENOENT; - kfree(fwreq); return 0; } @@ -1445,7 +1450,7 @@ static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { .wowl_config = brcmf_pcie_wowl_config, .get_ramsize = brcmf_pcie_get_ramsize, .get_memdump = brcmf_pcie_get_memdump, - .get_fwname = brcmf_pcie_get_fwname, + .get_blob = brcmf_pcie_get_blob, .reset = brcmf_pcie_reset, }; @@ -1731,6 +1736,7 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { #define BRCMF_PCIE_FW_CODE 0 #define BRCMF_PCIE_FW_NVRAM 1 +#define BRCMF_PCIE_FW_CLM 2 static void brcmf_pcie_setup(struct device *dev, int ret, struct brcmf_fw_request *fwreq) @@ -1755,6 +1761,7 @@ static void brcmf_pcie_setup(struct device *dev, int ret, 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; + devinfo->clm_fw = fwreq->items[BRCMF_PCIE_FW_CLM].binary; kfree(fwreq); ret = brcmf_chip_get_raminfo(devinfo->ci); @@ -1830,6 +1837,7 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo) struct brcmf_fw_name fwnames[] = { { ".bin", devinfo->fw_name }, { ".txt", devinfo->nvram_name }, + { ".clm_blob", devinfo->clm_name }, }; fwreq = brcmf_fw_alloc_request(devinfo->ci->chip, devinfo->ci->chiprev, @@ -1842,6 +1850,8 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo) 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->items[BRCMF_PCIE_FW_CLM].type = BRCMF_FW_TYPE_BINARY; + fwreq->items[BRCMF_PCIE_FW_CLM].flags = BRCMF_FW_REQF_OPTIONAL; fwreq->board_type = devinfo->settings->board_type; /* NVRAM reserves PCI domain 0 for Broadcom's SDK faked bus */ fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus) + 1; @@ -1981,6 +1991,7 @@ brcmf_pcie_remove(struct pci_dev *pdev) brcmf_pcie_release_ringbuffers(devinfo); brcmf_pcie_reset_device(devinfo); brcmf_pcie_release_resource(devinfo); + release_firmware(devinfo->clm_fw); if (devinfo->ci) brcmf_chip_detach(devinfo->ci); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index d7072009c47f..5eb9b3138f09 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -4131,23 +4131,24 @@ brcmf_sdio_watchdog(struct timer_list *t) } } -static -int brcmf_sdio_get_fwname(struct device *dev, const char *ext, u8 *fw_name) +static int brcmf_sdio_get_blob(struct device *dev, const struct firmware **fw, + enum brcmf_blob_type type) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_fw_request *fwreq; - struct brcmf_fw_name fwnames[] = { - { ext, fw_name }, - }; + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; - 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; + switch (type) { + case BRCMF_BLOB_CLM: + *fw = sdiodev->clm_fw; + sdiodev->clm_fw = NULL; + break; + default: + return -ENOENT; + } + + if (!*fw) + return -ENOENT; - kfree(fwreq); return 0; } @@ -4182,13 +4183,14 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { .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, + .get_blob = brcmf_sdio_get_blob, .debugfs_create = brcmf_sdio_debugfs_create, .reset = brcmf_sdio_bus_reset }; #define BRCMF_SDIO_FW_CODE 0 #define BRCMF_SDIO_FW_NVRAM 1 +#define BRCMF_SDIO_FW_CLM 2 static void brcmf_sdio_firmware_callback(struct device *dev, int err, struct brcmf_fw_request *fwreq) @@ -4211,6 +4213,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, 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; + sdiod->clm_fw = fwreq->items[BRCMF_SDIO_FW_CLM].binary; kfree(fwreq); /* try to download image and nvram to the dongle */ @@ -4409,6 +4412,7 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus) struct brcmf_fw_name fwnames[] = { { ".bin", bus->sdiodev->fw_name }, { ".txt", bus->sdiodev->nvram_name }, + { ".clm_blob", bus->sdiodev->clm_name }, }; fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev, @@ -4420,6 +4424,8 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus) fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY; fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; + fwreq->items[BRCMF_SDIO_FW_CLM].type = BRCMF_FW_TYPE_BINARY; + fwreq->items[BRCMF_SDIO_FW_CLM].flags = BRCMF_FW_REQF_OPTIONAL; fwreq->board_type = bus->sdiodev->settings->board_type; return fwreq; @@ -4576,6 +4582,8 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) if (bus->sdiodev->settings) brcmf_release_module_param(bus->sdiodev->settings); + release_firmware(bus->sdiodev->clm_fw); + bus->sdiodev->clm_fw = NULL; kfree(bus->rxbuf); kfree(bus->hdrbuf); kfree(bus); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h index 47351ff458ca..b76d34d36bde 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h @@ -186,9 +186,11 @@ struct brcmf_sdio_dev { struct sg_table sgtable; char fw_name[BRCMF_FW_NAME_LEN]; char nvram_name[BRCMF_FW_NAME_LEN]; + char clm_name[BRCMF_FW_NAME_LEN]; bool wowl_enabled; enum brcmf_sdiod_state state; struct brcmf_sdiod_freezer *freezer; + const struct firmware *clm_fw; }; /* sdio core registers */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index 9fb68c2dc7e3..85e18fb9c497 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -1154,24 +1154,11 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, return NULL; } -static -int brcmf_usb_get_fwname(struct device *dev, const char *ext, u8 *fw_name) +static int brcmf_usb_get_blob(struct device *dev, const struct firmware **fw, + enum brcmf_blob_type type) { - struct brcmf_bus *bus = dev_get_drvdata(dev); - struct brcmf_fw_request *fwreq; - struct brcmf_fw_name fwnames[] = { - { ext, fw_name }, - }; - - 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; - - kfree(fwreq); - return 0; + /* No blobs for USB devices... */ + return -ENOENT; } static const struct brcmf_bus_ops brcmf_usb_bus_ops = { @@ -1180,7 +1167,7 @@ static const struct brcmf_bus_ops brcmf_usb_bus_ops = { .txdata = brcmf_usb_tx, .txctl = brcmf_usb_tx_ctlpkt, .rxctl = brcmf_usb_rx_ctlpkt, - .get_fwname = brcmf_usb_get_fwname, + .get_blob = brcmf_usb_get_blob, }; #define BRCMF_USB_FW_CODE 0 From patchwork Fri Sep 16 16:02:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Russell King \(Oracle\)" X-Patchwork-Id: 606566 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 36E47C54EE9 for ; Fri, 16 Sep 2022 16:03:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230159AbiIPQDJ (ORCPT ); Fri, 16 Sep 2022 12:03:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38218 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230088AbiIPQCx (ORCPT ); Fri, 16 Sep 2022 12:02:53 -0400 Received: from pandora.armlinux.org.uk (pandora.armlinux.org.uk [IPv6:2001:4d48:ad52:32c8:5054:ff:fe00:142]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D7516B56F1; Fri, 16 Sep 2022 09:02:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=armlinux.org.uk; s=pandora-2019; h=Date:Sender:Message-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:Subject:Cc:To:From:References: In-Reply-To:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=q2B4e2Yl5JI9c7GcwkHC7CEN29XU0TUjbG9EmvqhnvM=; b=oQixZ3YVrRF9z4yMCiLM+eSC6u pxRtUj71H7UE4YwG9YubCZhX5QeXZ2nXtO8mNMPFVi2d7EpFumG64akrIKUzF47g/v74bRSdNiZrk ynkPoFHy3QySuDf7Cow7P/crkkYSPqSOIdkUhWgoYZFlTS+nNTyb1dhWNEkIfvMlNybyolQEQ/0ls Ora7Kg6czuwadi+jGXsh7p3yguLLj8A0/Xc/XAdPGeEDsbHKg5Os7JgVE7qOG+MHULtZAbimONrTc BuCnnYmx39/RjxkIUA1iQDEgGdrx+5kk42FHcnPMezRRI0in0OXo/n0eXX8v8AhTfmcp6lkAHAeaI jVeOA+Tw==; Received: from e0022681537dd.dyn.armlinux.org.uk ([fd8f:7570:feb6:1:222:68ff:fe15:37dd]:40116 helo=rmk-PC.armlinux.org.uk) by pandora.armlinux.org.uk with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1oZDnj-0006uJ-7X; Fri, 16 Sep 2022 17:02:47 +0100 Received: from rmk by rmk-PC.armlinux.org.uk with local (Exim 4.94.2) (envelope-from ) id 1oZDni-0077aM-I6; Fri, 16 Sep 2022 17:02:46 +0100 In-Reply-To: References: From: Russell King (Oracle) To: Arend van Spriel , Franky Lin , Hante Meuleman Cc: Alyssa Rosenzweig , asahi@lists.linux.dev, brcm80211-dev-list.pdl@broadcom.com, "David S. Miller" , devicetree@vger.kernel.org, Eric Dumazet , Hector Martin , Jakub Kicinski , Kalle Valo , Krzysztof Kozlowski , linux-arm-kernel@lists.infradead.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org, Paolo Abeni , "Rafa__ Mi__ecki" , Rob Herring , SHA-cyfmac-dev-list@infineon.com, Sven Peter Subject: [PATCH wireless-next v3 05/12] brcmfmac: pcie: Read Apple OTP information MIME-Version: 1.0 Content-Disposition: inline Message-Id: Sender: Russell King Date: Fri, 16 Sep 2022 17:02:46 +0100 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Hector Martin On Apple platforms, the One Time Programmable ROM in the Broadcom chips contains information about the specific board design (module, vendor, version) that is required to select the correct NVRAM file. Parse this OTP ROM and extract the required strings. Note that the user OTP offset/size is per-chip. This patch does not add any chips yet. Reviewed-by: Arend van Spriel Signed-off-by: Hector Martin Signed-off-by: Russell King (Oracle) --- .../broadcom/brcm80211/brcmfmac/pcie.c | 218 ++++++++++++++++++ include/linux/bcma/bcma_driver_chipcommon.h | 1 + 2 files changed, 219 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index 2a74c9d8d46a..76ca835378bb 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -256,6 +256,15 @@ struct brcmf_pcie_core_info { u32 wrapbase; }; +#define BRCMF_OTP_MAX_PARAM_LEN 16 + +struct brcmf_otp_params { + char module[BRCMF_OTP_MAX_PARAM_LEN]; + char vendor[BRCMF_OTP_MAX_PARAM_LEN]; + char version[BRCMF_OTP_MAX_PARAM_LEN]; + bool valid; +}; + struct brcmf_pciedev_info { enum brcmf_pcie_state state; bool in_irq; @@ -283,6 +292,7 @@ struct brcmf_pciedev_info { void (*write_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset, u16 value); struct brcmf_mp_device *settings; + struct brcmf_otp_params otp; }; struct brcmf_pcie_ringbuf { @@ -354,6 +364,14 @@ static void brcmf_pcie_setup(struct device *dev, int ret, static struct brcmf_fw_request * brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo); +static u16 +brcmf_pcie_read_reg16(struct brcmf_pciedev_info *devinfo, u32 reg_offset) +{ + void __iomem *address = devinfo->regs + reg_offset; + + return ioread16(address); +} + static u32 brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset) { @@ -499,6 +517,8 @@ brcmf_pcie_copy_dev_tomem(struct brcmf_pciedev_info *devinfo, u32 mem_offset, } +#define READCC32(devinfo, reg) brcmf_pcie_read_reg32(devinfo, \ + CHIPCREGOFFS(reg)) #define WRITECC32(devinfo, reg, value) brcmf_pcie_write_reg32(devinfo, \ CHIPCREGOFFS(reg), value) @@ -1734,6 +1754,198 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { .write32 = brcmf_pcie_buscore_write32, }; +#define BRCMF_OTP_SYS_VENDOR 0x15 +#define BRCMF_OTP_BRCM_CIS 0x80 + +#define BRCMF_OTP_VENDOR_HDR 0x00000008 + +static int +brcmf_pcie_parse_otp_sys_vendor(struct brcmf_pciedev_info *devinfo, + u8 *data, size_t size) +{ + int idx = 4; + const char *chip_params; + const char *board_params; + const char *p; + + /* 4-byte header and two empty strings */ + if (size < 6) + return -EINVAL; + + if (get_unaligned_le32(data) != BRCMF_OTP_VENDOR_HDR) + return -EINVAL; + + chip_params = &data[idx]; + + /* Skip first string, including terminator */ + idx += strnlen(chip_params, size - idx) + 1; + if (idx >= size) + return -EINVAL; + + board_params = &data[idx]; + + /* Skip to terminator of second string */ + idx += strnlen(board_params, size - idx); + if (idx >= size) + return -EINVAL; + + /* At this point both strings are guaranteed NUL-terminated */ + brcmf_dbg(PCIE, "OTP: chip_params='%s' board_params='%s'\n", + chip_params, board_params); + + p = skip_spaces(board_params); + while (*p) { + char tag = *p++; + const char *end; + size_t len; + + if (*p++ != '=') /* implicit NUL check */ + return -EINVAL; + + /* *p might be NUL here, if so end == p and len == 0 */ + end = strchrnul(p, ' '); + len = end - p; + + /* leave 1 byte for NUL in destination string */ + if (len > (BRCMF_OTP_MAX_PARAM_LEN - 1)) + return -EINVAL; + + /* Copy len characters plus a NUL terminator */ + switch (tag) { + case 'M': + strscpy(devinfo->otp.module, p, len + 1); + break; + case 'V': + strscpy(devinfo->otp.vendor, p, len + 1); + break; + case 'm': + strscpy(devinfo->otp.version, p, len + 1); + break; + } + + /* Skip to next arg, if any */ + p = skip_spaces(end); + } + + brcmf_dbg(PCIE, "OTP: module=%s vendor=%s version=%s\n", + devinfo->otp.module, devinfo->otp.vendor, + devinfo->otp.version); + + if (!devinfo->otp.module[0] || + !devinfo->otp.vendor[0] || + !devinfo->otp.version[0]) + return -EINVAL; + + devinfo->otp.valid = true; + return 0; +} + +static int +brcmf_pcie_parse_otp(struct brcmf_pciedev_info *devinfo, u8 *otp, size_t size) +{ + int p = 0; + int ret = -EINVAL; + + brcmf_dbg(PCIE, "parse_otp size=%zd\n", size); + + while (p < (size - 1)) { + u8 type = otp[p]; + u8 length = otp[p + 1]; + + if (type == 0) + break; + + if ((p + 2 + length) > size) + break; + + switch (type) { + case BRCMF_OTP_SYS_VENDOR: + brcmf_dbg(PCIE, "OTP @ 0x%x (%d): SYS_VENDOR\n", + p, length); + ret = brcmf_pcie_parse_otp_sys_vendor(devinfo, + &otp[p + 2], + length); + break; + case BRCMF_OTP_BRCM_CIS: + brcmf_dbg(PCIE, "OTP @ 0x%x (%d): BRCM_CIS\n", + p, length); + break; + default: + brcmf_dbg(PCIE, "OTP @ 0x%x (%d): Unknown type 0x%x\n", + p, length, type); + break; + } + + p += 2 + length; + } + + return ret; +} + +static int brcmf_pcie_read_otp(struct brcmf_pciedev_info *devinfo) +{ + const struct pci_dev *pdev = devinfo->pdev; + struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); + u32 coreid, base, words, idx, sromctl; + u16 *otp; + struct brcmf_core *core; + int ret; + + switch (devinfo->ci->chip) { + default: + /* OTP not supported on this chip */ + return 0; + } + + core = brcmf_chip_get_core(devinfo->ci, coreid); + if (!core) { + brcmf_err(bus, "No OTP core\n"); + return -ENODEV; + } + + if (coreid == BCMA_CORE_CHIPCOMMON) { + /* Chips with OTP accessed via ChipCommon need additional + * handling to access the OTP + */ + brcmf_pcie_select_core(devinfo, coreid); + sromctl = READCC32(devinfo, sromcontrol); + + if (!(sromctl & BCMA_CC_SROM_CONTROL_OTP_PRESENT)) { + /* Chip lacks OTP, try without it... */ + brcmf_err(bus, + "OTP unavailable, using default firmware\n"); + return 0; + } + + /* Map OTP to shadow area */ + WRITECC32(devinfo, sromcontrol, + sromctl | BCMA_CC_SROM_CONTROL_OTPSEL); + } + + otp = kcalloc(words, sizeof(u16), GFP_KERNEL); + if (!otp) + return -ENOMEM; + + /* Map bus window to SROM/OTP shadow area in core */ + base = brcmf_pcie_buscore_prep_addr(devinfo->pdev, base + core->base); + + brcmf_dbg(PCIE, "OTP data:\n"); + for (idx = 0; idx < words; idx++) { + otp[idx] = brcmf_pcie_read_reg16(devinfo, base + 2 * idx); + brcmf_dbg(PCIE, "[%8x] 0x%04x\n", base + 2 * idx, otp[idx]); + } + + if (coreid == BCMA_CORE_CHIPCOMMON) { + brcmf_pcie_select_core(devinfo, coreid); + WRITECC32(devinfo, sromcontrol, sromctl); + } + + ret = brcmf_pcie_parse_otp(devinfo, (u8 *)otp, 2 * words); + kfree(otp); + + return ret; +} + #define BRCMF_PCIE_FW_CODE 0 #define BRCMF_PCIE_FW_NVRAM 1 #define BRCMF_PCIE_FW_CLM 2 @@ -1930,6 +2142,12 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) goto fail_bus; + ret = brcmf_pcie_read_otp(devinfo); + if (ret) { + brcmf_err(bus, "failed to parse OTP\n"); + goto fail_brcmf; + } + fwreq = brcmf_pcie_prepare_fw_request(devinfo); if (!fwreq) { ret = -ENOMEM; diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index e3314f746bfa..2d94c30ed439 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -271,6 +271,7 @@ #define BCMA_CC_SROM_CONTROL_OP_WRDIS 0x40000000 #define BCMA_CC_SROM_CONTROL_OP_WREN 0x60000000 #define BCMA_CC_SROM_CONTROL_OTPSEL 0x00000010 +#define BCMA_CC_SROM_CONTROL_OTP_PRESENT 0x00000020 #define BCMA_CC_SROM_CONTROL_LOCK 0x00000008 #define BCMA_CC_SROM_CONTROL_SIZE_MASK 0x00000006 #define BCMA_CC_SROM_CONTROL_SIZE_1K 0x00000000 From patchwork Fri Sep 16 16:02:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Russell King \(Oracle\)" X-Patchwork-Id: 606565 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 348B9ECAAD8 for ; Fri, 16 Sep 2022 16:03:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230073AbiIPQDQ (ORCPT ); Fri, 16 Sep 2022 12:03:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38716 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230152AbiIPQDJ (ORCPT ); Fri, 16 Sep 2022 12:03:09 -0400 Received: from pandora.armlinux.org.uk (pandora.armlinux.org.uk [IPv6:2001:4d48:ad52:32c8:5054:ff:fe00:142]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A20AAB5A7E; Fri, 16 Sep 2022 09:03:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=armlinux.org.uk; s=pandora-2019; h=Date:Sender:Message-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:Subject:Cc:To:From:References: In-Reply-To:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=0qTTNlIz6eazaYWWx/kFgATHdyZNg/fwiURQVzK4hpQ=; b=ZfoRepnQ4jT6ALzelmZQpYFEws gUvihLRVHbZLkyKFyQxWMYsuQJO92jOhdiegOTeqojYx84uJIfRGWtSSPFS0/H+pDw7zxLchMlU6x ZuOpYW9pwDt+wRGQH11Ran8aNqmqTKoNk4eHw5BPSaVWSAgQ4c9lK787xjf7ohOQolS+++hjfsNJw pZ0mJFIAEM8vWRDFxinB2LzptnsdmoGCiOHu5GDgPWhbdnDuG7zdW8lZ4VFArO4PQK6s8Ew3HSTQi YWjDmcSn6KjXSlR9/iWQk3CJVe4Ri71gvY/7NTy3MFmJr80oVPMbWqmQM1mPg6UzEP+dtlWqNNRvW kKRc+Wmw==; Received: from e0022681537dd.dyn.armlinux.org.uk ([fd8f:7570:feb6:1:222:68ff:fe15:37dd]:48790 helo=rmk-PC.armlinux.org.uk) by pandora.armlinux.org.uk with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1oZDnt-0006v5-Fr; Fri, 16 Sep 2022 17:02:57 +0100 Received: from rmk by rmk-PC.armlinux.org.uk with local (Exim 4.94.2) (envelope-from ) id 1oZDns-0077aY-Qn; Fri, 16 Sep 2022 17:02:56 +0100 In-Reply-To: References: From: Russell King (Oracle) To: Arend van Spriel , Franky Lin , Hante Meuleman Cc: Alyssa Rosenzweig , asahi@lists.linux.dev, brcm80211-dev-list.pdl@broadcom.com, "David S. Miller" , devicetree@vger.kernel.org, Eric Dumazet , Hector Martin , Jakub Kicinski , Kalle Valo , Krzysztof Kozlowski , linux-arm-kernel@lists.infradead.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org, Paolo Abeni , "Rafa__ Mi__ecki" , Rob Herring , SHA-cyfmac-dev-list@infineon.com, Sven Peter Subject: [PATCH wireless-next v3 07/12] brcmfmac: pcie: Perform firmware selection for Apple platforms MIME-Version: 1.0 MIME-Version: 1.0 Content-Disposition: inline Message-Id: Sender: Russell King Date: Fri, 16 Sep 2022 17:02:56 +0100 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Hector Martin On Apple platforms, firmware selection uses the following elements: Property Example Source ============== ======= ======================== * Chip name 4378 Device ID * Chip revision B1 OTP * Platform shikoku DT (ARM64) or ACPI (x86) * Module type RASP OTP * Module vendor m OTP * Module version 6.11 OTP * Antenna SKU X3 DT (ARM64) or ACPI (x86) In macOS, these firmwares are stored using filenames in this format under /usr/share/firmware/wifi: C-4378__s-B1/P-shikoku-X3_M-RASP_V-m__m-6.11.txt To prepare firmwares for Linux, we rename these to a scheme following the existing brcmfmac convention: brcmfmac-pcie.apple,--\ --.txt The NVRAM uses all the components, while the firmware and CLM blob only use the chip/revision/platform/antenna_sku: brcmfmac-pcie.apple,-.bin e.g. brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m-6.11-X3.txt brcm/brcmfmac4378b1-pcie.apple,shikoku-X3.bin In addition, since there are over 1000 files in total, many of which are symlinks or outright duplicates, we deduplicate and prune the firmware tree to reduce firmware filenames to fewer dimensions. For example, the shikoku platform (MacBook Air M1 2020) simplifies to just 4 files: brcm/brcmfmac4378b1-pcie.apple,shikoku.clm_blob brcm/brcmfmac4378b1-pcie.apple,shikoku.bin brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m.txt brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-u.txt This reduces the total file count to around 170, of which 75 are symlinks and 95 are regular files: 7 firmware blobs, 27 CLM blobs, and 61 NVRAM config files. We also slightly process NVRAM files to correct some formatting issues. To handle this, the driver must try the following path formats when looking for firmware files: brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m-6.11-X3.txt brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m-6.11.txt brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m.txt brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP.txt brcm/brcmfmac4378b1-pcie.apple,shikoku-X3.txt * brcm/brcmfmac4378b1-pcie.apple,shikoku.txt * Not relevant for NVRAM, only for firmware/CLM. The chip revision nominally comes from OTP on Apple platforms, but it can be mapped to the PCI revision number, so we ignore the OTP revision and continue to use the existing PCI revision mechanism to identify chip revisions, as the driver already does for other chips. Unfortunately, the mapping is not consistent between different chip types, so this has to be determined experimentally. Reviewed-by: Linus Walleij Signed-off-by: Hector Martin Reviewed-by: Alvin Šipraga Signed-off-by: Russell King (Oracle) --- .../broadcom/brcm80211/brcmfmac/pcie.c | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index 76ca835378bb..2e9af2cacc2f 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -2068,8 +2068,44 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo) fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus) + 1; fwreq->bus_nr = devinfo->pdev->bus->number; - brcmf_dbg(PCIE, "Board: %s\n", devinfo->settings->board_type); - fwreq->board_types[0] = devinfo->settings->board_type; + /* Apple platforms with fancy firmware/NVRAM selection */ + if (devinfo->settings->board_type && + devinfo->settings->antenna_sku && + devinfo->otp.valid) { + const struct brcmf_otp_params *otp = &devinfo->otp; + struct device *dev = &devinfo->pdev->dev; + const char **bt = fwreq->board_types; + + brcmf_dbg(PCIE, "Apple board: %s\n", + devinfo->settings->board_type); + + /* Example: apple,shikoku-RASP-m-6.11-X3 */ + bt[0] = devm_kasprintf(dev, GFP_KERNEL, "%s-%s-%s-%s-%s", + devinfo->settings->board_type, + otp->module, otp->vendor, otp->version, + devinfo->settings->antenna_sku); + bt[1] = devm_kasprintf(dev, GFP_KERNEL, "%s-%s-%s-%s", + devinfo->settings->board_type, + otp->module, otp->vendor, otp->version); + bt[2] = devm_kasprintf(dev, GFP_KERNEL, "%s-%s-%s", + devinfo->settings->board_type, + otp->module, otp->vendor); + bt[3] = devm_kasprintf(dev, GFP_KERNEL, "%s-%s", + devinfo->settings->board_type, + otp->module); + bt[4] = devm_kasprintf(dev, GFP_KERNEL, "%s-%s", + devinfo->settings->board_type, + devinfo->settings->antenna_sku); + bt[5] = devinfo->settings->board_type; + + if (!bt[0] || !bt[1] || !bt[2] || !bt[3] || !bt[4]) { + kfree(fwreq); + return NULL; + } + } else { + brcmf_dbg(PCIE, "Board: %s\n", devinfo->settings->board_type); + fwreq->board_types[0] = devinfo->settings->board_type; + } return fwreq; } From patchwork Fri Sep 16 16:03:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Russell King \(Oracle\)" X-Patchwork-Id: 606564 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 309F0ECAAD8 for ; Fri, 16 Sep 2022 16:03:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230021AbiIPQDw (ORCPT ); Fri, 16 Sep 2022 12:03:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38890 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230103AbiIPQDO (ORCPT ); Fri, 16 Sep 2022 12:03:14 -0400 Received: from pandora.armlinux.org.uk (pandora.armlinux.org.uk [IPv6:2001:4d48:ad52:32c8:5054:ff:fe00:142]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DD705B56DE; Fri, 16 Sep 2022 09:03:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=armlinux.org.uk; s=pandora-2019; h=Date:Sender:Message-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:Subject:Cc:To:From:References: In-Reply-To:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=M1YvgbxuO3J4hqI1ceKg9NSimYPqJ08rzT5LCS0EJfU=; b=FBS/Qby0/CxTRKNVbfEU0rb8dL DBNDrCTChN5PBI1BwteRs2YjAWK4yRGv9mlgjY77UGXIskBKvhl4EKmDV1gXP6priSk6BS4ZFUa1D 6salHc9PPemUPHXBvzWlBrEGxDULpJCzuhPEnfoc9SYxbKfaxmZqJ65BKY/wrtCX/sjKrCn1pEEgL DkxI3N9MU0qZRV15Uu4Grr/QCaxLNWVssJeYXgPyaD86xi4GnSivSzlAlm+2/dfnHUry0td+pby6D sI0tTW5/w9k1WMuLTW9iSkJvxLtZMEfMkYtma8JV7344HfRtBF4vDwE9DNkNsN/QJYmB7g8Zn7CAa gqgJLx9w==; Received: from e0022681537dd.dyn.armlinux.org.uk ([fd8f:7570:feb6:1:222:68ff:fe15:37dd]:54034 helo=rmk-PC.armlinux.org.uk) by pandora.armlinux.org.uk with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1oZDo3-0006vr-Os; Fri, 16 Sep 2022 17:03:07 +0100 Received: from rmk by rmk-PC.armlinux.org.uk with local (Exim 4.94.2) (envelope-from ) id 1oZDo3-0077ak-2h; Fri, 16 Sep 2022 17:03:07 +0100 In-Reply-To: References: From: Russell King (Oracle) To: Arend van Spriel , Franky Lin , Hante Meuleman Cc: Alyssa Rosenzweig , asahi@lists.linux.dev, brcm80211-dev-list.pdl@broadcom.com, "David S. Miller" , devicetree@vger.kernel.org, Eric Dumazet , Hector Martin , Jakub Kicinski , Kalle Valo , Krzysztof Kozlowski , linux-arm-kernel@lists.infradead.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org, Paolo Abeni , "Rafa__ Mi__ecki" , Rob Herring , SHA-cyfmac-dev-list@infineon.com, Sven Peter Subject: [PATCH wireless-next v3 09/12] brcmfmac: msgbuf: Increase RX ring sizes to 1024 MIME-Version: 1.0 MIME-Version: 1.0 Content-Disposition: inline Message-Id: Sender: Russell King Date: Fri, 16 Sep 2022 17:03:07 +0100 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Hector Martin Newer chips used on Apple platforms have a max_rxbufpost greater than 512, which causes warnings when brcmf_msgbuf_rxbuf_data_fill tries to put more entries in the ring than will fit. Increase the ring sizes to 1024. Reviewed-by: Linus Walleij Signed-off-by: Hector Martin Reviewed-by: Alvin Šipraga Signed-off-by: Russell King (Oracle) --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h index 2e322edbb907..6a849f4a94dd 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h @@ -8,10 +8,10 @@ #ifdef CONFIG_BRCMFMAC_PROTO_MSGBUF #define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM 64 -#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM 512 +#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM 1024 #define BRCMF_D2H_MSGRING_CONTROL_COMPLETE_MAX_ITEM 64 #define BRCMF_D2H_MSGRING_TX_COMPLETE_MAX_ITEM 1024 -#define BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM 512 +#define BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM 1024 #define BRCMF_H2D_TXFLOWRING_MAX_ITEM 512 #define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE 40 From patchwork Fri Sep 16 16:03:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Russell King \(Oracle\)" X-Patchwork-Id: 606563 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8C229C6FA93 for ; Fri, 16 Sep 2022 16:03:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230152AbiIPQDz (ORCPT ); Fri, 16 Sep 2022 12:03:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39250 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230206AbiIPQD2 (ORCPT ); Fri, 16 Sep 2022 12:03:28 -0400 Received: from pandora.armlinux.org.uk (pandora.armlinux.org.uk [IPv6:2001:4d48:ad52:32c8:5054:ff:fe00:142]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9618DB56D4; Fri, 16 Sep 2022 09:03:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=armlinux.org.uk; s=pandora-2019; h=Date:Sender:Message-Id:Content-Type: Content-Transfer-Encoding:MIME-Version:Subject:Cc:To:From:References: In-Reply-To:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=euGjEP5KKPvWOnsVlf1QQNH2sq2qPX4DZ0kmuvczwCE=; b=KBifPY+MOqET7Rstnb8pTi4Ngj Kgf5/LRagQK/pNZ38qx1oCj2OCUI2ML+Ze+regOX1Po9a/BLwHdkbZxxdnbx3vYoIo2ihqObBI3kp h5iO8nJouNReJx8h7CYmiz7sjNsss1Gmoq+H/9zmqs+lO1DkRA6QStoyPa0TaxQFUjSJG5aZAQNEp 3kW4yk4J518it9VVDzA1JBD6zsBvvsFxtEi1XhHSNNqZVpZaEGOvjrBJ2jkTpDsbaY99m4/17hcAc pq+ONLLjsLqCbNhMJ9yX5n8AXw714+8srxUKyip4uR1Yxd9jI2G6/g//E4ZuQhZ6r4Hbosx0gsBpI rZ1gzvlw==; Received: from e0022681537dd.dyn.armlinux.org.uk ([fd8f:7570:feb6:1:222:68ff:fe15:37dd]:41316 helo=rmk-PC.armlinux.org.uk) by pandora.armlinux.org.uk with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1oZDo8-0006wF-Qp; Fri, 16 Sep 2022 17:03:12 +0100 Received: from rmk by rmk-PC.armlinux.org.uk with local (Exim 4.94.2) (envelope-from ) id 1oZDo8-0077aq-6I; Fri, 16 Sep 2022 17:03:12 +0100 In-Reply-To: References: From: Russell King (Oracle) To: Arend van Spriel , Franky Lin , Hante Meuleman Cc: Alyssa Rosenzweig , asahi@lists.linux.dev, brcm80211-dev-list.pdl@broadcom.com, "David S. Miller" , devicetree@vger.kernel.org, Eric Dumazet , Hector Martin , Jakub Kicinski , Kalle Valo , Krzysztof Kozlowski , linux-arm-kernel@lists.infradead.org, linux-wireless@vger.kernel.org, netdev@vger.kernel.org, Paolo Abeni , "Rafa__ Mi__ecki" , Rob Herring , SHA-cyfmac-dev-list@infineon.com, Sven Peter Subject: [PATCH wireless-next v3 10/12] brcmfmac: pcie: Support PCIe core revisions >= 64 MIME-Version: 1.0 Content-Disposition: inline Message-Id: Sender: Russell King Date: Fri, 16 Sep 2022 17:03:12 +0100 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Hector Martin These newer PCIe core revisions include new sets of registers that must be used instead of the legacy ones. Introduce a brcmf_pcie_reginfo to hold the specific register offsets and values to use for a given platform, and change all the register accesses to indirect through it. Reviewed-by: Linus Walleij Signed-off-by: Hector Martin --- .../broadcom/brcm80211/brcmfmac/pcie.c | 125 +++++++++++++++--- 1 file changed, 105 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index 2e9af2cacc2f..36fc643af086 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -119,6 +119,12 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { #define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0 0x140 #define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1 0x144 +#define BRCMF_PCIE_64_PCIE2REG_INTMASK 0xC14 +#define BRCMF_PCIE_64_PCIE2REG_MAILBOXINT 0xC30 +#define BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK 0xC34 +#define BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_0 0xA20 +#define BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_1 0xA24 + #define BRCMF_PCIE2_INTA 0x01 #define BRCMF_PCIE2_INTB 0x02 @@ -138,6 +144,8 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { #define BRCMF_PCIE_MB_INT_D2H3_DB0 0x400000 #define BRCMF_PCIE_MB_INT_D2H3_DB1 0x800000 +#define BRCMF_PCIE_MB_INT_FN0 (BRCMF_PCIE_MB_INT_FN0_0 | \ + BRCMF_PCIE_MB_INT_FN0_1) #define BRCMF_PCIE_MB_INT_D2H_DB (BRCMF_PCIE_MB_INT_D2H0_DB0 | \ BRCMF_PCIE_MB_INT_D2H0_DB1 | \ BRCMF_PCIE_MB_INT_D2H1_DB0 | \ @@ -147,6 +155,40 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { BRCMF_PCIE_MB_INT_D2H3_DB0 | \ BRCMF_PCIE_MB_INT_D2H3_DB1) +#define BRCMF_PCIE_64_MB_INT_D2H0_DB0 0x1 +#define BRCMF_PCIE_64_MB_INT_D2H0_DB1 0x2 +#define BRCMF_PCIE_64_MB_INT_D2H1_DB0 0x4 +#define BRCMF_PCIE_64_MB_INT_D2H1_DB1 0x8 +#define BRCMF_PCIE_64_MB_INT_D2H2_DB0 0x10 +#define BRCMF_PCIE_64_MB_INT_D2H2_DB1 0x20 +#define BRCMF_PCIE_64_MB_INT_D2H3_DB0 0x40 +#define BRCMF_PCIE_64_MB_INT_D2H3_DB1 0x80 +#define BRCMF_PCIE_64_MB_INT_D2H4_DB0 0x100 +#define BRCMF_PCIE_64_MB_INT_D2H4_DB1 0x200 +#define BRCMF_PCIE_64_MB_INT_D2H5_DB0 0x400 +#define BRCMF_PCIE_64_MB_INT_D2H5_DB1 0x800 +#define BRCMF_PCIE_64_MB_INT_D2H6_DB0 0x1000 +#define BRCMF_PCIE_64_MB_INT_D2H6_DB1 0x2000 +#define BRCMF_PCIE_64_MB_INT_D2H7_DB0 0x4000 +#define BRCMF_PCIE_64_MB_INT_D2H7_DB1 0x8000 + +#define BRCMF_PCIE_64_MB_INT_D2H_DB (BRCMF_PCIE_64_MB_INT_D2H0_DB0 | \ + BRCMF_PCIE_64_MB_INT_D2H0_DB1 | \ + BRCMF_PCIE_64_MB_INT_D2H1_DB0 | \ + BRCMF_PCIE_64_MB_INT_D2H1_DB1 | \ + BRCMF_PCIE_64_MB_INT_D2H2_DB0 | \ + BRCMF_PCIE_64_MB_INT_D2H2_DB1 | \ + BRCMF_PCIE_64_MB_INT_D2H3_DB0 | \ + BRCMF_PCIE_64_MB_INT_D2H3_DB1 | \ + BRCMF_PCIE_64_MB_INT_D2H4_DB0 | \ + BRCMF_PCIE_64_MB_INT_D2H4_DB1 | \ + BRCMF_PCIE_64_MB_INT_D2H5_DB0 | \ + BRCMF_PCIE_64_MB_INT_D2H5_DB1 | \ + BRCMF_PCIE_64_MB_INT_D2H6_DB0 | \ + BRCMF_PCIE_64_MB_INT_D2H6_DB1 | \ + BRCMF_PCIE_64_MB_INT_D2H7_DB0 | \ + BRCMF_PCIE_64_MB_INT_D2H7_DB1) + #define BRCMF_PCIE_SHARED_VERSION_7 7 #define BRCMF_PCIE_MIN_SHARED_VERSION 5 #define BRCMF_PCIE_MAX_SHARED_VERSION BRCMF_PCIE_SHARED_VERSION_7 @@ -273,6 +315,7 @@ struct brcmf_pciedev_info { char nvram_name[BRCMF_FW_NAME_LEN]; char clm_name[BRCMF_FW_NAME_LEN]; const struct firmware *clm_fw; + const struct brcmf_pcie_reginfo *reginfo; void __iomem *regs; void __iomem *tcm; u32 ram_base; @@ -359,6 +402,36 @@ static const u32 brcmf_ring_itemsize[BRCMF_NROF_COMMON_MSGRINGS] = { BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE }; +struct brcmf_pcie_reginfo { + u32 intmask; + u32 mailboxint; + u32 mailboxmask; + u32 h2d_mailbox_0; + u32 h2d_mailbox_1; + u32 int_d2h_db; + u32 int_fn0; +}; + +static const struct brcmf_pcie_reginfo brcmf_reginfo_default = { + .intmask = BRCMF_PCIE_PCIE2REG_INTMASK, + .mailboxint = BRCMF_PCIE_PCIE2REG_MAILBOXINT, + .mailboxmask = BRCMF_PCIE_PCIE2REG_MAILBOXMASK, + .h2d_mailbox_0 = BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0, + .h2d_mailbox_1 = BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1, + .int_d2h_db = BRCMF_PCIE_MB_INT_D2H_DB, + .int_fn0 = BRCMF_PCIE_MB_INT_FN0, +}; + +static const struct brcmf_pcie_reginfo brcmf_reginfo_64 = { + .intmask = BRCMF_PCIE_64_PCIE2REG_INTMASK, + .mailboxint = BRCMF_PCIE_64_PCIE2REG_MAILBOXINT, + .mailboxmask = BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK, + .h2d_mailbox_0 = BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_0, + .h2d_mailbox_1 = BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_1, + .int_d2h_db = BRCMF_PCIE_64_MB_INT_D2H_DB, + .int_fn0 = 0, +}; + static void brcmf_pcie_setup(struct device *dev, int ret, struct brcmf_fw_request *fwreq); static struct brcmf_fw_request * @@ -802,30 +875,29 @@ static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo, static void brcmf_pcie_intr_disable(struct brcmf_pciedev_info *devinfo) { - brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, 0); + brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->mailboxmask, 0); } static void brcmf_pcie_intr_enable(struct brcmf_pciedev_info *devinfo) { - brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, - BRCMF_PCIE_MB_INT_D2H_DB | - BRCMF_PCIE_MB_INT_FN0_0 | - BRCMF_PCIE_MB_INT_FN0_1); + brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->mailboxmask, + devinfo->reginfo->int_d2h_db | + devinfo->reginfo->int_fn0); } 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); + devinfo->reginfo->h2d_mailbox_1, 1); } static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg) { struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; - if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT)) { + if (brcmf_pcie_read_reg32(devinfo, devinfo->reginfo->mailboxint)) { brcmf_pcie_intr_disable(devinfo); brcmf_dbg(PCIE, "Enter\n"); return IRQ_WAKE_THREAD; @@ -840,15 +912,14 @@ static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg) u32 status; devinfo->in_irq = true; - status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); + status = brcmf_pcie_read_reg32(devinfo, devinfo->reginfo->mailboxint); brcmf_dbg(PCIE, "Enter %x\n", status); if (status) { - brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, + brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->mailboxint, status); - if (status & (BRCMF_PCIE_MB_INT_FN0_0 | - BRCMF_PCIE_MB_INT_FN0_1)) + if (status & devinfo->reginfo->int_fn0) brcmf_pcie_handle_mb_data(devinfo); - if (status & BRCMF_PCIE_MB_INT_D2H_DB) { + if (status & devinfo->reginfo->int_d2h_db) { if (devinfo->state == BRCMFMAC_PCIE_STATE_UP) brcmf_proto_msgbuf_rx_trigger( &devinfo->pdev->dev); @@ -907,8 +978,8 @@ static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo) if (devinfo->in_irq) brcmf_err(bus, "Still in IRQ (processing) !!!\n"); - status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); - brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status); + status = brcmf_pcie_read_reg32(devinfo, devinfo->reginfo->mailboxint); + brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->mailboxint, status); devinfo->irq_allocated = false; } @@ -960,7 +1031,7 @@ static int brcmf_pcie_ring_mb_ring_bell(void *ctx) brcmf_dbg(PCIE, "RING !\n"); /* Any arbitrary value will do, lets use 1 */ - brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0, 1); + brcmf_pcie_write_reg32(devinfo, devinfo->reginfo->h2d_mailbox_0, 1); return 0; } @@ -1723,15 +1794,22 @@ static int brcmf_pcie_buscoreprep(void *ctx) static int brcmf_pcie_buscore_reset(void *ctx, struct brcmf_chip *chip) { struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; - u32 val; + struct brcmf_core *core; + u32 val, reg; devinfo->ci = chip; brcmf_pcie_reset_device(devinfo); - val = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); + /* reginfo is not ready yet */ + core = brcmf_chip_get_core(chip, BCMA_CORE_PCIE2); + if (core->rev >= 64) + reg = BRCMF_PCIE_64_PCIE2REG_MAILBOXINT; + else + reg = BRCMF_PCIE_PCIE2REG_MAILBOXINT; + + val = brcmf_pcie_read_reg32(devinfo, reg); if (val != 0xffffffff) - brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, - val); + brcmf_pcie_write_reg32(devinfo, reg, val); return 0; } @@ -2117,6 +2195,7 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) struct brcmf_fw_request *fwreq; struct brcmf_pciedev_info *devinfo; struct brcmf_pciedev *pcie_bus_dev; + struct brcmf_core *core; struct brcmf_bus *bus; brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device); @@ -2136,6 +2215,12 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto fail; } + core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_PCIE2); + if (core->rev >= 64) + devinfo->reginfo = &brcmf_reginfo_64; + else + devinfo->reginfo = &brcmf_reginfo_default; + pcie_bus_dev = kzalloc(sizeof(*pcie_bus_dev), GFP_KERNEL); if (pcie_bus_dev == NULL) { ret = -ENOMEM; @@ -2305,7 +2390,7 @@ static int brcmf_pcie_pm_leave_D3(struct device *dev) brcmf_dbg(PCIE, "Enter, dev=%p, bus=%p\n", dev, bus); /* Check if device is still up and running, if so we are ready */ - if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0) { + if (brcmf_pcie_read_reg32(devinfo, devinfo->reginfo->intmask) != 0) { brcmf_dbg(PCIE, "Try to wakeup device....\n"); if (brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D0_INFORM)) goto cleanup;