Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F149564438
D6361.id16425.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
50 KB
Referenced Files
None
Subscribers
None
D6361.id16425.diff
View Options
Index: head/sys/dev/bhnd/bcma/bcma_bhndb.c
===================================================================
--- head/sys/dev/bhnd/bcma/bcma_bhndb.c
+++ head/sys/dev/bhnd/bcma/bcma_bhndb.c
@@ -166,6 +166,20 @@
return (0);
}
+static int
+bcma_bhndb_read_board_info(device_t dev, device_t child,
+ struct bhnd_board_info *info)
+{
+ int error;
+
+ /* Initialize with NVRAM-derived values */
+ if ((error = bhnd_bus_generic_read_board_info(dev, child, info)))
+ return (error);
+
+ /* Let the bridge fill in any additional data */
+ return (BHNDB_POPULATE_BOARD_INFO(device_get_parent(dev), dev, info));
+}
+
static device_method_t bcma_bhndb_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, bcma_bhndb_probe),
@@ -175,6 +189,9 @@
DEVMETHOD(bus_suspend_child, bcma_bhndb_suspend_child),
DEVMETHOD(bus_resume_child, bcma_bhndb_resume_child),
+ /* BHND interface */
+ DEVMETHOD(bhnd_bus_read_board_info, bcma_bhndb_read_board_info),
+
DEVMETHOD_END
};
Index: head/sys/dev/bhnd/bhnd.h
===================================================================
--- head/sys/dev/bhnd/bhnd.h
+++ head/sys/dev/bhnd/bhnd.h
@@ -110,6 +110,34 @@
#undef BHND_ACCESSOR
/**
+ * A bhnd(4) board descriptor.
+ */
+struct bhnd_board_info {
+ uint16_t board_vendor; /**< PCI-SIG vendor ID (even on non-PCI
+ * devices).
+ *
+ * On PCI devices, this will generally
+ * be the subsystem vendor ID, but the
+ * value may be overridden in device
+ * NVRAM.
+ */
+ uint16_t board_type; /**< Board type (See BHND_BOARD_*)
+ *
+ * On PCI devices, this will generally
+ * be the subsystem device ID, but the
+ * value may be overridden in device
+ * NVRAM.
+ */
+ uint16_t board_rev; /**< Board revision. */
+ uint8_t board_srom_rev; /**< Board SROM format revision */
+
+ uint32_t board_flags; /**< Board flags (see BHND_BFL_*) */
+ uint32_t board_flags2; /**< Board flags 2 (see BHND_BFL2_*) */
+ uint32_t board_flags3; /**< Board flags 3 (see BHND_BFL3_*) */
+};
+
+
+/**
* Chip Identification
*
* This is read from the ChipCommon ID register; on earlier bhnd(4) devices
@@ -131,23 +159,10 @@
};
/**
-* A bhnd(4) bus resource.
-*
-* This provides an abstract interface to per-core resources that may require
-* bus-level remapping of address windows prior to access.
-*/
-struct bhnd_resource {
- struct resource *res; /**< the system resource. */
- bool direct; /**< false if the resource requires
- * bus window remapping before it
- * is MMIO accessible. */
-};
-
-/**
* A bhnd(4) core descriptor.
*/
struct bhnd_core_info {
- uint16_t vendor; /**< vendor */
+ uint16_t vendor; /**< JEP-106 vendor (BHND_MFGID_*) */
uint16_t device; /**< device */
uint16_t hwrev; /**< hardware revision */
u_int core_idx; /**< bus-assigned core index */
@@ -165,6 +180,19 @@
to match on any revision. */
};
+/**
+* A bhnd(4) bus resource.
+*
+* This provides an abstract interface to per-core resources that may require
+* bus-level remapping of address windows prior to access.
+*/
+struct bhnd_resource {
+ struct resource *res; /**< the system resource. */
+ bool direct; /**< false if the resource requires
+ * bus window remapping before it
+ * is MMIO accessible. */
+};
+
/**
* Wildcard hardware revision match descriptor.
*/
@@ -233,31 +261,51 @@
.unit = -1 \
}
-/** A chipset match descriptor. */
+/**
+ * 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 */
- uint8_t
+ uint16_t
match_id:1,
match_rev:1,
match_pkg:1,
- match_flags_unused:5;
+ 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_id = 0, .match_rev = 0, .match_pkg = 0 }
+ { .match_any = 1 }
#define BHND_CHIP_MATCH_IS_ANY(_m) \
- ((_m)->match_id == 0 && (_m)->match_rev == 0 && (_m)->match_pkg == 0)
+ ((_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 revision range within a bhnd_chip_match instance */
+/** Set the required chip revision range within a bhnd_chip_match instance */
#define BHND_CHIP_REV(_rev) \
.match_rev = 1, .chip_rev = BHND_ ## _rev
@@ -265,6 +313,31 @@
#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_BT(_btype) \
+ .match_btype = 1, .board_type = BHND_BOARD_BCM ## _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_BVEND(_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)
@@ -314,23 +387,29 @@
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 */
};
-#define _BHND_DEVICE(_vendor, _device, _desc, _quirks, _flags, ...) \
- { BHND_CORE_MATCH(BHND_MFGID_ ## _vendor, BHND_COREID_ ## _device, \
- BHND_HWREV_ANY), _desc, _quirks, _flags }
-
-#define BHND_MIPS_DEVICE(_device, _desc, _quirks, ...) \
- _BHND_DEVICE(MIPS, _device, _desc, _quirks, ## __VA_ARGS__, 0)
-
-#define BHND_ARM_DEVICE(_device, _desc, _quirks, ...) \
- _BHND_DEVICE(ARM, _device, _desc, _quirks, ## __VA_ARGS__, 0)
+#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_MIPS_DEVICE(_device, _desc, _quirks, _chip_quirks, ...) \
+ _BHND_DEVICE(MIPS, _device, _desc, _quirks, _chip_quirks, \
+ ## __VA_ARGS__, 0)
+
+#define BHND_ARM_DEVICE(_device, _desc, _quirks, _chip_quirks, ...) \
+ _BHND_DEVICE(ARM, _device, _desc, _quirks, _chip_quirks, \
+ ## __VA_ARGS__, 0)
+
+#define BHND_DEVICE(_device, _desc, _quirks, _chip_quirks, ...) \
+ _BHND_DEVICE(BCM, _device, _desc, _quirks, _chip_quirks, \
+ ## __VA_ARGS__, 0)
-#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, 0 }
+#define BHND_DEVICE_END { BHND_CORE_MATCH_ANY, NULL, NULL, NULL, 0 }
const char *bhnd_vendor_name(uint16_t vendor);
const char *bhnd_port_type_name(bhnd_port_type port_type);
@@ -365,6 +444,7 @@
bool bhnd_chip_matches(
const struct bhnd_chipid *chipid,
+ const struct bhnd_board_info *binfo,
const struct bhnd_chip_match *desc);
bool bhnd_hwrev_matches(uint16_t hwrev,
@@ -418,6 +498,12 @@
void *buf, size_t *size);
const struct bhnd_chipid *bhnd_bus_generic_get_chipid(device_t dev,
device_t child);
+int bhnd_bus_generic_read_board_info(device_t dev,
+ device_t child,
+ struct bhnd_board_info *info);
+int bhnd_bus_generic_get_nvram_var(device_t dev,
+ device_t child, const char *name,
+ void *buf, size_t *size);
struct bhnd_resource *bhnd_bus_generic_alloc_resource (device_t dev,
device_t child, int type, int *rid,
rman_res_t start, rman_res_t end,
@@ -472,6 +558,28 @@
};
/**
+ * Attempt to read the BHND board identification from the bhnd bus.
+ *
+ * This relies on NVRAM access, and will fail if a valid NVRAM device cannot
+ * be found, or is not yet attached.
+ *
+ * @param dev The parent of @p child.
+ * @param child The bhnd device requesting board info.
+ * @param[out] info On success, will be populated with the bhnd(4) device's
+ * board information.
+ *
+ * @retval 0 success
+ * @retval ENODEV No valid NVRAM source could be found.
+ * @retval non-zero If reading @p name otherwise fails, a regular unix
+ * error code will be returned.
+ */
+static inline int
+bhnd_read_board_info(device_t dev, struct bhnd_board_info *info)
+{
+ return (BHND_BUS_READ_BOARD_INFO(device_get_parent(dev), dev, info));
+}
+
+/**
* Determine an NVRAM variable's expected size.
*
* @param dev A bhnd bus child device.
@@ -480,6 +588,7 @@
*
* @retval 0 success
* @retval ENOENT The requested variable was not found.
+ * @retval ENODEV No valid NVRAM source could be found.
* @retval non-zero If reading @p name otherwise fails, a regular unix
* error code will be returned.
*/
@@ -502,6 +611,7 @@
* @retval 0 success
* @retval ENOENT The requested variable was not found.
* @retval EINVAL If @p len does not match the actual variable size.
+ * @retval ENODEV No valid NVRAM source could be found.
* @retval non-zero If reading @p name otherwise fails, a regular unix
* error code will be returned.
*/
Index: head/sys/dev/bhnd/bhnd.c
===================================================================
--- head/sys/dev/bhnd/bhnd.c
+++ head/sys/dev/bhnd/bhnd.c
@@ -58,11 +58,6 @@
#include <sys/rman.h>
#include <machine/resource.h>
-#include "nvram/bhnd_nvram.h"
-
-#include "bhnd_chipc_if.h"
-#include "bhnd_nvram_if.h"
-
#include "bhnd.h"
#include "bhndvar.h"
@@ -85,8 +80,6 @@
{ BHND_MFGID_INVALID, BHND_COREID_INVALID, false }
};
-static device_t find_nvram_child(device_t dev);
-
static int compare_ascending_probe_order(const void *lhs,
const void *rhs);
static int compare_descending_probe_order(const void *lhs,
@@ -314,7 +307,9 @@
{
switch (bhnd_get_class(child)) {
case BHND_DEVCLASS_CC:
- return (BHND_PROBE_BUS + BHND_PROBE_ORDER_FIRST);
+ /* Must be early enough to provide NVRAM access to the
+ * host bridge */
+ return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_FIRST);
case BHND_DEVCLASS_CC_B:
/* fall through */
@@ -381,68 +376,6 @@
}
/**
- * Find an NVRAM child device on @p dev, if any.
- *
- * @retval device_t An NVRAM device.
- * @retval NULL If no NVRAM device is found.
- */
-static device_t
-find_nvram_child(device_t dev)
-{
- device_t chipc, nvram;
-
- /* Look for a directly-attached NVRAM child */
- nvram = device_find_child(dev, "bhnd_nvram", 0);
- if (nvram != NULL)
- return (nvram);
-
- /* Remaining checks are only applicable when searching a bhnd(4)
- * bus. */
- if (device_get_devclass(dev) != bhnd_devclass)
- return (NULL);
-
- /* Look for a ChipCommon device */
- if ((chipc = bhnd_find_child(dev, BHND_DEVCLASS_CC, -1)) != NULL) {
- bhnd_nvram_src_t src;
-
- /* Query the NVRAM source and determine whether it's
- * accessible via the ChipCommon device */
- src = BHND_CHIPC_NVRAM_SRC(chipc);
- if (BHND_NVRAM_SRC_CC(src))
- return (chipc);
- }
-
- /* Not found */
- return (NULL);
-}
-
-/**
- * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR().
- *
- * This implementation searches @p dev for a usable NVRAM child device:
- * - The first child device implementing the bhnd_nvram devclass is
- * returned, otherwise
- * - If @p dev is a bhnd(4) bus, a ChipCommon core that advertises an
- * attached NVRAM source.
- *
- * If no usable child device is found on @p dev, the request is delegated to
- * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev.
- */
-static int
-bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name,
- void *buf, size_t *size)
-{
- device_t nvram;
-
- /* Try to find an NVRAM device applicable to @p child */
- if ((nvram = find_nvram_child(dev)) == NULL)
- return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
- name, buf, size));
-
- return BHND_NVRAM_GETVAR(nvram, name, buf, size);
-}
-
-/**
* Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD().
*
* This implementation requests the device's struct resource_list via
@@ -693,7 +626,7 @@
DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order),
DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid),
DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled),
- DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_generic_get_nvram_var),
+ DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_bus_generic_get_nvram_var),
DEVMETHOD(bhnd_bus_read_1, bhnd_read_1),
DEVMETHOD(bhnd_bus_read_2, bhnd_read_2),
DEVMETHOD(bhnd_bus_read_4, bhnd_read_4),
Index: head/sys/dev/bhnd/bhnd_bus_if.m
===================================================================
--- head/sys/dev/bhnd/bhnd_bus_if.m
+++ head/sys/dev/bhnd/bhnd_bus_if.m
@@ -38,10 +38,10 @@
HEADER {
/* forward declarations */
+ struct bhnd_board_info;
struct bhnd_core_info;
struct bhnd_chipid;
struct bhnd_resource;
- struct bhnd_bus_ctx;
}
CODE {
@@ -54,7 +54,14 @@
{
panic("bhnd_bus_get_chipid unimplemented");
}
-
+
+ static int
+ bhnd_bus_null_read_board_info(device_t dev, device_t child,
+ struct bhnd_board_info *info)
+ {
+ panic("bhnd_bus_read_boardinfo unimplemented");
+ }
+
static device_t
bhnd_bus_null_find_hostb_device(device_t dev)
{
@@ -99,7 +106,7 @@
bhnd_bus_null_get_nvram_var(device_t dev, device_t child,
const char *name, void *buf, size_t *size)
{
- return (ENOENT);
+ return (ENODEV);
}
}
@@ -177,6 +184,28 @@
} DEFAULT bhnd_bus_null_get_chipid;
/**
+ * Attempt to read the BHND board identification from the parent bus.
+ *
+ * This relies on NVRAM access, and will fail if a valid NVRAM device cannot
+ * be found, or is not yet attached.
+ *
+ * @param dev The parent of @p child.
+ * @param child The bhnd device requesting board info.
+ * @param[out] info On success, will be populated with the bhnd(4) device's
+ * board information.
+ *
+ * @retval 0 success
+ * @retval ENODEV No valid NVRAM source could be found.
+ * @retval non-zero If reading @p name otherwise fails, a regular unix
+ * error code will be returned.
+ */
+METHOD int read_board_info {
+ device_t dev;
+ device_t child;
+ struct bhnd_board_info *info;
+} DEFAULT bhnd_bus_null_read_board_info;
+
+/**
* Reset the device's hardware core.
*
* @param dev The parent of @p child.
@@ -400,6 +429,7 @@
* @retval ENOENT The requested variable was not found.
* @retval ENOMEM If @p buf is non-NULL and a buffer of @p size is too
* small to hold the requested value.
+ * @retval ENODEV No valid NVRAM source could be found.
* @retval non-zero If reading @p name otherwise fails, a regular unix
* error code will be returned.
*/
Index: head/sys/dev/bhnd/bhnd_ids.h
===================================================================
--- head/sys/dev/bhnd/bhnd_ids.h
+++ head/sys/dev/bhnd/bhnd_ids.h
@@ -1,10 +1,12 @@
/*-
- * Copyright (C) 1999-2013, Broadcom Corporation
+ * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
+ * Copyright (c) 1999-2015, Broadcom Corporation
*
* This file is derived from the bcmdevs.h header contributed by Broadcom
- * to Android's bcmdhd driver module, and the hndsoc.h header distributed with
- * with Broadcom's initial brcm80211 Linux driver release, as contributed to
- * the Linux staging repository.
+ * to Android's bcmdhd driver module, later revisions of bcmdevs.h distributed
+ * with the dd-wrt project, and the hndsoc.h header distributed with Broadcom's
+ * initial brcm80211 Linux driver release as contributed to the Linux staging
+ * repository.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -18,8 +20,6 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: bcmdevs.h 387183 2013-02-24 07:42:07Z $
- *
* $FreeBSD$
*/
@@ -669,22 +669,22 @@
/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
-#define BHND_BOARD_GPIO_BTC3W_IN 0x850 /* bit 4 is RF_ACTIVE, bit 6 is STATUS, bit 11 is PRI */
-#define BHND_BOARD_GPIO_BTC3W_OUT 0x020 /* bit 5 is TX_CONF */
-#define BHND_BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistence Input */
-#define BHND_BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistence Out */
-#define BHND_BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistence Input */
-#define BHND_BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistence Out */
-#define BHND_BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
-#define BHND_BOARD_GPIO_12 0x1000 /* gpio 12 */
-#define BHND_BOARD_GPIO_13 0x2000 /* gpio 13 */
-#define BHND_BOARD_GPIO_BTC4_IN 0x0800 /* gpio 11, coex4, in */
-#define BHND_BOARD_GPIO_BTC4_BT 0x2000 /* gpio 12, coex4, bt active */
-#define BHND_BOARD_GPIO_BTC4_STAT 0x4000 /* gpio 14, coex4, status */
-#define BHND_BOARD_GPIO_BTC4_WLAN 0x8000 /* gpio 15, coex4, wlan active */
-#define BHND_BOARD_GPIO_1_WLAN_PWR 0x02 /* throttle WLAN power on X21 board */
-#define BHND_BOARD_GPIO_3_WLAN_PWR 0x08 /* throttle WLAN power on X28 board */
-#define BHND_BOARD_GPIO_4_WLAN_PWR 0x10 /* throttle WLAN power on X19 board */
+#define BHND_GPIO_BOARD_BTC3W_IN 0x850 /* bit 4 is RF_ACTIVE, bit 6 is STATUS, bit 11 is PRI */
+#define BHND_GPIO_BOARD_BTC3W_OUT 0x020 /* bit 5 is TX_CONF */
+#define BHND_GPIO_BOARD_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistence Input */
+#define BHND_GPIO_BOARD_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistence Out */
+#define BHND_GPIO_BOARD_BTC_IN 0x080 /* bit 7 is BT Coexistence Input */
+#define BHND_GPIO_BOARD_BTC_OUT 0x100 /* bit 8 is BT Coexistence Out */
+#define BHND_GPIO_BOARD_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
+#define BHND_GPIO_BOARD_12 0x1000 /* gpio 12 */
+#define BHND_GPIO_BOARD_13 0x2000 /* gpio 13 */
+#define BHND_GPIO_BOARD_BTC4_IN 0x0800 /* gpio 11, coex4, in */
+#define BHND_GPIO_BOARD_BTC4_BT 0x2000 /* gpio 12, coex4, bt active */
+#define BHND_GPIO_BOARD_BTC4_STAT 0x4000 /* gpio 14, coex4, status */
+#define BHND_GPIO_BOARD_BTC4_WLAN 0x8000 /* gpio 15, coex4, wlan active */
+#define BHND_GPIO_BOARD_1_WLAN_PWR 0x02 /* throttle WLAN power on X21 board */
+#define BHND_GPIO_BOARD_3_WLAN_PWR 0x08 /* throttle WLAN power on X28 board */
+#define BHND_GPIO_BOARD_4_WLAN_PWR 0x10 /* throttle WLAN power on X19 board */
#define BHND_GPIO_BTC4W_OUT_4312 0x010 /* bit 4 is BT_IODISABLE */
#define BHND_GPIO_BTC4W_OUT_43224 0x020 /* bit 5 is BT_IODISABLE */
@@ -700,11 +700,385 @@
#define BHND_CHIPC_MIN_SLOW_CLK 32 /* us Slow clock period */
#define BHND_CHIPC_XTAL_ON_DELAY 1000 /* us crystal power-on delay */
+/* Board Types */
+#define BHND_BOARD_BU4710 0x0400
+#define BHND_BOARD_VSIM4710 0x0401
+#define BHND_BOARD_QT4710 0x0402
+
+#define BHND_BOARD_BU4309 0x040a
+#define BHND_BOARD_BCM94309CB 0x040b
+#define BHND_BOARD_BCM94309MP 0x040c
+#define BHND_BOARD_BCM4309AP 0x040d
+
+#define BHND_BOARD_BCM94302MP 0x040e
+
+#define BHND_BOARD_BU4306 0x0416
+#define BHND_BOARD_BCM94306CB 0x0417
+#define BHND_BOARD_BCM94306MP 0x0418
+
+#define BHND_BOARD_BCM94710D 0x041a
+#define BHND_BOARD_BCM94710R1 0x041b
+#define BHND_BOARD_BCM94710R4 0x041c
+#define BHND_BOARD_BCM94710AP 0x041d
+
+#define BHND_BOARD_BU2050 0x041f
+
+
+#define BHND_BOARD_BCM94309G 0x0421
+
+#define BHND_BOARD_BU4704 0x0423
+#define BHND_BOARD_BU4702 0x0424
+
+#define BHND_BOARD_BCM94306PC 0x0425 /* pcmcia 3.3v 4306 card */
+
+
+#define BHND_BOARD_BCM94702MN 0x0428
+
+/* BCM4702 1U CompactPCI Board */
+#define BHND_BOARD_BCM94702CPCI 0x0429
+
+/* BCM4702 with BCM95380 VLAN Router */
+#define BHND_BOARD_BCM95380RR 0x042a
+
+/* cb4306 with SiGe PA */
+#define BHND_BOARD_BCM94306CBSG 0x042b
+
+/* cb4306 with SiGe PA */
+#define BHND_BOARD_PCSG94306 0x042d
+
+/* bu4704 with sdram */
+#define BHND_BOARD_BU4704SD 0x042e
+
+/* Dual 11a/11g Router */
+#define BHND_BOARD_BCM94704AGR 0x042f
+
+/* 11a-only minipci */
+#define BHND_BOARD_BCM94308MP 0x0430
+
+
+
+#define BHND_BOARD_BU4712 0x0444
+#define BHND_BOARD_BU4712SD 0x045d
+#define BHND_BOARD_BU4712L 0x045f
+
+/* BCM4712 boards */
+#define BHND_BOARD_BCM94712AP 0x0445
+#define BHND_BOARD_BCM94712P 0x0446
+
+/* BCM4318 boards */
+#define BHND_BOARD_BU4318 0x0447
+#define BHND_BOARD_CB4318 0x0448
+#define BHND_BOARD_MPG4318 0x0449
+#define BHND_BOARD_MP4318 0x044a
+#define BHND_BOARD_SD4318 0x044b
+
+/* BCM4313 boards */
+#define BHND_BOARD_BCM94313BU 0x050f
+#define BHND_BOARD_BCM94313HM 0x0510
+#define BHND_BOARD_BCM94313EPA 0x0511
+#define BHND_BOARD_BCM94313HMG 0x051C
+
+/* BCM63XX boards */
+#define BHND_BOARD_BCM96338 0x6338
+#define BHND_BOARD_BCM96348 0x6348
+#define BHND_BOARD_BCM96358 0x6358
+#define BHND_BOARD_BCM96368 0x6368
+
+/* Another mp4306 with SiGe */
+#define BHND_BOARD_BCM94306P 0x044c
+
+/* mp4303 */
+#define BHND_BOARD_BCM94303MP 0x044e
+
+/* mpsgh4306 */
+#define BHND_BOARD_BCM94306MPSGH 0x044f
+
+/* BRCM 4306 w/ Front End Modules */
+#define BHND_BOARD_BCM94306MPM 0x0450
+#define BHND_BOARD_BCM94306MPL 0x0453
+
+/* 4712agr */
+#define BHND_BOARD_BCM94712AGR 0x0451
+
+/* pcmcia 4303 */
+#define BHND_BOARD_PC4303 0x0454
+
+/* 5350K */
+#define BHND_BOARD_BCM95350K 0x0455
+
+/* 5350R */
+#define BHND_BOARD_BCM95350R 0x0456
+
+/* 4306mplna */
+#define BHND_BOARD_BCM94306MPLNA 0x0457
+
+/* 4320 boards */
+#define BHND_BOARD_BU4320 0x0458
+#define BHND_BOARD_BU4320S 0x0459
+#define BHND_BOARD_BCM94320PH 0x045a
+
+/* 4306mph */
+#define BHND_BOARD_BCM94306MPH 0x045b
+
+/* 4306pciv */
+#define BHND_BOARD_BCM94306PCIV 0x045c
+
+#define BHND_BOARD_BU4712SD 0x045d
+
+#define BHND_BOARD_BCM94320PFLSH 0x045e
+
+#define BHND_BOARD_BU4712L 0x045f
+#define BHND_BOARD_BCM94712LGR 0x0460
+#define BHND_BOARD_BCM94320R 0x0461
+
+#define BHND_BOARD_BU5352 0x0462
+
+#define BHND_BOARD_BCM94318MPGH 0x0463
+
+#define BHND_BOARD_BU4311 0x0464
+#define BHND_BOARD_BCM94311MC 0x0465
+#define BHND_BOARD_BCM94311MCAG 0x0466
+
+#define BHND_BOARD_BCM95352GR 0x0467
+
+/* bcm95351agr */
+#define BHND_BOARD_BCM95351AGR 0x0470
+
+/* bcm94704mpcb */
+#define BHND_BOARD_BCM94704MPCB 0x0472
+
+/* 4785 boards */
+#define BHND_BOARD_BU4785 0x0478
+
+/* 4321 boards */
+#define BHND_BOARD_BU4321 0x046b
+#define BHND_BOARD_BU4321E 0x047c
+#define BHND_BOARD_MP4321 0x046c
+#define BHND_BOARD_CB2_4321 0x046d
+#define BHND_BOARD_CB2_4321_AG 0x0066
+#define BHND_BOARD_MC4321 0x046e
+
+/* 4328 boards */
+#define BHND_BOARD_BU4328 0x0481
+#define BHND_BOARD_BCM4328SDG 0x0482
+#define BHND_BOARD_BCM4328SDAG 0x0483
+#define BHND_BOARD_BCM4328UG 0x0484
+#define BHND_BOARD_BCM4328UAG 0x0485
+#define BHND_BOARD_BCM4328PC 0x0486
+#define BHND_BOARD_BCM4328CF 0x0487
+
+/* 4325 boards */
+#define BHND_BOARD_BCM94325DEVBU 0x0490
+#define BHND_BOARD_BCM94325BGABU 0x0491
+
+#define BHND_BOARD_BCM94325SDGWB 0x0492
+
+#define BHND_BOARD_BCM94325SDGMDL 0x04aa
+#define BHND_BOARD_BCM94325SDGMDL2 0x04c6
+#define BHND_BOARD_BCM94325SDGMDL3 0x04c9
+
+#define BHND_BOARD_BCM94325SDABGWBA 0x04e1
+
+/* 4322 boards */
+#define BHND_BOARD_BCM94322MC 0x04a4
+#define BHND_BOARD_BCM94322USB 0x04a8 /* dualband */
+#define BHND_BOARD_BCM94322HM 0x04b0
+#define BHND_BOARD_BCM94322USB2D 0x04bf /* single band discrete front end */
+
+/* 4312 boards */
+#define BHND_BOARD_BCM4312MCGSG 0x04b5
+
+/* 4315 boards */
+#define BHND_BOARD_BCM94315DEVBU 0x04c2
+#define BHND_BOARD_BCM94315USBGP 0x04c7
+#define BHND_BOARD_BCM94315BGABU 0x04ca
+#define BHND_BOARD_BCM94315USBGP41 0x04cb
+
+/* 4319 boards */
+#define BHND_BOARD_BCM94319DEVBU 0X04e5
+#define BHND_BOARD_BCM94319USB 0X04e6
+#define BHND_BOARD_BCM94319SD 0X04e7
+
+/* 4716 boards */
+#define BHND_BOARD_BCM94716NR2 0x04cd
+
+/* 4319 boards */
+#define BHND_BOARD_BCM94319DEVBU 0X04e5
+#define BHND_BOARD_BCM94319USBNP4L 0X04e6
+#define BHND_BOARD_BCM94319WLUSBN4L 0X04e7
+#define BHND_BOARD_BCM94319SDG 0X04ea
+#define BHND_BOARD_BCM94319LCUSBSDN4L 0X04eb
+#define BHND_BOARD_BCM94319USBB 0x04ee
+#define BHND_BOARD_BCM94319LCSDN4L 0X0507
+#define BHND_BOARD_BCM94319LSUSBN4L 0X0508
+#define BHND_BOARD_BCM94319SDNA4L 0X0517
+#define BHND_BOARD_BCM94319SDELNA4L 0X0518
+#define BHND_BOARD_BCM94319SDELNA6L 0X0539
+#define BHND_BOARD_BCM94319ARCADYAN 0X0546
+#define BHND_BOARD_BCM94319WINDSOR 0x0561
+#define BHND_BOARD_BCM94319MLAP 0x0562
+#define BHND_BOARD_BCM94319SDNA 0x058b
+#define BHND_BOARD_BCM94319BHEMU3 0x0563
+#define BHND_BOARD_BCM94319SDHMB 0x058c
+#define BHND_BOARD_BCM94319SDBREF 0x05a1
+#define BHND_BOARD_BCM94319USBSDB 0x05a2
+
+/* 4329 boards */
+#define BHND_BOARD_BCM94329AGB 0X04b9
+#define BHND_BOARD_BCM94329TDKMDL1 0X04ba
+#define BHND_BOARD_BCM94329TDKMDL11 0X04fc
+#define BHND_BOARD_BCM94329OLYMPICN18 0X04fd
+#define BHND_BOARD_BCM94329OLYMPICN90 0X04fe
+#define BHND_BOARD_BCM94329OLYMPICN90U 0X050c
+#define BHND_BOARD_BCM94329OLYMPICN90M 0X050b
+#define BHND_BOARD_BCM94329AGBF 0X04ff
+#define BHND_BOARD_BCM94329OLYMPICX17 0X0504
+#define BHND_BOARD_BCM94329OLYMPICX17M 0X050a
+#define BHND_BOARD_BCM94329OLYMPICX17U 0X0509
+#define BHND_BOARD_BCM94329OLYMPICUNO 0X0564
+#define BHND_BOARD_BCM94329MOTOROLA 0X0565
+#define BHND_BOARD_BCM94329OLYMPICLOCO 0X0568
+
+/* 4336 SDIO board types */
+#define BHND_BOARD_BCM94336SD_WLBGABU 0x0511
+#define BHND_BOARD_BCM94336SD_WLBGAREF 0x0519
+#define BHND_BOARD_BCM94336SDGP 0x0538
+#define BHND_BOARD_BCM94336SDG 0x0519
+#define BHND_BOARD_BCM94336SDGN 0x0538
+#define BHND_BOARD_BCM94336SDGFC 0x056B
+
+/* 4330 SDIO board types */
+#define BHND_BOARD_BCM94330SDG 0x0528
+#define BHND_BOARD_BCM94330SD_FCBGABU 0x052e
+#define BHND_BOARD_BCM94330SD_WLBGABU 0x052f
+#define BHND_BOARD_BCM94330SD_FCBGA 0x0530
+#define BHND_BOARD_BCM94330FCSDAGB 0x0532
+#define BHND_BOARD_BCM94330OLYMPICAMG 0x0549
+#define BHND_BOARD_BCM94330OLYMPICAMGEPA 0x054F
+#define BHND_BOARD_BCM94330OLYMPICUNO3 0x0551
+#define BHND_BOARD_BCM94330WLSDAGB 0x0547
+#define BHND_BOARD_BCM94330CSPSDAGBB 0x054A
+
+/* 43224 boards */
+#define BHND_BOARD_BCM943224X21 0x056e
+#define BHND_BOARD_BCM943224X21_FCC 0x00d1
+#define BHND_BOARD_BCM943224X21B 0x00e9
+#define BHND_BOARD_BCM943224M93 0x008b
+#define BHND_BOARD_BCM943224M93A 0x0090
+#define BHND_BOARD_BCM943224X16 0x0093
+#define BHND_BOARD_BCM94322X9 0x008d
+#define BHND_BOARD_BCM94322M35e 0x008e
+
+/* 43228 Boards */
+#define BHND_BOARD_BCM943228BU8 0x0540
+#define BHND_BOARD_BCM943228BU9 0x0541
+#define BHND_BOARD_BCM943228BU 0x0542
+#define BHND_BOARD_BCM943227HM4L 0x0543
+#define BHND_BOARD_BCM943227HMB 0x0544
+#define BHND_BOARD_BCM943228HM4L 0x0545
+#define BHND_BOARD_BCM943228SD 0x0573
+
+/* 43239 Boards */
+#define BHND_BOARD_BCM943239MOD 0x05ac
+#define BHND_BOARD_BCM943239REF 0x05aa
+
+/* 4331 boards */
+#define BHND_BOARD_BCM94331X19 0x00D6 /* X19B */
+#define BHND_BOARD_BCM94331X28 0x00E4 /* X28 */
+#define BHND_BOARD_BCM94331X28B 0x010E /* X28B */
+#define BHND_BOARD_BCM94331PCIEBT3Ax BCM94331X28
+#define BHND_BOARD_BCM94331X12_2G 0x00EC /* X12 2G */
+#define BHND_BOARD_BCM94331X12_5G 0x00ED /* X12 5G */
+#define BHND_BOARD_BCM94331X29B 0x00EF /* X29B */
+#define BHND_BOARD_BCM94331X29D 0x010F /* X29D */
+#define BHND_BOARD_BCM94331CSAX BCM94331X29B
+#define BHND_BOARD_BCM94331X19C 0x00F5 /* X19C */
+#define BHND_BOARD_BCM94331X33 0x00F4 /* X33 */
+#define BHND_BOARD_BCM94331BU 0x0523
+#define BHND_BOARD_BCM94331S9BU 0x0524
+#define BHND_BOARD_BCM94331MC 0x0525
+#define BHND_BOARD_BCM94331MCI 0x0526
+#define BHND_BOARD_BCM94331PCIEBT4 0x0527
+#define BHND_BOARD_BCM94331HM 0x0574
+#define BHND_BOARD_BCM94331PCIEDUAL 0x059B
+#define BHND_BOARD_BCM94331MCH5 0x05A9
+#define BHND_BOARD_BCM94331CS 0x05C6
+#define BHND_BOARD_BCM94331CD 0x05DA
+
+/* 4314 Boards */
+#define BHND_BOARD_BCM94314BU 0x05b1
+
+/* 53572 Boards */
+#define BHND_BOARD_BCM953572BU 0x058D
+#define BHND_BOARD_BCM953572NR2 0x058E
+#define BHND_BOARD_BCM947188NR2 0x058F
+#define BHND_BOARD_BCM953572SDRNR2 0x0590
+
+/* 43236 boards */
+#define BHND_BOARD_BCM943236OLYMPICSULLEY 0x594
+#define BHND_BOARD_BCM943236PREPROTOBLU2O3 0x5b9
+#define BHND_BOARD_BCM943236USBELNA 0x5f8
+
+/* 4314 Boards */
+#define BHND_BOARD_BCM94314BUSDIO 0x05c8
+#define BHND_BOARD_BCM94314BGABU 0x05c9
+#define BHND_BOARD_BCM94314HMEPA 0x05ca
+#define BHND_BOARD_BCM94314HMEPABK 0x05cb
+#define BHND_BOARD_BCM94314SUHMEPA 0x05cc
+#define BHND_BOARD_BCM94314SUHM 0x05cd
+#define BHND_BOARD_BCM94314HM 0x05d1
+
+/* 4334 Boards */
+#define BHND_BOARD_BCM94334FCAGBI 0x05df
+#define BHND_BOARD_BCM94334WLAGBI 0x05dd
+
+/* 4335 Boards */
+#define BHND_BOARD_BCM94335X52 0x0114
+
+/* 4345 Boards */
+#define BHND_BOARD_BCM94345 0x0687
+
+/* 4360 Boards */
+#define BHND_BOARD_BCM94360X52C 0X0117
+#define BHND_BOARD_BCM94360X52D 0X0137
+#define BHND_BOARD_BCM94360X29C 0X0112
+#define BHND_BOARD_BCM94360X29CP2 0X0134
+#define BHND_BOARD_BCM94360X51 0x0111
+#define BHND_BOARD_BCM94360X51P2 0x0129
+#define BHND_BOARD_BCM94360X51A 0x0135
+#define BHND_BOARD_BCM94360X51B 0x0136
+#define BHND_BOARD_BCM94360CS 0x061B
+#define BHND_BOARD_BCM94360J28_D11AC2G 0x0c00
+#define BHND_BOARD_BCM94360J28_D11AC5G 0x0c01
+#define BHND_BOARD_BCM94360USBH5_D11AC5G 0x06aa
+
+/* 4350 Boards */
+#define BHND_BOARD_BCM94350X52B 0X0116
+#define BHND_BOARD_BCM94350X14 0X0131
+
+/* 43217 Boards */
+#define BHND_BOARD_BCM943217BU 0x05d5
+#define BHND_BOARD_BCM943217HM2L 0x05d6
+#define BHND_BOARD_BCM943217HMITR2L 0x05d7
+
+/* 43142 Boards */
+#define BHND_BOARD_BCM943142HM 0x05e0
+
/* 43341 Boards */
-#define BCM943341WLABGS_SSID 0x062d
+#define BHND_BOARD_BCM943341WLABGS 0x062d
/* 43342 Boards */
-#define BCM943342FCAGBI_SSID 0x0641
+#define BHND_BOARD_BCM943342FCAGBI 0x0641
+
+/* 43602 Boards, unclear yet what boards will be created. */
+#define BHND_BOARD_BCM943602RSVD1 0x06a5
+#define BHND_BOARD_BCM943602RSVD2 0x06a6
+#define BHND_BOARD_BCM943602X87 0X0133
+#define BHND_BOARD_BCM943602X238 0X0132
+
+/* 4354 board types */
+#define BHND_BOARD_BCM94354WLSAGBI 0x06db
+#define BHND_BOARD_BCM94354Z 0x0707
/* # of GPIO pins */
#define BHND_BCM43XX_GPIO_NUMPINS 32
Index: head/sys/dev/bhnd/bhnd_subr.c
===================================================================
--- head/sys/dev/bhnd/bhnd_subr.c
+++ head/sys/dev/bhnd/bhnd_subr.c
@@ -41,9 +41,18 @@
#include <dev/bhnd/cores/chipc/chipcreg.h>
+#include "nvram/bhnd_nvram.h"
+
+#include "bhnd_chipc_if.h"
+
+#include "bhnd_nvram_if.h"
+#include "bhnd_nvram_map.h"
+
#include "bhndreg.h"
#include "bhndvar.h"
+static device_t find_nvram_child(device_t dev);
+
/* BHND core device description table. */
static const struct bhnd_core_desc {
uint16_t vendor;
@@ -427,6 +436,7 @@
* 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
@@ -434,8 +444,19 @@
*/
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)
+ return (false);
+
+
+ /* Chip matching */
if (desc->match_id && chip->chip_id != desc->chip_id)
return (false);
@@ -446,6 +467,23 @@
!bhnd_hwrev_matches(chip->chip_rev, &desc->chip_rev))
return (false);
+
+ /* Board info matching */
+ if (desc->match_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)
+ return (false);
+
+ if (desc->match_btype && board->board_type != desc->board_type)
+ return (false);
+
+ if (desc->match_brev &&
+ !bhnd_hwrev_matches(board->board_rev, &desc->board_rev))
+ return (false);
+
+
return (true);
}
@@ -547,15 +585,43 @@
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_matches(cid, &qent->chip))
+ 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;
}
@@ -590,16 +656,18 @@
return (0);
}
- /* Quirks aren't a mandatory field */
- if ((qtable = dent->quirks_table) == NULL)
- return (0);
-
- /* Collect matching quirk entries */
- for (qent = qtable; !BHND_DEVICE_QUIRK_IS_END(qent); qent++) {
- if (bhnd_hwrev_matches(hwrev, &qent->hwrev))
- quirks |= qent->quirks;
+ /* 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;
+ }
}
+ /* Collect matching chip quirk entries */
+ if (dent->chip_quirks_table != NULL)
+ quirks |= bhnd_chip_quirks(dev, dent->chip_quirks_table);
+
return (quirks);
}
@@ -824,6 +892,130 @@
panic("missing BHND_BUS_GET_CHIPID()");
}
+/* nvram board_info population macros for bhnd_bus_generic_read_board_info() */
+#define BHND_GV(_dest, _name) \
+ bhnd_nvram_getvar(child, BHND_NVAR_ ## _name, &_dest, sizeof(_dest))
+
+#define REQ_BHND_GV(_dest, _name) do { \
+ if ((error = BHND_GV(_dest, _name))) { \
+ device_printf(dev, \
+ "error reading " __STRING(_name) ": %d\n", error); \
+ return (error); \
+ } \
+} while(0)
+
+#define OPT_BHND_GV(_dest, _name, _default) do { \
+ if ((error = BHND_GV(_dest, _name))) { \
+ if (error != ENOENT) { \
+ device_printf(dev, \
+ "error reading " \
+ __STRING(_name) ": %d\n", error); \
+ return (error); \
+ } \
+ _dest = _default; \
+ } \
+} while(0)
+
+/**
+ * Helper function for implementing BHND_BUS_READ_BOARDINFO().
+ *
+ * This implementation populates @p info with information from NVRAM,
+ * defaulting board_vendor and board_type fields to 0 if the
+ * requested variables cannot be found.
+ *
+ * This behavior is correct for most SoCs, but must be overridden on
+ * bridged (PCI, PCMCIA, etc) devices to produce a complete bhnd_board_info
+ * result.
+ */
+int
+bhnd_bus_generic_read_board_info(device_t dev, device_t child,
+ struct bhnd_board_info *info)
+{
+ int error;
+
+ OPT_BHND_GV(info->board_vendor, BOARDVENDOR, 0);
+ OPT_BHND_GV(info->board_type, BOARDTYPE, 0); /* srom >= 2 */
+ REQ_BHND_GV(info->board_rev, BOARDREV);
+ REQ_BHND_GV(info->board_srom_rev,SROMREV);
+ REQ_BHND_GV(info->board_flags, BOARDFLAGS);
+ OPT_BHND_GV(info->board_flags2, BOARDFLAGS2, 0); /* srom >= 4 */
+ OPT_BHND_GV(info->board_flags3, BOARDFLAGS3, 0); /* srom >= 11 */
+
+ return (0);
+}
+
+#undef BHND_GV
+#undef BHND_GV_REQ
+#undef BHND_GV_OPT
+
+
+/**
+ * Find an NVRAM child device on @p dev, if any.
+ *
+ * @retval device_t An NVRAM device.
+ * @retval NULL If no NVRAM device is found.
+ */
+static device_t
+find_nvram_child(device_t dev)
+{
+ device_t chipc, nvram;
+
+ /* Look for a directly-attached NVRAM child */
+ nvram = device_find_child(dev, "bhnd_nvram", 0);
+ if (nvram != NULL)
+ return (nvram);
+
+ /* Remaining checks are only applicable when searching a bhnd(4)
+ * bus. */
+ if (device_get_devclass(dev) != bhnd_devclass)
+ return (NULL);
+
+ /* Look for a ChipCommon device */
+ if ((chipc = bhnd_find_child(dev, BHND_DEVCLASS_CC, -1)) != NULL) {
+ bhnd_nvram_src_t src;
+
+ /* Query the NVRAM source and determine whether it's
+ * accessible via the ChipCommon device */
+ src = BHND_CHIPC_NVRAM_SRC(chipc);
+ if (BHND_NVRAM_SRC_CC(src))
+ return (chipc);
+ }
+
+ /* Not found */
+ return (NULL);
+}
+
+/**
+ * Helper function for implementing BHND_BUS_GET_NVRAM_VAR().
+ *
+ * This implementation searches @p dev for a usable NVRAM child device:
+ * - The first child device implementing the bhnd_nvram devclass is
+ * returned, otherwise
+ * - If @p dev is a bhnd(4) bus, a ChipCommon core that advertises an
+ * attached NVRAM source.
+ *
+ * If no usable child device is found on @p dev, the request is delegated to
+ * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev.
+ */
+int
+bhnd_bus_generic_get_nvram_var(device_t dev, device_t child, const char *name,
+ void *buf, size_t *size)
+{
+ device_t nvram;
+ device_t parent;
+
+ /* Try to find an NVRAM device applicable to @p child */
+ if ((nvram = find_nvram_child(dev)) != NULL)
+ return BHND_NVRAM_GETVAR(nvram, name, buf, size);
+
+ /* Try to delegate to parent */
+ if ((parent = device_get_parent(dev)) == NULL)
+ return (ENODEV);
+
+ return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
+ name, buf, size));
+}
+
/**
* Helper function for implementing BHND_BUS_ALLOC_RESOURCE().
*
Index: head/sys/dev/bhnd/bhndb/bhndb.c
===================================================================
--- head/sys/dev/bhnd/bhndb/bhndb.c
+++ head/sys/dev/bhnd/bhndb/bhndb.c
@@ -1714,26 +1714,6 @@
return (dwa);
}
-/**
- * Default bhndb(4) implementation of BHND_BUS_GET_NVRAM_VAR().
- */
-static int
-bhndb_get_nvram_var(device_t dev, device_t child, const char *name,
- void *buf, size_t *size)
-{
- device_t nvram;
-
- /* Look for a directly-attached NVRAM child */
- nvram = device_find_child(dev, devclass_get_name(bhnd_nvram_devclass),
- 0);
- if (nvram != NULL)
- return (BHND_NVRAM_GETVAR(nvram, name, buf, size));
-
- /* Otherwise, delegate to our parent */
- return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
- name, buf, size));
-}
-
/*
* BHND_BUS_(READ|WRITE_* implementations
*/
@@ -1961,7 +1941,7 @@
DEVMETHOD(bhnd_bus_get_chipid, bhndb_get_chipid),
DEVMETHOD(bhnd_bus_activate_resource, bhndb_activate_bhnd_resource),
DEVMETHOD(bhnd_bus_deactivate_resource, bhndb_deactivate_bhnd_resource),
- DEVMETHOD(bhnd_bus_get_nvram_var, bhndb_get_nvram_var),
+ DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_bus_generic_get_nvram_var),
DEVMETHOD(bhnd_bus_read_1, bhndb_bus_read_1),
DEVMETHOD(bhnd_bus_read_2, bhndb_bus_read_2),
DEVMETHOD(bhnd_bus_read_4, bhndb_bus_read_4),
Index: head/sys/dev/bhnd/bhndb/bhndb_if.m
===================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_if.m
+++ head/sys/dev/bhnd/bhndb/bhndb_if.m
@@ -56,6 +56,13 @@
}
static int
+ bhndb_null_populate_board_info(device_t dev, device_t child,
+ struct bhnd_board_info *info)
+ {
+ panic("bhndb_populate_board_info unimplemented");
+ }
+
+ static int
bhndb_null_init_full_config(device_t dev, device_t child,
const struct bhndb_hw_priority *priority_table)
{
@@ -102,6 +109,21 @@
} DEFAULT bhndb_null_get_chipid;
/**
+ * Populate @p info with board info known only to the bridge,
+ * deferring to any existing initialized fields in @p info.
+ *
+ * @param dev The parent device of @p child.
+ * @param child The bhndb-attached device.
+ * @param[in,out] info A board info structure previously initialized with any
+ * information available from NVRAM.
+ */
+METHOD int populate_board_info {
+ device_t dev;
+ device_t child;
+ struct bhnd_board_info *info;
+} DEFAULT bhndb_null_populate_board_info;
+
+/**
* Perform final bridge hardware configuration after @p child has fully
* enumerated its children.
*
Index: head/sys/dev/bhnd/bhndb/bhndb_pci.c
===================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_pci.c
+++ head/sys/dev/bhnd/bhndb/bhndb_pci.c
@@ -474,6 +474,25 @@
return (0);
}
+static int
+bhndb_pci_populate_board_info(device_t dev, device_t child,
+ struct bhnd_board_info *info)
+{
+ struct bhndb_pci_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ /* If NVRAM did not supply vendor/type info, provide the PCI
+ * subvendor/subdevice values. */
+ if (info->board_vendor == 0)
+ info->board_vendor = pci_get_subvendor(sc->parent);
+
+ if (info->board_type == 0)
+ info->board_type = pci_get_subdevice(sc->parent);
+
+ return (0);
+}
+
/**
* Enable externally managed clocks, if required.
*
@@ -572,6 +591,7 @@
/* BHNDB interface */
DEVMETHOD(bhndb_init_full_config, bhndb_pci_init_full_config),
DEVMETHOD(bhndb_set_window_addr, bhndb_pci_set_window_addr),
+ DEVMETHOD(bhndb_populate_board_info, bhndb_pci_populate_board_info),
DEVMETHOD_END
};
Index: head/sys/dev/bhnd/cores/chipc/chipc.c
===================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc.c
+++ head/sys/dev/bhnd/cores/chipc/chipc.c
@@ -65,10 +65,11 @@
};
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),
+ BHND_DEVICE(CC, "CC", chipc_quirks, chipc_chip_quirks),
BHND_DEVICE_END
};
@@ -158,7 +159,6 @@
sc->dev = dev;
sc->quirks = bhnd_device_quirks(dev, chipc_devices,
sizeof(chipc_devices[0]));
- sc->quirks |= bhnd_chip_quirks(dev, chipc_chip_quirks);
CHIPC_LOCK_INIT(sc);
Index: head/sys/dev/bhnd/cores/pci/bhnd_pci.c
===================================================================
--- head/sys/dev/bhnd/cores/pci/bhnd_pci.c
+++ head/sys/dev/bhnd/cores/pci/bhnd_pci.c
@@ -68,8 +68,8 @@
#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, \
+#define BHND_PCI_DEV(_core, _desc, ...) \
+ { BHND_DEVICE(_core, _desc, BHND_ ## _core ## _QUIRKS, NULL, \
## __VA_ARGS__), BHND_PCI_REGFMT_ ## _core }
static const struct bhnd_pci_device {
Index: head/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c
===================================================================
--- head/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c
+++ head/sys/dev/bhnd/cores/pci/bhnd_pci_hostb.c
@@ -62,11 +62,12 @@
#define BHND_PCI_ASSERT_QUIRK(_sc, _name) \
KASSERT((_sc)->quirks & (_name), ("quirk " __STRING(_name) " not set"))
-#define BHND_PCI_DEV(_core, _quirks) \
- BHND_DEVICE(_core, "", _quirks, BHND_DF_HOSTB)
+#define BHND_PCI_DEV(_core, _quirks, _chip_quirks) \
+ BHND_DEVICE(_core, "", _quirks, _chip_quirks, BHND_DF_HOSTB)
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_pcie_chip_quirks[];
static int bhnd_pci_wars_early_once(struct bhnd_pcihb_softc *sc);
static int bhnd_pci_wars_hwup(struct bhnd_pcihb_softc *sc);
@@ -76,8 +77,8 @@
* device/quirk tables
*/
static const struct bhnd_device bhnd_pci_devs[] = {
- BHND_PCI_DEV(PCI, bhnd_pci_quirks),
- BHND_PCI_DEV(PCIE, bhnd_pcie_quirks),
+ BHND_PCI_DEV(PCI, bhnd_pci_quirks, NULL),
+ BHND_PCI_DEV(PCIE, bhnd_pcie_quirks, bhnd_pcie_chip_quirks),
BHND_DEVICE_END
};
@@ -105,9 +106,21 @@
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 },
+
+ BHND_CHIP_QUIRK_END
+};
+
// Quirk handling TODO
// WARs for the following are not yet implemented:
// - BHND_PCIE_QUIRK_ASPM_OVR
+// - BHND_PCIE_QUIRK_BFL2_PCIEWAR_EN
// - BHND_PCIE_QUIRK_SERDES_NOPLLDOWN
// Quirks (and WARs) for the following are not yet defined:
// - Power savings via MDIO BLK1/PWR_MGMT3 on PCIe hwrev 15-20, 21-22
Index: head/sys/dev/bhnd/cores/pci/bhnd_pci_hostbvar.h
===================================================================
--- head/sys/dev/bhnd/cores/pci/bhnd_pci_hostbvar.h
+++ head/sys/dev/bhnd/cores/pci/bhnd_pci_hostbvar.h
@@ -131,20 +131,27 @@
* clear ASPM L1 in the PCIER_LINK_CTL register.
*/
BHND_PCIE_QUIRK_ASPM_OVR = (1<<9),
-
+
+ /**
+ * A subset of Apple devices did not set the BHND_BFL2_PCIEWAR_OVR
+ * flag in SPROM; on these devices, the BHND_BFL2_PCIEWAR_OVR flag
+ * should always be treated as if set.
+ */
+ BHND_PCIE_QUIRK_BFL2_PCIEWAR_EN = (1<<10),
+
/**
* Fix SerDes polarity on SerDes <= rev9 devices.
*
* The SerDes polarity must be saved at device attachment, and
* restored on suspend/resume.
*/
- BHND_PCIE_QUIRK_SDR9_POLARITY = (1<<10),
+ BHND_PCIE_QUIRK_SDR9_POLARITY = (1<<11),
/**
* SerDes PLL down flag must be manually disabled (by ChipCommon) on
* resume.
*/
- BHND_PCIE_QUIRK_SERDES_NOPLLDOWN = (1<<11),
+ BHND_PCIE_QUIRK_SERDES_NOPLLDOWN = (1<<12),
/**
* On attach and resume, consult the SPROM to determine whether
@@ -152,7 +159,7 @@
*
* If L23READY_EXIT_NOPRST is not already set in the SPROM, set it
*/
- BHND_PCIE_QUIRK_SPROM_L23_PCI_RESET = (1<<12),
+ BHND_PCIE_QUIRK_SPROM_L23_PCI_RESET = (1<<13),
/**
* The PCIe SerDes supports non-standard extended MDIO register access.
@@ -160,7 +167,7 @@
* The PCIe SerDes supports access to extended MDIO registers via
* a non-standard Clause 22 address extension mechanism.
*/
- BHND_PCIE_QUIRK_SD_C22_EXTADDR = (1<<13),
+ BHND_PCIE_QUIRK_SD_C22_EXTADDR = (1<<14),
/**
* The PCIe SerDes PLL must be configured to not retry the startup
@@ -168,7 +175,7 @@
*
* The issue this workaround resolves has not be determined.
*/
- BHND_PCIE_QUIRK_SDR9_NO_FREQRETRY = (1<<14),
+ BHND_PCIE_QUIRK_SDR9_NO_FREQRETRY = (1<<15),
};
/**
Index: head/sys/dev/bhnd/nvram/nvram_map
===================================================================
--- head/sys/dev/bhnd/nvram/nvram_map
+++ head/sys/dev/bhnd/nvram/nvram_map
@@ -30,6 +30,60 @@
# available ISC-licensed CIS and SROM code and associated headers.
#
+# Board Info
+#
+
+u16 boardvendor {} # PCI vendor ID (SoC NVRAM-only)
+u16 subvid { srom >= 2 0x6 } # PCI subvendor ID
+u16 devid { srom >= 8 0x60 } # PCI device ID
+
+u32 boardflags {
+ srom 1 u16 0x72
+ srom 2 u16 0x72 | u16 0x38 (<<16)
+ srom 3 u16 0x72 | u16 0x7A (<<16)
+ srom 4 0x44
+ srom 5-7 0x4A
+ srom >= 8 0x84
+}
+u32 boardflags2 {
+ srom 4 0x48
+ srom 5-7 0x4E
+ srom >= 8 0x88
+}
+u32 boardflags3 {
+ srom >= 11 0x8C
+}
+
+# Board serial number, independent of mac addr
+u16 boardnum {
+ srom 1-2 0x4C
+ srom 3 0x4E
+ srom 4 0x50
+ srom 5-7 0x56
+ srom 8-10 0x90
+ srom >= 11 0x94
+}
+
+# Board revision
+u16 boardrev {
+ srom 1-3 u8 0x5D
+ srom 4-7 0x42
+ srom >= 8 0x82
+}
+
+# Board type
+u16 boardtype {
+ srom >= 2 0x4
+}
+
+# SROM revision
+u8 sromrev {
+ srom 1-3 0x74
+ srom 4-9 0x1B6
+ srom 10 0x1CA
+ srom 11 0x1D2
+}
+
# Antennas available
u8 aa2g {
srom 1-3 0x5C (&0x30, >>4)
@@ -184,46 +238,6 @@
srom >= 11 0xA7
}
-# board flags
-u32 boardflags {
- srom 1 u16 0x72
- srom 2 u16 0x72 | u16 0x38 (<<16)
- srom 3 u16 0x72 | u16 0x7A (<<16)
- srom 4 0x44
- srom 5-7 0x4A
- srom >= 8 0x84
-}
-u32 boardflags2 {
- srom 4 0x48
- srom 5-7 0x4E
- srom >= 8 0x88
-}
-u32 boardflags3 {
- srom >= 11 0x8C
-}
-
-# board serial number, independent of mac addr
-u16 boardnum {
- srom 1-2 0x4C
- srom 3 0x4E
- srom 4 0x50
- srom 5-7 0x56
- srom 8-10 0x90
- srom >= 11 0x94
-}
-
-# One byte board revision
-u16 boardrev {
- srom 1-3 u8 0x5D
- srom 4-7 0x42
- srom >= 8 0x82
-}
-
-# 2 bytes; boardtype
-u16 boardtype {
- srom >= 2 0x4
-}
-
# Default country code (sromrev == 1)
u8 cc {
srom 1 0x5C (&0xF)
@@ -274,11 +288,6 @@
srom >= 11 u8 0xA8
}
-# PCI device id
-private u16 devid {
- srom >= 8 u16 0x60
-}
-
u8 elna2g {
srom 8-10 0xBB
}
@@ -1269,10 +1278,6 @@
srom >= 11 0x1BA
}
-u16 subvid {
- srom >= 2 0x6
-}
-
u32[5] swctrlmap_2g {
srom 10 u32[4] 0x1B8, u16 0x1C8
}
Index: head/sys/dev/bhnd/siba/siba_bhndb.c
===================================================================
--- head/sys/dev/bhnd/siba/siba_bhndb.c
+++ head/sys/dev/bhnd/siba/siba_bhndb.c
@@ -166,6 +166,20 @@
return (0);
}
+static int
+siba_bhndb_read_board_info(device_t dev, device_t child,
+ struct bhnd_board_info *info)
+{
+ int error;
+
+ /* Initialize with NVRAM-derived values */
+ if ((error = bhnd_bus_generic_read_board_info(dev, child, info)))
+ return (error);
+
+ /* Let the bridge fill in any additional data */
+ return (BHNDB_POPULATE_BOARD_INFO(device_get_parent(dev), dev, info));
+}
+
static device_method_t siba_bhndb_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, siba_bhndb_probe),
@@ -175,6 +189,9 @@
DEVMETHOD(bus_suspend_child, siba_bhndb_suspend_child),
DEVMETHOD(bus_resume_child, siba_bhndb_resume_child),
+ /* BHND interface */
+ DEVMETHOD(bhnd_bus_read_board_info, siba_bhndb_read_board_info),
+
DEVMETHOD_END
};
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 26, 7:09 AM (7 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30370039
Default Alt Text
D6361.id16425.diff (50 KB)
Attached To
Mode
D6361: [BHND] Centralize fetching of board information
Attached
Detach File
Event Timeline
Log In to Comment