Date: Mon, 5 Feb 2018 23:38:15 +0000 (UTC) From: "Landon J. Fuller" <landonf@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r328912 - in head: share/man/man4 sys/conf sys/dev/bhnd sys/dev/bwn sys/dev/siba sys/gnu/dev/bwn/phy_n sys/modules sys/modules/bwn sys/modules/bwn_pci sys/modules/siba_bwn Message-ID: <201802052338.w15NcFfD053829@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: landonf Date: Mon Feb 5 23:38:15 2018 New Revision: 328912 URL: https://svnweb.freebsd.org/changeset/base/328912 Log: bwn(4): migrate bwn(4) to the native bhnd(9) interface, and drop siba_bwn. - Remove the shim interface that allowed bwn(4) to use either siba_bwn or bhnd(4), replacing all siba_bwn calls with their bhnd(4) bus equivalents. - Drop the legay, now-unused siba_bwn bus driver. - Clean up bhnd(4) board flag defines referenced by bwn(4). Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D13518 Added: head/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_sprom.c (contents, props changed) head/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_sprom.h (contents, props changed) Deleted: head/sys/dev/bwn/if_bwn_bhnd.c head/sys/dev/bwn/if_bwn_chipid.h head/sys/dev/bwn/if_bwn_siba.c head/sys/dev/bwn/if_bwn_siba.h head/sys/dev/bwn/if_bwn_siba_compat.c head/sys/dev/bwn/if_bwn_siba_compat.h head/sys/dev/siba/ head/sys/modules/bwn_pci/ head/sys/modules/siba_bwn/ Modified: head/share/man/man4/bwn.4 head/sys/conf/files head/sys/dev/bhnd/bhnd_ids.h head/sys/dev/bwn/if_bwn.c head/sys/dev/bwn/if_bwn_misc.h head/sys/dev/bwn/if_bwn_pci.c head/sys/dev/bwn/if_bwn_phy_common.c head/sys/dev/bwn/if_bwn_phy_common.h head/sys/dev/bwn/if_bwn_phy_g.c head/sys/dev/bwn/if_bwn_phy_lp.c head/sys/dev/bwn/if_bwn_phy_n.c head/sys/dev/bwn/if_bwn_util.c head/sys/dev/bwn/if_bwnreg.h head/sys/dev/bwn/if_bwnvar.h head/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.c head/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h head/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.c head/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.c head/sys/modules/Makefile head/sys/modules/bwn/Makefile Modified: head/share/man/man4/bwn.4 ============================================================================== --- head/share/man/man4/bwn.4 Mon Feb 5 23:35:33 2018 (r328911) +++ head/share/man/man4/bwn.4 Mon Feb 5 23:38:15 2018 (r328912) @@ -24,26 +24,29 @@ .\" .\" $FreeBSD$ .\" -.Dd June 11, 2015 +.Dd December 16, 2017 .Dt BWN 4 .Os .Sh NAME .Nm bwn -.Nd Broadcom BCM43xx IEEE 802.11b/g wireless network driver +.Nd Broadcom BCM43xx SoftMAC IEEE 802.11 wireless network driver .Sh SYNOPSIS -To compile this driver into the kernel, -place the following lines in your -kernel configuration file: +To compile this driver into the kernel, add the following lines to the kernel +configuration file: .Bd -ragged -offset indent -.Cd "device siba_bwn" .Cd "device bwn" +.Cd "device bhnd" +.Cd "device bhndb" +.Cd "device bhndb_pci" +.Cd "device bcma" +.Cd "device siba" +.Cd "device gpio" .Cd "device wlan" .Cd "device wlan_amrr" .Cd "device firmware" .Ed .Pp -Alternatively, to load the driver as a -module at boot time, place the following line in +To load the driver as a module at boot, add the following lines to .Xr loader.conf 5 : .Bd -literal -offset indent if_bwn_load="YES" @@ -122,9 +125,6 @@ Tunables can be set at the prompt before booting the kernel or stored in .Xr loader.conf 5 . .Bl -tag -width indent -.It Va hw.bwn.msi_disable -This tunable disables MSI support on the hardware. -The default value is 0. .It Va hw.bwn.usedma This tunable enables DMA operations on the hardware. If the value is 0, PIO mode would be used. @@ -132,10 +132,14 @@ The default value is 1. .El .Sh SEE ALSO .Xr arp 4 , +.Xr bcma 4 , +.Xr bhnd 4 , +.Xr bhndb 4 , .Xr bwi 4 , .Xr cardbus 4 , .Xr intro 4 , .Xr pci 4 , +.Xr siba 4 , .Xr wlan 4 , .Xr wlan_amrr 4 , .Xr ifconfig 8 , @@ -145,12 +149,20 @@ The .Nm driver first appeared in .Fx 8.1 . +The driver was updated to support the common Broadcom +.Xr bhnd 4 +bus interface in +.Fx 12.0 . .Sh AUTHORS .An -nosplit The .Nm driver was written by .An Weongyo Jeong Aq Mt weongyo@FreeBSD.org . +Support for +.Xr bhnd 4 +was added by +.An Landon Fuller Aq Mt landonf@FreeBSD.org . .\".Sh BUGS .\"Some card based on the BCM4306 and BCM4309 chips do not work properly .\"on channel 1, 2 and 3. Modified: head/sys/conf/files ============================================================================== --- head/sys/conf/files Mon Feb 5 23:35:33 2018 (r328911) +++ head/sys/conf/files Mon Feb 5 23:38:15 2018 (r328912) @@ -1250,9 +1250,9 @@ dev/bhnd/bhndb/bhndb.c optional bhndb bhnd dev/bhnd/bhndb/bhndb_bus_if.m optional bhndb bhnd dev/bhnd/bhndb/bhndb_hwdata.c optional bhndb bhnd dev/bhnd/bhndb/bhndb_if.m optional bhndb bhnd -dev/bhnd/bhndb/bhndb_pci.c optional bhndb bhnd pci -dev/bhnd/bhndb/bhndb_pci_hwdata.c optional bhndb bhnd pci -dev/bhnd/bhndb/bhndb_pci_sprom.c optional bhndb bhnd pci +dev/bhnd/bhndb/bhndb_pci.c optional bhndb_pci bhndb bhnd pci +dev/bhnd/bhndb/bhndb_pci_hwdata.c optional bhndb_pci bhndb bhnd pci +dev/bhnd/bhndb/bhndb_pci_sprom.c optional bhndb_pci bhndb bhnd pci dev/bhnd/bhndb/bhndb_subr.c optional bhndb bhnd dev/bhnd/bcma/bcma.c optional bcma bhnd dev/bhnd/bcma/bcma_bhndb.c optional bcma bhnd bhndb @@ -1327,19 +1327,16 @@ dev/bwi/bwirf.c optional bwi dev/bwi/if_bwi.c optional bwi dev/bwi/if_bwi_pci.c optional bwi pci # XXX Work around clang warnings, until maintainer approves fix. -dev/bwn/if_bwn.c optional bwn siba_bwn \ +dev/bwn/if_bwn.c optional bwn bhnd \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" -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 \ +dev/bwn/if_bwn_pci.c optional bwn pci bhnd bhndb bhndb_pci +dev/bwn/if_bwn_phy_common.c optional bwn bhnd +dev/bwn/if_bwn_phy_g.c optional bwn bhnd \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED} ${NO_WCONSTANT_CONVERSION}" -dev/bwn/if_bwn_phy_lp.c optional bwn siba_bwn \ +dev/bwn/if_bwn_phy_lp.c optional bwn bhnd \ 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/if_bwn_phy_n.c optional bwn bhnd +dev/bwn/if_bwn_util.c optional bwn bhnd dev/cardbus/cardbus.c optional cardbus dev/cardbus/cardbus_cis.c optional cardbus dev/cardbus/cardbus_device.c optional cardbus @@ -3020,8 +3017,6 @@ dev/sdhci/sdhci_acpi.c optional sdhci acpi dev/sdhci/sdhci_pci.c optional sdhci pci dev/sf/if_sf.c optional sf pci dev/sge/if_sge.c optional sge pci -dev/siba/siba_bwn.c optional siba_bwn pci -dev/siba/siba_core.c optional siba_bwn pci dev/siis/siis.c optional siis pci dev/sis/if_sis.c optional sis pci dev/sk/if_sk.c optional sk pci Modified: head/sys/dev/bhnd/bhnd_ids.h ============================================================================== --- head/sys/dev/bhnd/bhnd_ids.h Mon Feb 5 23:35:33 2018 (r328911) +++ head/sys/dev/bhnd/bhnd_ids.h Mon Feb 5 23:38:15 2018 (r328912) @@ -69,6 +69,7 @@ /* PCI vendor IDs */ +#define PCI_VENDOR_ASUSTEK 0x1043 #define PCI_VENDOR_EPIGRAM 0xfeda #define PCI_VENDOR_BROADCOM 0x14e4 #define PCI_VENDOR_3COM 0x10b7 @@ -78,6 +79,8 @@ #define PCI_VENDOR_DELL 0x1028 #define PCI_VENDOR_HP 0x103c #define PCI_VENDOR_HP_COMPAQ 0x0e11 +#define PCI_VENDOR_LINKSYS 0x1737 +#define PCI_VENDOR_MOTOROLA 0x1057 #define PCI_VENDOR_APPLE 0x106b #define PCI_VENDOR_SI_IMAGE 0x1095 /* Silicon Image, used by Arasan SDIO Host */ #define PCI_VENDOR_BUFFALO 0x1154 /* Buffalo vendor id */ @@ -581,10 +584,10 @@ #define BHND_BFL_LNLDO2_2P5 0x04000000 /* Select 2.5V as LNLDO2 output voltage */ #define BHND_BFL_FASTPWR 0x08000000 #define BHND_BFL_UCPWRCTL_MININDX 0x08000000 /* Enforce min power index to avoid FEM damage */ -#define BHND_BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */ -#define BHND_BFL_TRSW_1by2 0x20000000 /* Board has 2 TRSW's in 1by2 designs */ +#define BHND_BFL_EXTLNA_5GHZ 0x10000000 /* Board has an external LNA in 5GHz band */ +#define BHND_BFL_TRSW_1BY2 0x20000000 /* Board has 2 TRSW's in 1by2 designs */ #define BHND_BFL_GAINBOOSTA01 0x20000000 /* 5g Gainboost for core0 and core1 */ -#define BHND_BFL_LO_TRSW_R_5GHz 0x40000000 /* In 5G do not throw TRSW to T for clipLO gain */ +#define BHND_BFL_LO_TRSW_R_5GHZ 0x40000000 /* In 5G do not throw TRSW to T for clipLO gain */ #define BHND_BFL_ELNA_GAINDEF 0x80000000 /* Backoff InitGain based on elna_2g/5g field * when this flag is set */ @@ -644,7 +647,7 @@ #define BHND_BFL_SROM11_BTCOEX 0x00000001 /* Board supports BTCOEX */ #define BHND_BFL_SROM11_WLAN_BT_SH_XTL 0x00000002 /* bluetooth and wlan share same crystal */ #define BHND_BFL_SROM11_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */ -#define BHND_BFL_SROM11_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */ +#define BHND_BFL_SROM11_EXTLNA_5GHZ 0x10000000 /* Board has an external LNA in 5GHz band */ #define BHND_BFL_SROM11_GAINBOOSTA01 0x20000000 /* 5g Gainboost for core0 and core1 */ #define BHND_BFL2_SROM11_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */ #define BHND_BFL2_SROM11_ANAPACTRL_2G 0x00100000 /* 2G ext PAs are ctrl-ed by analog PA ctrl lines */ Modified: head/sys/dev/bwn/if_bwn.c ============================================================================== --- head/sys/dev/bwn/if_bwn.c Mon Feb 5 23:35:33 2018 (r328911) +++ head/sys/dev/bwn/if_bwn.c Mon Feb 5 23:38:15 2018 (r328912) @@ -2,7 +2,12 @@ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org> + * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org> + * 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 @@ -42,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/gpio.h> #include <sys/malloc.h> #include <sys/module.h> #include <sys/endian.h> @@ -65,17 +71,18 @@ __FBSDID("$FreeBSD$"); #include <net/if_media.h> #include <net/if_types.h> -#include <dev/pci/pcivar.h> -#include <dev/pci/pcireg.h> - #include <net80211/ieee80211_var.h> #include <net80211/ieee80211_radiotap.h> #include <net80211/ieee80211_regdomain.h> #include <net80211/ieee80211_phy.h> #include <net80211/ieee80211_ratectl.h> -#include <dev/bwn/if_bwn_siba.h> +#include <dev/bhnd/bhnd.h> +#include <dev/bhnd/bhnd_ids.h> +#include <dev/bhnd/cores/chipc/chipc.h> +#include <dev/bhnd/cores/pmu/bhnd_pmu.h> + #include <dev/bwn/if_bwnreg.h> #include <dev/bwn/if_bwnvar.h> @@ -87,6 +94,10 @@ __FBSDID("$FreeBSD$"); #include <dev/bwn/if_bwn_phy_lp.h> #include <dev/bwn/if_bwn_phy_n.h> +#include "bhnd_nvram_map.h" + +#include "gpio_if.h" + static SYSCTL_NODE(_hw, OID_AUTO, bwn, CTLFLAG_RD, 0, "Broadcom driver parameters"); @@ -109,8 +120,6 @@ SYSCTL_INT(_hw_bwn, OID_AUTO, bluetooth, CTLFLAG_RW, & static int bwn_hwpctl = 0; SYSCTL_INT(_hw_bwn, OID_AUTO, hwpctl, CTLFLAG_RW, &bwn_hwpctl, 0, "uses H/W power control"); -static int bwn_msi_disable = 0; /* MSI disabled */ -TUNABLE_INT("hw.bwn.msi_disable", &bwn_msi_disable); static int bwn_usedma = 1; SYSCTL_INT(_hw_bwn, OID_AUTO, usedma, CTLFLAG_RD, &bwn_usedma, 0, "uses DMA"); @@ -121,6 +130,8 @@ SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wm static void bwn_attach_pre(struct bwn_softc *); static int bwn_attach_post(struct bwn_softc *); +static int bwn_retain_bus_providers(struct bwn_softc *sc); +static void bwn_release_bus_providers(struct bwn_softc *sc); static void bwn_sprom_bugfixes(device_t); static int bwn_init(struct bwn_softc *); static void bwn_parent(struct ieee80211com *); @@ -153,6 +164,7 @@ static struct ieee80211vap *bwn_vap_create(struct ieee const uint8_t [IEEE80211_ADDR_LEN]); static void bwn_vap_delete(struct ieee80211vap *); static void bwn_stop(struct bwn_softc *); +static int bwn_core_forceclk(struct bwn_mac *, bool); static int bwn_core_init(struct bwn_mac *); static void bwn_core_start(struct bwn_mac *); static void bwn_core_exit(struct bwn_mac *); @@ -211,8 +223,6 @@ static struct bwn_pio_txqueue *bwn_pio_parse_cookie(st uint16_t, struct bwn_pio_txpkt **); static void bwn_dma_init(struct bwn_mac *); static void bwn_dma_rxdirectfifo(struct bwn_mac *, int, uint8_t); -static int bwn_dma_mask2type(uint64_t); -static uint64_t bwn_dma_mask(struct bwn_mac *); static uint16_t bwn_dma_base(int, int); static void bwn_dma_ringfree(struct bwn_dma_ring **); static void bwn_dma_32_getdesc(struct bwn_dma_ring *, @@ -248,7 +258,6 @@ static int bwn_dma_rx_reset(struct bwn_mac *, uint16_t static void bwn_dma_free_descbuf(struct bwn_dma_ring *, struct bwn_dmadesc_meta *); static void bwn_dma_set_redzone(struct bwn_dma_ring *, struct mbuf *); -static int bwn_dma_gettype(struct bwn_mac *); static void bwn_dma_ring_addr(void *, bus_dma_segment_t *, int, int); static int bwn_dma_freeslot(struct bwn_dma_ring *); static int bwn_dma_nextslot(struct bwn_dma_ring *, int); @@ -270,7 +279,7 @@ static struct bwn_dma_ring *bwn_dma_select(struct bwn_ uint8_t); static int bwn_dma_attach(struct bwn_mac *); static struct bwn_dma_ring *bwn_dma_ringsetup(struct bwn_mac *, - int, int, int); + int, int); static struct bwn_dma_ring *bwn_dma_parse_cookie(struct bwn_mac *, const struct bwn_txstatus *, uint16_t, int *); static void bwn_dma_free(struct bwn_mac *); @@ -296,7 +305,7 @@ static void bwn_phy_exit(struct bwn_mac *); static void bwn_core_stop(struct bwn_mac *); static int bwn_switch_band(struct bwn_softc *, struct ieee80211_channel *); -static void bwn_phy_reset(struct bwn_mac *); +static int bwn_phy_reset(struct bwn_mac *); static int bwn_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void bwn_set_pretbtt(struct bwn_mac *); static int bwn_intr(void *); @@ -346,7 +355,7 @@ static void bwn_watchdog(void *); static void bwn_dma_stop(struct bwn_mac *); static void bwn_pio_stop(struct bwn_mac *); static void bwn_dma_ringstop(struct bwn_dma_ring **); -static void bwn_led_attach(struct bwn_mac *); +static int bwn_led_attach(struct bwn_mac *); static void bwn_led_newstate(struct bwn_mac *, enum ieee80211_state); static void bwn_led_event(struct bwn_mac *, int); static void bwn_led_blink_start(struct bwn_mac *, int, int); @@ -357,16 +366,6 @@ static void bwn_rf_turnon(struct bwn_mac *); static void bwn_rf_turnoff(struct bwn_mac *); static void bwn_sysctl_node(struct bwn_softc *); -static struct resource_spec bwn_res_spec_legacy[] = { - { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, - { -1, 0, 0 } -}; - -static struct resource_spec bwn_res_spec_msi[] = { - { SYS_RES_IRQ, 1, RF_ACTIVE }, - { -1, 0, 0 } -}; - static const struct bwn_channelinfo bwn_chantable_bg = { .channels = { { 2412, 1, 30 }, { 2417, 2, 30 }, { 2422, 3, 30 }, @@ -449,7 +448,7 @@ static const struct { uint16_t vid; uint8_t led_act[BWN_LED_MAX]; } bwn_vendor_led_act[] = { - VENDOR_LED_ACT(COMPAQ), + VENDOR_LED_ACT(HP_COMPAQ), VENDOR_LED_ACT(ASUSTEK) }; @@ -458,6 +457,13 @@ static const uint8_t bwn_default_led_act[BWN_LED_MAX] #undef VENDOR_LED_ACT +static const char *bwn_led_vars[] = { + BHND_NVAR_LEDBH0, + BHND_NVAR_LEDBH1, + BHND_NVAR_LEDBH2, + BHND_NVAR_LEDBH3 +}; + static const struct { int on_dur; int off_dur; @@ -484,89 +490,130 @@ static const uint16_t bwn_wme_shm_offsets[] = { [3] = BWN_WME_VIDEO, }; -static const struct siba_devid bwn_devs[] = { - SIBA_DEV(BROADCOM, 80211, 5, "Revision 5"), - SIBA_DEV(BROADCOM, 80211, 6, "Revision 6"), - SIBA_DEV(BROADCOM, 80211, 7, "Revision 7"), - SIBA_DEV(BROADCOM, 80211, 9, "Revision 9"), - SIBA_DEV(BROADCOM, 80211, 10, "Revision 10"), - SIBA_DEV(BROADCOM, 80211, 11, "Revision 11"), - SIBA_DEV(BROADCOM, 80211, 12, "Revision 12"), - SIBA_DEV(BROADCOM, 80211, 13, "Revision 13"), - SIBA_DEV(BROADCOM, 80211, 15, "Revision 15"), - SIBA_DEV(BROADCOM, 80211, 16, "Revision 16") +/* Supported D11 core revisions */ +#define BWN_DEV(_hwrev) {{ \ + BHND_MATCH_CORE(BHND_MFGID_BCM, BHND_COREID_D11), \ + BHND_MATCH_CORE_REV(_hwrev), \ +}} +static const struct bhnd_device bwn_devices[] = { + BWN_DEV(HWREV_RANGE(5, 16)), + BWN_DEV(HWREV_EQ(23)), + BHND_DEVICE_END }; -static const struct bwn_bus_ops * -bwn_get_bus_ops(device_t dev) -{ -#if BWN_USE_SIBA - return (NULL); -#else - devclass_t bus_cls; +/* D11 quirks when bridged via a PCI host bridge core */ +static const struct bhnd_device_quirk pci_bridge_quirks[] = { + BHND_CORE_QUIRK (HWREV_LTE(10), BWN_QUIRK_UCODE_SLOWCLOCK_WAR), + BHND_DEVICE_QUIRK_END +}; - 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 -} +/* D11 quirks when bridged via a PCMCIA host bridge core */ +static const struct bhnd_device_quirk pcmcia_bridge_quirks[] = { + BHND_CORE_QUIRK (HWREV_ANY, BWN_QUIRK_NODMA), + BHND_DEVICE_QUIRK_END +}; +/* Host bridge cores for which D11 quirk flags should be applied */ +static const struct bhnd_device bridge_devices[] = { + BHND_DEVICE(BCM, PCI, NULL, pci_bridge_quirks), + BHND_DEVICE(BCM, PCMCIA, NULL, pcmcia_bridge_quirks), + BHND_DEVICE_END +}; + static int bwn_probe(device_t dev) { - struct bwn_softc *sc; - int i; + const struct bhnd_device *id; - sc = device_get_softc(dev); - sc->sc_bus_ops = bwn_get_bus_ops(dev); + id = bhnd_device_lookup(dev, bwn_devices, sizeof(bwn_devices[0])); + if (id == NULL) + return (ENXIO); - for (i = 0; i < nitems(bwn_devs); i++) { - if (siba_get_vendor(dev) == bwn_devs[i].sd_vendor && - siba_get_device(dev) == bwn_devs[i].sd_device && - siba_get_revid(dev) == bwn_devs[i].sd_rev) - return (BUS_PROBE_DEFAULT); - } - - return (ENXIO); + bhnd_set_default_core_desc(dev); + return (BUS_PROBE_DEFAULT); } -int +static int bwn_attach(device_t dev) { - struct bwn_mac *mac; - struct bwn_softc *sc = device_get_softc(dev); - int error, i, msic, reg; + struct bwn_mac *mac; + struct bwn_softc *sc; + device_t parent, hostb; + char chip_name[BHND_CHIPID_MAX_NAMELEN]; + int error; + sc = device_get_softc(dev); sc->sc_dev = dev; #ifdef BWN_DEBUG 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); + mac = NULL; + + /* Determine the driver quirks applicable to this device, including any + * quirks specific to the bus host bridge core (if any) */ + sc->sc_quirks = bhnd_device_quirks(dev, bwn_devices, + sizeof(bwn_devices[0])); + + parent = device_get_parent(dev); + if ((hostb = bhnd_bus_find_hostb_device(parent)) != NULL) { + sc->sc_quirks |= bhnd_device_quirks(hostb, bridge_devices, + sizeof(bridge_devices[0])); + } + + /* DMA explicitly disabled? */ + if (!bwn_usedma) + sc->sc_quirks |= BWN_QUIRK_NODMA; + + /* Fetch our chip identification and board info */ + sc->sc_cid = *bhnd_get_chipid(dev); + if ((error = bhnd_read_board_info(dev, &sc->sc_board_info))) { + device_printf(sc->sc_dev, "couldn't read board info\n"); return (error); } + /* Allocate our D11 register block and PMU state */ + sc->sc_mem_rid = 0; + sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->sc_mem_rid, RF_ACTIVE); + if (sc->sc_mem_res == NULL) { + device_printf(sc->sc_dev, "couldn't allocate registers\n"); + return (error); + } + + if ((error = bhnd_alloc_pmu(sc->sc_dev))) { + bus_release_resource(sc->sc_dev, SYS_RES_MEMORY, + sc->sc_mem_rid, sc->sc_mem_res); + return (error); + } + + /* Retain references to all required bus service providers */ + if ((error = bwn_retain_bus_providers(sc))) + goto fail; + + /* Fetch mask of available antennas */ + error = bhnd_nvram_getvar_uint8(sc->sc_dev, BHND_NVAR_AA2G, + &sc->sc_ant2g); + if (error) { + device_printf(sc->sc_dev, "error determining 2GHz antenna " + "availability from NVRAM: %d\n", error); + goto fail; + } + + error = bhnd_nvram_getvar_uint8(sc->sc_dev, BHND_NVAR_AA5G, + &sc->sc_ant5g); + if (error) { + device_printf(sc->sc_dev, "error determining 5GHz antenna " + "availability from NVRAM: %d\n", error); + goto fail; + } + if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { bwn_attach_pre(sc); bwn_sprom_bugfixes(dev); sc->sc_flags |= BWN_FLAG_ATTACHED; } - if (!TAILQ_EMPTY(&sc->sc_maclist)) { - if (siba_get_pci_device(dev) != 0x4313 && - siba_get_pci_device(dev) != 0x431a && - siba_get_pci_device(dev) != 0x4321) { - device_printf(sc->sc_dev, - "skip 802.11 cores\n"); - return (ENODEV); - } - } - mac = malloc(sizeof(*mac), M_DEVBUF, M_WAITOK | M_ZERO); mac->mac_sc = sc; mac->mac_status = BWN_MAC_STATUS_UNINIT; @@ -579,18 +626,19 @@ bwn_attach(device_t dev) error = bwn_attach_core(mac); if (error) - goto fail0; - bwn_led_attach(mac); + goto fail; + error = bwn_led_attach(mac); + if (error) + goto fail; - device_printf(sc->sc_dev, "WLAN (chipid %#x rev %u) " + bhnd_format_chip_id(chip_name, sizeof(chip_name), sc->sc_cid.chip_id); + device_printf(sc->sc_dev, "WLAN (%s rev %u) " "PHY (analog %d type %d rev %d) RADIO (manuf %#x ver %#x rev %d)\n", - siba_get_chipid(sc->sc_dev), siba_get_revid(sc->sc_dev), - mac->mac_phy.analog, mac->mac_phy.type, mac->mac_phy.rev, - mac->mac_phy.rf_manuf, mac->mac_phy.rf_ver, - mac->mac_phy.rf_rev); + chip_name, bhnd_get_hwrev(sc->sc_dev), mac->mac_phy.analog, + mac->mac_phy.type, mac->mac_phy.rev, mac->mac_phy.rf_manuf, + mac->mac_phy.rf_ver, mac->mac_phy.rf_rev); if (mac->mac_flags & BWN_MAC_FLAG_DMA) - device_printf(sc->sc_dev, "DMA (%d bits)\n", - mac->mac_method.dma.dmatype); + device_printf(sc->sc_dev, "DMA (%d bits)\n", mac->mac_dmatype); else device_printf(sc->sc_dev, "PIO\n"); @@ -599,51 +647,25 @@ bwn_attach(device_t dev) "Note: compiled with BWN_GPL_PHY; includes GPLv2 code\n"); #endif - /* - * setup PCI resources and interrupt. - */ - if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) { - msic = pci_msi_count(dev); - if (bootverbose) - device_printf(sc->sc_dev, "MSI count : %d\n", msic); - } else - msic = 0; + mac->mac_rid_irq = 0; + mac->mac_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &mac->mac_rid_irq, RF_ACTIVE | RF_SHAREABLE); - mac->mac_intr_spec = bwn_res_spec_legacy; - if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) { - if (pci_alloc_msi(dev, &msic) == 0) { - device_printf(sc->sc_dev, - "Using %d MSI messages\n", msic); - mac->mac_intr_spec = bwn_res_spec_msi; - mac->mac_msi = 1; - } + if (mac->mac_res_irq == NULL) { + device_printf(sc->sc_dev, "couldn't allocate IRQ resource\n"); + error = ENXIO; + goto fail; } - error = bus_alloc_resources(dev, mac->mac_intr_spec, - mac->mac_res_irq); - if (error) { - device_printf(sc->sc_dev, - "couldn't allocate IRQ resources (%d)\n", error); - goto fail1; + error = bus_setup_intr(dev, mac->mac_res_irq, + INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, + &mac->mac_intrhand); + if (error != 0) { + device_printf(sc->sc_dev, "couldn't setup interrupt (%d)\n", + error); + goto fail; } - if (mac->mac_msi == 0) - error = bus_setup_intr(dev, mac->mac_res_irq[0], - INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, - &mac->mac_intrhand[0]); - else { - for (i = 0; i < BWN_MSI_MESSAGES; i++) { - error = bus_setup_intr(dev, mac->mac_res_irq[i], - INTR_TYPE_NET | INTR_MPSAFE, bwn_intr, NULL, mac, - &mac->mac_intrhand[i]); - if (error != 0) { - device_printf(sc->sc_dev, - "couldn't setup interrupt (%d)\n", error); - break; - } - } - } - TAILQ_INSERT_TAIL(&sc->sc_maclist, mac, mac_list); /* @@ -653,31 +675,86 @@ bwn_attach(device_t dev) bwn_attach_post(sc); return (0); -fail1: - if (msic == BWN_MSI_MESSAGES && bwn_msi_disable == 0) - pci_release_msi(dev); -fail0: - BWN_BUS_OPS_DETACH(dev); +fail: + if (mac != NULL && mac->mac_res_irq != NULL) { + bus_release_resource(dev, SYS_RES_IRQ, mac->mac_rid_irq, + mac->mac_res_irq); + } + free(mac, M_DEVBUF); + bhnd_release_pmu(dev); + bwn_release_bus_providers(sc); + + if (sc->sc_mem_res != NULL) { + bus_release_resource(sc->sc_dev, SYS_RES_MEMORY, + sc->sc_mem_rid, sc->sc_mem_res); + } + return (error); } static int -bwn_is_valid_ether_addr(uint8_t *addr) +bwn_retain_bus_providers(struct bwn_softc *sc) { - char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; + struct chipc_caps *ccaps; - if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) - return (FALSE); + sc->sc_chipc = bhnd_retain_provider(sc->sc_dev, BHND_SERVICE_CHIPC); + if (sc->sc_chipc == NULL) { + device_printf(sc->sc_dev, "ChipCommon device not found\n"); + goto failed; + } - return (TRUE); + ccaps = BHND_CHIPC_GET_CAPS(sc->sc_chipc); + + sc->sc_gpio = bhnd_retain_provider(sc->sc_dev, BHND_SERVICE_GPIO); + if (sc->sc_gpio == NULL) { + device_printf(sc->sc_dev, "GPIO device not found\n"); + goto failed; + } + + if (ccaps->pmu) { + sc->sc_pmu = bhnd_retain_provider(sc->sc_dev, BHND_SERVICE_PMU); + if (sc->sc_pmu == NULL) { + device_printf(sc->sc_dev, "PMU device not found\n"); + goto failed; + } + } + + return (0); + +failed: + bwn_release_bus_providers(sc); + return (ENXIO); } +static void +bwn_release_bus_providers(struct bwn_softc *sc) +{ +#define BWN_RELEASE_PROV(_sc, _prov, _service) do { \ + if ((_sc)-> _prov != NULL) { \ + bhnd_release_provider((_sc)->sc_dev, (_sc)-> _prov, \ + (_service)); \ + (_sc)-> _prov = NULL; \ + } \ +} while (0) + + BWN_RELEASE_PROV(sc, sc_chipc, BHND_SERVICE_CHIPC); + BWN_RELEASE_PROV(sc, sc_gpio, BHND_SERVICE_GPIO); + BWN_RELEASE_PROV(sc, sc_pmu, BHND_SERVICE_PMU); + +#undef BWN_RELEASE_PROV +} + static int bwn_attach_post(struct bwn_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; + const char *mac_varname; + u_int core_unit; + int error; + ic = &sc->sc_ic; + ic->ic_softc = sc; ic->ic_name = device_get_nameunit(sc->sc_dev); /* XXX not right but it's not used anywhere important */ @@ -699,11 +776,36 @@ bwn_attach_post(struct bwn_softc *sc) ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ - IEEE80211_ADDR_COPY(ic->ic_macaddr, - bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ? - siba_sprom_get_mac_80211a(sc->sc_dev) : - siba_sprom_get_mac_80211bg(sc->sc_dev)); + /* Determine the NVRAM variable containing our MAC address */ + core_unit = bhnd_get_core_unit(sc->sc_dev); + mac_varname = NULL; + if (sc->sc_board_info.board_srom_rev <= 2) { + if (core_unit == 0) { + mac_varname = BHND_NVAR_IL0MACADDR; + } else if (core_unit == 1) { + mac_varname = BHND_NVAR_ET1MACADDR; + } + } else { + if (core_unit == 0) { + mac_varname = BHND_NVAR_MACADDR; + } + } + if (mac_varname == NULL) { + device_printf(sc->sc_dev, "missing MAC address variable for " + "D11 core %u", core_unit); + return (ENXIO); + } + + /* Read the MAC address from NVRAM */ + error = bhnd_nvram_getvar_array(sc->sc_dev, mac_varname, ic->ic_macaddr, + sizeof(ic->ic_macaddr), BHND_NVRAM_TYPE_UINT8_ARRAY); + if (error) { + device_printf(sc->sc_dev, "error reading %s: %d\n", mac_varname, + error); + return (error); + } + /* call MI attach routine. */ ieee80211_ifattach(ic); @@ -743,13 +845,12 @@ bwn_phy_detach(struct bwn_mac *mac) mac->mac_phy.detach(mac); } -int +static int bwn_detach(device_t dev) { struct bwn_softc *sc = device_get_softc(dev); struct bwn_mac *mac = sc->sc_curmac; struct ieee80211com *ic = &sc->sc_ic; - int i; sc->sc_flags |= BWN_FLAG_INVALID; @@ -770,20 +871,22 @@ bwn_detach(device_t dev) taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); taskqueue_free(sc->sc_tq); - for (i = 0; i < BWN_MSI_MESSAGES; i++) { - if (mac->mac_intrhand[i] != NULL) { - bus_teardown_intr(dev, mac->mac_res_irq[i], - mac->mac_intrhand[i]); - mac->mac_intrhand[i] = NULL; - } + if (mac->mac_intrhand != NULL) { + bus_teardown_intr(dev, mac->mac_res_irq, mac->mac_intrhand); + mac->mac_intrhand = NULL; } - bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq); - if (mac->mac_msi != 0) - pci_release_msi(dev); + + bhnd_release_pmu(dev); + bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid, + sc->sc_mem_res); + bus_release_resource(dev, SYS_RES_IRQ, mac->mac_rid_irq, + mac->mac_res_irq); mbufq_drain(&sc->sc_snd); bwn_release_firmware(mac); BWN_LOCK_DESTROY(sc); - BWN_BUS_OPS_DETACH(dev); + + bwn_release_bus_providers(sc); + return (0); } @@ -806,32 +909,28 @@ bwn_attach_pre(struct bwn_softc *sc) static void bwn_sprom_bugfixes(device_t dev) { -#define BWN_ISDEV(_vendor, _device, _subvendor, _subdevice) \ - ((siba_get_pci_vendor(dev) == PCI_VENDOR_##_vendor) && \ - (siba_get_pci_device(dev) == _device) && \ - (siba_get_pci_subvendor(dev) == PCI_VENDOR_##_subvendor) && \ - (siba_get_pci_subdevice(dev) == _subdevice)) + struct bwn_softc *sc = device_get_softc(dev); - if (siba_get_pci_subvendor(dev) == PCI_VENDOR_APPLE && - siba_get_pci_subdevice(dev) == 0x4e && - siba_get_pci_revid(dev) > 0x40) - siba_sprom_set_bf_lo(dev, - siba_sprom_get_bf_lo(dev) | BWN_BFL_PACTRL); - if (siba_get_pci_subvendor(dev) == SIBA_BOARDVENDOR_DELL && - siba_get_chipid(dev) == 0x4301 && siba_get_pci_revid(dev) == 0x74) - siba_sprom_set_bf_lo(dev, - siba_sprom_get_bf_lo(dev) | BWN_BFL_BTCOEXIST); - if (siba_get_type(dev) == SIBA_TYPE_PCI) { - if (BWN_ISDEV(BROADCOM, 0x4318, ASUSTEK, 0x100f) || - BWN_ISDEV(BROADCOM, 0x4320, DELL, 0x0003) || - BWN_ISDEV(BROADCOM, 0x4320, HP, 0x12f8) || - BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0013) || - BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0014) || - BWN_ISDEV(BROADCOM, 0x4320, LINKSYS, 0x0015) || - BWN_ISDEV(BROADCOM, 0x4320, MOTOROLA, 0x7010)) - siba_sprom_set_bf_lo(dev, - siba_sprom_get_bf_lo(dev) & ~BWN_BFL_BTCOEXIST); - } +#define BWN_ISDEV(_device, _subvendor, _subdevice) \ + ((sc->sc_board_info.board_devid == PCI_DEVID_##_device) && \ + (sc->sc_board_info.board_vendor == PCI_VENDOR_##_subvendor) && \ + (sc->sc_board_info.board_type == _subdevice)) + + /* A subset of Apple Airport Extreme (BCM4306 rev 2) devices + * were programmed with a missing PACTRL boardflag */ + if (sc->sc_board_info.board_vendor == PCI_VENDOR_APPLE && + sc->sc_board_info.board_type == 0x4e && + sc->sc_board_info.board_rev > 0x40) + sc->sc_board_info.board_flags |= BHND_BFL_PACTRL; + + if (BWN_ISDEV(BCM4318_D11G, ASUSTEK, 0x100f) || + BWN_ISDEV(BCM4306_D11G, DELL, 0x0003) || + BWN_ISDEV(BCM4306_D11G, HP, 0x12f8) || + BWN_ISDEV(BCM4306_D11G, LINKSYS, 0x0013) || + BWN_ISDEV(BCM4306_D11G, LINKSYS, 0x0014) || + BWN_ISDEV(BCM4306_D11G, LINKSYS, 0x0015) || + BWN_ISDEV(BCM4306_D11G, MOTOROLA, 0x7010)) + sc->sc_board_info.board_flags &= ~BHND_BFL_BTCOEX; #undef BWN_ISDEV } @@ -1008,7 +1107,7 @@ bwn_pio_tx_start(struct bwn_mac *mac, struct ieee80211 tq->tq_used += roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); tq->tq_free--; - if (siba_get_revid(sc->sc_dev) >= 8) { + if (bhnd_get_hwrev(sc->sc_dev) >= 8) { /* * XXX please removes m_defrag(9) */ @@ -1181,29 +1280,37 @@ bwn_attach_core(struct bwn_mac *mac) { struct bwn_softc *sc = mac->mac_sc; int error, have_bg = 0, have_a = 0; - uint32_t high; + uint16_t iost; - KASSERT(siba_get_revid(sc->sc_dev) >= 5, - ("unsupported revision %d", siba_get_revid(sc->sc_dev))); + KASSERT(bhnd_get_hwrev(sc->sc_dev) >= 5, + ("unsupported revision %d", bhnd_get_hwrev(sc->sc_dev))); - 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) { + if ((error = bwn_core_forceclk(mac, true))) + return (error); + + if ((error = bhnd_read_iost(sc->sc_dev, &iost))) { + device_printf(sc->sc_dev, "error reading I/O status flags: " + "%d\n", error); + return (error); + } + + have_a = (iost & BWN_IOST_HAVE_5GHZ) ? 1 : 0; + have_bg = (iost & BWN_IOST_HAVE_2GHZ) ? 1 : 0; + if (iost & BWN_IOST_DUALPHY) { have_bg = 1; have_a = 1; } + #if 0 - device_printf(sc->sc_dev, "%s: high=0x%08x, have_a=%d, have_bg=%d," + device_printf(sc->sc_dev, "%s: iost=0x%04hx, have_a=%d, have_bg=%d," " deviceid=0x%04x, siba_deviceid=0x%04x\n", __func__, - high, + iost, have_a, have_bg, - siba_get_pci_device(sc->sc_dev), - siba_get_chipid(sc->sc_dev)); + sc->sc_board_info.board_devid, + sc->sc_cid.chip_id); #endif /* @@ -1211,9 +1318,31 @@ bwn_attach_core(struct bwn_mac *mac) * This is just used for resetting the core to probe things; * we will re-guess once it's all up and working. */ - bwn_reset_core(mac, have_bg); + error = bwn_reset_core(mac, have_bg); + if (error) + goto fail; /* + * Determine the DMA engine type + */ + if (iost & BHND_IOST_DMA64) { + mac->mac_dmatype = BHND_DMA_ADDR_64BIT; + } else { + uint32_t tmp; + uint16_t base; + + base = bwn_dma_base(0, 0); + BWN_WRITE_4(mac, base + BWN_DMA32_TXCTL, + BWN_DMA32_TXADDREXT_MASK); + tmp = BWN_READ_4(mac, base + BWN_DMA32_TXCTL); + if (tmp & BWN_DMA32_TXADDREXT_MASK) { + mac->mac_dmatype = BHND_DMA_ADDR_32BIT; + } else { + mac->mac_dmatype = BHND_DMA_ADDR_30BIT; + } + } + + /* * Get the PHY version. */ error = bwn_phy_getinfo(mac, have_bg); @@ -1224,12 +1353,12 @@ bwn_attach_core(struct bwn_mac *mac) * This is the whitelist of devices which we "believe" * the SPROM PHY config from. The rest are "guessed". */ - if (siba_get_pci_device(sc->sc_dev) != 0x4312 && - siba_get_pci_device(sc->sc_dev) != 0x4315 && - siba_get_pci_device(sc->sc_dev) != 0x4319 && - siba_get_pci_device(sc->sc_dev) != 0x4324 && - siba_get_pci_device(sc->sc_dev) != 0x4328 && - siba_get_pci_device(sc->sc_dev) != 0x432b) { + if (sc->sc_board_info.board_devid != PCI_DEVID_BCM4311_D11DUAL && + sc->sc_board_info.board_devid != PCI_DEVID_BCM4328_D11G && + sc->sc_board_info.board_devid != PCI_DEVID_BCM4318_D11DUAL && + sc->sc_board_info.board_devid != PCI_DEVID_BCM4306_D11DUAL && + sc->sc_board_info.board_devid != PCI_DEVID_BCM4321_D11N && + sc->sc_board_info.board_devid != PCI_DEVID_BCM4322_D11N) { have_a = have_bg = 0; if (mac->mac_phy.type == BWN_PHYTYPE_A) have_a = 1; @@ -1330,7 +1459,9 @@ bwn_attach_core(struct bwn_mac *mac) } } - bwn_reset_core(mac, have_bg); + error = bwn_reset_core(mac, have_bg); + if (error) + goto fail; error = bwn_chiptest(mac); if (error) @@ -1352,46 +1483,64 @@ bwn_attach_core(struct bwn_mac *mac) mac->mac_phy.switch_analog(mac, 0); - siba_dev_down(sc->sc_dev, 0); fail: - siba_powerdown(sc->sc_dev); + bhnd_suspend_hw(sc->sc_dev, 0); bwn_release_firmware(mac); return (error); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802052338.w15NcFfD053829>