Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 18 Oct 2015 22:10:08 +0000 (UTC)
From:      Zbigniew Bodek <zbb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r289552 - in head/sys: conf dev/vnic
Message-ID:  <201510182210.t9IMA8aL026196@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: zbb
Date: Sun Oct 18 22:10:08 2015
New Revision: 289552
URL: https://svnweb.freebsd.org/changeset/base/289552

Log:
  Introduce driver for Cavium's ThunderX MDIO
  
  This commit adds support for MDIO present in the ThunderX SoC.
  From the FDT point of view it is compatible with "octeon-3860-mdio"
  however only C22 mode is used.
  The code also implements lmac_if interface functions.
  
  Obtained from: Semihalf
  Sponsored by:  The FreeBSD Foundation

Added:
  head/sys/dev/vnic/thunder_mdio.c   (contents, props changed)
  head/sys/dev/vnic/thunder_mdio_fdt.c   (contents, props changed)
  head/sys/dev/vnic/thunder_mdio_var.h   (contents, props changed)
Modified:
  head/sys/conf/files.arm64

Modified: head/sys/conf/files.arm64
==============================================================================
--- head/sys/conf/files.arm64	Sun Oct 18 22:02:58 2015	(r289551)
+++ head/sys/conf/files.arm64	Sun Oct 18 22:10:08 2015	(r289552)
@@ -73,6 +73,8 @@ dev/vnic/nicvf_main.c		optional	vnic pci
 dev/vnic/nicvf_queues.c		optional	vnic pci pci_iov
 dev/vnic/thunder_bgx_fdt.c	optional	vnic fdt
 dev/vnic/thunder_bgx.c		optional	vnic pci
+dev/vnic/thunder_mdio_fdt.c	optional	vnic fdt
+dev/vnic/thunder_mdio.c		optional	vnic
 dev/vnic/lmac_if.m		optional	vnic
 kern/kern_clocksource.c		standard
 kern/subr_dummy_vdso_tc.c	standard

