From owner-svn-src-head@freebsd.org Sun Aug 28 20:39:55 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0E731BC11DC; Sun, 28 Aug 2016 20:39:55 +0000 (UTC) (envelope-from landonf@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C55DB2A5; Sun, 28 Aug 2016 20:39:54 +0000 (UTC) (envelope-from landonf@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u7SKdrsM050850; Sun, 28 Aug 2016 20:39:53 GMT (envelope-from landonf@FreeBSD.org) Received: (from landonf@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u7SKdrO9050847; Sun, 28 Aug 2016 20:39:53 GMT (envelope-from landonf@FreeBSD.org) Message-Id: <201608282039.u7SKdrO9050847@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: landonf set sender to landonf@FreeBSD.org using -f From: "Landon J. Fuller" Date: Sun, 28 Aug 2016 20:39:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r304967 - in head/sys/dev/bhnd: . siba X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 28 Aug 2016 20:39:55 -0000 Author: landonf Date: Sun Aug 28 20:39:53 2016 New Revision: 304967 URL: https://svnweb.freebsd.org/changeset/base/304967 Log: bhnd(4): Apply the siba chipid ncore fixup in bhnd_read_chipid(), ensuring that bhndb et al are always operating on a valid core count. Approved by: adrian (mentor, implicit) Modified: head/sys/dev/bhnd/bhnd.h head/sys/dev/bhnd/bhnd_subr.c head/sys/dev/bhnd/siba/siba.c Modified: head/sys/dev/bhnd/bhnd.h ============================================================================== --- head/sys/dev/bhnd/bhnd.h Sun Aug 28 20:39:33 2016 (r304966) +++ head/sys/dev/bhnd/bhnd.h Sun Aug 28 20:39:53 2016 (r304967) @@ -317,6 +317,10 @@ void bhnd_release_resources(device_t struct bhnd_chipid bhnd_parse_chipid(uint32_t idreg, bhnd_addr_t enum_addr); +int bhnd_chipid_fixed_ncores( + const struct bhnd_chipid *cid, + uint16_t chipc_hwrev, uint8_t *ncores); + int bhnd_read_chipid(device_t dev, struct resource_spec *rs, bus_size_t chipc_offset, Modified: head/sys/dev/bhnd/bhnd_subr.c ============================================================================== --- head/sys/dev/bhnd/bhnd_subr.c Sun Aug 28 20:39:33 2016 (r304966) +++ head/sys/dev/bhnd/bhnd_subr.c Sun Aug 28 20:39:53 2016 (r304967) @@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include #include "nvram/bhnd_nvram.h" @@ -840,6 +842,63 @@ bhnd_parse_chipid(uint32_t idreg, bhnd_a return (result); } + +/** + * Determine the correct core count for a chip identification value that + * may contain an invalid core count. + * + * On some early siba(4) devices (see CHIPC_NCORES_MIN_HWREV()), the ChipCommon + * core does not provide a valid CHIPC_ID_NUMCORE field. + * + * @param cid The chip identification to be queried. + * @param chipc_hwrev The hardware revision of the ChipCommon core from which + * @p cid was parsed. + * @param[out] ncores On success, will be set to the correct core count. + * + * @retval 0 If the core count is already correct, or was mapped to a + * a correct value. + * @retval EINVAL If the core count is incorrect, but the chip was not + * recognized. + */ +int +bhnd_chipid_fixed_ncores(const struct bhnd_chipid *cid, uint16_t chipc_hwrev, + uint8_t *ncores) +{ + /* bcma(4), and most siba(4) devices */ + if (CHIPC_NCORES_MIN_HWREV(chipc_hwrev)) { + *ncores = cid->ncores; + return (0); + } + + /* broken siba(4) chipsets */ + switch (cid->chip_id) { + case BHND_CHIPID_BCM4306: + *ncores = 6; + break; + case BHND_CHIPID_BCM4704: + *ncores = 9; + break; + case BHND_CHIPID_BCM5365: + /* + * BCM5365 does support ID_NUMCORE in at least + * some of its revisions, but for unknown + * reasons, Broadcom's drivers always exclude + * the ChipCommon revision (0x5) used by BCM5365 + * from the set of revisions supporting + * ID_NUMCORE, and instead supply a fixed value. + * + * Presumably, at least some of these devices + * shipped with a broken ID_NUMCORE value. + */ + *ncores = 7; + break; + default: + return (EINVAL); + } + + return (0); +} + /** * Allocate the resource defined by @p rs via @p dev, use it * to read the ChipCommon ID register relative to @p chipc_offset, @@ -894,6 +953,27 @@ bhnd_read_chipid(device_t dev, struct re *result = bhnd_parse_chipid(reg, enum_addr); + /* Fix the core count on early siba(4) devices */ + if (chip_type == BHND_CHIPTYPE_SIBA) { + uint32_t idh; + uint16_t chipc_hwrev; + + /* + * We need the ChipCommon revision to determine whether + * the ncore field is valid. + * + * We can safely assume the siba IDHIGH register is mapped + * within the chipc register block. + */ + idh = bus_read_4(res, SB0_REG_ABS(SIBA_CFG0_IDHIGH)); + chipc_hwrev = SIBA_IDH_CORE_REV(idh); + + error = bhnd_chipid_fixed_ncores(result, chipc_hwrev, + &result->ncores); + if (error) + goto cleanup; + } + cleanup: /* Clean up */ bus_release_resource(dev, rtype, rid, res); Modified: head/sys/dev/bhnd/siba/siba.c ============================================================================== --- head/sys/dev/bhnd/siba/siba.c Sun Aug 28 20:39:33 2016 (r304966) +++ head/sys/dev/bhnd/siba/siba.c Sun Aug 28 20:39:53 2016 (r304967) @@ -635,35 +635,12 @@ siba_add_children(device_t dev, const st ccreg = bus_read_4(r, CHIPC_ID); ccid = bhnd_parse_chipid(ccreg, SIBA_ENUM_ADDR); - if (!CHIPC_NCORES_MIN_HWREV(ccrev)) { - switch (ccid.chip_id) { - case BHND_CHIPID_BCM4306: - ccid.ncores = 6; - break; - case BHND_CHIPID_BCM4704: - ccid.ncores = 9; - break; - case BHND_CHIPID_BCM5365: - /* - * BCM5365 does support ID_NUMCORE in at least - * some of its revisions, but for unknown - * reasons, Broadcom's drivers always exclude - * the ChipCommon revision (0x5) used by BCM5365 - * from the set of revisions supporting - * ID_NUMCORE, and instead supply a fixed value. - * - * Presumably, at least some of these devices - * shipped with a broken ID_NUMCORE value. - */ - ccid.ncores = 7; - break; - default: - device_printf(dev, "unable to determine core " - "count for unrecognized chipset 0x%hx\n", - ccid.chip_id); - error = ENXIO; - goto cleanup; - } + /* Fix up the core count */ + error = bhnd_chipid_fixed_ncores(&ccid, ccrev, &ccid.ncores); + if (error) { + device_printf(dev, "unable to determine core count for " + "chipset 0x%hx\n", ccid.chip_id); + goto cleanup; } chipid = &ccid;