From: patrick Date: Fri, 26 Feb 2021 00:07:41 +0000 (+0000) Subject: Refactor bwfm(4) firmware loading. The PCIe backend will need to be able X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=94e4747cf8507bfa25f5391c2d82bc52c1f571c7;p=openbsd Refactor bwfm(4) firmware loading. The PCIe backend will need to be able to load the CLM blob like the SDIO backend already does. Additionally it is also helpful for the PCIe backend to try a file named after the device tree compatible. Thus refactor the SDIO code and make it available for both SDIO and PCIe. --- diff --git a/sys/dev/ic/bwfm.c b/sys/dev/ic/bwfm.c index ff734bc92d3..f720281b09e 100644 --- a/sys/dev/ic/bwfm.c +++ b/sys/dev/ic/bwfm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfm.c,v 1.82 2021/02/25 23:55:41 patrick Exp $ */ +/* $OpenBSD: bwfm.c,v 1.83 2021/02/26 00:07:41 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -28,6 +28,11 @@ #include #include +#if defined(__HAVE_FDT) +#include +#include +#endif + #if NBPFILTER > 0 #include #endif @@ -2901,3 +2906,115 @@ out: sc->sc_clm = NULL; sc->sc_clmsize = 0; } + +#if defined(__HAVE_FDT) +const char * +bwfm_sysname(void) +{ + static char sysfw[128]; + int len; + char *p; + + len = OF_getprop(OF_peer(0), "compatible", sysfw, sizeof(sysfw)); + if (len > 0 && len < sizeof(sysfw)) { + sysfw[len] = '\0'; + if ((p = strchr(sysfw, '/')) != NULL) + *p = '\0'; + return sysfw; + } + return NULL; +} +#else +const char * +bwfm_sysname(void) +{ + return NULL; +} +#endif + +int +bwfm_loadfirmware(struct bwfm_softc *sc, const char *chip, const char *bus, + u_char **ucode, size_t *size, u_char **nvram, size_t *nvsize, size_t *nvlen) +{ + const char *sysname = NULL; + char name[128]; + int r; + + *ucode = *nvram = NULL; + *size = *nvsize = *nvlen = 0; + + sysname = bwfm_sysname(); + + if (sysname != NULL) { + r = snprintf(name, sizeof(name), "brcmfmac%s%s.%s.bin", chip, + bus, sysname); + if ((r > 0 && r < sizeof(name)) && + loadfirmware(name, ucode, size) != 0) + *size = 0; + } + if (*size == 0) { + snprintf(name, sizeof(name), "brcmfmac%s%s.bin", chip, bus); + if (loadfirmware(name, ucode, size) != 0) { + printf("%s: failed loadfirmware of file %s\n", + DEVNAME(sc), name); + return 1; + } + } + + /* .txt needs to be processed first */ + if (sysname != NULL) { + r = snprintf(name, sizeof(name), "brcmfmac%s%s.%s.txt", chip, + bus, sysname); + if ((r > 0 && r < sizeof(name)) && + loadfirmware(name, nvram, nvsize) == 0) { + if (bwfm_nvram_convert(*nvram, *nvsize, nvlen) != 0) { + printf("%s: failed to process file %s\n", + DEVNAME(sc), name); + free(*ucode, M_DEVBUF, *size); + free(*nvram, M_DEVBUF, *nvsize); + return 1; + } + } + } + + if (*nvlen == 0) { + snprintf(name, sizeof(name), "brcmfmac%s%s.txt", chip, bus); + if (loadfirmware(name, nvram, nvsize) == 0) { + if (bwfm_nvram_convert(*nvram, *nvsize, nvlen) != 0) { + printf("%s: failed to process file %s\n", + DEVNAME(sc), name); + free(*ucode, M_DEVBUF, *size); + free(*nvram, M_DEVBUF, *nvsize); + return 1; + } + } + } + + /* .nvram is the pre-processed version */ + if (*nvlen == 0) { + snprintf(name, sizeof(name), "brcmfmac%s%s.nvram", chip, bus); + if (loadfirmware(name, nvram, nvsize) == 0) + *nvlen = *nvsize; + } + + if (*nvlen == 0 && strcmp(bus, "-sdio") == 0) { + snprintf(name, sizeof(name), "brcmfmac%s%s.txt", chip, bus); + printf("%s: failed loadfirmware of file %s\n", + DEVNAME(sc), name); + free(*ucode, M_DEVBUF, *size); + return 1; + } + + if (sysname != NULL) { + r = snprintf(name, sizeof(name), "brcmfmac%s%s.%s.clm_blob", + chip, bus, sysname); + if (r > 0 && r < sizeof(name)) + loadfirmware(name, &sc->sc_clm, &sc->sc_clmsize); + } + if (sc->sc_clmsize == 0) { + snprintf(name, sizeof(name), "brcmfmac%s%s.clm_blob", chip, bus); + loadfirmware(name, &sc->sc_clm, &sc->sc_clmsize); + } + + return 0; +} diff --git a/sys/dev/ic/bwfmvar.h b/sys/dev/ic/bwfmvar.h index 3262f326483..2d143ae7a31 100644 --- a/sys/dev/ic/bwfmvar.h +++ b/sys/dev/ic/bwfmvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfmvar.h,v 1.22 2021/01/31 11:07:51 patrick Exp $ */ +/* $OpenBSD: bwfmvar.h,v 1.23 2021/02/26 00:07:41 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -190,3 +190,5 @@ void bwfm_rx(struct bwfm_softc *, struct mbuf *, struct mbuf_list *); void bwfm_do_async(struct bwfm_softc *, void (*)(struct bwfm_softc *, void *), void *, int); int bwfm_nvram_convert(u_char *, size_t, size_t *); +int bwfm_loadfirmware(struct bwfm_softc *, const char *, const char *, + u_char **, size_t *, u_char **, size_t *, size_t *); diff --git a/sys/dev/pci/if_bwfm_pci.c b/sys/dev/pci/if_bwfm_pci.c index 557ace93f0b..fb6014a3ef5 100644 --- a/sys/dev/pci/if_bwfm_pci.c +++ b/sys/dev/pci/if_bwfm_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bwfm_pci.c,v 1.44 2021/02/26 00:02:07 patrick Exp $ */ +/* $OpenBSD: if_bwfm_pci.c,v 1.45 2021/02/26 00:07:41 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2017 Patrick Wildt @@ -390,9 +390,8 @@ bwfm_pci_preinit(struct bwfm_softc *bwfm) struct bwfm_pci_softc *sc = (void *)bwfm; struct bwfm_pci_ringinfo ringinfo; const char *chip = NULL; - char name[128]; - u_char *ucode, *nvram = NULL; - size_t size, nvsize, nvlen = 0; + u_char *ucode, *nvram; + size_t size, nvsize, nvlen; uint32_t d2h_w_idx_ptr, d2h_r_idx_ptr; uint32_t h2d_w_idx_ptr, h2d_r_idx_ptr; uint32_t idx_offset, reg; @@ -441,31 +440,9 @@ bwfm_pci_preinit(struct bwfm_softc *bwfm) return 1; } - snprintf(name, sizeof(name), "brcmfmac%s-pcie.bin", chip); - if (loadfirmware(name, &ucode, &size) != 0) { - printf("%s: failed loadfirmware of file %s\n", - DEVNAME(sc), name); + if (bwfm_loadfirmware(bwfm, chip, "-pcie", &ucode, &size, + &nvram, &nvsize, &nvlen) != 0) return 1; - } - - /* .txt needs to be processed first */ - snprintf(name, sizeof(name), "brcmfmac%s-pcie.txt", chip); - if (loadfirmware(name, &nvram, &nvsize) == 0) { - if (bwfm_nvram_convert(nvram, nvsize, &nvlen) != 0) { - printf("%s: failed to process file %s\n", - DEVNAME(sc), name); - free(ucode, M_DEVBUF, size); - free(nvram, M_DEVBUF, nvsize); - return 1; - } - } - - /* .nvram is the pre-processed version */ - if (nvlen == 0) { - snprintf(name, sizeof(name), "brcmfmac%s-pcie.nvram", chip); - if (loadfirmware(name, &nvram, &nvsize) == 0) - nvlen = nvsize; - } /* Retrieve RAM size from firmware. */ if (size >= BWFM_RAMSIZE + 8) { diff --git a/sys/dev/sdmmc/if_bwfm_sdio.c b/sys/dev/sdmmc/if_bwfm_sdio.c index 799c9b37117..694fbbc0579 100644 --- a/sys/dev/sdmmc/if_bwfm_sdio.c +++ b/sys/dev/sdmmc/if_bwfm_sdio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bwfm_sdio.c,v 1.38 2020/06/19 20:56:23 kettenis Exp $ */ +/* $OpenBSD: if_bwfm_sdio.c,v 1.39 2021/02/26 00:07:41 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -344,42 +344,14 @@ err: free(sc->sc_sf, M_DEVBUF, 0); } -#if defined(__HAVE_FDT) -const char * -bwfm_sdio_sysname(void) -{ - static char sysfw[128]; - int len; - char *p; - - len = OF_getprop(OF_peer(0), "compatible", sysfw, sizeof(sysfw)); - if (len > 0 && len < sizeof(sysfw)) { - sysfw[len] = '\0'; - if ((p = strchr(sysfw, '/')) != NULL) - *p = '\0'; - return sysfw; - } - return NULL; -} -#else -const char * -bwfm_sdio_sysname(void) -{ - return NULL; -} -#endif - int bwfm_sdio_preinit(struct bwfm_softc *bwfm) { struct bwfm_sdio_softc *sc = (void *)bwfm; const char *chip = NULL; - const char *sysname = NULL; - char name[128]; uint32_t clk, reg; u_char *ucode, *nvram; size_t size = 0, nvsize, nvlen = 0; - int r; if (sc->sc_initialized) return 0; @@ -431,78 +403,9 @@ bwfm_sdio_preinit(struct bwfm_softc *bwfm) goto err; } - sysname = bwfm_sdio_sysname(); - - if (sysname != NULL) { - r = snprintf(name, sizeof(name), "brcmfmac%s-sdio.%s.bin", chip, - sysname); - if ((r > 0 && r < sizeof(name)) && - loadfirmware(name, &ucode, &size) != 0) - size = 0; - } - if (size == 0) { - snprintf(name, sizeof(name), "brcmfmac%s-sdio.bin", chip); - if (loadfirmware(name, &ucode, &size) != 0) { - printf("%s: failed loadfirmware of file %s\n", - DEVNAME(sc), name); - goto err; - } - } - - /* .txt needs to be processed first */ - if (sysname != NULL) { - r = snprintf(name, sizeof(name), "brcmfmac%s-sdio.%s.txt", chip, - sysname); - if ((r > 0 && r < sizeof(name)) && - loadfirmware(name, &nvram, &nvsize) == 0) { - if (bwfm_nvram_convert(nvram, nvsize, &nvlen) != 0) { - printf("%s: failed to process file %s\n", - DEVNAME(sc), name); - free(ucode, M_DEVBUF, size); - free(nvram, M_DEVBUF, nvsize); - goto err; - } - } - - } - if (nvlen == 0) { - snprintf(name, sizeof(name), "brcmfmac%s-sdio.txt", chip); - if (loadfirmware(name, &nvram, &nvsize) == 0) { - if (bwfm_nvram_convert(nvram, nvsize, &nvlen) != 0) { - printf("%s: failed to process file %s\n", - DEVNAME(sc), name); - free(ucode, M_DEVBUF, size); - free(nvram, M_DEVBUF, nvsize); - goto err; - } - } - } - - /* .nvram is the pre-processed version */ - if (nvlen == 0) { - snprintf(name, sizeof(name), "brcmfmac%s-sdio.nvram", chip); - if (loadfirmware(name, &nvram, &nvsize) == 0) - nvlen = nvsize; - } - - if (nvlen == 0) { - snprintf(name, sizeof(name), "brcmfmac%s-sdio.txt", chip); - printf("%s: failed loadfirmware of file %s\n", - DEVNAME(sc), name); - free(ucode, M_DEVBUF, size); + if (bwfm_loadfirmware(bwfm, chip, "-sdio", &ucode, &size, + &nvram, &nvsize, &nvlen) != 0) goto err; - } - - if (sysname != NULL) { - r = snprintf(name, sizeof(name), "brcmfmac%s-sdio.%s.clm_blob", - chip, sysname); - if (r > 0 && r < sizeof(name)) - loadfirmware(name, &bwfm->sc_clm, &bwfm->sc_clmsize); - } - if (bwfm->sc_clmsize == 0) { - snprintf(name, sizeof(name), "brcmfmac%s-sdio.clm_blob", chip); - loadfirmware(name, &bwfm->sc_clm, &bwfm->sc_clmsize); - } sc->sc_alp_only = 1; if (bwfm_sdio_load_microcode(sc, ucode, size,