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