Index: sys/conf/files =================================================================== --- sys/conf/files +++ sys/conf/files @@ -1312,15 +1312,17 @@ # XXX Work around clang warnings, until maintainer approves fix. dev/bwn/if_bwn.c optional bwn siba_bwn \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" -dev/bwn/if_bwn_pci.c optional bwn pci bhnd +dev/bwn/if_bwn_bhnd.c optional bwn bhnd +dev/bwn/if_bwn_pci.c optional bwn pci bhnd bhndb dev/bwn/if_bwn_phy_common.c optional bwn siba_bwn dev/bwn/if_bwn_phy_g.c optional bwn siba_bwn \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED} ${NO_WCONSTANT_CONVERSION}" dev/bwn/if_bwn_phy_lp.c optional bwn siba_bwn \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/bwn/if_bwn_phy_n.c optional bwn siba_bwn +dev/bwn/if_bwn_siba.c optional bwn siba_bwn +dev/bwn/if_bwn_siba_compat.c optional bwn bhnd !bwn_use_siba dev/bwn/if_bwn_util.c optional bwn siba_bwn -dev/bwn/bwn_mac.c optional bwn bhnd dev/cardbus/cardbus.c optional cardbus dev/cardbus/cardbus_cis.c optional cardbus dev/cardbus/cardbus_device.c optional cardbus Index: sys/conf/options =================================================================== --- sys/conf/options +++ sys/conf/options @@ -850,6 +850,7 @@ # options for the Brodacom BCM43xx driver (bwn) BWN_DEBUG opt_bwn.h BWN_GPL_PHY opt_bwn.h +BWN_USE_SIBA opt_bwn.h # Options for the SIBA driver SIBA_DEBUG opt_siba.h Index: sys/dev/bwn/bwn_mac.c =================================================================== --- sys/dev/bwn/bwn_mac.c +++ /dev/null @@ -1,174 +0,0 @@ -/*- - * Copyright (c) 2015 Landon Fuller - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGES. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_bwn.h" -#include "opt_wlan.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "bhnd_nvram_map.h" - -struct bwn_softc { - int mem_rid; - struct bhnd_resource *mem_res; - - int intr_rid; - struct resource *intr_res; -}; - -static const struct bwn_device { - uint16_t vendor; - uint16_t device; -} bwn_devices[] = { - { BHND_MFGID_BCM, BHND_COREID_D11 }, - { BHND_MFGID_INVALID, BHND_COREID_INVALID } -}; - -static int -bwn_probe(device_t dev) -{ - const struct bwn_device *id; - - for (id = bwn_devices; id->device != BHND_COREID_INVALID; id++) - { - if (bhnd_get_vendor(dev) == id->vendor && - bhnd_get_device(dev) == id->device) - { - device_set_desc(dev, bhnd_get_device_name(dev)); - return (BUS_PROBE_DEFAULT); - } - } - - return (ENXIO); -} - -static int -bwn_attach(device_t dev) -{ - struct bwn_softc *sc; - int error; - - sc = device_get_softc(dev); - - /* Allocate device resources */ - sc->mem_rid = 0; - sc->mem_res = bhnd_alloc_resource_any(dev, SYS_RES_MEMORY, - &sc->mem_rid, RF_ACTIVE); - if (sc->mem_res == NULL) { - device_printf(dev, "failed to allocate device registers\n"); - error = ENXIO; - goto cleanup; - } - - sc->intr_rid = 0; - sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->intr_rid, - RF_ACTIVE|RF_SHAREABLE); - if (sc->intr_res == NULL) { - device_printf(dev, "failed to allocate device interrupt\n"); - error = ENXIO; - goto cleanup; - } - - // TODO - uint8_t macaddr[6]; - error = bhnd_nvram_getvar_array(dev, BHND_NVAR_MACADDR, macaddr, - sizeof(macaddr), BHND_NVRAM_TYPE_UINT8_ARRAY); - if (error) - device_printf(dev, "error fetching macaddr: %d\n", error); - else - device_printf(dev, "got macaddr %6D\n", macaddr, ":"); - - return (0); - -cleanup: - if (sc->mem_res != NULL) - bhnd_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, - sc->mem_res); - - if (sc->intr_res != NULL) - bus_release_resource(dev, SYS_RES_IRQ, sc->intr_rid, - sc->intr_res); - - return (error); -} - -static int -bwn_detach(device_t dev) -{ - struct bwn_softc *sc; - - sc = device_get_softc(dev); - - bhnd_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem_res); - bus_release_resource(dev, SYS_RES_IRQ, sc->intr_rid, sc->intr_res); - - return (0); -} - -static int -bwn_suspend(device_t dev) -{ - return (0); -} - -static int -bwn_resume(device_t dev) -{ - return (0); -} - -static device_method_t bwn_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, bwn_probe), - DEVMETHOD(device_attach, bwn_attach), - DEVMETHOD(device_detach, bwn_detach), - DEVMETHOD(device_suspend, bwn_suspend), - DEVMETHOD(device_resume, bwn_resume), - DEVMETHOD_END -}; - -static devclass_t bwn_devclass; - -DEFINE_CLASS_0(bwn, bwn_driver, bwn_methods, sizeof(struct bwn_softc)); -DRIVER_MODULE(bwn_mac, bhnd, bwn_driver, bwn_devclass, 0, 0); -MODULE_DEPEND(bwn_mac, bhnd, 1, 1, 1); -MODULE_VERSION(bwn_mac, 1); Index: sys/dev/bwn/if_bwn.c =================================================================== --- sys/dev/bwn/if_bwn.c +++ sys/dev/bwn/if_bwn.c @@ -67,9 +67,6 @@ #include #include -#include -#include -#include #include #include @@ -77,6 +74,8 @@ #include #include +#include + #include #include @@ -498,10 +497,30 @@ SIBA_DEV(BROADCOM, 80211, 16, "Revision 16") }; +static const struct bwn_bus_ops * +bwn_get_bus_ops(device_t dev) +{ +#if BWN_USE_SIBA + return (NULL); +#else + devclass_t bus_cls; + + bus_cls = device_get_devclass(device_get_parent(dev)); + if (bus_cls == devclass_find("bhnd")) + return (&bwn_bhnd_bus_ops); + else + return (&bwn_siba_bus_ops); +#endif +} + static int bwn_probe(device_t dev) { - int i; + struct bwn_softc *sc; + int i; + + sc = device_get_softc(dev); + sc->sc_bus_ops = bwn_get_bus_ops(dev); for (i = 0; i < nitems(bwn_devs); i++) { if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor && @@ -513,7 +532,7 @@ return (ENXIO); } -static int +int bwn_attach(device_t dev) { struct bwn_mac *mac; @@ -525,6 +544,13 @@ sc->sc_debug = bwn_debug; #endif + sc->sc_bus_ops = bwn_get_bus_ops(dev); + if ((error = BWN_BUS_OPS_ATTACH(dev))) { + device_printf(sc->sc_dev, + "bus-specific initialization failed (%d)\n", error); + return (error); + } + if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { bwn_attach_pre(sc); bwn_sprom_bugfixes(dev); @@ -631,6 +657,7 @@ if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) pci_release_msi(dev); fail0: + BWN_BUS_OPS_DETACH(dev); free(mac, M_DEVBUF); return (error); } @@ -716,7 +743,7 @@ mac->mac_phy.detach(mac); } -static int +int bwn_detach(device_t dev) { struct bwn_softc *sc = device_get_softc(dev); @@ -756,6 +783,7 @@ mbufq_drain(&sc->sc_snd); bwn_release_firmware(mac); BWN_LOCK_DESTROY(sc); + BWN_BUS_OPS_DETACH(dev); return (0); } @@ -1153,36 +1181,30 @@ { struct bwn_softc *sc = mac->mac_sc; int error, have_bg = 0, have_a = 0; + uint32_t high; KASSERT(siba_get_revid(sc->sc_dev) >= 5, ("unsupported revision %d", siba_get_revid(sc->sc_dev))); - if (bwn_is_bus_siba(mac)) { - uint32_t high; + siba_powerup(sc->sc_dev, 0); + high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); + have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; + have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; + if (high & BWN_TGSHIGH_DUALPHY) { + have_bg = 1; + have_a = 1; + } - siba_powerup(sc->sc_dev, 0); - high = siba_read_4(sc->sc_dev, SIBA_TGSHIGH); - have_a = (high & BWN_TGSHIGH_HAVE_5GHZ) ? 1 : 0; - have_bg = (high & BWN_TGSHIGH_HAVE_2GHZ) ? 1 : 0; - if (high & BWN_TGSHIGH_DUALPHY) { - have_bg = 1; - have_a = 1; - } #if 0 - device_printf(sc->sc_dev, "%s: high=0x%08x, have_a=%d, have_bg=%d," - " deviceid=0x%04x, siba_deviceid=0x%04x\n", - __func__, - high, - have_a, - have_bg, - siba_get_pci_device(sc->sc_dev), - siba_get_chipid(sc->sc_dev)); + device_printf(sc->sc_dev, "%s: high=0x%08x, have_a=%d, have_bg=%d," + " deviceid=0x%04x, siba_deviceid=0x%04x\n", + __func__, + high, + have_a, + have_bg, + siba_get_pci_device(sc->sc_dev), + siba_get_chipid(sc->sc_dev)); #endif - } else { - device_printf(sc->sc_dev, "%s: not siba; bailing\n", __func__); - error = ENXIO; - goto fail; - } /* * Guess at whether it has A-PHY or G-PHY. @@ -1339,8 +1361,6 @@ /* * Reset - SIBA. - * - * XXX TODO: implement BCMA version! */ void bwn_reset_core(struct bwn_mac *mac, int g_mode) @@ -2267,7 +2287,6 @@ bwn_mac_phy_clock_set(mac, true); /* SIBA powerup */ - /* XXX TODO: BCMA powerup */ BWN_WRITE_2(mac, BWN_POWERUP_DELAY, siba_get_cc_powerdelay(sc->sc_dev)); return (error); } @@ -4717,10 +4736,10 @@ } /* - * SSB PHY reset. + * PHY reset. */ static void -bwn_phy_reset_siba(struct bwn_mac *mac) +bwn_phy_reset(struct bwn_mac *mac) { struct bwn_softc *sc = mac->mac_sc; @@ -4733,17 +4752,6 @@ DELAY(1000); } -static void -bwn_phy_reset(struct bwn_mac *mac) -{ - - if (bwn_is_bus_siba(mac)) { - bwn_phy_reset_siba(mac); - } else { - BWN_ERRPRINTF(mac->mac_sc, "%s: unknown bus!\n", __func__); - } -} - static int bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { @@ -7471,7 +7479,7 @@ DEVMETHOD(device_resume, bwn_resume), DEVMETHOD_END }; -static driver_t bwn_driver = { +driver_t bwn_driver = { "bwn", bwn_methods, sizeof(struct bwn_softc) @@ -7479,6 +7487,7 @@ static devclass_t bwn_devclass; DRIVER_MODULE(bwn, siba_bwn, bwn_driver, bwn_devclass, 0, 0); MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1); +MODULE_DEPEND(bwn, gpiobus, 1, 1, 1); MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */ MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */ MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1); Index: sys/dev/bwn/if_bwn_bhnd.c =================================================================== --- /dev/null +++ sys/dev/bwn/if_bwn_bhnd.c @@ -0,0 +1,107 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_bwn.h" +#include "opt_wlan.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "if_bwnvar.h" + +/* Supported device identifiers */ +static const struct bhnd_device bwn_devices[] = { + {{ + BHND_MATCH_CORE (BHND_MFGID_BCM, BHND_COREID_D11), + BHND_MATCH_CORE_REV (HWREV_RANGE(5, 16)) + }}, + + BHND_DEVICE_END +}; + +static int +bwn_bhnd_probe(device_t dev) +{ + const struct bhnd_device *id; + + id = bhnd_device_lookup(dev, bwn_devices, sizeof(bwn_devices[0])); + if (id == NULL) + return (ENXIO); + + bhnd_set_default_core_desc(dev); + return (BUS_PROBE_DEFAULT); +} + +static device_method_t bwn_bhnd_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, bwn_bhnd_probe), + + DEVMETHOD_END +}; + +static devclass_t bwn_devclass; + +DEFINE_CLASS_1(bwn, bwn_bhnd_driver, bwn_bhnd_methods, sizeof(struct bwn_softc), + bwn_driver); + +DRIVER_MODULE(bwn_bhnd, bhnd, bwn_bhnd_driver, bwn_devclass, 0, 0); +MODULE_DEPEND(bwn_bhnd, bhnd, 1, 1, 1); +MODULE_VERSION(bwn_bhnd, 1); Index: sys/dev/bwn/if_bwn_pci.c =================================================================== --- sys/dev/bwn/if_bwn_pci.c +++ sys/dev/bwn/if_bwn_pci.c @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2015-2016 Landon Fuller * All rights reserved. * @@ -6,25 +8,22 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGES. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #include @@ -64,7 +63,6 @@ BWN_BCM_DEV(BCM4301, "BCM4301 802.11b", BWN_QUIRK_ENET_HW_UNPOPULATED), - BWN_BCM_DEV(BCM4306, "BCM4306 802.11b/g", 0), BWN_BCM_DEV(BCM4306_D11G, "BCM4306 802.11g", 0), BWN_BCM_DEV(BCM4306_D11A, "BCM4306 802.11a", BWN_QUIRK_WLAN_DUALCORE), @@ -88,7 +86,7 @@ BWN_QUIRK_USBH_UNPOPULATED), BWN_BCM_DEV(BCM4321_D11N2G, "BCM4321 802.11n 2GHz", BWN_QUIRK_USBH_UNPOPULATED), - BWN_BCM_DEV(BCM4321_D11N2G, "BCM4321 802.11n 5GHz", + BWN_BCM_DEV(BCM4321_D11N5G, "BCM4321 802.11n 5GHz", BWN_QUIRK_UNTESTED|BWN_QUIRK_USBH_UNPOPULATED), BWN_BCM_DEV(BCM4322_D11N, "BCM4322 802.11n Dual-Band", 0), @@ -302,6 +300,7 @@ DRIVER_MODULE(bhndb, bwn_pci, bhndb_pci_driver, bhndb_devclass, NULL, NULL); MODULE_DEPEND(bwn_pci, bwn, 1, 1, 1); +MODULE_DEPEND(bwn_pci, bhnd, 1, 1, 1); MODULE_DEPEND(bwn_pci, bhndb, 1, 1, 1); MODULE_DEPEND(bwn_pci, bhndb_pci, 1, 1, 1); MODULE_DEPEND(bwn_pci, bcma_bhndb, 1, 1, 1); Index: sys/dev/bwn/if_bwn_pcivar.h =================================================================== --- sys/dev/bwn/if_bwn_pcivar.h +++ sys/dev/bwn/if_bwn_pcivar.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2015-2016 Landon Fuller * All rights reserved. * @@ -6,25 +8,22 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGES. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. * * $FreeBSD$ */ Index: sys/dev/bwn/if_bwn_phy_common.c =================================================================== --- sys/dev/bwn/if_bwn_phy_common.c +++ sys/dev/bwn/if_bwn_phy_common.c @@ -66,9 +66,6 @@ #include #include -#include -#include -#include #include #include @@ -76,6 +73,8 @@ #include #include +#include + #include #include @@ -149,17 +148,12 @@ /* XXX Only for N, HT and AC PHYs */ - /* XXX bhnd bus */ - if (bwn_is_bus_siba(mac)) { - tmp = siba_read_4(sc->sc_dev, SIBA_TGSLOW); - if (force) - tmp |= SIBA_TGSLOW_FGC; - else - tmp &= ~SIBA_TGSLOW_FGC; - siba_write_4(sc->sc_dev, SIBA_TGSLOW, tmp); - } else { - BWN_ERRPRINTF(sc, "%s: unknown bus!\n", __func__); - } + tmp = siba_read_4(sc->sc_dev, SIBA_TGSLOW); + if (force) + tmp |= SIBA_TGSLOW_FGC; + else + tmp &= ~SIBA_TGSLOW_FGC; + siba_write_4(sc->sc_dev, SIBA_TGSLOW, tmp); } int @@ -184,17 +178,12 @@ struct bwn_softc *sc = mac->mac_sc; uint32_t val; - /* XXX bhnd bus */ - if (bwn_is_bus_siba(mac)) { - val = siba_read_4(sc->sc_dev, SIBA_TGSLOW); - if (enabled) - val |= BWN_TGSLOW_MACPHYCLKEN; - else - val &= ~BWN_TGSLOW_MACPHYCLKEN; - siba_write_4(sc->sc_dev, SIBA_TGSLOW, val); - } else { - BWN_ERRPRINTF(sc, "%s: unknown bus!\n", __func__); - } + val = siba_read_4(sc->sc_dev, SIBA_TGSLOW); + if (enabled) + val |= BWN_TGSLOW_MACPHYCLKEN; + else + val &= ~BWN_TGSLOW_MACPHYCLKEN; + siba_write_4(sc->sc_dev, SIBA_TGSLOW, val); } /* http://bcm-v4.sipsolutions.net/802.11/PHY/BmacCorePllReset */ @@ -203,13 +192,8 @@ { struct bwn_softc *sc = mac->mac_sc; - /* XXX bhnd bus */ - if (bwn_is_bus_siba(mac)) { - siba_cc_write32(sc->sc_dev, SIBA_CC_CHIPCTL_ADDR, 0); - siba_cc_mask32(sc->sc_dev, SIBA_CC_CHIPCTL_DATA, ~0x4); - siba_cc_set32(sc->sc_dev, SIBA_CC_CHIPCTL_DATA, 0x4); - siba_cc_mask32(sc->sc_dev, SIBA_CC_CHIPCTL_DATA, ~0x4); - } else { - BWN_ERRPRINTF(sc, "%s: unknown bus!\n", __func__); - } + siba_cc_write32(sc->sc_dev, SIBA_CC_CHIPCTL_ADDR, 0); + siba_cc_mask32(sc->sc_dev, SIBA_CC_CHIPCTL_DATA, ~0x4); + siba_cc_set32(sc->sc_dev, SIBA_CC_CHIPCTL_DATA, 0x4); + siba_cc_mask32(sc->sc_dev, SIBA_CC_CHIPCTL_DATA, ~0x4); } Index: sys/dev/bwn/if_bwn_phy_g.c =================================================================== --- sys/dev/bwn/if_bwn_phy_g.c +++ sys/dev/bwn/if_bwn_phy_g.c @@ -65,9 +65,6 @@ #include #include -#include -#include -#include #include #include @@ -75,6 +72,8 @@ #include #include +#include + #include #include Index: sys/dev/bwn/if_bwn_phy_lp.c =================================================================== --- sys/dev/bwn/if_bwn_phy_lp.c +++ sys/dev/bwn/if_bwn_phy_lp.c @@ -65,9 +65,6 @@ #include #include -#include -#include -#include #include #include @@ -75,6 +72,8 @@ #include #include +#include + #include #include Index: sys/dev/bwn/if_bwn_phy_n.c =================================================================== --- sys/dev/bwn/if_bwn_phy_n.c +++ sys/dev/bwn/if_bwn_phy_n.c @@ -65,9 +65,6 @@ #include #include -#include -#include -#include #include #include @@ -75,6 +72,8 @@ #include #include +#include + #include #include Index: sys/dev/bwn/if_bwn_siba.h =================================================================== --- /dev/null +++ sys/dev/bwn/if_bwn_siba.h @@ -0,0 +1,491 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2016 Landon J. Fuller . + * Copyright (c) 2007 Bruce M. Simpson. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _IF_BWN_SIBA_H_ +#define _IF_BWN_SIBA_H_ + +/** If true, expose legacy siba_pci headers directly. Otherwise, + * we expose our siba/bhnd compatibility shims. */ +#ifndef BWN_USE_SIBA +#define BWN_USE_SIBA 0 +#endif + +struct bwn_softc; +struct siba_sprom_core_pwr_info; + +/* + * Legacy siba(4) bus API compatibility shims. + */ +struct bwn_bus_ops { + /* bus-specific initialization/finalization */ + int (*init)(device_t); + void (*fini)(device_t); + + /* compatibility shims */ + int (*pci_find_cap)(device_t, int, int *); + int (*pci_alloc_msi)(device_t, int *); + int (*pci_release_msi)(device_t); + int (*pci_msi_count)(device_t); + uint16_t (*get_vendor)(device_t); + uint16_t (*get_device)(device_t); + uint8_t (*get_revid)(device_t); + uint16_t (*get_pci_vendor)(device_t); + uint16_t (*get_pci_device)(device_t); + uint16_t (*get_pci_subvendor)(device_t); + uint16_t (*get_pci_subdevice)(device_t); + uint8_t (*get_pci_revid)(device_t); + uint16_t (*get_chipid)(device_t); + uint16_t (*get_chiprev)(device_t); + uint8_t (*get_chippkg)(device_t); + enum siba_type (*get_type)(device_t); + uint32_t (*get_cc_pmufreq)(device_t); + uint32_t (*get_cc_caps)(device_t); + uint16_t (*get_cc_powerdelay)(device_t); + uint8_t (*get_pcicore_revid)(device_t); + uint8_t (*sprom_get_rev)(device_t); + uint8_t *(*sprom_get_mac_80211bg)(device_t); + uint8_t *(*sprom_get_mac_80211a)(device_t); + uint8_t (*sprom_get_brev)(device_t); + uint8_t (*sprom_get_ccode)(device_t); + uint8_t (*sprom_get_ant_a)(device_t); + uint8_t (*sprom_get_ant_bg)(device_t); + uint16_t (*sprom_get_pa0b0)(device_t); + uint16_t (*sprom_get_pa0b1)(device_t); + uint16_t (*sprom_get_pa0b2)(device_t); + uint8_t (*sprom_get_gpio0)(device_t); + uint8_t (*sprom_get_gpio1)(device_t); + uint8_t (*sprom_get_gpio2)(device_t); + uint8_t (*sprom_get_gpio3)(device_t); + uint16_t (*sprom_get_maxpwr_bg)(device_t); + void (*sprom_set_maxpwr_bg)(device_t, uint16_t); + uint8_t (*sprom_get_rxpo2g)(device_t); + uint8_t (*sprom_get_rxpo5g)(device_t); + uint8_t (*sprom_get_tssi_bg)(device_t); + uint8_t (*sprom_get_tri2g)(device_t); + uint8_t (*sprom_get_tri5gl)(device_t); + uint8_t (*sprom_get_tri5g)(device_t); + uint8_t (*sprom_get_tri5gh)(device_t); + uint8_t (*sprom_get_rssisav2g)(device_t); + uint8_t (*sprom_get_rssismc2g)(device_t); + uint8_t (*sprom_get_rssismf2g)(device_t); + uint8_t (*sprom_get_bxa2g)(device_t); + uint8_t (*sprom_get_rssisav5g)(device_t); + uint8_t (*sprom_get_rssismc5g)(device_t); + uint8_t (*sprom_get_rssismf5g)(device_t); + uint8_t (*sprom_get_bxa5g)(device_t); + uint16_t (*sprom_get_cck2gpo)(device_t); + uint32_t (*sprom_get_ofdm2gpo)(device_t); + uint32_t (*sprom_get_ofdm5glpo)(device_t); + uint32_t (*sprom_get_ofdm5gpo)(device_t); + uint32_t (*sprom_get_ofdm5ghpo)(device_t); + uint16_t (*sprom_get_bf_lo)(device_t); + void (*sprom_set_bf_lo)(device_t, uint16_t); + uint16_t (*sprom_get_bf_hi)(device_t); + uint16_t (*sprom_get_bf2_lo)(device_t); + uint16_t (*sprom_get_bf2_hi)(device_t); + uint8_t (*sprom_get_fem_2ghz_tssipos)(device_t); + uint8_t (*sprom_get_fem_2ghz_extpa_gain)(device_t); + uint8_t (*sprom_get_fem_2ghz_pdet_range)(device_t); + uint8_t (*sprom_get_fem_2ghz_tr_iso)(device_t); + uint8_t (*sprom_get_fem_2ghz_antswlut)(device_t); + uint8_t (*sprom_get_fem_5ghz_extpa_gain)(device_t); + uint8_t (*sprom_get_fem_5ghz_pdet_range)(device_t); + uint8_t (*sprom_get_fem_5ghz_antswlut)(device_t); + uint8_t (*sprom_get_txpid_2g_0)(device_t); + uint8_t (*sprom_get_txpid_2g_1)(device_t); + uint8_t (*sprom_get_txpid_5gl_0)(device_t); + uint8_t (*sprom_get_txpid_5gl_1)(device_t); + uint8_t (*sprom_get_txpid_5g_0)(device_t); + uint8_t (*sprom_get_txpid_5g_1)(device_t); + uint8_t (*sprom_get_txpid_5gh_0)(device_t); + uint8_t (*sprom_get_txpid_5gh_1)(device_t); + uint16_t (*sprom_get_stbcpo)(device_t); + uint16_t (*sprom_get_cddpo)(device_t); + void (*powerup)(device_t, int); + int (*powerdown)(device_t); + uint16_t (*read_2)(device_t, uint16_t); + void (*write_2)(device_t, uint16_t, uint16_t); + uint32_t (*read_4)(device_t, uint16_t); + void (*write_4)(device_t, uint16_t, uint32_t); + void (*dev_up)(device_t, uint32_t); + void (*dev_down)(device_t, uint32_t); + int (*dev_isup)(device_t); + void (*pcicore_intr)(device_t); + uint32_t (*dma_translation)(device_t); + void (*read_multi_2)(device_t, void *, size_t, uint16_t); + void (*read_multi_4)(device_t, void *, size_t, uint16_t); + void (*write_multi_2)(device_t, const void *, size_t, uint16_t); + void (*write_multi_4)(device_t, const void *, size_t, uint16_t); + void (*barrier)(device_t, int); + void (*cc_pmu_set_ldovolt)(device_t, int, uint32_t); + void (*cc_pmu_set_ldoparef)(device_t, uint8_t); + void (*gpio_set)(device_t, uint32_t); + uint32_t (*gpio_get)(device_t); + void (*fix_imcfglobug)(device_t); + int (*sprom_get_core_power_info)(device_t, int, struct siba_sprom_core_pwr_info *); + int (*sprom_get_mcs2gpo)(device_t, uint16_t *); + int (*sprom_get_mcs5glpo)(device_t, uint16_t *); + int (*sprom_get_mcs5gpo)(device_t, uint16_t *); + int (*sprom_get_mcs5ghpo)(device_t, uint16_t *); + void (*pmu_spuravoid_pllupdate)(device_t, int); + void (*cc_set32)(device_t, uint32_t, uint32_t); + void (*cc_mask32)(device_t, uint32_t, uint32_t); + void (*cc_write32)(device_t, uint32_t, uint32_t); +}; + +#if BWN_USE_SIBA + +#include +#include +#include + +#define BWN_BUS_OPS_ATTACH(_dev) (0) +#define BWN_BUS_OPS_DETACH(_dev) + +#else /* !BWN_USE_SIBA */ + +struct bwn_bus_ops; + +extern const struct bwn_bus_ops bwn_siba_bus_ops; +extern const struct bwn_bus_ops bwn_bhnd_bus_ops; + +/* + * Declared in: + * /usr/home/landonf/Documents/Code/FreeBSD/svn/head/sys/dev/siba/siba_ids.h + */ + +struct siba_devid { + uint16_t sd_vendor; + uint16_t sd_device; + uint8_t sd_rev; + char *sd_desc; +}; + +#define SIBA_DEV(_vendor, _cid, _rev, _msg) \ + { SIBA_VID_##_vendor, SIBA_DEVID_##_cid, _rev, _msg } + +#define SIBA_DEVID_80211 0x812 +#define SIBA_VID_BROADCOM 0x4243 + +/* + * Declared in: + * /usr/home/landonf/Documents/Code/FreeBSD/svn/head/sys/dev/siba/sibareg.h + */ + +#define SIBA_CC_CAPS_PMU 0x10000000 +#define SIBA_CC_CHIPCTL 0x0028 +#define SIBA_CC_CHIPCTL_ADDR 0x0650 +#define SIBA_CC_CHIPCTL_DATA 0x0654 + +#define SIBA_DMA_TRANSLATION_MASK 0xc0000000 + +#define SIBA_TGSLOW 0x0f98 +#define SIBA_TGSLOW_FGC 0x00020000 + +#define SIBA_TGSHIGH 0x0f9c +#define SIBA_TGSHIGH_DMA64 0x10000000 + +#define SIBA_BOARDVENDOR_DELL 0x1028 +#define SIBA_BOARDVENDOR_BCM 0x14e4 + +#define SIBA_BOARD_BCM4309G 0x0421 +#define SIBA_BOARD_BU4306 0x0416 +#define SIBA_BOARD_BCM4321 0x046d + +#define SIBA_CHIPPACK_BCM4712S 1 + + +/* + * Declared in: + * /usr/home/landonf/Documents/Code/FreeBSD/svn/head/sys/dev/siba/sibavar.h + */ + +enum siba_type { + SIBA_TYPE_SSB /* unused */, + SIBA_TYPE_PCI, + SIBA_TYPE_PCMCIA +}; + +/* TODO: need a real country code table */ +enum { + SIBA_CCODE_JAPAN, + SIBA_CCODE_UNKNOWN +}; + +struct siba_sprom_core_pwr_info { + uint8_t itssi_2g; + uint8_t itssi_5g; + uint8_t maxpwr_2g; + uint8_t maxpwr_5gl; + uint8_t maxpwr_5g; + uint8_t maxpwr_5gh; + int16_t pa_2g[3]; + int16_t pa_5gl[4]; + int16_t pa_5g[4]; + int16_t pa_5gh[4]; +}; + +#define SIBA_LDO_PAREF 0 + +#define BWN_BUS_OPS_SC(_sc) \ + ((_sc)->sc_bus_ops) + +#define BWN_BUS_OPS(_dev) \ + BWN_BUS_OPS_SC((struct bwn_softc *)device_get_softc(_dev)) + +#define BWN_BUS_OPS_ATTACH(_dev) \ + BWN_BUS_OPS(_dev)->init(_dev) +#define BWN_BUS_OPS_DETACH(_dev) \ + BWN_BUS_OPS(_dev)->fini(_dev) + +#define pci_find_cap(_dev, capability, capreg) \ + BWN_BUS_OPS(_dev)->pci_find_cap(_dev, capability, capreg) +#define pci_alloc_msi(_dev, count) \ + BWN_BUS_OPS(_dev)->pci_alloc_msi(_dev, count) +#define pci_release_msi(_dev) \ + BWN_BUS_OPS(_dev)->pci_release_msi(_dev) +#define pci_msi_count(_dev) \ + BWN_BUS_OPS(_dev)->pci_msi_count(_dev) + +#define siba_get_vendor(_dev) \ + BWN_BUS_OPS(_dev)->get_vendor(_dev) +#define siba_get_device(_dev) \ + BWN_BUS_OPS(_dev)->get_device(_dev) +#define siba_get_revid(_dev) \ + BWN_BUS_OPS(_dev)->get_revid(_dev) +#define siba_get_pci_vendor(_dev) \ + BWN_BUS_OPS(_dev)->get_pci_vendor(_dev) +#define siba_get_pci_device(_dev) \ + BWN_BUS_OPS(_dev)->get_pci_device(_dev) +#define siba_get_pci_subvendor(_dev) \ + BWN_BUS_OPS(_dev)->get_pci_subvendor(_dev) +#define siba_get_pci_subdevice(_dev) \ + BWN_BUS_OPS(_dev)->get_pci_subdevice(_dev) +#define siba_get_pci_revid(_dev) \ + BWN_BUS_OPS(_dev)->get_pci_revid(_dev) +#define siba_get_chipid(_dev) \ + BWN_BUS_OPS(_dev)->get_chipid(_dev) +#define siba_get_chiprev(_dev) \ + BWN_BUS_OPS(_dev)->get_chiprev(_dev) +#define siba_get_chippkg(_dev) \ + BWN_BUS_OPS(_dev)->get_chippkg(_dev) +#define siba_get_type(_dev) \ + BWN_BUS_OPS(_dev)->get_type(_dev) +#define siba_get_cc_pmufreq(_dev) \ + BWN_BUS_OPS(_dev)->get_cc_pmufreq(_dev) +#define siba_get_cc_caps(_dev) \ + BWN_BUS_OPS(_dev)->get_cc_caps(_dev) +#define siba_get_cc_powerdelay(_dev) \ + BWN_BUS_OPS(_dev)->get_cc_powerdelay(_dev) +#define siba_get_pcicore_revid(_dev) \ + BWN_BUS_OPS(_dev)->get_pcicore_revid(_dev) +#define siba_sprom_get_rev(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_rev(_dev) +#define siba_sprom_get_mac_80211bg(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_mac_80211bg(_dev) +#define siba_sprom_get_mac_80211a(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_mac_80211a(_dev) +#define siba_sprom_get_brev(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_brev(_dev) +#define siba_sprom_get_ccode(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_ccode(_dev) +#define siba_sprom_get_ant_a(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_ant_a(_dev) +#define siba_sprom_get_ant_bg(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_ant_bg(_dev) +#define siba_sprom_get_pa0b0(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_pa0b0(_dev) +#define siba_sprom_get_pa0b1(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_pa0b1(_dev) +#define siba_sprom_get_pa0b2(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_pa0b2(_dev) +#define siba_sprom_get_gpio0(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_gpio0(_dev) +#define siba_sprom_get_gpio1(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_gpio1(_dev) +#define siba_sprom_get_gpio2(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_gpio2(_dev) +#define siba_sprom_get_gpio3(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_gpio3(_dev) +#define siba_sprom_get_maxpwr_bg(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_maxpwr_bg(_dev) +#define siba_sprom_set_maxpwr_bg(_dev, t) \ + BWN_BUS_OPS(_dev)->sprom_set_maxpwr_bg(_dev, t) +#define siba_sprom_get_rxpo2g(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_rxpo2g(_dev) +#define siba_sprom_get_rxpo5g(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_rxpo5g(_dev) +#define siba_sprom_get_tssi_bg(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_tssi_bg(_dev) +#define siba_sprom_get_tri2g(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_tri2g(_dev) +#define siba_sprom_get_tri5gl(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_tri5gl(_dev) +#define siba_sprom_get_tri5g(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_tri5g(_dev) +#define siba_sprom_get_tri5gh(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_tri5gh(_dev) +#define siba_sprom_get_rssisav2g(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_rssisav2g(_dev) +#define siba_sprom_get_rssismc2g(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_rssismc2g(_dev) +#define siba_sprom_get_rssismf2g(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_rssismf2g(_dev) +#define siba_sprom_get_bxa2g(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_bxa2g(_dev) +#define siba_sprom_get_rssisav5g(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_rssisav5g(_dev) +#define siba_sprom_get_rssismc5g(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_rssismc5g(_dev) +#define siba_sprom_get_rssismf5g(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_rssismf5g(_dev) +#define siba_sprom_get_bxa5g(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_bxa5g(_dev) +#define siba_sprom_get_cck2gpo(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_cck2gpo(_dev) +#define siba_sprom_get_ofdm2gpo(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_ofdm2gpo(_dev) +#define siba_sprom_get_ofdm5glpo(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_ofdm5glpo(_dev) +#define siba_sprom_get_ofdm5gpo(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_ofdm5gpo(_dev) +#define siba_sprom_get_ofdm5ghpo(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_ofdm5ghpo(_dev) +#define siba_sprom_get_bf_lo(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_bf_lo(_dev) +#define siba_sprom_set_bf_lo(_dev, t) \ + BWN_BUS_OPS(_dev)->sprom_set_bf_lo(_dev, t) +#define siba_sprom_get_bf_hi(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_bf_hi(_dev) +#define siba_sprom_get_bf2_lo(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_bf2_lo(_dev) +#define siba_sprom_get_bf2_hi(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_bf2_hi(_dev) +#define siba_sprom_get_fem_2ghz_tssipos(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_fem_2ghz_tssipos(_dev) +#define siba_sprom_get_fem_2ghz_extpa_gain(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_fem_2ghz_extpa_gain(_dev) +#define siba_sprom_get_fem_2ghz_pdet_range(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_fem_2ghz_pdet_range(_dev) +#define siba_sprom_get_fem_2ghz_tr_iso(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_fem_2ghz_tr_iso(_dev) +#define siba_sprom_get_fem_2ghz_antswlut(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_fem_2ghz_antswlut(_dev) +#define siba_sprom_get_fem_5ghz_extpa_gain(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_fem_5ghz_extpa_gain(_dev) +#define siba_sprom_get_fem_5ghz_pdet_range(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_fem_5ghz_pdet_range(_dev) +#define siba_sprom_get_fem_5ghz_antswlut(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_fem_5ghz_antswlut(_dev) +#define siba_sprom_get_txpid_2g_0(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_txpid_2g_0(_dev) +#define siba_sprom_get_txpid_2g_1(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_txpid_2g_1(_dev) +#define siba_sprom_get_txpid_5gl_0(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_txpid_5gl_0(_dev) +#define siba_sprom_get_txpid_5gl_1(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_txpid_5gl_1(_dev) +#define siba_sprom_get_txpid_5g_0(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_txpid_5g_0(_dev) +#define siba_sprom_get_txpid_5g_1(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_txpid_5g_1(_dev) +#define siba_sprom_get_txpid_5gh_0(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_txpid_5gh_0(_dev) +#define siba_sprom_get_txpid_5gh_1(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_txpid_5gh_1(_dev) +#define siba_sprom_get_stbcpo(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_stbcpo(_dev) +#define siba_sprom_get_cddpo(_dev) \ + BWN_BUS_OPS(_dev)->sprom_get_cddpo(_dev) +#define siba_powerup(_dev, _arg1) \ + BWN_BUS_OPS(_dev)->powerup(_dev, _arg1) +#define siba_powerdown(_dev) \ + BWN_BUS_OPS(_dev)->powerdown(_dev) +#define siba_read_2(_dev, _arg1) \ + BWN_BUS_OPS(_dev)->read_2(_dev, _arg1) +#define siba_write_2(_dev, _arg1, _arg2) \ + BWN_BUS_OPS(_dev)->write_2(_dev, _arg1, _arg2) +#define siba_read_4(_dev, _arg1) \ + BWN_BUS_OPS(_dev)->read_4(_dev, _arg1) +#define siba_write_4(_dev, _arg1, _arg2) \ + BWN_BUS_OPS(_dev)->write_4(_dev, _arg1, _arg2) +#define siba_dev_up(_dev, _arg1) \ + BWN_BUS_OPS(_dev)->dev_up(_dev, _arg1) +#define siba_dev_down(_dev, _arg1) \ + BWN_BUS_OPS(_dev)->dev_down(_dev, _arg1) +#define siba_dev_isup(_dev) \ + BWN_BUS_OPS(_dev)->dev_isup(_dev) +#define siba_pcicore_intr(_dev) \ + BWN_BUS_OPS(_dev)->pcicore_intr(_dev) +#define siba_dma_translation(_dev) \ + BWN_BUS_OPS(_dev)->dma_translation(_dev) +#define siba_read_multi_2(_dev, _arg1, _arg2, _arg3) \ + BWN_BUS_OPS(_dev)->read_multi_2(_dev, _arg1, _arg2, _arg3) +#define siba_read_multi_4(_dev, _arg1, _arg2, _arg3) \ + BWN_BUS_OPS(_dev)->read_multi_4(_dev, _arg1, _arg2, _arg3) +#define siba_write_multi_2(_dev, _arg1, _arg2, _arg3) \ + BWN_BUS_OPS(_dev)->write_multi_2(_dev, _arg1, _arg2, _arg3) +#define siba_write_multi_4(_dev, _arg1, _arg2, _arg3) \ + BWN_BUS_OPS(_dev)->write_multi_4(_dev, _arg1, _arg2, _arg3) +#define siba_barrier(_dev, _arg1) \ + BWN_BUS_OPS(_dev)->barrier(_dev, _arg1) +#define siba_cc_pmu_set_ldovolt(_dev, _arg1, _arg2) \ + BWN_BUS_OPS(_dev)->cc_pmu_set_ldovolt(_dev, _arg1, _arg2) +#define siba_cc_pmu_set_ldoparef(_dev, _arg1) \ + BWN_BUS_OPS(_dev)->cc_pmu_set_ldoparef(_dev, _arg1) +#define siba_gpio_set(_dev, _arg1) \ + BWN_BUS_OPS(_dev)->gpio_set(_dev, _arg1) +#define siba_gpio_get(_dev) \ + BWN_BUS_OPS(_dev)->gpio_get(_dev) +#define siba_fix_imcfglobug(_dev) \ + BWN_BUS_OPS(_dev)->fix_imcfglobug(_dev) +#define siba_sprom_get_core_power_info(_dev, _arg1, _arg2) \ + BWN_BUS_OPS(_dev)->sprom_get_core_power_info(_dev, _arg1, _arg2) +#define siba_sprom_get_mcs2gpo(_dev, _arg1) \ + BWN_BUS_OPS(_dev)->sprom_get_mcs2gpo(_dev, _arg1) +#define siba_sprom_get_mcs5glpo(_dev, _arg1) \ + BWN_BUS_OPS(_dev)->sprom_get_mcs5glpo(_dev, _arg1) +#define siba_sprom_get_mcs5gpo(_dev, _arg1) \ + BWN_BUS_OPS(_dev)->sprom_get_mcs5gpo(_dev, _arg1) +#define siba_sprom_get_mcs5ghpo(_dev, _arg1) \ + BWN_BUS_OPS(_dev)->sprom_get_mcs5ghpo(_dev, _arg1) +#define siba_pmu_spuravoid_pllupdate(_dev, _arg1) \ + BWN_BUS_OPS(_dev)->pmu_spuravoid_pllupdate(_dev, _arg1) +#define siba_cc_set32(_dev, _arg1, _arg2) \ + BWN_BUS_OPS(_dev)->cc_set32(_dev, _arg1, _arg2) +#define siba_cc_mask32(_dev, _arg1, _arg2) \ + BWN_BUS_OPS(_dev)->cc_mask32(_dev, _arg1, _arg2) +#define siba_cc_write32(_dev, _arg1, _arg2) \ + BWN_BUS_OPS(_dev)->cc_write32(_dev, _arg1, _arg2) + +#endif /* BWN_USE_SIBA */ + +#endif /* _IF_BWN_SIBA_H_ */ Index: sys/dev/bwn/if_bwn_siba.c =================================================================== --- /dev/null +++ sys/dev/bwn/if_bwn_siba.c @@ -0,0 +1,171 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2016 Landon Fuller + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define BWN_USE_SIBA 1 +#include "if_bwn_siba.h" + +/** Legacy siba(4) bus operations */ + +static int +bwn_siba_bus_ops_init(device_t dev) +{ + return (0); +} + +static void +bwn_siba_bus_ops_fini(device_t dev) +{ +} + +const struct bwn_bus_ops bwn_siba_bus_ops = { + .init = bwn_siba_bus_ops_init, + .fini = bwn_siba_bus_ops_fini, + .pci_find_cap = pci_find_cap, + .pci_alloc_msi = pci_alloc_msi, + .pci_release_msi = pci_release_msi, + .pci_msi_count = pci_msi_count, + .get_vendor = siba_get_vendor, + .get_device = siba_get_device, + .get_revid = siba_get_revid, + .get_pci_vendor = siba_get_pci_vendor, + .get_pci_device = siba_get_pci_device, + .get_pci_subvendor = siba_get_pci_subvendor, + .get_pci_subdevice = siba_get_pci_subdevice, + .get_pci_revid = siba_get_pci_revid, + .get_chipid = siba_get_chipid, + .get_chiprev = siba_get_chiprev, + .get_chippkg = siba_get_chippkg, + .get_type = siba_get_type, + .get_cc_pmufreq = siba_get_cc_pmufreq, + .get_cc_caps = siba_get_cc_caps, + .get_cc_powerdelay = siba_get_cc_powerdelay, + .get_pcicore_revid = siba_get_pcicore_revid, + .sprom_get_rev = siba_sprom_get_rev, + .sprom_get_mac_80211bg = siba_sprom_get_mac_80211bg, + .sprom_get_mac_80211a = siba_sprom_get_mac_80211a, + .sprom_get_brev = siba_sprom_get_brev, + .sprom_get_ccode = siba_sprom_get_ccode, + .sprom_get_ant_a = siba_sprom_get_ant_a, + .sprom_get_ant_bg = siba_sprom_get_ant_bg, + .sprom_get_pa0b0 = siba_sprom_get_pa0b0, + .sprom_get_pa0b1 = siba_sprom_get_pa0b1, + .sprom_get_pa0b2 = siba_sprom_get_pa0b2, + .sprom_get_gpio0 = siba_sprom_get_gpio0, + .sprom_get_gpio1 = siba_sprom_get_gpio1, + .sprom_get_gpio2 = siba_sprom_get_gpio2, + .sprom_get_gpio3 = siba_sprom_get_gpio3, + .sprom_get_maxpwr_bg = siba_sprom_get_maxpwr_bg, + .sprom_set_maxpwr_bg = siba_sprom_set_maxpwr_bg, + .sprom_get_rxpo2g = siba_sprom_get_rxpo2g, + .sprom_get_rxpo5g = siba_sprom_get_rxpo5g, + .sprom_get_tssi_bg = siba_sprom_get_tssi_bg, + .sprom_get_tri2g = siba_sprom_get_tri2g, + .sprom_get_tri5gl = siba_sprom_get_tri5gl, + .sprom_get_tri5g = siba_sprom_get_tri5g, + .sprom_get_tri5gh = siba_sprom_get_tri5gh, + .sprom_get_rssisav2g = siba_sprom_get_rssisav2g, + .sprom_get_rssismc2g = siba_sprom_get_rssismc2g, + .sprom_get_rssismf2g = siba_sprom_get_rssismf2g, + .sprom_get_bxa2g = siba_sprom_get_bxa2g, + .sprom_get_rssisav5g = siba_sprom_get_rssisav5g, + .sprom_get_rssismc5g = siba_sprom_get_rssismc5g, + .sprom_get_rssismf5g = siba_sprom_get_rssismf5g, + .sprom_get_bxa5g = siba_sprom_get_bxa5g, + .sprom_get_cck2gpo = siba_sprom_get_cck2gpo, + .sprom_get_ofdm2gpo = siba_sprom_get_ofdm2gpo, + .sprom_get_ofdm5glpo = siba_sprom_get_ofdm5glpo, + .sprom_get_ofdm5gpo = siba_sprom_get_ofdm5gpo, + .sprom_get_ofdm5ghpo = siba_sprom_get_ofdm5ghpo, + .sprom_get_bf_lo = siba_sprom_get_bf_lo, + .sprom_set_bf_lo = siba_sprom_set_bf_lo, + .sprom_get_bf_hi = siba_sprom_get_bf_hi, + .sprom_get_bf2_lo = siba_sprom_get_bf2_lo, + .sprom_get_bf2_hi = siba_sprom_get_bf2_hi, + .sprom_get_fem_2ghz_tssipos = siba_sprom_get_fem_2ghz_tssipos, + .sprom_get_fem_2ghz_extpa_gain = siba_sprom_get_fem_2ghz_extpa_gain, + .sprom_get_fem_2ghz_pdet_range = siba_sprom_get_fem_2ghz_pdet_range, + .sprom_get_fem_2ghz_tr_iso = siba_sprom_get_fem_2ghz_tr_iso, + .sprom_get_fem_2ghz_antswlut = siba_sprom_get_fem_2ghz_antswlut, + .sprom_get_fem_5ghz_extpa_gain = siba_sprom_get_fem_5ghz_extpa_gain, + .sprom_get_fem_5ghz_pdet_range = siba_sprom_get_fem_5ghz_pdet_range, + .sprom_get_fem_5ghz_antswlut = siba_sprom_get_fem_5ghz_antswlut, + .sprom_get_txpid_2g_0 = siba_sprom_get_txpid_2g_0, + .sprom_get_txpid_2g_1 = siba_sprom_get_txpid_2g_1, + .sprom_get_txpid_5gl_0 = siba_sprom_get_txpid_5gl_0, + .sprom_get_txpid_5gl_1 = siba_sprom_get_txpid_5gl_1, + .sprom_get_txpid_5g_0 = siba_sprom_get_txpid_5g_0, + .sprom_get_txpid_5g_1 = siba_sprom_get_txpid_5g_1, + .sprom_get_txpid_5gh_0 = siba_sprom_get_txpid_5gh_0, + .sprom_get_txpid_5gh_1 = siba_sprom_get_txpid_5gh_1, + .sprom_get_stbcpo = siba_sprom_get_stbcpo, + .sprom_get_cddpo = siba_sprom_get_cddpo, + .powerup = siba_powerup, + .powerdown = siba_powerdown, + .read_2 = siba_read_2, + .write_2 = siba_write_2, + .read_4 = siba_read_4, + .write_4 = siba_write_4, + .dev_up = siba_dev_up, + .dev_down = siba_dev_down, + .dev_isup = siba_dev_isup, + .pcicore_intr = siba_pcicore_intr, + .dma_translation = siba_dma_translation, + .read_multi_2 = siba_read_multi_2, + .read_multi_4 = siba_read_multi_4, + .write_multi_2 = siba_write_multi_2, + .write_multi_4 = siba_write_multi_4, + .barrier = siba_barrier, + .cc_pmu_set_ldovolt = siba_cc_pmu_set_ldovolt, + .cc_pmu_set_ldoparef = siba_cc_pmu_set_ldoparef, + .gpio_set = siba_gpio_set, + .gpio_get = siba_gpio_get, + .fix_imcfglobug = siba_fix_imcfglobug, + .sprom_get_core_power_info = siba_sprom_get_core_power_info, + .sprom_get_mcs2gpo = siba_sprom_get_mcs2gpo, + .sprom_get_mcs5glpo = siba_sprom_get_mcs5glpo, + .sprom_get_mcs5gpo = siba_sprom_get_mcs5gpo, + .sprom_get_mcs5ghpo = siba_sprom_get_mcs5ghpo, + .pmu_spuravoid_pllupdate = siba_pmu_spuravoid_pllupdate, + .cc_set32 = siba_cc_set32, + .cc_mask32 = siba_cc_mask32, + .cc_write32 = siba_cc_write32, +}; Index: sys/dev/bwn/if_bwn_siba_compat.h =================================================================== --- /dev/null +++ sys/dev/bwn/if_bwn_siba_compat.h @@ -0,0 +1,102 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2016 Landon J. Fuller . + * Copyright (c) 2017 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _IF_BWN_SIBA_COMPAT_H_ +#define _IF_BWN_SIBA_COMPAT_H_ + +#define BWN_USE_SIBA 0 +#include "if_bwn_siba.h" + +#include "if_bwnvar.h" + +#define BWN_BHND_NUM_CORE_PWR 4 + +/** + * Compatiblity shim state. + */ +struct bwn_bhnd_ctx { + device_t chipc_dev; /**< ChipCommon device */ + device_t gpio_dev; /**< GPIO device */ + + device_t pmu_dev; /**< PMU device, or NULL if no PMU */ + uint32_t pmu_cctl_addr; /**< chipctrl_addr target of + reads/writes to/from the + chipctrl_data register */ + + uint8_t sromrev; /**< SROM format revision */ + + /* NVRAM variables for which bwn(4) expects the bus to manage storage + * for (and in some cases, allow writes). */ + uint8_t mac_80211bg[6]; /**< D11 unit 0 */ + uint8_t mac_80211a[6]; /**< D11 unit 1 */ + + uint32_t boardflags; /**< boardflags (bwn-writable) */ + uint8_t pa0maxpwr; /**< 2GHz max power (bwn-writable) */ +}; + +/** + * Return the bwn(4) device's bhnd compatiblity context. + */ +static inline struct bwn_bhnd_ctx * +bwn_bhnd_get_ctx(device_t dev) +{ + struct bwn_softc *sc = device_get_softc(dev); + return (sc->sc_bus_ctx); +} + +/** + * Fetch an NVRAM variable via bhnd_nvram_getvar_*(). + */ +#define BWN_BHND_NVRAM_FETCH_VAR(_dev, _type, _name, _result) \ +do { \ + int error; \ + \ + error = bhnd_nvram_getvar_ ## _type(_dev, _name, _result); \ + if (error) { \ + panic("NVRAM variable %s unreadable: %d", _name, \ + error); \ + } \ +} while(0) + +/** + * Fetch and return an NVRAM variable via bhnd_nvram_getvar_*(). + */ +#define BWN_BHND_NVRAM_RETURN_VAR(_dev, _type, _name) \ +do { \ + _type ## _t value; \ + BWN_BHND_NVRAM_FETCH_VAR(_dev, _type, _name, &value); \ + return (value); \ +} while(0) + +#endif /* _IF_BWN_SIBA_COMPAT_H_ */ Index: sys/dev/bwn/if_bwn_siba_compat.c =================================================================== --- /dev/null +++ sys/dev/bwn/if_bwn_siba_compat.c @@ -0,0 +1,2556 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2016 Landon Fuller + * Copyright (c) 2017 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Landon Fuller + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "gpio_if.h" + +#include "bhnd_nvram_map.h" + +#include "if_bwn_siba_compat.h" + +static int bwn_bhnd_populate_nvram_data(device_t dev, + struct bwn_bhnd_ctx *ctx); +static inline bool bwn_bhnd_is_siba_reg(device_t dev, uint16_t offset); + +#define BWN_ASSERT_VALID_REG(_dev, _offset) \ + KASSERT(!bwn_bhnd_is_siba_reg(_dev, _offset), \ + ("%s: accessing siba-specific register %#jx", __FUNCTION__, \ + (uintmax_t)(_offset))); + +static int +bwn_bhnd_bus_ops_init(device_t dev) +{ + struct bwn_bhnd_ctx *ctx; + struct bwn_softc *sc; + const struct chipc_caps *ccaps; + int error; + + sc = device_get_softc(dev); + ctx = NULL; + + sc->sc_mem_rid = 0; + sc->sc_mem_res = bhnd_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->sc_mem_rid, RF_ACTIVE); + if (sc->sc_mem_res == NULL) { + return (ENXIO); + } + + /* Allocate PMU state */ + if ((error = bhnd_alloc_pmu(dev))) { + device_printf(dev, "PMU allocation failed: %d\n", error); + goto failed; + } + + /* Allocate our context */ + ctx = malloc(sizeof(struct bwn_bhnd_ctx), M_DEVBUF, M_WAITOK|M_ZERO); + + /* Locate the ChipCommon device */ + ctx->chipc_dev = bhnd_retain_provider(dev, BHND_SERVICE_CHIPC); + if (ctx->chipc_dev == NULL) { + device_printf(dev, "ChipCommon not found\n"); + error = ENXIO; + goto failed; + } + + /* Locate the GPIO device */ + ctx->gpio_dev = bhnd_retain_provider(dev, BHND_SERVICE_GPIO); + if (ctx->gpio_dev == NULL) { + device_printf(dev, "GPIO not found\n"); + error = ENXIO; + goto failed; + } + + /* Locate the PMU device (if any) */ + ccaps = BHND_CHIPC_GET_CAPS(ctx->chipc_dev); + if (ccaps->pmu) { + ctx->pmu_dev = bhnd_retain_provider(dev, BHND_SERVICE_PMU); + if (ctx->pmu_dev == NULL) { + device_printf(dev, "PMU not found\n"); + error = ENXIO; + goto failed; + } + } + + /* Populate NVRAM data */ + if ((error = bwn_bhnd_populate_nvram_data(dev, ctx))) + goto failed; + + /* Initialize bwn_softc */ + sc->sc_bus_ctx = ctx; + return (0); + +failed: + bhnd_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid, + sc->sc_mem_res); + + if (ctx != NULL) { + if (ctx->chipc_dev != NULL) { + bhnd_release_provider(dev, ctx->chipc_dev, + BHND_SERVICE_CHIPC); + } + + if (ctx->gpio_dev != NULL) { + bhnd_release_provider(dev, ctx->gpio_dev, + BHND_SERVICE_GPIO); + } + + if (ctx->pmu_dev != NULL) { + bhnd_release_provider(dev, ctx->pmu_dev, + BHND_SERVICE_PMU); + } + + free(ctx, M_DEVBUF); + } + + return (error); +} + +static void +bwn_bhnd_bus_ops_fini(device_t dev) +{ + struct bwn_bhnd_ctx *ctx; + struct bwn_softc *sc; + + sc = device_get_softc(dev); + ctx = sc->sc_bus_ctx; + + bhnd_release_pmu(dev); + bhnd_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid, + sc->sc_mem_res); + + bhnd_release_provider(dev, ctx->chipc_dev, BHND_SERVICE_CHIPC); + bhnd_release_provider(dev, ctx->gpio_dev, BHND_SERVICE_GPIO); + + if (ctx->pmu_dev != NULL) + bhnd_release_provider(dev, ctx->pmu_dev, BHND_SERVICE_PMU); + + free(ctx, M_DEVBUF); + sc->sc_bus_ctx = NULL; +} + + +/** + * Return true if @p offset is within a siba-specific configuration register + * block. + */ +static inline bool +bwn_bhnd_is_siba_reg(device_t dev, uint16_t offset) +{ + if (offset >= SIBA_CFG0_OFFSET && + offset <= SIBA_CFG0_OFFSET + SIBA_CFG_SIZE) + return (true); + + if (offset >= SIBA_CFG1_OFFSET && + offset <= SIBA_CFG1_OFFSET + SIBA_CFG_SIZE) + return (true); + + return (false); +} + +/* Populate SPROM values from NVRAM */ +static int +bwn_bhnd_populate_nvram_data(device_t dev, struct bwn_bhnd_ctx *ctx) +{ + const char *mac_80211bg_var, *mac_80211a_var; + int error; + + /* Fetch SROM revision */ + error = bhnd_nvram_getvar_uint8(dev, BHND_NVAR_SROMREV, &ctx->sromrev); + if (error) { + device_printf(dev, "error reading %s: %d\n", BHND_NVAR_SROMREV, + error); + return (error); + } + + /* Fetch board flags */ + error = bhnd_nvram_getvar_uint32(dev, BHND_NVAR_BOARDFLAGS, + &ctx->boardflags); + if (error) { + device_printf(dev, "error reading %s: %d\n", + BHND_NVAR_BOARDFLAGS, error); + return (error); + } + + /* Fetch macaddrs if available; bwn(4) expects any missing macaddr + * values to be initialized with 0xFF octets */ + memset(ctx->mac_80211bg, 0xFF, sizeof(ctx->mac_80211bg)); + memset(ctx->mac_80211a, 0xFF, sizeof(ctx->mac_80211a)); + + if (ctx->sromrev <= 2) { + mac_80211bg_var = BHND_NVAR_IL0MACADDR; + mac_80211a_var = BHND_NVAR_ET1MACADDR; + } else { + mac_80211bg_var = BHND_NVAR_MACADDR; + mac_80211a_var = NULL; + } + + /* Fetch required D11 core 0 macaddr */ + error = bhnd_nvram_getvar_array(dev, mac_80211bg_var, ctx->mac_80211bg, + sizeof(ctx->mac_80211bg), BHND_NVRAM_TYPE_UINT8_ARRAY); + if (error) { + device_printf(dev, "error reading %s: %d\n", mac_80211bg_var, + error); + return (error); + } + + /* Fetch optional D11 core 1 macaddr */ + if (mac_80211a_var != NULL) { + error = bhnd_nvram_getvar_array(dev, mac_80211a_var, + ctx->mac_80211a, sizeof(ctx->mac_80211a), + BHND_NVRAM_TYPE_UINT8_ARRAY); + + if (error && error != ENOENT) { + device_printf(dev, "error reading %s: %d\n", + mac_80211a_var, error); + return (error); + } + }; + + /* Fetch pa0maxpwr; bwn(4) expects to be able to modify it */ + if ((ctx->sromrev >= 1 && ctx->sromrev <= 3) || + (ctx->sromrev >= 8 && ctx->sromrev <= 10)) + { + error = bhnd_nvram_getvar_uint8(dev, BHND_NVAR_PA0MAXPWR, + &ctx->pa0maxpwr); + if (error) { + device_printf(dev, "error reading %s: %d\n", + BHND_NVAR_PA0MAXPWR, error); + return (error); + } + } + + return (0); +} + +/* + * Disable PCI-specific MSI interrupt allocation handling + */ + +/* + * pci_find_cap() + * + * Referenced by: + * bwn_attach() + */ +static int +bhnd_compat_pci_find_cap(device_t dev, int capability, int *capreg) +{ + return (ENODEV); +} + +/* + * pci_alloc_msi() + * + * Referenced by: + * bwn_attach() + */ +static int +bhnd_compat_pci_alloc_msi(device_t dev, int *count) +{ + return (ENODEV); +} + +/* + * pci_release_msi() + * + * Referenced by: + * bwn_attach() + * bwn_detach() + */ +static int +bhnd_compat_pci_release_msi(device_t dev) +{ + return (ENODEV); +} + +/* + * pci_msi_count() + * + * Referenced by: + * bwn_attach() + */ +static int +bhnd_compat_pci_msi_count(device_t dev) +{ + return (0); +} + +/* + * siba_get_vendor() + * + * Referenced by: + * bwn_probe() + */ +static uint16_t +bhnd_compat_get_vendor(device_t dev) +{ + uint16_t vendor = bhnd_get_vendor(dev); + + switch (vendor) { + case BHND_MFGID_BCM: + return (SIBA_VID_BROADCOM); + default: + return (0x0000); + } +} + +/* + * siba_get_device() + * + * Referenced by: + * bwn_probe() + */ +static uint16_t +bhnd_compat_get_device(device_t dev) +{ + return (bhnd_get_device(dev)); +} + +/* + * siba_get_revid() + * + * Referenced by: + * bwn_attach() + * bwn_attach_core() + * bwn_chip_init() + * bwn_chiptest() + * bwn_core_init() + * bwn_core_start() + * bwn_pio_idx2base() + * bwn_pio_set_txqueue() + * bwn_pio_tx_start() + * bwn_probe() + * ... and 19 others + * + */ +static uint8_t +bhnd_compat_get_revid(device_t dev) +{ + return (bhnd_get_hwrev(dev)); +} + +/** + * Return the PCI bridge root device. + * + * Will panic if a PCI bridge root device is not found. + */ +static device_t +bwn_bhnd_get_pci_dev(device_t dev) +{ device_t bridge_root; + + bridge_root = bhnd_find_bridge_root(dev, devclass_find("pci")); + if (bridge_root == NULL) + panic("not a PCI device"); + + return (bridge_root); +} + +/* + * siba_get_pci_vendor() + * + * Referenced by: + * bwn_sprom_bugfixes() + */ +static uint16_t +bhnd_compat_get_pci_vendor(device_t dev) +{ + return (pci_get_vendor(bwn_bhnd_get_pci_dev(dev))); +} + +/* + * siba_get_pci_device() + * + * Referenced by: + * bwn_attach() + * bwn_attach_core() + * bwn_nphy_op_prepare_structs() + * bwn_sprom_bugfixes() + */ +static uint16_t +bhnd_compat_get_pci_device(device_t dev) +{ + return (pci_get_device(bwn_bhnd_get_pci_dev(dev))); +} + +/* + * siba_get_pci_subvendor() + * + * Referenced by: + * bwn_led_attach() + * bwn_nphy_op_prepare_structs() + * bwn_phy_g_prepare_hw() + * bwn_phy_hwpctl_init() + * bwn_phy_init_b5() + * bwn_phy_initn() + * bwn_phy_txpower_check() + * bwn_radio_init2055_post() + * bwn_sprom_bugfixes() + * bwn_wa_init() + */ +static uint16_t +bhnd_compat_get_pci_subvendor(device_t dev) +{ + return (pci_get_subvendor(bwn_bhnd_get_pci_dev(dev))); +} + +/* + * siba_get_pci_subdevice() + * + * Referenced by: + * bwn_nphy_workarounds_rev1_2() + * bwn_phy_g_prepare_hw() + * bwn_phy_hwpctl_init() + * bwn_phy_init_b5() + * bwn_phy_initn() + * bwn_phy_lp_bbinit_r01() + * bwn_phy_txpower_check() + * bwn_radio_init2055_post() + * bwn_sprom_bugfixes() + * bwn_wa_init() + */ +static uint16_t +bhnd_compat_get_pci_subdevice(device_t dev) +{ + return (pci_get_subdevice(bwn_bhnd_get_pci_dev(dev))); +} + +/* + * siba_get_pci_revid() + * + * Referenced by: + * bwn_phy_g_prepare_hw() + * bwn_phy_lp_bbinit_r2() + * bwn_sprom_bugfixes() + * bwn_wa_init() + */ +static uint8_t +bhnd_compat_get_pci_revid(device_t dev) +{ + return (pci_get_revid(bwn_bhnd_get_pci_dev(dev))); +} + +/* + * siba_get_chipid() + * + * Referenced by: + * bwn_attach() + * bwn_gpio_init() + * bwn_mac_switch_freq() + * bwn_phy_g_attach() + * bwn_phy_g_init_sub() + * bwn_phy_g_prepare_hw() + * bwn_phy_getinfo() + * bwn_phy_lp_calib() + * bwn_set_opmode() + * bwn_sprom_bugfixes() + * ... and 9 others + * + */ +static uint16_t +bhnd_compat_get_chipid(device_t dev) +{ + return (bhnd_get_chipid(dev)->chip_id); +} + +/* + * siba_get_chiprev() + * + * Referenced by: + * bwn_phy_getinfo() + * bwn_phy_lp_bbinit_r2() + * bwn_phy_lp_tblinit_r2() + * bwn_set_opmode() + */ +static uint16_t +bhnd_compat_get_chiprev(device_t dev) +{ + return (bhnd_get_chipid(dev)->chip_rev); +} + +/* + * siba_get_chippkg() + * + * Referenced by: + * bwn_phy_g_init_sub() + * bwn_phy_lp_bbinit_r01() + * bwn_radio_2056_setup() + */ +static uint8_t +bhnd_compat_get_chippkg(device_t dev) +{ + return (bhnd_get_chipid(dev)->chip_pkg); +} + +/* + * siba_get_type() + * + * Referenced by: + * bwn_core_init() + * bwn_dma_attach() + * bwn_nphy_op_prepare_structs() + * bwn_sprom_bugfixes() + */ +static enum siba_type +bhnd_compat_get_type(device_t dev) +{ + device_t bus, hostb; + bhnd_devclass_t hostb_devclass; + + bus = device_get_parent(dev); + hostb = bhnd_bus_find_hostb_device(bus); + + if (hostb == NULL) + return (SIBA_TYPE_SSB); + + hostb_devclass = bhnd_get_class(hostb); + switch (hostb_devclass) { + case BHND_DEVCLASS_PCCARD: + return (SIBA_TYPE_PCMCIA); + case BHND_DEVCLASS_PCI: + case BHND_DEVCLASS_PCIE: + return (SIBA_TYPE_PCI); + default: + panic("unsupported hostb devclass: %d\n", hostb_devclass); + } +} + +/* + * siba_get_cc_pmufreq() + * + * Referenced by: + * bwn_phy_lp_b2062_init() + * bwn_phy_lp_b2062_switch_channel() + * bwn_phy_lp_b2063_switch_channel() + * bwn_phy_lp_rxcal_r2() + */ +static uint32_t +bhnd_compat_get_cc_pmufreq(device_t dev) +{ + u_int freq; + int error; + + if ((error = bhnd_get_clock_freq(dev, BHND_CLOCK_ALP, &freq))) + panic("failed to fetch clock frequency: %d", error); + + /* TODO: bwn(4) immediately multiplies the result by 1000 (MHz -> Hz) */ + return (freq / 1000); +} + +/* + * siba_get_cc_caps() + * + * Referenced by: + * bwn_phy_lp_b2062_init() + */ +static uint32_t +bhnd_compat_get_cc_caps(device_t dev) +{ + device_t chipc; + const struct chipc_caps *ccaps; + uint32_t result; + + /* Fetch our ChipCommon device */ + chipc = bhnd_retain_provider(dev, BHND_SERVICE_CHIPC); + if (chipc == NULL) + panic("missing ChipCommon device"); + + /* + * The ChipCommon capability flags are only used in one LP-PHY function, + * to assert that a PMU is in fact available. + * + * We can support this by producing a value containing just that flag. + */ + result = 0; + ccaps = BHND_CHIPC_GET_CAPS(chipc); + if (ccaps->pmu) + result |= SIBA_CC_CAPS_PMU; + + bhnd_release_provider(dev, chipc, BHND_SERVICE_CHIPC); + + return (result); +} + +/* + * siba_get_cc_powerdelay() + * + * Referenced by: + * bwn_chip_init() + */ +static uint16_t +bhnd_compat_get_cc_powerdelay(device_t dev) +{ + u_int delay; + int error; + + if ((error = bhnd_get_clock_latency(dev, BHND_CLOCK_HT, &delay))) + panic("failed to fetch clock latency: %d", error); + + if (delay > UINT16_MAX) + panic("%#x would overflow", delay); + + return (delay); +} + +/* + * siba_get_pcicore_revid() + * + * Referenced by: + * bwn_core_init() + */ +static uint8_t +bhnd_compat_get_pcicore_revid(device_t dev) +{ + device_t hostb; + uint8_t nomatch_revid; + + /* + * This is used by bwn(4) in only bwn_core_init(), where a revid <= 10 + * results in the BWN_HF_PCI_SLOWCLOCK_WORKAROUND workaround being + * enabled. + * + * The quirk should only be applied on siba(4) devices using a PCI + * core; we handle around this by returning a bogus value >= 10 here. + * + * TODO: bwn(4) should match this quirk on: + * - BHND_CHIPTYPE_SIBA + * - BHND_COREID_PCI + * - HWREV_LTE(10) + */ + nomatch_revid = 0xFF; + + hostb = bhnd_bus_find_hostb_device(device_get_parent(dev)); + if (hostb == NULL) { + /* Not a bridged device */ + return (nomatch_revid); + } + + if (bhnd_get_device(hostb) != BHND_COREID_PCI) { + /* Not a PCI core */ + return (nomatch_revid); + } + + /* This is a PCI core; we can return the real core revision */ + return (bhnd_get_hwrev(hostb)); +} + +/* + * siba_sprom_get_rev() + * + * Referenced by: + * bwn_nphy_op_prepare_structs() + * bwn_nphy_tx_power_ctl_setup() + * bwn_nphy_tx_power_fix() + * bwn_nphy_workarounds_rev7plus() + */ +static uint8_t +bhnd_compat_sprom_get_rev(device_t dev) +{ + return (bwn_bhnd_get_ctx(dev)->sromrev); +} + +/* + * siba_sprom_get_mac_80211bg() + * + * Referenced by: + * bwn_attach_post() + */ +static uint8_t * +bhnd_compat_sprom_get_mac_80211bg(device_t dev) +{ + /* 'MAC_80211BG' is il0macaddr or macaddr*/ + return (bwn_bhnd_get_ctx(dev)->mac_80211bg); +} + +/* + * siba_sprom_get_mac_80211a() + * + * Referenced by: + * bwn_attach_post() + */ +static uint8_t * +bhnd_compat_sprom_get_mac_80211a(device_t dev) +{ + /* 'MAC_80211A' is et1macaddr */ + return (bwn_bhnd_get_ctx(dev)->mac_80211a); +} + +/* + * siba_sprom_get_brev() + * + * Referenced by: + * bwn_radio_init2055_post() + */ +static uint8_t +bhnd_compat_sprom_get_brev(device_t dev) +{ + /* TODO: bwn(4) needs to switch to uint16_t */ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_BOARDREV); +} + +/* + * siba_sprom_get_ccode() + * + * Referenced by: + * bwn_phy_g_switch_chan() + */ +static uint8_t +bhnd_compat_sprom_get_ccode(device_t dev) +{ + /* This has been replaced with 'ccode' in later SPROM + * revisions, but this API is only called on devices with + * spromrev 1. */ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_CC); +} + +/* + * siba_sprom_get_ant_a() + * + * Referenced by: + * bwn_antenna_sanitize() + */ +static uint8_t +bhnd_compat_sprom_get_ant_a(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_AA5G); +} + +/* + * siba_sprom_get_ant_bg() + * + * Referenced by: + * bwn_antenna_sanitize() + */ +static uint8_t +bhnd_compat_sprom_get_ant_bg(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_AA2G); +} + +/* + * siba_sprom_get_pa0b0() + * + * Referenced by: + * bwn_phy_g_attach() + */ +static uint16_t +bhnd_compat_sprom_get_pa0b0(device_t dev) +{ + int16_t value; + + BWN_BHND_NVRAM_FETCH_VAR(dev, int16, BHND_NVAR_PA0B0, &value); + + /* TODO: bwn(4) immediately casts this back to int16_t */ + return ((uint16_t)value); +} + +/* + * siba_sprom_get_pa0b1() + * + * Referenced by: + * bwn_phy_g_attach() + */ +static uint16_t +bhnd_compat_sprom_get_pa0b1(device_t dev) +{ + int16_t value; + + BWN_BHND_NVRAM_FETCH_VAR(dev, int16, BHND_NVAR_PA0B1, &value); + + /* TODO: bwn(4) immediately casts this back to int16_t */ + return ((uint16_t)value); +} + +/* + * siba_sprom_get_pa0b2() + * + * Referenced by: + * bwn_phy_g_attach() + */ +static uint16_t +bhnd_compat_sprom_get_pa0b2(device_t dev) +{ + int16_t value; + + BWN_BHND_NVRAM_FETCH_VAR(dev, int16, BHND_NVAR_PA0B2, &value); + + /* TODO: bwn(4) immediately casts this back to int16_t */ + return ((uint16_t)value); +} + +/** + * Fetch an led behavior (ledbhX) NVRAM variable value, for use by + * siba_sprom_get_gpioX(). + * + * ('gpioX' are actually the ledbhX NVRAM variables). + */ +static uint8_t +bhnd_compat_sprom_get_ledbh(device_t dev, const char *name) +{ + uint8_t value; + int error; + + error = bhnd_nvram_getvar_uint8(dev, name, &value); + if (error && error != ENOENT) + panic("NVRAM variable %s unreadable: %d", name, error); + + /* For some variables (including ledbhX), a value with all bits set is + * treated as uninitialized in the SPROM format; our SPROM parser + * detects this case and returns ENOENT, but bwn(4) actually expects + * to read the raw value 0xFF value. */ + if (error == ENOENT) + value = 0xFF; + + return (value); +} + +/* + * siba_sprom_get_gpio0() + * + * 'gpioX' are actually the led behavior (ledbh) NVRAM variables. + * + * Referenced by: + * bwn_led_attach() + */ +static uint8_t +bhnd_compat_sprom_get_gpio0(device_t dev) +{ + return (bhnd_compat_sprom_get_ledbh(dev, BHND_NVAR_LEDBH0)); +} + +/* + * siba_sprom_get_gpio1() + * + * Referenced by: + * bwn_led_attach() + */ +static uint8_t +bhnd_compat_sprom_get_gpio1(device_t dev) +{ + return (bhnd_compat_sprom_get_ledbh(dev, BHND_NVAR_LEDBH1)); +} + +/* + * siba_sprom_get_gpio2() + * + * Referenced by: + * bwn_led_attach() + */ +static uint8_t +bhnd_compat_sprom_get_gpio2(device_t dev) +{ + return (bhnd_compat_sprom_get_ledbh(dev, BHND_NVAR_LEDBH2)); +} + +/* + * siba_sprom_get_gpio3() + * + * Referenced by: + * bwn_led_attach() + */ +static uint8_t +bhnd_compat_sprom_get_gpio3(device_t dev) +{ + return (bhnd_compat_sprom_get_ledbh(dev, BHND_NVAR_LEDBH3)); +} + +/* + * siba_sprom_get_maxpwr_bg() + * + * Referenced by: + * bwn_phy_g_recalc_txpwr() + */ +static uint16_t +bhnd_compat_sprom_get_maxpwr_bg(device_t dev) +{ + return (bwn_bhnd_get_ctx(dev)->pa0maxpwr); +} + +/* + * siba_sprom_set_maxpwr_bg() + * + * Referenced by: + * bwn_phy_g_recalc_txpwr() + */ +static void +bhnd_compat_sprom_set_maxpwr_bg(device_t dev, uint16_t t) +{ + KASSERT(t <= UINT8_MAX, ("invalid maxpwr value %hu", t)); + bwn_bhnd_get_ctx(dev)->pa0maxpwr = t; +} + +/* + * siba_sprom_get_rxpo2g() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_rxpo2g(device_t dev) +{ + /* Should be signed, but bwn(4) expects an unsigned value */ + BWN_BHND_NVRAM_RETURN_VAR(dev, int8, BHND_NVAR_RXPO2G); +} + +/* + * siba_sprom_get_rxpo5g() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_rxpo5g(device_t dev) +{ + /* Should be signed, but bwn(4) expects an unsigned value */ + BWN_BHND_NVRAM_RETURN_VAR(dev, int8, BHND_NVAR_RXPO5G); +} + +/* + * siba_sprom_get_tssi_bg() + * + * Referenced by: + * bwn_phy_g_attach() + */ +static uint8_t +bhnd_compat_sprom_get_tssi_bg(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_PA0ITSSIT); +} + +/* + * siba_sprom_get_tri2g() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_tri2g(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TRI2G); +} + +/* + * siba_sprom_get_tri5gl() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_tri5gl(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TRI5GL); +} + +/* + * siba_sprom_get_tri5g() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_tri5g(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TRI5G); +} + +/* + * siba_sprom_get_tri5gh() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_tri5gh(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TRI5GH); +} + +/* + * siba_sprom_get_rssisav2g() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_rssisav2g(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_RSSISAV2G); +} + +/* + * siba_sprom_get_rssismc2g() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_rssismc2g(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_RSSISMC2G); +} + +/* + * siba_sprom_get_rssismf2g() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_rssismf2g(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_RSSISMF2G); +} + +/* + * siba_sprom_get_bxa2g() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_bxa2g(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_BXA2G); +} + +/* + * siba_sprom_get_rssisav5g() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_rssisav5g(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_RSSISAV5G); +} + +/* + * siba_sprom_get_rssismc5g() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_rssismc5g(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_RSSISMC5G); +} + +/* + * siba_sprom_get_rssismf5g() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_rssismf5g(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_RSSISMF5G); +} + +/* + * siba_sprom_get_bxa5g() + * + * Referenced by: + * bwn_phy_lp_readsprom() + */ +static uint8_t +bhnd_compat_sprom_get_bxa5g(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_BXA5G); +} + +/* + * siba_sprom_get_cck2gpo() + * + * Referenced by: + * bwn_ppr_load_max_from_sprom() + */ +static uint16_t +bhnd_compat_sprom_get_cck2gpo(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint16, BHND_NVAR_CCK2GPO); +} + +/* + * siba_sprom_get_ofdm2gpo() + * + * Referenced by: + * bwn_ppr_load_max_from_sprom() + */ +static uint32_t +bhnd_compat_sprom_get_ofdm2gpo(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint32, BHND_NVAR_OFDM2GPO); +} + +/* + * siba_sprom_get_ofdm5glpo() + * + * Referenced by: + * bwn_ppr_load_max_from_sprom() + */ +static uint32_t +bhnd_compat_sprom_get_ofdm5glpo(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint32, BHND_NVAR_OFDM5GLPO); +} + +/* + * siba_sprom_get_ofdm5gpo() + * + * Referenced by: + * bwn_ppr_load_max_from_sprom() + */ +static uint32_t +bhnd_compat_sprom_get_ofdm5gpo(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint32, BHND_NVAR_OFDM5GPO); +} + +/* + * siba_sprom_get_ofdm5ghpo() + * + * Referenced by: + * bwn_ppr_load_max_from_sprom() + */ +static uint32_t +bhnd_compat_sprom_get_ofdm5ghpo(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint32, BHND_NVAR_OFDM5GHPO); +} + +/* + * siba_sprom_set_bf_lo() + * + * Referenced by: + * bwn_sprom_bugfixes() + */ +static void +bhnd_compat_sprom_set_bf_lo(device_t dev, uint16_t t) +{ + struct bwn_bhnd_ctx *ctx = bwn_bhnd_get_ctx(dev); + ctx->boardflags &= ~0xFFFF; + ctx->boardflags |= t; +} + +/* + * siba_sprom_get_bf_lo() + * + * Referenced by: + * bwn_bt_enable() + * bwn_core_init() + * bwn_gpio_init() + * bwn_loopback_calcgain() + * bwn_phy_g_init_sub() + * bwn_phy_g_recalc_txpwr() + * bwn_phy_g_set_txpwr() + * bwn_phy_g_task_60s() + * bwn_rx_rssi_calc() + * bwn_sprom_bugfixes() + * ... and 11 others + * + */ +static uint16_t +bhnd_compat_sprom_get_bf_lo(device_t dev) +{ + struct bwn_bhnd_ctx *ctx = bwn_bhnd_get_ctx(dev); + return (ctx->boardflags & UINT16_MAX); +} + +/* + * siba_sprom_get_bf_hi() + * + * Referenced by: + * bwn_nphy_gain_ctl_workarounds_rev3() + * bwn_phy_lp_bbinit_r01() + * bwn_phy_lp_tblinit_txgain() + */ +static uint16_t +bhnd_compat_sprom_get_bf_hi(device_t dev) +{ + struct bwn_bhnd_ctx *ctx = bwn_bhnd_get_ctx(dev); + return (ctx->boardflags >> 16); +} + +/* + * siba_sprom_get_bf2_lo() + * + * Referenced by: + * bwn_nphy_op_prepare_structs() + * bwn_nphy_workarounds_rev1_2() + * bwn_nphy_workarounds_rev3plus() + * bwn_phy_initn() + * bwn_radio_2056_setup() + * bwn_radio_init2055_post() + */ +static uint16_t +bhnd_compat_sprom_get_bf2_lo(device_t dev) +{ + uint32_t bf2; + + BWN_BHND_NVRAM_FETCH_VAR(dev, uint32, BHND_NVAR_BOARDFLAGS2, &bf2); + return (bf2 & UINT16_MAX); +} + +/* + * siba_sprom_get_bf2_hi() + * + * Referenced by: + * bwn_nphy_workarounds_rev7plus() + * bwn_phy_initn() + * bwn_radio_2056_setup() + */ +static uint16_t +bhnd_compat_sprom_get_bf2_hi(device_t dev) +{ + uint32_t bf2; + + BWN_BHND_NVRAM_FETCH_VAR(dev, uint32, BHND_NVAR_BOARDFLAGS2, &bf2); + return (bf2 >> 16); +} + +/* + * siba_sprom_get_fem_2ghz_tssipos() + * + * Referenced by: + * bwn_nphy_tx_power_ctl_setup() + */ +static uint8_t +bhnd_compat_sprom_get_fem_2ghz_tssipos(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TSSIPOS2G); +} + +/* + * siba_sprom_get_fem_2ghz_extpa_gain() + * + * Referenced by: + * bwn_nphy_op_prepare_structs() + */ +static uint8_t +bhnd_compat_sprom_get_fem_2ghz_extpa_gain(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_EXTPAGAIN2G); +} + +/* + * siba_sprom_get_fem_2ghz_pdet_range() + * + * Referenced by: + * bwn_nphy_workarounds_rev3plus() + */ +static uint8_t +bhnd_compat_sprom_get_fem_2ghz_pdet_range(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_PDETRANGE2G); +} + +/* + * siba_sprom_get_fem_2ghz_tr_iso() + * + * Referenced by: + * bwn_nphy_get_gain_ctl_workaround_ent() + */ +static uint8_t +bhnd_compat_sprom_get_fem_2ghz_tr_iso(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TRISO2G); +} + +/* + * siba_sprom_get_fem_2ghz_antswlut() + * + * Referenced by: + * bwn_nphy_tables_init_rev3() + * bwn_nphy_tables_init_rev7_volatile() + */ +static uint8_t +bhnd_compat_sprom_get_fem_2ghz_antswlut(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_ANTSWCTL2G); +} + +/* + * siba_sprom_get_fem_5ghz_extpa_gain() + * + * Referenced by: + * bwn_nphy_get_tx_gain_table() + * bwn_nphy_op_prepare_structs() + */ +static uint8_t +bhnd_compat_sprom_get_fem_5ghz_extpa_gain(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_EXTPAGAIN5G); +} + +/* + * siba_sprom_get_fem_5ghz_pdet_range() + * + * Referenced by: + * bwn_nphy_workarounds_rev3plus() + */ +static uint8_t +bhnd_compat_sprom_get_fem_5ghz_pdet_range(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_PDETRANGE5G); +} + +/* + * siba_sprom_get_fem_5ghz_antswlut() + * + * Referenced by: + * bwn_nphy_tables_init_rev3() + * bwn_nphy_tables_init_rev7_volatile() + */ +static uint8_t +bhnd_compat_sprom_get_fem_5ghz_antswlut(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_ANTSWCTL5G); +} + +/* + * siba_sprom_get_txpid_2g_0() + * + * Referenced by: + * bwn_nphy_tx_power_fix() + */ +static uint8_t +bhnd_compat_sprom_get_txpid_2g_0(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID2GA0); +} + +/* + * siba_sprom_get_txpid_2g_1() + * + * Referenced by: + * bwn_nphy_tx_power_fix() + */ +static uint8_t +bhnd_compat_sprom_get_txpid_2g_1(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID2GA1); +} + +/* + * siba_sprom_get_txpid_5gl_0() + * + * Referenced by: + * bwn_nphy_tx_power_fix() + */ +static uint8_t +bhnd_compat_sprom_get_txpid_5gl_0(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID5GLA0); +} + +/* + * siba_sprom_get_txpid_5gl_1() + * + * Referenced by: + * bwn_nphy_tx_power_fix() + */ +static uint8_t +bhnd_compat_sprom_get_txpid_5gl_1(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID5GLA1); +} + +/* + * siba_sprom_get_txpid_5g_0() + * + * Referenced by: + * bwn_nphy_tx_power_fix() + */ +static uint8_t +bhnd_compat_sprom_get_txpid_5g_0(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID5GA0); +} + +/* + * siba_sprom_get_txpid_5g_1() + * + * Referenced by: + * bwn_nphy_tx_power_fix() + */ +static uint8_t +bhnd_compat_sprom_get_txpid_5g_1(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID5GA1); +} + +/* + * siba_sprom_get_txpid_5gh_0() + * + * Referenced by: + * bwn_nphy_tx_power_fix() + */ +static uint8_t +bhnd_compat_sprom_get_txpid_5gh_0(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID5GHA0); +} + +/* + * siba_sprom_get_txpid_5gh_1() + * + * Referenced by: + * bwn_nphy_tx_power_fix() + */ +static uint8_t +bhnd_compat_sprom_get_txpid_5gh_1(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID5GHA1); +} + +/* + * siba_sprom_get_stbcpo() + * + * Referenced by: + * bwn_ppr_load_max_from_sprom() + */ +static uint16_t +bhnd_compat_sprom_get_stbcpo(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint16, BHND_NVAR_STBCPO); +} + +/* + * siba_sprom_get_cddpo() + * + * Referenced by: + * bwn_ppr_load_max_from_sprom() + */ +static uint16_t +bhnd_compat_sprom_get_cddpo(device_t dev) +{ + BWN_BHND_NVRAM_RETURN_VAR(dev, uint16, BHND_NVAR_CDDPO); +} + +/* + * siba_powerup() + * + * Referenced by: + * bwn_attach_core() + * bwn_core_init() + */ +static void +bhnd_compat_powerup(device_t dev, int dynamic) +{ + struct bwn_bhnd_ctx *ctx; + bhnd_clock clock; + int error; + + ctx = bwn_bhnd_get_ctx(dev); + + /* On PMU equipped devices, we do not need to issue a clock request + * at powerup */ + if (ctx->pmu_dev != NULL) + return; + + /* Issue a PMU clock request */ + if (dynamic) + clock = BHND_CLOCK_DYN; + else + clock = BHND_CLOCK_HT; + + if ((error = bhnd_request_clock(dev, clock))) { + device_printf(dev, "%d clock request failed: %d\n", + clock, error); + } + +} + +/* + * siba_powerdown() + * + * Referenced by: + * bwn_attach_core() + * bwn_core_exit() + * bwn_core_init() + */ +static int +bhnd_compat_powerdown(device_t dev) +{ + int error; + + /* Suspend the core */ + if ((error = bhnd_suspend_hw(dev, 0))) + return (error); + + return (0); +} + +/* + * siba_read_2() + * + * Referenced by: + * bwn_chip_init() + * bwn_chiptest() + * bwn_dummy_transmission() + * bwn_gpio_init() + * bwn_phy_getinfo() + * bwn_pio_read_2() + * bwn_shm_read_2() + * bwn_shm_read_4() + * bwn_wme_init() + * bwn_wme_loadparams() + * ... and 23 others + * + */ +static uint16_t +bhnd_compat_read_2(device_t dev, uint16_t offset) +{ + struct bwn_softc *sc = device_get_softc(dev); + + BWN_ASSERT_VALID_REG(dev, offset); + + return (bhnd_bus_read_2(sc->sc_mem_res, offset)); +} + +/* + * siba_write_2() + * + * Referenced by: + * bwn_chip_init() + * bwn_chiptest() + * bwn_crypt_init() + * bwn_gpio_init() + * bwn_phy_getinfo() + * bwn_pio_tx_start() + * bwn_set_opmode() + * bwn_shm_write_2() + * bwn_shm_write_4() + * bwn_wme_init() + * ... and 43 others + * + */ +static void +bhnd_compat_write_2(device_t dev, uint16_t offset, uint16_t value) +{ + struct bwn_softc *sc = device_get_softc(dev); + + BWN_ASSERT_VALID_REG(dev, offset); + + return (bhnd_bus_write_2(sc->sc_mem_res, offset, value)); +} + +/* + * siba_read_4() + * + * Referenced by: + * bwn_attach_core() + * bwn_chip_init() + * bwn_chiptest() + * bwn_core_exit() + * bwn_core_init() + * bwn_core_start() + * bwn_pio_init() + * bwn_pio_tx_start() + * bwn_reset_core() + * bwn_shm_read_4() + * ... and 42 others + * + */ +static uint32_t +bhnd_compat_read_4(device_t dev, uint16_t offset) +{ + struct bwn_softc *sc = device_get_softc(dev); + uint16_t ioreg; + int error; + + /* bwn(4) fetches IOCTL/IOST values directly from siba-specific target + * state registers; we map these directly to bhnd_read_(ioctl|iost) */ + switch (offset) { + case SB0_REG_ABS(SIBA_CFG0_TMSTATELOW): + if ((error = bhnd_read_ioctl(dev, &ioreg))) + panic("error reading IOCTL: %d\n", error); + + return (((uint32_t)ioreg) << SIBA_TML_SICF_SHIFT); + + case SB0_REG_ABS(SIBA_CFG0_TMSTATEHIGH): + if ((error = bhnd_read_iost(dev, &ioreg))) + panic("error reading IOST: %d\n", error); + + return (((uint32_t)ioreg) << SIBA_TMH_SISF_SHIFT); + } + + /* Otherwise, perform a standard bus read */ + BWN_ASSERT_VALID_REG(dev, offset); + return (bhnd_bus_read_4(sc->sc_mem_res, offset)); +} + +/* + * siba_write_4() + * + * Referenced by: + * bwn_chip_init() + * bwn_chiptest() + * bwn_core_exit() + * bwn_core_start() + * bwn_dma_mask() + * bwn_dma_rxdirectfifo() + * bwn_pio_init() + * bwn_reset_core() + * bwn_shm_ctlword() + * bwn_shm_write_4() + * ... and 37 others + * + */ +static void +bhnd_compat_write_4(device_t dev, uint16_t offset, uint32_t value) +{ + struct bwn_softc *sc = device_get_softc(dev); + uint16_t ioctl; + int error; + + /* bwn(4) writes IOCTL values directly to siba-specific target state + * registers; we map these directly to bhnd_write_ioctl() */ + if (offset == SB0_REG_ABS(SIBA_CFG0_TMSTATELOW)) { + /* shift IOCTL flags back down to their original values */ + if (value & ~SIBA_TML_SICF_MASK) + panic("%s: non-IOCTL flags provided", __FUNCTION__); + + ioctl = (value & SIBA_TML_SICF_MASK) >> SIBA_TML_SICF_SHIFT; + + if ((error = bhnd_write_ioctl(dev, ioctl, UINT16_MAX))) + panic("error writing IOCTL: %d\n", error); + } else { + /* Otherwise, perform a standard bus write */ + BWN_ASSERT_VALID_REG(dev, offset); + + bhnd_bus_write_4(sc->sc_mem_res, offset, value); + } + + return; +} + +/* + * siba_dev_up() + * + * Referenced by: + * bwn_reset_core() + */ +static void +bhnd_compat_dev_up(device_t dev, uint32_t flags) +{ + uint16_t ioctl; + int error; + + /* shift IOCTL flags back down to their original values */ + if (flags & ~SIBA_TML_SICF_MASK) + panic("%s: non-IOCTL flags provided", __FUNCTION__); + + ioctl = (flags & SIBA_TML_SICF_MASK) >> SIBA_TML_SICF_SHIFT; + + /* Perform core reset; note that bwn(4) incorrectly assumes that both + * RESET and post-RESET ioctl flags should be identical */ + if ((error = bhnd_reset_hw(dev, ioctl, ioctl))) + panic("%s: core reset failed: %d", __FUNCTION__, error); +} + +/* + * siba_dev_down() + * + * Referenced by: + * bwn_attach_core() + * bwn_core_exit() + */ +static void +bhnd_compat_dev_down(device_t dev, uint32_t flags) +{ + uint16_t ioctl; + int error; + + /* shift IOCTL flags back down to their original values */ + if (flags & ~SIBA_TML_SICF_MASK) + panic("%s: non-IOCTL flags provided", __FUNCTION__); + + ioctl = (flags & SIBA_TML_SICF_MASK) >> SIBA_TML_SICF_SHIFT; + + /* Put core into RESET state */ + if ((error = bhnd_suspend_hw(dev, ioctl))) + panic("%s: core suspend failed: %d", __FUNCTION__, error); +} + +/* + * siba_dev_isup() + * + * Referenced by: + * bwn_core_init() + */ +static int +bhnd_compat_dev_isup(device_t dev) +{ + return (!bhnd_is_hw_suspended(dev)); +} + +/* + * siba_pcicore_intr() + * + * Referenced by: + * bwn_core_init() + */ +static void +bhnd_compat_pcicore_intr(device_t dev) +{ + /* This is handled by bhnd_bhndb on the first call to + * bus_setup_intr() */ +} + +/* + * siba_dma_translation() + * + * Referenced by: + * bwn_dma_32_setdesc() + * bwn_dma_64_setdesc() + * bwn_dma_setup() + */ +static uint32_t +bhnd_compat_dma_translation(device_t dev) +{ + struct bhnd_dma_translation dt; + struct bwn_softc *sc; + struct bwn_mac *mac; + int bwn_dmatype, error; + + sc = device_get_softc(dev); + mac = sc->sc_curmac; + KASSERT(mac != NULL, ("no MAC")); + + /* Fetch our DMA translation */ + bwn_dmatype = mac->mac_method.dma.dmatype; + if ((error = bhnd_get_dma_translation(dev, bwn_dmatype, 0, NULL, &dt))) + panic("error requesting DMA translation: %d\n", error); + + /* + * TODO: bwn(4) needs to switch to bhnd_get_dma_translation(). + * + * Currently, bwn(4) incorrectly assumes that: + * - The 32-bit translation mask is always SIBA_DMA_TRANSLATION_MASK. + * - The 32-bit mask can simply be applied to the top 32-bits of a + * 64-bit DMA address. + * - The 64-bit address translation is always derived by shifting the + * 32-bit siba_dma_translation() left by 1 bit. + * + * In practice, these assumptions won't result in any bugs on known + * PCI/PCIe Wi-Fi hardware: + * - The 32-bit mask _is_ always SIBA_DMA_TRANSLATION_MASK on + * the subset of devices supported by bwn(4). + * - The 64-bit mask used by bwn(4) is a superset of the real + * mask, and thus: + * - Our DMA tag will still have valid constraints. + * - Our address translation will not be corrupted by + * applying the mask. + * - The mask falls within the top 16 address bits, and our + * supported 64-bit architectures are all still limited + * to 48-bit addresses anyway; we don't need to worry about + * addressing >= 48-bit host memory. + * + * However, we will need to resolve these issues in bwn(4) if DMA is to + * work on new hardware (e.g. WiSoCs). + */ + switch (bwn_dmatype) { + case BWN_DMA_32BIT: + case BWN_DMA_30BIT: + KASSERT((~dt.addr_mask & BHND_DMA_ADDR_BITMASK(32)) == + SIBA_DMA_TRANSLATION_MASK, ("unexpected DMA mask: %#jx", + (uintmax_t)dt.addr_mask)); + + return (dt.base_addr); + + case BWN_DMA_64BIT: + /* bwn(4) will shift this left by 32+1 bits before applying it + * to the top 32-bits of the DMA address */ + KASSERT((~dt.addr_mask & BHND_DMA_ADDR_BITMASK(33)) == 0, + ("DMA64 translation %#jx masks low 33-bits", + (uintmax_t)dt.addr_mask)); + + return (dt.base_addr >> 33); + + default: + panic("unknown dma type %d", bwn_dmatype); + } +} + +/* + * siba_read_multi_2() + * + * Referenced by: + * bwn_pio_rxeof() + */ +static void +bhnd_compat_read_multi_2(device_t dev, void *buffer, size_t count, + uint16_t offset) +{ + struct bwn_softc *sc = device_get_softc(dev); + + BWN_ASSERT_VALID_REG(dev, offset); + return (bhnd_bus_read_multi_2(sc->sc_mem_res, offset, buffer, count)); +} + +/* + * siba_read_multi_4() + * + * Referenced by: + * bwn_pio_rxeof() + */ +static void +bhnd_compat_read_multi_4(device_t dev, void *buffer, size_t count, + uint16_t offset) +{ + struct bwn_softc *sc = device_get_softc(dev); + + BWN_ASSERT_VALID_REG(dev, offset); + return (bhnd_bus_read_multi_4(sc->sc_mem_res, offset, buffer, count)); +} + +/* + * siba_write_multi_2() + * + * Referenced by: + * bwn_pio_write_multi_2() + */ +static void +bhnd_compat_write_multi_2(device_t dev, const void *buffer, size_t count, + uint16_t offset) +{ + struct bwn_softc *sc = device_get_softc(dev); + + BWN_ASSERT_VALID_REG(dev, offset); + + /* XXX discarding const to maintain API compatibility with + * siba_write_multi_2() */ + bhnd_bus_write_multi_2(sc->sc_mem_res, offset, + __DECONST(void *, buffer), count); +} + +/* + * siba_write_multi_4() + * + * Referenced by: + * bwn_pio_write_multi_4() + */ +static void +bhnd_compat_write_multi_4(device_t dev, const void *buffer, size_t count, + uint16_t offset) +{ + struct bwn_softc *sc = device_get_softc(dev); + + BWN_ASSERT_VALID_REG(dev, offset); + + /* XXX discarding const to maintain API compatibility with + * siba_write_multi_4() */ + bhnd_bus_write_multi_4(sc->sc_mem_res, offset, + __DECONST(void *, buffer), count); +} + +/* + * siba_barrier() + * + * Referenced by: + * bwn_intr() + * bwn_intrtask() + * bwn_ram_write() + */ +static void +bhnd_compat_barrier(device_t dev, int flags) +{ + struct bwn_softc *sc = device_get_softc(dev); + + /* XXX is siba_barrier()'s use of an offset and length of 0 + * correct? */ + BWN_ASSERT_VALID_REG(dev, 0); + bhnd_bus_barrier(sc->sc_mem_res, 0, 0, flags); +} + +/* + * siba_cc_pmu_set_ldovolt() + * + * Referenced by: + * bwn_phy_lp_bbinit_r01() + */ +static void +bhnd_compat_cc_pmu_set_ldovolt(device_t dev, int id, uint32_t volt) +{ + struct bwn_bhnd_ctx *ctx; + int error; + + ctx = bwn_bhnd_get_ctx(dev); + + /* Only ever used to set the PAREF LDO voltage */ + if (id != SIBA_LDO_PAREF) + panic("invalid LDO id: %d", id); + + /* Configuring regulator voltage requires a PMU */ + if (ctx->pmu_dev == NULL) + panic("no PMU; cannot set LDO voltage"); + + error = bhnd_pmu_set_voltage_raw(ctx->pmu_dev, BHND_REGULATOR_PAREF_LDO, + volt); + if (error) + panic("failed to set LDO voltage: %d", error); +} + +/* + * siba_cc_pmu_set_ldoparef() + * + * Referenced by: + * bwn_phy_lp_bbinit_r01() + */ +static void +bhnd_compat_cc_pmu_set_ldoparef(device_t dev, uint8_t on) +{ + struct bwn_bhnd_ctx *ctx; + int error; + + ctx = bwn_bhnd_get_ctx(dev); + + /* Enabling/disabling regulators requires a PMU */ + if (ctx->pmu_dev == NULL) + panic("no PMU; cannot set LDO voltage"); + + if (on) { + error = bhnd_pmu_enable_regulator(ctx->pmu_dev, + BHND_REGULATOR_PAREF_LDO); + } else { + error = bhnd_pmu_enable_regulator(ctx->pmu_dev, + BHND_REGULATOR_PAREF_LDO); + } + + if (error) { + panic("failed to %s PAREF_LDO: %d", on ? "enable" : "disable", + error); + } +} + +/* + * siba_gpio_set() + * + * Referenced by: + * bwn_chip_exit() + * bwn_chip_init() + * bwn_gpio_init() + * bwn_nphy_superswitch_init() + */ +static void +bhnd_compat_gpio_set(device_t dev, uint32_t value) +{ + struct bwn_bhnd_ctx *ctx; + uint32_t flags[32]; + int error; + + ctx = bwn_bhnd_get_ctx(dev); + + for (size_t i = 0; i < nitems(flags); i++) { + if (value & (1 << i)) { + /* Tristate pin */ + flags[i] = (GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE); + } else { + /* Leave unmodified */ + flags[i] = 0; + } + } + + error = GPIO_PIN_CONFIG_32(ctx->gpio_dev, 0, nitems(flags), flags); + if (error) + panic("error configuring pin flags: %d", error); +} + +/* + * siba_gpio_get() + * + * Referenced by: + * bwn_gpio_init() + */ +static uint32_t +bhnd_compat_gpio_get(device_t dev) +{ + struct bwn_bhnd_ctx *ctx; + uint32_t ctrl; + int npin; + int error; + + /* + * We recreate the expected GPIOCTRL register value for bwn_gpio_init() + * by querying pins individually for GPIO_PIN_TRISTATE. + * + * Once we drop these compatibility shims, the GPIO_PIN_CONFIG_32 method + * can be used to set pin configuration without bwn(4) externally + * implementing RMW. + */ + + /* Fetch the total pin count */ + ctx = bwn_bhnd_get_ctx(dev); + if ((error = GPIO_PIN_MAX(ctx->gpio_dev, &npin))) + panic("failed to fetch max pin: %d", error); + + /* Must be representable within a 32-bit GPIOCTRL register value */ + KASSERT(npin <= 32, ("unsupported pin count: %u", npin)); + + ctrl = 0; + for (uint32_t pin = 0; pin < npin; pin++) { + uint32_t flags; + + if ((error = GPIO_PIN_GETFLAGS(ctx->gpio_dev, pin, &flags))) + panic("error fetching pin%u flags: %d", pin, error); + + if (flags & GPIO_PIN_TRISTATE) + ctrl |= (1 << pin); + } + + return (ctrl); +} + +/* + * siba_fix_imcfglobug() + * + * Referenced by: + * bwn_core_init() + */ +static void +bhnd_compat_fix_imcfglobug(device_t dev) +{ + /* This is handled by siba_bhndb during attach/resume */ +} + + +/* Core power NVRAM variables, indexed by D11 core unit number */ +static const struct bwn_power_vars { + const char *itt2ga; + const char *itt5ga; + const char *maxp2ga; + const char *pa2ga; + const char *pa5ga; +} bwn_power_vars[BWN_BHND_NUM_CORE_PWR] = { +#define BHND_POWER_NVAR(_idx) \ + { BHND_NVAR_ITT2GA ## _idx, BHND_NVAR_ITT5GA ## _idx, \ + BHND_NVAR_MAXP2GA ## _idx, BHND_NVAR_PA2GA ## _idx, \ + BHND_NVAR_PA5GA ## _idx } + BHND_POWER_NVAR(0), + BHND_POWER_NVAR(1), + BHND_POWER_NVAR(2), + BHND_POWER_NVAR(3) +#undef BHND_POWER_NVAR +}; + +static int +bwn_get_core_power_info_r11(device_t dev, const struct bwn_power_vars *v, + struct siba_sprom_core_pwr_info *c) +{ + int16_t pa5ga[12]; + int error; + + /* BHND_NVAR_PA2GA[core] */ + error = bhnd_nvram_getvar_array(dev, v->pa2ga, c->pa_2g, + sizeof(c->pa_2g), BHND_NVRAM_TYPE_INT16); + if (error) + return (error); + + /* + * BHND_NVAR_PA5GA + * + * The NVRAM variable is defined as a single pa5ga[12] array; we have + * to split this into pa_5gl[4], pa_5g[4], and pa_5gh[4] for use + * by bwn(4); + */ + _Static_assert(nitems(pa5ga) == nitems(c->pa_5g) + nitems(c->pa_5gh) + + nitems(c->pa_5gl), "cannot split pa5ga into pa_5gl/pa_5g/pa_5gh"); + + error = bhnd_nvram_getvar_array(dev, v->pa5ga, pa5ga, sizeof(pa5ga), + BHND_NVRAM_TYPE_INT16); + if (error) + return (error); + + memcpy(c->pa_5gl, &pa5ga[0], sizeof(c->pa_5gl)); + memcpy(c->pa_5g, &pa5ga[4], sizeof(c->pa_5g)); + memcpy(c->pa_5gh, &pa5ga[8], sizeof(c->pa_5gh)); + return (0); +} + +static int +bwn_get_core_power_info_r4_r10(device_t dev, + const struct bwn_power_vars *v, struct siba_sprom_core_pwr_info *c) +{ + int error; + + /* BHND_NVAR_ITT2GA[core] */ + if ((error = bhnd_nvram_getvar_uint8(dev, v->itt2ga, &c->itssi_2g))) + return (error); + + /* BHND_NVAR_ITT5GA[core] */ + if ((error = bhnd_nvram_getvar_uint8(dev, v->itt5ga, &c->itssi_5g))) + return (error); + + return (0); +} + +/* + * siba_sprom_get_core_power_info() + * + * Referenced by: + * bwn_nphy_tx_power_ctl_setup() + * bwn_ppr_load_max_from_sprom() + */ +static int +bhnd_compat_sprom_get_core_power_info(device_t dev, int core, + struct siba_sprom_core_pwr_info *c) +{ + struct bwn_bhnd_ctx *ctx; + const struct bwn_power_vars *v; + int error; + + if (core < 0 || core >= nitems(bwn_power_vars)) + return (EINVAL); + + ctx = bwn_bhnd_get_ctx(dev); + if (ctx->sromrev < 4) + return (ENXIO); + + v = &bwn_power_vars[core]; + + /* Any power variables not found in NVRAM (or returning a + * shorter array for a particular NVRAM revision) should be zero + * initialized */ + memset(c, 0x0, sizeof(*c)); + + /* Populate SPROM revision-independent values */ + if ((error = bhnd_nvram_getvar_uint8(dev, v->maxp2ga, &c->maxpwr_2g))) + return (error); + + /* Populate SPROM revision-specific values */ + if (ctx->sromrev >= 4 && ctx->sromrev <= 10) + return (bwn_get_core_power_info_r4_r10(dev, v, c)); + else + return (bwn_get_core_power_info_r11(dev, v, c)); +} + +/* + * siba_sprom_get_mcs2gpo() + * + * Referenced by: + * bwn_ppr_load_max_from_sprom() + */ +static int +bhnd_compat_sprom_get_mcs2gpo(device_t dev, uint16_t *c) +{ + static const char *varnames[] = { + BHND_NVAR_MCS2GPO0, + BHND_NVAR_MCS2GPO1, + BHND_NVAR_MCS2GPO2, + BHND_NVAR_MCS2GPO3, + BHND_NVAR_MCS2GPO4, + BHND_NVAR_MCS2GPO5, + BHND_NVAR_MCS2GPO6, + BHND_NVAR_MCS2GPO7 + }; + + for (size_t i = 0; i < nitems(varnames); i++) { + const char *name = varnames[i]; + BWN_BHND_NVRAM_FETCH_VAR(dev, uint16, name, &c[i]); + } + + return (0); +} + +/* + * siba_sprom_get_mcs5glpo() + * + * Referenced by: + * bwn_ppr_load_max_from_sprom() + */ +static int +bhnd_compat_sprom_get_mcs5glpo(device_t dev, uint16_t *c) +{ + static const char *varnames[] = { + BHND_NVAR_MCS5GLPO0, + BHND_NVAR_MCS5GLPO1, + BHND_NVAR_MCS5GLPO2, + BHND_NVAR_MCS5GLPO3, + BHND_NVAR_MCS5GLPO4, + BHND_NVAR_MCS5GLPO5, + BHND_NVAR_MCS5GLPO6, + BHND_NVAR_MCS5GLPO7 + }; + + for (size_t i = 0; i < nitems(varnames); i++) { + const char *name = varnames[i]; + BWN_BHND_NVRAM_FETCH_VAR(dev, uint16, name, &c[i]); + } + + return (0); +} + +/* + * siba_sprom_get_mcs5gpo() + * + * Referenced by: + * bwn_ppr_load_max_from_sprom() + */ +static int +bhnd_compat_sprom_get_mcs5gpo(device_t dev, uint16_t *c) +{ + static const char *varnames[] = { + BHND_NVAR_MCS5GPO0, + BHND_NVAR_MCS5GPO1, + BHND_NVAR_MCS5GPO2, + BHND_NVAR_MCS5GPO3, + BHND_NVAR_MCS5GPO4, + BHND_NVAR_MCS5GPO5, + BHND_NVAR_MCS5GPO6, + BHND_NVAR_MCS5GPO7 + }; + + for (size_t i = 0; i < nitems(varnames); i++) { + const char *name = varnames[i]; + BWN_BHND_NVRAM_FETCH_VAR(dev, uint16, name, &c[i]); + } + + return (0); +} + +/* + * siba_sprom_get_mcs5ghpo() + * + * Referenced by: + * bwn_ppr_load_max_from_sprom() + */ +static int +bhnd_compat_sprom_get_mcs5ghpo(device_t dev, uint16_t *c) +{ + static const char *varnames[] = { + BHND_NVAR_MCS5GHPO0, + BHND_NVAR_MCS5GHPO1, + BHND_NVAR_MCS5GHPO2, + BHND_NVAR_MCS5GHPO3, + BHND_NVAR_MCS5GHPO4, + BHND_NVAR_MCS5GHPO5, + BHND_NVAR_MCS5GHPO6, + BHND_NVAR_MCS5GHPO7 + }; + + for (size_t i = 0; i < nitems(varnames); i++) { + const char *name = varnames[i]; + BWN_BHND_NVRAM_FETCH_VAR(dev, uint16, name, &c[i]); + } + + return (0); +} + +/* + * siba_pmu_spuravoid_pllupdate() + * + * Referenced by: + * bwn_nphy_pmu_spur_avoid() + */ +static void +bhnd_compat_pmu_spuravoid_pllupdate(device_t dev, int spur_avoid) +{ + struct bwn_bhnd_ctx *ctx; + bhnd_pmu_spuravoid mode; + int error; + + ctx = bwn_bhnd_get_ctx(dev); + + if (ctx->pmu_dev == NULL) + panic("requested spuravoid on non-PMU device"); + + switch (spur_avoid) { + case 0: + mode = BHND_PMU_SPURAVOID_NONE; + break; + case 1: + mode = BHND_PMU_SPURAVOID_M1; + break; + default: + panic("unknown spur_avoid: %d", spur_avoid); + } + + if ((error = bhnd_pmu_request_spuravoid(ctx->pmu_dev, mode))) + panic("spuravoid request failed: %d", error); +} + +/* + * siba_cc_set32() + * + * Referenced by: + * bwn_phy_initn() + * bwn_wireless_core_phy_pll_reset() + */ +static void +bhnd_compat_cc_set32(device_t dev, uint32_t reg, uint32_t val) +{ + struct bwn_bhnd_ctx *ctx = bwn_bhnd_get_ctx(dev); + + /* + * OR with the current value. + * + * This function is only ever used to write to either ChipCommon's + * chipctrl register or chipctl_data register. Note that chipctl_data + * is actually a PMU register; it is not actually mapped by ChipCommon + * on Always-on-Bus (AOB) devices with a standalone PMU core. + */ + if (dev != ctx->chipc_dev) + panic("unsupported device: %s", device_get_nameunit(dev)); + + switch (reg) { + case SIBA_CC_CHIPCTL: + BHND_CHIPC_WRITE_CHIPCTRL(ctx->chipc_dev, val, val); + break; + case SIBA_CC_CHIPCTL_DATA: + bhnd_pmu_write_chipctrl(ctx->pmu_dev, ctx->pmu_cctl_addr, val, + val); + break; + default: + panic("unsupported register: %#x", reg); + } +} + +/* + * siba_cc_mask32() + * + * Referenced by: + * bwn_wireless_core_phy_pll_reset() + */ +static void +bhnd_compat_cc_mask32(device_t dev, uint32_t reg, uint32_t mask) +{ + struct bwn_bhnd_ctx *ctx = bwn_bhnd_get_ctx(dev); + + /* + * AND with the current value. + * + * This function is only ever used to write to ChipCommon's chipctl_data + * register. Note that chipctl_data is actually a PMU register; it is + * not actually mapped by ChipCommon on Always-on-Bus (AOB) devices with + * a standalone PMU core. + */ + if (dev != ctx->chipc_dev) + panic("unsupported device: %s", device_get_nameunit(dev)); + + switch (reg) { + case SIBA_CC_CHIPCTL_DATA: + bhnd_pmu_write_chipctrl(ctx->pmu_dev, ctx->pmu_cctl_addr, 0, + ~mask); + break; + default: + panic("unsupported register: %#x", reg); + } +} + +/* + * siba_cc_write32() + * + * Referenced by: + * bwn_wireless_core_phy_pll_reset() + */ +static void +bhnd_compat_cc_write32(device_t dev, uint32_t reg, uint32_t val) +{ + struct bwn_bhnd_ctx *ctx = bwn_bhnd_get_ctx(dev); + + /* + * This function is only ever used to write to ChipCommon's chipctl_addr + * register; setting chipctl_addr is handled atomically by + * bhnd_pmu_write_chipctrl(), so we merely cache the intended address + * for later use when chipctl_data is written. + * + * Also, note that chipctl_addr is actually a PMU register; it is + * not actually mapped by ChipCommon on Always-on-Bus (AOB) devices with + * a standalone PMU core. + */ + if (dev != ctx->chipc_dev) + panic("unsupported device: %s", device_get_nameunit(dev)); + + switch (reg) { + case SIBA_CC_CHIPCTL_ADDR: + ctx->pmu_cctl_addr = val; + break; + default: + panic("unsupported register: %#x", reg); + } +} + +const struct bwn_bus_ops bwn_bhnd_bus_ops = { + .init = bwn_bhnd_bus_ops_init, + .fini = bwn_bhnd_bus_ops_fini, + .pci_find_cap = bhnd_compat_pci_find_cap, + .pci_alloc_msi = bhnd_compat_pci_alloc_msi, + .pci_release_msi = bhnd_compat_pci_release_msi, + .pci_msi_count = bhnd_compat_pci_msi_count, + .get_vendor = bhnd_compat_get_vendor, + .get_device = bhnd_compat_get_device, + .get_revid = bhnd_compat_get_revid, + .get_pci_vendor = bhnd_compat_get_pci_vendor, + .get_pci_device = bhnd_compat_get_pci_device, + .get_pci_subvendor = bhnd_compat_get_pci_subvendor, + .get_pci_subdevice = bhnd_compat_get_pci_subdevice, + .get_pci_revid = bhnd_compat_get_pci_revid, + .get_chipid = bhnd_compat_get_chipid, + .get_chiprev = bhnd_compat_get_chiprev, + .get_chippkg = bhnd_compat_get_chippkg, + .get_type = bhnd_compat_get_type, + .get_cc_pmufreq = bhnd_compat_get_cc_pmufreq, + .get_cc_caps = bhnd_compat_get_cc_caps, + .get_cc_powerdelay = bhnd_compat_get_cc_powerdelay, + .get_pcicore_revid = bhnd_compat_get_pcicore_revid, + .sprom_get_rev = bhnd_compat_sprom_get_rev, + .sprom_get_mac_80211bg = bhnd_compat_sprom_get_mac_80211bg, + .sprom_get_mac_80211a = bhnd_compat_sprom_get_mac_80211a, + .sprom_get_brev = bhnd_compat_sprom_get_brev, + .sprom_get_ccode = bhnd_compat_sprom_get_ccode, + .sprom_get_ant_a = bhnd_compat_sprom_get_ant_a, + .sprom_get_ant_bg = bhnd_compat_sprom_get_ant_bg, + .sprom_get_pa0b0 = bhnd_compat_sprom_get_pa0b0, + .sprom_get_pa0b1 = bhnd_compat_sprom_get_pa0b1, + .sprom_get_pa0b2 = bhnd_compat_sprom_get_pa0b2, + .sprom_get_gpio0 = bhnd_compat_sprom_get_gpio0, + .sprom_get_gpio1 = bhnd_compat_sprom_get_gpio1, + .sprom_get_gpio2 = bhnd_compat_sprom_get_gpio2, + .sprom_get_gpio3 = bhnd_compat_sprom_get_gpio3, + .sprom_get_maxpwr_bg = bhnd_compat_sprom_get_maxpwr_bg, + .sprom_set_maxpwr_bg = bhnd_compat_sprom_set_maxpwr_bg, + .sprom_get_rxpo2g = bhnd_compat_sprom_get_rxpo2g, + .sprom_get_rxpo5g = bhnd_compat_sprom_get_rxpo5g, + .sprom_get_tssi_bg = bhnd_compat_sprom_get_tssi_bg, + .sprom_get_tri2g = bhnd_compat_sprom_get_tri2g, + .sprom_get_tri5gl = bhnd_compat_sprom_get_tri5gl, + .sprom_get_tri5g = bhnd_compat_sprom_get_tri5g, + .sprom_get_tri5gh = bhnd_compat_sprom_get_tri5gh, + .sprom_get_rssisav2g = bhnd_compat_sprom_get_rssisav2g, + .sprom_get_rssismc2g = bhnd_compat_sprom_get_rssismc2g, + .sprom_get_rssismf2g = bhnd_compat_sprom_get_rssismf2g, + .sprom_get_bxa2g = bhnd_compat_sprom_get_bxa2g, + .sprom_get_rssisav5g = bhnd_compat_sprom_get_rssisav5g, + .sprom_get_rssismc5g = bhnd_compat_sprom_get_rssismc5g, + .sprom_get_rssismf5g = bhnd_compat_sprom_get_rssismf5g, + .sprom_get_bxa5g = bhnd_compat_sprom_get_bxa5g, + .sprom_get_cck2gpo = bhnd_compat_sprom_get_cck2gpo, + .sprom_get_ofdm2gpo = bhnd_compat_sprom_get_ofdm2gpo, + .sprom_get_ofdm5glpo = bhnd_compat_sprom_get_ofdm5glpo, + .sprom_get_ofdm5gpo = bhnd_compat_sprom_get_ofdm5gpo, + .sprom_get_ofdm5ghpo = bhnd_compat_sprom_get_ofdm5ghpo, + .sprom_get_bf_lo = bhnd_compat_sprom_get_bf_lo, + .sprom_set_bf_lo = bhnd_compat_sprom_set_bf_lo, + .sprom_get_bf_hi = bhnd_compat_sprom_get_bf_hi, + .sprom_get_bf2_lo = bhnd_compat_sprom_get_bf2_lo, + .sprom_get_bf2_hi = bhnd_compat_sprom_get_bf2_hi, + .sprom_get_fem_2ghz_tssipos = bhnd_compat_sprom_get_fem_2ghz_tssipos, + .sprom_get_fem_2ghz_extpa_gain = bhnd_compat_sprom_get_fem_2ghz_extpa_gain, + .sprom_get_fem_2ghz_pdet_range = bhnd_compat_sprom_get_fem_2ghz_pdet_range, + .sprom_get_fem_2ghz_tr_iso = bhnd_compat_sprom_get_fem_2ghz_tr_iso, + .sprom_get_fem_2ghz_antswlut = bhnd_compat_sprom_get_fem_2ghz_antswlut, + .sprom_get_fem_5ghz_extpa_gain = bhnd_compat_sprom_get_fem_5ghz_extpa_gain, + .sprom_get_fem_5ghz_pdet_range = bhnd_compat_sprom_get_fem_5ghz_pdet_range, + .sprom_get_fem_5ghz_antswlut = bhnd_compat_sprom_get_fem_5ghz_antswlut, + .sprom_get_txpid_2g_0 = bhnd_compat_sprom_get_txpid_2g_0, + .sprom_get_txpid_2g_1 = bhnd_compat_sprom_get_txpid_2g_1, + .sprom_get_txpid_5gl_0 = bhnd_compat_sprom_get_txpid_5gl_0, + .sprom_get_txpid_5gl_1 = bhnd_compat_sprom_get_txpid_5gl_1, + .sprom_get_txpid_5g_0 = bhnd_compat_sprom_get_txpid_5g_0, + .sprom_get_txpid_5g_1 = bhnd_compat_sprom_get_txpid_5g_1, + .sprom_get_txpid_5gh_0 = bhnd_compat_sprom_get_txpid_5gh_0, + .sprom_get_txpid_5gh_1 = bhnd_compat_sprom_get_txpid_5gh_1, + .sprom_get_stbcpo = bhnd_compat_sprom_get_stbcpo, + .sprom_get_cddpo = bhnd_compat_sprom_get_cddpo, + .powerup = bhnd_compat_powerup, + .powerdown = bhnd_compat_powerdown, + .read_2 = bhnd_compat_read_2, + .write_2 = bhnd_compat_write_2, + .read_4 = bhnd_compat_read_4, + .write_4 = bhnd_compat_write_4, + .dev_up = bhnd_compat_dev_up, + .dev_down = bhnd_compat_dev_down, + .dev_isup = bhnd_compat_dev_isup, + .pcicore_intr = bhnd_compat_pcicore_intr, + .dma_translation = bhnd_compat_dma_translation, + .read_multi_2 = bhnd_compat_read_multi_2, + .read_multi_4 = bhnd_compat_read_multi_4, + .write_multi_2 = bhnd_compat_write_multi_2, + .write_multi_4 = bhnd_compat_write_multi_4, + .barrier = bhnd_compat_barrier, + .cc_pmu_set_ldovolt = bhnd_compat_cc_pmu_set_ldovolt, + .cc_pmu_set_ldoparef = bhnd_compat_cc_pmu_set_ldoparef, + .gpio_set = bhnd_compat_gpio_set, + .gpio_get = bhnd_compat_gpio_get, + .fix_imcfglobug = bhnd_compat_fix_imcfglobug, + .sprom_get_core_power_info = bhnd_compat_sprom_get_core_power_info, + .sprom_get_mcs2gpo = bhnd_compat_sprom_get_mcs2gpo, + .sprom_get_mcs5glpo = bhnd_compat_sprom_get_mcs5glpo, + .sprom_get_mcs5gpo = bhnd_compat_sprom_get_mcs5gpo, + .sprom_get_mcs5ghpo = bhnd_compat_sprom_get_mcs5ghpo, + .pmu_spuravoid_pllupdate = bhnd_compat_pmu_spuravoid_pllupdate, + .cc_set32 = bhnd_compat_cc_set32, + .cc_mask32 = bhnd_compat_cc_mask32, + .cc_write32 = bhnd_compat_cc_write32, +}; Index: sys/dev/bwn/if_bwn_util.c =================================================================== --- sys/dev/bwn/if_bwn_util.c +++ sys/dev/bwn/if_bwn_util.c @@ -65,9 +65,6 @@ #include #include -#include -#include -#include #include #include @@ -75,6 +72,8 @@ #include #include +#include + #include #include Index: sys/dev/bwn/if_bwnvar.h =================================================================== --- sys/dev/bwn/if_bwnvar.h +++ sys/dev/bwn/if_bwnvar.h @@ -34,10 +34,16 @@ #ifndef _IF_BWNVAR_H #define _IF_BWNVAR_H -struct siba_dev_softc; +#include "if_bwn_siba.h" + struct bwn_softc; struct bwn_mac; +extern driver_t bwn_driver; + +int bwn_attach(device_t dev); +int bwn_detach(device_t dev); + #define N(a) (sizeof(a) / sizeof(a[0])) #define BWN_ALIGN 0x1000 #define BWN_BUS_SPACE_MAXADDR_30BIT 0x3fffffff @@ -1005,6 +1011,12 @@ struct bwn_softc { device_t sc_dev; + const struct bwn_bus_ops *sc_bus_ops; +#if !BWN_USE_SIBA + void *sc_bus_ctx; + struct bhnd_resource *sc_mem_res; + int sc_mem_rid; +#endif /* !BWN_USE_SIBA */ struct mtx sc_mtx; struct ieee80211com sc_ic; struct mbufq sc_snd; @@ -1152,14 +1164,4 @@ return c->ic_maxpower / 2; } -/* - * For now there's no bhnd bus support. Places where it matters - * should call this routine so we can start logging things. - */ -static inline int -bwn_is_bus_siba(struct bwn_mac *mac) -{ - - return 1; -} #endif /* !_IF_BWNVAR_H */ Index: sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.c =================================================================== --- sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.c +++ sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.c @@ -62,9 +62,6 @@ #include #include -#include -#include -#include #include #include @@ -6138,10 +6135,7 @@ BWN_PHY_WRITE(mac, BWN_NPHY_GPIO_LOOEN, 0); BWN_PHY_WRITE(mac, BWN_NPHY_GPIO_HIOEN, 0); - /* XXX handle bhnd bus */ - if (bwn_is_bus_siba(mac)) { - siba_gpio_set(sc->sc_dev, 0xfc00); - } + siba_gpio_set(sc->sc_dev, 0xfc00); BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~BWN_MACCTL_GPOUT_MASK, 0); BWN_WRITE_SETMASK2(mac, BWN_GPIO_MASK, ~0, 0xFC00); @@ -6175,10 +6169,7 @@ if ((mac->mac_phy.rev >= 3) && (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && (bwn_current_band(mac) == BWN_BAND_2G)) { - /* XXX bhnd bus */ - if (bwn_is_bus_siba(mac)) { - siba_cc_set32(sc->sc_dev, SIBA_CC_CHIPCTL, 0x40); - } + siba_cc_set32(sc->sc_dev, SIBA_CC_CHIPCTL, 0x40); } nphy->use_int_tx_iq_lo_cal = bwn_nphy_ipa(mac) || phy->rev >= 7 || @@ -6380,11 +6371,8 @@ { struct bwn_softc *sc = mac->mac_sc; - /* XXX bhnd */ - if (bwn_is_bus_siba(mac)) { - DPRINTF(sc, BWN_DEBUG_RESET, "%s: spuravoid %d\n", __func__, avoid); - siba_pmu_spuravoid_pllupdate(sc->sc_dev, avoid); - } + DPRINTF(sc, BWN_DEBUG_RESET, "%s: spuravoid %d\n", __func__, avoid); + siba_pmu_spuravoid_pllupdate(sc->sc_dev, avoid); } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */ @@ -6635,8 +6623,7 @@ if (mac->mac_phy.rev >= 2 && (siba_sprom_get_bf2_lo(sc->sc_dev) & BWN_BFL2_TXPWRCTRL_EN)) { nphy->txpwrctrl = true; - if (bwn_is_bus_siba(mac) && - (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI)) { + if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) { if ((siba_get_pci_device(sc->sc_dev) == 0x4328) || (siba_get_pci_device(sc->sc_dev) == 0x432a)) nphy->pwg_gain_5ghz = true; Index: sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.c =================================================================== --- sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.c +++ sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.c @@ -60,9 +60,6 @@ #include #include -#include -#include -#include #include #include Index: sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.c =================================================================== --- sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.c +++ sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.c @@ -61,9 +61,6 @@ #include #include -#include -#include -#include #include #include Index: sys/gnu/dev/bwn/phy_n/if_bwn_radio_2055.c =================================================================== --- sys/gnu/dev/bwn/phy_n/if_bwn_radio_2055.c +++ sys/gnu/dev/bwn/phy_n/if_bwn_radio_2055.c @@ -61,9 +61,6 @@ #include #include -#include -#include -#include #include #include Index: sys/gnu/dev/bwn/phy_n/if_bwn_radio_2056.c =================================================================== --- sys/gnu/dev/bwn/phy_n/if_bwn_radio_2056.c +++ sys/gnu/dev/bwn/phy_n/if_bwn_radio_2056.c @@ -62,9 +62,6 @@ #include #include -#include -#include -#include #include #include Index: sys/gnu/dev/bwn/phy_n/if_bwn_radio_2057.c =================================================================== --- sys/gnu/dev/bwn/phy_n/if_bwn_radio_2057.c +++ sys/gnu/dev/bwn/phy_n/if_bwn_radio_2057.c @@ -62,9 +62,6 @@ #include #include -#include -#include -#include #include #include Index: sys/modules/bwn/Makefile =================================================================== --- sys/modules/bwn/Makefile +++ sys/modules/bwn/Makefile @@ -4,6 +4,7 @@ KMOD= if_bwn SRCS= if_bwn.c if_bwnreg.h if_bwnvar.h +SRCS+= if_bwn_siba.c if_bwn_bhnd.c if_bwn_siba_compat.c SRCS+= if_bwn_util.c # PHY @@ -11,8 +12,15 @@ SRCS+= if_bwn_phy_g.c if_bwn_phy_lp.c SRCS+= if_bwn_phy_n.c +# BHND +SRCS+= bhnd_bus_if.h \ + bhnd_chipc_if.h \ + bhnd_pmu_if.h \ + bhnd_pwrctl_if.h +SRCS+= bhnd_nvram_map.h + # Other -SRCS+= device_if.h bus_if.h pci_if.h opt_bwn.h opt_wlan.h +SRCS+= device_if.h bus_if.h gpio_if.h pci_if.h opt_bwn.h opt_wlan.h # The following need the BWN_GPL_PHY kenrel option to opt-in # to the GPL'd 802.11n PHY support for this driver. Index: sys/modules/bwn_pci/Makefile =================================================================== --- sys/modules/bwn_pci/Makefile +++ sys/modules/bwn_pci/Makefile @@ -3,9 +3,10 @@ .PATH: ${SRCTOP}/sys/dev/bwn KMOD= if_bwn_pci -SRCS= if_bwn_pci.c bwn_mac.c +SRCS= if_bwn_pci.c + SRCS+= bhnd_bus_if.h bhndb_bus_if.h \ - bhndb_if.h bhnd_nvram_map.h + bhndb_if.h SRCS+= device_if.h bus_if.h pci_if.h \ opt_bwn.h opt_wlan.h opt_global.h