diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2020-03-06 08:41:58 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2020-03-06 08:41:58 +0000 |
commit | 3cb00cbe60c1afc3e69c0eb46488430d19037c9c (patch) | |
tree | 24bc255f3805302ffd96fc807917a936cab456e0 /sys/dev | |
parent | 0f7d1eb38e8a6ee4cadc7a96203ed6d3db88f2e4 (diff) |
Process the NVRAM in bwfm(4) itself. So far we have relied on some
external tool to pre-process the NVRAM, even though it's simple to
do ourselves. This allows easier firmware distribution.
ok kurt@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/bwfm.c | 51 | ||||
-rw-r--r-- | sys/dev/ic/bwfmvar.h | 3 | ||||
-rw-r--r-- | sys/dev/sdmmc/if_bwfm_sdio.c | 36 |
3 files changed, 82 insertions, 8 deletions
diff --git a/sys/dev/ic/bwfm.c b/sys/dev/ic/bwfm.c index 377305b9b1a..a8b0ca0becd 100644 --- a/sys/dev/ic/bwfm.c +++ b/sys/dev/ic/bwfm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfm.c,v 1.69 2020/02/25 14:24:58 patrick Exp $ */ +/* $OpenBSD: bwfm.c,v 1.70 2020/03/06 08:41:57 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> @@ -2700,3 +2700,52 @@ bwfm_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) splx(s); return 0; } + +int +bwfm_nvram_convert(u_char *buf, size_t len, size_t *newlenp) +{ + u_char *src, *dst, *end = buf + len; + size_t count = 0, pad; + uint32_t token; + int skip = 0; + + for (src = buf, dst = buf; src != end; ++src) { + if (*src == '\n') { + if (count > 0) + *dst++ = '\0'; + count = 0; + skip = 0; + continue; + } + if (skip) + continue; + if (*src == '#' && count == 0) { + skip = 1; + continue; + } + if (*src == '\r') + continue; + *dst++ = *src; + ++count; + } + + count = dst - buf; + pad = roundup(count + 1, 4) - count; + + if (count + pad + sizeof(token) > len) + return 1; + + memset(dst, 0, pad); + count += pad; + dst += pad; + + token = (count / 4) & 0xffff; + token |= ~token << 16; + token = htole32(token); + + memcpy(dst, &token, sizeof(token)); + count += sizeof(token); + + *newlenp = count; + return 0; +} diff --git a/sys/dev/ic/bwfmvar.h b/sys/dev/ic/bwfmvar.h index 1d235fa857c..5080c17220d 100644 --- a/sys/dev/ic/bwfmvar.h +++ b/sys/dev/ic/bwfmvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfmvar.h,v 1.17 2020/02/25 14:24:58 patrick Exp $ */ +/* $OpenBSD: bwfmvar.h,v 1.18 2020/03/06 08:41:57 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> @@ -183,3 +183,4 @@ struct bwfm_core *bwfm_chip_get_pmu(struct bwfm_softc *); 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 *); diff --git a/sys/dev/sdmmc/if_bwfm_sdio.c b/sys/dev/sdmmc/if_bwfm_sdio.c index 652b3c35efc..ebdf75a93ae 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.31 2020/02/25 14:24:58 patrick Exp $ */ +/* $OpenBSD: if_bwfm_sdio.c,v 1.32 2020/03/06 08:41:57 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> @@ -348,9 +348,10 @@ bwfm_sdio_preinit(struct bwfm_softc *bwfm) struct bwfm_sdio_softc *sc = (void *)bwfm; const char *name = NULL; const char *nvname = NULL; + const char *txtname = NULL; uint32_t clk, reg; u_char *ucode, *nvram; - size_t size, nvlen; + size_t size, nvsize, nvlen; if (sc->sc_initialized) return 0; @@ -362,49 +363,60 @@ bwfm_sdio_preinit(struct bwfm_softc *bwfm) case BRCM_CC_4330_CHIP_ID: name = "brcmfmac4330-sdio.bin"; nvname = "brcmfmac4330-sdio.nvram"; + txtname = "brcmfmac4330-sdio.txt"; break; case BRCM_CC_4334_CHIP_ID: name = "brcmfmac4334-sdio.bin"; nvname = "brcmfmac4334-sdio.nvram"; + txtname = "brcmfmac4334-sdio.txt"; break; case BRCM_CC_4345_CHIP_ID: if (bwfm->sc_chip.ch_chiprev == 9) { name = "brcmfmac43456-sdio.bin"; nvname = "brcmfmac43456-sdio.nvram"; + txtname = "brcmfmac43456-sdio.txt"; } else { name = "brcmfmac43455-sdio.bin"; nvname = "brcmfmac43455-sdio.nvram"; + txtname = "brcmfmac43455-sdio.txt"; } break; case BRCM_CC_43340_CHIP_ID: name = "brcmfmac43340-sdio.bin"; nvname = "brcmfmac43340-sdio.nvram"; + txtname = "brcmfmac43340-sdio.txt"; break; case BRCM_CC_4335_CHIP_ID: if (bwfm->sc_chip.ch_chiprev < 2) { name = "brcmfmac4335-sdio.bin"; nvname = "brcmfmac4335-sdio.nvram"; + txtname = "brcmfmac4335-sdio.txt"; } else { name = "brcmfmac4339-sdio.bin"; nvname = "brcmfmac4339-sdio.nvram"; + txtname = "brcmfmac4339-sdio.txt"; } break; case BRCM_CC_4339_CHIP_ID: name = "brcmfmac4339-sdio.bin"; nvname = "brcmfmac4339-sdio.nvram"; + txtname = "brcmfmac4339-sdio.txt"; break; case BRCM_CC_43430_CHIP_ID: if (bwfm->sc_chip.ch_chiprev == 0) { name = "brcmfmac43430a0-sdio.bin"; nvname = "brcmfmac43430a0-sdio.nvram"; + txtname = "brcmfmac43430a0-sdio.txt"; } else { name = "brcmfmac43430-sdio.bin"; nvname = "brcmfmac43430-sdio.nvram"; + txtname = "brcmfmac43430-sdio.txt"; } break; case BRCM_CC_4356_CHIP_ID: name = "brcmfmac4356-sdio.bin"; nvname = "brcmfmac4356-sdio.nvram"; + txtname = "brcmfmac4356-sdio.txt"; break; default: printf("%s: unknown firmware for chip %s\n", @@ -418,9 +430,21 @@ bwfm_sdio_preinit(struct bwfm_softc *bwfm) goto err; } - if (loadfirmware(nvname, &nvram, &nvlen) != 0) { + if (loadfirmware(txtname, &nvram, &nvsize) == 0) { + /* .txt needs to be processed first */ + if (bwfm_nvram_convert(nvram, nvsize, &nvlen) != 0) { + printf("%s: failed to process file %s\n", + DEVNAME(sc), txtname); + free(ucode, M_DEVBUF, size); + free(nvram, M_DEVBUF, nvsize); + goto err; + } + } else if (loadfirmware(nvname, &nvram, &nvsize) == 0) { + /* .nvram is the pre-processed version */ + nvlen = nvsize; + } else { printf("%s: failed loadfirmware of file %s\n", - DEVNAME(sc), nvname); + DEVNAME(sc), txtname); free(ucode, M_DEVBUF, size); goto err; } @@ -431,12 +455,12 @@ bwfm_sdio_preinit(struct bwfm_softc *bwfm) printf("%s: could not load microcode\n", DEVNAME(sc)); free(ucode, M_DEVBUF, size); - free(nvram, M_DEVBUF, nvlen); + free(nvram, M_DEVBUF, nvsize); goto err; } sc->sc_alp_only = 0; free(ucode, M_DEVBUF, size); - free(nvram, M_DEVBUF, nvlen); + free(nvram, M_DEVBUF, nvsize); bwfm_sdio_clkctl(sc, CLK_AVAIL, 0); if (sc->sc_clkstate != CLK_AVAIL) |