1*ba7319e9SDmitry Salychev /*- 2*ba7319e9SDmitry Salychev * SPDX-License-Identifier: BSD-2-Clause 3*ba7319e9SDmitry Salychev * 4*ba7319e9SDmitry Salychev * Copyright © 2021-2022 Dmitry Salychev 5*ba7319e9SDmitry Salychev * 6*ba7319e9SDmitry Salychev * Redistribution and use in source and binary forms, with or without 7*ba7319e9SDmitry Salychev * modification, are permitted provided that the following conditions 8*ba7319e9SDmitry Salychev * are met: 9*ba7319e9SDmitry Salychev * 1. Redistributions of source code must retain the above copyright 10*ba7319e9SDmitry Salychev * notice, this list of conditions and the following disclaimer. 11*ba7319e9SDmitry Salychev * 2. Redistributions in binary form must reproduce the above copyright 12*ba7319e9SDmitry Salychev * notice, this list of conditions and the following disclaimer in the 13*ba7319e9SDmitry Salychev * documentation and/or other materials provided with the distribution. 14*ba7319e9SDmitry Salychev * 15*ba7319e9SDmitry Salychev * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*ba7319e9SDmitry Salychev * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*ba7319e9SDmitry Salychev * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*ba7319e9SDmitry Salychev * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*ba7319e9SDmitry Salychev * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*ba7319e9SDmitry Salychev * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*ba7319e9SDmitry Salychev * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*ba7319e9SDmitry Salychev * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*ba7319e9SDmitry Salychev * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*ba7319e9SDmitry Salychev * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*ba7319e9SDmitry Salychev * SUCH DAMAGE. 26*ba7319e9SDmitry Salychev */ 27*ba7319e9SDmitry Salychev 28*ba7319e9SDmitry Salychev #include <sys/cdefs.h> 29*ba7319e9SDmitry Salychev __FBSDID("$FreeBSD$"); 30*ba7319e9SDmitry Salychev 31*ba7319e9SDmitry Salychev /* 32*ba7319e9SDmitry Salychev * The DPAA2 MAC driver. 33*ba7319e9SDmitry Salychev * 34*ba7319e9SDmitry Salychev * For every DPAA2 MAC, there is an MC object named DPMAC, for MDIO and link 35*ba7319e9SDmitry Salychev * state updates. The DPMAC virtualizes the MDIO interface, so each PHY driver 36*ba7319e9SDmitry Salychev * may see a private interface (removing the need for synchronization in GPP on 37*ba7319e9SDmitry Salychev * the multiplexed MDIO hardware). 38*ba7319e9SDmitry Salychev */ 39*ba7319e9SDmitry Salychev 40*ba7319e9SDmitry Salychev #include <sys/param.h> 41*ba7319e9SDmitry Salychev #include <sys/kernel.h> 42*ba7319e9SDmitry Salychev #include <sys/bus.h> 43*ba7319e9SDmitry Salychev #include <sys/rman.h> 44*ba7319e9SDmitry Salychev #include <sys/module.h> 45*ba7319e9SDmitry Salychev #include <sys/malloc.h> 46*ba7319e9SDmitry Salychev #include <sys/mutex.h> 47*ba7319e9SDmitry Salychev 48*ba7319e9SDmitry Salychev #include <vm/vm.h> 49*ba7319e9SDmitry Salychev 50*ba7319e9SDmitry Salychev #include <machine/bus.h> 51*ba7319e9SDmitry Salychev #include <machine/resource.h> 52*ba7319e9SDmitry Salychev 53*ba7319e9SDmitry Salychev #include <dev/pci/pcivar.h> 54*ba7319e9SDmitry Salychev 55*ba7319e9SDmitry Salychev #include "pcib_if.h" 56*ba7319e9SDmitry Salychev #include "pci_if.h" 57*ba7319e9SDmitry Salychev 58*ba7319e9SDmitry Salychev #include "dpaa2_mc.h" 59*ba7319e9SDmitry Salychev #include "dpaa2_ni.h" 60*ba7319e9SDmitry Salychev #include "dpaa2_mcp.h" 61*ba7319e9SDmitry Salychev #include "dpaa2_swp.h" 62*ba7319e9SDmitry Salychev #include "dpaa2_swp_if.h" 63*ba7319e9SDmitry Salychev #include "dpaa2_cmd_if.h" 64*ba7319e9SDmitry Salychev 65*ba7319e9SDmitry Salychev /* Index of the only DPMAC IRQ. */ 66*ba7319e9SDmitry Salychev #define DPMAC_IRQ_INDEX 0 67*ba7319e9SDmitry Salychev 68*ba7319e9SDmitry Salychev /* DPMAC IRQ statuses. */ 69*ba7319e9SDmitry Salychev #define DPMAC_IRQ_LINK_CFG_REQ 0x00000001 /* change in requested link config. */ 70*ba7319e9SDmitry Salychev #define DPMAC_IRQ_LINK_CHANGED 0x00000002 /* link state changed */ 71*ba7319e9SDmitry Salychev #define DPMAC_IRQ_LINK_UP_REQ 0x00000004 /* link up request */ 72*ba7319e9SDmitry Salychev #define DPMAC_IRQ_LINK_DOWN_REQ 0x00000008 /* link down request */ 73*ba7319e9SDmitry Salychev #define DPMAC_IRQ_EP_CHANGED 0x00000010 /* DPAA2 endpoint dis/connected */ 74*ba7319e9SDmitry Salychev 75*ba7319e9SDmitry Salychev /* DPAA2 MAC resource specification. */ 76*ba7319e9SDmitry Salychev struct resource_spec dpaa2_mac_spec[] = { 77*ba7319e9SDmitry Salychev /* 78*ba7319e9SDmitry Salychev * DPMCP resources. 79*ba7319e9SDmitry Salychev * 80*ba7319e9SDmitry Salychev * NOTE: MC command portals (MCPs) are used to send commands to, and 81*ba7319e9SDmitry Salychev * receive responses from, the MC firmware. One portal per DPMAC. 82*ba7319e9SDmitry Salychev */ 83*ba7319e9SDmitry Salychev #define MCP_RES_NUM (1u) 84*ba7319e9SDmitry Salychev #define MCP_RID_OFF (0u) 85*ba7319e9SDmitry Salychev #define MCP_RID(rid) ((rid) + MCP_RID_OFF) 86*ba7319e9SDmitry Salychev /* --- */ 87*ba7319e9SDmitry Salychev { DPAA2_DEV_MCP, MCP_RID(0), RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL }, 88*ba7319e9SDmitry Salychev /* --- */ 89*ba7319e9SDmitry Salychev RESOURCE_SPEC_END 90*ba7319e9SDmitry Salychev }; 91*ba7319e9SDmitry Salychev 92*ba7319e9SDmitry Salychev /* Interrupt configuration routines. */ 93*ba7319e9SDmitry Salychev static int dpaa2_mac_setup_irq(device_t); 94*ba7319e9SDmitry Salychev static int dpaa2_mac_setup_msi(struct dpaa2_mac_softc *); 95*ba7319e9SDmitry Salychev 96*ba7319e9SDmitry Salychev /* Subroutines to get text representation. */ 97*ba7319e9SDmitry Salychev static const char *dpaa2_mac_ethif_to_str(enum dpaa2_mac_eth_if); 98*ba7319e9SDmitry Salychev static const char *dpaa2_mac_link_type_to_str(enum dpaa2_mac_link_type); 99*ba7319e9SDmitry Salychev 100*ba7319e9SDmitry Salychev /* Interrupt handlers */ 101*ba7319e9SDmitry Salychev static void dpaa2_mac_intr(void *arg); 102*ba7319e9SDmitry Salychev 103*ba7319e9SDmitry Salychev static int 104*ba7319e9SDmitry Salychev dpaa2_mac_probe(device_t dev) 105*ba7319e9SDmitry Salychev { 106*ba7319e9SDmitry Salychev /* DPIO device will be added by a parent resource container itself. */ 107*ba7319e9SDmitry Salychev device_set_desc(dev, "DPAA2 MAC"); 108*ba7319e9SDmitry Salychev return (BUS_PROBE_DEFAULT); 109*ba7319e9SDmitry Salychev } 110*ba7319e9SDmitry Salychev 111*ba7319e9SDmitry Salychev static int 112*ba7319e9SDmitry Salychev dpaa2_mac_attach(device_t dev) 113*ba7319e9SDmitry Salychev { 114*ba7319e9SDmitry Salychev device_t pdev = device_get_parent(dev); 115*ba7319e9SDmitry Salychev device_t child = dev; 116*ba7319e9SDmitry Salychev device_t mcp_dev; 117*ba7319e9SDmitry Salychev struct dpaa2_mac_softc *sc = device_get_softc(dev); 118*ba7319e9SDmitry Salychev struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev); 119*ba7319e9SDmitry Salychev struct dpaa2_devinfo *dinfo = device_get_ivars(dev); 120*ba7319e9SDmitry Salychev struct dpaa2_devinfo *mcp_dinfo; 121*ba7319e9SDmitry Salychev int error; 122*ba7319e9SDmitry Salychev 123*ba7319e9SDmitry Salychev sc->dev = dev; 124*ba7319e9SDmitry Salychev 125*ba7319e9SDmitry Salychev memset(sc->addr, 0, ETHER_ADDR_LEN); 126*ba7319e9SDmitry Salychev 127*ba7319e9SDmitry Salychev error = bus_alloc_resources(sc->dev, dpaa2_mac_spec, sc->res); 128*ba7319e9SDmitry Salychev if (error) { 129*ba7319e9SDmitry Salychev device_printf(dev, "%s: failed to allocate resources: " 130*ba7319e9SDmitry Salychev "error=%d\n", __func__, error); 131*ba7319e9SDmitry Salychev return (ENXIO); 132*ba7319e9SDmitry Salychev } 133*ba7319e9SDmitry Salychev 134*ba7319e9SDmitry Salychev /* Obtain MC portal. */ 135*ba7319e9SDmitry Salychev mcp_dev = (device_t) rman_get_start(sc->res[MCP_RID(0)]); 136*ba7319e9SDmitry Salychev mcp_dinfo = device_get_ivars(mcp_dev); 137*ba7319e9SDmitry Salychev dinfo->portal = mcp_dinfo->portal; 138*ba7319e9SDmitry Salychev 139*ba7319e9SDmitry Salychev /* Allocate a command to send to MC hardware. */ 140*ba7319e9SDmitry Salychev error = dpaa2_mcp_init_command(&sc->cmd, DPAA2_CMD_DEF); 141*ba7319e9SDmitry Salychev if (error) { 142*ba7319e9SDmitry Salychev device_printf(dev, "Failed to allocate dpaa2_cmd: error=%d\n", 143*ba7319e9SDmitry Salychev error); 144*ba7319e9SDmitry Salychev goto err_exit; 145*ba7319e9SDmitry Salychev } 146*ba7319e9SDmitry Salychev 147*ba7319e9SDmitry Salychev /* Open resource container and DPMAC object. */ 148*ba7319e9SDmitry Salychev error = DPAA2_CMD_RC_OPEN(dev, child, sc->cmd, rcinfo->id, 149*ba7319e9SDmitry Salychev &sc->rc_token); 150*ba7319e9SDmitry Salychev if (error) { 151*ba7319e9SDmitry Salychev device_printf(dev, "Failed to open DPRC: error=%d\n", error); 152*ba7319e9SDmitry Salychev goto err_free_cmd; 153*ba7319e9SDmitry Salychev } 154*ba7319e9SDmitry Salychev error = DPAA2_CMD_MAC_OPEN(dev, child, sc->cmd, dinfo->id, 155*ba7319e9SDmitry Salychev &sc->mac_token); 156*ba7319e9SDmitry Salychev if (error) { 157*ba7319e9SDmitry Salychev device_printf(dev, "Failed to open DPMAC: id=%d, error=%d\n", 158*ba7319e9SDmitry Salychev dinfo->id, error); 159*ba7319e9SDmitry Salychev goto err_close_rc; 160*ba7319e9SDmitry Salychev } 161*ba7319e9SDmitry Salychev 162*ba7319e9SDmitry Salychev error = DPAA2_CMD_MAC_GET_ATTRIBUTES(dev, child, sc->cmd, &sc->attr); 163*ba7319e9SDmitry Salychev if (error) { 164*ba7319e9SDmitry Salychev device_printf(dev, "Failed to get DPMAC attributes: id=%d, " 165*ba7319e9SDmitry Salychev "error=%d\n", dinfo->id, error); 166*ba7319e9SDmitry Salychev goto err_close_mac; 167*ba7319e9SDmitry Salychev } 168*ba7319e9SDmitry Salychev error = DPAA2_CMD_MAC_GET_ADDR(dev, child, sc->cmd, sc->addr); 169*ba7319e9SDmitry Salychev if (error) 170*ba7319e9SDmitry Salychev device_printf(dev, "Failed to get physical address: error=%d\n", 171*ba7319e9SDmitry Salychev error); 172*ba7319e9SDmitry Salychev /* 173*ba7319e9SDmitry Salychev * TODO: Enable debug output via sysctl. 174*ba7319e9SDmitry Salychev */ 175*ba7319e9SDmitry Salychev if (bootverbose) { 176*ba7319e9SDmitry Salychev device_printf(dev, "ether %6D\n", sc->addr, ":"); 177*ba7319e9SDmitry Salychev device_printf(dev, "max_rate=%d, eth_if=%s, link_type=%s\n", 178*ba7319e9SDmitry Salychev sc->attr.max_rate, 179*ba7319e9SDmitry Salychev dpaa2_mac_ethif_to_str(sc->attr.eth_if), 180*ba7319e9SDmitry Salychev dpaa2_mac_link_type_to_str(sc->attr.link_type)); 181*ba7319e9SDmitry Salychev } 182*ba7319e9SDmitry Salychev 183*ba7319e9SDmitry Salychev error = dpaa2_mac_setup_irq(dev); 184*ba7319e9SDmitry Salychev if (error) { 185*ba7319e9SDmitry Salychev device_printf(dev, "Failed to setup IRQs: error=%d\n", error); 186*ba7319e9SDmitry Salychev goto err_close_mac; 187*ba7319e9SDmitry Salychev } 188*ba7319e9SDmitry Salychev 189*ba7319e9SDmitry Salychev return (0); 190*ba7319e9SDmitry Salychev 191*ba7319e9SDmitry Salychev err_close_mac: 192*ba7319e9SDmitry Salychev DPAA2_CMD_MAC_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->mac_token)); 193*ba7319e9SDmitry Salychev err_close_rc: 194*ba7319e9SDmitry Salychev DPAA2_CMD_RC_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->rc_token)); 195*ba7319e9SDmitry Salychev err_free_cmd: 196*ba7319e9SDmitry Salychev dpaa2_mcp_free_command(sc->cmd); 197*ba7319e9SDmitry Salychev err_exit: 198*ba7319e9SDmitry Salychev return (ENXIO); 199*ba7319e9SDmitry Salychev } 200*ba7319e9SDmitry Salychev 201*ba7319e9SDmitry Salychev static int 202*ba7319e9SDmitry Salychev dpaa2_mac_detach(device_t dev) 203*ba7319e9SDmitry Salychev { 204*ba7319e9SDmitry Salychev device_t child = dev; 205*ba7319e9SDmitry Salychev struct dpaa2_mac_softc *sc = device_get_softc(dev); 206*ba7319e9SDmitry Salychev 207*ba7319e9SDmitry Salychev DPAA2_CMD_MAC_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->mac_token)); 208*ba7319e9SDmitry Salychev DPAA2_CMD_RC_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->rc_token)); 209*ba7319e9SDmitry Salychev dpaa2_mcp_free_command(sc->cmd); 210*ba7319e9SDmitry Salychev 211*ba7319e9SDmitry Salychev sc->cmd = NULL; 212*ba7319e9SDmitry Salychev sc->rc_token = 0; 213*ba7319e9SDmitry Salychev sc->mac_token = 0; 214*ba7319e9SDmitry Salychev 215*ba7319e9SDmitry Salychev return (0); 216*ba7319e9SDmitry Salychev } 217*ba7319e9SDmitry Salychev 218*ba7319e9SDmitry Salychev /** 219*ba7319e9SDmitry Salychev * @brief Configure DPMAC object to generate interrupts. 220*ba7319e9SDmitry Salychev */ 221*ba7319e9SDmitry Salychev static int 222*ba7319e9SDmitry Salychev dpaa2_mac_setup_irq(device_t dev) 223*ba7319e9SDmitry Salychev { 224*ba7319e9SDmitry Salychev device_t child = dev; 225*ba7319e9SDmitry Salychev struct dpaa2_mac_softc *sc = device_get_softc(dev); 226*ba7319e9SDmitry Salychev struct dpaa2_cmd *cmd = sc->cmd; 227*ba7319e9SDmitry Salychev uint16_t mac_token = sc->mac_token; 228*ba7319e9SDmitry Salychev uint32_t irq_mask; 229*ba7319e9SDmitry Salychev int error; 230*ba7319e9SDmitry Salychev 231*ba7319e9SDmitry Salychev /* Configure IRQs. */ 232*ba7319e9SDmitry Salychev error = dpaa2_mac_setup_msi(sc); 233*ba7319e9SDmitry Salychev if (error) { 234*ba7319e9SDmitry Salychev device_printf(dev, "Failed to allocate MSI\n"); 235*ba7319e9SDmitry Salychev return (error); 236*ba7319e9SDmitry Salychev } 237*ba7319e9SDmitry Salychev if ((sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 238*ba7319e9SDmitry Salychev &sc->irq_rid[0], RF_ACTIVE | RF_SHAREABLE)) == NULL) { 239*ba7319e9SDmitry Salychev device_printf(dev, "Failed to allocate IRQ resource\n"); 240*ba7319e9SDmitry Salychev return (ENXIO); 241*ba7319e9SDmitry Salychev } 242*ba7319e9SDmitry Salychev if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, 243*ba7319e9SDmitry Salychev NULL, dpaa2_mac_intr, sc, &sc->intr)) { 244*ba7319e9SDmitry Salychev device_printf(dev, "Failed to setup IRQ resource\n"); 245*ba7319e9SDmitry Salychev return (ENXIO); 246*ba7319e9SDmitry Salychev } 247*ba7319e9SDmitry Salychev 248*ba7319e9SDmitry Salychev /* Configure DPNI to generate interrupts. */ 249*ba7319e9SDmitry Salychev irq_mask = 250*ba7319e9SDmitry Salychev DPMAC_IRQ_LINK_CFG_REQ | 251*ba7319e9SDmitry Salychev DPMAC_IRQ_LINK_CHANGED | 252*ba7319e9SDmitry Salychev DPMAC_IRQ_LINK_UP_REQ | 253*ba7319e9SDmitry Salychev DPMAC_IRQ_LINK_DOWN_REQ | 254*ba7319e9SDmitry Salychev DPMAC_IRQ_EP_CHANGED; 255*ba7319e9SDmitry Salychev error = DPAA2_CMD_MAC_SET_IRQ_MASK(dev, child, dpaa2_mcp_tk(cmd, 256*ba7319e9SDmitry Salychev mac_token), DPMAC_IRQ_INDEX, irq_mask); 257*ba7319e9SDmitry Salychev if (error) { 258*ba7319e9SDmitry Salychev device_printf(dev, "Failed to set IRQ mask\n"); 259*ba7319e9SDmitry Salychev return (error); 260*ba7319e9SDmitry Salychev } 261*ba7319e9SDmitry Salychev 262*ba7319e9SDmitry Salychev /* Enable IRQ. */ 263*ba7319e9SDmitry Salychev error = DPAA2_CMD_MAC_SET_IRQ_ENABLE(dev, child, cmd, DPMAC_IRQ_INDEX, 264*ba7319e9SDmitry Salychev true); 265*ba7319e9SDmitry Salychev if (error) { 266*ba7319e9SDmitry Salychev device_printf(dev, "Failed to enable IRQ\n"); 267*ba7319e9SDmitry Salychev return (error); 268*ba7319e9SDmitry Salychev } 269*ba7319e9SDmitry Salychev 270*ba7319e9SDmitry Salychev return (0); 271*ba7319e9SDmitry Salychev } 272*ba7319e9SDmitry Salychev 273*ba7319e9SDmitry Salychev /** 274*ba7319e9SDmitry Salychev * @brief Allocate MSI interrupts for DPMAC. 275*ba7319e9SDmitry Salychev */ 276*ba7319e9SDmitry Salychev static int 277*ba7319e9SDmitry Salychev dpaa2_mac_setup_msi(struct dpaa2_mac_softc *sc) 278*ba7319e9SDmitry Salychev { 279*ba7319e9SDmitry Salychev int val; 280*ba7319e9SDmitry Salychev 281*ba7319e9SDmitry Salychev val = pci_msi_count(sc->dev); 282*ba7319e9SDmitry Salychev if (val < DPAA2_MAC_MSI_COUNT) 283*ba7319e9SDmitry Salychev device_printf(sc->dev, "MSI: actual=%d, expected=%d\n", val, 284*ba7319e9SDmitry Salychev DPAA2_MAC_MSI_COUNT); 285*ba7319e9SDmitry Salychev val = MIN(val, DPAA2_MAC_MSI_COUNT); 286*ba7319e9SDmitry Salychev 287*ba7319e9SDmitry Salychev if (pci_alloc_msi(sc->dev, &val) != 0) 288*ba7319e9SDmitry Salychev return (EINVAL); 289*ba7319e9SDmitry Salychev 290*ba7319e9SDmitry Salychev for (int i = 0; i < val; i++) 291*ba7319e9SDmitry Salychev sc->irq_rid[i] = i + 1; 292*ba7319e9SDmitry Salychev 293*ba7319e9SDmitry Salychev return (0); 294*ba7319e9SDmitry Salychev } 295*ba7319e9SDmitry Salychev 296*ba7319e9SDmitry Salychev static void 297*ba7319e9SDmitry Salychev dpaa2_mac_intr(void *arg) 298*ba7319e9SDmitry Salychev { 299*ba7319e9SDmitry Salychev struct dpaa2_mac_softc *sc = (struct dpaa2_mac_softc *) arg; 300*ba7319e9SDmitry Salychev device_t child = sc->dev; 301*ba7319e9SDmitry Salychev uint32_t status = ~0u; /* clear all IRQ status bits */ 302*ba7319e9SDmitry Salychev int error; 303*ba7319e9SDmitry Salychev 304*ba7319e9SDmitry Salychev error = DPAA2_CMD_MAC_GET_IRQ_STATUS(sc->dev, child, 305*ba7319e9SDmitry Salychev dpaa2_mcp_tk(sc->cmd, sc->mac_token), DPMAC_IRQ_INDEX, &status); 306*ba7319e9SDmitry Salychev if (error) 307*ba7319e9SDmitry Salychev device_printf(sc->dev, "%s: failed to obtain IRQ status: " 308*ba7319e9SDmitry Salychev "error=%d\n", __func__, error); 309*ba7319e9SDmitry Salychev } 310*ba7319e9SDmitry Salychev 311*ba7319e9SDmitry Salychev static const char * 312*ba7319e9SDmitry Salychev dpaa2_mac_ethif_to_str(enum dpaa2_mac_eth_if eth_if) 313*ba7319e9SDmitry Salychev { 314*ba7319e9SDmitry Salychev switch (eth_if) { 315*ba7319e9SDmitry Salychev case DPAA2_MAC_ETH_IF_MII: 316*ba7319e9SDmitry Salychev return ("MII"); 317*ba7319e9SDmitry Salychev case DPAA2_MAC_ETH_IF_RMII: 318*ba7319e9SDmitry Salychev return ("RMII"); 319*ba7319e9SDmitry Salychev case DPAA2_MAC_ETH_IF_SMII: 320*ba7319e9SDmitry Salychev return ("SMII"); 321*ba7319e9SDmitry Salychev case DPAA2_MAC_ETH_IF_GMII: 322*ba7319e9SDmitry Salychev return ("GMII"); 323*ba7319e9SDmitry Salychev case DPAA2_MAC_ETH_IF_RGMII: 324*ba7319e9SDmitry Salychev return ("RGMII"); 325*ba7319e9SDmitry Salychev case DPAA2_MAC_ETH_IF_SGMII: 326*ba7319e9SDmitry Salychev return ("SGMII"); 327*ba7319e9SDmitry Salychev case DPAA2_MAC_ETH_IF_QSGMII: 328*ba7319e9SDmitry Salychev return ("QSGMII"); 329*ba7319e9SDmitry Salychev case DPAA2_MAC_ETH_IF_XAUI: 330*ba7319e9SDmitry Salychev return ("XAUI"); 331*ba7319e9SDmitry Salychev case DPAA2_MAC_ETH_IF_XFI: 332*ba7319e9SDmitry Salychev return ("XFI"); 333*ba7319e9SDmitry Salychev case DPAA2_MAC_ETH_IF_CAUI: 334*ba7319e9SDmitry Salychev return ("CAUI"); 335*ba7319e9SDmitry Salychev case DPAA2_MAC_ETH_IF_1000BASEX: 336*ba7319e9SDmitry Salychev return ("1000BASE-X"); 337*ba7319e9SDmitry Salychev case DPAA2_MAC_ETH_IF_USXGMII: 338*ba7319e9SDmitry Salychev return ("USXGMII"); 339*ba7319e9SDmitry Salychev default: 340*ba7319e9SDmitry Salychev return ("unknown"); 341*ba7319e9SDmitry Salychev } 342*ba7319e9SDmitry Salychev } 343*ba7319e9SDmitry Salychev 344*ba7319e9SDmitry Salychev static const char * 345*ba7319e9SDmitry Salychev dpaa2_mac_link_type_to_str(enum dpaa2_mac_link_type link_type) 346*ba7319e9SDmitry Salychev { 347*ba7319e9SDmitry Salychev switch (link_type) { 348*ba7319e9SDmitry Salychev case DPAA2_MAC_LINK_TYPE_NONE: 349*ba7319e9SDmitry Salychev return ("NONE"); 350*ba7319e9SDmitry Salychev case DPAA2_MAC_LINK_TYPE_FIXED: 351*ba7319e9SDmitry Salychev return ("FIXED"); 352*ba7319e9SDmitry Salychev case DPAA2_MAC_LINK_TYPE_PHY: 353*ba7319e9SDmitry Salychev return ("PHY"); 354*ba7319e9SDmitry Salychev case DPAA2_MAC_LINK_TYPE_BACKPLANE: 355*ba7319e9SDmitry Salychev return ("BACKPLANE"); 356*ba7319e9SDmitry Salychev default: 357*ba7319e9SDmitry Salychev return ("unknown"); 358*ba7319e9SDmitry Salychev } 359*ba7319e9SDmitry Salychev } 360*ba7319e9SDmitry Salychev 361*ba7319e9SDmitry Salychev static device_method_t dpaa2_mac_methods[] = { 362*ba7319e9SDmitry Salychev /* Device interface */ 363*ba7319e9SDmitry Salychev DEVMETHOD(device_probe, dpaa2_mac_probe), 364*ba7319e9SDmitry Salychev DEVMETHOD(device_attach, dpaa2_mac_attach), 365*ba7319e9SDmitry Salychev DEVMETHOD(device_detach, dpaa2_mac_detach), 366*ba7319e9SDmitry Salychev 367*ba7319e9SDmitry Salychev DEVMETHOD_END 368*ba7319e9SDmitry Salychev }; 369*ba7319e9SDmitry Salychev 370*ba7319e9SDmitry Salychev static driver_t dpaa2_mac_driver = { 371*ba7319e9SDmitry Salychev "dpaa2_mac", 372*ba7319e9SDmitry Salychev dpaa2_mac_methods, 373*ba7319e9SDmitry Salychev sizeof(struct dpaa2_mac_softc), 374*ba7319e9SDmitry Salychev }; 375*ba7319e9SDmitry Salychev 376*ba7319e9SDmitry Salychev DRIVER_MODULE(dpaa2_mac, dpaa2_rc, dpaa2_mac_driver, 0, 0); 377