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
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to