Refactor bwfm(4) firmware loading. The PCIe backend will need to be able
authorpatrick <patrick@openbsd.org>
Fri, 26 Feb 2021 00:07:41 +0000 (00:07 +0000)
committerpatrick <patrick@openbsd.org>
Fri, 26 Feb 2021 00:07:41 +0000 (00:07 +0000)
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.

sys/dev/ic/bwfm.c
sys/dev/ic/bwfmvar.h
sys/dev/pci/if_bwfm_pci.c
sys/dev/sdmmc/if_bwfm_sdio.c

index ff734bc..f720281 100644 (file)
@@ -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 <patrick@blueri.se>
 #include <sys/socket.h>
 #include <sys/sockio.h>
 
+#if defined(__HAVE_FDT)
+#include <machine/fdt.h>
+#include <dev/ofw/openfirm.h>
+#endif
+
 #if NBPFILTER > 0
 #include <net/bpf.h>
 #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;
+}
index 3262f32..2d143ae 100644 (file)
@@ -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 <patrick@blueri.se>
@@ -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 *);
index 557ace9..fb6014a 100644 (file)
@@ -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 <patrick@blueri.se>
@@ -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) {
index 799c9b3..694fbbc 100644 (file)
@@ -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 <patrick@blueri.se>
@@ -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,