summaryrefslogtreecommitdiff
path: root/sys/dev/sdmmc
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2020-03-14 01:30:35 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2020-03-14 01:30:35 +0000
commitd219da3aad761b8401ed0b75b56fd25333e5c8c5 (patch)
tree1862a874dba6a14455394ab200ffbe18f674ad0a /sys/dev/sdmmc
parentc027294d5b68e5debe672e174e99e09bda83ddef (diff)
On fdt platforms attempt to load system specific .txt and .bin files
with filenames constructed from the first compatible string of the root node. Matches the format used in the linux-firmware repository. If these are not found fallback to the generic filenames. When the compatible string contains a '/' as in 'solidrun,cubox-i/q' it will be handled as everything before the '/' so the cubox filename is brcmfmac4330-sdio.solidrun,cubox-i.txt. ok kurt@ patrick@
Diffstat (limited to 'sys/dev/sdmmc')
-rw-r--r--sys/dev/sdmmc/if_bwfm_sdio.c86
1 files changed, 71 insertions, 15 deletions
diff --git a/sys/dev/sdmmc/if_bwfm_sdio.c b/sys/dev/sdmmc/if_bwfm_sdio.c
index dade2d3b8d4..b053ab936ef 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.34 2020/03/13 15:30:58 patrick Exp $ */
+/* $OpenBSD: if_bwfm_sdio.c,v 1.35 2020/03/14 01:30:34 jsg Exp $ */
/*
* Copyright (c) 2010-2016 Broadcom Corporation
* Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se>
@@ -30,6 +30,7 @@
#if defined(__HAVE_FDT)
#include <machine/fdt.h>
+#include <dev/ofw/openfirm.h>
#endif
#if NBPFILTER > 0
@@ -342,15 +343,42 @@ 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, nvsize, nvlen = 0;
+ size_t size = 0, nvsize, nvlen = 0;
+ int r;
if (sc->sc_initialized)
return 0;
@@ -399,25 +427,53 @@ bwfm_sdio_preinit(struct bwfm_softc *bwfm)
goto err;
}
- 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;
- }
+ sysname = bwfm_sdio_sysname();
- /* .txt needs to be processed first */
- 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",
+ 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);
- free(ucode, M_DEVBUF, size);
- free(nvram, M_DEVBUF, nvsize);
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);