Message ID | 20220104072658.69756-36-marcan@marcan.st (mailing list archive) |
---|---|
State | Handled Elsewhere, archived |
Headers | show |
Series | brcmfmac: Support Apple T2 and M1 platforms | expand |
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 --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) {