freebsd-skq/sys/dev/bwn/if_bwn_siba.c
landonf 6f4a9c1918 Introduce bwn(4) support for the bhnd(4) bus.
Currently, bwn(4) relies on the siba_bwn(4) bus driver to provide support
for the on-chip SSB interconnect found in Broadcom's older PCI(e) Wi-Fi
adapters. Non-PCI Wi-Fi adapters, as well as the newer BCMA interconnect
found in post-2009 Broadcom Wi-Fi hardware, are not supported by
siba_bwn(4).

The bhnd(4) bus driver (also used by the FreeBSD/MIPS Broadcom port)
provides a unified kernel interface to a superset of the hardware supported
by siba_bwn; by attaching bwn(4) via bhnd(4), we can support both modern
PCI(e) Wi-Fi devices based on the BCMA backplane interconnect, as well as
Broadcom MIPS WiSoCs that include a D11 MAC core directly attached to their
SSB or BCMA backplane.

This diff introduces opt-in bwn(4) support for bhnd(4) by providing:

 - A small bwn(4) driver subclass, if_bwn_bhnd, that attaches via
   bhnd(4) instead of siba_bwn(4).
 - A bhndb(4)-based PCI host bridge driver, if_bwn_pci, that optionally
   probes at a higher priority than the siba_bwn(4) PCI driver.
 - A set of compatibility shims that perform translation of bwn(4)'s
   siba_bwn function calls into their bhnd(9) API equivalents when bwn(4)
   is attached via a bhnd(4) bus parent. When bwn(4) is attached via
   siba_bwn(4), all siba_bwn function calls are simply passed through to
   their original implementations.

To test bwn(4) with bhnd(4), place the following lines in loader.conf(5):

  hw.bwn_pci.preferred="1"

  if_bwn_pci_load="YES
  bwn_v4_ucode_load="YES"
  bwn_v4_lp_ucode_load="YES"

To verify that bwn(4) is using bhnd(4), you can check dmesg:

  bwn0: <Broadcom 802.11 MAC/PHY/Radio, rev 15> ... on bhnd0

... or devinfo(8):

pcib2
  pci2
    bwn_pci0
      bhndb0
        bhnd0
          bwn0
          ...

bwn(4)/bhnd(4) has been tested for regressions with most chipsets currently
supported by bwn(4), including:

  - BCM4312
  - BCM4318
  - BCM4321

With minimal changes to the DMA code (not included in this commit), I was
also able to test support for newer BCMA devices by bringing up basic
working Wi-Fi on two previously unsupported, BCMA-based N-PHY chipsets:

  - BCM43224
  - BCM43225

Approved by:	adrian (mentor, implicit)
Sponsored by:	The FreeBSD Foundation & Plausible Labs
Differential Revision:	https://reviews.freebsd.org/D13041
2017-12-02 02:21:27 +00:00

172 lines
6.7 KiB
C

