diff mbox series

[v2,35/35] brcmfmac: common: Add support for external calibration blobs

Message ID 20220104072658.69756-36-marcan@marcan.st (mailing list archive)
State Awaiting Upstream
Delegated to: Netdev Maintainers
Headers show
Series brcmfmac: Support Apple T2 and M1 platforms | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

Hector Martin Jan. 4, 2022, 7:26 a.m. UTC
The calibration blob for a chip is normally stored in SROM and loaded
internally by the firmware. However, Apple ARM64 platforms instead store
it as part of platform configuration data, and provide it via the Apple
Device Tree. We forward this into the Linux DT in the bootloader.

Add support for taking this blob from the DT and loading it into the
dongle. The loading mechanism is the same as used for the CLM and TxCap
blobs.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Hector Martin <marcan@marcan.st>
---
 .../broadcom/brcm80211/brcmfmac/common.c      | 24 +++++++++++++++++++
 .../broadcom/brcm80211/brcmfmac/common.h      |  2 ++
 .../wireless/broadcom/brcm80211/brcmfmac/of.c |  8 +++++++
 3 files changed, 34 insertions(+)

Comments

Arend van Spriel Jan. 21, 2022, 7:35 a.m. UTC | #1
On 1/4/2022 8:26 AM, Hector Martin wrote:
> The calibration blob for a chip is normally stored in SROM and loaded
> internally by the firmware. However, Apple ARM64 platforms instead store
> it as part of platform configuration data, and provide it via the Apple
> Device Tree. We forward this into the Linux DT in the bootloader.
> 
> Add support for taking this blob from the DT and loading it into the
> dongle. The loading mechanism is the same as used for the CLM and TxCap
> blobs.
> 
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
> Signed-off-by: Hector Martin <marcan@marcan.st>
> ---
>   .../broadcom/brcm80211/brcmfmac/common.c      | 24 +++++++++++++++++++
>   .../broadcom/brcm80211/brcmfmac/common.h      |  2 ++
>   .../wireless/broadcom/brcm80211/brcmfmac/of.c |  8 +++++++
>   3 files changed, 34 insertions(+)
diff mbox series

Patch

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index d65308c3f070..ad36e6b5dd47 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -218,6 +218,23 @@  static int brcmf_c_process_txcap_blob(struct brcmf_if *ifp)
 	return err;
 }
 
+static int brcmf_c_process_cal_blob(struct brcmf_if *ifp)
+{
+	struct brcmf_pub *drvr = ifp->drvr;
+	struct brcmf_mp_device *settings = drvr->settings;
+	s32 err;
+
+	brcmf_dbg(TRACE, "Enter\n");
+
+	if (!settings->cal_blob || !settings->cal_size)
+		return 0;
+
+	brcmf_info("Calibration blob provided by platform, loading\n");
+	err = brcmf_c_download_blob(ifp, settings->cal_blob, settings->cal_size,
+				    "calload", "calload_status");
+	return err;
+}
+
 int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
 {
 	struct brcmf_pub *drvr = ifp->drvr;
@@ -291,6 +308,13 @@  int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
 		goto done;
 	}
 
+	/* Download external calibration blob, if available */
+	err = brcmf_c_process_cal_blob(ifp);
+	if (err < 0) {
+		bphy_err(drvr, "download calibration blob file failed, %d\n", err);
+		goto done;
+	}
+
 	/* query for 'ver' to get version info from firmware */
 	memset(buf, 0, sizeof(buf));
 	err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf));
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index a88c4a9310f3..f321346edd01 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -51,6 +51,8 @@  struct brcmf_mp_device {
 	struct brcmfmac_pd_cc *country_codes;
 	const char	*board_type;
 	const char	*antenna_sku;
+	void		*cal_blob;
+	int		cal_size;
 	union {
 		struct brcmfmac_sdio_pd sdio;
 	} bus;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
index 085d34176b78..6f885c3210c3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
@@ -78,6 +78,14 @@  void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
 	if (!of_property_read_string(np, "apple,antenna-sku", &prop))
 		settings->antenna_sku = devm_kstrdup(dev, prop, GFP_KERNEL);
 
+	/* The WLAN calibration blob is normally stored in SROM, but Apple
+	 * ARM64 platforms pass it via the DT instead.
+	 */
+	prop = of_get_property(np, "brcm,cal-blob", &settings->cal_size);
+	if (prop && settings->cal_size)
+		settings->cal_blob = devm_kmemdup(dev, prop, settings->cal_size,
+						  GFP_KERNEL);
+
 	/* Set board-type to the first string of the machine compatible prop */
 	root = of_find_node_by_path("/");
 	if (root && !settings->board_type) {