aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/drivers/net/ldpaa_eth
diff options
context:
space:
mode:
Diffstat (limited to 'roms/u-boot/drivers/net/ldpaa_eth')
-rw-r--r--roms/u-boot/drivers/net/ldpaa_eth/Makefile10
-rw-r--r--roms/u-boot/drivers/net/ldpaa_eth/ldpaa_eth.c1273
-rw-r--r--roms/u-boot/drivers/net/ldpaa_eth/ldpaa_eth.h156
-rw-r--r--roms/u-boot/drivers/net/ldpaa_eth/ldpaa_wriop.c192
-rw-r--r--roms/u-boot/drivers/net/ldpaa_eth/ls1088a.c114
-rw-r--r--roms/u-boot/drivers/net/ldpaa_eth/ls2080a.c110
-rw-r--r--roms/u-boot/drivers/net/ldpaa_eth/lx2160a.c108
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