From c6a4ab0d91fe97ec68f2f7fc86cf971d461a453d Mon Sep 17 00:00:00 2001 From: kettenis Date: Wed, 2 Mar 2022 16:35:49 +0000 Subject: [PATCH] The firmware for the bwfm(4) variants in Apple Silicon Macs has variants for different module types, module vendors and module revisions. Make our driver use the same naming scheme as Asahi Linux. ok patrick@ --- sys/dev/ic/bwfm.c | 75 +++++++++++++++++++++++---------------- sys/dev/ic/bwfmvar.h | 7 +++- sys/dev/pci/if_bwfm_pci.c | 21 ++++++++--- 3 files changed, 66 insertions(+), 37 deletions(-) diff --git a/sys/dev/ic/bwfm.c b/sys/dev/ic/bwfm.c index 9741456e067..dbd2793c98a 100644 --- a/sys/dev/ic/bwfm.c +++ b/sys/dev/ic/bwfm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfm.c,v 1.98 2022/01/05 05:18:24 dlg Exp $ */ +/* $OpenBSD: bwfm.c,v 1.99 2022/03/02 16:35:49 kettenis Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -70,6 +70,7 @@ void bwfm_update_nodes(struct bwfm_softc *); int bwfm_ioctl(struct ifnet *, u_long, caddr_t); int bwfm_media_change(struct ifnet *); +void bwfm_init_board_type(struct bwfm_softc *); void bwfm_process_blob(struct bwfm_softc *, char *, u_char **, size_t *); int bwfm_chip_attach(struct bwfm_softc *); @@ -964,6 +965,8 @@ bwfm_chip_attach(struct bwfm_softc *sc) if (sc->sc_buscore_ops->bc_setup) sc->sc_buscore_ops->bc_setup(sc); + bwfm_init_board_type(sc); + return 0; } @@ -3018,47 +3021,41 @@ out: *blobsize = 0; } -#if defined(__HAVE_FDT) -const char * -bwfm_sysname(void) +void +bwfm_init_board_type(struct bwfm_softc *sc) { - static char sysfw[128]; +#if defined(__HAVE_FDT) + char compat[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) + len = OF_getprop(OF_peer(0), "compatible", compat, sizeof(compat)); + if (len > 0 && len < sizeof(compat)) { + compat[len] = '\0'; + if ((p = strchr(compat, '/')) != NULL) *p = '\0'; - return sysfw; + strlcpy(sc->sc_board_type, compat, sizeof(sc->sc_board_type)); } - 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; + const char *board_type = NULL; char name[128]; int r; *ucode = *nvram = NULL; *size = *nvsize = *nvlen = 0; - sysname = bwfm_sysname(); + if (strlen(sc->sc_board_type) > 0) + board_type = sc->sc_board_type; - if (sysname != NULL) { + if (board_type != NULL) { r = snprintf(name, sizeof(name), "brcmfmac%s%s.%s.bin", chip, - bus, sysname); + bus, board_type); if ((r > 0 && r < sizeof(name)) && loadfirmware(name, ucode, size) != 0) *size = 0; @@ -3066,8 +3063,9 @@ bwfm_loadfirmware(struct bwfm_softc *sc, const char *chip, const char *bus, if (*size == 0) { snprintf(name, sizeof(name), "brcmfmac%s%s.bin", chip, bus); if (loadfirmware(name, ucode, size) != 0) { - snprintf(name, sizeof(name), "brcmfmac%s%s%s%s.bin", chip, bus, - sysname ? "." : "", sysname ? sysname : ""); + snprintf(name, sizeof(name), "brcmfmac%s%s%s%s.bin", + chip, bus, board_type ? "." : "", + board_type ? board_type : ""); printf("%s: failed loadfirmware of file %s\n", DEVNAME(sc), name); return 1; @@ -3075,9 +3073,24 @@ bwfm_loadfirmware(struct bwfm_softc *sc, const char *chip, const char *bus, } /* .txt needs to be processed first */ - if (sysname != NULL) { + if (strlen(sc->sc_modrev) > 0) { + r = snprintf(name, sizeof(name), + "brcmfmac%s%s.%s-%s-%s-%s.txt", chip, bus, board_type, + sc->sc_module, sc->sc_vendor, sc->sc_modrev); + if (r > 0 && r < sizeof(name)) + loadfirmware(name, nvram, nvsize); + } + if (*nvsize == 0 && strlen(sc->sc_vendor) > 0) { + r = snprintf(name, sizeof(name), + "brcmfmac%s%s.%s-%s-%s.txt", chip, bus, board_type, + sc->sc_module, sc->sc_vendor); + if (r > 0 && r < sizeof(name)) + loadfirmware(name, nvram, nvsize); + } + + if (*nvsize == 0 && board_type != NULL) { r = snprintf(name, sizeof(name), "brcmfmac%s%s.%s.txt", chip, - bus, sysname); + bus, board_type); if (r > 0 && r < sizeof(name)) loadfirmware(name, nvram, nvsize); } @@ -3106,16 +3119,16 @@ bwfm_loadfirmware(struct bwfm_softc *sc, const char *chip, const char *bus, if (*nvlen == 0 && strcmp(bus, "-sdio") == 0) { snprintf(name, sizeof(name), "brcmfmac%s%s%s%s.txt", chip, bus, - sysname ? "." : "", sysname ? sysname : ""); + board_type ? "." : "", board_type ? board_type : ""); printf("%s: failed loadfirmware of file %s\n", DEVNAME(sc), name); free(*ucode, M_DEVBUF, *size); return 1; } - if (sysname != NULL) { + if (board_type != NULL) { r = snprintf(name, sizeof(name), "brcmfmac%s%s.%s.clm_blob", - chip, bus, sysname); + chip, bus, board_type); if (r > 0 && r < sizeof(name)) loadfirmware(name, &sc->sc_clm, &sc->sc_clmsize); } @@ -3124,9 +3137,9 @@ bwfm_loadfirmware(struct bwfm_softc *sc, const char *chip, const char *bus, loadfirmware(name, &sc->sc_clm, &sc->sc_clmsize); } - if (sysname != NULL) { + if (board_type != NULL) { r = snprintf(name, sizeof(name), "brcmfmac%s%s.%s.txcap_blob", - chip, bus, sysname); + chip, bus, board_type); if (r > 0 && r < sizeof(name)) loadfirmware(name, &sc->sc_txcap, &sc->sc_txcapsize); } diff --git a/sys/dev/ic/bwfmvar.h b/sys/dev/ic/bwfmvar.h index 3f797897e63..41f548d3956 100644 --- a/sys/dev/ic/bwfmvar.h +++ b/sys/dev/ic/bwfmvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfmvar.h,v 1.28 2021/12/27 13:54:39 patrick Exp $ */ +/* $OpenBSD: bwfmvar.h,v 1.29 2022/03/02 16:35:49 kettenis Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -191,6 +191,11 @@ struct bwfm_softc { u_char *sc_cal; size_t sc_calsize; int sc_key_tasks; + + char sc_board_type[128]; + char sc_module[8]; + char sc_vendor[8]; + char sc_modrev[8]; }; void bwfm_attach(struct bwfm_softc *); diff --git a/sys/dev/pci/if_bwfm_pci.c b/sys/dev/pci/if_bwfm_pci.c index 070b592af88..b72b15e0ffc 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.66 2022/01/01 18:52:26 patrick Exp $ */ +/* $OpenBSD: if_bwfm_pci.c,v 1.67 2022/03/02 16:35:49 kettenis Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2017 Patrick Wildt @@ -490,7 +490,7 @@ bwfm_pci_preinit(struct bwfm_softc *bwfm) chip = "4377b3"; break; case BRCM_CC_4378_CHIP_ID: - chip = "4378"; + chip = "4378b1"; break; case BRCM_CC_4387_CHIP_ID: chip = "4387c2"; @@ -1060,6 +1060,7 @@ bwfm_pci_process_otp_tuple(struct bwfm_pci_softc *sc, uint8_t type, uint8_t size { struct bwfm_softc *bwfm = (void *)sc; char chiprev[8] = "", module[8] = "", modrev[8] = "", vendor[8] = "", chip[8] = ""; + char board_type[128] = ""; char product[16] = "unknown"; int len; @@ -1115,13 +1116,23 @@ next: snprintf(chip, sizeof(chip), bwfm->sc_chip.ch_chip > 40000 ? "%05d" : "%04x", bwfm->sc_chip.ch_chip); - if (sc->sc_sc.sc_node) - OF_getprop(sc->sc_sc.sc_node, "apple,module-instance", - product, sizeof(product)); + if (sc->sc_sc.sc_node) { + OF_getprop(sc->sc_sc.sc_node, "brcm,board-type", + board_type, sizeof(board_type)); + strlcpy(product, &board_type[6], sizeof(product)); + } printf("%s: firmware C-%s%s%s/P-%s_M-%s_V-%s__m-%s\n", DEVNAME(sc), chip, *chiprev ? "__s-" : "", *chiprev ? chiprev : "", product, module, vendor, modrev); + strlcpy(sc->sc_sc.sc_board_type, board_type, + sizeof(sc->sc_sc.sc_board_type)); + strlcpy(sc->sc_sc.sc_module, module, + sizeof(sc->sc_sc.sc_module)); + strlcpy(sc->sc_sc.sc_vendor, vendor, + sizeof(sc->sc_sc.sc_vendor)); + strlcpy(sc->sc_sc.sc_modrev, modrev, + sizeof(sc->sc_sc.sc_modrev)); break; case 0x80: /* Broadcom CIS */ DPRINTF(("%s: Broadcom CIS\n", DEVNAME(sc))); -- 2.20.1