From 9b1839171b9bedde62f71243a2427759701c36e7 Mon Sep 17 00:00:00 2001 From: kettenis Date: Fri, 4 Mar 2022 22:34:41 +0000 Subject: [PATCH] Add support for the BCM4387. The firmware for this variant uses a new scan command, which is indicated by the "scan_ver" firmware variable. ok patrick@ --- sys/dev/ic/bwfm.c | 117 ++++++++++++++++++++++++++++++++++++-- sys/dev/ic/bwfmreg.h | 32 +++++++++-- sys/dev/ic/bwfmvar.h | 4 +- sys/dev/pci/if_bwfm_pci.c | 3 +- 4 files changed, 145 insertions(+), 11 deletions(-) diff --git a/sys/dev/ic/bwfm.c b/sys/dev/ic/bwfm.c index dbd2793c98a..85b6dd5b896 100644 --- a/sys/dev/ic/bwfm.c +++ b/sys/dev/ic/bwfm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfm.c,v 1.99 2022/03/02 16:35:49 kettenis Exp $ */ +/* $OpenBSD: bwfm.c,v 1.100 2022/03/04 22:34:41 kettenis Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -273,6 +273,8 @@ bwfm_preinit(struct bwfm_softc *sc) nmode = 0; if (bwfm_fwvar_var_get_int(sc, "vhtmode", &vhtmode)) vhtmode = 0; + if (bwfm_fwvar_var_get_int(sc, "scan_ver", &sc->sc_scan_ver)) + sc->sc_scan_ver = 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)); @@ -2135,10 +2137,10 @@ bwfm_hostap(struct bwfm_softc *sc) #endif void -bwfm_scan(struct bwfm_softc *sc) +bwfm_scan_v0(struct bwfm_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - struct bwfm_escan_params *params; + struct bwfm_escan_params_v0 *params; uint32_t nssid = 0, nchan = 0; size_t params_size, chan_size, ssid_size; struct bwfm_ssid *ssid; @@ -2193,9 +2195,78 @@ bwfm_scan(struct bwfm_softc *sc) } void -bwfm_scan_abort(struct bwfm_softc *sc) +bwfm_scan_v2(struct bwfm_softc *sc) { - struct bwfm_escan_params *params; + struct ieee80211com *ic = &sc->sc_ic; + struct bwfm_escan_params_v2 *params; + uint32_t nssid = 0, nchan = 0; + size_t params_size, chan_size, ssid_size; + struct bwfm_ssid *ssid; + + if (ic->ic_flags & IEEE80211_F_ASCAN && + ic->ic_des_esslen && ic->ic_des_esslen <= BWFM_MAX_SSID_LEN) + nssid = 1; + + chan_size = roundup(nchan * sizeof(uint16_t), sizeof(uint32_t)); + ssid_size = sizeof(struct bwfm_ssid) * nssid; + params_size = sizeof(*params) + chan_size + ssid_size; + + params = malloc(params_size, M_TEMP, M_WAITOK | M_ZERO); + ssid = (struct bwfm_ssid *) + (((uint8_t *)params) + sizeof(*params) + chan_size); + + params->scan_params.version = 2; + params->scan_params.length = params_size; + memset(params->scan_params.bssid, 0xff, + sizeof(params->scan_params.bssid)); + params->scan_params.bss_type = 2; + params->scan_params.scan_type = BWFM_SCANTYPE_PASSIVE; + params->scan_params.nprobes = htole32(-1); + params->scan_params.active_time = htole32(-1); + params->scan_params.passive_time = htole32(-1); + params->scan_params.home_time = htole32(-1); + params->version = htole32(BWFM_ESCAN_REQ_VERSION_V2); + params->action = htole16(WL_ESCAN_ACTION_START); + params->sync_id = htole16(0x1234); + + if (ic->ic_flags & IEEE80211_F_ASCAN && + ic->ic_des_esslen && ic->ic_des_esslen <= BWFM_MAX_SSID_LEN) { + params->scan_params.scan_type = BWFM_SCANTYPE_ACTIVE; + ssid->len = htole32(ic->ic_des_esslen); + memcpy(ssid->ssid, ic->ic_des_essid, ic->ic_des_esslen); + } + + params->scan_params.channel_num = htole32( + nssid << BWFM_CHANNUM_NSSID_SHIFT | + nchan << BWFM_CHANNUM_NCHAN_SHIFT); + +#if 0 + /* Scan a specific channel */ + params->scan_params.channel_list[0] = htole16( + (1 & 0xff) << 0 | + (3 & 0x3) << 8 | + (2 & 0x3) << 10 | + (2 & 0x3) << 12 + ); +#endif + + bwfm_fwvar_var_set_data(sc, "escan", params, params_size); + free(params, M_TEMP, params_size); +} + +void +bwfm_scan(struct bwfm_softc *sc) +{ + if (sc->sc_scan_ver == 0) + bwfm_scan_v0(sc); + else + bwfm_scan_v2(sc); +} + +void +bwfm_scan_abort_v0(struct bwfm_softc *sc) +{ + struct bwfm_escan_params_v0 *params; size_t params_size; params_size = sizeof(*params) + sizeof(uint16_t); @@ -2217,6 +2288,42 @@ bwfm_scan_abort(struct bwfm_softc *sc) free(params, M_TEMP, params_size); } +void +bwfm_scan_abort_v2(struct bwfm_softc *sc) +{ + struct bwfm_escan_params_v2 *params; + size_t params_size; + + params_size = sizeof(*params) + sizeof(uint16_t); + params = malloc(params_size, M_TEMP, M_WAITOK | M_ZERO); + params->scan_params.version = 2; + params->scan_params.length = params_size; + memset(params->scan_params.bssid, 0xff, + sizeof(params->scan_params.bssid)); + params->scan_params.bss_type = 2; + params->scan_params.scan_type = BWFM_SCANTYPE_PASSIVE; + params->scan_params.nprobes = htole32(-1); + params->scan_params.active_time = htole32(-1); + params->scan_params.passive_time = htole32(-1); + params->scan_params.home_time = htole32(-1); + params->version = htole32(BWFM_ESCAN_REQ_VERSION_V2); + params->action = htole16(WL_ESCAN_ACTION_START); + params->sync_id = htole16(0x1234); + params->scan_params.channel_num = htole32(1); + params->scan_params.channel_list[0] = htole16(-1); + bwfm_fwvar_var_set_data(sc, "escan", params, params_size); + free(params, M_TEMP, params_size); +} + +void +bwfm_scan_abort(struct bwfm_softc *sc) +{ + if (sc->sc_scan_ver == 0) + bwfm_scan_abort_v0(sc); + else + bwfm_scan_abort_v2(sc); +} + struct mbuf * bwfm_newbuf(void) { diff --git a/sys/dev/ic/bwfmreg.h b/sys/dev/ic/bwfmreg.h index a58bcfebbcf..b67dc33b665 100644 --- a/sys/dev/ic/bwfmreg.h +++ b/sys/dev/ic/bwfmreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfmreg.h,v 1.25 2022/01/09 05:42:38 jsg Exp $ */ +/* $OpenBSD: bwfmreg.h,v 1.26 2022/03/04 22:34:41 kettenis Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -511,7 +511,7 @@ struct bwfm_ssid { uint8_t ssid[BWFM_MAX_SSID_LEN]; }; -struct bwfm_scan_params { +struct bwfm_scan_params_v0 { struct bwfm_ssid ssid; uint8_t bssid[ETHER_ADDR_LEN]; uint8_t bss_type; @@ -532,6 +532,22 @@ struct bwfm_scan_params { uint16_t channel_list[]; }; +struct bwfm_scan_params_v2 { + uint16_t version; + uint16_t length; + struct bwfm_ssid ssid; + uint8_t bssid[ETHER_ADDR_LEN]; + uint8_t bss_type; + uint8_t pad; + uint32_t scan_type; + uint32_t nprobes; + uint32_t active_time; + uint32_t passive_time; + uint32_t home_time; + uint32_t channel_num; + uint16_t channel_list[]; +}; + struct bwfm_scan_results { uint32_t buflen; uint32_t version; @@ -539,7 +555,7 @@ struct bwfm_scan_results { struct bwfm_bss_info bss_info[]; }; -struct bwfm_escan_params { +struct bwfm_escan_params_v0 { uint32_t version; #define BWFM_ESCAN_REQ_VERSION 1 uint16_t action; @@ -547,7 +563,15 @@ struct bwfm_escan_params { #define WL_ESCAN_ACTION_CONTINUE 2 #define WL_ESCAN_ACTION_ABORT 3 uint16_t sync_id; - struct bwfm_scan_params scan_params; + struct bwfm_scan_params_v0 scan_params; +}; + +struct bwfm_escan_params_v2 { + uint32_t version; +#define BWFM_ESCAN_REQ_VERSION_V2 2 + uint16_t action; + uint16_t sync_id; + struct bwfm_scan_params_v2 scan_params; }; struct bwfm_escan_results { diff --git a/sys/dev/ic/bwfmvar.h b/sys/dev/ic/bwfmvar.h index 41f548d3956..065ab349323 100644 --- a/sys/dev/ic/bwfmvar.h +++ b/sys/dev/ic/bwfmvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bwfmvar.h,v 1.29 2022/03/02 16:35:49 kettenis Exp $ */ +/* $OpenBSD: bwfmvar.h,v 1.30 2022/03/04 22:34:41 kettenis Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2016,2017 Patrick Wildt @@ -174,6 +174,8 @@ struct bwfm_softc { int sc_initialized; int sc_tx_timer; + int sc_scan_ver; + int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int); struct bwfm_host_cmd_ring sc_cmdq; diff --git a/sys/dev/pci/if_bwfm_pci.c b/sys/dev/pci/if_bwfm_pci.c index b72b15e0ffc..fd473fb7d8d 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.67 2022/03/02 16:35:49 kettenis Exp $ */ +/* $OpenBSD: if_bwfm_pci.c,v 1.68 2022/03/04 22:34:41 kettenis Exp $ */ /* * Copyright (c) 2010-2016 Broadcom Corporation * Copyright (c) 2017 Patrick Wildt @@ -344,6 +344,7 @@ static const struct pci_matchid bwfm_pci_devices[] = { { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM43602 }, { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4371 }, { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4378 }, + { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4387 }, }; int -- 2.20.1