-/* $OpenBSD: bwfm.c,v 1.90 2021/08/31 23:05:11 patrick Exp $ */
+/* $OpenBSD: bwfm.c,v 1.91 2021/10/23 12:48:17 kettenis Exp $ */
/*
* Copyright (c) 2010-2016 Broadcom Corporation
* Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se>
}
int
-bwfm_nvram_convert(u_char *buf, size_t len, size_t *newlenp)
+bwfm_nvram_convert(int node, u_char **bufp, size_t *sizep, size_t *newlenp)
{
- u_char *src, *dst, *end = buf + len;
- size_t count = 0, pad;
+ u_char *src, *dst, *end = *bufp + *sizep, *newbuf;
+ size_t count = 0, newsize, pad;
uint32_t token;
int skip = 0;
- for (src = buf, dst = buf; src != end; ++src) {
+ /*
+ * Allocate a new buffer with enough space for the MAC
+ * address, padding and final token.
+ */
+ newsize = *sizep + 64;
+ newbuf = malloc(newsize, M_DEVBUF, M_NOWAIT);
+ if (newbuf == NULL)
+ return 1;
+
+ for (src = *bufp, dst = newbuf; src != end; ++src) {
if (*src == '\n') {
if (count > 0)
*dst++ = '\0';
++count;
}
- count = dst - buf;
- pad = roundup(count + 1, 4) - count;
+#if defined(__HAVE_FDT)
+ /*
+ * Append MAC address if one is provided in the device tree.
+ * This is needed on Apple Silicon Macs.
+ */
+ if (node) {
+ u_char enaddr[ETHER_ADDR_LEN];
+ char macaddr[32];
+
+ if (OF_getprop(node, "local-mac-address",
+ enaddr, sizeof(enaddr))) {
+ snprintf(macaddr, sizeof(macaddr),
+ "macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
+ enaddr[0], enaddr[1], enaddr[2], enaddr[3],
+ enaddr[4], enaddr[5]);
+ if (*dst)
+ *dst++ = '\0';
+ memcpy(dst, macaddr, strlen(macaddr));
+ dst += strlen(macaddr);
+ }
+ }
+#endif
- if (count + pad + sizeof(token) > len)
- return 1;
+ count = dst - newbuf;
+ pad = roundup(count + 1, 4) - count;
memset(dst, 0, pad);
count += pad;
memcpy(dst, &token, sizeof(token));
count += sizeof(token);
+ free(*bufp, M_DEVBUF, *sizep);
+ *bufp = newbuf;
+ *sizep = newsize;
*newlenp = count;
return 0;
}
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 (r > 0 && r < sizeof(name))
+ loadfirmware(name, nvram, nvsize);
}
- if (*nvlen == 0) {
+ if (*nvsize == 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;
- }
+ loadfirmware(name, nvram, nvsize);
+ }
+
+ if (*nvsize != 0) {
+ if (bwfm_nvram_convert(sc->sc_node, nvram, nvsize, nvlen)) {
+ printf("%s: failed to process file %s\n",
+ DEVNAME(sc), name);
+ free(*ucode, M_DEVBUF, *size);
+ free(*nvram, M_DEVBUF, *nvsize);
+ return 1;
}
}
-/* $OpenBSD: bwfmvar.h,v 1.24 2021/08/31 23:05:11 patrick Exp $ */
+/* $OpenBSD: bwfmvar.h,v 1.25 2021/10/23 12:48:17 kettenis Exp $ */
/*
* Copyright (c) 2010-2016 Broadcom Corporation
* Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se>
#define BWFM_IO_TYPE_D11N 1
#define BWFM_IO_TYPE_D11AC 2
+ int sc_node;
int sc_initialized;
int sc_tx_timer;
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_nvram_convert(int, 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 *);
-/* $OpenBSD: if_bwfm_sdio.c,v 1.40 2021/06/06 10:48:30 aoyama Exp $ */
+/* $OpenBSD: if_bwfm_sdio.c,v 1.41 2021/10/23 12:48:17 kettenis Exp $ */
/*
* Copyright (c) 2010-2016 Broadcom Corporation
* Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se>
struct sdmmc_function **sc_sf;
struct rwlock *sc_lock;
void *sc_ih;
- int sc_node;
int sc_oob;
int sc_initialized;
#if defined(__HAVE_FDT)
if (sf->cookie)
- sc->sc_node = *(int *)sf->cookie;
+ sc->sc_sc.sc_node = *(int *)sf->cookie;
#endif
task_set(&sc->sc_task, bwfm_sdio_task, sc);
}
#if defined(__HAVE_FDT)
- if (sc->sc_node) {
- sc->sc_ih = fdt_intr_establish(sc->sc_node,
+ if (sc->sc_sc.sc_node) {
+ sc->sc_ih = fdt_intr_establish(sc->sc_sc.sc_node,
IPL_NET, bwfm_sdio_oob_intr, sc, DEVNAME(sc));
if (sc->sc_ih != NULL) {
bwfm_sdio_write_1(sc, BWFM_SDIO_CCCR_SEPINT,