1c517771aSPrabhakar Kushwaha /* 2c517771aSPrabhakar Kushwaha * Copyright (C) 2014 Freescale Semiconductor 3c517771aSPrabhakar Kushwaha * 4c517771aSPrabhakar Kushwaha * SPDX-License-Identifier: GPL-2.0+ 5c517771aSPrabhakar Kushwaha */ 6c517771aSPrabhakar Kushwaha 7c517771aSPrabhakar Kushwaha #include <common.h> 8c517771aSPrabhakar Kushwaha #include <asm/io.h> 9c517771aSPrabhakar Kushwaha #include <asm/types.h> 10c517771aSPrabhakar Kushwaha #include <malloc.h> 11c517771aSPrabhakar Kushwaha #include <net.h> 12c517771aSPrabhakar Kushwaha #include <hwconfig.h> 13c517771aSPrabhakar Kushwaha #include <phy.h> 14c517771aSPrabhakar Kushwaha #include <linux/compat.h> 15c919ab9eSPrabhakar Kushwaha #include <fsl-mc/fsl_dpmac.h> 16c517771aSPrabhakar Kushwaha 17c517771aSPrabhakar Kushwaha #include "ldpaa_eth.h" 18c517771aSPrabhakar Kushwaha 195753b0f1SPrabhakar Kushwaha #undef CONFIG_PHYLIB 20c517771aSPrabhakar Kushwaha static int init_phy(struct eth_device *dev) 21c517771aSPrabhakar Kushwaha { 22c517771aSPrabhakar Kushwaha /*TODO for external PHY */ 23c517771aSPrabhakar Kushwaha 24c517771aSPrabhakar Kushwaha return 0; 25c517771aSPrabhakar Kushwaha } 26c517771aSPrabhakar Kushwaha 275038d3e5SPrabhakar Kushwaha #ifdef DEBUG 285038d3e5SPrabhakar Kushwaha static void ldpaa_eth_get_dpni_counter(void) 295038d3e5SPrabhakar Kushwaha { 305038d3e5SPrabhakar Kushwaha int err = 0; 315038d3e5SPrabhakar Kushwaha u64 value; 325038d3e5SPrabhakar Kushwaha 335038d3e5SPrabhakar Kushwaha err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 345038d3e5SPrabhakar Kushwaha dflt_dpni->dpni_handle, 355038d3e5SPrabhakar Kushwaha DPNI_CNT_ING_FRAME, 365038d3e5SPrabhakar Kushwaha &value); 375038d3e5SPrabhakar Kushwaha if (err < 0) { 385038d3e5SPrabhakar Kushwaha printf("dpni_get_counter: DPNI_CNT_ING_FRAME failed\n"); 395038d3e5SPrabhakar Kushwaha return; 405038d3e5SPrabhakar Kushwaha } 415038d3e5SPrabhakar Kushwaha printf("DPNI_CNT_ING_FRAME=%lld\n", value); 425038d3e5SPrabhakar Kushwaha 435038d3e5SPrabhakar Kushwaha err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 445038d3e5SPrabhakar Kushwaha dflt_dpni->dpni_handle, 455038d3e5SPrabhakar Kushwaha DPNI_CNT_ING_BYTE, 465038d3e5SPrabhakar Kushwaha &value); 475038d3e5SPrabhakar Kushwaha if (err < 0) { 485038d3e5SPrabhakar Kushwaha printf("dpni_get_counter: DPNI_CNT_ING_BYTE failed\n"); 495038d3e5SPrabhakar Kushwaha return; 505038d3e5SPrabhakar Kushwaha } 515038d3e5SPrabhakar Kushwaha printf("DPNI_CNT_ING_BYTE=%lld\n", value); 525038d3e5SPrabhakar Kushwaha 535038d3e5SPrabhakar Kushwaha err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 545038d3e5SPrabhakar Kushwaha dflt_dpni->dpni_handle, 555038d3e5SPrabhakar Kushwaha DPNI_CNT_ING_FRAME_DROP , 565038d3e5SPrabhakar Kushwaha &value); 575038d3e5SPrabhakar Kushwaha if (err < 0) { 585038d3e5SPrabhakar Kushwaha printf("dpni_get_counter: DPNI_CNT_ING_FRAME_DROP failed\n"); 595038d3e5SPrabhakar Kushwaha return; 605038d3e5SPrabhakar Kushwaha } 615038d3e5SPrabhakar Kushwaha printf("DPNI_CNT_ING_FRAME_DROP =%lld\n", value); 625038d3e5SPrabhakar Kushwaha 635038d3e5SPrabhakar Kushwaha err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 645038d3e5SPrabhakar Kushwaha dflt_dpni->dpni_handle, 655038d3e5SPrabhakar Kushwaha DPNI_CNT_ING_FRAME_DISCARD, 665038d3e5SPrabhakar Kushwaha &value); 675038d3e5SPrabhakar Kushwaha if (err < 0) { 685038d3e5SPrabhakar Kushwaha printf("dpni_get_counter: DPNI_CNT_ING_FRAME_DISCARD failed\n"); 695038d3e5SPrabhakar Kushwaha return; 705038d3e5SPrabhakar Kushwaha } 715038d3e5SPrabhakar Kushwaha printf("DPNI_CNT_ING_FRAME_DISCARD=%lld\n", value); 725038d3e5SPrabhakar Kushwaha 735038d3e5SPrabhakar Kushwaha err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 745038d3e5SPrabhakar Kushwaha dflt_dpni->dpni_handle, 755038d3e5SPrabhakar Kushwaha DPNI_CNT_EGR_FRAME, 765038d3e5SPrabhakar Kushwaha &value); 775038d3e5SPrabhakar Kushwaha if (err < 0) { 785038d3e5SPrabhakar Kushwaha printf("dpni_get_counter: DPNI_CNT_EGR_FRAME failed\n"); 795038d3e5SPrabhakar Kushwaha return; 805038d3e5SPrabhakar Kushwaha } 815038d3e5SPrabhakar Kushwaha printf("DPNI_CNT_EGR_FRAME=%lld\n", value); 825038d3e5SPrabhakar Kushwaha 835038d3e5SPrabhakar Kushwaha err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 845038d3e5SPrabhakar Kushwaha dflt_dpni->dpni_handle, 855038d3e5SPrabhakar Kushwaha DPNI_CNT_EGR_BYTE , 865038d3e5SPrabhakar Kushwaha &value); 875038d3e5SPrabhakar Kushwaha if (err < 0) { 885038d3e5SPrabhakar Kushwaha printf("dpni_get_counter: DPNI_CNT_EGR_BYTE failed\n"); 895038d3e5SPrabhakar Kushwaha return; 905038d3e5SPrabhakar Kushwaha } 915038d3e5SPrabhakar Kushwaha printf("DPNI_CNT_EGR_BYTE =%lld\n", value); 925038d3e5SPrabhakar Kushwaha 935038d3e5SPrabhakar Kushwaha err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 945038d3e5SPrabhakar Kushwaha dflt_dpni->dpni_handle, 955038d3e5SPrabhakar Kushwaha DPNI_CNT_EGR_FRAME_DISCARD , 965038d3e5SPrabhakar Kushwaha &value); 975038d3e5SPrabhakar Kushwaha if (err < 0) { 985038d3e5SPrabhakar Kushwaha printf("dpni_get_counter: DPNI_CNT_EGR_FRAME_DISCARD failed\n"); 995038d3e5SPrabhakar Kushwaha return; 1005038d3e5SPrabhakar Kushwaha } 1015038d3e5SPrabhakar Kushwaha printf("DPNI_CNT_EGR_FRAME_DISCARD =%lld\n", value); 1025038d3e5SPrabhakar Kushwaha } 103*44b2036eSPrabhakar Kushwaha 104*44b2036eSPrabhakar Kushwaha static void ldpaa_eth_get_dpmac_counter(struct eth_device *net_dev) 105*44b2036eSPrabhakar Kushwaha { 106*44b2036eSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 107*44b2036eSPrabhakar Kushwaha int err = 0; 108*44b2036eSPrabhakar Kushwaha u64 value; 109*44b2036eSPrabhakar Kushwaha 110*44b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 111*44b2036eSPrabhakar Kushwaha priv->dpmac_handle, 112*44b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_BYTE, 113*44b2036eSPrabhakar Kushwaha &value); 114*44b2036eSPrabhakar Kushwaha if (err < 0) { 115*44b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n"); 116*44b2036eSPrabhakar Kushwaha return; 117*44b2036eSPrabhakar Kushwaha } 118*44b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_BYTE=%lld\n", value); 119*44b2036eSPrabhakar Kushwaha 120*44b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 121*44b2036eSPrabhakar Kushwaha priv->dpmac_handle, 122*44b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_FRAME_DISCARD, 123*44b2036eSPrabhakar Kushwaha &value); 124*44b2036eSPrabhakar Kushwaha if (err < 0) { 125*44b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n"); 126*44b2036eSPrabhakar Kushwaha return; 127*44b2036eSPrabhakar Kushwaha } 128*44b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_FRAME_DISCARD=%lld\n", value); 129*44b2036eSPrabhakar Kushwaha 130*44b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 131*44b2036eSPrabhakar Kushwaha priv->dpmac_handle, 132*44b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_ALIGN_ERR, 133*44b2036eSPrabhakar Kushwaha &value); 134*44b2036eSPrabhakar Kushwaha if (err < 0) { 135*44b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n"); 136*44b2036eSPrabhakar Kushwaha return; 137*44b2036eSPrabhakar Kushwaha } 138*44b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_ALIGN_ERR =%lld\n", value); 139*44b2036eSPrabhakar Kushwaha 140*44b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 141*44b2036eSPrabhakar Kushwaha priv->dpmac_handle, 142*44b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_BYTE, 143*44b2036eSPrabhakar Kushwaha &value); 144*44b2036eSPrabhakar Kushwaha if (err < 0) { 145*44b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n"); 146*44b2036eSPrabhakar Kushwaha return; 147*44b2036eSPrabhakar Kushwaha } 148*44b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_BYTE=%lld\n", value); 149*44b2036eSPrabhakar Kushwaha 150*44b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 151*44b2036eSPrabhakar Kushwaha priv->dpmac_handle, 152*44b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_ERR_FRAME, 153*44b2036eSPrabhakar Kushwaha &value); 154*44b2036eSPrabhakar Kushwaha if (err < 0) { 155*44b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n"); 156*44b2036eSPrabhakar Kushwaha return; 157*44b2036eSPrabhakar Kushwaha } 158*44b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_ERR_FRAME=%lld\n", value); 159*44b2036eSPrabhakar Kushwaha 160*44b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 161*44b2036eSPrabhakar Kushwaha priv->dpmac_handle, 162*44b2036eSPrabhakar Kushwaha DPMAC_CNT_EGR_BYTE , 163*44b2036eSPrabhakar Kushwaha &value); 164*44b2036eSPrabhakar Kushwaha if (err < 0) { 165*44b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n"); 166*44b2036eSPrabhakar Kushwaha return; 167*44b2036eSPrabhakar Kushwaha } 168*44b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_EGR_BYTE =%lld\n", value); 169*44b2036eSPrabhakar Kushwaha 170*44b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 171*44b2036eSPrabhakar Kushwaha priv->dpmac_handle, 172*44b2036eSPrabhakar Kushwaha DPMAC_CNT_EGR_ERR_FRAME , 173*44b2036eSPrabhakar Kushwaha &value); 174*44b2036eSPrabhakar Kushwaha if (err < 0) { 175*44b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n"); 176*44b2036eSPrabhakar Kushwaha return; 177*44b2036eSPrabhakar Kushwaha } 178*44b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value); 179*44b2036eSPrabhakar Kushwaha } 1805038d3e5SPrabhakar Kushwaha #endif 1815038d3e5SPrabhakar Kushwaha 182c517771aSPrabhakar Kushwaha static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv, 183c517771aSPrabhakar Kushwaha const struct dpaa_fd *fd) 184c517771aSPrabhakar Kushwaha { 185c517771aSPrabhakar Kushwaha u64 fd_addr; 186c517771aSPrabhakar Kushwaha uint16_t fd_offset; 187c517771aSPrabhakar Kushwaha uint32_t fd_length; 188c517771aSPrabhakar Kushwaha struct ldpaa_fas *fas; 189c517771aSPrabhakar Kushwaha uint32_t status, err; 19056c57cf7SPrabhakar Kushwaha u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; 19156c57cf7SPrabhakar Kushwaha u32 time_start; 192c517771aSPrabhakar Kushwaha struct qbman_release_desc releasedesc; 193c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 194c517771aSPrabhakar Kushwaha 195c517771aSPrabhakar Kushwaha fd_addr = ldpaa_fd_get_addr(fd); 196c517771aSPrabhakar Kushwaha fd_offset = ldpaa_fd_get_offset(fd); 197c517771aSPrabhakar Kushwaha fd_length = ldpaa_fd_get_len(fd); 198c517771aSPrabhakar Kushwaha 199c517771aSPrabhakar Kushwaha debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length); 200c517771aSPrabhakar Kushwaha 201c517771aSPrabhakar Kushwaha if (fd->simple.frc & LDPAA_FD_FRC_FASV) { 202c517771aSPrabhakar Kushwaha /* Read the frame annotation status word and check for errors */ 203c517771aSPrabhakar Kushwaha fas = (struct ldpaa_fas *) 204c517771aSPrabhakar Kushwaha ((uint8_t *)(fd_addr) + 205c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.private_data_size); 206c517771aSPrabhakar Kushwaha status = le32_to_cpu(fas->status); 207c517771aSPrabhakar Kushwaha if (status & LDPAA_ETH_RX_ERR_MASK) { 208c517771aSPrabhakar Kushwaha printf("Rx frame error(s): 0x%08x\n", 209c517771aSPrabhakar Kushwaha status & LDPAA_ETH_RX_ERR_MASK); 210c517771aSPrabhakar Kushwaha goto error; 211c517771aSPrabhakar Kushwaha } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) { 212c517771aSPrabhakar Kushwaha printf("Unsupported feature in bitmask: 0x%08x\n", 213c517771aSPrabhakar Kushwaha status & LDPAA_ETH_RX_UNSUPP_MASK); 214c517771aSPrabhakar Kushwaha goto error; 215c517771aSPrabhakar Kushwaha } 216c517771aSPrabhakar Kushwaha } 217c517771aSPrabhakar Kushwaha 218c517771aSPrabhakar Kushwaha debug("Rx frame: To Upper layer\n"); 219c517771aSPrabhakar Kushwaha net_process_received_packet((uint8_t *)(fd_addr) + fd_offset, 220c517771aSPrabhakar Kushwaha fd_length); 221c517771aSPrabhakar Kushwaha 222c517771aSPrabhakar Kushwaha error: 2235753b0f1SPrabhakar Kushwaha flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE); 224c517771aSPrabhakar Kushwaha qbman_release_desc_clear(&releasedesc); 225c517771aSPrabhakar Kushwaha qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 22656c57cf7SPrabhakar Kushwaha time_start = get_timer(0); 227c517771aSPrabhakar Kushwaha do { 228c517771aSPrabhakar Kushwaha /* Release buffer into the QBMAN */ 229c517771aSPrabhakar Kushwaha err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); 23056c57cf7SPrabhakar Kushwaha } while (get_timer(time_start) < timeo && err == -EBUSY); 23156c57cf7SPrabhakar Kushwaha 23256c57cf7SPrabhakar Kushwaha if (err == -EBUSY) 23356c57cf7SPrabhakar Kushwaha printf("Rx frame: QBMAN buffer release fails\n"); 23456c57cf7SPrabhakar Kushwaha 235c517771aSPrabhakar Kushwaha return; 236c517771aSPrabhakar Kushwaha } 237c517771aSPrabhakar Kushwaha 238c517771aSPrabhakar Kushwaha static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) 239c517771aSPrabhakar Kushwaha { 240c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; 241c517771aSPrabhakar Kushwaha const struct ldpaa_dq *dq; 242c517771aSPrabhakar Kushwaha const struct dpaa_fd *fd; 243b4c3a35dSPrabhakar Kushwaha int i = 5, err = 0, status; 244b4c3a35dSPrabhakar Kushwaha u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; 245b4c3a35dSPrabhakar Kushwaha u32 time_start; 246c517771aSPrabhakar Kushwaha static struct qbman_pull_desc pulldesc; 247c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 248c517771aSPrabhakar Kushwaha 2495753b0f1SPrabhakar Kushwaha while (--i) { 250c517771aSPrabhakar Kushwaha qbman_pull_desc_clear(&pulldesc); 251c517771aSPrabhakar Kushwaha qbman_pull_desc_set_numframes(&pulldesc, 1); 252c517771aSPrabhakar Kushwaha qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid); 253c517771aSPrabhakar Kushwaha 254c517771aSPrabhakar Kushwaha err = qbman_swp_pull(swp, &pulldesc); 255c517771aSPrabhakar Kushwaha if (err < 0) { 256c517771aSPrabhakar Kushwaha printf("Dequeue frames error:0x%08x\n", err); 257c517771aSPrabhakar Kushwaha continue; 258c517771aSPrabhakar Kushwaha } 259c517771aSPrabhakar Kushwaha 260b4c3a35dSPrabhakar Kushwaha time_start = get_timer(0); 2615753b0f1SPrabhakar Kushwaha 262b4c3a35dSPrabhakar Kushwaha do { 263b4c3a35dSPrabhakar Kushwaha dq = qbman_swp_dqrr_next(swp); 264b4c3a35dSPrabhakar Kushwaha } while (get_timer(time_start) < timeo && !dq); 2655753b0f1SPrabhakar Kushwaha 266c517771aSPrabhakar Kushwaha if (dq) { 267c517771aSPrabhakar Kushwaha /* Check for valid frame. If not sent a consume 268c517771aSPrabhakar Kushwaha * confirmation to QBMAN otherwise give it to NADK 269c517771aSPrabhakar Kushwaha * application and then send consume confirmation to 270c517771aSPrabhakar Kushwaha * QBMAN. 271c517771aSPrabhakar Kushwaha */ 272c517771aSPrabhakar Kushwaha status = (uint8_t)ldpaa_dq_flags(dq); 273c517771aSPrabhakar Kushwaha if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) { 274c517771aSPrabhakar Kushwaha debug("Dequeue RX frames:"); 275c517771aSPrabhakar Kushwaha debug("No frame delivered\n"); 276c517771aSPrabhakar Kushwaha 277c517771aSPrabhakar Kushwaha qbman_swp_dqrr_consume(swp, dq); 2780c7c87a4SPrabhakar Kushwaha continue; 279c517771aSPrabhakar Kushwaha } 280c517771aSPrabhakar Kushwaha 281c517771aSPrabhakar Kushwaha fd = ldpaa_dq_fd(dq); 282c517771aSPrabhakar Kushwaha 283c517771aSPrabhakar Kushwaha /* Obtain FD and process it */ 284c517771aSPrabhakar Kushwaha ldpaa_eth_rx(priv, fd); 285c517771aSPrabhakar Kushwaha qbman_swp_dqrr_consume(swp, dq); 286c517771aSPrabhakar Kushwaha break; 287b4c3a35dSPrabhakar Kushwaha } else { 288b4c3a35dSPrabhakar Kushwaha err = -ENODATA; 289b4c3a35dSPrabhakar Kushwaha debug("No DQRR entries\n"); 290b4c3a35dSPrabhakar Kushwaha break; 291c517771aSPrabhakar Kushwaha } 292c517771aSPrabhakar Kushwaha } 293c517771aSPrabhakar Kushwaha 294c517771aSPrabhakar Kushwaha return err; 295c517771aSPrabhakar Kushwaha } 296c517771aSPrabhakar Kushwaha 297c517771aSPrabhakar Kushwaha static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) 298c517771aSPrabhakar Kushwaha { 299c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 300c517771aSPrabhakar Kushwaha struct dpaa_fd fd; 301c517771aSPrabhakar Kushwaha u64 buffer_start; 302c517771aSPrabhakar Kushwaha int data_offset, err; 303e48df52bSPrabhakar Kushwaha u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; 304e48df52bSPrabhakar Kushwaha u32 time_start; 305c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 306c517771aSPrabhakar Kushwaha struct qbman_eq_desc ed; 307e48df52bSPrabhakar Kushwaha struct qbman_release_desc releasedesc; 308c517771aSPrabhakar Kushwaha 309c517771aSPrabhakar Kushwaha /* Setup the FD fields */ 310c517771aSPrabhakar Kushwaha memset(&fd, 0, sizeof(fd)); 311c517771aSPrabhakar Kushwaha 312c517771aSPrabhakar Kushwaha data_offset = priv->tx_data_offset; 313c517771aSPrabhakar Kushwaha 314c517771aSPrabhakar Kushwaha do { 315c517771aSPrabhakar Kushwaha err = qbman_swp_acquire(dflt_dpio->sw_portal, 316c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.bpid, 317c517771aSPrabhakar Kushwaha &buffer_start, 1); 318c517771aSPrabhakar Kushwaha } while (err == -EBUSY); 319c517771aSPrabhakar Kushwaha 320c517771aSPrabhakar Kushwaha if (err < 0) { 321c517771aSPrabhakar Kushwaha printf("qbman_swp_acquire() failed\n"); 322c517771aSPrabhakar Kushwaha return -ENOMEM; 323c517771aSPrabhakar Kushwaha } 324c517771aSPrabhakar Kushwaha 325c517771aSPrabhakar Kushwaha debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start); 326c517771aSPrabhakar Kushwaha 327c517771aSPrabhakar Kushwaha memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len); 328c517771aSPrabhakar Kushwaha 3295753b0f1SPrabhakar Kushwaha flush_dcache_range(buffer_start, buffer_start + 3305753b0f1SPrabhakar Kushwaha LDPAA_ETH_RX_BUFFER_SIZE); 331c517771aSPrabhakar Kushwaha 332c517771aSPrabhakar Kushwaha ldpaa_fd_set_addr(&fd, (u64)buffer_start); 333c517771aSPrabhakar Kushwaha ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset)); 334c517771aSPrabhakar Kushwaha ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid); 335c517771aSPrabhakar Kushwaha ldpaa_fd_set_len(&fd, len); 336c517771aSPrabhakar Kushwaha 337c517771aSPrabhakar Kushwaha fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA | 338c517771aSPrabhakar Kushwaha LDPAA_FD_CTRL_PTV1; 339c517771aSPrabhakar Kushwaha 340c517771aSPrabhakar Kushwaha qbman_eq_desc_clear(&ed); 341c517771aSPrabhakar Kushwaha qbman_eq_desc_set_no_orp(&ed, 0); 342c517771aSPrabhakar Kushwaha qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0); 343e48df52bSPrabhakar Kushwaha 344e48df52bSPrabhakar Kushwaha time_start = get_timer(0); 345e48df52bSPrabhakar Kushwaha 346e48df52bSPrabhakar Kushwaha while (get_timer(time_start) < timeo) { 347e48df52bSPrabhakar Kushwaha err = qbman_swp_enqueue(swp, &ed, 348e48df52bSPrabhakar Kushwaha (const struct qbman_fd *)(&fd)); 349e48df52bSPrabhakar Kushwaha if (err != -EBUSY) 350e48df52bSPrabhakar Kushwaha break; 351e48df52bSPrabhakar Kushwaha } 352e48df52bSPrabhakar Kushwaha 353e48df52bSPrabhakar Kushwaha if (err < 0) { 354c517771aSPrabhakar Kushwaha printf("error enqueueing Tx frame\n"); 355e48df52bSPrabhakar Kushwaha goto error; 356e48df52bSPrabhakar Kushwaha } 357c517771aSPrabhakar Kushwaha 358c517771aSPrabhakar Kushwaha return err; 359e48df52bSPrabhakar Kushwaha 360e48df52bSPrabhakar Kushwaha error: 361e48df52bSPrabhakar Kushwaha qbman_release_desc_clear(&releasedesc); 362e48df52bSPrabhakar Kushwaha qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 363e48df52bSPrabhakar Kushwaha time_start = get_timer(0); 364e48df52bSPrabhakar Kushwaha do { 365e48df52bSPrabhakar Kushwaha /* Release buffer into the QBMAN */ 366e48df52bSPrabhakar Kushwaha err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1); 367e48df52bSPrabhakar Kushwaha } while (get_timer(time_start) < timeo && err == -EBUSY); 368e48df52bSPrabhakar Kushwaha 369e48df52bSPrabhakar Kushwaha if (err == -EBUSY) 370e48df52bSPrabhakar Kushwaha printf("TX data: QBMAN buffer release fails\n"); 371e48df52bSPrabhakar Kushwaha 372e48df52bSPrabhakar Kushwaha return err; 373c517771aSPrabhakar Kushwaha } 374c517771aSPrabhakar Kushwaha 375c517771aSPrabhakar Kushwaha static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) 376c517771aSPrabhakar Kushwaha { 377c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 378c517771aSPrabhakar Kushwaha struct dpni_queue_attr rx_queue_attr; 379c919ab9eSPrabhakar Kushwaha struct dpmac_link_state dpmac_link_state = { 0 }; 3805038d3e5SPrabhakar Kushwaha #ifdef DEBUG 3815038d3e5SPrabhakar Kushwaha struct dpni_link_state link_state; 3825038d3e5SPrabhakar Kushwaha #endif 383c517771aSPrabhakar Kushwaha int err; 384c517771aSPrabhakar Kushwaha 385c517771aSPrabhakar Kushwaha if (net_dev->state == ETH_STATE_ACTIVE) 386c517771aSPrabhakar Kushwaha return 0; 387c517771aSPrabhakar Kushwaha 388c919ab9eSPrabhakar Kushwaha if (get_mc_boot_status() != 0) { 389c919ab9eSPrabhakar Kushwaha printf("ERROR (MC is not booted)\n"); 390c919ab9eSPrabhakar Kushwaha return -ENODEV; 391c919ab9eSPrabhakar Kushwaha } 392c919ab9eSPrabhakar Kushwaha 393c919ab9eSPrabhakar Kushwaha if (get_dpl_apply_status() == 0) { 394c919ab9eSPrabhakar Kushwaha printf("ERROR (DPL is deployed. No device available)\n"); 395c919ab9eSPrabhakar Kushwaha return -ENODEV; 396c919ab9eSPrabhakar Kushwaha } 397c919ab9eSPrabhakar Kushwaha /* DPMAC initialization */ 398c919ab9eSPrabhakar Kushwaha err = ldpaa_dpmac_setup(priv); 399c919ab9eSPrabhakar Kushwaha if (err < 0) 400c919ab9eSPrabhakar Kushwaha goto err_dpmac_setup; 401c919ab9eSPrabhakar Kushwaha 402c919ab9eSPrabhakar Kushwaha /* DPMAC binding DPNI */ 403c919ab9eSPrabhakar Kushwaha err = ldpaa_dpmac_bind(priv); 404c919ab9eSPrabhakar Kushwaha if (err) 405c919ab9eSPrabhakar Kushwaha goto err_dpamc_bind; 406c919ab9eSPrabhakar Kushwaha 407c517771aSPrabhakar Kushwaha /* DPNI initialization */ 408c517771aSPrabhakar Kushwaha err = ldpaa_dpni_setup(priv); 409c517771aSPrabhakar Kushwaha if (err < 0) 410c517771aSPrabhakar Kushwaha goto err_dpni_setup; 411c517771aSPrabhakar Kushwaha 412c517771aSPrabhakar Kushwaha err = ldpaa_dpbp_setup(); 413c517771aSPrabhakar Kushwaha if (err < 0) 414c517771aSPrabhakar Kushwaha goto err_dpbp_setup; 415c517771aSPrabhakar Kushwaha 416c517771aSPrabhakar Kushwaha /* DPNI binding DPBP */ 417c517771aSPrabhakar Kushwaha err = ldpaa_dpni_bind(priv); 418c517771aSPrabhakar Kushwaha if (err) 419c919ab9eSPrabhakar Kushwaha goto err_dpni_bind; 420c517771aSPrabhakar Kushwaha 4217b2edb8bSPrabhakar Kushwaha err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, 422c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, net_dev->enetaddr); 423c517771aSPrabhakar Kushwaha if (err) { 4247b2edb8bSPrabhakar Kushwaha printf("dpni_add_mac_addr() failed\n"); 425c517771aSPrabhakar Kushwaha return err; 426c517771aSPrabhakar Kushwaha } 427c517771aSPrabhakar Kushwaha 428c517771aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB 429c517771aSPrabhakar Kushwaha /* TODO Check this path */ 4305753b0f1SPrabhakar Kushwaha err = phy_startup(priv->phydev); 4315753b0f1SPrabhakar Kushwaha if (err) { 432c517771aSPrabhakar Kushwaha printf("%s: Could not initialize\n", priv->phydev->dev->name); 4335753b0f1SPrabhakar Kushwaha return err; 434c517771aSPrabhakar Kushwaha } 435c517771aSPrabhakar Kushwaha #else 436c517771aSPrabhakar Kushwaha priv->phydev->speed = SPEED_1000; 437c517771aSPrabhakar Kushwaha priv->phydev->link = 1; 438c517771aSPrabhakar Kushwaha priv->phydev->duplex = DUPLEX_FULL; 439c517771aSPrabhakar Kushwaha #endif 440c517771aSPrabhakar Kushwaha 441c919ab9eSPrabhakar Kushwaha err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 442c517771aSPrabhakar Kushwaha if (err < 0) { 443c517771aSPrabhakar Kushwaha printf("dpni_enable() failed\n"); 444c517771aSPrabhakar Kushwaha return err; 445c517771aSPrabhakar Kushwaha } 446c517771aSPrabhakar Kushwaha 447c919ab9eSPrabhakar Kushwaha dpmac_link_state.rate = SPEED_1000; 448c919ab9eSPrabhakar Kushwaha dpmac_link_state.options = DPMAC_LINK_OPT_AUTONEG; 449c919ab9eSPrabhakar Kushwaha dpmac_link_state.up = 1; 450c919ab9eSPrabhakar Kushwaha err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, 451c919ab9eSPrabhakar Kushwaha priv->dpmac_handle, &dpmac_link_state); 452c919ab9eSPrabhakar Kushwaha if (err < 0) { 453c919ab9eSPrabhakar Kushwaha printf("dpmac_set_link_state() failed\n"); 454c919ab9eSPrabhakar Kushwaha return err; 455c919ab9eSPrabhakar Kushwaha } 4565038d3e5SPrabhakar Kushwaha 4575038d3e5SPrabhakar Kushwaha #ifdef DEBUG 4585038d3e5SPrabhakar Kushwaha err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, 4595038d3e5SPrabhakar Kushwaha dflt_dpni->dpni_handle, &link_state); 4605038d3e5SPrabhakar Kushwaha if (err < 0) { 4615038d3e5SPrabhakar Kushwaha printf("dpni_get_link_state() failed\n"); 4625038d3e5SPrabhakar Kushwaha return err; 4635038d3e5SPrabhakar Kushwaha } 4645038d3e5SPrabhakar Kushwaha 4655038d3e5SPrabhakar Kushwaha printf("link status: %d - ", link_state.up); 4665038d3e5SPrabhakar Kushwaha link_state.up == 0 ? printf("down\n") : 4675038d3e5SPrabhakar Kushwaha link_state.up == 1 ? printf("up\n") : printf("error state\n"); 4685038d3e5SPrabhakar Kushwaha #endif 4695038d3e5SPrabhakar Kushwaha 470c517771aSPrabhakar Kushwaha /* TODO: support multiple Rx flows */ 471c919ab9eSPrabhakar Kushwaha err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, 472c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr); 473c517771aSPrabhakar Kushwaha if (err) { 474c517771aSPrabhakar Kushwaha printf("dpni_get_rx_flow() failed\n"); 475c517771aSPrabhakar Kushwaha goto err_rx_flow; 476c517771aSPrabhakar Kushwaha } 477c517771aSPrabhakar Kushwaha 478c517771aSPrabhakar Kushwaha priv->rx_dflt_fqid = rx_queue_attr.fqid; 479c517771aSPrabhakar Kushwaha 480c919ab9eSPrabhakar Kushwaha err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, 48187457d11SPrabhakar Kushwaha &priv->tx_qdid); 482c517771aSPrabhakar Kushwaha if (err) { 483c517771aSPrabhakar Kushwaha printf("dpni_get_qdid() failed\n"); 484c517771aSPrabhakar Kushwaha goto err_qdid; 485c517771aSPrabhakar Kushwaha } 486c517771aSPrabhakar Kushwaha 487c517771aSPrabhakar Kushwaha if (!priv->phydev->link) 488c517771aSPrabhakar Kushwaha printf("%s: No link.\n", priv->phydev->dev->name); 489c517771aSPrabhakar Kushwaha 490c517771aSPrabhakar Kushwaha return priv->phydev->link ? 0 : -1; 491c517771aSPrabhakar Kushwaha 492c517771aSPrabhakar Kushwaha err_qdid: 493c517771aSPrabhakar Kushwaha err_rx_flow: 494c919ab9eSPrabhakar Kushwaha dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 495c919ab9eSPrabhakar Kushwaha err_dpni_bind: 496c517771aSPrabhakar Kushwaha ldpaa_dpbp_free(); 497c517771aSPrabhakar Kushwaha err_dpbp_setup: 498c919ab9eSPrabhakar Kushwaha err_dpamc_bind: 499c919ab9eSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 500c517771aSPrabhakar Kushwaha err_dpni_setup: 501c919ab9eSPrabhakar Kushwaha err_dpmac_setup: 502c517771aSPrabhakar Kushwaha return err; 503c517771aSPrabhakar Kushwaha } 504c517771aSPrabhakar Kushwaha 505c517771aSPrabhakar Kushwaha static void ldpaa_eth_stop(struct eth_device *net_dev) 506c517771aSPrabhakar Kushwaha { 507c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 508c517771aSPrabhakar Kushwaha int err = 0; 509c517771aSPrabhakar Kushwaha 5105753b0f1SPrabhakar Kushwaha if ((net_dev->state == ETH_STATE_PASSIVE) || 5115753b0f1SPrabhakar Kushwaha (net_dev->state == ETH_STATE_INIT)) 512c517771aSPrabhakar Kushwaha return; 513c919ab9eSPrabhakar Kushwaha 5145038d3e5SPrabhakar Kushwaha #ifdef DEBUG 5155038d3e5SPrabhakar Kushwaha ldpaa_eth_get_dpni_counter(); 516*44b2036eSPrabhakar Kushwaha ldpaa_eth_get_dpmac_counter(net_dev); 5175038d3e5SPrabhakar Kushwaha #endif 5185038d3e5SPrabhakar Kushwaha 519c919ab9eSPrabhakar Kushwaha err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS, 520c919ab9eSPrabhakar Kushwaha dflt_dprc_handle, &dpmac_endpoint); 521c919ab9eSPrabhakar Kushwaha if (err < 0) 522c919ab9eSPrabhakar Kushwaha printf("dprc_disconnect() failed dpmac_endpoint\n"); 523c919ab9eSPrabhakar Kushwaha 524c919ab9eSPrabhakar Kushwaha err = dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); 525c919ab9eSPrabhakar Kushwaha if (err < 0) 526c919ab9eSPrabhakar Kushwaha printf("dpmac_destroy() failed\n"); 527c919ab9eSPrabhakar Kushwaha 528c517771aSPrabhakar Kushwaha /* Stop Tx and Rx traffic */ 529c919ab9eSPrabhakar Kushwaha err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 530c517771aSPrabhakar Kushwaha if (err < 0) 531c517771aSPrabhakar Kushwaha printf("dpni_disable() failed\n"); 532c517771aSPrabhakar Kushwaha 533c517771aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB 534c517771aSPrabhakar Kushwaha phy_shutdown(priv->phydev); 535c517771aSPrabhakar Kushwaha #endif 536c517771aSPrabhakar Kushwaha 537c517771aSPrabhakar Kushwaha ldpaa_dpbp_free(); 538c919ab9eSPrabhakar Kushwaha dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 539c919ab9eSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 540c517771aSPrabhakar Kushwaha } 541c517771aSPrabhakar Kushwaha 542c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain_cnt(int count) 543c517771aSPrabhakar Kushwaha { 544c517771aSPrabhakar Kushwaha uint64_t buf_array[7]; 545c517771aSPrabhakar Kushwaha void *addr; 546c517771aSPrabhakar Kushwaha int ret, i; 547c517771aSPrabhakar Kushwaha 548c517771aSPrabhakar Kushwaha BUG_ON(count > 7); 549c517771aSPrabhakar Kushwaha 550c517771aSPrabhakar Kushwaha do { 551c517771aSPrabhakar Kushwaha ret = qbman_swp_acquire(dflt_dpio->sw_portal, 552c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.bpid, 553c517771aSPrabhakar Kushwaha buf_array, count); 554c517771aSPrabhakar Kushwaha if (ret < 0) { 555c517771aSPrabhakar Kushwaha printf("qbman_swp_acquire() failed\n"); 556c517771aSPrabhakar Kushwaha return; 557c517771aSPrabhakar Kushwaha } 558c517771aSPrabhakar Kushwaha for (i = 0; i < ret; i++) { 559c517771aSPrabhakar Kushwaha addr = (void *)buf_array[i]; 560c517771aSPrabhakar Kushwaha debug("Free: buffer addr =0x%p\n", addr); 561c517771aSPrabhakar Kushwaha free(addr); 562c517771aSPrabhakar Kushwaha } 563c517771aSPrabhakar Kushwaha } while (ret); 564c517771aSPrabhakar Kushwaha } 565c517771aSPrabhakar Kushwaha 566c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain(void) 567c517771aSPrabhakar Kushwaha { 568c517771aSPrabhakar Kushwaha int i; 569c517771aSPrabhakar Kushwaha for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) 570c517771aSPrabhakar Kushwaha ldpaa_dpbp_drain_cnt(7); 571c517771aSPrabhakar Kushwaha } 572c517771aSPrabhakar Kushwaha 573c517771aSPrabhakar Kushwaha static int ldpaa_bp_add_7(uint16_t bpid) 574c517771aSPrabhakar Kushwaha { 575c517771aSPrabhakar Kushwaha uint64_t buf_array[7]; 576c517771aSPrabhakar Kushwaha u8 *addr; 577c517771aSPrabhakar Kushwaha int i; 578c517771aSPrabhakar Kushwaha struct qbman_release_desc rd; 579c517771aSPrabhakar Kushwaha 580c517771aSPrabhakar Kushwaha for (i = 0; i < 7; i++) { 58114480454SPrabhakar Kushwaha addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE); 582c517771aSPrabhakar Kushwaha if (!addr) { 583c517771aSPrabhakar Kushwaha printf("addr allocation failed\n"); 584c517771aSPrabhakar Kushwaha goto err_alloc; 585c517771aSPrabhakar Kushwaha } 586c517771aSPrabhakar Kushwaha memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE); 5875753b0f1SPrabhakar Kushwaha flush_dcache_range((u64)addr, 5885753b0f1SPrabhakar Kushwaha (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE)); 589c517771aSPrabhakar Kushwaha 590c517771aSPrabhakar Kushwaha buf_array[i] = (uint64_t)addr; 591c517771aSPrabhakar Kushwaha debug("Release: buffer addr =0x%p\n", addr); 592c517771aSPrabhakar Kushwaha } 593c517771aSPrabhakar Kushwaha 594c517771aSPrabhakar Kushwaha release_bufs: 595c517771aSPrabhakar Kushwaha /* In case the portal is busy, retry until successful. 596c517771aSPrabhakar Kushwaha * This function is guaranteed to succeed in a reasonable amount 597c517771aSPrabhakar Kushwaha * of time. 598c517771aSPrabhakar Kushwaha */ 599c517771aSPrabhakar Kushwaha 600c517771aSPrabhakar Kushwaha do { 601c517771aSPrabhakar Kushwaha mdelay(1); 602c517771aSPrabhakar Kushwaha qbman_release_desc_clear(&rd); 603c517771aSPrabhakar Kushwaha qbman_release_desc_set_bpid(&rd, bpid); 604c517771aSPrabhakar Kushwaha } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i)); 605c517771aSPrabhakar Kushwaha 606c517771aSPrabhakar Kushwaha return i; 607c517771aSPrabhakar Kushwaha 608c517771aSPrabhakar Kushwaha err_alloc: 609c517771aSPrabhakar Kushwaha if (i) 610c517771aSPrabhakar Kushwaha goto release_bufs; 611c517771aSPrabhakar Kushwaha 612c517771aSPrabhakar Kushwaha return 0; 613c517771aSPrabhakar Kushwaha } 614c517771aSPrabhakar Kushwaha 615c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_seed(uint16_t bpid) 616c517771aSPrabhakar Kushwaha { 617c517771aSPrabhakar Kushwaha int i; 618c517771aSPrabhakar Kushwaha int count; 619c517771aSPrabhakar Kushwaha 620c517771aSPrabhakar Kushwaha for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) { 621c517771aSPrabhakar Kushwaha count = ldpaa_bp_add_7(bpid); 622c517771aSPrabhakar Kushwaha if (count < 7) 623c517771aSPrabhakar Kushwaha printf("Buffer Seed= %d\n", count); 624c517771aSPrabhakar Kushwaha } 625c517771aSPrabhakar Kushwaha 626c517771aSPrabhakar Kushwaha return 0; 627c517771aSPrabhakar Kushwaha } 628c517771aSPrabhakar Kushwaha 629c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_setup(void) 630c517771aSPrabhakar Kushwaha { 631c517771aSPrabhakar Kushwaha int err; 632c517771aSPrabhakar Kushwaha 63387457d11SPrabhakar Kushwaha err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, 634c517771aSPrabhakar Kushwaha &dflt_dpbp->dpbp_handle); 635c517771aSPrabhakar Kushwaha if (err) { 636c517771aSPrabhakar Kushwaha printf("dpbp_open() failed\n"); 637c517771aSPrabhakar Kushwaha goto err_open; 638c517771aSPrabhakar Kushwaha } 639c517771aSPrabhakar Kushwaha 64087457d11SPrabhakar Kushwaha err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 641c517771aSPrabhakar Kushwaha if (err) { 642c517771aSPrabhakar Kushwaha printf("dpbp_enable() failed\n"); 643c517771aSPrabhakar Kushwaha goto err_enable; 644c517771aSPrabhakar Kushwaha } 645c517771aSPrabhakar Kushwaha 64687457d11SPrabhakar Kushwaha err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 64787457d11SPrabhakar Kushwaha dflt_dpbp->dpbp_handle, 648c517771aSPrabhakar Kushwaha &dflt_dpbp->dpbp_attr); 649c517771aSPrabhakar Kushwaha if (err) { 650c517771aSPrabhakar Kushwaha printf("dpbp_get_attributes() failed\n"); 651c517771aSPrabhakar Kushwaha goto err_get_attr; 652c517771aSPrabhakar Kushwaha } 653c517771aSPrabhakar Kushwaha 654c517771aSPrabhakar Kushwaha err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid); 655c517771aSPrabhakar Kushwaha if (err) { 656c517771aSPrabhakar Kushwaha printf("Buffer seeding failed for DPBP %d (bpid=%d)\n", 657c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid); 658c517771aSPrabhakar Kushwaha goto err_seed; 659c517771aSPrabhakar Kushwaha } 660c517771aSPrabhakar Kushwaha 661c517771aSPrabhakar Kushwaha return 0; 662c517771aSPrabhakar Kushwaha 663c517771aSPrabhakar Kushwaha err_seed: 664c517771aSPrabhakar Kushwaha err_get_attr: 66587457d11SPrabhakar Kushwaha dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 666c517771aSPrabhakar Kushwaha err_enable: 66787457d11SPrabhakar Kushwaha dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 668c517771aSPrabhakar Kushwaha err_open: 669c517771aSPrabhakar Kushwaha return err; 670c517771aSPrabhakar Kushwaha } 671c517771aSPrabhakar Kushwaha 672c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_free(void) 673c517771aSPrabhakar Kushwaha { 674c517771aSPrabhakar Kushwaha ldpaa_dpbp_drain(); 67587457d11SPrabhakar Kushwaha dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 67687457d11SPrabhakar Kushwaha dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 67787457d11SPrabhakar Kushwaha dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 678c517771aSPrabhakar Kushwaha } 679c517771aSPrabhakar Kushwaha 6809a696f56SPrabhakar Kushwaha static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io, 6819a696f56SPrabhakar Kushwaha struct ldpaa_eth_priv *priv) 6829a696f56SPrabhakar Kushwaha { 6839a696f56SPrabhakar Kushwaha struct dpmac_attr attr; 6849a696f56SPrabhakar Kushwaha int error; 6859a696f56SPrabhakar Kushwaha 6869a696f56SPrabhakar Kushwaha memset(&attr, 0, sizeof(struct dpmac_attr)); 6879a696f56SPrabhakar Kushwaha error = dpmac_get_attributes(mc_io, MC_CMD_NO_FLAGS, 6889a696f56SPrabhakar Kushwaha priv->dpmac_handle, 6899a696f56SPrabhakar Kushwaha &attr); 6909a696f56SPrabhakar Kushwaha if (error == 0) { 6919a696f56SPrabhakar Kushwaha if ((attr.version.major != DPMAC_VER_MAJOR) || 6929a696f56SPrabhakar Kushwaha (attr.version.minor != DPMAC_VER_MINOR)) { 6939a696f56SPrabhakar Kushwaha printf("DPMAC version mismatch found %u.%u,", 6949a696f56SPrabhakar Kushwaha attr.version.major, attr.version.minor); 6959a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 6969a696f56SPrabhakar Kushwaha DPMAC_VER_MAJOR, DPMAC_VER_MINOR); 6979a696f56SPrabhakar Kushwaha } 6989a696f56SPrabhakar Kushwaha } 6999a696f56SPrabhakar Kushwaha 7009a696f56SPrabhakar Kushwaha return error; 7019a696f56SPrabhakar Kushwaha } 7029a696f56SPrabhakar Kushwaha 703c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv) 704c919ab9eSPrabhakar Kushwaha { 705c919ab9eSPrabhakar Kushwaha int err = 0; 706c919ab9eSPrabhakar Kushwaha struct dpmac_cfg dpmac_cfg; 707c919ab9eSPrabhakar Kushwaha 708c919ab9eSPrabhakar Kushwaha dpmac_cfg.mac_id = priv->dpmac_id; 709c919ab9eSPrabhakar Kushwaha err = dpmac_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpmac_cfg, 710c919ab9eSPrabhakar Kushwaha &priv->dpmac_handle); 711c919ab9eSPrabhakar Kushwaha if (err) 712c919ab9eSPrabhakar Kushwaha printf("dpmac_create() failed\n"); 7139a696f56SPrabhakar Kushwaha 7149a696f56SPrabhakar Kushwaha err = ldpaa_dpmac_version_check(dflt_mc_io, priv); 7159a696f56SPrabhakar Kushwaha if (err < 0) 7169a696f56SPrabhakar Kushwaha printf("ldpaa_dpmac_version_check() failed: %d\n", err); 7179a696f56SPrabhakar Kushwaha 718c919ab9eSPrabhakar Kushwaha return err; 719c919ab9eSPrabhakar Kushwaha } 720c919ab9eSPrabhakar Kushwaha 721c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv) 722c919ab9eSPrabhakar Kushwaha { 723c919ab9eSPrabhakar Kushwaha int err = 0; 724c919ab9eSPrabhakar Kushwaha struct dprc_connection_cfg dprc_connection_cfg = { 725c919ab9eSPrabhakar Kushwaha /* If both rates are zero the connection */ 726c919ab9eSPrabhakar Kushwaha /* will be configured in "best effort" mode. */ 727c919ab9eSPrabhakar Kushwaha .committed_rate = 0, 728c919ab9eSPrabhakar Kushwaha .max_rate = 0 729c919ab9eSPrabhakar Kushwaha }; 730c919ab9eSPrabhakar Kushwaha 7315038d3e5SPrabhakar Kushwaha #ifdef DEBUG 7325038d3e5SPrabhakar Kushwaha struct dprc_endpoint dbg_endpoint; 7335038d3e5SPrabhakar Kushwaha int state = 0; 7345038d3e5SPrabhakar Kushwaha #endif 7355038d3e5SPrabhakar Kushwaha 736c919ab9eSPrabhakar Kushwaha memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint)); 737192bc694SBen Whitten strcpy(dpmac_endpoint.type, "dpmac"); 738c919ab9eSPrabhakar Kushwaha dpmac_endpoint.id = priv->dpmac_id; 739c919ab9eSPrabhakar Kushwaha 740c919ab9eSPrabhakar Kushwaha memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint)); 741192bc694SBen Whitten strcpy(dpni_endpoint.type, "dpni"); 742c919ab9eSPrabhakar Kushwaha dpni_endpoint.id = dflt_dpni->dpni_id; 743c919ab9eSPrabhakar Kushwaha 744c919ab9eSPrabhakar Kushwaha err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS, 745c919ab9eSPrabhakar Kushwaha dflt_dprc_handle, 746c919ab9eSPrabhakar Kushwaha &dpmac_endpoint, 747c919ab9eSPrabhakar Kushwaha &dpni_endpoint, 748c919ab9eSPrabhakar Kushwaha &dprc_connection_cfg); 7495038d3e5SPrabhakar Kushwaha if (err) 7505038d3e5SPrabhakar Kushwaha printf("dprc_connect() failed\n"); 7515038d3e5SPrabhakar Kushwaha 7525038d3e5SPrabhakar Kushwaha #ifdef DEBUG 7535038d3e5SPrabhakar Kushwaha err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 7545038d3e5SPrabhakar Kushwaha dflt_dprc_handle, &dpni_endpoint, 7555038d3e5SPrabhakar Kushwaha &dbg_endpoint, &state); 7565038d3e5SPrabhakar Kushwaha printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type); 7575038d3e5SPrabhakar Kushwaha printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id); 7585038d3e5SPrabhakar Kushwaha printf("%s, DPMAC State= %d\n", __func__, state); 7595038d3e5SPrabhakar Kushwaha 7605038d3e5SPrabhakar Kushwaha memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint)); 7615038d3e5SPrabhakar Kushwaha err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 7625038d3e5SPrabhakar Kushwaha dflt_dprc_handle, &dpmac_endpoint, 7635038d3e5SPrabhakar Kushwaha &dbg_endpoint, &state); 7645038d3e5SPrabhakar Kushwaha printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type); 7655038d3e5SPrabhakar Kushwaha printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id); 7665038d3e5SPrabhakar Kushwaha printf("%s, DPNI State= %d\n", __func__, state); 7675038d3e5SPrabhakar Kushwaha #endif 768c919ab9eSPrabhakar Kushwaha return err; 769c919ab9eSPrabhakar Kushwaha } 770c919ab9eSPrabhakar Kushwaha 771c517771aSPrabhakar Kushwaha static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) 772c517771aSPrabhakar Kushwaha { 773c517771aSPrabhakar Kushwaha int err; 774c517771aSPrabhakar Kushwaha 775c517771aSPrabhakar Kushwaha /* and get a handle for the DPNI this interface is associate with */ 776c919ab9eSPrabhakar Kushwaha err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, 777c919ab9eSPrabhakar Kushwaha &dflt_dpni->dpni_handle); 778c517771aSPrabhakar Kushwaha if (err) { 779c517771aSPrabhakar Kushwaha printf("dpni_open() failed\n"); 780c517771aSPrabhakar Kushwaha goto err_open; 781c517771aSPrabhakar Kushwaha } 782c517771aSPrabhakar Kushwaha 78387457d11SPrabhakar Kushwaha err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 784c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 785c919ab9eSPrabhakar Kushwaha &dflt_dpni->dpni_attrs); 786c517771aSPrabhakar Kushwaha if (err) { 787c517771aSPrabhakar Kushwaha printf("dpni_get_attributes() failed (err=%d)\n", err); 788c517771aSPrabhakar Kushwaha goto err_get_attr; 789c517771aSPrabhakar Kushwaha } 790c517771aSPrabhakar Kushwaha 791c517771aSPrabhakar Kushwaha /* Configure our buffers' layout */ 792c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | 793c517771aSPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | 79414480454SPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE | 79514480454SPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_DATA_ALIGN; 796c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.pass_parser_result = true; 797c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.pass_frame_status = true; 798c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE; 79914480454SPrabhakar Kushwaha /* HW erratum mandates data alignment in multiples of 256 */ 80014480454SPrabhakar Kushwaha dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN; 801c517771aSPrabhakar Kushwaha /* ...rx, ... */ 80287457d11SPrabhakar Kushwaha err = dpni_set_rx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 803c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 804c919ab9eSPrabhakar Kushwaha &dflt_dpni->buf_layout); 805c517771aSPrabhakar Kushwaha if (err) { 806c517771aSPrabhakar Kushwaha printf("dpni_set_rx_buffer_layout() failed"); 807c517771aSPrabhakar Kushwaha goto err_buf_layout; 808c517771aSPrabhakar Kushwaha } 809c517771aSPrabhakar Kushwaha 810c517771aSPrabhakar Kushwaha /* ... tx, ... */ 81114480454SPrabhakar Kushwaha /* remove Rx-only options */ 81214480454SPrabhakar Kushwaha dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN | 81314480454SPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_PARSER_RESULT); 81487457d11SPrabhakar Kushwaha err = dpni_set_tx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 815c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 816c919ab9eSPrabhakar Kushwaha &dflt_dpni->buf_layout); 817c517771aSPrabhakar Kushwaha if (err) { 818c517771aSPrabhakar Kushwaha printf("dpni_set_tx_buffer_layout() failed"); 819c517771aSPrabhakar Kushwaha goto err_buf_layout; 820c517771aSPrabhakar Kushwaha } 821c517771aSPrabhakar Kushwaha 822c517771aSPrabhakar Kushwaha /* ... tx-confirm. */ 823c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; 82487457d11SPrabhakar Kushwaha err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 825c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 826c919ab9eSPrabhakar Kushwaha &dflt_dpni->buf_layout); 827c517771aSPrabhakar Kushwaha if (err) { 828c517771aSPrabhakar Kushwaha printf("dpni_set_tx_conf_buffer_layout() failed"); 829c517771aSPrabhakar Kushwaha goto err_buf_layout; 830c517771aSPrabhakar Kushwaha } 831c517771aSPrabhakar Kushwaha 832c517771aSPrabhakar Kushwaha /* Now that we've set our tx buffer layout, retrieve the minimum 833c517771aSPrabhakar Kushwaha * required tx data offset. 834c517771aSPrabhakar Kushwaha */ 83587457d11SPrabhakar Kushwaha err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS, 836c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 837c919ab9eSPrabhakar Kushwaha &priv->tx_data_offset); 838c517771aSPrabhakar Kushwaha if (err) { 839c517771aSPrabhakar Kushwaha printf("dpni_get_tx_data_offset() failed\n"); 840c517771aSPrabhakar Kushwaha goto err_data_offset; 841c517771aSPrabhakar Kushwaha } 842c517771aSPrabhakar Kushwaha 843c517771aSPrabhakar Kushwaha /* Warn in case TX data offset is not multiple of 64 bytes. */ 844c517771aSPrabhakar Kushwaha WARN_ON(priv->tx_data_offset % 64); 845c517771aSPrabhakar Kushwaha 846c517771aSPrabhakar Kushwaha /* Accomodate SWA space. */ 847c517771aSPrabhakar Kushwaha priv->tx_data_offset += LDPAA_ETH_SWA_SIZE; 848c517771aSPrabhakar Kushwaha debug("priv->tx_data_offset=%d\n", priv->tx_data_offset); 849c517771aSPrabhakar Kushwaha 850c517771aSPrabhakar Kushwaha return 0; 851c517771aSPrabhakar Kushwaha 852c517771aSPrabhakar Kushwaha err_data_offset: 853c517771aSPrabhakar Kushwaha err_buf_layout: 854c517771aSPrabhakar Kushwaha err_get_attr: 855c919ab9eSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 856c517771aSPrabhakar Kushwaha err_open: 857c517771aSPrabhakar Kushwaha return err; 858c517771aSPrabhakar Kushwaha } 859c517771aSPrabhakar Kushwaha 860c517771aSPrabhakar Kushwaha static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) 861c517771aSPrabhakar Kushwaha { 862c517771aSPrabhakar Kushwaha struct dpni_pools_cfg pools_params; 863c517771aSPrabhakar Kushwaha struct dpni_tx_flow_cfg dflt_tx_flow; 8646073548aSPrabhakar Kushwaha struct dpni_tx_conf_cfg tx_conf_cfg; 865c517771aSPrabhakar Kushwaha int err = 0; 866c517771aSPrabhakar Kushwaha 867c517771aSPrabhakar Kushwaha pools_params.num_dpbp = 1; 868c517771aSPrabhakar Kushwaha pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id; 869c517771aSPrabhakar Kushwaha pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE; 870c919ab9eSPrabhakar Kushwaha err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS, 871c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, &pools_params); 872c517771aSPrabhakar Kushwaha if (err) { 873c517771aSPrabhakar Kushwaha printf("dpni_set_pools() failed\n"); 874c517771aSPrabhakar Kushwaha return err; 875c517771aSPrabhakar Kushwaha } 876c517771aSPrabhakar Kushwaha 877c517771aSPrabhakar Kushwaha priv->tx_flow_id = DPNI_NEW_FLOW_ID; 878c517771aSPrabhakar Kushwaha memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow)); 879c517771aSPrabhakar Kushwaha 88053e353fcSPrabhakar Kushwaha dflt_tx_flow.use_common_tx_conf_queue = 0; 881c919ab9eSPrabhakar Kushwaha err = dpni_set_tx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, 882c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, &priv->tx_flow_id, 883c919ab9eSPrabhakar Kushwaha &dflt_tx_flow); 884c517771aSPrabhakar Kushwaha if (err) { 885c517771aSPrabhakar Kushwaha printf("dpni_set_tx_flow() failed\n"); 886c517771aSPrabhakar Kushwaha return err; 887c517771aSPrabhakar Kushwaha } 888c517771aSPrabhakar Kushwaha 8896073548aSPrabhakar Kushwaha memset(&tx_conf_cfg, 0, sizeof(struct dpni_tx_conf_cfg)); 8906073548aSPrabhakar Kushwaha tx_conf_cfg.errors_only = true; 8916073548aSPrabhakar Kushwaha /*Set tx-conf and error configuration*/ 8926073548aSPrabhakar Kushwaha err = dpni_set_tx_conf(dflt_mc_io, MC_CMD_NO_FLAGS, 8936073548aSPrabhakar Kushwaha dflt_dpni->dpni_handle, 8946073548aSPrabhakar Kushwaha priv->tx_flow_id, &tx_conf_cfg); 8956073548aSPrabhakar Kushwaha if (err) { 8966073548aSPrabhakar Kushwaha printf("dpni_set_tx_conf() failed\n"); 8976073548aSPrabhakar Kushwaha return err; 8986073548aSPrabhakar Kushwaha } 8996073548aSPrabhakar Kushwaha 900c517771aSPrabhakar Kushwaha return 0; 901c517771aSPrabhakar Kushwaha } 902c517771aSPrabhakar Kushwaha 903c919ab9eSPrabhakar Kushwaha static int ldpaa_eth_netdev_init(struct eth_device *net_dev, 904c919ab9eSPrabhakar Kushwaha phy_interface_t enet_if) 905c517771aSPrabhakar Kushwaha { 906c517771aSPrabhakar Kushwaha int err; 907c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 908c517771aSPrabhakar Kushwaha 909c919ab9eSPrabhakar Kushwaha sprintf(net_dev->name, "DPMAC%d@%s", priv->dpmac_id, 910c919ab9eSPrabhakar Kushwaha phy_interface_strings[enet_if]); 911c517771aSPrabhakar Kushwaha 912c517771aSPrabhakar Kushwaha net_dev->iobase = 0; 913c517771aSPrabhakar Kushwaha net_dev->init = ldpaa_eth_open; 914c517771aSPrabhakar Kushwaha net_dev->halt = ldpaa_eth_stop; 915c517771aSPrabhakar Kushwaha net_dev->send = ldpaa_eth_tx; 916c517771aSPrabhakar Kushwaha net_dev->recv = ldpaa_eth_pull_dequeue_rx; 917c517771aSPrabhakar Kushwaha /* 918c517771aSPrabhakar Kushwaha TODO: PHY MDIO information 919c517771aSPrabhakar Kushwaha priv->bus = info->bus; 920c517771aSPrabhakar Kushwaha priv->phyaddr = info->phy_addr; 921c517771aSPrabhakar Kushwaha priv->enet_if = info->enet_if; 922c517771aSPrabhakar Kushwaha */ 923c517771aSPrabhakar Kushwaha 924c517771aSPrabhakar Kushwaha if (init_phy(net_dev)) 925c517771aSPrabhakar Kushwaha return 0; 926c517771aSPrabhakar Kushwaha 927c517771aSPrabhakar Kushwaha err = eth_register(net_dev); 928c517771aSPrabhakar Kushwaha if (err < 0) { 929c517771aSPrabhakar Kushwaha printf("eth_register() = %d\n", err); 930c517771aSPrabhakar Kushwaha return err; 931c517771aSPrabhakar Kushwaha } 932c517771aSPrabhakar Kushwaha 933c517771aSPrabhakar Kushwaha return 0; 934c517771aSPrabhakar Kushwaha } 935c517771aSPrabhakar Kushwaha 936c919ab9eSPrabhakar Kushwaha int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if) 937c517771aSPrabhakar Kushwaha { 938c517771aSPrabhakar Kushwaha struct eth_device *net_dev = NULL; 939c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = NULL; 940c517771aSPrabhakar Kushwaha int err = 0; 941c517771aSPrabhakar Kushwaha 942c517771aSPrabhakar Kushwaha 943c517771aSPrabhakar Kushwaha /* Net device */ 944c517771aSPrabhakar Kushwaha net_dev = (struct eth_device *)malloc(sizeof(struct eth_device)); 945c517771aSPrabhakar Kushwaha if (!net_dev) { 946c517771aSPrabhakar Kushwaha printf("eth_device malloc() failed\n"); 947c517771aSPrabhakar Kushwaha return -ENOMEM; 948c517771aSPrabhakar Kushwaha } 949c517771aSPrabhakar Kushwaha memset(net_dev, 0, sizeof(struct eth_device)); 950c517771aSPrabhakar Kushwaha 951c517771aSPrabhakar Kushwaha /* alloc the ldpaa ethernet private struct */ 952c517771aSPrabhakar Kushwaha priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv)); 953c517771aSPrabhakar Kushwaha if (!priv) { 954c517771aSPrabhakar Kushwaha printf("ldpaa_eth_priv malloc() failed\n"); 955c517771aSPrabhakar Kushwaha return -ENOMEM; 956c517771aSPrabhakar Kushwaha } 957c517771aSPrabhakar Kushwaha memset(priv, 0, sizeof(struct ldpaa_eth_priv)); 958c517771aSPrabhakar Kushwaha 959c517771aSPrabhakar Kushwaha net_dev->priv = (void *)priv; 960c517771aSPrabhakar Kushwaha priv->net_dev = (struct eth_device *)net_dev; 961c919ab9eSPrabhakar Kushwaha priv->dpmac_id = dpmac_id; 962c919ab9eSPrabhakar Kushwaha debug("%s dpmac_id=%d\n", __func__, dpmac_id); 963c517771aSPrabhakar Kushwaha 964c919ab9eSPrabhakar Kushwaha err = ldpaa_eth_netdev_init(net_dev, enet_if); 965c517771aSPrabhakar Kushwaha if (err) 966c517771aSPrabhakar Kushwaha goto err_netdev_init; 967c517771aSPrabhakar Kushwaha 968c517771aSPrabhakar Kushwaha debug("ldpaa ethernet: Probed interface %s\n", net_dev->name); 969c517771aSPrabhakar Kushwaha return 0; 970c517771aSPrabhakar Kushwaha 971c517771aSPrabhakar Kushwaha err_netdev_init: 972c517771aSPrabhakar Kushwaha free(priv); 973c517771aSPrabhakar Kushwaha net_dev->priv = NULL; 974c517771aSPrabhakar Kushwaha free(net_dev); 975c517771aSPrabhakar Kushwaha 976c517771aSPrabhakar Kushwaha return err; 977c517771aSPrabhakar Kushwaha } 978