/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/systm.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#define BWN_USE_SIBA 1
#include "if_bwn_siba.h"
/** Legacy siba(4) bus operations */
static int
bwn_siba_bus_ops_init(device_t dev)
{
return (0);
}
static void
bwn_siba_bus_ops_fini(device_t dev)
{
}
const struct bwn_bus_ops bwn_siba_bus_ops = {
.init = bwn_siba_bus_ops_init,
.fini = bwn_siba_bus_ops_fini,
.pci_find_cap = pci_find_cap,
.pci_alloc_msi = pci_alloc_msi,
.pci_release_msi = pci_release_msi,
.pci_msi_count = pci_msi_count,
.get_vendor = siba_get_vendor,
.get_device = siba_get_device,
.get_revid = siba_get_revid,
.get_pci_vendor = siba_get_pci_vendor,
.get_pci_device = siba_get_pci_device,
.get_pci_subvendor = siba_get_pci_subvendor,
.get_pci_subdevice = siba_get_pci_subdevice,
.get_pci_revid = siba_get_pci_revid,
.get_chipid = siba_get_chipid,
.get_chiprev = siba_get_chiprev,
.get_chippkg = siba_get_chippkg,
.get_type = siba_get_type,
.get_cc_pmufreq = siba_get_cc_pmufreq,
.get_cc_caps = siba_get_cc_caps,
.get_cc_powerdelay = siba_get_cc_powerdelay,
.get_pcicore_revid = siba_get_pcicore_revid,
.sprom_get_rev = siba_sprom_get_rev,
.sprom_get_mac_80211bg = siba_sprom_get_mac_80211bg,
.sprom_get_mac_80211a = siba_sprom_get_mac_80211a,
.sprom_get_brev = siba_sprom_get_brev,
.sprom_get_ccode = siba_sprom_get_ccode,
.sprom_get_ant_a = siba_sprom_get_ant_a,
.sprom_get_ant_bg = siba_sprom_get_ant_bg,
.sprom_get_pa0b0 = siba_sprom_get_pa0b0,
.sprom_get_pa0b1 = siba_sprom_get_pa0b1,
.sprom_get_pa0b2 = siba_sprom_get_pa0b2,
.sprom_get_gpio0 = siba_sprom_get_gpio0,
.sprom_get_gpio1 = siba_sprom_get_gpio1,
.sprom_get_gpio2 = siba_sprom_get_gpio2,
.sprom_get_gpio3 = siba_sprom_get_gpio3,
.sprom_get_maxpwr_bg = siba_sprom_get_maxpwr_bg,
.sprom_set_maxpwr_bg = siba_sprom_set_maxpwr_bg,
.sprom_get_rxpo2g = siba_sprom_get_rxpo2g,
.sprom_get_rxpo5g = siba_sprom_get_rxpo5g,
.sprom_get_tssi_bg = siba_sprom_get_tssi_bg,
.sprom_get_tri2g = siba_sprom_get_tri2g,
.sprom_get_tri5gl = siba_sprom_get_tri5gl,
.sprom_get_tri5g = siba_sprom_get_tri5g,
.sprom_get_tri5gh = siba_sprom_get_tri5gh,
.sprom_get_rssisav2g = siba_sprom_get_rssisav2g,
.sprom_get_rssismc2g = siba_sprom_get_rssismc2g,
.sprom_get_rssismf2g = siba_sprom_get_rssismf2g,
.sprom_get_bxa2g = siba_sprom_get_bxa2g,
.sprom_get_rssisav5g = siba_sprom_get_rssisav5g,
.sprom_get_rssismc5g = siba_sprom_get_rssismc5g,
.sprom_get_rssismf5g = siba_sprom_get_rssismf5g,
.sprom_get_bxa5g = siba_sprom_get_bxa5g,
.sprom_get_cck2gpo = siba_sprom_get_cck2gpo,
.sprom_get_ofdm2gpo = siba_sprom_get_ofdm2gpo,
.sprom_get_ofdm5glpo = siba_sprom_get_ofdm5glpo,
.sprom_get_ofdm5gpo = siba_sprom_get_ofdm5gpo,
.sprom_get_ofdm5ghpo = siba_sprom_get_ofdm5ghpo,
.sprom_get_bf_lo = siba_sprom_get_bf_lo,
.sprom_set_bf_lo = siba_sprom_set_bf_lo,
.sprom_get_bf_hi = siba_sprom_get_bf_hi,
.sprom_get_bf2_lo = siba_sprom_get_bf2_lo,
.sprom_get_bf2_hi = siba_sprom_get_bf2_hi,
.sprom_get_fem_2ghz_tssipos = siba_sprom_get_fem_2ghz_tssipos,
.sprom_get_fem_2ghz_extpa_gain = siba_sprom_get_fem_2ghz_extpa_gain,
.sprom_get_fem_2ghz_pdet_range = siba_sprom_get_fem_2ghz_pdet_range,
.sprom_get_fem_2ghz_tr_iso = siba_sprom_get_fem_2ghz_tr_iso,
.sprom_get_fem_2ghz_antswlut = siba_sprom_get_fem_2ghz_antswlut,
.sprom_get_fem_5ghz_extpa_gain = siba_sprom_get_fem_5ghz_extpa_gain,
.sprom_get_fem_5ghz_pdet_range = siba_sprom_get_fem_5ghz_pdet_range,
.sprom_get_fem_5ghz_antswlut = siba_sprom_get_fem_5ghz_antswlut,
.sprom_get_txpid_2g_0 = siba_sprom_get_txpid_2g_0,
.sprom_get_txpid_2g_1 = siba_sprom_get_txpid_2g_1,
.sprom_get_txpid_5gl_0 = siba_sprom_get_txpid_5gl_0,
.sprom_get_txpid_5gl_1 = siba_sprom_get_txpid_5gl_1,
.sprom_get_txpid_5g_0 = siba_sprom_get_txpid_5g_0,
.sprom_get_txpid_5g_1 = siba_sprom_get_txpid_5g_1,
.sprom_get_txpid_5gh_0 = siba_sprom_get_txpid_5gh_0,
.sprom_get_txpid_5gh_1 = siba_sprom_get_txpid_5gh_1,
.sprom_get_stbcpo = siba_sprom_get_stbcpo,
.sprom_get_cddpo = siba_sprom_get_cddpo,
.powerup = siba_powerup,
.powerdown = siba_powerdown,
.read_2 = siba_read_2,
.write_2 = siba_write_2,
.read_4 = siba_read_4,
.write_4 = siba_write_4,
.dev_up = siba_dev_up,
.dev_down = siba_dev_down,
.dev_isup = siba_dev_isup,
.pcicore_intr = siba_pcicore_intr,
.dma_translation = siba_dma_translation,
.read_multi_2 = siba_read_multi_2,
.read_multi_4 = siba_read_multi_4,
.write_multi_2 = siba_write_multi_2,
.write_multi_4 = siba_write_multi_4,
.barrier = siba_barrier,
.cc_pmu_set_ldovolt = siba_cc_pmu_set_ldovolt,
.cc_pmu_set_ldoparef = siba_cc_pmu_set_ldoparef,
.gpio_set = siba_gpio_set,
.gpio_get = siba_gpio_get,
.fix_imcfglobug = siba_fix_imcfglobug,
.sprom_get_core_power_info = siba_sprom_get_core_power_info,
.sprom_get_mcs2gpo = siba_sprom_get_mcs2gpo,
.sprom_get_mcs5glpo = siba_sprom_get_mcs5glpo,
.sprom_get_mcs5gpo = siba_sprom_get_mcs5gpo,
.sprom_get_mcs5ghpo = siba_sprom_get_mcs5ghpo,
.pmu_spuravoid_pllupdate = siba_pmu_spuravoid_pllupdate,
.cc_set32 = siba_cc_set32,
.cc_mask32 = siba_cc_mask32,
.cc_write32 = siba_cc_write32,
};