Added: head/sys/dev/vnic/thunder_mdio.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/vnic/thunder_mdio.c	Sun Oct 18 22:10:08 2015	(r289552)
@@ -0,0 +1,512 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under
+ * the sponsorship of the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+#include <sys/queue.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_var.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include "thunder_mdio_var.h"
+
+#include "lmac_if.h"
+#include "miibus_if.h"
+
+#define	REG_BASE_RID	0
+
+#define	SMI_CMD				0x00
+#define	 SMI_CMD_PHY_REG_ADR_SHIFT	(0)
+#define	 SMI_CMD_PHY_REG_ADR_MASK	(0x1FUL << SMI_CMD_PHY_REG_ADR_SHIFT)
+#define	 SMI_CMD_PHY_ADR_SHIFT		(8)
+#define	 SMI_CMD_PHY_ADR_MASK		(0x1FUL << SMI_CMD_PHY_ADR_SHIFT)
+#define	 SMI_CMD_PHY_OP_MASK		(0x3UL << 16)
+#define	 SMI_CMD_PHY_OP_C22_READ	(0x1UL << 16)
+#define	 SMI_CMD_PHY_OP_C22_WRITE	(0x0UL << 16)
+#define	 SMI_CMD_PHY_OP_C45_READ	(0x3UL << 16)
+#define	 SMI_CMD_PHY_OP_C45_WRITE	(0x1UL << 16)
+#define	 SMI_CMD_PHY_OP_C45_ADDR	(0x0UL << 16)
+
+#define	SMI_WR_DAT			0x08
+#define	 SMI_WR_DAT_PENDING		(1UL << 17)
+#define	 SMI_WR_DAT_VAL			(1UL << 16)
+#define	 SMI_WR_DAT_DAT_MASK		(0xFFFFUL << 0)
+
+#define	SMI_RD_DAT			0x10
+#define	 SMI_RD_DAT_PENDING		(1UL << 17)
+#define	 SMI_RD_DAT_VAL			(1UL << 16)
+#define	 SMI_RD_DAT_DAT_MASK		(0xFFFFUL << 0)
+
+#define	SMI_CLK				0x18
+#define	 SMI_CLK_PREAMBLE		(1UL << 12)
+#define	 SMI_CLK_MODE			(1UL << 24)
+
+#define	SMI_EN				0x20
+#define	 SMI_EN_EN			(1UL << 0)	/* Enabele interface */
+
+#define	SMI_DRV_CTL			0x28
+
+static int thunder_mdio_detach(device_t);
+
+static int thunder_mdio_read(device_t, int, int);
+static int thunder_mdio_write(device_t, int, int, int);
+
+static int thunder_ifmedia_change_stub(struct ifnet *);
+static void thunder_ifmedia_status_stub(struct ifnet *, struct ifmediareq *);
+
+static int thunder_mdio_media_status(device_t, int, int *, int *, int *);
+static int thunder_mdio_media_change(device_t, int, int, int, int);
+static int thunder_mdio_phy_connect(device_t, int, int);
+static int thunder_mdio_phy_disconnect(device_t, int, int);
+
+static device_method_t thunder_mdio_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_detach,	thunder_mdio_detach),
+	/* LMAC interface */
+	DEVMETHOD(lmac_media_status,	thunder_mdio_media_status),
+	DEVMETHOD(lmac_media_change,	thunder_mdio_media_change),
+	DEVMETHOD(lmac_phy_connect,	thunder_mdio_phy_connect),
+	DEVMETHOD(lmac_phy_disconnect,	thunder_mdio_phy_disconnect),
+	/* MII interface */
+	DEVMETHOD(miibus_readreg,	thunder_mdio_read),
+	DEVMETHOD(miibus_writereg,	thunder_mdio_write),
+
+	/* End */
+	DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(thunder_mdio, thunder_mdio_driver, thunder_mdio_methods,
+    sizeof(struct thunder_mdio_softc));
+
+DRIVER_MODULE(miibus, thunder_mdio, miibus_driver, miibus_devclass, 0, 0);
+MODULE_DEPEND(thunder_mdio, ether, 1, 1, 1);
+MODULE_DEPEND(thunder_mdio, miibus, 1, 1, 1);
+
+MALLOC_DEFINE(M_THUNDER_MDIO, "ThunderX MDIO",
+    "Cavium ThunderX MDIO dynamic memory");
+
+#define	MDIO_LOCK_INIT(sc, name)			\
+    mtx_init(&(sc)->mtx, name, NULL, MTX_DEF)
+
+#define	MDIO_LOCK_DESTROY(sc)				\
+    mtx_destroy(&(sc)->mtx)
+
+#define	MDIO_LOCK(sc)	mtx_lock(&(sc)->mtx)
+#define	MDIO_UNLOCK(sc)	mtx_unlock(&(sc)->mtx)
+
+#define	MDIO_LOCK_ASSERT(sc)				\
+    mtx_assert(&(sc)->mtx, MA_OWNED)
+
+
+#define	mdio_reg_read(sc, reg)				\
+    bus_read_8((sc)->reg_base, (reg))
+
+#define	mdio_reg_write(sc, reg, val)			\
+    bus_write_8((sc)->reg_base, (reg), (val))
+
+int
+thunder_mdio_attach(device_t dev)
+{
+	struct thunder_mdio_softc *sc;
+	int rid;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	/* Allocate memory resources */
+	rid = REG_BASE_RID;
+	sc->reg_base = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->reg_base == NULL) {
+		device_printf(dev, "Could not allocate memory\n");
+		return (ENXIO);
+	}
+
+	TAILQ_INIT(&sc->phy_desc_head);
+	MDIO_LOCK_INIT(sc, "ThunderX MDIO lock");
+
+	/* Enable SMI/MDIO interface */
+	mdio_reg_write(sc, SMI_EN, SMI_EN_EN);
+
+	return (0);
+}
+
+static int
+thunder_mdio_detach(device_t dev)
+{
+	struct thunder_mdio_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	if (sc->reg_base != NULL) {
+		bus_release_resource(dev, SYS_RES_MEMORY, REG_BASE_RID,
+		    sc->reg_base);
+	}
+
+	return (0);
+}
+
+static __inline void
+thunder_mdio_set_mode(struct thunder_mdio_softc *sc,
+    enum thunder_mdio_mode mode)
+{
+	uint64_t smi_clk;
+
+	if (sc->mode == mode)
+		return;
+
+	/* Set mode, IEEE CLAUSE 22 or IEEE CAUSE 45 */
+	smi_clk = mdio_reg_read(sc, SMI_CLK);
+	if (mode == MODE_IEEE_C22)
+		smi_clk &= ~SMI_CLK_MODE;
+	else
+		smi_clk |= SMI_CLK_MODE;
+	/* Enable sending 32 bit preable on SMI transactions */
+	smi_clk |= SMI_CLK_PREAMBLE;
+	/* Saved setings */
+	mdio_reg_write(sc, SMI_CLK, smi_clk);
+	sc->mode = mode;
+}
+
+static int
+thunder_mdio_c45_addr(struct thunder_mdio_softc *sc, int phy, int reg)
+{
+	uint64_t smi_cmd, smi_wr_dat;
+	ssize_t timeout;
+
+	thunder_mdio_set_mode(sc, MODE_IEEE_C45);
+
+	/* Prepare data for transmission */
+	mdio_reg_write(sc, SMI_WR_DAT, reg & SMI_WR_DAT_DAT_MASK);
+	/*
+	 * Assemble command
+	 */
+	smi_cmd = 0;
+	/* Set opcode */
+	smi_cmd |= SMI_CMD_PHY_OP_C45_WRITE;
+
+	/* Set PHY address */
+	smi_cmd |= ((phy << SMI_CMD_PHY_ADR_SHIFT) & SMI_CMD_PHY_ADR_MASK);
+	/* Set PHY register offset */
+	smi_cmd |= ((reg << SMI_CMD_PHY_REG_ADR_SHIFT) &
+	    SMI_CMD_PHY_REG_ADR_MASK);
+
+	mdio_reg_write(sc, SMI_CMD, smi_cmd);
+	for (timeout = 1000; timeout > 0; timeout--) {
+		smi_wr_dat = mdio_reg_read(sc, SMI_WR_DAT);
+		if (smi_wr_dat & SMI_WR_DAT_PENDING)
+			DELAY(1000);
+		else
+			break;
+	}
+
+	if (timeout <= 0)
+		return (EIO);
+	else {
+		/* Return 0 on success */
+		return (0);
+	}
+}
+
+static int
+thunder_mdio_read(device_t dev, int phy, int reg)
+{
+	struct thunder_mdio_softc *sc;
+	uint64_t smi_cmd, smi_rd_dat;
+	ssize_t timeout;
+	int err;
+
+	sc = device_get_softc(dev);
+
+	/* XXX Always C22 - for <= 1Gbps only */
+	thunder_mdio_set_mode(sc, MODE_IEEE_C22);
+
+	/*
+	 * Assemble command
+	 */
+	smi_cmd = 0;
+	/* Set opcode */
+	if (sc->mode == MODE_IEEE_C22)
+		smi_cmd |= SMI_CMD_PHY_OP_C22_READ;
+	else {
+		smi_cmd |= SMI_CMD_PHY_OP_C45_READ;
+		err = thunder_mdio_c45_addr(sc, phy, reg);
+		if (err != 0)
+			return (err);
+
+		reg = (reg >> 16) & 0x1F;
+	}
+
+	/* Set PHY address */
+	smi_cmd |= ((phy << SMI_CMD_PHY_ADR_SHIFT) & SMI_CMD_PHY_ADR_MASK);
+	/* Set PHY register offset */
+	smi_cmd |= ((reg << SMI_CMD_PHY_REG_ADR_SHIFT) &
+	    SMI_CMD_PHY_REG_ADR_MASK);
+
+	mdio_reg_write(sc, SMI_CMD, smi_cmd);
+	for (timeout = 1000; timeout > 0; timeout--) {
+		smi_rd_dat = mdio_reg_read(sc, SMI_RD_DAT);
+		if (smi_rd_dat & SMI_RD_DAT_PENDING)
+			DELAY(1000);
+		else
+			break;
+	}
+
+	if (smi_rd_dat & SMI_RD_DAT_VAL)
+		return (smi_rd_dat & SMI_RD_DAT_DAT_MASK);
+	else {
+		/* Return 0 on error */
+		return (0);
+	}
+}
+
+static int
+thunder_mdio_write(device_t dev, int phy, int reg, int data)
+{
+	struct thunder_mdio_softc *sc;
+	uint64_t smi_cmd, smi_wr_dat;
+	ssize_t timeout;
+
+	sc = device_get_softc(dev);
+
+	/* XXX Always C22 - for <= 1Gbps only */
+	thunder_mdio_set_mode(sc, MODE_IEEE_C22);
+
+	/* Prepare data for transmission */
+	mdio_reg_write(sc, SMI_WR_DAT, data & SMI_WR_DAT_DAT_MASK);
+	/*
+	 * Assemble command
+	 */
+	smi_cmd = 0;
+	/* Set opcode */
+	if (sc->mode == MODE_IEEE_C22)
+		smi_cmd |= SMI_CMD_PHY_OP_C22_WRITE;
+	else
+		smi_cmd |= SMI_CMD_PHY_OP_C45_WRITE;
+
+	/* Set PHY address */
+	smi_cmd |= ((phy << SMI_CMD_PHY_ADR_SHIFT) & SMI_CMD_PHY_ADR_MASK);
+	/* Set PHY register offset */
+	smi_cmd |= ((reg << SMI_CMD_PHY_REG_ADR_SHIFT) &
+	    SMI_CMD_PHY_REG_ADR_MASK);
+
+	mdio_reg_write(sc, SMI_CMD, smi_cmd);
+	for (timeout = 1000; timeout > 0; timeout--) {
+		smi_wr_dat = mdio_reg_read(sc, SMI_WR_DAT);
+		if (smi_wr_dat & SMI_WR_DAT_PENDING)
+			DELAY(1000);
+		else
+			break;
+	}
+
+	if (timeout <= 0)
+		return (EIO);
+	else {
+		/* Return 0 on success */
+		return (0);
+	}
+}
+
+static int
+thunder_ifmedia_change_stub(struct ifnet *ifp __unused)
+{
+	/* Will never be called by if_media */
+	return (0);
+}
+
+static void
+thunder_ifmedia_status_stub(struct ifnet *ifp __unused, struct ifmediareq
+    *ifmr __unused)
+{
+	/* Will never be called by if_media */
+}
+
+static __inline struct phy_desc *
+get_phy_desc(struct thunder_mdio_softc *sc, int lmacid)
+{
+	struct phy_desc *pd = NULL;
+
+	MDIO_LOCK_ASSERT(sc);
+	TAILQ_FOREACH(pd, &sc->phy_desc_head, phy_desc_list) {
+		if (pd->lmacid == lmacid)
+			break;
+	}
+
+	return (pd);
+}
+static int
+thunder_mdio_media_status(device_t dev, int lmacid, int *link, int *duplex,
+    int *speed)
+{
+	struct thunder_mdio_softc *sc;
+	struct mii_data *mii_sc;
+	struct phy_desc *pd;
+
+	sc = device_get_softc(dev);
+
+	MDIO_LOCK(sc);
+	pd = get_phy_desc(sc, lmacid);
+	if (pd == NULL) {
+		/* Panic when invariants are enabled, fail otherwise. */
+		KASSERT(0, ("%s: no PHY descriptor for LMAC%d",
+		    __func__, lmacid));
+		MDIO_UNLOCK(sc);
+		return (ENXIO);
+	}
+	mii_sc = device_get_softc(pd->miibus);
+
+	mii_tick(mii_sc);
+	if ((mii_sc->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+	    (IFM_ACTIVE | IFM_AVALID)) {
+		/* Link is up */
+		*link = 1;
+	} else
+		*link = 0;
+
+	switch (IFM_SUBTYPE(mii_sc->mii_media_active)) {
+	case IFM_10_T:
+		*speed = 10;
+		break;
+	case IFM_100_TX:
+		*speed = 100;
+		break;
+	case IFM_1000_T:
+		*speed = 1000;
+		break;
+	default:
+		/* IFM_NONE */
+		*speed = 0;
+	}
+
+	if ((IFM_OPTIONS(mii_sc->mii_media_active) & IFM_FDX) != 0)
+		*duplex = 1;
+	else
+		*duplex = 0;
+
+	MDIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+thunder_mdio_media_change(device_t dev, int lmacid, int link, int duplex,
+    int speed)
+{
+
+	return (EIO);
+}
+
+static int
+thunder_mdio_phy_connect(device_t dev, int lmacid, int phy)
+{
+	struct thunder_mdio_softc *sc;
+	struct phy_desc *pd;
+	int err;
+
+	sc = device_get_softc(dev);
+
+	MDIO_LOCK(sc);
+	pd = get_phy_desc(sc, lmacid);
+	MDIO_UNLOCK(sc);
+	if (pd == NULL) {
+		pd = malloc(sizeof(*pd), M_THUNDER_MDIO, (M_NOWAIT | M_ZERO));
+		if (pd == NULL)
+			return (ENOMEM);
+		pd->ifp = if_alloc(IFT_ETHER);
+		if (pd->ifp == NULL) {
+			free(pd, M_THUNDER_MDIO);
+			return (ENOMEM);
+		}
+		pd->lmacid = lmacid;
+	}
+
+	err = mii_attach(dev, &pd->miibus, pd->ifp,
+	    thunder_ifmedia_change_stub, thunder_ifmedia_status_stub,
+	    BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0);
+
+	if (err != 0) {
+		device_printf(dev, "Could not attach PHY%d\n", phy);
+		if_free(pd->ifp);
+		free(pd, M_THUNDER_MDIO);
+		return (ENXIO);
+	}
+
+	MDIO_LOCK(sc);
+	TAILQ_INSERT_TAIL(&sc->phy_desc_head, pd, phy_desc_list);
+	MDIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+thunder_mdio_phy_disconnect(device_t dev, int lmacid, int phy)
+{
+	struct thunder_mdio_softc *sc;
+	struct phy_desc *pd;
+
+	sc = device_get_softc(dev);
+	MDIO_LOCK(sc);
+
+	pd = get_phy_desc(sc, lmacid);
+	if (pd == NULL) {
+		MDIO_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	/* Remove this PHY descriptor from the list */
+	TAILQ_REMOVE(&sc->phy_desc_head, pd, phy_desc_list);
+
+	/* Detach miibus */
+	bus_generic_detach(dev);
+	device_delete_child(dev, pd->miibus);
+	/* Free fake ifnet */
+	if_free(pd->ifp);
+	/* Free memory under phy descriptor */
+	free(pd, M_THUNDER_MDIO);
+	MDIO_UNLOCK(sc);
+
+	return (0);
+}

Added: head/sys/dev/vnic/thunder_mdio_fdt.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/vnic/thunder_mdio_fdt.c	Sun Oct 18 22:10:08 2015	(r289552)
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under
+ * the sponsorship of the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "thunder_mdio_var.h"
+
+static int thunder_mdio_fdt_probe(device_t);
+static int thunder_mdio_fdt_attach(device_t);
+
+static device_method_t thunder_mdio_fdt_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		thunder_mdio_fdt_probe),
+	DEVMETHOD(device_attach,	thunder_mdio_fdt_attach),
+
+	/* End */
+	DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(thunder_mdio, thunder_mdio_fdt_driver, thunder_mdio_fdt_methods,
+    sizeof(struct thunder_mdio_softc), thunder_mdio_driver);
+
+static devclass_t thunder_mdio_fdt_devclass;
+
+DRIVER_MODULE(thunder_mdio, ofwbus, thunder_mdio_fdt_driver,
+    thunder_mdio_fdt_devclass, 0, 0);
+
+static int
+thunder_mdio_fdt_probe(device_t dev)
+{
+
+	if (ofw_bus_is_compatible(dev, "cavium,octeon-3860-mdio")) {
+		device_set_desc(dev, THUNDER_MDIO_DEVSTR);
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+thunder_mdio_fdt_attach(device_t dev)
+{
+	phandle_t node;
+	int ret;
+
+	/* Call core attach */
+	ret = thunder_mdio_attach(dev);
+	if (ret != 0)
+		return (ret);
+	/*
+	 * Register device to this node/xref.
+	 * Thanks to that we will be able to retrieve device_t structure
+	 * while holding only node reference acquired from FDT.
+	 */
+	node = ofw_bus_get_node(dev);
+	OF_device_register_xref(OF_xref_from_node(node), dev);
+
+	return (0);
+}

Added: head/sys/dev/vnic/thunder_mdio_var.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/vnic/thunder_mdio_var.h	Sun Oct 18 22:10:08 2015	(r289552)
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under
+ * the sponsorship of the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#ifndef __THUNDER_MDIO_VAR_H__
+#define	__THUNDER_MDIO_VAR_H__
+
+#define	THUNDER_MDIO_DEVSTR	"Cavium ThunderX SMI/MDIO driver"
+DECLARE_CLASS(thunder_mdio_driver);
+
+enum thunder_mdio_mode {
+	MODE_NONE = 0,
+	MODE_IEEE_C22,
+	MODE_IEEE_C45
+};
+
+struct phy_desc {
+	device_t		miibus; /* One miibus per LMAC */
+	struct ifnet *		ifp;	/* Fake ifp to satisfy miibus */
+	int			lmacid;	/* ID number of LMAC connected */
+	TAILQ_ENTRY(phy_desc)	phy_desc_list;
+};
+
+struct thunder_mdio_softc {
+	device_t		dev;
+	struct mtx		mtx;
+	struct resource *	reg_base;
+
+	enum thunder_mdio_mode	mode;
+
+	TAILQ_HEAD(,phy_desc)	phy_desc_head;
+};
+
+int thunder_mdio_attach(device_t);
+#endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201510182210.t9IMA8aL026196>