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 weon...@freebsd.org .
+Support for
+.Xr bhnd 4
+was added by
+.An Landon Fuller Aq Mt land...@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 <weon...@freebsd.org>
+ * Copyright (c) 2016 Landon Fuller <land...@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, &reg) == 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 ***
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to