diff options
Diffstat (limited to 'roms/u-boot/drivers/net/ldpaa_eth')
-rw-r--r-- | roms/u-boot/drivers/net/ldpaa_eth/Makefile | 10 | ||||
-rw-r--r-- | roms/u-boot/drivers/net/ldpaa_eth/ldpaa_eth.c | 1273 | ||||
-rw-r--r-- | roms/u-boot/drivers/net/ldpaa_eth/ldpaa_eth.h | 156 | ||||
-rw-r--r-- | roms/u-boot/drivers/net/ldpaa_eth/ldpaa_wriop.c | 192 | ||||
-rw-r--r-- | roms/u-boot/drivers/net/ldpaa_eth/ls1088a.c | 114 | ||||
-rw-r--r-- | roms/u-boot/drivers/net/ldpaa_eth/ls2080a.c | 110 | ||||
-rw-r--r-- | roms/u-boot/drivers/net/ldpaa_eth/lx2160a.c | 108 |
7 files changed, 1963 insertions, 0 deletions
diff --git a/roms/u-boot/drivers/net/ldpaa_eth/Makefile b/roms/u-boot/drivers/net/ldpaa_eth/Makefile new file mode 100644 index 000000000..52ab828f0 --- /dev/null +++ b/roms/u-boot/drivers/net/ldpaa_eth/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2015-2018 NXP +# Copyright 2014 Freescale Semiconductor, Inc. + +obj-y += ldpaa_wriop.o +obj-y += ldpaa_eth.o +obj-$(CONFIG_ARCH_LS2080A) += ls2080a.o +obj-$(CONFIG_ARCH_LS1088A) += ls1088a.o +obj-$(CONFIG_ARCH_LX2160A) += lx2160a.o +obj-$(CONFIG_ARCH_LX2162A) += lx2160a.o diff --git a/roms/u-boot/drivers/net/ldpaa_eth/ldpaa_eth.c b/roms/u-boot/drivers/net/ldpaa_eth/ldpaa_eth.c new file mode 100644 index 000000000..725173f62 --- /dev/null +++ b/roms/u-boot/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -0,0 +1,1273 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014-2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + */ + +#include <common.h> +#include <cpu_func.h> +#include <dm/device_compat.h> +#include <fsl-mc/fsl_dpmac.h> +#include <fsl-mc/ldpaa_wriop.h> +#include <hwconfig.h> +#include <log.h> +#include <malloc.h> +#include <miiphy.h> +#include <net.h> +#include <phy.h> +#include <asm/io.h> +#include <asm/types.h> +#include <linux/bug.h> +#include <linux/compat.h> +#include <linux/delay.h> +#include <asm/global_data.h> +#include "ldpaa_eth.h" + +#ifdef CONFIG_PHYLIB +#ifdef CONFIG_DM_ETH +static void init_phy(struct udevice *dev) +{ + struct ldpaa_eth_priv *priv = dev_get_priv(dev); + + priv->phy = dm_eth_phy_connect(dev); + + if (!priv->phy) + return; + + phy_config(priv->phy); +} +#else +static int init_phy(struct eth_device *dev) +{ + struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; + struct phy_device *phydev = NULL; + struct mii_dev *bus; + int phy_addr, phy_num; + int ret = 0; + + bus = wriop_get_mdio(priv->dpmac_id); + if (bus == NULL) + return 0; + + for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { + phy_addr = wriop_get_phy_address(priv->dpmac_id, phy_num); + if (phy_addr < 0) + continue; + + phydev = phy_connect(bus, phy_addr, dev, + wriop_get_enet_if(priv->dpmac_id)); + if (!phydev) { + printf("Failed to connect\n"); + ret = -ENODEV; + break; + } + wriop_set_phy_dev(priv->dpmac_id, phy_num, phydev); + ret = phy_config(phydev); + if (ret) + break; + } + + if (ret) { + for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { + phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num); + if (!phydev) + continue; + + free(phydev); + wriop_set_phy_dev(priv->dpmac_id, phy_num, NULL); + } + } + + return ret; +} +#endif +#endif + +#ifdef DEBUG + +#define DPNI_STATS_PER_PAGE 6 + +static const char *dpni_statistics[][DPNI_STATS_PER_PAGE] = { + { + "DPNI_CNT_ING_ALL_FRAMES", + "DPNI_CNT_ING_ALL_BYTES", + "DPNI_CNT_ING_MCAST_FRAMES", + "DPNI_CNT_ING_MCAST_BYTES", + "DPNI_CNT_ING_BCAST_FRAMES", + "DPNI_CNT_ING_BCAST_BYTES", + }, { + "DPNI_CNT_EGR_ALL_FRAMES", + "DPNI_CNT_EGR_ALL_BYTES", + "DPNI_CNT_EGR_MCAST_FRAMES", + "DPNI_CNT_EGR_MCAST_BYTES", + "DPNI_CNT_EGR_BCAST_FRAMES", + "DPNI_CNT_EGR_BCAST_BYTES", + }, { + "DPNI_CNT_ING_FILTERED_FRAMES", + "DPNI_CNT_ING_DISCARDED_FRAMES", + "DPNI_CNT_ING_NOBUFFER_DISCARDS", + "DPNI_CNT_EGR_DISCARDED_FRAMES", + "DPNI_CNT_EGR_CNF_FRAMES", + "" + }, +}; + +static void print_dpni_stats(const char *strings[], + struct dpni_statistics dpni_stats) +{ + uint64_t *stat; + int i; + + stat = (uint64_t *)&dpni_stats; + for (i = 0; i < DPNI_STATS_PER_PAGE; i++) { + if (strcmp(strings[i], "\0") == 0) + break; + printf("%s= %llu\n", strings[i], *stat); + stat++; + } +} + +static void ldpaa_eth_get_dpni_counter(void) +{ + int err = 0; + unsigned int page = 0; + struct dpni_statistics dpni_stats; + + printf("DPNI counters ..\n"); + for (page = 0; page < 3; page++) { + err = dpni_get_statistics(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, page, + &dpni_stats); + if (err < 0) { + printf("dpni_get_statistics: failed:"); + printf("%d for page[%d]\n", err, page); + return; + } + print_dpni_stats(dpni_statistics[page], dpni_stats); + } +} + +#ifdef CONFIG_DM_ETH +static void ldpaa_eth_get_dpmac_counter(struct udevice *dev) +{ + struct ldpaa_eth_priv *priv = dev_get_priv(dev); +#else +static void ldpaa_eth_get_dpmac_counter(struct eth_device *net_dev) +{ + struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; +#endif + int err = 0; + u64 value; + + err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpmac_handle, + DPMAC_CNT_ING_BYTE, + &value); + if (err < 0) { + printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n"); + return; + } + printf("\nDPMAC counters ..\n"); + printf("DPMAC_CNT_ING_BYTE=%lld\n", value); + + err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpmac_handle, + DPMAC_CNT_ING_FRAME_DISCARD, + &value); + if (err < 0) { + printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n"); + return; + } + printf("DPMAC_CNT_ING_FRAME_DISCARD=%lld\n", value); + + err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpmac_handle, + DPMAC_CNT_ING_ALIGN_ERR, + &value); + if (err < 0) { + printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n"); + return; + } + printf("DPMAC_CNT_ING_ALIGN_ERR =%lld\n", value); + + err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpmac_handle, + DPMAC_CNT_ING_BYTE, + &value); + if (err < 0) { + printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n"); + return; + } + printf("DPMAC_CNT_ING_BYTE=%lld\n", value); + + err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpmac_handle, + DPMAC_CNT_ING_ERR_FRAME, + &value); + if (err < 0) { + printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n"); + return; + } + printf("DPMAC_CNT_ING_ERR_FRAME=%lld\n", value); + + err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpmac_handle, + DPMAC_CNT_EGR_BYTE , + &value); + if (err < 0) { + printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n"); + return; + } + printf("DPMAC_CNT_EGR_BYTE =%lld\n", value); + + err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpmac_handle, + DPMAC_CNT_EGR_ERR_FRAME , + &value); + if (err < 0) { + printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n"); + return; + } + printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value); +} +#endif + +static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv, + const struct dpaa_fd *fd) +{ + u64 fd_addr; + uint16_t fd_offset; + uint32_t fd_length; + struct ldpaa_fas *fas; + uint32_t status, err; + u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; + u32 time_start; + struct qbman_release_desc releasedesc; + struct qbman_swp *swp = dflt_dpio->sw_portal; + + fd_addr = ldpaa_fd_get_addr(fd); + fd_offset = ldpaa_fd_get_offset(fd); + fd_length = ldpaa_fd_get_len(fd); + + debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length); + + if (fd->simple.frc & LDPAA_FD_FRC_FASV) { + /* Read the frame annotation status word and check for errors */ + fas = (struct ldpaa_fas *) + ((uint8_t *)(fd_addr) + + dflt_dpni->buf_layout.private_data_size); + status = le32_to_cpu(fas->status); + if (status & LDPAA_ETH_RX_ERR_MASK) { + printf("Rx frame error(s): 0x%08x\n", + status & LDPAA_ETH_RX_ERR_MASK); + goto error; + } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) { + printf("Unsupported feature in bitmask: 0x%08x\n", + status & LDPAA_ETH_RX_UNSUPP_MASK); + goto error; + } + } + + debug("Rx frame: To Upper layer\n"); + net_process_received_packet((uint8_t *)(fd_addr) + fd_offset, + fd_length); + +error: + flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE); + qbman_release_desc_clear(&releasedesc); + qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); + time_start = get_timer(0); + do { + /* Release buffer into the QBMAN */ + err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); + } while (get_timer(time_start) < timeo && err == -EBUSY); + + if (err == -EBUSY) + printf("Rx frame: QBMAN buffer release fails\n"); + + return; +} + +#ifdef CONFIG_DM_ETH +static int ldpaa_eth_pull_dequeue_rx(struct udevice *dev, + int flags, uchar **packetp) +{ + struct ldpaa_eth_priv *priv = dev_get_priv(dev); +#else +static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) +{ + struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; +#endif + const struct ldpaa_dq *dq; + const struct dpaa_fd *fd; + int i = 5, err = 0, status; + u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; + u32 time_start; + static struct qbman_pull_desc pulldesc; + struct qbman_swp *swp = dflt_dpio->sw_portal; + + while (--i) { + qbman_pull_desc_clear(&pulldesc); + qbman_pull_desc_set_numframes(&pulldesc, 1); + qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid); + + err = qbman_swp_pull(swp, &pulldesc); + if (err < 0) { + printf("Dequeue frames error:0x%08x\n", err); + continue; + } + + time_start = get_timer(0); + + do { + dq = qbman_swp_dqrr_next(swp); + } while (get_timer(time_start) < timeo && !dq); + + if (dq) { + /* Check for valid frame. If not sent a consume + * confirmation to QBMAN otherwise give it to NADK + * application and then send consume confirmation to + * QBMAN. + */ + status = (uint8_t)ldpaa_dq_flags(dq); + if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) { + debug("Dequeue RX frames:"); + debug("No frame delivered\n"); + + qbman_swp_dqrr_consume(swp, dq); + continue; + } + + fd = ldpaa_dq_fd(dq); + + /* Obtain FD and process it */ + ldpaa_eth_rx(priv, fd); + qbman_swp_dqrr_consume(swp, dq); + break; + } else { + err = -ENODATA; + debug("No DQRR entries\n"); + break; + } + } + + return err; +} + +#ifdef CONFIG_DM_ETH +static int ldpaa_eth_tx(struct udevice *dev, void *buf, int len) +{ + struct ldpaa_eth_priv *priv = dev_get_priv(dev); +#else +static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) +{ + struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; +#endif + struct dpaa_fd fd; + u64 buffer_start; + int data_offset, err; + u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; + u32 time_start; + struct qbman_swp *swp = dflt_dpio->sw_portal; + struct qbman_eq_desc ed; + struct qbman_release_desc releasedesc; + + /* Setup the FD fields */ + memset(&fd, 0, sizeof(fd)); + + data_offset = priv->tx_data_offset; + + do { + err = qbman_swp_acquire(dflt_dpio->sw_portal, + dflt_dpbp->dpbp_attr.bpid, + &buffer_start, 1); + } while (err == -EBUSY); + + if (err <= 0) { + printf("qbman_swp_acquire() failed\n"); + return -ENOMEM; + } + + debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start); + + memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len); + + flush_dcache_range(buffer_start, buffer_start + + LDPAA_ETH_RX_BUFFER_SIZE); + + ldpaa_fd_set_addr(&fd, (u64)buffer_start); + ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset)); + ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid); + ldpaa_fd_set_len(&fd, len); + + fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA | + LDPAA_FD_CTRL_PTV1; + + qbman_eq_desc_clear(&ed); + qbman_eq_desc_set_no_orp(&ed, 0); + qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0); + + time_start = get_timer(0); + + while (get_timer(time_start) < timeo) { + err = qbman_swp_enqueue(swp, &ed, + (const struct qbman_fd *)(&fd)); + if (err != -EBUSY) + break; + } + + if (err < 0) { + printf("error enqueueing Tx frame\n"); + goto error; + } + + return err; + +error: + qbman_release_desc_clear(&releasedesc); + qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); + time_start = get_timer(0); + do { + /* Release buffer into the QBMAN */ + err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1); + } while (get_timer(time_start) < timeo && err == -EBUSY); + + if (err == -EBUSY) + printf("TX data: QBMAN buffer release fails\n"); + + return err; +} + +static struct phy_device *ldpaa_get_phydev(struct ldpaa_eth_priv *priv) +{ +#ifdef CONFIG_DM_ETH + return priv->phy; +#else +#ifdef CONFIG_PHYLIB + struct phy_device *phydev = NULL; + int phy_num; + + /* start the phy devices one by one and update the dpmac state */ + for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { + phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num); + if (phydev) + return phydev; + } + return NULL; +#endif + return NULL; +#endif +} + +static int ldpaa_get_dpmac_state(struct ldpaa_eth_priv *priv, + struct dpmac_link_state *state) +{ + phy_interface_t enet_if; + struct phy_device *phydev = NULL; + int err; + + /* let's start off with maximum capabilities */ + enet_if = wriop_get_enet_if(priv->dpmac_id); + switch (enet_if) { + case PHY_INTERFACE_MODE_XGMII: + state->rate = SPEED_10000; + break; + default: + state->rate = SPEED_1000; + break; + } + + state->up = 1; + state->options |= DPMAC_LINK_OPT_AUTONEG; + phydev = ldpaa_get_phydev(priv); + + if (phydev) { + err = phy_startup(phydev); + if (err) { + printf("%s: Could not initialize\n", phydev->dev->name); + state->up = 0; + } else if (phydev->link) { + state->rate = min(state->rate, (uint32_t)phydev->speed); + if (!phydev->duplex) + state->options |= DPMAC_LINK_OPT_HALF_DUPLEX; + if (!phydev->autoneg) + state->options &= ~DPMAC_LINK_OPT_AUTONEG; + } else { + state->up = 0; + } + } + + if (!phydev) + state->options &= ~DPMAC_LINK_OPT_AUTONEG; + + if (!state->up) { + state->rate = 0; + state->options = 0; + return -ENOLINK; + } + + return 0; +} + +#ifdef CONFIG_DM_ETH +static int ldpaa_eth_open(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_plat(dev); + struct ldpaa_eth_priv *priv = dev_get_priv(dev); +#else +static int ldpaa_eth_open(struct eth_device *net_dev, struct bd_info *bd) +{ + struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; +#endif + struct dpmac_link_state dpmac_link_state = { 0 }; +#ifdef DEBUG + struct dpni_link_state link_state; +#endif + int err = 0; + struct dpni_queue d_queue; + +#ifdef CONFIG_DM_ETH + if (eth_is_active(dev)) + return 0; +#else + if (net_dev->state == ETH_STATE_ACTIVE) + return 0; +#endif + + if (get_mc_boot_status() != 0) { + printf("ERROR (MC is not booted)\n"); + return -ENODEV; + } + + if (get_dpl_apply_status() == 0) { + printf("ERROR (DPL is deployed. No device available)\n"); + return -ENODEV; + } + + /* DPMAC initialization */ + err = ldpaa_dpmac_setup(priv); + if (err < 0) + goto err_dpmac_setup; + + err = ldpaa_get_dpmac_state(priv, &dpmac_link_state); + if (err < 0) + goto err_dpmac_bind; + + /* DPMAC binding DPNI */ + err = ldpaa_dpmac_bind(priv); + if (err) + goto err_dpmac_bind; + + /* DPNI initialization */ + err = ldpaa_dpni_setup(priv); + if (err < 0) + goto err_dpni_setup; + + err = ldpaa_dpbp_setup(); + if (err < 0) + goto err_dpbp_setup; + + /* DPNI binding DPBP */ + err = ldpaa_dpni_bind(priv); + if (err) + goto err_dpni_bind; + +#ifdef CONFIG_DM_ETH + err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, plat->enetaddr); +#else + err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, net_dev->enetaddr); +#endif + if (err) { + printf("dpni_add_mac_addr() failed\n"); + return err; + } + + err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); + if (err < 0) { + printf("dpni_enable() failed\n"); + return err; + } + + err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpmac_handle, &dpmac_link_state); + if (err < 0) { + printf("dpmac_set_link_state() failed\n"); + return err; + } + +#ifdef DEBUG + printf("DPMAC link status: %d - ", dpmac_link_state.up); + dpmac_link_state.up == 0 ? printf("down\n") : + dpmac_link_state.up == 1 ? printf("up\n") : printf("error state\n"); + + err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, &link_state); + if (err < 0) { + printf("dpni_get_link_state() failed\n"); + return err; + } + + printf("DPNI link status: %d - ", link_state.up); + link_state.up == 0 ? printf("down\n") : + link_state.up == 1 ? printf("up\n") : printf("error state\n"); +#endif + + memset(&d_queue, 0, sizeof(struct dpni_queue)); + err = dpni_get_queue(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, DPNI_QUEUE_RX, + 0, 0, &d_queue); + if (err) { + printf("dpni_get_queue failed\n"); + goto err_get_queue; + } + + priv->rx_dflt_fqid = d_queue.fqid; + + err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, + &priv->tx_qdid); + if (err) { + printf("dpni_get_qdid() failed\n"); + goto err_qdid; + } + + return dpmac_link_state.up; + +err_qdid: +err_get_queue: + dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); +err_dpni_bind: + ldpaa_dpbp_free(); +err_dpbp_setup: + dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); +err_dpni_setup: +err_dpmac_bind: + dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); + dpmac_destroy(dflt_mc_io, + dflt_dprc_handle, + MC_CMD_NO_FLAGS, priv->dpmac_id); +err_dpmac_setup: + return err; +} + +#ifdef CONFIG_DM_ETH +static void ldpaa_eth_stop(struct udevice *dev) +{ + struct ldpaa_eth_priv *priv = dev_get_priv(dev); +#else +static void ldpaa_eth_stop(struct eth_device *net_dev) +{ + struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; +#endif + struct phy_device *phydev = NULL; + int err = 0; + +#ifdef CONFIG_DM_ETH + if (!eth_is_active(dev)) + return; +#else + if ((net_dev->state == ETH_STATE_PASSIVE) || + (net_dev->state == ETH_STATE_INIT)) + return; +#endif + +#ifdef DEBUG + ldpaa_eth_get_dpni_counter(); +#ifdef CONFIG_DM_ETH + ldpaa_eth_get_dpmac_counter(dev); +#else + ldpaa_eth_get_dpmac_counter(net_dev); +#endif +#endif + + err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dprc_handle, &dpmac_endpoint); + if (err < 0) + printf("dprc_disconnect() failed dpmac_endpoint\n"); + + err = dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); + if (err < 0) + printf("dpmac_close() failed\n"); + + err = dpmac_destroy(dflt_mc_io, + dflt_dprc_handle, + MC_CMD_NO_FLAGS, + priv->dpmac_id); + if (err < 0) + printf("dpmac_destroy() failed\n"); + + /* Stop Tx and Rx traffic */ + err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); + if (err < 0) + printf("dpni_disable() failed\n"); + + phydev = ldpaa_get_phydev(priv); + if (phydev) + phy_shutdown(phydev); + + /* Free DPBP handle and reset. */ + ldpaa_dpbp_free(); + + dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); + if (err < 0) + printf("dpni_reset() failed\n"); + + dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); + if (err < 0) + printf("dpni_close() failed\n"); +} + +static void ldpaa_dpbp_drain_cnt(int count) +{ + uint64_t buf_array[7]; + void *addr; + int ret, i; + + BUG_ON(count > 7); + + do { + ret = qbman_swp_acquire(dflt_dpio->sw_portal, + dflt_dpbp->dpbp_attr.bpid, + buf_array, count); + if (ret < 0) { + printf("qbman_swp_acquire() failed\n"); + return; + } + for (i = 0; i < ret; i++) { + addr = (void *)buf_array[i]; + debug("Free: buffer addr =0x%p\n", addr); + free(addr); + } + } while (ret); +} + +static void ldpaa_dpbp_drain(void) +{ + int i; + for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) + ldpaa_dpbp_drain_cnt(7); +} + +static int ldpaa_bp_add_7(uint16_t bpid) +{ + uint64_t buf_array[7]; + u8 *addr; + int i; + struct qbman_release_desc rd; + + for (i = 0; i < 7; i++) { + addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE); + if (!addr) { + printf("addr allocation failed\n"); + goto err_alloc; + } + memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE); + flush_dcache_range((u64)addr, + (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE)); + + buf_array[i] = (uint64_t)addr; + debug("Release: buffer addr =0x%p\n", addr); + } + +release_bufs: + /* In case the portal is busy, retry until successful. + * This function is guaranteed to succeed in a reasonable amount + * of time. + */ + + do { + mdelay(1); + qbman_release_desc_clear(&rd); + qbman_release_desc_set_bpid(&rd, bpid); + } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i)); + + return i; + +err_alloc: + if (i) + goto release_bufs; + + return 0; +} + +static int ldpaa_dpbp_seed(uint16_t bpid) +{ + int i; + int count; + + for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) { + count = ldpaa_bp_add_7(bpid); + if (count < 7) + printf("Buffer Seed= %d\n", count); + } + + return 0; +} + +static int ldpaa_dpbp_setup(void) +{ + int err; + + err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, + &dflt_dpbp->dpbp_handle); + if (err) { + printf("dpbp_open() failed\n"); + goto err_open; + } + + err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); + if (err) { + printf("dpbp_enable() failed\n"); + goto err_enable; + } + + err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpbp->dpbp_handle, + &dflt_dpbp->dpbp_attr); + if (err) { + printf("dpbp_get_attributes() failed\n"); + goto err_get_attr; + } + + err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid); + + if (err) { + printf("Buffer seeding failed for DPBP %d (bpid=%d)\n", + dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid); + goto err_seed; + } + + return 0; + +err_seed: +err_get_attr: + dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); +err_enable: + dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); +err_open: + return err; +} + +static void ldpaa_dpbp_free(void) +{ + ldpaa_dpbp_drain(); + dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); + dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); + dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); +} + +static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io, + struct ldpaa_eth_priv *priv) +{ + int error; + uint16_t major_ver, minor_ver; + + error = dpmac_get_api_version(dflt_mc_io, 0, + &major_ver, + &minor_ver); + if ((major_ver < DPMAC_VER_MAJOR) || + (major_ver == DPMAC_VER_MAJOR && minor_ver < DPMAC_VER_MINOR)) { + printf("DPMAC version mismatch found %u.%u,", + major_ver, minor_ver); + printf("supported version is %u.%u\n", + DPMAC_VER_MAJOR, DPMAC_VER_MINOR); + return error; + } + + return error; +} + +static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv) +{ + int err = 0; + struct dpmac_cfg dpmac_cfg; + + dpmac_cfg.mac_id = priv->dpmac_id; + + err = dpmac_create(dflt_mc_io, + dflt_dprc_handle, + MC_CMD_NO_FLAGS, &dpmac_cfg, + &priv->dpmac_id); + if (err) + printf("dpmac_create() failed\n"); + + err = ldpaa_dpmac_version_check(dflt_mc_io, priv); + if (err < 0) { + printf("ldpaa_dpmac_version_check() failed: %d\n", err); + goto err_version_check; + } + + err = dpmac_open(dflt_mc_io, + MC_CMD_NO_FLAGS, + priv->dpmac_id, + &priv->dpmac_handle); + if (err < 0) { + printf("dpmac_open() failed: %d\n", err); + goto err_open; + } + + return err; + +err_open: +err_version_check: + dpmac_destroy(dflt_mc_io, + dflt_dprc_handle, + MC_CMD_NO_FLAGS, priv->dpmac_id); + + return err; +} + +static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv) +{ + int err = 0; + struct dprc_connection_cfg dprc_connection_cfg = { + /* If both rates are zero the connection */ + /* will be configured in "best effort" mode. */ + .committed_rate = 0, + .max_rate = 0 + }; + +#ifdef DEBUG + struct dprc_endpoint dbg_endpoint; + int state = 0; +#endif + + memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint)); + strcpy(dpmac_endpoint.type, "dpmac"); + dpmac_endpoint.id = priv->dpmac_id; + + memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint)); + strcpy(dpni_endpoint.type, "dpni"); + dpni_endpoint.id = dflt_dpni->dpni_id; + + err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dprc_handle, + &dpmac_endpoint, + &dpni_endpoint, + &dprc_connection_cfg); + if (err) + printf("dprc_connect() failed\n"); + +#ifdef DEBUG + err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dprc_handle, &dpni_endpoint, + &dbg_endpoint, &state); + printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type); + printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id); + printf("%s, DPMAC State= %d\n", __func__, state); + + memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint)); + err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dprc_handle, &dpmac_endpoint, + &dbg_endpoint, &state); + printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type); + printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id); + printf("%s, DPNI State= %d\n", __func__, state); +#endif + return err; +} + +static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) +{ + int err; + + /* and get a handle for the DPNI this interface is associate with */ + err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, + &dflt_dpni->dpni_handle); + if (err) { + printf("dpni_open() failed\n"); + goto err_open; + } + err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, + &dflt_dpni->dpni_attrs); + if (err) { + printf("dpni_get_attributes() failed (err=%d)\n", err); + goto err_get_attr; + } + + /* Configure our buffers' layout */ + dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | + DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | + DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE | + DPNI_BUF_LAYOUT_OPT_DATA_ALIGN; + dflt_dpni->buf_layout.pass_parser_result = true; + dflt_dpni->buf_layout.pass_frame_status = true; + dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE; + /* HW erratum mandates data alignment in multiples of 256 */ + dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN; + + /* ...rx, ... */ + err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, + &dflt_dpni->buf_layout, DPNI_QUEUE_RX); + if (err) { + printf("dpni_set_buffer_layout() failed"); + goto err_buf_layout; + } + + /* ... tx, ... */ + /* remove Rx-only options */ + dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN | + DPNI_BUF_LAYOUT_OPT_PARSER_RESULT); + err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, + &dflt_dpni->buf_layout, DPNI_QUEUE_TX); + if (err) { + printf("dpni_set_buffer_layout() failed"); + goto err_buf_layout; + } + + /* ... tx-confirm. */ + dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; + err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, + &dflt_dpni->buf_layout, + DPNI_QUEUE_TX_CONFIRM); + if (err) { + printf("dpni_set_buffer_layout() failed"); + goto err_buf_layout; + } + + /* Now that we've set our tx buffer layout, retrieve the minimum + * required tx data offset. + */ + err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, + &priv->tx_data_offset); + if (err) { + printf("dpni_get_tx_data_offset() failed\n"); + goto err_data_offset; + } + + /* Warn in case TX data offset is not multiple of 64 bytes. */ + WARN_ON(priv->tx_data_offset % 64); + + /* Accomodate SWA space. */ + priv->tx_data_offset += LDPAA_ETH_SWA_SIZE; + debug("priv->tx_data_offset=%d\n", priv->tx_data_offset); + + return 0; + +err_data_offset: +err_buf_layout: +err_get_attr: + dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); +err_open: + return err; +} + +static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) +{ + struct dpni_pools_cfg pools_params; + struct dpni_queue tx_queue; + int err = 0; + + memset(&pools_params, 0, sizeof(pools_params)); + pools_params.num_dpbp = 1; + pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id; + pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE; + err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, &pools_params); + if (err) { + printf("dpni_set_pools() failed\n"); + return err; + } + + memset(&tx_queue, 0, sizeof(struct dpni_queue)); + + err = dpni_set_queue(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, + DPNI_QUEUE_TX, 0, 0, &tx_queue); + + if (err) { + printf("dpni_set_queue() failed\n"); + return err; + } + + err = dpni_set_tx_confirmation_mode(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpni->dpni_handle, + DPNI_CONF_DISABLE); + if (err) { + printf("dpni_set_tx_confirmation_mode() failed\n"); + return err; + } + + return 0; +} + +#ifdef CONFIG_DM_ETH +static int ldpaa_eth_probe(struct udevice *dev) +{ + struct ofnode_phandle_args phandle; + + /* Nothing to do if there is no "phy-handle" in the DTS node */ + if (dev_read_phandle_with_args(dev, "phy-handle", NULL, + 0, 0, &phandle)) { + return 0; + } + + init_phy(dev); + + return 0; +} + +static uint32_t ldpaa_eth_get_dpmac_id(struct udevice *dev) +{ + int port_node = dev_of_offset(dev); + + return fdtdec_get_uint(gd->fdt_blob, port_node, "reg", -1); +} + +static const char *ldpaa_eth_get_phy_mode_str(struct udevice *dev) +{ + int port_node = dev_of_offset(dev); + const char *phy_mode_str; + + phy_mode_str = fdt_getprop(gd->fdt_blob, port_node, + "phy-connection-type", NULL); + if (phy_mode_str) + return phy_mode_str; + + phy_mode_str = fdt_getprop(gd->fdt_blob, port_node, "phy-mode", NULL); + return phy_mode_str; +} + +static int ldpaa_eth_bind(struct udevice *dev) +{ + const char *phy_mode_str = NULL; + uint32_t dpmac_id; + char eth_name[16]; + int phy_mode = -1; + + phy_mode_str = ldpaa_eth_get_phy_mode_str(dev); + if (phy_mode_str) + phy_mode = phy_get_interface_by_name(phy_mode_str); + if (phy_mode == -1) { + dev_err(dev, "incorrect phy mode\n"); + return -EINVAL; + } + + dpmac_id = ldpaa_eth_get_dpmac_id(dev); + if (dpmac_id == -1) { + dev_err(dev, "missing reg field from the dpmac node\n"); + return -EINVAL; + } + + sprintf(eth_name, "DPMAC%d@%s", dpmac_id, phy_mode_str); + device_set_name(dev, eth_name); + + return 0; +} + +static int ldpaa_eth_of_to_plat(struct udevice *dev) +{ + struct ldpaa_eth_priv *priv = dev_get_priv(dev); + const char *phy_mode_str; + + priv->dpmac_id = ldpaa_eth_get_dpmac_id(dev); + phy_mode_str = ldpaa_eth_get_phy_mode_str(dev); + priv->phy_mode = phy_get_interface_by_name(phy_mode_str); + + return 0; +} + +static const struct eth_ops ldpaa_eth_ops = { + .start = ldpaa_eth_open, + .send = ldpaa_eth_tx, + .recv = ldpaa_eth_pull_dequeue_rx, + .stop = ldpaa_eth_stop, +}; + +static const struct udevice_id ldpaa_eth_of_ids[] = { + { .compatible = "fsl,qoriq-mc-dpmac" }, +}; + +U_BOOT_DRIVER(ldpaa_eth) = { + .name = "ldpaa_eth", + .id = UCLASS_ETH, + .of_match = ldpaa_eth_of_ids, + .of_to_plat = ldpaa_eth_of_to_plat, + .bind = ldpaa_eth_bind, + .probe = ldpaa_eth_probe, + .ops = &ldpaa_eth_ops, + .priv_auto = sizeof(struct ldpaa_eth_priv), + .plat_auto = sizeof(struct eth_pdata), +}; + +#else + +static int ldpaa_eth_netdev_init(struct eth_device *net_dev, + phy_interface_t enet_if) +{ + int err; + struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; + + snprintf(net_dev->name, ETH_NAME_LEN, "DPMAC%d@%s", priv->dpmac_id, + phy_interface_strings[enet_if]); + + net_dev->iobase = 0; + net_dev->init = ldpaa_eth_open; + net_dev->halt = ldpaa_eth_stop; + net_dev->send = ldpaa_eth_tx; + net_dev->recv = ldpaa_eth_pull_dequeue_rx; + +#ifdef CONFIG_PHYLIB + err = init_phy(net_dev); + if (err < 0) + return err; +#endif + + err = eth_register(net_dev); + if (err < 0) { + printf("eth_register() = %d\n", err); + return err; + } + + return 0; +} + +int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if) +{ + struct eth_device *net_dev = NULL; + struct ldpaa_eth_priv *priv = NULL; + int err = 0; + + /* Net device */ + net_dev = (struct eth_device *)malloc(sizeof(struct eth_device)); + if (!net_dev) { + printf("eth_device malloc() failed\n"); + return -ENOMEM; + } + memset(net_dev, 0, sizeof(struct eth_device)); + + /* alloc the ldpaa ethernet private struct */ + priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv)); + if (!priv) { + printf("ldpaa_eth_priv malloc() failed\n"); + free(net_dev); + return -ENOMEM; + } + memset(priv, 0, sizeof(struct ldpaa_eth_priv)); + + net_dev->priv = (void *)priv; + priv->net_dev = (struct eth_device *)net_dev; + priv->dpmac_id = dpmac_id; + debug("%s dpmac_id=%d\n", __func__, dpmac_id); + + err = ldpaa_eth_netdev_init(net_dev, enet_if); + if (err) + goto err_netdev_init; + + debug("ldpaa ethernet: Probed interface %s\n", net_dev->name); + return 0; + +err_netdev_init: + free(priv); + net_dev->priv = NULL; + free(net_dev); + + return err; +} +#endif diff --git a/roms/u-boot/drivers/net/ldpaa_eth/ldpaa_eth.h b/roms/u-boot/drivers/net/ldpaa_eth/ldpaa_eth.h new file mode 100644 index 000000000..e90513e56 --- /dev/null +++ b/roms/u-boot/drivers/net/ldpaa_eth/ldpaa_eth.h @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2014-2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + */ + +#ifndef __LDPAA_ETH_H +#define __LDPAA_ETH_H + +#include <linux/netdevice.h> +#include <fsl-mc/fsl_mc.h> +#include <fsl-mc/fsl_dpaa_fd.h> +#include <fsl-mc/fsl_dprc.h> +#include <fsl-mc/fsl_dpni.h> +#include <fsl-mc/fsl_dpbp.h> +#include <fsl-mc/fsl_dpio.h> +#include <fsl-mc/fsl_qbman_portal.h> +#include <fsl-mc/fsl_mc_private.h> + + +enum ldpaa_eth_type { + LDPAA_ETH_1G_E, + LDPAA_ETH_10G_E, +}; + +/* Arbitrary values for now, but we'll need to tune */ +#define LDPAA_ETH_NUM_BUFS (7 * 7) +#define LDPAA_ETH_REFILL_THRESH (LDPAA_ETH_NUM_BUFS/2) +#define LDPAA_ETH_RX_BUFFER_SIZE 2048 + +/* Hardware requires alignment for buffer address and length: 256-byte + * for ingress, 64-byte for egress. Using 256 for both. + */ +#define LDPAA_ETH_BUF_ALIGN 256 + +/* So far we're only accomodating a skb backpointer in the frame's + * software annotation, but the hardware options are either 0 or 64. + */ +#define LDPAA_ETH_SWA_SIZE 64 + +/* Annotation valid bits in FD FRC */ +#define LDPAA_FD_FRC_FASV 0x8000 +#define LDPAA_FD_FRC_FAEADV 0x4000 +#define LDPAA_FD_FRC_FAPRV 0x2000 +#define LDPAA_FD_FRC_FAIADV 0x1000 +#define LDPAA_FD_FRC_FASWOV 0x0800 +#define LDPAA_FD_FRC_FAICFDV 0x0400 + +/* Annotation bits in FD CTRL */ +#define LDPAA_FD_CTRL_ASAL 0x00020000 /* ASAL = 128 */ +#define LDPAA_FD_CTRL_PTA 0x00800000 +#define LDPAA_FD_CTRL_PTV1 0x00400000 + +/* TODO: we may want to move this and other WRIOP related defines + * to a separate header + */ +/* Frame annotation status */ +struct ldpaa_fas { + u8 reserved; + u8 ppid; + __le16 ifpid; + __le32 status; +} __packed; + +/* Debug frame, otherwise supposed to be discarded */ +#define LDPAA_ETH_FAS_DISC 0x80000000 +/* MACSEC frame */ +#define LDPAA_ETH_FAS_MS 0x40000000 +#define LDPAA_ETH_FAS_PTP 0x08000000 +/* Ethernet multicast frame */ +#define LDPAA_ETH_FAS_MC 0x04000000 +/* Ethernet broadcast frame */ +#define LDPAA_ETH_FAS_BC 0x02000000 +#define LDPAA_ETH_FAS_KSE 0x00040000 +#define LDPAA_ETH_FAS_EOFHE 0x00020000 +#define LDPAA_ETH_FAS_MNLE 0x00010000 +#define LDPAA_ETH_FAS_TIDE 0x00008000 +#define LDPAA_ETH_FAS_PIEE 0x00004000 +/* Frame length error */ +#define LDPAA_ETH_FAS_FLE 0x00002000 +/* Frame physical error; our favourite pastime */ +#define LDPAA_ETH_FAS_FPE 0x00001000 +#define LDPAA_ETH_FAS_PTE 0x00000080 +#define LDPAA_ETH_FAS_ISP 0x00000040 +#define LDPAA_ETH_FAS_PHE 0x00000020 +#define LDPAA_ETH_FAS_BLE 0x00000010 +/* L3 csum validation performed */ +#define LDPAA_ETH_FAS_L3CV 0x00000008 +/* L3 csum error */ +#define LDPAA_ETH_FAS_L3CE 0x00000004 +/* L4 csum validation performed */ +#define LDPAA_ETH_FAS_L4CV 0x00000002 +/* L4 csum error */ +#define LDPAA_ETH_FAS_L4CE 0x00000001 +/* These bits always signal errors */ +#define LDPAA_ETH_RX_ERR_MASK (LDPAA_ETH_FAS_DISC | \ + LDPAA_ETH_FAS_KSE | \ + LDPAA_ETH_FAS_EOFHE | \ + LDPAA_ETH_FAS_MNLE | \ + LDPAA_ETH_FAS_TIDE | \ + LDPAA_ETH_FAS_PIEE | \ + LDPAA_ETH_FAS_FLE | \ + LDPAA_ETH_FAS_FPE | \ + LDPAA_ETH_FAS_PTE | \ + LDPAA_ETH_FAS_ISP | \ + LDPAA_ETH_FAS_PHE | \ + LDPAA_ETH_FAS_BLE | \ + LDPAA_ETH_FAS_L3CE | \ + LDPAA_ETH_FAS_L4CE) +/* Unsupported features in the ingress */ +#define LDPAA_ETH_RX_UNSUPP_MASK LDPAA_ETH_FAS_MS +/* TODO trim down the bitmask; not all of them apply to Tx-confirm */ +#define LDPAA_ETH_TXCONF_ERR_MASK (LDPAA_ETH_FAS_KSE | \ + LDPAA_ETH_FAS_EOFHE | \ + LDPAA_ETH_FAS_MNLE | \ + LDPAA_ETH_FAS_TIDE) + +struct ldpaa_eth_priv { +#ifdef CONFIG_DM_ETH + struct phy_device *phy; + int phy_mode; + bool started; +#else + struct eth_device *net_dev; +#endif + uint32_t dpmac_id; + uint16_t dpmac_handle; + + uint16_t tx_data_offset; + + uint32_t rx_dflt_fqid; + uint16_t tx_qdid; + uint16_t tx_flow_id; + + enum ldpaa_eth_type type; /* 1G or 10G ethernet */ +}; + +struct dprc_endpoint dpmac_endpoint; +struct dprc_endpoint dpni_endpoint; + +extern struct fsl_mc_io *dflt_mc_io; +extern struct fsl_dpbp_obj *dflt_dpbp; +extern struct fsl_dpio_obj *dflt_dpio; +extern struct fsl_dpni_obj *dflt_dpni; +extern uint16_t dflt_dprc_handle; + +static void ldpaa_dpbp_drain_cnt(int count); +static void ldpaa_dpbp_drain(void); +static int ldpaa_dpbp_seed(uint16_t bpid); +static void ldpaa_dpbp_free(void); +static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv); +static int ldpaa_dpbp_setup(void); +static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv); +static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv); +static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv); +#endif /* __LDPAA_H */ diff --git a/roms/u-boot/drivers/net/ldpaa_eth/ldpaa_wriop.c b/roms/u-boot/drivers/net/ldpaa_eth/ldpaa_wriop.c new file mode 100644 index 000000000..06a284ad6 --- /dev/null +++ b/roms/u-boot/drivers/net/ldpaa_eth/ldpaa_wriop.c @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2015 Freescale Semiconductor + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/types.h> +#include <malloc.h> +#include <net.h> +#include <linux/compat.h> +#include <asm/arch/fsl_serdes.h> +#include <fsl-mc/ldpaa_wriop.h> + +struct wriop_dpmac_info dpmac_info[NUM_WRIOP_PORTS]; + +__weak phy_interface_t wriop_dpmac_enet_if(int dpmac_id, int lane_prtc) +{ + return PHY_INTERFACE_MODE_NONE; +} + +void wriop_init_dpmac(int sd, int dpmac_id, int lane_prtcl) +{ + phy_interface_t enet_if; + int phy_num; + + dpmac_info[dpmac_id].enabled = 0; + dpmac_info[dpmac_id].id = 0; + dpmac_info[dpmac_id].enet_if = PHY_INTERFACE_MODE_NONE; + + enet_if = wriop_dpmac_enet_if(dpmac_id, lane_prtcl); + if (enet_if != PHY_INTERFACE_MODE_NONE) { + dpmac_info[dpmac_id].enabled = 1; + dpmac_info[dpmac_id].id = dpmac_id; + dpmac_info[dpmac_id].enet_if = enet_if; + } + for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { + dpmac_info[dpmac_id].phydev[phy_num] = NULL; + dpmac_info[dpmac_id].phy_addr[phy_num] = -1; + } +} + +void wriop_init_dpmac_enet_if(int dpmac_id, phy_interface_t enet_if) +{ + int phy_num; + + dpmac_info[dpmac_id].enabled = 1; + dpmac_info[dpmac_id].id = dpmac_id; + dpmac_info[dpmac_id].enet_if = enet_if; + for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { + dpmac_info[dpmac_id].phydev[phy_num] = NULL; + dpmac_info[dpmac_id].phy_addr[phy_num] = -1; + } +} + + +/*TODO what it do */ +static int wriop_dpmac_to_index(int dpmac_id) +{ + int i; + + for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) { + if (dpmac_info[i].id == dpmac_id) + return i; + } + + return -1; +} + +int wriop_disable_dpmac(int dpmac_id) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return -ENODEV; + + dpmac_info[i].enabled = 0; + wriop_dpmac_disable(dpmac_id); + + return 0; +} + +int wriop_enable_dpmac(int dpmac_id) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return -ENODEV; + + dpmac_info[i].enabled = 1; + wriop_dpmac_enable(dpmac_id); + + return 0; +} + +int wriop_is_enabled_dpmac(int dpmac_id) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return -ENODEV; + + return dpmac_info[i].enabled; +} + + +int wriop_set_mdio(int dpmac_id, struct mii_dev *bus) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return -ENODEV; + + dpmac_info[i].bus = bus; + + return 0; +} + +struct mii_dev *wriop_get_mdio(int dpmac_id) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return NULL; + + return dpmac_info[i].bus; +} + +int wriop_set_phy_address(int dpmac_id, int phy_num, int address) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return -ENODEV; + if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM) + return -EINVAL; + + dpmac_info[i].phy_addr[phy_num] = address; + + return 0; +} + +int wriop_get_phy_address(int dpmac_id, int phy_num) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return -ENODEV; + if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM) + return -EINVAL; + + return dpmac_info[i].phy_addr[phy_num]; +} + +int wriop_set_phy_dev(int dpmac_id, int phy_num, struct phy_device *phydev) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return -ENODEV; + if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM) + return -EINVAL; + + dpmac_info[i].phydev[phy_num] = phydev; + + return 0; +} + +struct phy_device *wriop_get_phy_dev(int dpmac_id, int phy_num) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return NULL; + if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM) + return NULL; + + return dpmac_info[i].phydev[phy_num]; +} + +phy_interface_t wriop_get_enet_if(int dpmac_id) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return PHY_INTERFACE_MODE_NONE; + + if (dpmac_info[i].enabled) + return dpmac_info[i].enet_if; + + return PHY_INTERFACE_MODE_NONE; +} diff --git a/roms/u-boot/drivers/net/ldpaa_eth/ls1088a.c b/roms/u-boot/drivers/net/ldpaa_eth/ls1088a.c new file mode 100644 index 000000000..54cb16e51 --- /dev/null +++ b/roms/u-boot/drivers/net/ldpaa_eth/ls1088a.c @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2017 NXP + */ +#include <common.h> +#include <phy.h> +#include <fsl-mc/ldpaa_wriop.h> +#include <asm/io.h> +#include <asm/arch/fsl_serdes.h> +#include <asm/arch/soc.h> +#include <linux/mii.h> + +u32 dpmac_to_devdisr[] = { + [WRIOP1_DPMAC1] = FSL_CHASSIS3_DEVDISR2_DPMAC1, + [WRIOP1_DPMAC2] = FSL_CHASSIS3_DEVDISR2_DPMAC2, + [WRIOP1_DPMAC3] = FSL_CHASSIS3_DEVDISR2_DPMAC3, + [WRIOP1_DPMAC4] = FSL_CHASSIS3_DEVDISR2_DPMAC4, + [WRIOP1_DPMAC5] = FSL_CHASSIS3_DEVDISR2_DPMAC5, + [WRIOP1_DPMAC6] = FSL_CHASSIS3_DEVDISR2_DPMAC6, + [WRIOP1_DPMAC7] = FSL_CHASSIS3_DEVDISR2_DPMAC7, + [WRIOP1_DPMAC8] = FSL_CHASSIS3_DEVDISR2_DPMAC8, + [WRIOP1_DPMAC9] = FSL_CHASSIS3_DEVDISR2_DPMAC9, + [WRIOP1_DPMAC10] = FSL_CHASSIS3_DEVDISR2_DPMAC10, +}; + +static int is_device_disabled(int dpmac_id) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + u32 devdisr2 = in_le32(&gur->devdisr2); + + return dpmac_to_devdisr[dpmac_id] & devdisr2; +} + +void wriop_dpmac_disable(int dpmac_id) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + + setbits_le32(&gur->devdisr2, dpmac_to_devdisr[dpmac_id]); +} + +void wriop_dpmac_enable(int dpmac_id) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + + clrbits_le32(&gur->devdisr2, dpmac_to_devdisr[dpmac_id]); +} + +phy_interface_t wriop_dpmac_enet_if(int dpmac_id, int lane_prtcl) +{ + enum srds_prtcl; + + if (is_device_disabled(dpmac_id + 1)) + return PHY_INTERFACE_MODE_NONE; + + switch (lane_prtcl) { + case SGMII1: + case SGMII2: + case SGMII3: + case SGMII7: + return PHY_INTERFACE_MODE_SGMII; + } + + if (lane_prtcl >= XFI1 && lane_prtcl <= XFI2) + return PHY_INTERFACE_MODE_XGMII; + + if (lane_prtcl >= QSGMII_A && lane_prtcl <= QSGMII_B) + return PHY_INTERFACE_MODE_QSGMII; + + return PHY_INTERFACE_MODE_NONE; +} + +void wriop_init_dpmac_qsgmii(int sd, int lane_prtcl) +{ + switch (lane_prtcl) { + case QSGMII_A: + wriop_init_dpmac(sd, 3, (int)lane_prtcl); + wriop_init_dpmac(sd, 4, (int)lane_prtcl); + wriop_init_dpmac(sd, 5, (int)lane_prtcl); + wriop_init_dpmac(sd, 6, (int)lane_prtcl); + break; + case QSGMII_B: + wriop_init_dpmac(sd, 7, (int)lane_prtcl); + wriop_init_dpmac(sd, 8, (int)lane_prtcl); + wriop_init_dpmac(sd, 9, (int)lane_prtcl); + wriop_init_dpmac(sd, 10, (int)lane_prtcl); + break; + } +} + +#ifdef CONFIG_SYS_FSL_HAS_RGMII +void fsl_rgmii_init(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 ec; + +#ifdef CONFIG_SYS_FSL_EC1 + ec = gur_in32(&gur->rcwsr[FSL_CHASSIS3_EC1_REGSR]) + & FSL_CHASSIS3_RCWSR25_EC1_PRTCL_MASK; + ec >>= FSL_CHASSIS3_RCWSR25_EC1_PRTCL_SHIFT; + + if (!ec) + wriop_init_dpmac_enet_if(4, PHY_INTERFACE_MODE_RGMII_ID); +#endif + +#ifdef CONFIG_SYS_FSL_EC2 + ec = gur_in32(&gur->rcwsr[FSL_CHASSIS3_EC2_REGSR]) + & FSL_CHASSIS3_RCWSR25_EC2_PRTCL_MASK; + ec >>= FSL_CHASSIS3_RCWSR25_EC2_PRTCL_SHIFT; + + if (!ec) + wriop_init_dpmac_enet_if(5, PHY_INTERFACE_MODE_RGMII_ID); +#endif +} +#endif diff --git a/roms/u-boot/drivers/net/ldpaa_eth/ls2080a.c b/roms/u-boot/drivers/net/ldpaa_eth/ls2080a.c new file mode 100644 index 000000000..49eee044f --- /dev/null +++ b/roms/u-boot/drivers/net/ldpaa_eth/ls2080a.c @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + */ +#include <common.h> +#include <phy.h> +#include <fsl-mc/ldpaa_wriop.h> +#include <asm/io.h> +#include <asm/arch/fsl_serdes.h> + +u32 dpmac_to_devdisr[] = { + [WRIOP1_DPMAC1] = FSL_CHASSIS3_DEVDISR2_DPMAC1, + [WRIOP1_DPMAC2] = FSL_CHASSIS3_DEVDISR2_DPMAC2, + [WRIOP1_DPMAC3] = FSL_CHASSIS3_DEVDISR2_DPMAC3, + [WRIOP1_DPMAC4] = FSL_CHASSIS3_DEVDISR2_DPMAC4, + [WRIOP1_DPMAC5] = FSL_CHASSIS3_DEVDISR2_DPMAC5, + [WRIOP1_DPMAC6] = FSL_CHASSIS3_DEVDISR2_DPMAC6, + [WRIOP1_DPMAC7] = FSL_CHASSIS3_DEVDISR2_DPMAC7, + [WRIOP1_DPMAC8] = FSL_CHASSIS3_DEVDISR2_DPMAC8, + [WRIOP1_DPMAC9] = FSL_CHASSIS3_DEVDISR2_DPMAC9, + [WRIOP1_DPMAC10] = FSL_CHASSIS3_DEVDISR2_DPMAC10, + [WRIOP1_DPMAC11] = FSL_CHASSIS3_DEVDISR2_DPMAC11, + [WRIOP1_DPMAC12] = FSL_CHASSIS3_DEVDISR2_DPMAC12, + [WRIOP1_DPMAC13] = FSL_CHASSIS3_DEVDISR2_DPMAC13, + [WRIOP1_DPMAC14] = FSL_CHASSIS3_DEVDISR2_DPMAC14, + [WRIOP1_DPMAC15] = FSL_CHASSIS3_DEVDISR2_DPMAC15, + [WRIOP1_DPMAC16] = FSL_CHASSIS3_DEVDISR2_DPMAC16, + [WRIOP1_DPMAC17] = FSL_CHASSIS3_DEVDISR2_DPMAC17, + [WRIOP1_DPMAC18] = FSL_CHASSIS3_DEVDISR2_DPMAC18, + [WRIOP1_DPMAC19] = FSL_CHASSIS3_DEVDISR2_DPMAC19, + [WRIOP1_DPMAC20] = FSL_CHASSIS3_DEVDISR2_DPMAC20, + [WRIOP1_DPMAC21] = FSL_CHASSIS3_DEVDISR2_DPMAC21, + [WRIOP1_DPMAC22] = FSL_CHASSIS3_DEVDISR2_DPMAC22, + [WRIOP1_DPMAC23] = FSL_CHASSIS3_DEVDISR2_DPMAC23, + [WRIOP1_DPMAC24] = FSL_CHASSIS3_DEVDISR2_DPMAC24, +}; + +static int is_device_disabled(int dpmac_id) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + u32 devdisr2 = in_le32(&gur->devdisr2); + + return dpmac_to_devdisr[dpmac_id] & devdisr2; +} + +void wriop_dpmac_disable(int dpmac_id) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + + setbits_le32(&gur->devdisr2, dpmac_to_devdisr[dpmac_id]); +} + +void wriop_dpmac_enable(int dpmac_id) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + + clrbits_le32(&gur->devdisr2, dpmac_to_devdisr[dpmac_id]); +} + +phy_interface_t wriop_dpmac_enet_if(int dpmac_id, int lane_prtcl) +{ + enum srds_prtcl; + + if (is_device_disabled(dpmac_id + 1)) + return PHY_INTERFACE_MODE_NONE; + + if (lane_prtcl >= SGMII1 && lane_prtcl <= SGMII16) + return PHY_INTERFACE_MODE_SGMII; + + if (lane_prtcl >= XFI1 && lane_prtcl <= XFI8) + return PHY_INTERFACE_MODE_XGMII; + + if (lane_prtcl >= XAUI1 && lane_prtcl <= XAUI2) + return PHY_INTERFACE_MODE_XGMII; + + if (lane_prtcl >= QSGMII_A && lane_prtcl <= QSGMII_D) + return PHY_INTERFACE_MODE_QSGMII; + + return PHY_INTERFACE_MODE_NONE; +} + +void wriop_init_dpmac_qsgmii(int sd, int lane_prtcl) +{ + switch (lane_prtcl) { + case QSGMII_A: + wriop_init_dpmac(sd, 5, (int)lane_prtcl); + wriop_init_dpmac(sd, 6, (int)lane_prtcl); + wriop_init_dpmac(sd, 7, (int)lane_prtcl); + wriop_init_dpmac(sd, 8, (int)lane_prtcl); + break; + case QSGMII_B: + wriop_init_dpmac(sd, 1, (int)lane_prtcl); + wriop_init_dpmac(sd, 2, (int)lane_prtcl); + wriop_init_dpmac(sd, 3, (int)lane_prtcl); + wriop_init_dpmac(sd, 4, (int)lane_prtcl); + break; + case QSGMII_C: + wriop_init_dpmac(sd, 13, (int)lane_prtcl); + wriop_init_dpmac(sd, 14, (int)lane_prtcl); + wriop_init_dpmac(sd, 15, (int)lane_prtcl); + wriop_init_dpmac(sd, 16, (int)lane_prtcl); + break; + case QSGMII_D: + wriop_init_dpmac(sd, 9, (int)lane_prtcl); + wriop_init_dpmac(sd, 10, (int)lane_prtcl); + wriop_init_dpmac(sd, 11, (int)lane_prtcl); + wriop_init_dpmac(sd, 12, (int)lane_prtcl); + break; + } +} diff --git a/roms/u-boot/drivers/net/ldpaa_eth/lx2160a.c b/roms/u-boot/drivers/net/ldpaa_eth/lx2160a.c new file mode 100644 index 000000000..e57f1a19a --- /dev/null +++ b/roms/u-boot/drivers/net/ldpaa_eth/lx2160a.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018, 2020 NXP + */ +#include <common.h> +#include <phy.h> +#include <fsl-mc/ldpaa_wriop.h> +#include <asm/io.h> +#include <asm/arch/fsl_serdes.h> +#include <asm/arch/soc.h> +#include <linux/mii.h> + +u32 dpmac_to_devdisr[] = { + [WRIOP1_DPMAC1] = FSL_CHASSIS3_DEVDISR2_DPMAC1, + [WRIOP1_DPMAC2] = FSL_CHASSIS3_DEVDISR2_DPMAC2, + [WRIOP1_DPMAC3] = FSL_CHASSIS3_DEVDISR2_DPMAC3, + [WRIOP1_DPMAC4] = FSL_CHASSIS3_DEVDISR2_DPMAC4, + [WRIOP1_DPMAC5] = FSL_CHASSIS3_DEVDISR2_DPMAC5, + [WRIOP1_DPMAC6] = FSL_CHASSIS3_DEVDISR2_DPMAC6, + [WRIOP1_DPMAC7] = FSL_CHASSIS3_DEVDISR2_DPMAC7, + [WRIOP1_DPMAC8] = FSL_CHASSIS3_DEVDISR2_DPMAC8, + [WRIOP1_DPMAC9] = FSL_CHASSIS3_DEVDISR2_DPMAC9, + [WRIOP1_DPMAC10] = FSL_CHASSIS3_DEVDISR2_DPMAC10, + [WRIOP1_DPMAC11] = FSL_CHASSIS3_DEVDISR2_DPMAC11, + [WRIOP1_DPMAC12] = FSL_CHASSIS3_DEVDISR2_DPMAC12, + [WRIOP1_DPMAC13] = FSL_CHASSIS3_DEVDISR2_DPMAC13, + [WRIOP1_DPMAC14] = FSL_CHASSIS3_DEVDISR2_DPMAC14, + [WRIOP1_DPMAC15] = FSL_CHASSIS3_DEVDISR2_DPMAC15, + [WRIOP1_DPMAC16] = FSL_CHASSIS3_DEVDISR2_DPMAC16, + [WRIOP1_DPMAC17] = FSL_CHASSIS3_DEVDISR2_DPMAC17, + [WRIOP1_DPMAC18] = FSL_CHASSIS3_DEVDISR2_DPMAC18, +}; + +static int is_device_disabled(int dpmac_id) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + u32 devdisr2 = in_le32(&gur->devdisr2); + + return dpmac_to_devdisr[dpmac_id] & devdisr2; +} + +void wriop_dpmac_disable(int dpmac_id) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + + setbits_le32(&gur->devdisr2, dpmac_to_devdisr[dpmac_id]); +} + +void wriop_dpmac_enable(int dpmac_id) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + + clrbits_le32(&gur->devdisr2, dpmac_to_devdisr[dpmac_id]); +} + +phy_interface_t wriop_dpmac_enet_if(int dpmac_id, int lane_prtcl) +{ + enum srds_prtcl; + + if (is_device_disabled(dpmac_id)) + return PHY_INTERFACE_MODE_NONE; + + if (lane_prtcl >= SGMII1 && lane_prtcl <= SGMII18) + return PHY_INTERFACE_MODE_SGMII; + + if (lane_prtcl >= XFI1 && lane_prtcl <= XFI14) + return PHY_INTERFACE_MODE_XGMII; + + if (lane_prtcl >= _25GE1 && lane_prtcl <= _25GE10) + return PHY_INTERFACE_MODE_25G_AUI; + + if (lane_prtcl >= _40GE1 && lane_prtcl <= _40GE2) + return PHY_INTERFACE_MODE_XLAUI; + + if (lane_prtcl >= _50GE1 && lane_prtcl <= _50GE2) + return PHY_INTERFACE_MODE_CAUI2; + + if (lane_prtcl >= _100GE1 && lane_prtcl <= _100GE2) + return PHY_INTERFACE_MODE_CAUI4; + + return PHY_INTERFACE_MODE_NONE; +} + +#ifdef CONFIG_SYS_FSL_HAS_RGMII +void fsl_rgmii_init(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 ec; + +#ifdef CONFIG_SYS_FSL_EC1 + ec = gur_in32(&gur->rcwsr[FSL_CHASSIS3_EC1_REGSR - 1]) + & FSL_CHASSIS3_EC1_REGSR_PRTCL_MASK; + ec >>= FSL_CHASSIS3_EC1_REGSR_PRTCL_SHIFT; + + if (!ec) + wriop_init_dpmac_enet_if(17, PHY_INTERFACE_MODE_RGMII_ID); +#endif + +#ifdef CONFIG_SYS_FSL_EC2 + ec = gur_in32(&gur->rcwsr[FSL_CHASSIS3_EC2_REGSR - 1]) + & FSL_CHASSIS3_EC2_REGSR_PRTCL_MASK; + ec >>= FSL_CHASSIS3_EC2_REGSR_PRTCL_SHIFT; + + if (!ec) + wriop_init_dpmac_enet_if(18, PHY_INTERFACE_MODE_RGMII_ID); +#endif +} +#endif |