[bhnd] Normalize bhnd(4) device matching API

This unifies handling of core, chip, and board-level device
matching, and adds support for matching device drivers
against the bus attach type (e.g. SoC vs WiFi adapter).

Core-level quirks on Broadcom's chipsets generally are specific
to some combination of chip model, core revision, chip
package (e.g. 12x9 SMT package), SROM revision, etc.

Unifying the match APIs for all three attribute types (core, chip,
board/srom) allows defining a single device quirk table that
matches across all of those attributes.

Submitted by:	Landon Fuller <landonf@landonf.org>
Differential Revision:	 https://reviews.freebsd.org/D6515
This commit is contained in:
Adrian Chadd 2016-05-24 21:20:17 +00:00
parent c5e44d6cd5
commit 5ad9ac037d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=300628
13 changed files with 669 additions and 615 deletions

View File

@ -41,6 +41,7 @@
#include "bhnd_types.h"
#include "bhnd_debug.h"
#include "bhnd_bus_if.h"
#include "bhnd_match.h"
extern devclass_t bhnd_devclass;
extern devclass_t bhnd_hostb_devclass;
@ -169,17 +170,6 @@ struct bhnd_core_info {
int unit; /**< bus-assigned core unit */
};
/**
* A hardware revision match descriptor.
*/
struct bhnd_hwrev_match {
uint16_t start; /**< first revision, or BHND_HWREV_INVALID
to match on any revision. */
uint16_t end; /**< last revision, or BHND_HWREV_INVALID
to match on any revision. */
};
/**
* A bhnd(4) bus resource.
*
@ -193,223 +183,70 @@ struct bhnd_resource {
* is MMIO accessible. */
};
/**
* Wildcard hardware revision match descriptor.
*/
#define BHND_HWREV_ANY { BHND_HWREV_INVALID, BHND_HWREV_INVALID }
#define BHND_HWREV_IS_ANY(_m) \
((_m)->start == BHND_HWREV_INVALID && (_m)->end == BHND_HWREV_INVALID)
/**
* Hardware revision match descriptor for an inclusive range.
*
* @param _start The first applicable hardware revision.
* @param _end The last applicable hardware revision, or BHND_HWREV_INVALID
* to match on any revision.
*/
#define BHND_HWREV_RANGE(_start, _end) { _start, _end }
/**
* Hardware revision match descriptor for a single revision.
*
* @param _hwrev The hardware revision to match on.
*/
#define BHND_HWREV_EQ(_hwrev) BHND_HWREV_RANGE(_hwrev, _hwrev)
/**
* Hardware revision match descriptor for any revision equal to or greater
* than @p _start.
*
* @param _start The first hardware revision to match on.
*/
#define BHND_HWREV_GTE(_start) BHND_HWREV_RANGE(_start, BHND_HWREV_INVALID)
/**
* Hardware revision match descriptor for any revision equal to or less
* than @p _end.
*
* @param _end The last hardware revision to match on.
*/
#define BHND_HWREV_LTE(_end) BHND_HWREV_RANGE(0, _end)
/** A core match descriptor. */
struct bhnd_core_match {
uint16_t vendor; /**< required JEP106 device vendor or BHND_MFGID_INVALID. */
uint16_t device; /**< required core ID or BHND_COREID_INVALID */
struct bhnd_hwrev_match hwrev; /**< matching revisions. */
bhnd_devclass_t class; /**< required class or BHND_DEVCLASS_INVALID */
int unit; /**< required core unit, or -1 */
};
/**
* Core match descriptor matching against the given @p _vendor, @p _device,
* and @p _hwrev match descriptors.
*/
#define BHND_CORE_MATCH(_vendor, _device, _hwrev) \
{ _vendor, _device, _hwrev, BHND_DEVCLASS_INVALID, -1 }
/**
* Wildcard core match descriptor.
*/
#define BHND_CORE_MATCH_ANY \
{ \
.vendor = BHND_MFGID_INVALID, \
.device = BHND_COREID_INVALID, \
.hwrev = BHND_HWREV_ANY, \
.class = BHND_DEVCLASS_INVALID, \
.unit = -1 \
}
/**
* A chipset match descriptor.
*
* @warning Matching on board/nvram attributes relies on NVRAM access, and will
* fail if a valid NVRAM device cannot be found, or is not yet attached.
*/
struct bhnd_chip_match {
/** Select fields to be matched */
uint16_t
match_id:1,
match_rev:1,
match_pkg:1,
match_bvendor:1,
match_btype:1,
match_brev:1,
match_srom_rev:1,
match_any:1,
match_flags_unused:8;
uint16_t chip_id; /**< required chip id */
struct bhnd_hwrev_match chip_rev; /**< matching chip revisions */
uint8_t chip_pkg; /**< required package */
uint16_t board_vendor; /**< required board vendor */
uint16_t board_type; /**< required board type */
struct bhnd_hwrev_match board_rev; /**< matching board revisions */
struct bhnd_hwrev_match board_srom_rev; /**< matching board srom revisions */
};
#define BHND_CHIP_MATCH_ANY \
{ .match_any = 1 }
#define BHND_CHIP_MATCH_IS_ANY(_m) \
((_m)->match_any == 1)
#define BHND_CHIP_MATCH_REQ_BOARD_INFO(_m) \
((_m)->match_srom_rev || (_m)->match_bvendor || \
(_m)->match_btype || (_m)->match_brev)
/** Set the required chip ID within a bhnd_chip_match instance */
#define BHND_CHIP_ID(_cid) \
.match_id = 1, .chip_id = BHND_CHIPID_BCM ## _cid
/** Set the required chip revision range within a bhnd_chip_match instance */
#define BHND_CHIP_REV(_rev) \
.match_rev = 1, .chip_rev = BHND_ ## _rev
/** Set the required package ID within a bhnd_chip_match instance */
#define BHND_CHIP_PKG(_pkg) \
.match_pkg = 1, .chip_pkg = BHND_PKGID_BCM ## _pkg
/** Set the required board vendor within a bhnd_chip_match instance */
#define BHND_CHIP_BVENDOR(_vend) \
.match_bvendor = 1, .board_vendor = _vend
/** Set the required board type within a bhnd_chip_match instance */
#define BHND_CHIP_BTYPE(_btype) \
.match_btype = 1, .board_type = BHND_BOARD_ ## _btype
/** Set the required SROM revision range within a bhnd_chip_match instance */
#define BHND_CHIP_SROMREV(_rev) \
.match_srom_rev = 1, .board_srom_rev = BHND_ ## _rev
/** Set the required board revision range within a bhnd_chip_match instance */
#define BHND_CHIP_BREV(_rev) \
.match_brev = 1, .board_rev = BHND_ ## _rev
/** Set the required board vendor and type within a bhnd_chip_match instance */
#define BHND_CHIP_BVT(_vend, _type) \
BHND_CHIP_BVENDOR(_vend), BHND_CHIP_BTYPE(_type)
/** Set the required board vendor, type, and revision within a bhnd_chip_match
* instance */
#define BHND_CHIP_BVTR(_vend, _type, _rev) \
BHND_CHIP_BVT(_vend, _type), BHND_CHIP_BREV(_rev)
/** Set the required chip and package ID within a bhnd_chip_match instance */
#define BHND_CHIP_IP(_cid, _pkg) \
BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg)
/** Set the required chip ID, package ID, and revision within a bhnd_chip_match
* instance */
#define BHND_CHIP_IPR(_cid, _pkg, _rev) \
BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg), BHND_CHIP_REV(_rev)
/** Set the required chip ID and revision within a bhnd_chip_match
* instance */
#define BHND_CHIP_IR(_cid, _rev) \
BHND_CHIP_ID(_cid), BHND_CHIP_REV(_rev)
/**
* Chipset quirk table descriptor.
*/
struct bhnd_chip_quirk {
const struct bhnd_chip_match chip; /**< chip match descriptor */
uint32_t quirks; /**< quirk flags */
};
#define BHND_CHIP_QUIRK_END { BHND_CHIP_MATCH_ANY, 0 }
#define BHND_CHIP_QUIRK_IS_END(_q) \
(BHND_CHIP_MATCH_IS_ANY(&(_q)->chip) && (_q)->quirks == 0)
/**
* Device quirk table descriptor.
*/
struct bhnd_device_quirk {
struct bhnd_hwrev_match hwrev; /**< applicable hardware revisions */
struct bhnd_device_match desc; /**< device match descriptor */
uint32_t quirks; /**< quirk flags */
};
#define BHND_DEVICE_QUIRK_END { BHND_HWREV_ANY, 0 }
#define BHND_CORE_QUIRK(_rev, _flags) \
{{ BHND_MATCH_CORE_REV(_rev) }, (_flags) }
#define BHND_CHIP_QUIRK(_chip, _rev, _flags) \
{{ BHND_CHIP_IR(BCM ## _chip, _rev) }, (_flags) }
#define BHND_PKG_QUIRK(_chip, _pkg, _flags) \
{{ BHND_CHIP_IP(BCM ## _chip, BCM ## _chip ## _pkg) }, (_flags) }
#define BHND_BOARD_QUIRK(_board, _flags) \
{{ BHND_MATCH_BOARD_TYPE(_board) }, \
(_flags) }
#define BHND_DEVICE_QUIRK_END { { BHND_MATCH_ANY }, 0 }
#define BHND_DEVICE_QUIRK_IS_END(_q) \
(BHND_HWREV_IS_ANY(&(_q)->hwrev) && (_q)->quirks == 0)
(((_q)->desc.m.match_flags == 0) && (_q)->quirks == 0)
enum {
BHND_DF_ANY = 0,
BHND_DF_HOSTB = (1<<0) /**< core is serving as the bus'
* host bridge */
BHND_DF_HOSTB = (1<<0), /**< core is serving as the bus' host
* bridge. implies BHND_DF_ADAPTER */
BHND_DF_SOC = (1<<1), /**< core is attached to a native
bus (BHND_ATTACH_NATIVE) */
BHND_DF_ADAPTER = (1<<2), /**< core is attached to a bridged
* adapter (BHND_ATTACH_ADAPTER) */
};
/** Device probe table descriptor */
struct bhnd_device {
const struct bhnd_core_match core; /**< core match descriptor */
const char *desc; /**< device description, or NULL. */
const struct bhnd_device_quirk *quirks_table; /**< quirks table for this device, or NULL */
const struct bhnd_chip_quirk *chip_quirks_table; /**< chipset-specific quirks for this device, or NULL */
uint32_t device_flags; /**< required BHND_DF_* flags */
const struct bhnd_device_match core; /**< core match descriptor */
const char *desc; /**< device description, or NULL. */
const struct bhnd_device_quirk *quirks_table; /**< quirks table for this device, or NULL */
uint32_t device_flags; /**< required BHND_DF_* flags */
};
#define _BHND_DEVICE(_vendor, _device, _desc, _quirks, _chip_quirks, \
_flags, ...) \
{ BHND_CORE_MATCH(BHND_MFGID_ ## _vendor, \
BHND_COREID_ ## _device, BHND_HWREV_ANY), _desc, _quirks, \
_chip_quirks, _flags }
#define _BHND_DEVICE(_vendor, _device, _desc, _quirks, \
_flags, ...) \
{ { BHND_MATCH_CORE(BHND_MFGID_ ## _vendor, \
BHND_COREID_ ## _device) }, _desc, _quirks, \
_flags }
#define BHND_MIPS_DEVICE(_device, _desc, _quirks, _chip_quirks, ...) \
_BHND_DEVICE(MIPS, _device, _desc, _quirks, _chip_quirks, \
#define BHND_MIPS_DEVICE(_device, _desc, _quirks, ...) \
_BHND_DEVICE(MIPS, _device, _desc, _quirks, \
## __VA_ARGS__, 0)
#define BHND_ARM_DEVICE(_device, _desc, _quirks, _chip_quirks, ...) \
_BHND_DEVICE(ARM, _device, _desc, _quirks, _chip_quirks, \
#define BHND_ARM_DEVICE(_device, _desc, _quirks, ...) \
_BHND_DEVICE(ARM, _device, _desc, _quirks, \
## __VA_ARGS__, 0)
#define BHND_DEVICE(_device, _desc, _quirks, _chip_quirks, ...) \
_BHND_DEVICE(BCM, _device, _desc, _quirks, _chip_quirks, \
#define BHND_DEVICE(_device, _desc, _quirks, ...) \
_BHND_DEVICE(BCM, _device, _desc, _quirks, \
## __VA_ARGS__, 0)
#define BHND_DEVICE_END { BHND_CORE_MATCH_ANY, NULL, NULL, NULL, 0 }
#define BHND_DEVICE_END { { BHND_MATCH_ANY }, NULL, NULL, 0 }
#define BHND_DEVICE_IS_END(_d) \
(BHND_MATCH_IS_ANY(&(_d)->core) && (_d)->desc == NULL)
const char *bhnd_vendor_name(uint16_t vendor);
const char *bhnd_port_type_name(bhnd_port_type port_type);
@ -447,17 +284,17 @@ bool bhnd_core_matches(
bool bhnd_chip_matches(
const struct bhnd_chipid *chipid,
const struct bhnd_board_info *binfo,
const struct bhnd_chip_match *desc);
bool bhnd_board_matches(
const struct bhnd_board_info *info,
const struct bhnd_board_match *desc);
bool bhnd_hwrev_matches(uint16_t hwrev,
const struct bhnd_hwrev_match *desc);
uint32_t bhnd_chip_quirks(device_t dev,
const struct bhnd_chip_quirk *table);
bool bhnd_device_matches(device_t dev,
const struct bhnd_core_match *desc);
const struct bhnd_device_match *desc);
const struct bhnd_device *bhnd_device_lookup(device_t dev,
const struct bhnd_device *table,
@ -469,7 +306,6 @@ uint32_t bhnd_device_quirks(device_t dev,
struct bhnd_core_info bhnd_get_core_info(device_t dev);
int bhnd_alloc_resources(device_t dev,
struct resource_spec *rs,
struct bhnd_resource **res);

291
sys/dev/bhnd/bhnd_match.h Normal file
View File

@ -0,0 +1,291 @@
/*-
* Copyright (c) 2015-2016 Landon Fuller <landon@landonf.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,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $FreeBSD$
*/
#ifndef _BHND_BHND_MATCH_H_
#define _BHND_BHND_MATCH_H_
#include "bhnd_types.h"
/**
* A hardware revision match descriptor.
*/
struct bhnd_hwrev_match {
uint16_t start; /**< first revision, or BHND_HWREV_INVALID
to match on any revision. */
uint16_t end; /**< last revision, or BHND_HWREV_INVALID
to match on any revision. */
};
/* Copy match field @p _name from @p _src */
#define _BHND_COPY_MATCH_FIELD(_src, _name) \
.m.match._name = (_src)->m.match._name, \
._name = (_src)->_name
/* Set match field @p _name with @p _value */
#define _BHND_SET_MATCH_FIELD(_name, _value) \
.m.match._name = 1, ._name = _value
/**
* Wildcard hardware revision match descriptor.
*/
#define BHND_HWREV_ANY { BHND_HWREV_INVALID, BHND_HWREV_INVALID }
#define BHND_HWREV_IS_ANY(_m) \
((_m)->start == BHND_HWREV_INVALID && (_m)->end == BHND_HWREV_INVALID)
/**
* Hardware revision match descriptor for an inclusive range.
*
* @param _start The first applicable hardware revision.
* @param _end The last applicable hardware revision, or BHND_HWREV_INVALID
* to match on any revision.
*/
#define BHND_HWREV_RANGE(_start, _end) { _start, _end }
/**
* Hardware revision match descriptor for a single revision.
*
* @param _hwrev The hardware revision to match on.
*/
#define BHND_HWREV_EQ(_hwrev) BHND_HWREV_RANGE(_hwrev, _hwrev)
/**
* Hardware revision match descriptor for any revision equal to or greater
* than @p _start.
*
* @param _start The first hardware revision to match on.
*/
#define BHND_HWREV_GTE(_start) BHND_HWREV_RANGE(_start, BHND_HWREV_INVALID)
/**
* Hardware revision match descriptor for any revision equal to or less
* than @p _end.
*
* @param _end The last hardware revision to match on.
*/
#define BHND_HWREV_LTE(_end) BHND_HWREV_RANGE(0, _end)
/**
* A bhnd(4) core match descriptor.
*/
struct bhnd_core_match {
/** Select fields to be matched */
union {
uint8_t match_flags;
struct {
uint8_t
core_vendor:1,
core_id:1,
core_rev:1,
core_class:1,
core_unit:1,
flags_unused:3;
} match;
} m;
uint16_t core_vendor; /**< required JEP106 device vendor */
uint16_t core_id; /**< required core ID */
struct bhnd_hwrev_match core_rev; /**< matching core revisions. */
bhnd_devclass_t core_class; /**< required bhnd class */
int core_unit; /**< required core unit */
};
#define _BHND_CORE_MATCH_COPY(_src) \
_BHND_COPY_MATCH_FIELD(_src, core_vendor), \
_BHND_COPY_MATCH_FIELD(_src, core_id), \
_BHND_COPY_MATCH_FIELD(_src, core_rev), \
_BHND_COPY_MATCH_FIELD(_src, core_class), \
_BHND_COPY_MATCH_FIELD(_src, core_unit) \
#define BHND_MATCH_CORE_VENDOR(_v) _BHND_SET_MATCH_FIELD(core_vendor, _v)
#define BHND_MATCH_CORE_ID(_id) _BHND_SET_MATCH_FIELD(core_id, _id)
#define BHND_MATCH_CORE_REV(_rev) _BHND_SET_MATCH_FIELD(core_rev, \
BHND_ ## _rev)
#define BHND_MATCH_CORE_CLASS(_cls) _BHND_SET_MATCH_FIELD(core_class, _cls)
#define BHND_MATCH_CORE_UNIT(_unit) _BHND_SET_MATCH_FIELD(core_unit, _unit)
/**
* Match against the given @p _vendor and @p _id,
*/
#define BHND_MATCH_CORE(_vendor, _id) \
BHND_MATCH_CORE_VENDOR(_vendor), \
BHND_MATCH_CORE_ID(_id)
/**
* A bhnd(4) chip match descriptor.
*/
struct bhnd_chip_match {
/** Select fields to be matched */
union {
uint8_t match_flags;
struct {
uint8_t
chip_id:1,
chip_rev:1,
chip_pkg:1,
flags_unused:5;
} match;
} m;
uint16_t chip_id; /**< required chip id */
struct bhnd_hwrev_match chip_rev; /**< matching chip revisions */
uint8_t chip_pkg; /**< required package */
};
#define _BHND_CHIP_MATCH_COPY(_src) \
_BHND_COPY_MATCH_FIELD(_src, chip_id), \
_BHND_COPY_MATCH_FIELD(_src, chip_rev), \
_BHND_COPY_MATCH_FIELD(_src, chip_pkg) \
/** Set the required chip ID within a bhnd match descriptor */
#define BHND_CHIP_ID(_cid) _BHND_SET_MATCH_FIELD(chip_id, \
BHND_CHIPID_ ## _cid)
/** Set the required chip revision range within a bhnd match descriptor */
#define BHND_CHIP_REV(_rev) _BHND_SET_MATCH_FIELD(chip_rev, \
BHND_ ## _rev)
/** Set the required package ID within a bhnd match descriptor */
#define BHND_CHIP_PKG(_pkg) _BHND_SET_MATCH_FIELD(chip_pkg, \
BHND_PKGID_ ## _pkg)
/** Set the required chip and package ID within a bhnd match descriptor */
#define BHND_CHIP_IP(_cid, _pkg) \
BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg)
/** Set the required chip ID, package ID, and revision within a bhnd_device_match
* instance */
#define BHND_CHIP_IPR(_cid, _pkg, _rev) \
BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg), BHND_CHIP_REV(_rev)
/** Set the required chip ID and revision within a bhnd_device_match
* instance */
#define BHND_CHIP_IR(_cid, _rev) \
BHND_CHIP_ID(_cid), BHND_CHIP_REV(_rev)
/**
* A bhnd(4) board match descriptor.
*/
struct bhnd_board_match {
/** Select fields to be matched */
union {
uint8_t match_flags;
struct {
uint8_t
board_vendor:1,
board_type:1,
board_rev:1,
board_srom_rev:1,
flags_unused:4;
} match;
} m;
uint16_t board_vendor; /**< required board vendor */
uint16_t board_type; /**< required board type */
struct bhnd_hwrev_match board_rev; /**< matching board revisions */
struct bhnd_hwrev_match board_srom_rev; /**< matching board srom revisions */
};
#define _BHND_BOARD_MATCH_COPY(_src) \
_BHND_COPY_MATCH_FIELD(_src, board_vendor), \
_BHND_COPY_MATCH_FIELD(_src, board_type), \
_BHND_COPY_MATCH_FIELD(_src, board_rev), \
_BHND_COPY_MATCH_FIELD(_src, board_srom_rev)
/** Set the required board vendor within a bhnd match descriptor */
#define BHND_MATCH_BOARD_VENDOR(_v) _BHND_SET_MATCH_FIELD(board_vendor, _v)
/** Set the required board type within a bhnd match descriptor */
#define BHND_MATCH_BOARD_TYPE(_type) _BHND_SET_MATCH_FIELD(board_type, \
BHND_BOARD_ ## _type)
/** Set the required SROM revision range within a bhnd match descriptor */
#define BHND_MATCH_SROMREV(_rev) _BHND_SET_MATCH_FIELD(board_srom_rev, \
BHND_HWREV_ ## _rev)
/** Set the required board revision range within a bhnd match descriptor */
#define BHND_MATCH_BOARD_REV(_rev) _BHND_SET_MATCH_FIELD(board_rev, \
BHND_ ## _rev)
/** Set the required board vendor and type within a bhnd match descriptor */
#define BHND_MATCH_BOARD(_vend, _type) \
BHND_MATCH_BOARD_VENDOR(_vend), BHND_MATCH_BOARD_TYPE(_type)
/**
* A bhnd(4) device match descriptor.
*
* @warning Matching on board attributes relies on NVRAM access, and will
* fail if a valid NVRAM device cannot be found, or is not yet attached.
*/
struct bhnd_device_match {
/** Select fields to be matched */
union {
uint16_t match_flags;
struct {
uint16_t
core_vendor:1,
core_id:1,
core_rev:1,
core_class:1,
core_unit:1,
chip_id:1,
chip_rev:1,
chip_pkg:1,
board_vendor:1,
board_type:1,
board_rev:1,
board_srom_rev:1,
flags_unused:2;
} match;
} m;
uint16_t core_vendor; /**< required JEP106 device vendor */
uint16_t core_id; /**< required core ID */
struct bhnd_hwrev_match core_rev; /**< matching core revisions. */
bhnd_devclass_t core_class; /**< required bhnd class */
int core_unit; /**< required core unit */
uint16_t chip_id; /**< required chip id */
struct bhnd_hwrev_match chip_rev; /**< matching chip revisions */
uint8_t chip_pkg; /**< required package */
uint16_t board_vendor; /**< required board vendor */
uint16_t board_type; /**< required board type */
struct bhnd_hwrev_match board_rev; /**< matching board revisions */
struct bhnd_hwrev_match board_srom_rev; /**< matching board srom revisions */
};
/** Define a wildcard match requirement (matches on any device). */
#define BHND_MATCH_ANY .m.match_flags = 0
#define BHND_MATCH_IS_ANY(_m) \
((_m)->m.match_flags == 0)
#endif /* _BHND_BHND_MATCH_H_ */

View File

@ -303,14 +303,13 @@ device_t
bhnd_find_child(device_t dev, bhnd_devclass_t class, int unit)
{
struct bhnd_core_match md = {
.vendor = BHND_MFGID_INVALID,
.device = BHND_COREID_INVALID,
.hwrev.start = BHND_HWREV_INVALID,
.hwrev.end = BHND_HWREV_INVALID,
.class = class,
.unit = unit
BHND_MATCH_CORE_CLASS(class),
BHND_MATCH_CORE_UNIT(unit)
};
if (unit == -1)
md.m.match.core_unit = 0;
return bhnd_match_child(dev, &md);
}
@ -337,9 +336,10 @@ bhnd_match_child(device_t dev, const struct bhnd_core_match *desc)
match = NULL;
for (int i = 0; i < devcnt; i++) {
device_t dev = devlistp[i];
if (bhnd_device_matches(dev, desc)) {
match = dev;
struct bhnd_core_info ci = bhnd_get_core_info(devlistp[i]);
if (bhnd_core_matches(&ci, desc)) {
match = devlistp[i];
goto done;
}
}
@ -437,12 +437,7 @@ bhnd_find_core(const struct bhnd_core_info *cores, u_int num_cores,
bhnd_devclass_t class)
{
struct bhnd_core_match md = {
.vendor = BHND_MFGID_INVALID,
.device = BHND_COREID_INVALID,
.hwrev.start = BHND_HWREV_INVALID,
.hwrev.end = BHND_HWREV_INVALID,
.class = class,
.unit = -1
BHND_MATCH_CORE_CLASS(class)
};
return bhnd_match_core(cores, num_cores, &md);
@ -461,22 +456,21 @@ bool
bhnd_core_matches(const struct bhnd_core_info *core,
const struct bhnd_core_match *desc)
{
if (desc->vendor != BHND_MFGID_INVALID &&
desc->vendor != core->vendor)
if (desc->m.match.core_vendor && desc->core_vendor != core->vendor)
return (false);
if (desc->device != BHND_COREID_INVALID &&
desc->device != core->device)
if (desc->m.match.core_id && desc->core_id != core->device)
return (false);
if (desc->unit != -1 && desc->unit != core->unit)
if (desc->m.match.core_unit && desc->core_unit != core->unit)
return (false);
if (!bhnd_hwrev_matches(core->hwrev, &desc->hwrev))
if (desc->m.match.core_rev &&
!bhnd_hwrev_matches(core->hwrev, &desc->core_rev))
return (false);
if (desc->class != BHND_DEVCLASS_INVALID &&
desc->class != bhnd_core_class(core))
if (desc->m.match.core_class &&
desc->core_class != bhnd_core_class(core))
return (false);
return true;
@ -486,7 +480,6 @@ bhnd_core_matches(const struct bhnd_core_info *core,
* Return true if the @p chip matches @p desc.
*
* @param chip A bhnd chip identifier.
* @param board The bhnd board info, or NULL if unavailable.
* @param desc A match descriptor to compare against @p chip.
*
* @retval true if @p chip matches @p match
@ -494,46 +487,49 @@ bhnd_core_matches(const struct bhnd_core_info *core,
*/
bool
bhnd_chip_matches(const struct bhnd_chipid *chip,
const struct bhnd_board_info *board,
const struct bhnd_chip_match *desc)
{
/* Explicit wildcard match */
if (desc->match_any)
return (true);
/* If board_info is missing, but required, we cannot match. */
if (BHND_CHIP_MATCH_REQ_BOARD_INFO(desc) && board == NULL)
if (desc->m.match.chip_id && chip->chip_id != desc->chip_id)
return (false);
/* Chip matching */
if (desc->match_id && chip->chip_id != desc->chip_id)
if (desc->m.match.chip_pkg && chip->chip_pkg != desc->chip_pkg)
return (false);
if (desc->match_pkg && chip->chip_pkg != desc->chip_pkg)
return (false);
if (desc->match_rev &&
if (desc->m.match.chip_rev &&
!bhnd_hwrev_matches(chip->chip_rev, &desc->chip_rev))
return (false);
return (true);
}
/* Board info matching */
if (desc->match_srom_rev &&
/**
* Return true if the @p board matches @p desc.
*
* @param board The bhnd board info.
* @param desc A match descriptor to compare against @p board.
*
* @retval true if @p chip matches @p match
* @retval false if @p chip does not match @p match.
*/
bool
bhnd_board_matches(const struct bhnd_board_info *board,
const struct bhnd_board_match *desc)
{
if (desc->m.match.board_srom_rev &&
!bhnd_hwrev_matches(board->board_srom_rev, &desc->board_srom_rev))
return (false);
if (desc->match_bvendor && board->board_vendor != desc->board_vendor)
if (desc->m.match.board_vendor &&
board->board_vendor != desc->board_vendor)
return (false);
if (desc->match_btype && board->board_type != desc->board_type)
if (desc->m.match.board_type && board->board_type != desc->board_type)
return (false);
if (desc->match_brev &&
if (desc->m.match.board_rev &&
!bhnd_hwrev_matches(board->board_rev, &desc->board_rev))
return (false);
return (true);
}
@ -570,16 +566,59 @@ bhnd_hwrev_matches(uint16_t hwrev, const struct bhnd_hwrev_match *desc)
* @retval false if @p dev does not match @p match.
*/
bool
bhnd_device_matches(device_t dev, const struct bhnd_core_match *desc)
bhnd_device_matches(device_t dev, const struct bhnd_device_match *desc)
{
struct bhnd_core_info ci = {
.vendor = bhnd_get_vendor(dev),
.device = bhnd_get_device(dev),
.unit = bhnd_get_core_unit(dev),
.hwrev = bhnd_get_hwrev(dev)
};
struct bhnd_core_info core;
const struct bhnd_chipid *chip;
struct bhnd_board_info board;
device_t parent;
int error;
return bhnd_core_matches(&ci, desc);
/* Construct individual match descriptors */
struct bhnd_core_match m_core = { _BHND_CORE_MATCH_COPY(desc) };
struct bhnd_chip_match m_chip = { _BHND_CHIP_MATCH_COPY(desc) };
struct bhnd_board_match m_board = { _BHND_BOARD_MATCH_COPY(desc) };
/* Fetch and match core info */
if (m_core.m.match_flags) {
/* Only applicable to bhnd-attached cores */
parent = device_get_parent(dev);
if (device_get_devclass(parent) != bhnd_devclass) {
device_printf(dev, "attempting to match core "
"attributes against non-core device\n");
return (false);
}
core = bhnd_get_core_info(dev);
if (!bhnd_core_matches(&core, &m_core))
return (false);
}
/* Fetch and match chip info */
if (m_chip.m.match_flags) {
chip = bhnd_get_chipid(dev);
if (!bhnd_chip_matches(chip, &m_chip))
return (false);
}
/* Fetch and match board info.
*
* This is not available until after NVRAM is up; earlier device
* matches should not include board requirements */
if (m_board.m.match_flags) {
if ((error = bhnd_read_board_info(dev, &board))) {
device_printf(dev, "failed to read required board info "
"during device matching: %d\n", error);
return (false);
}
if (!bhnd_board_matches(&board, &m_board))
return (false);
}
/* All matched */
return (true);
}
/**
@ -598,11 +637,14 @@ bhnd_device_lookup(device_t dev, const struct bhnd_device *table,
{
const struct bhnd_device *entry;
device_t hostb, parent;
bhnd_attach_type attach_type;
uint32_t dflags;
parent = device_get_parent(dev);
hostb = bhnd_find_hostb_device(parent);
attach_type = bhnd_get_attach_type(dev);
for (entry = table; entry->desc != NULL; entry =
for (entry = table; !BHND_DEVICE_IS_END(entry); entry =
(const struct bhnd_device *) ((const char *) entry + entry_size))
{
/* match core info */
@ -610,10 +652,23 @@ bhnd_device_lookup(device_t dev, const struct bhnd_device *table,
continue;
/* match device flags */
if (entry->device_flags & BHND_DF_HOSTB) {
dflags = entry->device_flags;
/* hostb implies BHND_ATTACH_ADAPTER requirement */
if (dflags & BHND_DF_HOSTB)
dflags |= BHND_DF_ADAPTER;
if (dflags & BHND_DF_ADAPTER)
if (attach_type != BHND_ATTACH_ADAPTER)
continue;
if (dflags & BHND_DF_HOSTB)
if (dev != hostb)
continue;
}
if (dflags & BHND_DF_SOC)
if (attach_type != BHND_ATTACH_NATIVE)
continue;
/* device found */
return (entry);
@ -624,66 +679,10 @@ bhnd_device_lookup(device_t dev, const struct bhnd_device *table,
}
/**
* Scan @p table for all quirk flags applicable to @p dev's chip identifier
* (as returned by bhnd_get_chipid).
*
* @param dev A bhnd device.
* @param table The chip quirk table to search.
*
* @return returns all matching quirk flags.
*/
uint32_t
bhnd_chip_quirks(device_t dev, const struct bhnd_chip_quirk *table)
{
struct bhnd_board_info bi, *board;
const struct bhnd_chipid *cid;
const struct bhnd_chip_quirk *qent;
uint32_t quirks;
int error;
bool need_boardinfo;
cid = bhnd_get_chipid(dev);
quirks = 0;
need_boardinfo = 0;
board = NULL;
/* Determine whether quirk matching requires board_info; we want to
* avoid fetching board_info for early devices (e.g. ChipCommon)
* that are brought up prior to NVRAM being readable. */
for (qent = table; !BHND_CHIP_QUIRK_IS_END(qent); qent++) {
if (!BHND_CHIP_MATCH_REQ_BOARD_INFO(&qent->chip))
continue;
need_boardinfo = true;
break;
}
/* If required, fetch board info */
if (need_boardinfo) {
error = bhnd_read_board_info(dev, &bi);
if (!error) {
board = &bi;
} else {
device_printf(dev, "failed to read required board info "
"during quirk matching: %d\n", error);
}
}
/* Apply all matching quirk flags */
for (qent = table; !BHND_CHIP_QUIRK_IS_END(qent); qent++) {
if (bhnd_chip_matches(cid, board, &qent->chip))
quirks |= qent->quirks;
}
return (quirks);
}
/**
* Scan @p table for all quirk flags applicable to @p dev.
* Scan the device @p table for all quirk flags applicable to @p dev.
*
* @param dev A bhnd device to match against @p table.
* @param table The device table to search.
* @param entry_size The @p table entry size, in bytes.
*
* @return returns all matching quirk flags.
*/
@ -692,32 +691,25 @@ bhnd_device_quirks(device_t dev, const struct bhnd_device *table,
size_t entry_size)
{
const struct bhnd_device *dent;
const struct bhnd_device_quirk *qtable, *qent;
const struct bhnd_device_quirk *qent, *qtable;
uint32_t quirks;
uint16_t hwrev;
hwrev = bhnd_get_hwrev(dev);
quirks = 0;
/* Find the quirk table */
if ((dent = bhnd_device_lookup(dev, table, entry_size)) == NULL) {
/* This is almost certainly a (caller) implementation bug */
device_printf(dev, "quirk lookup did not match any device\n");
/* Locate the device entry */
if ((dent = bhnd_device_lookup(dev, table, entry_size)) == NULL)
return (0);
/* Quirks table is optional */
qtable = dent->quirks_table;
if (qtable == NULL)
return (0);
}
/* Collect matching device quirk entries */
if ((qtable = dent->quirks_table) != NULL) {
for (qent = qtable; !BHND_DEVICE_QUIRK_IS_END(qent); qent++) {
if (bhnd_hwrev_matches(hwrev, &qent->hwrev))
quirks |= qent->quirks;
}
quirks = 0;
for (qent = qtable; !BHND_DEVICE_QUIRK_IS_END(qent); qent++) {
if (bhnd_device_matches(dev, &qent->desc))
quirks |= qent->quirks;
}
/* Collect matching chip quirk entries */
if (dent->chip_quirks_table != NULL)
quirks |= bhnd_chip_quirks(dev, dent->chip_quirks_table);
return (quirks);
}

View File

@ -194,13 +194,15 @@ bhndb_hw_matches(device_t *devlist, int num_devs, const struct bhndb_hw *hw)
{
for (u_int i = 0; i < hw->num_hw_reqs; i++) {
const struct bhnd_core_match *match;
struct bhnd_core_info ci;
bool found;
match = &hw->hw_reqs[i];
found = false;
for (int d = 0; d < num_devs; d++) {
if (!bhnd_device_matches(devlist[d], match))
ci = bhnd_get_core_info(devlist[d]);
if (!bhnd_core_matches(&ci, match))
continue;
found = true;
@ -986,20 +988,17 @@ compare_core_index(const void *lhs, const void *rhs)
static device_t
bhndb_find_hostb_device(device_t dev, device_t child)
{
struct bhndb_softc *sc;
struct bhnd_core_match md;
device_t hostb_dev, *devlist;
int devcnt, error;
struct bhndb_softc *sc;
struct bhnd_device_match md;
device_t hostb_dev, *devlist;
int devcnt, error;
sc = device_get_softc(dev);
/* Determine required device class and set up a match descriptor. */
md = (struct bhnd_core_match) {
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_INVALID,
.hwrev = { BHND_HWREV_INVALID, BHND_HWREV_INVALID },
.class = sc->bridge_class,
.unit = 0
/* Set up a match descriptor for the required device class. */
md = (struct bhnd_device_match) {
BHND_MATCH_CORE_CLASS(sc->bridge_class),
BHND_MATCH_CORE_UNIT(0)
};
/* Must be the absolute first matching device on the bus. */

View File

@ -55,26 +55,27 @@ __FBSDID("$FreeBSD$");
}
/*
* Define a core priority record for all cores matching @p devclass and
* @p unit.
*
* If a devclass of BHNDB_DEVCLASS_INVALID is specified, this will match
* on all device classes.
*
* If a unit number of -1 is specified, this will match on all units.
* Define a core priority record for all cores matching @p devclass
*/
#define BHNDB_CLASS_PRIO(_devclass, _unit, _priority, ...) { \
#define BHNDB_CLASS_PRIO(_devclass, _priority, ...) { \
.match = { \
.vendor = BHND_MFGID_INVALID, \
.device = BHND_COREID_INVALID, \
.hwrev = { BHND_HWREV_INVALID, BHND_HWREV_INVALID }, \
.class = (BHND_DEVCLASS_ ## _devclass), \
.unit = (_unit) \
BHND_MATCH_CORE_CLASS(BHND_DEVCLASS_ ## _devclass), \
}, \
.priority = (BHNDB_PRIORITY_ ## _priority), \
BHNDB_PORTS(__VA_ARGS__) \
}
/*
* Define a default core priority record
*/
#define BHNDB_DEFAULT_PRIO(...) { \
.match = { \
BHND_MATCH_ANY , \
}, \
.priority = (BHNDB_PRIORITY_DEFAULT), \
BHNDB_PORTS(__VA_ARGS__) \
}
/* Define a port priority record for the type/port/region
* triplet. */
#define BHNDB_PORT_PRIO(_type, _port, _region, _priority) { \
@ -100,10 +101,10 @@ const struct bhndb_hw_priority bhndb_bcma_priority_table[] = {
* Runtime access to these cores is not required, and no register
* windows should be reserved for these device types.
*/
BHNDB_CLASS_PRIO(SOC_ROUTER, -1, NONE),
BHNDB_CLASS_PRIO(SOC_BRIDGE, -1, NONE),
BHNDB_CLASS_PRIO(EROM, -1, NONE),
BHNDB_CLASS_PRIO(OTHER, -1, NONE),
BHNDB_CLASS_PRIO(SOC_ROUTER, NONE),
BHNDB_CLASS_PRIO(SOC_BRIDGE, NONE),
BHNDB_CLASS_PRIO(EROM, NONE),
BHNDB_CLASS_PRIO(OTHER, NONE),
/*
* Low priority device classes.
@ -111,7 +112,7 @@ const struct bhndb_hw_priority bhndb_bcma_priority_table[] = {
* These devices do not sit in a performance-critical path and can be
* treated as a low allocation priority.
*/
BHNDB_CLASS_PRIO(CC, -1, LOW,
BHNDB_CLASS_PRIO(CC, LOW,
/* Device Block */
BHNDB_PORT0_PRIO(DEVICE, LOW),
@ -119,7 +120,7 @@ const struct bhndb_hw_priority bhndb_bcma_priority_table[] = {
BHNDB_PORT0_PRIO(AGENT, NONE)
),
BHNDB_CLASS_PRIO(PMU, -1, LOW,
BHNDB_CLASS_PRIO(PMU, LOW,
/* Device Block */
BHNDB_PORT0_PRIO(DEVICE, LOW),
@ -133,7 +134,7 @@ const struct bhndb_hw_priority bhndb_bcma_priority_table[] = {
* All other cores are assumed to require efficient runtime access to
* the default device port, and if supported by the bus, an agent port.
*/
BHNDB_CLASS_PRIO(INVALID, -1, DEFAULT,
BHNDB_DEFAULT_PRIO(
/* Device Block */
BHNDB_PORT0_PRIO(DEVICE, HIGH),
@ -155,10 +156,10 @@ const struct bhndb_hw_priority bhndb_siba_priority_table[] = {
* Runtime access to these cores is not required, and no register
* windows should be reserved for these device types.
*/
BHNDB_CLASS_PRIO(SOC_ROUTER, -1, NONE),
BHNDB_CLASS_PRIO(SOC_BRIDGE, -1, NONE),
BHNDB_CLASS_PRIO(EROM, -1, NONE),
BHNDB_CLASS_PRIO(OTHER, -1, NONE),
BHNDB_CLASS_PRIO(SOC_ROUTER, NONE),
BHNDB_CLASS_PRIO(SOC_BRIDGE, NONE),
BHNDB_CLASS_PRIO(EROM, NONE),
BHNDB_CLASS_PRIO(OTHER, NONE),
/*
* Low priority device classes.
@ -170,12 +171,12 @@ const struct bhndb_hw_priority bhndb_siba_priority_table[] = {
* will be fully mappable via register windows shared with the
* device0.0 port.
*/
BHNDB_CLASS_PRIO(CC, -1, LOW,
BHNDB_CLASS_PRIO(CC, LOW,
/* Device Block */
BHNDB_PORT_PRIO(DEVICE, 0, 0, LOW)
),
BHNDB_CLASS_PRIO(PMU, -1, LOW,
BHNDB_CLASS_PRIO(PMU, LOW,
/* Device Block */
BHNDB_PORT_PRIO(DEVICE, 0, 0, LOW)
),
@ -186,7 +187,7 @@ const struct bhndb_hw_priority bhndb_siba_priority_table[] = {
* All other cores are assumed to require efficient runtime access to
* the device port.
*/
BHNDB_CLASS_PRIO(INVALID, -1, DEFAULT,
BHNDB_DEFAULT_PRIO(
/* Device Block */
BHNDB_PORT_PRIO(DEVICE, 0, 0, HIGH)
),

View File

@ -157,26 +157,19 @@ const struct bhndb_hw bhndb_pci_generic_hw_table[] = {
BHNDB_HW_MATCH("PCI/v0 WLAN", v0,
/* PCI Core */
{
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_PCI,
.hwrev = {
.start = 0,
.end = BHNDB_PCI_V0_MAX_PCI_HWREV
},
.class = BHND_DEVCLASS_PCI,
.unit = 0
BHND_MATCH_CORE_VENDOR (BHND_MFGID_BCM),
BHND_MATCH_CORE_ID (BHND_COREID_PCI),
BHND_MATCH_CORE_REV(
HWREV_LTE (BHNDB_PCI_V0_MAX_PCI_HWREV)),
BHND_MATCH_CORE_CLASS (BHND_DEVCLASS_PCI),
BHND_MATCH_CORE_UNIT (0)
},
/* 802.11 Core */
{
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_INVALID,
.hwrev = {
.start = 0,
.end = BHND_HWREV_INVALID
},
.class = BHND_DEVCLASS_WLAN,
.unit = 0
BHND_MATCH_CORE_VENDOR (BHND_MFGID_BCM),
BHND_MATCH_CORE_CLASS (BHND_DEVCLASS_WLAN),
BHND_MATCH_CORE_UNIT (0)
}
),
@ -184,26 +177,19 @@ const struct bhndb_hw bhndb_pci_generic_hw_table[] = {
BHNDB_HW_MATCH("PCI/v1 WLAN", v1_pci,
/* PCI Core */
{
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_PCI,
.hwrev = {
.start = BHNDB_PCI_V1_MIN_PCI_HWREV,
.end = BHND_HWREV_INVALID
},
.class = BHND_DEVCLASS_PCI,
.unit = 0
BHND_MATCH_CORE_VENDOR (BHND_MFGID_BCM),
BHND_MATCH_CORE_ID (BHND_COREID_PCI),
BHND_MATCH_CORE_REV(
HWREV_GTE (BHNDB_PCI_V1_MIN_PCI_HWREV)),
BHND_MATCH_CORE_CLASS (BHND_DEVCLASS_PCI),
BHND_MATCH_CORE_UNIT (0)
},
/* 802.11 Core */
{
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_INVALID,
.hwrev = {
.start = 0,
.end = BHND_HWREV_INVALID
},
.class = BHND_DEVCLASS_WLAN,
.unit = 0
BHND_MATCH_CORE_VENDOR (BHND_MFGID_BCM),
BHND_MATCH_CORE_CLASS (BHND_DEVCLASS_WLAN),
BHND_MATCH_CORE_UNIT (0)
}
),
@ -211,38 +197,27 @@ const struct bhndb_hw bhndb_pci_generic_hw_table[] = {
BHNDB_HW_MATCH("PCIe/v1 WLAN", v1_pcie,
/* PCIe Core */
{
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_PCIE,
.hwrev = {
.start = 0,
.end = BHND_HWREV_INVALID
},
.class = BHND_DEVCLASS_PCIE,
.unit = 0
BHND_MATCH_CORE_VENDOR (BHND_MFGID_BCM),
BHND_MATCH_CORE_ID (BHND_COREID_PCIE),
BHND_MATCH_CORE_CLASS (BHND_DEVCLASS_PCIE),
BHND_MATCH_CORE_UNIT (0)
},
/* ChipCommon (revision <= 31) */
{
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_CC,
.hwrev = {
.start = 0,
.end = BHNDB_PCI_V1_MAX_CHIPC_HWREV
},
.class = BHND_DEVCLASS_CC,
.unit = 0
BHND_MATCH_CORE_VENDOR (BHND_MFGID_BCM),
BHND_MATCH_CORE_ID (BHND_COREID_CC),
BHND_MATCH_CORE_REV(
HWREV_LTE (BHNDB_PCI_V1_MAX_CHIPC_HWREV)),
BHND_MATCH_CORE_CLASS (BHND_DEVCLASS_CC),
BHND_MATCH_CORE_UNIT (0)
},
/* 802.11 Core */
{
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_INVALID,
.hwrev = {
.start = 0,
.end = BHND_HWREV_INVALID
},
.class = BHND_DEVCLASS_WLAN,
.unit = 0
BHND_MATCH_CORE_VENDOR (BHND_MFGID_BCM),
BHND_MATCH_CORE_CLASS (BHND_DEVCLASS_WLAN),
BHND_MATCH_CORE_UNIT (0)
}
),
@ -250,35 +225,27 @@ const struct bhndb_hw bhndb_pci_generic_hw_table[] = {
BHNDB_HW_MATCH("PCIe/v2 WLAN", v2,
/* PCIe Core */
{
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_PCIE,
.hwrev = { 0, BHND_HWREV_INVALID },
.class = BHND_DEVCLASS_PCIE,
.unit = 0
BHND_MATCH_CORE_VENDOR (BHND_MFGID_BCM),
BHND_MATCH_CORE_ID (BHND_COREID_PCIE),
BHND_MATCH_CORE_CLASS (BHND_DEVCLASS_PCIE),
BHND_MATCH_CORE_UNIT (0)
},
/* ChipCommon (revision >= 32) */
{
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_CC,
.hwrev = {
.start = BHNDB_PCI_V2_MIN_CHIPC_HWREV,
.end = BHND_HWREV_INVALID
},
.class = BHND_DEVCLASS_CC,
.unit = 0
BHND_MATCH_CORE_VENDOR (BHND_MFGID_BCM),
BHND_MATCH_CORE_ID (BHND_COREID_CC),
BHND_MATCH_CORE_REV(
HWREV_GTE (BHNDB_PCI_V2_MIN_CHIPC_HWREV)),
BHND_MATCH_CORE_CLASS (BHND_DEVCLASS_CC),
BHND_MATCH_CORE_UNIT (0)
},
/* 802.11 Core */
{
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_INVALID,
.hwrev = {
.start = 0,
.end = BHND_HWREV_INVALID
},
.class = BHND_DEVCLASS_WLAN,
.unit = 0
BHND_MATCH_CORE_VENDOR (BHND_MFGID_BCM),
BHND_MATCH_CORE_CLASS (BHND_DEVCLASS_WLAN),
BHND_MATCH_CORE_UNIT (0)
}
),
@ -287,26 +254,17 @@ const struct bhndb_hw bhndb_pci_generic_hw_table[] = {
BHNDB_HW_MATCH("PCIe-Gen2/v3 WLAN", v3,
/* PCIe Gen2 Core */
{
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_PCIE2,
.hwrev = {
.start = 0,
.end = BHND_HWREV_INVALID
},
.class = BHND_DEVCLASS_PCIE,
.unit = 0
BHND_MATCH_CORE_VENDOR (BHND_MFGID_BCM),
BHND_MATCH_CORE_ID (BHND_COREID_PCIE2),
BHND_MATCH_CORE_CLASS (BHND_DEVCLASS_PCIE),
BHND_MATCH_CORE_UNIT (0)
},
/* 802.11 Core */
{
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_INVALID,
.hwrev = {
.start = 0,
.end = BHND_HWREV_INVALID
},
.class = BHND_DEVCLASS_WLAN,
.unit = 0
BHND_MATCH_CORE_VENDOR (BHND_MFGID_BCM),
BHND_MATCH_CORE_CLASS (BHND_DEVCLASS_WLAN),
BHND_MATCH_CORE_UNIT (0)
}
),

View File

@ -1017,10 +1017,13 @@ const struct bhndb_hw_priority *
bhndb_hw_priority_find_device(const struct bhndb_hw_priority *table,
device_t device)
{
const struct bhndb_hw_priority *hp;
const struct bhndb_hw_priority *hp;
struct bhnd_core_info ci;
ci = bhnd_get_core_info(device);
for (hp = table; hp->ports != NULL; hp++) {
if (bhnd_device_matches(device, &hp->match))
if (bhnd_core_matches(&ci, &hp->match))
return (hp);
}

View File

@ -64,62 +64,40 @@ __FBSDID("$FreeBSD$");
devclass_t bhnd_chipc_devclass; /**< bhnd(4) chipcommon device class */
static struct bhnd_device_quirk chipc_quirks[];
static struct bhnd_chip_quirk chipc_chip_quirks[];
/* Supported device identifiers */
static const struct bhnd_device chipc_devices[] = {
BHND_DEVICE(CC, "CC", chipc_quirks, chipc_chip_quirks),
BHND_DEVICE(CC, NULL, chipc_quirks),
BHND_DEVICE_END
};
/* Device quirks table */
static struct bhnd_device_quirk chipc_quirks[] = {
{ BHND_HWREV_GTE (32), CHIPC_QUIRK_SUPPORTS_SPROM },
{ BHND_HWREV_GTE (35), CHIPC_QUIRK_SUPPORTS_CAP_EXT },
{ BHND_HWREV_EQ (38), CHIPC_QUIRK_4706_NFLASH }, /*BCM5357 ?*/
{ BHND_HWREV_GTE (49), CHIPC_QUIRK_IPX_OTPLAYOUT_SIZE },
/* core revision quirks */
BHND_CORE_QUIRK (HWREV_GTE(32), CHIPC_QUIRK_SUPPORTS_SPROM),
BHND_CORE_QUIRK (HWREV_GTE(35), CHIPC_QUIRK_SUPPORTS_CAP_EXT),
BHND_CORE_QUIRK (HWREV_GTE(49), CHIPC_QUIRK_IPX_OTPLAYOUT_SIZE),
/* 4706 variant quirks */
BHND_CORE_QUIRK (HWREV_EQ (38), CHIPC_QUIRK_4706_NFLASH), /* BCM5357? */
BHND_CHIP_QUIRK (4706, HWREV_ANY, CHIPC_QUIRK_4706_NFLASH),
/* 4331 quirks*/
BHND_CHIP_QUIRK (4331, HWREV_ANY, CHIPC_QUIRK_4331_EXTPA_MUX_SPROM),
BHND_PKG_QUIRK (4331, TN, CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM),
BHND_PKG_QUIRK (4331, TNA0, CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM),
BHND_PKG_QUIRK (4331, TT, CHIPC_QUIRK_4331_EXTPA2_MUX_SPROM),
/* 4360 quirks */
BHND_CHIP_QUIRK (4352, HWREV_LTE(2), CHIPC_QUIRK_4360_FEM_MUX_SPROM),
BHND_CHIP_QUIRK (43460, HWREV_LTE(2), CHIPC_QUIRK_4360_FEM_MUX_SPROM),
BHND_CHIP_QUIRK (43462, HWREV_LTE(2), CHIPC_QUIRK_4360_FEM_MUX_SPROM),
BHND_CHIP_QUIRK (43602, HWREV_LTE(2), CHIPC_QUIRK_4360_FEM_MUX_SPROM),
BHND_DEVICE_QUIRK_END
};
/* Chip-specific quirks table */
static struct bhnd_chip_quirk chipc_chip_quirks[] = {
/* 4331 12x9 packages */
{{ BHND_CHIP_IP(4331, 4331TN) },
CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM
},
{{ BHND_CHIP_IP(4331, 4331TNA0) },
CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM
},
/* 4331 12x12 packages */
{{ BHND_CHIP_IPR(4331, 4331TT, HWREV_GTE(1)) },
CHIPC_QUIRK_4331_EXTPA2_MUX_SPROM
},
/* 4331 (all packages/revisions) */
{{ BHND_CHIP_ID(4331) },
CHIPC_QUIRK_4331_EXTPA_MUX_SPROM
},
/* 4360 family (all revs <= 2) */
{{ BHND_CHIP_IR(4352, HWREV_LTE(2)) },
CHIPC_QUIRK_4360_FEM_MUX_SPROM },
{{ BHND_CHIP_IR(43460, HWREV_LTE(2)) },
CHIPC_QUIRK_4360_FEM_MUX_SPROM },
{{ BHND_CHIP_IR(43462, HWREV_LTE(2)) },
CHIPC_QUIRK_4360_FEM_MUX_SPROM },
{{ BHND_CHIP_IR(43602, HWREV_LTE(2)) },
CHIPC_QUIRK_4360_FEM_MUX_SPROM },
/* BCM4706 */
{{ BHND_CHIP_ID(4306) },
CHIPC_QUIRK_4706_NFLASH },
BHND_CHIP_QUIRK_END
};
static int chipc_try_activate_resource(
struct chipc_softc *sc, device_t child,
int type, int rid, struct resource *r,
@ -316,7 +294,7 @@ chipc_read_caps(struct chipc_softc *sc, struct chipc_caps *caps)
caps->otp_size = CHIPC_GET_BITS(regval, CHIPC_OTPL_SIZE);
}
/* Determine flash type and paramters */
/* Determine flash type and parameters */
caps->cfi_width = 0;
switch (CHIPC_GET_BITS(cap_reg, CHIPC_CAP_FLASH)) {

View File

@ -68,8 +68,8 @@ static struct bhnd_device_quirk bhnd_pcie_quirks[];
#define BHND_PCI_QUIRKS bhnd_pci_quirks
#define BHND_PCIE_QUIRKS bhnd_pcie_quirks
#define BHND_PCI_DEV(_core, _desc, ...) \
{ BHND_DEVICE(_core, _desc, BHND_ ## _core ## _QUIRKS, NULL, \
#define BHND_PCI_DEV(_core, _desc, ...) \
{ BHND_DEVICE(_core, _desc, BHND_ ## _core ## _QUIRKS, \
## __VA_ARGS__), BHND_PCI_REGFMT_ ## _core }
static const struct bhnd_pci_device {
@ -77,9 +77,9 @@ static const struct bhnd_pci_device {
bhnd_pci_regfmt_t regfmt; /**< register format */
} bhnd_pci_devs[] = {
BHND_PCI_DEV(PCI, "Host-PCI bridge", BHND_DF_HOSTB),
BHND_PCI_DEV(PCI, "PCI-BHND bridge"),
BHND_PCI_DEV(PCI, "PCI-BHND bridge", BHND_DF_SOC),
BHND_PCI_DEV(PCIE, "PCIe-G1 Host-PCI bridge", BHND_DF_HOSTB),
BHND_PCI_DEV(PCIE, "PCIe-G1 PCI-BHND bridge"),
BHND_PCI_DEV(PCIE, "PCIe-G1 PCI-BHND bridge", BHND_DF_SOC),
{ BHND_DEVICE_END, 0 }
};
@ -87,7 +87,8 @@ static const struct bhnd_pci_device {
/* Device quirks tables */
static struct bhnd_device_quirk bhnd_pci_quirks[] = { BHND_DEVICE_QUIRK_END };
static struct bhnd_device_quirk bhnd_pcie_quirks[] = {
{ BHND_HWREV_GTE (10), BHND_PCI_QUIRK_SD_C22_EXTADDR },
BHND_CORE_QUIRK(HWREV_GTE(10), BHND_PCI_QUIRK_SD_C22_EXTADDR),
BHND_DEVICE_QUIRK_END
};

View File

@ -67,8 +67,6 @@ __FBSDID("$FreeBSD$");
static const struct bhnd_device_quirk bhnd_pci_quirks[];
static const struct bhnd_device_quirk bhnd_pcie_quirks[];
static const struct bhnd_chip_quirk bhnd_pci_chip_quirks[];
static const struct bhnd_chip_quirk bhnd_pcie_chip_quirks[];
/* Device driver work-around variations */
typedef enum {
@ -88,88 +86,87 @@ static int bhnd_pci_wars_hwdown(struct bhnd_pcihb_softc *sc,
* device/quirk tables
*/
#define BHND_PCI_DEV(_core, _quirks, _chip_quirks) \
BHND_DEVICE(_core, "", _quirks, _chip_quirks, BHND_DF_HOSTB)
#define BHND_PCI_DEV(_core, _quirks) \
BHND_DEVICE(_core, NULL, _quirks, BHND_DF_HOSTB)
static const struct bhnd_device bhnd_pci_devs[] = {
BHND_PCI_DEV(PCI, bhnd_pci_quirks, bhnd_pci_chip_quirks),
BHND_PCI_DEV(PCIE, bhnd_pcie_quirks, bhnd_pcie_chip_quirks),
BHND_PCI_DEV(PCI, bhnd_pci_quirks),
BHND_PCI_DEV(PCIE, bhnd_pcie_quirks),
BHND_DEVICE_END
};
static const struct bhnd_device_quirk bhnd_pci_quirks[] = {
{ BHND_HWREV_ANY, BHND_PCI_QUIRK_SBTOPCI2_PREF_BURST },
{ BHND_HWREV_GTE(11), BHND_PCI_QUIRK_SBTOPCI2_READMULTI |
BHND_PCI_QUIRK_CLKRUN_DSBL },
BHND_DEVICE_QUIRK_END
};
/* core revision quirks */
BHND_CORE_QUIRK (HWREV_ANY, BHND_PCI_QUIRK_SBTOPCI2_PREF_BURST),
BHND_CORE_QUIRK (HWREV_GTE(11), BHND_PCI_QUIRK_SBTOPCI2_READMULTI |
BHND_PCI_QUIRK_CLKRUN_DSBL),
static const struct bhnd_chip_quirk bhnd_pci_chip_quirks[] = {
/* BCM4321CB2 boards that require 960ns latency timer override */
{{ BHND_CHIP_BTYPE(BCM4321CB2) },
BHND_PCI_QUIRK_960NS_LATTIM_OVR },
{{ BHND_CHIP_BTYPE(BCM4321CB2_AG) },
BHND_PCI_QUIRK_960NS_LATTIM_OVR },
BHND_BOARD_QUIRK(BCM4321CB2, BHND_PCI_QUIRK_960NS_LATTIM_OVR),
BHND_BOARD_QUIRK(BCM4321CB2_AG, BHND_PCI_QUIRK_960NS_LATTIM_OVR),
BHND_CHIP_QUIRK_END
BHND_DEVICE_QUIRK_END
};
static const struct bhnd_device_quirk bhnd_pcie_quirks[] = {
{ BHND_HWREV_EQ (0), BHND_PCIE_QUIRK_SDR9_L0s_HANG },
{ BHND_HWREV_RANGE (0,1), BHND_PCIE_QUIRK_UR_STATUS_FIX },
{ BHND_HWREV_EQ (1), BHND_PCIE_QUIRK_PCIPM_REQEN },
/* core revision quirks */
BHND_CORE_QUIRK (HWREV_EQ (0), BHND_PCIE_QUIRK_SDR9_L0s_HANG),
BHND_CORE_QUIRK (HWREV_RANGE(0,1),
BHND_PCIE_QUIRK_UR_STATUS_FIX),
{ BHND_HWREV_RANGE (3,5), BHND_PCIE_QUIRK_ASPM_OVR |
BHND_PCIE_QUIRK_SDR9_POLARITY |
BHND_PCIE_QUIRK_SDR9_NO_FREQRETRY },
BHND_CORE_QUIRK (HWREV_EQ (1), BHND_PCIE_QUIRK_PCIPM_REQEN),
{ BHND_HWREV_LTE (6), BHND_PCIE_QUIRK_L1_IDLE_THRESH },
{ BHND_HWREV_GTE (6), BHND_PCIE_QUIRK_SPROM_L23_PCI_RESET },
{ BHND_HWREV_EQ (7), BHND_PCIE_QUIRK_SERDES_NOPLLDOWN },
{ BHND_HWREV_GTE (8), BHND_PCIE_QUIRK_L1_TIMER_PERF },
BHND_CORE_QUIRK (HWREV_RANGE(3,5),
BHND_PCIE_QUIRK_ASPM_OVR | BHND_PCIE_QUIRK_SDR9_POLARITY |
BHND_PCIE_QUIRK_SDR9_NO_FREQRETRY),
{ BHND_HWREV_LTE (17), BHND_PCIE_QUIRK_MAX_MRRS_128 },
BHND_CORE_QUIRK (HWREV_LTE(6), BHND_PCIE_QUIRK_L1_IDLE_THRESH),
BHND_CORE_QUIRK (HWREV_GTE(6), BHND_PCIE_QUIRK_SPROM_L23_PCI_RESET),
BHND_CORE_QUIRK (HWREV_EQ (7), BHND_PCIE_QUIRK_SERDES_NOPLLDOWN),
BHND_CORE_QUIRK (HWREV_GTE(8), BHND_PCIE_QUIRK_L1_TIMER_PERF),
BHND_CORE_QUIRK (HWREV_LTE(17), BHND_PCIE_QUIRK_MAX_MRRS_128),
/* Apple boards on which BHND_BFL2_PCIEWAR_OVR should be assumed
* to be set. */
{{ BHND_MATCH_BOARD_VENDOR (PCI_VENDOR_APPLE),
BHND_MATCH_BOARD_REV (HWREV_LTE(0x71)),
BHND_MATCH_SROMREV (EQ(4)) },
BHND_PCIE_QUIRK_BFL2_PCIEWAR_EN },
/* Apple BCM4322 boards that require 700mV SerDes TX drive strength. */
{{ BHND_CHIP_ID(BCM4322),
BHND_MATCH_BOARD(PCI_VENDOR_APPLE, BCM94322X9), },
BHND_PCIE_QUIRK_SERDES_TXDRV_700MV },
/* Apple BCM4331 board-specific quirks */
#define BHND_A4331_QUIRK(_board, ...) \
{{ BHND_CHIP_ID(BCM4331), \
BHND_MATCH_BOARD(PCI_VENDOR_APPLE, _board) }, __VA_ARGS__ }
BHND_A4331_QUIRK(BCM94331X19, BHND_PCIE_QUIRK_SERDES_TXDRV_MAX |
BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
BHND_A4331_QUIRK(BCM94331X28, BHND_PCIE_QUIRK_SERDES_TXDRV_MAX |
BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
BHND_A4331_QUIRK(BCM94331X28B, BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
BHND_A4331_QUIRK(BCM94331X29B, BHND_PCIE_QUIRK_SERDES_TXDRV_MAX |
BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
BHND_A4331_QUIRK(BCM94331X19C, BHND_PCIE_QUIRK_SERDES_TXDRV_MAX |
BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
BHND_A4331_QUIRK(BCM94331X29D, BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
BHND_A4331_QUIRK(BCM94331X33, BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
#undef BHND_A4331_QUIRK
BHND_DEVICE_QUIRK_END
};
static const struct bhnd_chip_quirk bhnd_pcie_chip_quirks[] = {
/* Apple boards on which BHND_BFL2_PCIEWAR_OVR should be assumed
* to be set. */
{{ BHND_CHIP_BVENDOR (PCI_VENDOR_APPLE),
BHND_CHIP_SROMREV (HWREV_EQ(4)),
BHND_CHIP_BREV (HWREV_LTE(0x71)) },
BHND_PCIE_QUIRK_BFL2_PCIEWAR_EN },
/* Apple BCM4322 boards that require 700mV SerDes TX drive strength. */
{{ BHND_CHIP_BVT (PCI_VENDOR_APPLE, BCM94322X9) },
BHND_PCIE_QUIRK_SERDES_TXDRV_700MV },
/* Apple BCM4331 board-specific quirks */
#define BHND_APPLE_4331_QUIRK(_board, ...) \
{{ BHND_CHIP_ID (4331), \
BHND_CHIP_BVT (PCI_VENDOR_APPLE, _board), }, \
__VA_ARGS__ }
BHND_APPLE_4331_QUIRK(BCM94331X19,
BHND_PCIE_QUIRK_SERDES_TXDRV_MAX|BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
BHND_APPLE_4331_QUIRK(BCM94331X28,
BHND_PCIE_QUIRK_SERDES_TXDRV_MAX|BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
BHND_APPLE_4331_QUIRK(BCM94331X28B, BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
BHND_APPLE_4331_QUIRK(BCM94331X29B,
BHND_PCIE_QUIRK_SERDES_TXDRV_MAX|BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
BHND_APPLE_4331_QUIRK(BCM94331X19C,
BHND_PCIE_QUIRK_SERDES_TXDRV_MAX|BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
BHND_APPLE_4331_QUIRK(BCM94331X29D, BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
BHND_APPLE_4331_QUIRK(BCM94331X33, BHND_PCIE_QUIRK_DEFAULT_MRRS_512),
#undef BHND_APPLE_4331_QUIRK
BHND_CHIP_QUIRK_END
};
#define BHND_PCI_SOFTC(_sc) (&((_sc)->common))

View File

@ -57,11 +57,11 @@ __FBSDID("$FreeBSD$");
static struct bhnd_device_quirk bhnd_pcie2_quirks[];
#define BHND_PCIE_DEV(_core, _desc, ...) \
BHND_DEVICE(_core, _desc, bhnd_pcie2_quirks, NULL, ## __VA_ARGS__)
BHND_DEVICE(_core, _desc, bhnd_pcie2_quirks, ## __VA_ARGS__)
static const struct bhnd_device bhnd_pcie2_devs[] = {
BHND_PCIE_DEV(PCIE2, "PCIe-G2 Host-PCI bridge", BHND_DF_HOSTB),
BHND_PCIE_DEV(PCIE2, "PCIe-G2 PCI-BHND bridge"),
BHND_PCIE_DEV(PCIE2, "PCIe-G2 PCI-BHND bridge", BHND_DF_SOC),
BHND_DEVICE_END
};

View File

@ -72,7 +72,6 @@ __FBSDID("$FreeBSD$");
#include "bhnd_pcie2_hostbvar.h"
static const struct bhnd_device_quirk bhnd_pcie2_quirks[];
static const struct bhnd_chip_quirk bhnd_pcie2_chip_quirks[];
static int bhnd_pcie2_wars_early_once(struct bhnd_pcie2hb_softc *sc);
@ -83,27 +82,23 @@ static int bhnd_pcie2_wars_hwdown(struct bhnd_pcie2hb_softc *sc);
* device/quirk tables
*/
#define BHND_PCI_DEV(_core, _quirks, _chip_quirks) \
BHND_DEVICE(_core, "", _quirks, _chip_quirks, BHND_DF_HOSTB)
#define BHND_PCI_DEV(_core, _quirks) \
BHND_DEVICE(_core, NULL, _quirks, BHND_DF_HOSTB)
static const struct bhnd_device bhnd_pcie2_devs[] = {
BHND_PCI_DEV(PCIE2, bhnd_pcie2_quirks, bhnd_pcie2_chip_quirks),
BHND_PCI_DEV(PCIE2, bhnd_pcie2_quirks),
BHND_DEVICE_END
};
static const struct bhnd_device_quirk bhnd_pcie2_quirks[] = {
BHND_DEVICE_QUIRK_END
};
static const struct bhnd_chip_quirk bhnd_pcie2_chip_quirks[] = {
/* Apple BCM4360 boards that require adjusting TX amplitude and
* differential output de-emphasis of the PCIe SerDes */
{{ BHND_CHIP_BVT (PCI_VENDOR_APPLE, BCM94360X51P2) },
BHND_PCIE2_QUIRK_SERDES_TXDRV_DEEMPH },
{{ BHND_CHIP_BVT (PCI_VENDOR_APPLE, BCM94360X51A) },
BHND_PCIE2_QUIRK_SERDES_TXDRV_DEEMPH },
{{ BHND_MATCH_BOARD(PCI_VENDOR_APPLE, BCM94360X51P2), },
BHND_PCIE2_QUIRK_SERDES_TXDRV_DEEMPH },
{{ BHND_MATCH_BOARD(PCI_VENDOR_APPLE, BCM94360X51A), },
BHND_PCIE2_QUIRK_SERDES_TXDRV_DEEMPH },
BHND_CHIP_QUIRK_END
BHND_DEVICE_QUIRK_END
};
static int

View File

@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
static int siba_bhndb_wars_hwup(struct siba_softc *sc);
/* Bridge-specific core device quirks */
enum {
/** When PCIe-bridged, the D11 core's initiator request
* timeout must be disabled to prevent D11 from entering a
@ -67,9 +68,13 @@ enum {
SIBA_QUIRK_PCIE_D11_SB_TIMEOUT = (1<<0)
};
static struct bhnd_chip_quirk chip_quirks[] = {
{{ BHND_CHIP_IR(4311, HWREV_EQ(2)) }, SIBA_QUIRK_PCIE_D11_SB_TIMEOUT },
{{ BHND_CHIP_IR(4312, HWREV_EQ(0)) }, SIBA_QUIRK_PCIE_D11_SB_TIMEOUT },
static struct bhnd_device_quirk bridge_quirks[] = {
BHND_CHIP_QUIRK(4311, HWREV_EQ(2), SIBA_QUIRK_PCIE_D11_SB_TIMEOUT),
BHND_CHIP_QUIRK(4312, HWREV_EQ(0), SIBA_QUIRK_PCIE_D11_SB_TIMEOUT),
};
static struct bhnd_device bridge_devs[] = {
BHND_DEVICE(PCI, NULL, bridge_quirks),
};
static int
@ -218,12 +223,9 @@ siba_bhndb_wars_pcie_clear_d11_timeout(struct siba_softc *sc)
return (0);
/* Only applies if there's a D11 core */
d11 = bhnd_match_child(sc->dev, &(struct bhnd_core_match){
.vendor = BHND_MFGID_BCM,
.device = BHND_COREID_D11,
.hwrev = BHND_HWREV_ANY,
.class = BHND_DEVCLASS_INVALID,
.unit = 0
d11 = bhnd_match_child(sc->dev, &(struct bhnd_core_match) {
BHND_MATCH_CORE(BHND_MFGID_BCM, BHND_COREID_D11),
BHND_MATCH_CORE_UNIT(0)
});
if (d11 == NULL)
return (0);
@ -250,7 +252,8 @@ siba_bhndb_wars_hwup(struct siba_softc *sc)
uint32_t quirks;
int error;
quirks = bhnd_chip_quirks(sc->hostb_dev, chip_quirks);
quirks = bhnd_device_quirks(sc->hostb_dev, bridge_devs,
sizeof(bridge_devs[0]));
if (quirks & SIBA_QUIRK_PCIE_D11_SB_TIMEOUT) {
if ((error = siba_bhndb_wars_pcie_clear_d11_timeout(sc)))