Module Name: src Committed By: mlelstv Date: Mon Mar 14 06:40:12 UTC 2022
Modified Files: src/sys/dev/ic: bwfm.c bwfmreg.h bwfmvar.h src/sys/dev/sdmmc: if_bwfm_sdio.c Log Message: Add OpenBSD to code to optionally load CLM (Country Locale Matrix) files. To generate a diff of this commit: cvs rdiff -u -r1.31 -r1.32 src/sys/dev/ic/bwfm.c cvs rdiff -u -r1.7 -r1.8 src/sys/dev/ic/bwfmreg.h cvs rdiff -u -r1.12 -r1.13 src/sys/dev/ic/bwfmvar.h cvs rdiff -u -r1.27 -r1.28 src/sys/dev/sdmmc/if_bwfm_sdio.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ic/bwfm.c diff -u src/sys/dev/ic/bwfm.c:1.31 src/sys/dev/ic/bwfm.c:1.32 --- src/sys/dev/ic/bwfm.c:1.31 Wed Jun 16 00:21:18 2021 +++ src/sys/dev/ic/bwfm.c Mon Mar 14 06:40:12 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: bwfm.c,v 1.31 2021/06/16 00:21:18 riastradh Exp $ */ +/* $NetBSD: bwfm.c,v 1.32 2022/03/14 06:40:12 mlelstv Exp $ */ /* $OpenBSD: bwfm.c,v 1.5 2017/10/16 22:27:16 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -99,6 +99,8 @@ void bwfm_chip_sysmem_ramsize(struct bw void bwfm_chip_tcm_ramsize(struct bwfm_softc *, struct bwfm_core *); void bwfm_chip_tcm_rambase(struct bwfm_softc *); +void bwfm_process_blob(struct bwfm_softc *, const char *, uint8_t **, + size_t *); int bwfm_proto_bcdc_query_dcmd(struct bwfm_softc *, int, int, char *, size_t *); int bwfm_proto_bcdc_set_dcmd(struct bwfm_softc *, int, @@ -152,6 +154,14 @@ static const struct { .suffix = "clm_blob", .description = "CLM", }, + [BWFM_FILETYPE_TXCAP] = { + .suffix = "txcap_blob", + .description = "TXCAP", + }, + [BWFM_FILETYPE_CAL] = { + .suffix = "cal_blob", + .description = "CAL", + }, }; static void @@ -320,6 +330,7 @@ bwfm_attach(struct bwfm_softc *sc) struct ifnet *ifp = &sc->sc_if; char fw_version[BWFM_DCMD_SMLEN]; uint32_t bandlist[3]; + int nmode, vhtmode; uint32_t tmp; int i, j, error; @@ -348,10 +359,15 @@ bwfm_attach(struct bwfm_softc *sc) return; } + printf("%s: address %s\n", DEVNAME(sc), ether_sprintf(ic->ic_myaddr)); + + bwfm_process_blob(sc, "clmload", &sc->sc_clm, &sc->sc_clmsize); + bwfm_process_blob(sc, "txcapload", &sc->sc_txcap, &sc->sc_txcapsize); + bwfm_process_blob(sc, "calload", &sc->sc_cal, &sc->sc_calsize); + memset(fw_version, 0, sizeof(fw_version)); if (bwfm_fwvar_var_get_data(sc, "ver", fw_version, sizeof(fw_version)) == 0) printf("%s: %s", DEVNAME(sc), fw_version); - printf("%s: address %s\n", DEVNAME(sc), ether_sprintf(ic->ic_myaddr)); ic->ic_ifp = ifp; ic->ic_phytype = IEEE80211_T_OFDM; @@ -377,6 +393,10 @@ bwfm_attach(struct bwfm_softc *sc) /* IBSS channel undefined for now. */ ic->ic_ibss_chan = &ic->ic_channels[0]; + if (bwfm_fwvar_var_get_int(sc, "nmode", &nmode)) + nmode = 0; + if (bwfm_fwvar_var_get_int(sc, "vhtmode", &vhtmode)) + vhtmode = 0; if (bwfm_fwvar_cmd_get_data(sc, BWFM_C_GET_BANDLIST, bandlist, sizeof(bandlist))) { printf("%s: couldn't get supported band list\n", DEVNAME(sc)); @@ -396,6 +416,9 @@ bwfm_attach(struct bwfm_softc *sc) ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; + if (nmode) + ic->ic_channels[chan].ic_flags |= + IEEE80211_CHAN_HT; } break; case BWFM_BAND_5G: @@ -407,8 +430,18 @@ bwfm_attach(struct bwfm_softc *sc) ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ); ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A; + if (nmode) + ic->ic_channels[chan].ic_flags |= + IEEE80211_CHAN_HT; + if (vhtmode) + ic->ic_channels[chan].ic_flags |= + IEEE80211_CHAN_VHT; } break; + default: + printf("%s: unsupported band 0x%x\n", DEVNAME(sc), + le32toh(bandlist[i])); + break; } } @@ -655,6 +688,8 @@ bwfm_stop(struct ifnet *ifp, int disable ifp->if_timer = 0; ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + ieee80211_new_state(ic, IEEE80211_S_INIT, -1); + memset(&join, 0, sizeof(join)); bwfm_fwvar_cmd_set_data(sc, BWFM_C_SET_SSID, &join, sizeof(join)); bwfm_fwvar_cmd_set_int(sc, BWFM_C_DOWN, 1); @@ -663,8 +698,7 @@ bwfm_stop(struct ifnet *ifp, int disable bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_INFRA, 0); bwfm_fwvar_cmd_set_int(sc, BWFM_C_UP, 1); bwfm_fwvar_cmd_set_int(sc, BWFM_C_SET_PM, BWFM_PM_FAST_PS); - - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); + bwfm_fwvar_var_set_int(sc, "mpc", 1); if (sc->sc_bus_ops->bs_stop) sc->sc_bus_ops->bs_stop(sc); @@ -1772,6 +1806,50 @@ err: return ret; } +void +bwfm_process_blob(struct bwfm_softc *sc, const char *var, uint8_t **blob, + size_t *blobsize) +{ + struct bwfm_dload_data *data; + size_t off, remain, len; + + if (*blob == NULL || *blobsize == 0) + return; + + off = 0; + remain = *blobsize; + data = kmem_alloc(sizeof(*data) + BWFM_DLOAD_MAX_LEN, KM_SLEEP); + + while (remain) { + len = uimin(remain, BWFM_DLOAD_MAX_LEN); + + data->flag = htole16(BWFM_DLOAD_FLAG_HANDLER_VER_1); + if (off == 0) + data->flag |= htole16(BWFM_DLOAD_FLAG_BEGIN); + if (remain <= BWFM_DLOAD_MAX_LEN) + data->flag |= htole16(BWFM_DLOAD_FLAG_END); + data->type = htole16(BWFM_DLOAD_TYPE_CLM); + data->len = htole32(len); + data->crc = 0; + memcpy(data->data, *blob + off, len); + + if (bwfm_fwvar_var_set_data(sc, var, data, + sizeof(*data) + len)) { + printf("%s: could not load blob (%s)\n", DEVNAME(sc), + var); + break; + } + + off += len; + remain -= len; + } + + kmem_free(data, sizeof(*data) + BWFM_DLOAD_MAX_LEN); + // kmem_free(*blob, *blobsize); + *blob = NULL; + *blobsize = 0; +} + /* FW Variable code */ int bwfm_fwvar_cmd_get_data(struct bwfm_softc *sc, int cmd, void *data, size_t len) Index: src/sys/dev/ic/bwfmreg.h diff -u src/sys/dev/ic/bwfmreg.h:1.7 src/sys/dev/ic/bwfmreg.h:1.8 --- src/sys/dev/ic/bwfmreg.h:1.7 Wed Jul 22 17:21:25 2020 +++ src/sys/dev/ic/bwfmreg.h Mon Mar 14 06:40:12 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: bwfmreg.h,v 1.7 2020/07/22 17:21:25 riastradh Exp $ */ +/* $NetBSD: bwfmreg.h,v 1.8 2022/03/14 06:40:12 mlelstv Exp $ */ /* $OpenBSD: bwfmreg.h,v 1.16 2018/02/07 21:44:09 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -799,4 +799,18 @@ struct bwfm_event { struct bwfm_event_msg msg; } __packed; +struct bwfm_dload_data { + uint16_t flag; +#define BWFM_DLOAD_FLAG_BEGIN (1 << 1) +#define BWFM_DLOAD_FLAG_END (1 << 2) +#define BWFM_DLOAD_FLAG_HANDLER_VER_1 (1 << 12) +#define BWFM_DLOAD_FLAG_HANDLER_VER_MASK (0xf << 12) + uint16_t type; +#define BWFM_DLOAD_TYPE_CLM 2 + uint32_t len; +#define BWFM_DLOAD_MAX_LEN 1400 + uint32_t crc; + uint8_t data[]; +} __packed; + #endif /* _DEV_IC_BWFMREG_H */ Index: src/sys/dev/ic/bwfmvar.h diff -u src/sys/dev/ic/bwfmvar.h:1.12 src/sys/dev/ic/bwfmvar.h:1.13 --- src/sys/dev/ic/bwfmvar.h:1.12 Wed Jul 22 17:23:52 2020 +++ src/sys/dev/ic/bwfmvar.h Mon Mar 14 06:40:12 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: bwfmvar.h,v 1.12 2020/07/22 17:23:52 riastradh Exp $ */ +/* $NetBSD: bwfmvar.h,v 1.13 2022/03/14 06:40:12 mlelstv Exp $ */ /* $OpenBSD: bwfmvar.h,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -50,6 +50,7 @@ struct pool_cache; #define BRCM_CC_43340_CHIP_ID 43340 #define BRCM_CC_43341_CHIP_ID 43341 #define BRCM_CC_43362_CHIP_ID 43362 +#define BRCM_CC_43364_CHIP_ID 43364 #define BRCM_CC_4335_CHIP_ID 0x4335 #define BRCM_CC_4339_CHIP_ID 0x4339 #define BRCM_CC_43430_CHIP_ID 43430 @@ -103,7 +104,9 @@ struct bwfm_firmware_selector { #define BWFM_FILETYPE_UCODE 0 #define BWFM_FILETYPE_NVRAM 1 #define BWFM_FILETYPE_CLM 2 -#define BWFM_NFILETYPES 3 +#define BWFM_FILETYPE_TXCAP 3 +#define BWFM_FILETYPE_CAL 4 +#define BWFM_NFILETYPES 5 struct bwfm_firmware_context { /* inputs */ @@ -235,6 +238,13 @@ struct bwfm_softc { struct bwfm_bss_info bss_info; uint8_t padding[BWFM_BSS_INFO_BUFLEN]; } sc_bss_buf; + + uint8_t *sc_clm; + size_t sc_clmsize; + uint8_t *sc_txcap; + size_t sc_txcapsize; + uint8_t *sc_cal; + size_t sc_calsize; }; void bwfm_attach(struct bwfm_softc *); Index: src/sys/dev/sdmmc/if_bwfm_sdio.c diff -u src/sys/dev/sdmmc/if_bwfm_sdio.c:1.27 src/sys/dev/sdmmc/if_bwfm_sdio.c:1.28 --- src/sys/dev/sdmmc/if_bwfm_sdio.c:1.27 Sun Aug 8 11:11:29 2021 +++ src/sys/dev/sdmmc/if_bwfm_sdio.c Mon Mar 14 06:40:12 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bwfm_sdio.c,v 1.27 2021/08/08 11:11:29 jmcneill Exp $ */ +/* $NetBSD: if_bwfm_sdio.c,v 1.28 2022/03/14 06:40:12 mlelstv Exp $ */ /* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation @@ -410,8 +410,7 @@ bwfm_sdio_attach(device_t parent, device core = bwfm_chip_get_core(&sc->sc_sc, BWFM_AGENT_CORE_SDIO_DEV); if (core->co_rev >= 12) { - reg = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_SLEEPCSR); - if ((reg & BWFM_SDIO_FUNC1_SLEEPCSR_KSO) == 0) { + reg = bwfm_sdio_read_1(sc, BWFM_SDIO_FUNC1_SLEEPCSR); if ((reg & BWFM_SDIO_FUNC1_SLEEPCSR_KSO) == 0) { reg |= BWFM_SDIO_FUNC1_SLEEPCSR_KSO; bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SLEEPCSR, reg); } @@ -444,8 +443,8 @@ bwfm_sdio_attachhook(device_t self) struct bwfm_sdio_softc *sc = device_private(self); struct bwfm_softc *bwfm = &sc->sc_sc; struct bwfm_firmware_context fwctx; - size_t ucsize = 0, nvlen = 0, nvsize = 0; - uint8_t *ucode, *nvram; + size_t ucsize = 0, nvlen = 0, nvsize = 0, clmsize = 0; + uint8_t *ucode, *nvram, *clm; uint32_t reg, clk; DPRINTF(("%s: chip 0x%08x rev %u\n", DEVNAME(sc), @@ -461,7 +460,10 @@ bwfm_sdio_attachhook(device_t self) bwfm_firmware_context_init(&fwctx, bwfm->sc_chip.ch_chip, bwfm->sc_chip.ch_chiprev, bwfm_fdt_get_model(), - BWFM_FWREQ(BWFM_FILETYPE_UCODE) | BWFM_FWREQ(BWFM_FILETYPE_NVRAM)); + BWFM_FWREQ(BWFM_FILETYPE_UCODE) + | BWFM_FWREQ(BWFM_FILETYPE_NVRAM) + | BWFM_FWOPT(BWFM_FILETYPE_CLM) + ); if (!bwfm_firmware_open(bwfm, bwfm_sdio_fwtab, &fwctx)) { /* Error message already displayed. */ @@ -472,6 +474,7 @@ bwfm_sdio_attachhook(device_t self) KASSERT(ucode != NULL); nvram = bwfm_firmware_data(&fwctx, BWFM_FILETYPE_NVRAM, &nvlen); KASSERT(nvram != NULL); + clm = bwfm_firmware_data(&fwctx, BWFM_FILETYPE_CLM, &clmsize); if (bwfm_nvram_convert(nvram, nvlen, &nvsize)) { aprint_error_dev(bwfm->sc_dev, @@ -548,6 +551,11 @@ bwfm_sdio_attachhook(device_t self) sc->sc_sc.sc_bus_ops = &bwfm_sdio_bus_ops; sc->sc_sc.sc_proto_ops = &bwfm_proto_bcdc_ops; + + /* used and cleared by bwfm_attach */ + sc->sc_sc.sc_clm = clm; + sc->sc_sc.sc_clmsize = clmsize; + bwfm_attach(&sc->sc_sc); sc->sc_bwfm_attached = true;