2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org>
5 * Copyright (c) 2017 The FreeBSD Foundation
8 * Portions of this software were developed by Landon Fuller
9 * under sponsorship from the FreeBSD Foundation.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include <sys/param.h>
39 #include <sys/kernel.h>
40 #include <sys/systm.h>
41 #include <sys/socket.h>
42 #include <sys/sockio.h>
44 #include <machine/bus.h>
46 #include <machine/resource.h>
48 #include <net/ethernet.h>
50 #include <net/if_var.h>
51 #include <net/if_arp.h>
52 #include <net/if_dl.h>
53 #include <net/if_llc.h>
54 #include <net/if_media.h>
55 #include <net/if_types.h>
57 #include <dev/pci/pcireg.h>
58 #include <dev/pci/pcivar.h>
60 #include <net80211/ieee80211_var.h>
61 #include <net80211/ieee80211_radiotap.h>
62 #include <net80211/ieee80211_regdomain.h>
63 #include <net80211/ieee80211_phy.h>
64 #include <net80211/ieee80211_ratectl.h>
66 #include <dev/bhnd/bhnd.h>
67 #include <dev/bhnd/siba/sibareg.h>
69 #include <dev/bhnd/cores/chipc/chipc.h>
70 #include <dev/bhnd/cores/pci/bhnd_pcireg.h>
71 #include <dev/bhnd/cores/pmu/bhnd_pmu.h>
75 #include "bhnd_nvram_map.h"
77 #include "if_bwn_siba_compat.h"
79 static int bwn_bhnd_populate_nvram_data(device_t dev,
80 struct bwn_bhnd_ctx *ctx);
81 static inline bool bwn_bhnd_is_siba_reg(device_t dev, uint16_t offset);
83 #define BWN_ASSERT_VALID_REG(_dev, _offset) \
84 KASSERT(!bwn_bhnd_is_siba_reg(_dev, _offset), \
85 ("%s: accessing siba-specific register %#jx", __FUNCTION__, \
86 (uintmax_t)(_offset)));
89 bwn_bhnd_bus_ops_init(device_t dev)
91 struct bwn_bhnd_ctx *ctx;
93 const struct chipc_caps *ccaps;
96 sc = device_get_softc(dev);
100 sc->sc_mem_res = bhnd_alloc_resource_any(dev, SYS_RES_MEMORY,
101 &sc->sc_mem_rid, RF_ACTIVE);
102 if (sc->sc_mem_res == NULL) {
106 /* Allocate PMU state */
107 if ((error = bhnd_alloc_pmu(dev))) {
108 device_printf(dev, "PMU allocation failed: %d\n", error);
112 /* Allocate our context */
113 ctx = malloc(sizeof(struct bwn_bhnd_ctx), M_DEVBUF, M_WAITOK|M_ZERO);
115 /* Locate the ChipCommon device */
116 ctx->chipc_dev = bhnd_retain_provider(dev, BHND_SERVICE_CHIPC);
117 if (ctx->chipc_dev == NULL) {
118 device_printf(dev, "ChipCommon not found\n");
123 /* Locate the GPIO device */
124 ctx->gpio_dev = bhnd_retain_provider(dev, BHND_SERVICE_GPIO);
125 if (ctx->gpio_dev == NULL) {
126 device_printf(dev, "GPIO not found\n");
131 /* Locate the PMU device (if any) */
132 ccaps = BHND_CHIPC_GET_CAPS(ctx->chipc_dev);
134 ctx->pmu_dev = bhnd_retain_provider(dev, BHND_SERVICE_PMU);
135 if (ctx->pmu_dev == NULL) {
136 device_printf(dev, "PMU not found\n");
142 /* Populate NVRAM data */
143 if ((error = bwn_bhnd_populate_nvram_data(dev, ctx)))
146 /* Initialize bwn_softc */
147 sc->sc_bus_ctx = ctx;
151 bhnd_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid,
155 if (ctx->chipc_dev != NULL) {
156 bhnd_release_provider(dev, ctx->chipc_dev,
160 if (ctx->gpio_dev != NULL) {
161 bhnd_release_provider(dev, ctx->gpio_dev,
165 if (ctx->pmu_dev != NULL) {
166 bhnd_release_provider(dev, ctx->pmu_dev,
177 bwn_bhnd_bus_ops_fini(device_t dev)
179 struct bwn_bhnd_ctx *ctx;
180 struct bwn_softc *sc;
182 sc = device_get_softc(dev);
183 ctx = sc->sc_bus_ctx;
185 bhnd_release_pmu(dev);
186 bhnd_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid,
189 bhnd_release_provider(dev, ctx->chipc_dev, BHND_SERVICE_CHIPC);
190 bhnd_release_provider(dev, ctx->gpio_dev, BHND_SERVICE_GPIO);
192 if (ctx->pmu_dev != NULL)
193 bhnd_release_provider(dev, ctx->pmu_dev, BHND_SERVICE_PMU);
196 sc->sc_bus_ctx = NULL;
201 * Return true if @p offset is within a siba-specific configuration register
205 bwn_bhnd_is_siba_reg(device_t dev, uint16_t offset)
207 if (offset >= SIBA_CFG0_OFFSET &&
208 offset <= SIBA_CFG0_OFFSET + SIBA_CFG_SIZE)
211 if (offset >= SIBA_CFG1_OFFSET &&
212 offset <= SIBA_CFG1_OFFSET + SIBA_CFG_SIZE)
218 /* Populate SPROM values from NVRAM */
220 bwn_bhnd_populate_nvram_data(device_t dev, struct bwn_bhnd_ctx *ctx)
222 const char *mac_80211bg_var, *mac_80211a_var;
225 /* Fetch SROM revision */
226 error = bhnd_nvram_getvar_uint8(dev, BHND_NVAR_SROMREV, &ctx->sromrev);
228 device_printf(dev, "error reading %s: %d\n", BHND_NVAR_SROMREV,
233 /* Fetch board flags */
234 error = bhnd_nvram_getvar_uint32(dev, BHND_NVAR_BOARDFLAGS,
237 device_printf(dev, "error reading %s: %d\n",
238 BHND_NVAR_BOARDFLAGS, error);
242 /* Fetch macaddrs if available; bwn(4) expects any missing macaddr
243 * values to be initialized with 0xFF octets */
244 memset(ctx->mac_80211bg, 0xFF, sizeof(ctx->mac_80211bg));
245 memset(ctx->mac_80211a, 0xFF, sizeof(ctx->mac_80211a));
247 if (ctx->sromrev <= 2) {
248 mac_80211bg_var = BHND_NVAR_IL0MACADDR;
249 mac_80211a_var = BHND_NVAR_ET1MACADDR;
251 mac_80211bg_var = BHND_NVAR_MACADDR;
252 mac_80211a_var = NULL;
255 /* Fetch required D11 core 0 macaddr */
256 error = bhnd_nvram_getvar_array(dev, mac_80211bg_var, ctx->mac_80211bg,
257 sizeof(ctx->mac_80211bg), BHND_NVRAM_TYPE_UINT8_ARRAY);
259 device_printf(dev, "error reading %s: %d\n", mac_80211bg_var,
264 /* Fetch optional D11 core 1 macaddr */
265 if (mac_80211a_var != NULL) {
266 error = bhnd_nvram_getvar_array(dev, mac_80211a_var,
267 ctx->mac_80211a, sizeof(ctx->mac_80211a),
268 BHND_NVRAM_TYPE_UINT8_ARRAY);
270 if (error && error != ENOENT) {
271 device_printf(dev, "error reading %s: %d\n",
272 mac_80211a_var, error);
277 /* Fetch pa0maxpwr; bwn(4) expects to be able to modify it */
278 if ((ctx->sromrev >= 1 && ctx->sromrev <= 3) ||
279 (ctx->sromrev >= 8 && ctx->sromrev <= 10))
281 error = bhnd_nvram_getvar_uint8(dev, BHND_NVAR_PA0MAXPWR,
284 device_printf(dev, "error reading %s: %d\n",
285 BHND_NVAR_PA0MAXPWR, error);
294 * Disable PCI-specific MSI interrupt allocation handling
304 bhnd_compat_pci_find_cap(device_t dev, int capability, int *capreg)
316 bhnd_compat_pci_alloc_msi(device_t dev, int *count)
329 bhnd_compat_pci_release_msi(device_t dev)
341 bhnd_compat_pci_msi_count(device_t dev)
353 bhnd_compat_get_vendor(device_t dev)
355 uint16_t vendor = bhnd_get_vendor(dev);
359 return (SIBA_VID_BROADCOM);
372 bhnd_compat_get_device(device_t dev)
374 return (bhnd_get_device(dev));
388 * bwn_pio_set_txqueue()
395 bhnd_compat_get_revid(device_t dev)
397 return (bhnd_get_hwrev(dev));
401 * Return the PCI bridge root device.
403 * Will panic if a PCI bridge root device is not found.
406 bwn_bhnd_get_pci_dev(device_t dev)
407 { device_t bridge_root;
409 bridge_root = bhnd_find_bridge_root(dev, devclass_find("pci"));
410 if (bridge_root == NULL)
411 panic("not a PCI device");
413 return (bridge_root);
417 * siba_get_pci_vendor()
420 * bwn_sprom_bugfixes()
423 bhnd_compat_get_pci_vendor(device_t dev)
425 return (pci_get_vendor(bwn_bhnd_get_pci_dev(dev)));
429 * siba_get_pci_device()
434 * bwn_nphy_op_prepare_structs()
435 * bwn_sprom_bugfixes()
438 bhnd_compat_get_pci_device(device_t dev)
440 return (pci_get_device(bwn_bhnd_get_pci_dev(dev)));
444 * siba_get_pci_subvendor()
448 * bwn_nphy_op_prepare_structs()
449 * bwn_phy_g_prepare_hw()
450 * bwn_phy_hwpctl_init()
453 * bwn_phy_txpower_check()
454 * bwn_radio_init2055_post()
455 * bwn_sprom_bugfixes()
459 bhnd_compat_get_pci_subvendor(device_t dev)
461 return (pci_get_subvendor(bwn_bhnd_get_pci_dev(dev)));
465 * siba_get_pci_subdevice()
468 * bwn_nphy_workarounds_rev1_2()
469 * bwn_phy_g_prepare_hw()
470 * bwn_phy_hwpctl_init()
473 * bwn_phy_lp_bbinit_r01()
474 * bwn_phy_txpower_check()
475 * bwn_radio_init2055_post()
476 * bwn_sprom_bugfixes()
480 bhnd_compat_get_pci_subdevice(device_t dev)
482 return (pci_get_subdevice(bwn_bhnd_get_pci_dev(dev)));
486 * siba_get_pci_revid()
489 * bwn_phy_g_prepare_hw()
490 * bwn_phy_lp_bbinit_r2()
491 * bwn_sprom_bugfixes()
495 bhnd_compat_get_pci_revid(device_t dev)
497 return (pci_get_revid(bwn_bhnd_get_pci_dev(dev)));
506 * bwn_mac_switch_freq()
508 * bwn_phy_g_init_sub()
509 * bwn_phy_g_prepare_hw()
513 * bwn_sprom_bugfixes()
518 bhnd_compat_get_chipid(device_t dev)
520 return (bhnd_get_chipid(dev)->chip_id);
528 * bwn_phy_lp_bbinit_r2()
529 * bwn_phy_lp_tblinit_r2()
533 bhnd_compat_get_chiprev(device_t dev)
535 return (bhnd_get_chipid(dev)->chip_rev);
542 * bwn_phy_g_init_sub()
543 * bwn_phy_lp_bbinit_r01()
544 * bwn_radio_2056_setup()
547 bhnd_compat_get_chippkg(device_t dev)
549 return (bhnd_get_chipid(dev)->chip_pkg);
558 * bwn_nphy_op_prepare_structs()
559 * bwn_sprom_bugfixes()
561 static enum siba_type
562 bhnd_compat_get_type(device_t dev)
565 bhnd_devclass_t hostb_devclass;
567 bus = device_get_parent(dev);
568 hostb = bhnd_bus_find_hostb_device(bus);
571 return (SIBA_TYPE_SSB);
573 hostb_devclass = bhnd_get_class(hostb);
574 switch (hostb_devclass) {
575 case BHND_DEVCLASS_PCCARD:
576 return (SIBA_TYPE_PCMCIA);
577 case BHND_DEVCLASS_PCI:
578 case BHND_DEVCLASS_PCIE:
579 return (SIBA_TYPE_PCI);
581 panic("unsupported hostb devclass: %d\n", hostb_devclass);
586 * siba_get_cc_pmufreq()
589 * bwn_phy_lp_b2062_init()
590 * bwn_phy_lp_b2062_switch_channel()
591 * bwn_phy_lp_b2063_switch_channel()
592 * bwn_phy_lp_rxcal_r2()
595 bhnd_compat_get_cc_pmufreq(device_t dev)
600 if ((error = bhnd_get_clock_freq(dev, BHND_CLOCK_ALP, &freq)))
601 panic("failed to fetch clock frequency: %d", error);
603 /* TODO: bwn(4) immediately multiplies the result by 1000 (MHz -> Hz) */
604 return (freq / 1000);
611 * bwn_phy_lp_b2062_init()
614 bhnd_compat_get_cc_caps(device_t dev)
617 const struct chipc_caps *ccaps;
620 /* Fetch our ChipCommon device */
621 chipc = bhnd_retain_provider(dev, BHND_SERVICE_CHIPC);
623 panic("missing ChipCommon device");
626 * The ChipCommon capability flags are only used in one LP-PHY function,
627 * to assert that a PMU is in fact available.
629 * We can support this by producing a value containing just that flag.
632 ccaps = BHND_CHIPC_GET_CAPS(chipc);
634 result |= SIBA_CC_CAPS_PMU;
636 bhnd_release_provider(dev, chipc, BHND_SERVICE_CHIPC);
642 * siba_get_cc_powerdelay()
648 bhnd_compat_get_cc_powerdelay(device_t dev)
653 if ((error = bhnd_get_clock_latency(dev, BHND_CLOCK_HT, &delay)))
654 panic("failed to fetch clock latency: %d", error);
656 if (delay > UINT16_MAX)
657 panic("%#x would overflow", delay);
663 * siba_get_pcicore_revid()
669 bhnd_compat_get_pcicore_revid(device_t dev)
672 uint8_t nomatch_revid;
675 * This is used by bwn(4) in only bwn_core_init(), where a revid <= 10
676 * results in the BWN_HF_PCI_SLOWCLOCK_WORKAROUND workaround being
679 * The quirk should only be applied on siba(4) devices using a PCI
680 * core; we handle around this by returning a bogus value >= 10 here.
682 * TODO: bwn(4) should match this quirk on:
683 * - BHND_CHIPTYPE_SIBA
687 nomatch_revid = 0xFF;
689 hostb = bhnd_bus_find_hostb_device(device_get_parent(dev));
691 /* Not a bridged device */
692 return (nomatch_revid);
695 if (bhnd_get_device(hostb) != BHND_COREID_PCI) {
697 return (nomatch_revid);
700 /* This is a PCI core; we can return the real core revision */
701 return (bhnd_get_hwrev(hostb));
705 * siba_sprom_get_rev()
708 * bwn_nphy_op_prepare_structs()
709 * bwn_nphy_tx_power_ctl_setup()
710 * bwn_nphy_tx_power_fix()
711 * bwn_nphy_workarounds_rev7plus()
714 bhnd_compat_sprom_get_rev(device_t dev)
716 return (bwn_bhnd_get_ctx(dev)->sromrev);
720 * siba_sprom_get_mac_80211bg()
726 bhnd_compat_sprom_get_mac_80211bg(device_t dev)
728 /* 'MAC_80211BG' is il0macaddr or macaddr*/
729 return (bwn_bhnd_get_ctx(dev)->mac_80211bg);
733 * siba_sprom_get_mac_80211a()
739 bhnd_compat_sprom_get_mac_80211a(device_t dev)
741 /* 'MAC_80211A' is et1macaddr */
742 return (bwn_bhnd_get_ctx(dev)->mac_80211a);
746 * siba_sprom_get_brev()
749 * bwn_radio_init2055_post()
752 bhnd_compat_sprom_get_brev(device_t dev)
754 /* TODO: bwn(4) needs to switch to uint16_t */
755 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_BOARDREV);
759 * siba_sprom_get_ccode()
762 * bwn_phy_g_switch_chan()
765 bhnd_compat_sprom_get_ccode(device_t dev)
767 /* This has been replaced with 'ccode' in later SPROM
768 * revisions, but this API is only called on devices with
770 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_CC);
774 * siba_sprom_get_ant_a()
777 * bwn_antenna_sanitize()
780 bhnd_compat_sprom_get_ant_a(device_t dev)
782 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_AA5G);
786 * siba_sprom_get_ant_bg()
789 * bwn_antenna_sanitize()
792 bhnd_compat_sprom_get_ant_bg(device_t dev)
794 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_AA2G);
798 * siba_sprom_get_pa0b0()
804 bhnd_compat_sprom_get_pa0b0(device_t dev)
808 BWN_BHND_NVRAM_FETCH_VAR(dev, int16, BHND_NVAR_PA0B0, &value);
810 /* TODO: bwn(4) immediately casts this back to int16_t */
811 return ((uint16_t)value);
815 * siba_sprom_get_pa0b1()
821 bhnd_compat_sprom_get_pa0b1(device_t dev)
825 BWN_BHND_NVRAM_FETCH_VAR(dev, int16, BHND_NVAR_PA0B1, &value);
827 /* TODO: bwn(4) immediately casts this back to int16_t */
828 return ((uint16_t)value);
832 * siba_sprom_get_pa0b2()
838 bhnd_compat_sprom_get_pa0b2(device_t dev)
842 BWN_BHND_NVRAM_FETCH_VAR(dev, int16, BHND_NVAR_PA0B2, &value);
844 /* TODO: bwn(4) immediately casts this back to int16_t */
845 return ((uint16_t)value);
849 * Fetch an led behavior (ledbhX) NVRAM variable value, for use by
850 * siba_sprom_get_gpioX().
852 * ('gpioX' are actually the ledbhX NVRAM variables).
855 bhnd_compat_sprom_get_ledbh(device_t dev, const char *name)
860 error = bhnd_nvram_getvar_uint8(dev, name, &value);
861 if (error && error != ENOENT)
862 panic("NVRAM variable %s unreadable: %d", name, error);
864 /* For some variables (including ledbhX), a value with all bits set is
865 * treated as uninitialized in the SPROM format; our SPROM parser
866 * detects this case and returns ENOENT, but bwn(4) actually expects
867 * to read the raw value 0xFF value. */
875 * siba_sprom_get_gpio0()
877 * 'gpioX' are actually the led behavior (ledbh) NVRAM variables.
883 bhnd_compat_sprom_get_gpio0(device_t dev)
885 return (bhnd_compat_sprom_get_ledbh(dev, BHND_NVAR_LEDBH0));
889 * siba_sprom_get_gpio1()
895 bhnd_compat_sprom_get_gpio1(device_t dev)
897 return (bhnd_compat_sprom_get_ledbh(dev, BHND_NVAR_LEDBH1));
901 * siba_sprom_get_gpio2()
907 bhnd_compat_sprom_get_gpio2(device_t dev)
909 return (bhnd_compat_sprom_get_ledbh(dev, BHND_NVAR_LEDBH2));
913 * siba_sprom_get_gpio3()
919 bhnd_compat_sprom_get_gpio3(device_t dev)
921 return (bhnd_compat_sprom_get_ledbh(dev, BHND_NVAR_LEDBH3));
925 * siba_sprom_get_maxpwr_bg()
928 * bwn_phy_g_recalc_txpwr()
931 bhnd_compat_sprom_get_maxpwr_bg(device_t dev)
933 return (bwn_bhnd_get_ctx(dev)->pa0maxpwr);
937 * siba_sprom_set_maxpwr_bg()
940 * bwn_phy_g_recalc_txpwr()
943 bhnd_compat_sprom_set_maxpwr_bg(device_t dev, uint16_t t)
945 KASSERT(t <= UINT8_MAX, ("invalid maxpwr value %hu", t));
946 bwn_bhnd_get_ctx(dev)->pa0maxpwr = t;
950 * siba_sprom_get_rxpo2g()
953 * bwn_phy_lp_readsprom()
956 bhnd_compat_sprom_get_rxpo2g(device_t dev)
958 /* Should be signed, but bwn(4) expects an unsigned value */
959 BWN_BHND_NVRAM_RETURN_VAR(dev, int8, BHND_NVAR_RXPO2G);
963 * siba_sprom_get_rxpo5g()
966 * bwn_phy_lp_readsprom()
969 bhnd_compat_sprom_get_rxpo5g(device_t dev)
971 /* Should be signed, but bwn(4) expects an unsigned value */
972 BWN_BHND_NVRAM_RETURN_VAR(dev, int8, BHND_NVAR_RXPO5G);
976 * siba_sprom_get_tssi_bg()
982 bhnd_compat_sprom_get_tssi_bg(device_t dev)
984 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_PA0ITSSIT);
988 * siba_sprom_get_tri2g()
991 * bwn_phy_lp_readsprom()
994 bhnd_compat_sprom_get_tri2g(device_t dev)
996 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TRI2G);
1000 * siba_sprom_get_tri5gl()
1003 * bwn_phy_lp_readsprom()
1006 bhnd_compat_sprom_get_tri5gl(device_t dev)
1008 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TRI5GL);
1012 * siba_sprom_get_tri5g()
1015 * bwn_phy_lp_readsprom()
1018 bhnd_compat_sprom_get_tri5g(device_t dev)
1020 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TRI5G);
1024 * siba_sprom_get_tri5gh()
1027 * bwn_phy_lp_readsprom()
1030 bhnd_compat_sprom_get_tri5gh(device_t dev)
1032 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TRI5GH);
1036 * siba_sprom_get_rssisav2g()
1039 * bwn_phy_lp_readsprom()
1042 bhnd_compat_sprom_get_rssisav2g(device_t dev)
1044 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_RSSISAV2G);
1048 * siba_sprom_get_rssismc2g()
1051 * bwn_phy_lp_readsprom()
1054 bhnd_compat_sprom_get_rssismc2g(device_t dev)
1056 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_RSSISMC2G);
1060 * siba_sprom_get_rssismf2g()
1063 * bwn_phy_lp_readsprom()
1066 bhnd_compat_sprom_get_rssismf2g(device_t dev)
1068 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_RSSISMF2G);
1072 * siba_sprom_get_bxa2g()
1075 * bwn_phy_lp_readsprom()
1078 bhnd_compat_sprom_get_bxa2g(device_t dev)
1080 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_BXA2G);
1084 * siba_sprom_get_rssisav5g()
1087 * bwn_phy_lp_readsprom()
1090 bhnd_compat_sprom_get_rssisav5g(device_t dev)
1092 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_RSSISAV5G);
1096 * siba_sprom_get_rssismc5g()
1099 * bwn_phy_lp_readsprom()
1102 bhnd_compat_sprom_get_rssismc5g(device_t dev)
1104 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_RSSISMC5G);
1108 * siba_sprom_get_rssismf5g()
1111 * bwn_phy_lp_readsprom()
1114 bhnd_compat_sprom_get_rssismf5g(device_t dev)
1116 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_RSSISMF5G);
1120 * siba_sprom_get_bxa5g()
1123 * bwn_phy_lp_readsprom()
1126 bhnd_compat_sprom_get_bxa5g(device_t dev)
1128 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_BXA5G);
1132 * siba_sprom_get_cck2gpo()
1135 * bwn_ppr_load_max_from_sprom()
1138 bhnd_compat_sprom_get_cck2gpo(device_t dev)
1140 BWN_BHND_NVRAM_RETURN_VAR(dev, uint16, BHND_NVAR_CCK2GPO);
1144 * siba_sprom_get_ofdm2gpo()
1147 * bwn_ppr_load_max_from_sprom()
1150 bhnd_compat_sprom_get_ofdm2gpo(device_t dev)
1152 BWN_BHND_NVRAM_RETURN_VAR(dev, uint32, BHND_NVAR_OFDM2GPO);
1156 * siba_sprom_get_ofdm5glpo()
1159 * bwn_ppr_load_max_from_sprom()
1162 bhnd_compat_sprom_get_ofdm5glpo(device_t dev)
1164 BWN_BHND_NVRAM_RETURN_VAR(dev, uint32, BHND_NVAR_OFDM5GLPO);
1168 * siba_sprom_get_ofdm5gpo()
1171 * bwn_ppr_load_max_from_sprom()
1174 bhnd_compat_sprom_get_ofdm5gpo(device_t dev)
1176 BWN_BHND_NVRAM_RETURN_VAR(dev, uint32, BHND_NVAR_OFDM5GPO);
1180 * siba_sprom_get_ofdm5ghpo()
1183 * bwn_ppr_load_max_from_sprom()
1186 bhnd_compat_sprom_get_ofdm5ghpo(device_t dev)
1188 BWN_BHND_NVRAM_RETURN_VAR(dev, uint32, BHND_NVAR_OFDM5GHPO);
1192 * siba_sprom_set_bf_lo()
1195 * bwn_sprom_bugfixes()
1198 bhnd_compat_sprom_set_bf_lo(device_t dev, uint16_t t)
1200 struct bwn_bhnd_ctx *ctx = bwn_bhnd_get_ctx(dev);
1201 ctx->boardflags &= ~0xFFFF;
1202 ctx->boardflags |= t;
1206 * siba_sprom_get_bf_lo()
1212 * bwn_loopback_calcgain()
1213 * bwn_phy_g_init_sub()
1214 * bwn_phy_g_recalc_txpwr()
1215 * bwn_phy_g_set_txpwr()
1216 * bwn_phy_g_task_60s()
1217 * bwn_rx_rssi_calc()
1218 * bwn_sprom_bugfixes()
1223 bhnd_compat_sprom_get_bf_lo(device_t dev)
1225 struct bwn_bhnd_ctx *ctx = bwn_bhnd_get_ctx(dev);
1226 return (ctx->boardflags & UINT16_MAX);
1230 * siba_sprom_get_bf_hi()
1233 * bwn_nphy_gain_ctl_workarounds_rev3()
1234 * bwn_phy_lp_bbinit_r01()
1235 * bwn_phy_lp_tblinit_txgain()
1238 bhnd_compat_sprom_get_bf_hi(device_t dev)
1240 struct bwn_bhnd_ctx *ctx = bwn_bhnd_get_ctx(dev);
1241 return (ctx->boardflags >> 16);
1245 * siba_sprom_get_bf2_lo()
1248 * bwn_nphy_op_prepare_structs()
1249 * bwn_nphy_workarounds_rev1_2()
1250 * bwn_nphy_workarounds_rev3plus()
1252 * bwn_radio_2056_setup()
1253 * bwn_radio_init2055_post()
1256 bhnd_compat_sprom_get_bf2_lo(device_t dev)
1260 BWN_BHND_NVRAM_FETCH_VAR(dev, uint32, BHND_NVAR_BOARDFLAGS2, &bf2);
1261 return (bf2 & UINT16_MAX);
1265 * siba_sprom_get_bf2_hi()
1268 * bwn_nphy_workarounds_rev7plus()
1270 * bwn_radio_2056_setup()
1273 bhnd_compat_sprom_get_bf2_hi(device_t dev)
1277 BWN_BHND_NVRAM_FETCH_VAR(dev, uint32, BHND_NVAR_BOARDFLAGS2, &bf2);
1282 * siba_sprom_get_fem_2ghz_tssipos()
1285 * bwn_nphy_tx_power_ctl_setup()
1288 bhnd_compat_sprom_get_fem_2ghz_tssipos(device_t dev)
1290 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TSSIPOS2G);
1294 * siba_sprom_get_fem_2ghz_extpa_gain()
1297 * bwn_nphy_op_prepare_structs()
1300 bhnd_compat_sprom_get_fem_2ghz_extpa_gain(device_t dev)
1302 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_EXTPAGAIN2G);
1306 * siba_sprom_get_fem_2ghz_pdet_range()
1309 * bwn_nphy_workarounds_rev3plus()
1312 bhnd_compat_sprom_get_fem_2ghz_pdet_range(device_t dev)
1314 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_PDETRANGE2G);
1318 * siba_sprom_get_fem_2ghz_tr_iso()
1321 * bwn_nphy_get_gain_ctl_workaround_ent()
1324 bhnd_compat_sprom_get_fem_2ghz_tr_iso(device_t dev)
1326 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TRISO2G);
1330 * siba_sprom_get_fem_2ghz_antswlut()
1333 * bwn_nphy_tables_init_rev3()
1334 * bwn_nphy_tables_init_rev7_volatile()
1337 bhnd_compat_sprom_get_fem_2ghz_antswlut(device_t dev)
1339 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_ANTSWCTL2G);
1343 * siba_sprom_get_fem_5ghz_extpa_gain()
1346 * bwn_nphy_get_tx_gain_table()
1347 * bwn_nphy_op_prepare_structs()
1350 bhnd_compat_sprom_get_fem_5ghz_extpa_gain(device_t dev)
1352 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_EXTPAGAIN5G);
1356 * siba_sprom_get_fem_5ghz_pdet_range()
1359 * bwn_nphy_workarounds_rev3plus()
1362 bhnd_compat_sprom_get_fem_5ghz_pdet_range(device_t dev)
1364 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_PDETRANGE5G);
1368 * siba_sprom_get_fem_5ghz_antswlut()
1371 * bwn_nphy_tables_init_rev3()
1372 * bwn_nphy_tables_init_rev7_volatile()
1375 bhnd_compat_sprom_get_fem_5ghz_antswlut(device_t dev)
1377 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_ANTSWCTL5G);
1381 * siba_sprom_get_txpid_2g_0()
1384 * bwn_nphy_tx_power_fix()
1387 bhnd_compat_sprom_get_txpid_2g_0(device_t dev)
1389 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID2GA0);
1393 * siba_sprom_get_txpid_2g_1()
1396 * bwn_nphy_tx_power_fix()
1399 bhnd_compat_sprom_get_txpid_2g_1(device_t dev)
1401 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID2GA1);
1405 * siba_sprom_get_txpid_5gl_0()
1408 * bwn_nphy_tx_power_fix()
1411 bhnd_compat_sprom_get_txpid_5gl_0(device_t dev)
1413 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID5GLA0);
1417 * siba_sprom_get_txpid_5gl_1()
1420 * bwn_nphy_tx_power_fix()
1423 bhnd_compat_sprom_get_txpid_5gl_1(device_t dev)
1425 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID5GLA1);
1429 * siba_sprom_get_txpid_5g_0()
1432 * bwn_nphy_tx_power_fix()
1435 bhnd_compat_sprom_get_txpid_5g_0(device_t dev)
1437 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID5GA0);
1441 * siba_sprom_get_txpid_5g_1()
1444 * bwn_nphy_tx_power_fix()
1447 bhnd_compat_sprom_get_txpid_5g_1(device_t dev)
1449 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID5GA1);
1453 * siba_sprom_get_txpid_5gh_0()
1456 * bwn_nphy_tx_power_fix()
1459 bhnd_compat_sprom_get_txpid_5gh_0(device_t dev)
1461 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID5GHA0);
1465 * siba_sprom_get_txpid_5gh_1()
1468 * bwn_nphy_tx_power_fix()
1471 bhnd_compat_sprom_get_txpid_5gh_1(device_t dev)
1473 BWN_BHND_NVRAM_RETURN_VAR(dev, uint8, BHND_NVAR_TXPID5GHA1);
1477 * siba_sprom_get_stbcpo()
1480 * bwn_ppr_load_max_from_sprom()
1483 bhnd_compat_sprom_get_stbcpo(device_t dev)
1485 BWN_BHND_NVRAM_RETURN_VAR(dev, uint16, BHND_NVAR_STBCPO);
1489 * siba_sprom_get_cddpo()
1492 * bwn_ppr_load_max_from_sprom()
1495 bhnd_compat_sprom_get_cddpo(device_t dev)
1497 BWN_BHND_NVRAM_RETURN_VAR(dev, uint16, BHND_NVAR_CDDPO);
1508 bhnd_compat_powerup(device_t dev, int dynamic)
1510 struct bwn_bhnd_ctx *ctx;
1514 ctx = bwn_bhnd_get_ctx(dev);
1516 /* On PMU equipped devices, we do not need to issue a clock request
1518 if (ctx->pmu_dev != NULL)
1521 /* Issue a PMU clock request */
1523 clock = BHND_CLOCK_DYN;
1525 clock = BHND_CLOCK_HT;
1527 if ((error = bhnd_request_clock(dev, clock))) {
1528 device_printf(dev, "%d clock request failed: %d\n",
1543 bhnd_compat_powerdown(device_t dev)
1547 /* Suspend the core */
1548 if ((error = bhnd_suspend_hw(dev, 0)))
1560 * bwn_dummy_transmission()
1567 * bwn_wme_loadparams()
1572 bhnd_compat_read_2(device_t dev, uint16_t offset)
1574 struct bwn_softc *sc = device_get_softc(dev);
1576 BWN_ASSERT_VALID_REG(dev, offset);
1578 return (bhnd_bus_read_2(sc->sc_mem_res, offset));
1590 * bwn_pio_tx_start()
1599 bhnd_compat_write_2(device_t dev, uint16_t offset, uint16_t value)
1601 struct bwn_softc *sc = device_get_softc(dev);
1603 BWN_ASSERT_VALID_REG(dev, offset);
1605 return (bhnd_bus_write_2(sc->sc_mem_res, offset, value));
1619 * bwn_pio_tx_start()
1626 bhnd_compat_read_4(device_t dev, uint16_t offset)
1628 struct bwn_softc *sc = device_get_softc(dev);
1632 /* bwn(4) fetches IOCTL/IOST values directly from siba-specific target
1633 * state registers; we map these directly to bhnd_read_(ioctl|iost) */
1635 case SB0_REG_ABS(SIBA_CFG0_TMSTATELOW):
1636 if ((error = bhnd_read_ioctl(dev, &ioreg)))
1637 panic("error reading IOCTL: %d\n", error);
1639 return (((uint32_t)ioreg) << SIBA_TML_SICF_SHIFT);
1641 case SB0_REG_ABS(SIBA_CFG0_TMSTATEHIGH):
1642 if ((error = bhnd_read_iost(dev, &ioreg)))
1643 panic("error reading IOST: %d\n", error);
1645 return (((uint32_t)ioreg) << SIBA_TMH_SISF_SHIFT);
1648 /* Otherwise, perform a standard bus read */
1649 BWN_ASSERT_VALID_REG(dev, offset);
1650 return (bhnd_bus_read_4(sc->sc_mem_res, offset));
1662 * bwn_dma_rxdirectfifo()
1671 bhnd_compat_write_4(device_t dev, uint16_t offset, uint32_t value)
1673 struct bwn_softc *sc = device_get_softc(dev);
1677 /* bwn(4) writes IOCTL values directly to siba-specific target state
1678 * registers; we map these directly to bhnd_write_ioctl() */
1679 if (offset == SB0_REG_ABS(SIBA_CFG0_TMSTATELOW)) {
1680 /* shift IOCTL flags back down to their original values */
1681 if (value & ~SIBA_TML_SICF_MASK)
1682 panic("%s: non-IOCTL flags provided", __FUNCTION__);
1684 ioctl = (value & SIBA_TML_SICF_MASK) >> SIBA_TML_SICF_SHIFT;
1686 if ((error = bhnd_write_ioctl(dev, ioctl, UINT16_MAX)))
1687 panic("error writing IOCTL: %d\n", error);
1689 /* Otherwise, perform a standard bus write */
1690 BWN_ASSERT_VALID_REG(dev, offset);
1692 bhnd_bus_write_4(sc->sc_mem_res, offset, value);
1705 bhnd_compat_dev_up(device_t dev, uint32_t flags)
1710 /* shift IOCTL flags back down to their original values */
1711 if (flags & ~SIBA_TML_SICF_MASK)
1712 panic("%s: non-IOCTL flags provided", __FUNCTION__);
1714 ioctl = (flags & SIBA_TML_SICF_MASK) >> SIBA_TML_SICF_SHIFT;
1716 /* Perform core reset; note that bwn(4) incorrectly assumes that both
1717 * RESET and post-RESET ioctl flags should be identical */
1718 if ((error = bhnd_reset_hw(dev, ioctl, ioctl)))
1719 panic("%s: core reset failed: %d", __FUNCTION__, error);
1730 bhnd_compat_dev_down(device_t dev, uint32_t flags)
1735 /* shift IOCTL flags back down to their original values */
1736 if (flags & ~SIBA_TML_SICF_MASK)
1737 panic("%s: non-IOCTL flags provided", __FUNCTION__);
1739 ioctl = (flags & SIBA_TML_SICF_MASK) >> SIBA_TML_SICF_SHIFT;
1741 /* Put core into RESET state */
1742 if ((error = bhnd_suspend_hw(dev, ioctl)))
1743 panic("%s: core suspend failed: %d", __FUNCTION__, error);
1753 bhnd_compat_dev_isup(device_t dev)
1755 return (!bhnd_is_hw_suspended(dev));
1759 * siba_pcicore_intr()
1765 bhnd_compat_pcicore_intr(device_t dev)
1767 /* This is handled by bhnd_bhndb on the first call to
1768 * bus_setup_intr() */
1772 * siba_dma_translation()
1775 * bwn_dma_32_setdesc()
1776 * bwn_dma_64_setdesc()
1780 bhnd_compat_dma_translation(device_t dev)
1782 struct bhnd_dma_translation dt;
1783 struct bwn_softc *sc;
1784 struct bwn_mac *mac;
1788 sc = device_get_softc(dev);
1789 mac = sc->sc_curmac;
1790 KASSERT(mac != NULL, ("no MAC"));
1793 * Use the DMA engine's maximum host address width to determine the
1794 * supported device address width.
1796 switch (mac->mac_method.dma.dmatype) {
1799 /* The 32-bit engine is always capable of addressing
1800 * a full 32-bit device address */
1801 width = BHND_DMA_ADDR_32BIT;
1805 width = BHND_DMA_ADDR_64BIT;
1809 panic("unknown dma type %d",
1810 mac->mac_method.dma.dmatype);
1814 /* Fetch our DMA translation */
1815 if ((error = bhnd_get_dma_translation(dev, width, 0, NULL, &dt)))
1816 panic("error requesting DMA translation: %d\n", error);
1819 * TODO: bwn(4) needs to switch to bhnd_get_dma_translation().
1821 * Currently, bwn(4) incorrectly assumes that:
1822 * - The 32-bit translation mask is always SIBA_DMA_TRANSLATION_MASK.
1823 * - The 32-bit mask can simply be applied to the top 32-bits of a
1824 * 64-bit DMA address.
1825 * - The 64-bit address translation is always derived by shifting the
1826 * 32-bit siba_dma_translation() left by 1 bit.
1828 * In practice, these assumptions won't result in any bugs on known
1829 * PCI/PCIe Wi-Fi hardware:
1830 * - The 32-bit mask _is_ always SIBA_DMA_TRANSLATION_MASK on
1831 * the subset of devices supported by bwn(4).
1832 * - The 64-bit mask used by bwn(4) is a superset of the real
1834 * - Our DMA tag will still have valid constraints.
1835 * - Our address translation will not be corrupted by
1836 * applying the mask.
1837 * - The mask falls within the top 16 address bits, and our
1838 * supported 64-bit architectures are all still limited
1839 * to 48-bit addresses anyway; we don't need to worry about
1840 * addressing >= 48-bit host memory.
1842 * However, we will need to resolve these issues in bwn(4) if DMA is to
1843 * work on new hardware (e.g. WiSoCs).
1846 case BHND_DMA_ADDR_32BIT:
1847 KASSERT((~dt.addr_mask & BHND_DMA_ADDR_BITMASK(32)) ==
1848 SIBA_DMA_TRANSLATION_MASK, ("unexpected DMA mask: %#jx",
1849 (uintmax_t)dt.addr_mask));
1851 return (dt.base_addr);
1853 case BHND_DMA_ADDR_64BIT:
1854 /* bwn(4) will shift this left by 32+1 bits before applying it
1855 * to the top 32-bits of the DMA address */
1856 KASSERT((~dt.addr_mask & BHND_DMA_ADDR_BITMASK(33)) == 0,
1857 ("DMA64 translation %#jx masks low 33-bits",
1858 (uintmax_t)dt.addr_mask));
1860 return (dt.base_addr >> 33);
1863 panic("unsupported address width: %u", width);
1868 * siba_read_multi_2()
1874 bhnd_compat_read_multi_2(device_t dev, void *buffer, size_t count,
1877 struct bwn_softc *sc = device_get_softc(dev);
1879 BWN_ASSERT_VALID_REG(dev, offset);
1880 return (bhnd_bus_read_multi_2(sc->sc_mem_res, offset, buffer, count));
1884 * siba_read_multi_4()
1890 bhnd_compat_read_multi_4(device_t dev, void *buffer, size_t count,
1893 struct bwn_softc *sc = device_get_softc(dev);
1895 BWN_ASSERT_VALID_REG(dev, offset);
1896 return (bhnd_bus_read_multi_4(sc->sc_mem_res, offset, buffer, count));
1900 * siba_write_multi_2()
1903 * bwn_pio_write_multi_2()
1906 bhnd_compat_write_multi_2(device_t dev, const void *buffer, size_t count,
1909 struct bwn_softc *sc = device_get_softc(dev);
1911 BWN_ASSERT_VALID_REG(dev, offset);
1913 /* XXX discarding const to maintain API compatibility with
1914 * siba_write_multi_2() */
1915 bhnd_bus_write_multi_2(sc->sc_mem_res, offset,
1916 __DECONST(void *, buffer), count);
1920 * siba_write_multi_4()
1923 * bwn_pio_write_multi_4()
1926 bhnd_compat_write_multi_4(device_t dev, const void *buffer, size_t count,
1929 struct bwn_softc *sc = device_get_softc(dev);
1931 BWN_ASSERT_VALID_REG(dev, offset);
1933 /* XXX discarding const to maintain API compatibility with
1934 * siba_write_multi_4() */
1935 bhnd_bus_write_multi_4(sc->sc_mem_res, offset,
1936 __DECONST(void *, buffer), count);
1948 bhnd_compat_barrier(device_t dev, int flags)
1950 struct bwn_softc *sc = device_get_softc(dev);
1952 /* XXX is siba_barrier()'s use of an offset and length of 0
1954 BWN_ASSERT_VALID_REG(dev, 0);
1955 bhnd_bus_barrier(sc->sc_mem_res, 0, 0, flags);
1959 * siba_cc_pmu_set_ldovolt()
1962 * bwn_phy_lp_bbinit_r01()
1965 bhnd_compat_cc_pmu_set_ldovolt(device_t dev, int id, uint32_t volt)
1967 struct bwn_bhnd_ctx *ctx;
1970 ctx = bwn_bhnd_get_ctx(dev);
1972 /* Only ever used to set the PAREF LDO voltage */
1973 if (id != SIBA_LDO_PAREF)
1974 panic("invalid LDO id: %d", id);
1976 /* Configuring regulator voltage requires a PMU */
1977 if (ctx->pmu_dev == NULL)
1978 panic("no PMU; cannot set LDO voltage");
1980 error = bhnd_pmu_set_voltage_raw(ctx->pmu_dev, BHND_REGULATOR_PAREF_LDO,
1983 panic("failed to set LDO voltage: %d", error);
1987 * siba_cc_pmu_set_ldoparef()
1990 * bwn_phy_lp_bbinit_r01()
1993 bhnd_compat_cc_pmu_set_ldoparef(device_t dev, uint8_t on)
1995 struct bwn_bhnd_ctx *ctx;
1998 ctx = bwn_bhnd_get_ctx(dev);
2000 /* Enabling/disabling regulators requires a PMU */
2001 if (ctx->pmu_dev == NULL)
2002 panic("no PMU; cannot set LDO voltage");
2005 error = bhnd_pmu_enable_regulator(ctx->pmu_dev,
2006 BHND_REGULATOR_PAREF_LDO);
2008 error = bhnd_pmu_disable_regulator(ctx->pmu_dev,
2009 BHND_REGULATOR_PAREF_LDO);
2013 panic("failed to %s PAREF_LDO: %d", on ? "enable" : "disable",
2025 * bwn_nphy_superswitch_init()
2028 bhnd_compat_gpio_set(device_t dev, uint32_t value)
2030 struct bwn_bhnd_ctx *ctx;
2034 ctx = bwn_bhnd_get_ctx(dev);
2036 for (size_t i = 0; i < nitems(flags); i++) {
2037 if (value & (1 << i)) {
2039 flags[i] = (GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE);
2041 /* Leave unmodified */
2046 error = GPIO_PIN_CONFIG_32(ctx->gpio_dev, 0, nitems(flags), flags);
2048 panic("error configuring pin flags: %d", error);
2058 bhnd_compat_gpio_get(device_t dev)
2060 struct bwn_bhnd_ctx *ctx;
2066 * We recreate the expected GPIOCTRL register value for bwn_gpio_init()
2067 * by querying pins individually for GPIO_PIN_TRISTATE.
2069 * Once we drop these compatibility shims, the GPIO_PIN_CONFIG_32 method
2070 * can be used to set pin configuration without bwn(4) externally
2074 /* Fetch the total pin count */
2075 ctx = bwn_bhnd_get_ctx(dev);
2076 if ((error = GPIO_PIN_MAX(ctx->gpio_dev, &npin)))
2077 panic("failed to fetch max pin: %d", error);
2079 /* Must be representable within a 32-bit GPIOCTRL register value */
2080 KASSERT(npin <= 32, ("unsupported pin count: %u", npin));
2083 for (uint32_t pin = 0; pin < npin; pin++) {
2086 if ((error = GPIO_PIN_GETFLAGS(ctx->gpio_dev, pin, &flags)))
2087 panic("error fetching pin%u flags: %d", pin, error);
2089 if (flags & GPIO_PIN_TRISTATE)
2097 * siba_fix_imcfglobug()
2103 bhnd_compat_fix_imcfglobug(device_t dev)
2105 /* This is handled by siba_bhndb during attach/resume */
2109 /* Core power NVRAM variables, indexed by D11 core unit number */
2110 static const struct bwn_power_vars {
2113 const char *maxp2ga;
2116 } bwn_power_vars[BWN_BHND_NUM_CORE_PWR] = {
2117 #define BHND_POWER_NVAR(_idx) \
2118 { BHND_NVAR_ITT2GA ## _idx, BHND_NVAR_ITT5GA ## _idx, \
2119 BHND_NVAR_MAXP2GA ## _idx, BHND_NVAR_PA2GA ## _idx, \
2120 BHND_NVAR_PA5GA ## _idx }
2125 #undef BHND_POWER_NVAR
2129 bwn_get_core_power_info_r11(device_t dev, const struct bwn_power_vars *v,
2130 struct siba_sprom_core_pwr_info *c)
2135 /* BHND_NVAR_PA2GA[core] */
2136 error = bhnd_nvram_getvar_array(dev, v->pa2ga, c->pa_2g,
2137 sizeof(c->pa_2g), BHND_NVRAM_TYPE_INT16);
2144 * The NVRAM variable is defined as a single pa5ga[12] array; we have
2145 * to split this into pa_5gl[4], pa_5g[4], and pa_5gh[4] for use
2148 _Static_assert(nitems(pa5ga) == nitems(c->pa_5g) + nitems(c->pa_5gh) +
2149 nitems(c->pa_5gl), "cannot split pa5ga into pa_5gl/pa_5g/pa_5gh");
2151 error = bhnd_nvram_getvar_array(dev, v->pa5ga, pa5ga, sizeof(pa5ga),
2152 BHND_NVRAM_TYPE_INT16);
2156 memcpy(c->pa_5gl, &pa5ga[0], sizeof(c->pa_5gl));
2157 memcpy(c->pa_5g, &pa5ga[4], sizeof(c->pa_5g));
2158 memcpy(c->pa_5gh, &pa5ga[8], sizeof(c->pa_5gh));
2163 bwn_get_core_power_info_r4_r10(device_t dev,
2164 const struct bwn_power_vars *v, struct siba_sprom_core_pwr_info *c)
2168 /* BHND_NVAR_ITT2GA[core] */
2169 if ((error = bhnd_nvram_getvar_uint8(dev, v->itt2ga, &c->itssi_2g)))
2172 /* BHND_NVAR_ITT5GA[core] */
2173 if ((error = bhnd_nvram_getvar_uint8(dev, v->itt5ga, &c->itssi_5g)))
2180 * siba_sprom_get_core_power_info()
2183 * bwn_nphy_tx_power_ctl_setup()
2184 * bwn_ppr_load_max_from_sprom()
2187 bhnd_compat_sprom_get_core_power_info(device_t dev, int core,
2188 struct siba_sprom_core_pwr_info *c)
2190 struct bwn_bhnd_ctx *ctx;
2191 const struct bwn_power_vars *v;
2194 if (core < 0 || core >= nitems(bwn_power_vars))
2197 ctx = bwn_bhnd_get_ctx(dev);
2198 if (ctx->sromrev < 4)
2201 v = &bwn_power_vars[core];
2203 /* Any power variables not found in NVRAM (or returning a
2204 * shorter array for a particular NVRAM revision) should be zero
2206 memset(c, 0x0, sizeof(*c));
2208 /* Populate SPROM revision-independent values */
2209 if ((error = bhnd_nvram_getvar_uint8(dev, v->maxp2ga, &c->maxpwr_2g)))
2212 /* Populate SPROM revision-specific values */
2213 if (ctx->sromrev >= 4 && ctx->sromrev <= 10)
2214 return (bwn_get_core_power_info_r4_r10(dev, v, c));
2216 return (bwn_get_core_power_info_r11(dev, v, c));
2220 * siba_sprom_get_mcs2gpo()
2223 * bwn_ppr_load_max_from_sprom()
2226 bhnd_compat_sprom_get_mcs2gpo(device_t dev, uint16_t *c)
2228 static const char *varnames[] = {
2239 for (size_t i = 0; i < nitems(varnames); i++) {
2240 const char *name = varnames[i];
2241 BWN_BHND_NVRAM_FETCH_VAR(dev, uint16, name, &c[i]);
2248 * siba_sprom_get_mcs5glpo()
2251 * bwn_ppr_load_max_from_sprom()
2254 bhnd_compat_sprom_get_mcs5glpo(device_t dev, uint16_t *c)
2256 static const char *varnames[] = {
2257 BHND_NVAR_MCS5GLPO0,
2258 BHND_NVAR_MCS5GLPO1,
2259 BHND_NVAR_MCS5GLPO2,
2260 BHND_NVAR_MCS5GLPO3,
2261 BHND_NVAR_MCS5GLPO4,
2262 BHND_NVAR_MCS5GLPO5,
2263 BHND_NVAR_MCS5GLPO6,
2267 for (size_t i = 0; i < nitems(varnames); i++) {
2268 const char *name = varnames[i];
2269 BWN_BHND_NVRAM_FETCH_VAR(dev, uint16, name, &c[i]);
2276 * siba_sprom_get_mcs5gpo()
2279 * bwn_ppr_load_max_from_sprom()
2282 bhnd_compat_sprom_get_mcs5gpo(device_t dev, uint16_t *c)
2284 static const char *varnames[] = {
2295 for (size_t i = 0; i < nitems(varnames); i++) {
2296 const char *name = varnames[i];
2297 BWN_BHND_NVRAM_FETCH_VAR(dev, uint16, name, &c[i]);
2304 * siba_sprom_get_mcs5ghpo()
2307 * bwn_ppr_load_max_from_sprom()
2310 bhnd_compat_sprom_get_mcs5ghpo(device_t dev, uint16_t *c)
2312 static const char *varnames[] = {
2313 BHND_NVAR_MCS5GHPO0,
2314 BHND_NVAR_MCS5GHPO1,
2315 BHND_NVAR_MCS5GHPO2,
2316 BHND_NVAR_MCS5GHPO3,
2317 BHND_NVAR_MCS5GHPO4,
2318 BHND_NVAR_MCS5GHPO5,
2319 BHND_NVAR_MCS5GHPO6,
2323 for (size_t i = 0; i < nitems(varnames); i++) {
2324 const char *name = varnames[i];
2325 BWN_BHND_NVRAM_FETCH_VAR(dev, uint16, name, &c[i]);
2332 * siba_pmu_spuravoid_pllupdate()
2335 * bwn_nphy_pmu_spur_avoid()
2338 bhnd_compat_pmu_spuravoid_pllupdate(device_t dev, int spur_avoid)
2340 struct bwn_bhnd_ctx *ctx;
2341 bhnd_pmu_spuravoid mode;
2344 ctx = bwn_bhnd_get_ctx(dev);
2346 if (ctx->pmu_dev == NULL)
2347 panic("requested spuravoid on non-PMU device");
2349 switch (spur_avoid) {
2351 mode = BHND_PMU_SPURAVOID_NONE;
2354 mode = BHND_PMU_SPURAVOID_M1;
2357 panic("unknown spur_avoid: %d", spur_avoid);
2360 if ((error = bhnd_pmu_request_spuravoid(ctx->pmu_dev, mode)))
2361 panic("spuravoid request failed: %d", error);
2369 * bwn_wireless_core_phy_pll_reset()
2372 bhnd_compat_cc_set32(device_t dev, uint32_t reg, uint32_t val)
2374 struct bwn_bhnd_ctx *ctx = bwn_bhnd_get_ctx(dev);
2377 * OR with the current value.
2379 * This function is only ever used to write to either ChipCommon's
2380 * chipctrl register or chipctl_data register. Note that chipctl_data
2381 * is actually a PMU register; it is not actually mapped by ChipCommon
2382 * on Always-on-Bus (AOB) devices with a standalone PMU core.
2384 if (dev != ctx->chipc_dev)
2385 panic("unsupported device: %s", device_get_nameunit(dev));
2388 case SIBA_CC_CHIPCTL:
2389 BHND_CHIPC_WRITE_CHIPCTRL(ctx->chipc_dev, val, val);
2391 case SIBA_CC_CHIPCTL_DATA:
2392 bhnd_pmu_write_chipctrl(ctx->pmu_dev, ctx->pmu_cctl_addr, val,
2396 panic("unsupported register: %#x", reg);
2404 * bwn_wireless_core_phy_pll_reset()
2407 bhnd_compat_cc_mask32(device_t dev, uint32_t reg, uint32_t mask)
2409 struct bwn_bhnd_ctx *ctx = bwn_bhnd_get_ctx(dev);
2412 * AND with the current value.
2414 * This function is only ever used to write to ChipCommon's chipctl_data
2415 * register. Note that chipctl_data is actually a PMU register; it is
2416 * not actually mapped by ChipCommon on Always-on-Bus (AOB) devices with
2417 * a standalone PMU core.
2419 if (dev != ctx->chipc_dev)
2420 panic("unsupported device: %s", device_get_nameunit(dev));
2423 case SIBA_CC_CHIPCTL_DATA:
2424 bhnd_pmu_write_chipctrl(ctx->pmu_dev, ctx->pmu_cctl_addr, 0,
2428 panic("unsupported register: %#x", reg);
2436 * bwn_wireless_core_phy_pll_reset()
2439 bhnd_compat_cc_write32(device_t dev, uint32_t reg, uint32_t val)
2441 struct bwn_bhnd_ctx *ctx = bwn_bhnd_get_ctx(dev);
2444 * This function is only ever used to write to ChipCommon's chipctl_addr
2445 * register; setting chipctl_addr is handled atomically by
2446 * bhnd_pmu_write_chipctrl(), so we merely cache the intended address
2447 * for later use when chipctl_data is written.
2449 * Also, note that chipctl_addr is actually a PMU register; it is
2450 * not actually mapped by ChipCommon on Always-on-Bus (AOB) devices with
2451 * a standalone PMU core.
2453 if (dev != ctx->chipc_dev)
2454 panic("unsupported device: %s", device_get_nameunit(dev));
2457 case SIBA_CC_CHIPCTL_ADDR:
2458 ctx->pmu_cctl_addr = val;
2461 panic("unsupported register: %#x", reg);
2465 const struct bwn_bus_ops bwn_bhnd_bus_ops = {
2466 .init = bwn_bhnd_bus_ops_init,
2467 .fini = bwn_bhnd_bus_ops_fini,
2468 .pci_find_cap = bhnd_compat_pci_find_cap,
2469 .pci_alloc_msi = bhnd_compat_pci_alloc_msi,
2470 .pci_release_msi = bhnd_compat_pci_release_msi,
2471 .pci_msi_count = bhnd_compat_pci_msi_count,
2472 .get_vendor = bhnd_compat_get_vendor,
2473 .get_device = bhnd_compat_get_device,
2474 .get_revid = bhnd_compat_get_revid,
2475 .get_pci_vendor = bhnd_compat_get_pci_vendor,
2476 .get_pci_device = bhnd_compat_get_pci_device,
2477 .get_pci_subvendor = bhnd_compat_get_pci_subvendor,
2478 .get_pci_subdevice = bhnd_compat_get_pci_subdevice,
2479 .get_pci_revid = bhnd_compat_get_pci_revid,
2480 .get_chipid = bhnd_compat_get_chipid,
2481 .get_chiprev = bhnd_compat_get_chiprev,
2482 .get_chippkg = bhnd_compat_get_chippkg,
2483 .get_type = bhnd_compat_get_type,
2484 .get_cc_pmufreq = bhnd_compat_get_cc_pmufreq,
2485 .get_cc_caps = bhnd_compat_get_cc_caps,
2486 .get_cc_powerdelay = bhnd_compat_get_cc_powerdelay,
2487 .get_pcicore_revid = bhnd_compat_get_pcicore_revid,
2488 .sprom_get_rev = bhnd_compat_sprom_get_rev,
2489 .sprom_get_mac_80211bg = bhnd_compat_sprom_get_mac_80211bg,
2490 .sprom_get_mac_80211a = bhnd_compat_sprom_get_mac_80211a,
2491 .sprom_get_brev = bhnd_compat_sprom_get_brev,
2492 .sprom_get_ccode = bhnd_compat_sprom_get_ccode,
2493 .sprom_get_ant_a = bhnd_compat_sprom_get_ant_a,
2494 .sprom_get_ant_bg = bhnd_compat_sprom_get_ant_bg,
2495 .sprom_get_pa0b0 = bhnd_compat_sprom_get_pa0b0,
2496 .sprom_get_pa0b1 = bhnd_compat_sprom_get_pa0b1,
2497 .sprom_get_pa0b2 = bhnd_compat_sprom_get_pa0b2,
2498 .sprom_get_gpio0 = bhnd_compat_sprom_get_gpio0,
2499 .sprom_get_gpio1 = bhnd_compat_sprom_get_gpio1,
2500 .sprom_get_gpio2 = bhnd_compat_sprom_get_gpio2,
2501 .sprom_get_gpio3 = bhnd_compat_sprom_get_gpio3,
2502 .sprom_get_maxpwr_bg = bhnd_compat_sprom_get_maxpwr_bg,
2503 .sprom_set_maxpwr_bg = bhnd_compat_sprom_set_maxpwr_bg,
2504 .sprom_get_rxpo2g = bhnd_compat_sprom_get_rxpo2g,
2505 .sprom_get_rxpo5g = bhnd_compat_sprom_get_rxpo5g,
2506 .sprom_get_tssi_bg = bhnd_compat_sprom_get_tssi_bg,
2507 .sprom_get_tri2g = bhnd_compat_sprom_get_tri2g,
2508 .sprom_get_tri5gl = bhnd_compat_sprom_get_tri5gl,
2509 .sprom_get_tri5g = bhnd_compat_sprom_get_tri5g,
2510 .sprom_get_tri5gh = bhnd_compat_sprom_get_tri5gh,
2511 .sprom_get_rssisav2g = bhnd_compat_sprom_get_rssisav2g,
2512 .sprom_get_rssismc2g = bhnd_compat_sprom_get_rssismc2g,
2513 .sprom_get_rssismf2g = bhnd_compat_sprom_get_rssismf2g,
2514 .sprom_get_bxa2g = bhnd_compat_sprom_get_bxa2g,
2515 .sprom_get_rssisav5g = bhnd_compat_sprom_get_rssisav5g,
2516 .sprom_get_rssismc5g = bhnd_compat_sprom_get_rssismc5g,
2517 .sprom_get_rssismf5g = bhnd_compat_sprom_get_rssismf5g,
2518 .sprom_get_bxa5g = bhnd_compat_sprom_get_bxa5g,
2519 .sprom_get_cck2gpo = bhnd_compat_sprom_get_cck2gpo,
2520 .sprom_get_ofdm2gpo = bhnd_compat_sprom_get_ofdm2gpo,
2521 .sprom_get_ofdm5glpo = bhnd_compat_sprom_get_ofdm5glpo,
2522 .sprom_get_ofdm5gpo = bhnd_compat_sprom_get_ofdm5gpo,
2523 .sprom_get_ofdm5ghpo = bhnd_compat_sprom_get_ofdm5ghpo,
2524 .sprom_get_bf_lo = bhnd_compat_sprom_get_bf_lo,
2525 .sprom_set_bf_lo = bhnd_compat_sprom_set_bf_lo,
2526 .sprom_get_bf_hi = bhnd_compat_sprom_get_bf_hi,
2527 .sprom_get_bf2_lo = bhnd_compat_sprom_get_bf2_lo,
2528 .sprom_get_bf2_hi = bhnd_compat_sprom_get_bf2_hi,
2529 .sprom_get_fem_2ghz_tssipos = bhnd_compat_sprom_get_fem_2ghz_tssipos,
2530 .sprom_get_fem_2ghz_extpa_gain = bhnd_compat_sprom_get_fem_2ghz_extpa_gain,
2531 .sprom_get_fem_2ghz_pdet_range = bhnd_compat_sprom_get_fem_2ghz_pdet_range,
2532 .sprom_get_fem_2ghz_tr_iso = bhnd_compat_sprom_get_fem_2ghz_tr_iso,
2533 .sprom_get_fem_2ghz_antswlut = bhnd_compat_sprom_get_fem_2ghz_antswlut,
2534 .sprom_get_fem_5ghz_extpa_gain = bhnd_compat_sprom_get_fem_5ghz_extpa_gain,
2535 .sprom_get_fem_5ghz_pdet_range = bhnd_compat_sprom_get_fem_5ghz_pdet_range,
2536 .sprom_get_fem_5ghz_antswlut = bhnd_compat_sprom_get_fem_5ghz_antswlut,
2537 .sprom_get_txpid_2g_0 = bhnd_compat_sprom_get_txpid_2g_0,
2538 .sprom_get_txpid_2g_1 = bhnd_compat_sprom_get_txpid_2g_1,
2539 .sprom_get_txpid_5gl_0 = bhnd_compat_sprom_get_txpid_5gl_0,
2540 .sprom_get_txpid_5gl_1 = bhnd_compat_sprom_get_txpid_5gl_1,
2541 .sprom_get_txpid_5g_0 = bhnd_compat_sprom_get_txpid_5g_0,
2542 .sprom_get_txpid_5g_1 = bhnd_compat_sprom_get_txpid_5g_1,
2543 .sprom_get_txpid_5gh_0 = bhnd_compat_sprom_get_txpid_5gh_0,
2544 .sprom_get_txpid_5gh_1 = bhnd_compat_sprom_get_txpid_5gh_1,
2545 .sprom_get_stbcpo = bhnd_compat_sprom_get_stbcpo,
2546 .sprom_get_cddpo = bhnd_compat_sprom_get_cddpo,
2547 .powerup = bhnd_compat_powerup,
2548 .powerdown = bhnd_compat_powerdown,
2549 .read_2 = bhnd_compat_read_2,
2550 .write_2 = bhnd_compat_write_2,
2551 .read_4 = bhnd_compat_read_4,
2552 .write_4 = bhnd_compat_write_4,
2553 .dev_up = bhnd_compat_dev_up,
2554 .dev_down = bhnd_compat_dev_down,
2555 .dev_isup = bhnd_compat_dev_isup,
2556 .pcicore_intr = bhnd_compat_pcicore_intr,
2557 .dma_translation = bhnd_compat_dma_translation,
2558 .read_multi_2 = bhnd_compat_read_multi_2,
2559 .read_multi_4 = bhnd_compat_read_multi_4,
2560 .write_multi_2 = bhnd_compat_write_multi_2,
2561 .write_multi_4 = bhnd_compat_write_multi_4,
2562 .barrier = bhnd_compat_barrier,
2563 .cc_pmu_set_ldovolt = bhnd_compat_cc_pmu_set_ldovolt,
2564 .cc_pmu_set_ldoparef = bhnd_compat_cc_pmu_set_ldoparef,
2565 .gpio_set = bhnd_compat_gpio_set,
2566 .gpio_get = bhnd_compat_gpio_get,
2567 .fix_imcfglobug = bhnd_compat_fix_imcfglobug,
2568 .sprom_get_core_power_info = bhnd_compat_sprom_get_core_power_info,
2569 .sprom_get_mcs2gpo = bhnd_compat_sprom_get_mcs2gpo,
2570 .sprom_get_mcs5glpo = bhnd_compat_sprom_get_mcs5glpo,
2571 .sprom_get_mcs5gpo = bhnd_compat_sprom_get_mcs5gpo,
2572 .sprom_get_mcs5ghpo = bhnd_compat_sprom_get_mcs5ghpo,
2573 .pmu_spuravoid_pllupdate = bhnd_compat_pmu_spuravoid_pllupdate,
2574 .cc_set32 = bhnd_compat_cc_set32,
2575 .cc_mask32 = bhnd_compat_cc_mask32,
2576 .cc_write32 = bhnd_compat_cc_write32,