1*c517771aSPrabhakar Kushwaha /* 2*c517771aSPrabhakar Kushwaha * Copyright (C) 2014 Freescale Semiconductor 3*c517771aSPrabhakar Kushwaha * 4*c517771aSPrabhakar Kushwaha * SPDX-License-Identifier: GPL-2.0+ 5*c517771aSPrabhakar Kushwaha */ 6*c517771aSPrabhakar Kushwaha 7*c517771aSPrabhakar Kushwaha #include <common.h> 8*c517771aSPrabhakar Kushwaha #include <asm/io.h> 9*c517771aSPrabhakar Kushwaha #include <asm/types.h> 10*c517771aSPrabhakar Kushwaha #include <malloc.h> 11*c517771aSPrabhakar Kushwaha #include <net.h> 12*c517771aSPrabhakar Kushwaha #include <hwconfig.h> 13*c517771aSPrabhakar Kushwaha #include <phy.h> 14*c517771aSPrabhakar Kushwaha #include <linux/compat.h> 15*c517771aSPrabhakar Kushwaha 16*c517771aSPrabhakar Kushwaha #include "ldpaa_eth.h" 17*c517771aSPrabhakar Kushwaha 18*c517771aSPrabhakar Kushwaha static int init_phy(struct eth_device *dev) 19*c517771aSPrabhakar Kushwaha { 20*c517771aSPrabhakar Kushwaha /*TODO for external PHY */ 21*c517771aSPrabhakar Kushwaha 22*c517771aSPrabhakar Kushwaha return 0; 23*c517771aSPrabhakar Kushwaha } 24*c517771aSPrabhakar Kushwaha 25*c517771aSPrabhakar Kushwaha static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv, 26*c517771aSPrabhakar Kushwaha const struct dpaa_fd *fd) 27*c517771aSPrabhakar Kushwaha { 28*c517771aSPrabhakar Kushwaha u64 fd_addr; 29*c517771aSPrabhakar Kushwaha uint16_t fd_offset; 30*c517771aSPrabhakar Kushwaha uint32_t fd_length; 31*c517771aSPrabhakar Kushwaha struct ldpaa_fas *fas; 32*c517771aSPrabhakar Kushwaha uint32_t status, err; 33*c517771aSPrabhakar Kushwaha struct qbman_release_desc releasedesc; 34*c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 35*c517771aSPrabhakar Kushwaha 36*c517771aSPrabhakar Kushwaha invalidate_dcache_all(); 37*c517771aSPrabhakar Kushwaha 38*c517771aSPrabhakar Kushwaha fd_addr = ldpaa_fd_get_addr(fd); 39*c517771aSPrabhakar Kushwaha fd_offset = ldpaa_fd_get_offset(fd); 40*c517771aSPrabhakar Kushwaha fd_length = ldpaa_fd_get_len(fd); 41*c517771aSPrabhakar Kushwaha 42*c517771aSPrabhakar Kushwaha debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length); 43*c517771aSPrabhakar Kushwaha 44*c517771aSPrabhakar Kushwaha if (fd->simple.frc & LDPAA_FD_FRC_FASV) { 45*c517771aSPrabhakar Kushwaha /* Read the frame annotation status word and check for errors */ 46*c517771aSPrabhakar Kushwaha fas = (struct ldpaa_fas *) 47*c517771aSPrabhakar Kushwaha ((uint8_t *)(fd_addr) + 48*c517771aSPrabhakar Kushwaha priv->buf_layout.private_data_size); 49*c517771aSPrabhakar Kushwaha status = le32_to_cpu(fas->status); 50*c517771aSPrabhakar Kushwaha if (status & LDPAA_ETH_RX_ERR_MASK) { 51*c517771aSPrabhakar Kushwaha printf("Rx frame error(s): 0x%08x\n", 52*c517771aSPrabhakar Kushwaha status & LDPAA_ETH_RX_ERR_MASK); 53*c517771aSPrabhakar Kushwaha goto error; 54*c517771aSPrabhakar Kushwaha } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) { 55*c517771aSPrabhakar Kushwaha printf("Unsupported feature in bitmask: 0x%08x\n", 56*c517771aSPrabhakar Kushwaha status & LDPAA_ETH_RX_UNSUPP_MASK); 57*c517771aSPrabhakar Kushwaha goto error; 58*c517771aSPrabhakar Kushwaha } 59*c517771aSPrabhakar Kushwaha } 60*c517771aSPrabhakar Kushwaha 61*c517771aSPrabhakar Kushwaha debug("Rx frame: To Upper layer\n"); 62*c517771aSPrabhakar Kushwaha net_process_received_packet((uint8_t *)(fd_addr) + fd_offset, 63*c517771aSPrabhakar Kushwaha fd_length); 64*c517771aSPrabhakar Kushwaha 65*c517771aSPrabhakar Kushwaha error: 66*c517771aSPrabhakar Kushwaha qbman_release_desc_clear(&releasedesc); 67*c517771aSPrabhakar Kushwaha qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 68*c517771aSPrabhakar Kushwaha do { 69*c517771aSPrabhakar Kushwaha /* Release buffer into the QBMAN */ 70*c517771aSPrabhakar Kushwaha err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); 71*c517771aSPrabhakar Kushwaha } while (err == -EBUSY); 72*c517771aSPrabhakar Kushwaha return; 73*c517771aSPrabhakar Kushwaha } 74*c517771aSPrabhakar Kushwaha 75*c517771aSPrabhakar Kushwaha static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) 76*c517771aSPrabhakar Kushwaha { 77*c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; 78*c517771aSPrabhakar Kushwaha const struct ldpaa_dq *dq; 79*c517771aSPrabhakar Kushwaha const struct dpaa_fd *fd; 80*c517771aSPrabhakar Kushwaha int i = 5, err = 0, status; 81*c517771aSPrabhakar Kushwaha static struct qbman_pull_desc pulldesc; 82*c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 83*c517771aSPrabhakar Kushwaha 84*c517771aSPrabhakar Kushwaha qbman_pull_desc_clear(&pulldesc); 85*c517771aSPrabhakar Kushwaha qbman_pull_desc_set_numframes(&pulldesc, 1); 86*c517771aSPrabhakar Kushwaha qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid); 87*c517771aSPrabhakar Kushwaha 88*c517771aSPrabhakar Kushwaha while (--i) { 89*c517771aSPrabhakar Kushwaha err = qbman_swp_pull(swp, &pulldesc); 90*c517771aSPrabhakar Kushwaha if (err < 0) { 91*c517771aSPrabhakar Kushwaha printf("Dequeue frames error:0x%08x\n", err); 92*c517771aSPrabhakar Kushwaha continue; 93*c517771aSPrabhakar Kushwaha } 94*c517771aSPrabhakar Kushwaha 95*c517771aSPrabhakar Kushwaha dq = qbman_swp_dqrr_next(swp); 96*c517771aSPrabhakar Kushwaha if (dq) { 97*c517771aSPrabhakar Kushwaha /* Check for valid frame. If not sent a consume 98*c517771aSPrabhakar Kushwaha * confirmation to QBMAN otherwise give it to NADK 99*c517771aSPrabhakar Kushwaha * application and then send consume confirmation to 100*c517771aSPrabhakar Kushwaha * QBMAN. 101*c517771aSPrabhakar Kushwaha */ 102*c517771aSPrabhakar Kushwaha status = (uint8_t)ldpaa_dq_flags(dq); 103*c517771aSPrabhakar Kushwaha if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) { 104*c517771aSPrabhakar Kushwaha debug("Dequeue RX frames:"); 105*c517771aSPrabhakar Kushwaha debug("No frame delivered\n"); 106*c517771aSPrabhakar Kushwaha 107*c517771aSPrabhakar Kushwaha qbman_swp_dqrr_consume(swp, dq); 108*c517771aSPrabhakar Kushwaha break; 109*c517771aSPrabhakar Kushwaha } 110*c517771aSPrabhakar Kushwaha 111*c517771aSPrabhakar Kushwaha fd = ldpaa_dq_fd(dq); 112*c517771aSPrabhakar Kushwaha 113*c517771aSPrabhakar Kushwaha /* Obtain FD and process it */ 114*c517771aSPrabhakar Kushwaha ldpaa_eth_rx(priv, fd); 115*c517771aSPrabhakar Kushwaha qbman_swp_dqrr_consume(swp, dq); 116*c517771aSPrabhakar Kushwaha break; 117*c517771aSPrabhakar Kushwaha } 118*c517771aSPrabhakar Kushwaha } 119*c517771aSPrabhakar Kushwaha 120*c517771aSPrabhakar Kushwaha return err; 121*c517771aSPrabhakar Kushwaha } 122*c517771aSPrabhakar Kushwaha 123*c517771aSPrabhakar Kushwaha static void ldpaa_eth_tx_conf(struct ldpaa_eth_priv *priv, 124*c517771aSPrabhakar Kushwaha const struct dpaa_fd *fd) 125*c517771aSPrabhakar Kushwaha { 126*c517771aSPrabhakar Kushwaha uint64_t fd_addr; 127*c517771aSPrabhakar Kushwaha struct ldpaa_fas *fas; 128*c517771aSPrabhakar Kushwaha uint32_t status, err; 129*c517771aSPrabhakar Kushwaha struct qbman_release_desc releasedesc; 130*c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 131*c517771aSPrabhakar Kushwaha 132*c517771aSPrabhakar Kushwaha invalidate_dcache_all(); 133*c517771aSPrabhakar Kushwaha fd_addr = ldpaa_fd_get_addr(fd); 134*c517771aSPrabhakar Kushwaha 135*c517771aSPrabhakar Kushwaha 136*c517771aSPrabhakar Kushwaha debug("TX Conf frame:data addr=0x%p\n", (u64 *)fd_addr); 137*c517771aSPrabhakar Kushwaha 138*c517771aSPrabhakar Kushwaha /* Check the status from the Frame Annotation */ 139*c517771aSPrabhakar Kushwaha if (fd->simple.frc & LDPAA_FD_FRC_FASV) { 140*c517771aSPrabhakar Kushwaha fas = (struct ldpaa_fas *) 141*c517771aSPrabhakar Kushwaha ((uint8_t *)(fd_addr) + 142*c517771aSPrabhakar Kushwaha priv->buf_layout.private_data_size); 143*c517771aSPrabhakar Kushwaha status = le32_to_cpu(fas->status); 144*c517771aSPrabhakar Kushwaha if (status & LDPAA_ETH_TXCONF_ERR_MASK) { 145*c517771aSPrabhakar Kushwaha printf("TxConf frame error(s): 0x%08x\n", 146*c517771aSPrabhakar Kushwaha status & LDPAA_ETH_TXCONF_ERR_MASK); 147*c517771aSPrabhakar Kushwaha } 148*c517771aSPrabhakar Kushwaha } 149*c517771aSPrabhakar Kushwaha 150*c517771aSPrabhakar Kushwaha qbman_release_desc_clear(&releasedesc); 151*c517771aSPrabhakar Kushwaha qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 152*c517771aSPrabhakar Kushwaha do { 153*c517771aSPrabhakar Kushwaha /* Release buffer into the QBMAN */ 154*c517771aSPrabhakar Kushwaha err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); 155*c517771aSPrabhakar Kushwaha } while (err == -EBUSY); 156*c517771aSPrabhakar Kushwaha } 157*c517771aSPrabhakar Kushwaha 158*c517771aSPrabhakar Kushwaha static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv) 159*c517771aSPrabhakar Kushwaha { 160*c517771aSPrabhakar Kushwaha const struct ldpaa_dq *dq; 161*c517771aSPrabhakar Kushwaha const struct dpaa_fd *fd; 162*c517771aSPrabhakar Kushwaha int err = 0; 163*c517771aSPrabhakar Kushwaha int i = 5, status; 164*c517771aSPrabhakar Kushwaha static struct qbman_pull_desc pulldesc; 165*c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 166*c517771aSPrabhakar Kushwaha 167*c517771aSPrabhakar Kushwaha qbman_pull_desc_clear(&pulldesc); 168*c517771aSPrabhakar Kushwaha qbman_pull_desc_set_numframes(&pulldesc, 1); 169*c517771aSPrabhakar Kushwaha qbman_pull_desc_set_fq(&pulldesc, priv->tx_conf_fqid); 170*c517771aSPrabhakar Kushwaha 171*c517771aSPrabhakar Kushwaha while (--i) { 172*c517771aSPrabhakar Kushwaha err = qbman_swp_pull(swp, &pulldesc); 173*c517771aSPrabhakar Kushwaha if (err < 0) { 174*c517771aSPrabhakar Kushwaha printf("Dequeue TX conf frames error:0x%08x\n", err); 175*c517771aSPrabhakar Kushwaha continue; 176*c517771aSPrabhakar Kushwaha } 177*c517771aSPrabhakar Kushwaha 178*c517771aSPrabhakar Kushwaha dq = qbman_swp_dqrr_next(swp); 179*c517771aSPrabhakar Kushwaha if (dq) { 180*c517771aSPrabhakar Kushwaha /* Check for valid frame. If not sent a consume 181*c517771aSPrabhakar Kushwaha * confirmation to QBMAN otherwise give it to NADK 182*c517771aSPrabhakar Kushwaha * application and then send consume confirmation to 183*c517771aSPrabhakar Kushwaha * QBMAN. 184*c517771aSPrabhakar Kushwaha */ 185*c517771aSPrabhakar Kushwaha status = (uint8_t)ldpaa_dq_flags(dq); 186*c517771aSPrabhakar Kushwaha if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) { 187*c517771aSPrabhakar Kushwaha debug("Dequeue TX conf frames:"); 188*c517771aSPrabhakar Kushwaha debug("No frame is delivered\n"); 189*c517771aSPrabhakar Kushwaha 190*c517771aSPrabhakar Kushwaha qbman_swp_dqrr_consume(swp, dq); 191*c517771aSPrabhakar Kushwaha break; 192*c517771aSPrabhakar Kushwaha } 193*c517771aSPrabhakar Kushwaha fd = ldpaa_dq_fd(dq); 194*c517771aSPrabhakar Kushwaha 195*c517771aSPrabhakar Kushwaha ldpaa_eth_tx_conf(priv, fd); 196*c517771aSPrabhakar Kushwaha qbman_swp_dqrr_consume(swp, dq); 197*c517771aSPrabhakar Kushwaha break; 198*c517771aSPrabhakar Kushwaha } 199*c517771aSPrabhakar Kushwaha } 200*c517771aSPrabhakar Kushwaha 201*c517771aSPrabhakar Kushwaha return err; 202*c517771aSPrabhakar Kushwaha } 203*c517771aSPrabhakar Kushwaha 204*c517771aSPrabhakar Kushwaha static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) 205*c517771aSPrabhakar Kushwaha { 206*c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 207*c517771aSPrabhakar Kushwaha struct dpaa_fd fd; 208*c517771aSPrabhakar Kushwaha u64 buffer_start; 209*c517771aSPrabhakar Kushwaha int data_offset, err; 210*c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 211*c517771aSPrabhakar Kushwaha struct qbman_eq_desc ed; 212*c517771aSPrabhakar Kushwaha 213*c517771aSPrabhakar Kushwaha /* Setup the FD fields */ 214*c517771aSPrabhakar Kushwaha memset(&fd, 0, sizeof(fd)); 215*c517771aSPrabhakar Kushwaha 216*c517771aSPrabhakar Kushwaha data_offset = priv->tx_data_offset; 217*c517771aSPrabhakar Kushwaha 218*c517771aSPrabhakar Kushwaha do { 219*c517771aSPrabhakar Kushwaha err = qbman_swp_acquire(dflt_dpio->sw_portal, 220*c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.bpid, 221*c517771aSPrabhakar Kushwaha &buffer_start, 1); 222*c517771aSPrabhakar Kushwaha } while (err == -EBUSY); 223*c517771aSPrabhakar Kushwaha 224*c517771aSPrabhakar Kushwaha if (err < 0) { 225*c517771aSPrabhakar Kushwaha printf("qbman_swp_acquire() failed\n"); 226*c517771aSPrabhakar Kushwaha return -ENOMEM; 227*c517771aSPrabhakar Kushwaha } 228*c517771aSPrabhakar Kushwaha 229*c517771aSPrabhakar Kushwaha debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start); 230*c517771aSPrabhakar Kushwaha 231*c517771aSPrabhakar Kushwaha memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len); 232*c517771aSPrabhakar Kushwaha 233*c517771aSPrabhakar Kushwaha flush_dcache_range(buffer_start, LDPAA_ETH_RX_BUFFER_SIZE); 234*c517771aSPrabhakar Kushwaha 235*c517771aSPrabhakar Kushwaha ldpaa_fd_set_addr(&fd, (u64)buffer_start); 236*c517771aSPrabhakar Kushwaha ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset)); 237*c517771aSPrabhakar Kushwaha ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid); 238*c517771aSPrabhakar Kushwaha ldpaa_fd_set_len(&fd, len); 239*c517771aSPrabhakar Kushwaha 240*c517771aSPrabhakar Kushwaha fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA | 241*c517771aSPrabhakar Kushwaha LDPAA_FD_CTRL_PTV1; 242*c517771aSPrabhakar Kushwaha 243*c517771aSPrabhakar Kushwaha qbman_eq_desc_clear(&ed); 244*c517771aSPrabhakar Kushwaha qbman_eq_desc_set_no_orp(&ed, 0); 245*c517771aSPrabhakar Kushwaha qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0); 246*c517771aSPrabhakar Kushwaha err = qbman_swp_enqueue(swp, &ed, (const struct qbman_fd *)(&fd)); 247*c517771aSPrabhakar Kushwaha if (err < 0) 248*c517771aSPrabhakar Kushwaha printf("error enqueueing Tx frame\n"); 249*c517771aSPrabhakar Kushwaha 250*c517771aSPrabhakar Kushwaha mdelay(1); 251*c517771aSPrabhakar Kushwaha 252*c517771aSPrabhakar Kushwaha err = ldpaa_eth_pull_dequeue_tx_conf(priv); 253*c517771aSPrabhakar Kushwaha if (err < 0) 254*c517771aSPrabhakar Kushwaha printf("error Tx Conf frame\n"); 255*c517771aSPrabhakar Kushwaha 256*c517771aSPrabhakar Kushwaha return err; 257*c517771aSPrabhakar Kushwaha } 258*c517771aSPrabhakar Kushwaha 259*c517771aSPrabhakar Kushwaha static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) 260*c517771aSPrabhakar Kushwaha { 261*c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 262*c517771aSPrabhakar Kushwaha struct dpni_queue_attr rx_queue_attr; 263*c517771aSPrabhakar Kushwaha struct dpni_tx_flow_attr tx_flow_attr; 264*c517771aSPrabhakar Kushwaha uint8_t mac_addr[6]; 265*c517771aSPrabhakar Kushwaha int err; 266*c517771aSPrabhakar Kushwaha 267*c517771aSPrabhakar Kushwaha if (net_dev->state == ETH_STATE_ACTIVE) 268*c517771aSPrabhakar Kushwaha return 0; 269*c517771aSPrabhakar Kushwaha 270*c517771aSPrabhakar Kushwaha /* DPNI initialization */ 271*c517771aSPrabhakar Kushwaha err = ldpaa_dpni_setup(priv); 272*c517771aSPrabhakar Kushwaha if (err < 0) 273*c517771aSPrabhakar Kushwaha goto err_dpni_setup; 274*c517771aSPrabhakar Kushwaha 275*c517771aSPrabhakar Kushwaha err = ldpaa_dpbp_setup(); 276*c517771aSPrabhakar Kushwaha if (err < 0) 277*c517771aSPrabhakar Kushwaha goto err_dpbp_setup; 278*c517771aSPrabhakar Kushwaha 279*c517771aSPrabhakar Kushwaha /* DPNI binding DPBP */ 280*c517771aSPrabhakar Kushwaha err = ldpaa_dpni_bind(priv); 281*c517771aSPrabhakar Kushwaha if (err) 282*c517771aSPrabhakar Kushwaha goto err_bind; 283*c517771aSPrabhakar Kushwaha 284*c517771aSPrabhakar Kushwaha err = dpni_get_primary_mac_addr(dflt_mc_io, priv->dpni_handle, 285*c517771aSPrabhakar Kushwaha mac_addr); 286*c517771aSPrabhakar Kushwaha if (err) { 287*c517771aSPrabhakar Kushwaha printf("dpni_get_primary_mac_addr() failed\n"); 288*c517771aSPrabhakar Kushwaha return err; 289*c517771aSPrabhakar Kushwaha } 290*c517771aSPrabhakar Kushwaha 291*c517771aSPrabhakar Kushwaha memcpy(net_dev->enetaddr, mac_addr, 0x6); 292*c517771aSPrabhakar Kushwaha 293*c517771aSPrabhakar Kushwaha /* setup the MAC address */ 294*c517771aSPrabhakar Kushwaha if (net_dev->enetaddr[0] & 0x01) { 295*c517771aSPrabhakar Kushwaha printf("%s: MacAddress is multcast address\n", __func__); 296*c517771aSPrabhakar Kushwaha return 1; 297*c517771aSPrabhakar Kushwaha } 298*c517771aSPrabhakar Kushwaha 299*c517771aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB 300*c517771aSPrabhakar Kushwaha /* TODO Check this path */ 301*c517771aSPrabhakar Kushwaha ret = phy_startup(priv->phydev); 302*c517771aSPrabhakar Kushwaha if (ret) { 303*c517771aSPrabhakar Kushwaha printf("%s: Could not initialize\n", priv->phydev->dev->name); 304*c517771aSPrabhakar Kushwaha return ret; 305*c517771aSPrabhakar Kushwaha } 306*c517771aSPrabhakar Kushwaha #else 307*c517771aSPrabhakar Kushwaha priv->phydev->speed = SPEED_1000; 308*c517771aSPrabhakar Kushwaha priv->phydev->link = 1; 309*c517771aSPrabhakar Kushwaha priv->phydev->duplex = DUPLEX_FULL; 310*c517771aSPrabhakar Kushwaha #endif 311*c517771aSPrabhakar Kushwaha 312*c517771aSPrabhakar Kushwaha err = dpni_enable(dflt_mc_io, priv->dpni_handle); 313*c517771aSPrabhakar Kushwaha if (err < 0) { 314*c517771aSPrabhakar Kushwaha printf("dpni_enable() failed\n"); 315*c517771aSPrabhakar Kushwaha return err; 316*c517771aSPrabhakar Kushwaha } 317*c517771aSPrabhakar Kushwaha 318*c517771aSPrabhakar Kushwaha /* TODO: support multiple Rx flows */ 319*c517771aSPrabhakar Kushwaha err = dpni_get_rx_flow(dflt_mc_io, priv->dpni_handle, 0, 0, 320*c517771aSPrabhakar Kushwaha &rx_queue_attr); 321*c517771aSPrabhakar Kushwaha if (err) { 322*c517771aSPrabhakar Kushwaha printf("dpni_get_rx_flow() failed\n"); 323*c517771aSPrabhakar Kushwaha goto err_rx_flow; 324*c517771aSPrabhakar Kushwaha } 325*c517771aSPrabhakar Kushwaha 326*c517771aSPrabhakar Kushwaha priv->rx_dflt_fqid = rx_queue_attr.fqid; 327*c517771aSPrabhakar Kushwaha 328*c517771aSPrabhakar Kushwaha err = dpni_get_qdid(dflt_mc_io, priv->dpni_handle, &priv->tx_qdid); 329*c517771aSPrabhakar Kushwaha if (err) { 330*c517771aSPrabhakar Kushwaha printf("dpni_get_qdid() failed\n"); 331*c517771aSPrabhakar Kushwaha goto err_qdid; 332*c517771aSPrabhakar Kushwaha } 333*c517771aSPrabhakar Kushwaha 334*c517771aSPrabhakar Kushwaha err = dpni_get_tx_flow(dflt_mc_io, priv->dpni_handle, priv->tx_flow_id, 335*c517771aSPrabhakar Kushwaha &tx_flow_attr); 336*c517771aSPrabhakar Kushwaha if (err) { 337*c517771aSPrabhakar Kushwaha printf("dpni_get_tx_flow() failed\n"); 338*c517771aSPrabhakar Kushwaha goto err_tx_flow; 339*c517771aSPrabhakar Kushwaha } 340*c517771aSPrabhakar Kushwaha 341*c517771aSPrabhakar Kushwaha priv->tx_conf_fqid = tx_flow_attr.conf_err_attr.queue_attr.fqid; 342*c517771aSPrabhakar Kushwaha 343*c517771aSPrabhakar Kushwaha if (!priv->phydev->link) 344*c517771aSPrabhakar Kushwaha printf("%s: No link.\n", priv->phydev->dev->name); 345*c517771aSPrabhakar Kushwaha 346*c517771aSPrabhakar Kushwaha return priv->phydev->link ? 0 : -1; 347*c517771aSPrabhakar Kushwaha 348*c517771aSPrabhakar Kushwaha err_tx_flow: 349*c517771aSPrabhakar Kushwaha err_qdid: 350*c517771aSPrabhakar Kushwaha err_rx_flow: 351*c517771aSPrabhakar Kushwaha dpni_disable(dflt_mc_io, priv->dpni_handle); 352*c517771aSPrabhakar Kushwaha err_bind: 353*c517771aSPrabhakar Kushwaha ldpaa_dpbp_free(); 354*c517771aSPrabhakar Kushwaha err_dpbp_setup: 355*c517771aSPrabhakar Kushwaha dpni_close(dflt_mc_io, priv->dpni_handle); 356*c517771aSPrabhakar Kushwaha err_dpni_setup: 357*c517771aSPrabhakar Kushwaha return err; 358*c517771aSPrabhakar Kushwaha } 359*c517771aSPrabhakar Kushwaha 360*c517771aSPrabhakar Kushwaha static void ldpaa_eth_stop(struct eth_device *net_dev) 361*c517771aSPrabhakar Kushwaha { 362*c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 363*c517771aSPrabhakar Kushwaha int err = 0; 364*c517771aSPrabhakar Kushwaha 365*c517771aSPrabhakar Kushwaha if (net_dev->state == ETH_STATE_PASSIVE) 366*c517771aSPrabhakar Kushwaha return; 367*c517771aSPrabhakar Kushwaha /* Stop Tx and Rx traffic */ 368*c517771aSPrabhakar Kushwaha err = dpni_disable(dflt_mc_io, priv->dpni_handle); 369*c517771aSPrabhakar Kushwaha if (err < 0) 370*c517771aSPrabhakar Kushwaha printf("dpni_disable() failed\n"); 371*c517771aSPrabhakar Kushwaha 372*c517771aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB 373*c517771aSPrabhakar Kushwaha phy_shutdown(priv->phydev); 374*c517771aSPrabhakar Kushwaha #endif 375*c517771aSPrabhakar Kushwaha 376*c517771aSPrabhakar Kushwaha ldpaa_dpbp_free(); 377*c517771aSPrabhakar Kushwaha dpni_reset(dflt_mc_io, priv->dpni_handle); 378*c517771aSPrabhakar Kushwaha dpni_close(dflt_mc_io, priv->dpni_handle); 379*c517771aSPrabhakar Kushwaha } 380*c517771aSPrabhakar Kushwaha 381*c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain_cnt(int count) 382*c517771aSPrabhakar Kushwaha { 383*c517771aSPrabhakar Kushwaha uint64_t buf_array[7]; 384*c517771aSPrabhakar Kushwaha void *addr; 385*c517771aSPrabhakar Kushwaha int ret, i; 386*c517771aSPrabhakar Kushwaha 387*c517771aSPrabhakar Kushwaha BUG_ON(count > 7); 388*c517771aSPrabhakar Kushwaha 389*c517771aSPrabhakar Kushwaha do { 390*c517771aSPrabhakar Kushwaha ret = qbman_swp_acquire(dflt_dpio->sw_portal, 391*c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.bpid, 392*c517771aSPrabhakar Kushwaha buf_array, count); 393*c517771aSPrabhakar Kushwaha if (ret < 0) { 394*c517771aSPrabhakar Kushwaha printf("qbman_swp_acquire() failed\n"); 395*c517771aSPrabhakar Kushwaha return; 396*c517771aSPrabhakar Kushwaha } 397*c517771aSPrabhakar Kushwaha for (i = 0; i < ret; i++) { 398*c517771aSPrabhakar Kushwaha addr = (void *)buf_array[i]; 399*c517771aSPrabhakar Kushwaha debug("Free: buffer addr =0x%p\n", addr); 400*c517771aSPrabhakar Kushwaha free(addr); 401*c517771aSPrabhakar Kushwaha } 402*c517771aSPrabhakar Kushwaha } while (ret); 403*c517771aSPrabhakar Kushwaha } 404*c517771aSPrabhakar Kushwaha 405*c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain(void) 406*c517771aSPrabhakar Kushwaha { 407*c517771aSPrabhakar Kushwaha int i; 408*c517771aSPrabhakar Kushwaha for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) 409*c517771aSPrabhakar Kushwaha ldpaa_dpbp_drain_cnt(7); 410*c517771aSPrabhakar Kushwaha } 411*c517771aSPrabhakar Kushwaha 412*c517771aSPrabhakar Kushwaha static int ldpaa_bp_add_7(uint16_t bpid) 413*c517771aSPrabhakar Kushwaha { 414*c517771aSPrabhakar Kushwaha uint64_t buf_array[7]; 415*c517771aSPrabhakar Kushwaha u8 *addr; 416*c517771aSPrabhakar Kushwaha int i; 417*c517771aSPrabhakar Kushwaha struct qbman_release_desc rd; 418*c517771aSPrabhakar Kushwaha 419*c517771aSPrabhakar Kushwaha for (i = 0; i < 7; i++) { 420*c517771aSPrabhakar Kushwaha addr = memalign(L1_CACHE_BYTES, LDPAA_ETH_RX_BUFFER_SIZE); 421*c517771aSPrabhakar Kushwaha if (!addr) { 422*c517771aSPrabhakar Kushwaha printf("addr allocation failed\n"); 423*c517771aSPrabhakar Kushwaha goto err_alloc; 424*c517771aSPrabhakar Kushwaha } 425*c517771aSPrabhakar Kushwaha memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE); 426*c517771aSPrabhakar Kushwaha 427*c517771aSPrabhakar Kushwaha buf_array[i] = (uint64_t)addr; 428*c517771aSPrabhakar Kushwaha debug("Release: buffer addr =0x%p\n", addr); 429*c517771aSPrabhakar Kushwaha } 430*c517771aSPrabhakar Kushwaha 431*c517771aSPrabhakar Kushwaha release_bufs: 432*c517771aSPrabhakar Kushwaha /* In case the portal is busy, retry until successful. 433*c517771aSPrabhakar Kushwaha * This function is guaranteed to succeed in a reasonable amount 434*c517771aSPrabhakar Kushwaha * of time. 435*c517771aSPrabhakar Kushwaha */ 436*c517771aSPrabhakar Kushwaha 437*c517771aSPrabhakar Kushwaha do { 438*c517771aSPrabhakar Kushwaha mdelay(1); 439*c517771aSPrabhakar Kushwaha qbman_release_desc_clear(&rd); 440*c517771aSPrabhakar Kushwaha qbman_release_desc_set_bpid(&rd, bpid); 441*c517771aSPrabhakar Kushwaha } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i)); 442*c517771aSPrabhakar Kushwaha 443*c517771aSPrabhakar Kushwaha return i; 444*c517771aSPrabhakar Kushwaha 445*c517771aSPrabhakar Kushwaha err_alloc: 446*c517771aSPrabhakar Kushwaha if (i) 447*c517771aSPrabhakar Kushwaha goto release_bufs; 448*c517771aSPrabhakar Kushwaha 449*c517771aSPrabhakar Kushwaha return 0; 450*c517771aSPrabhakar Kushwaha } 451*c517771aSPrabhakar Kushwaha 452*c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_seed(uint16_t bpid) 453*c517771aSPrabhakar Kushwaha { 454*c517771aSPrabhakar Kushwaha int i; 455*c517771aSPrabhakar Kushwaha int count; 456*c517771aSPrabhakar Kushwaha 457*c517771aSPrabhakar Kushwaha for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) { 458*c517771aSPrabhakar Kushwaha count = ldpaa_bp_add_7(bpid); 459*c517771aSPrabhakar Kushwaha if (count < 7) 460*c517771aSPrabhakar Kushwaha printf("Buffer Seed= %d\n", count); 461*c517771aSPrabhakar Kushwaha } 462*c517771aSPrabhakar Kushwaha 463*c517771aSPrabhakar Kushwaha return 0; 464*c517771aSPrabhakar Kushwaha } 465*c517771aSPrabhakar Kushwaha 466*c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_setup(void) 467*c517771aSPrabhakar Kushwaha { 468*c517771aSPrabhakar Kushwaha int err; 469*c517771aSPrabhakar Kushwaha 470*c517771aSPrabhakar Kushwaha err = dpbp_open(dflt_mc_io, dflt_dpbp->dpbp_attr.id, 471*c517771aSPrabhakar Kushwaha &dflt_dpbp->dpbp_handle); 472*c517771aSPrabhakar Kushwaha if (err) { 473*c517771aSPrabhakar Kushwaha printf("dpbp_open() failed\n"); 474*c517771aSPrabhakar Kushwaha goto err_open; 475*c517771aSPrabhakar Kushwaha } 476*c517771aSPrabhakar Kushwaha 477*c517771aSPrabhakar Kushwaha err = dpbp_enable(dflt_mc_io, dflt_dpbp->dpbp_handle); 478*c517771aSPrabhakar Kushwaha if (err) { 479*c517771aSPrabhakar Kushwaha printf("dpbp_enable() failed\n"); 480*c517771aSPrabhakar Kushwaha goto err_enable; 481*c517771aSPrabhakar Kushwaha } 482*c517771aSPrabhakar Kushwaha 483*c517771aSPrabhakar Kushwaha err = dpbp_get_attributes(dflt_mc_io, dflt_dpbp->dpbp_handle, 484*c517771aSPrabhakar Kushwaha &dflt_dpbp->dpbp_attr); 485*c517771aSPrabhakar Kushwaha if (err) { 486*c517771aSPrabhakar Kushwaha printf("dpbp_get_attributes() failed\n"); 487*c517771aSPrabhakar Kushwaha goto err_get_attr; 488*c517771aSPrabhakar Kushwaha } 489*c517771aSPrabhakar Kushwaha 490*c517771aSPrabhakar Kushwaha err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid); 491*c517771aSPrabhakar Kushwaha if (err) { 492*c517771aSPrabhakar Kushwaha printf("Buffer seeding failed for DPBP %d (bpid=%d)\n", 493*c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid); 494*c517771aSPrabhakar Kushwaha goto err_seed; 495*c517771aSPrabhakar Kushwaha } 496*c517771aSPrabhakar Kushwaha 497*c517771aSPrabhakar Kushwaha return 0; 498*c517771aSPrabhakar Kushwaha 499*c517771aSPrabhakar Kushwaha err_seed: 500*c517771aSPrabhakar Kushwaha err_get_attr: 501*c517771aSPrabhakar Kushwaha dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle); 502*c517771aSPrabhakar Kushwaha err_enable: 503*c517771aSPrabhakar Kushwaha dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle); 504*c517771aSPrabhakar Kushwaha err_open: 505*c517771aSPrabhakar Kushwaha return err; 506*c517771aSPrabhakar Kushwaha } 507*c517771aSPrabhakar Kushwaha 508*c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_free(void) 509*c517771aSPrabhakar Kushwaha { 510*c517771aSPrabhakar Kushwaha ldpaa_dpbp_drain(); 511*c517771aSPrabhakar Kushwaha dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle); 512*c517771aSPrabhakar Kushwaha dpbp_reset(dflt_mc_io, dflt_dpbp->dpbp_handle); 513*c517771aSPrabhakar Kushwaha dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle); 514*c517771aSPrabhakar Kushwaha } 515*c517771aSPrabhakar Kushwaha 516*c517771aSPrabhakar Kushwaha static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) 517*c517771aSPrabhakar Kushwaha { 518*c517771aSPrabhakar Kushwaha int err; 519*c517771aSPrabhakar Kushwaha 520*c517771aSPrabhakar Kushwaha /* and get a handle for the DPNI this interface is associate with */ 521*c517771aSPrabhakar Kushwaha err = dpni_open(dflt_mc_io, priv->dpni_id, &priv->dpni_handle); 522*c517771aSPrabhakar Kushwaha if (err) { 523*c517771aSPrabhakar Kushwaha printf("dpni_open() failed\n"); 524*c517771aSPrabhakar Kushwaha goto err_open; 525*c517771aSPrabhakar Kushwaha } 526*c517771aSPrabhakar Kushwaha 527*c517771aSPrabhakar Kushwaha err = dpni_get_attributes(dflt_mc_io, priv->dpni_handle, 528*c517771aSPrabhakar Kushwaha &priv->dpni_attrs); 529*c517771aSPrabhakar Kushwaha if (err) { 530*c517771aSPrabhakar Kushwaha printf("dpni_get_attributes() failed (err=%d)\n", err); 531*c517771aSPrabhakar Kushwaha goto err_get_attr; 532*c517771aSPrabhakar Kushwaha } 533*c517771aSPrabhakar Kushwaha 534*c517771aSPrabhakar Kushwaha /* Configure our buffers' layout */ 535*c517771aSPrabhakar Kushwaha priv->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | 536*c517771aSPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | 537*c517771aSPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; 538*c517771aSPrabhakar Kushwaha priv->buf_layout.pass_parser_result = true; 539*c517771aSPrabhakar Kushwaha priv->buf_layout.pass_frame_status = true; 540*c517771aSPrabhakar Kushwaha priv->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE; 541*c517771aSPrabhakar Kushwaha /* ...rx, ... */ 542*c517771aSPrabhakar Kushwaha err = dpni_set_rx_buffer_layout(dflt_mc_io, priv->dpni_handle, 543*c517771aSPrabhakar Kushwaha &priv->buf_layout); 544*c517771aSPrabhakar Kushwaha if (err) { 545*c517771aSPrabhakar Kushwaha printf("dpni_set_rx_buffer_layout() failed"); 546*c517771aSPrabhakar Kushwaha goto err_buf_layout; 547*c517771aSPrabhakar Kushwaha } 548*c517771aSPrabhakar Kushwaha 549*c517771aSPrabhakar Kushwaha /* ... tx, ... */ 550*c517771aSPrabhakar Kushwaha priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PARSER_RESULT; 551*c517771aSPrabhakar Kushwaha err = dpni_set_tx_buffer_layout(dflt_mc_io, priv->dpni_handle, 552*c517771aSPrabhakar Kushwaha &priv->buf_layout); 553*c517771aSPrabhakar Kushwaha if (err) { 554*c517771aSPrabhakar Kushwaha printf("dpni_set_tx_buffer_layout() failed"); 555*c517771aSPrabhakar Kushwaha goto err_buf_layout; 556*c517771aSPrabhakar Kushwaha } 557*c517771aSPrabhakar Kushwaha 558*c517771aSPrabhakar Kushwaha /* ... tx-confirm. */ 559*c517771aSPrabhakar Kushwaha priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; 560*c517771aSPrabhakar Kushwaha err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, priv->dpni_handle, 561*c517771aSPrabhakar Kushwaha &priv->buf_layout); 562*c517771aSPrabhakar Kushwaha if (err) { 563*c517771aSPrabhakar Kushwaha printf("dpni_set_tx_conf_buffer_layout() failed"); 564*c517771aSPrabhakar Kushwaha goto err_buf_layout; 565*c517771aSPrabhakar Kushwaha } 566*c517771aSPrabhakar Kushwaha 567*c517771aSPrabhakar Kushwaha /* Now that we've set our tx buffer layout, retrieve the minimum 568*c517771aSPrabhakar Kushwaha * required tx data offset. 569*c517771aSPrabhakar Kushwaha */ 570*c517771aSPrabhakar Kushwaha err = dpni_get_tx_data_offset(dflt_mc_io, priv->dpni_handle, 571*c517771aSPrabhakar Kushwaha &priv->tx_data_offset); 572*c517771aSPrabhakar Kushwaha if (err) { 573*c517771aSPrabhakar Kushwaha printf("dpni_get_tx_data_offset() failed\n"); 574*c517771aSPrabhakar Kushwaha goto err_data_offset; 575*c517771aSPrabhakar Kushwaha } 576*c517771aSPrabhakar Kushwaha 577*c517771aSPrabhakar Kushwaha /* Warn in case TX data offset is not multiple of 64 bytes. */ 578*c517771aSPrabhakar Kushwaha WARN_ON(priv->tx_data_offset % 64); 579*c517771aSPrabhakar Kushwaha 580*c517771aSPrabhakar Kushwaha /* Accomodate SWA space. */ 581*c517771aSPrabhakar Kushwaha priv->tx_data_offset += LDPAA_ETH_SWA_SIZE; 582*c517771aSPrabhakar Kushwaha debug("priv->tx_data_offset=%d\n", priv->tx_data_offset); 583*c517771aSPrabhakar Kushwaha 584*c517771aSPrabhakar Kushwaha return 0; 585*c517771aSPrabhakar Kushwaha 586*c517771aSPrabhakar Kushwaha err_data_offset: 587*c517771aSPrabhakar Kushwaha err_buf_layout: 588*c517771aSPrabhakar Kushwaha err_get_attr: 589*c517771aSPrabhakar Kushwaha dpni_close(dflt_mc_io, priv->dpni_handle); 590*c517771aSPrabhakar Kushwaha err_open: 591*c517771aSPrabhakar Kushwaha return err; 592*c517771aSPrabhakar Kushwaha } 593*c517771aSPrabhakar Kushwaha 594*c517771aSPrabhakar Kushwaha static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) 595*c517771aSPrabhakar Kushwaha { 596*c517771aSPrabhakar Kushwaha struct dpni_pools_cfg pools_params; 597*c517771aSPrabhakar Kushwaha struct dpni_tx_flow_cfg dflt_tx_flow; 598*c517771aSPrabhakar Kushwaha int err = 0; 599*c517771aSPrabhakar Kushwaha 600*c517771aSPrabhakar Kushwaha pools_params.num_dpbp = 1; 601*c517771aSPrabhakar Kushwaha pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id; 602*c517771aSPrabhakar Kushwaha pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE; 603*c517771aSPrabhakar Kushwaha err = dpni_set_pools(dflt_mc_io, priv->dpni_handle, &pools_params); 604*c517771aSPrabhakar Kushwaha if (err) { 605*c517771aSPrabhakar Kushwaha printf("dpni_set_pools() failed\n"); 606*c517771aSPrabhakar Kushwaha return err; 607*c517771aSPrabhakar Kushwaha } 608*c517771aSPrabhakar Kushwaha 609*c517771aSPrabhakar Kushwaha priv->tx_flow_id = DPNI_NEW_FLOW_ID; 610*c517771aSPrabhakar Kushwaha memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow)); 611*c517771aSPrabhakar Kushwaha 612*c517771aSPrabhakar Kushwaha err = dpni_set_tx_flow(dflt_mc_io, priv->dpni_handle, 613*c517771aSPrabhakar Kushwaha &priv->tx_flow_id, &dflt_tx_flow); 614*c517771aSPrabhakar Kushwaha if (err) { 615*c517771aSPrabhakar Kushwaha printf("dpni_set_tx_flow() failed\n"); 616*c517771aSPrabhakar Kushwaha return err; 617*c517771aSPrabhakar Kushwaha } 618*c517771aSPrabhakar Kushwaha 619*c517771aSPrabhakar Kushwaha return 0; 620*c517771aSPrabhakar Kushwaha } 621*c517771aSPrabhakar Kushwaha 622*c517771aSPrabhakar Kushwaha static int ldpaa_eth_netdev_init(struct eth_device *net_dev) 623*c517771aSPrabhakar Kushwaha { 624*c517771aSPrabhakar Kushwaha int err; 625*c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 626*c517771aSPrabhakar Kushwaha 627*c517771aSPrabhakar Kushwaha if (priv->type == LDPAA_ETH_1G_E) 628*c517771aSPrabhakar Kushwaha sprintf(net_dev->name, "DTSEC%d", priv->dpni_id); 629*c517771aSPrabhakar Kushwaha else 630*c517771aSPrabhakar Kushwaha sprintf(net_dev->name, "TGEC%d", priv->dpni_id); 631*c517771aSPrabhakar Kushwaha 632*c517771aSPrabhakar Kushwaha net_dev->iobase = 0; 633*c517771aSPrabhakar Kushwaha net_dev->init = ldpaa_eth_open; 634*c517771aSPrabhakar Kushwaha net_dev->halt = ldpaa_eth_stop; 635*c517771aSPrabhakar Kushwaha net_dev->send = ldpaa_eth_tx; 636*c517771aSPrabhakar Kushwaha net_dev->recv = ldpaa_eth_pull_dequeue_rx; 637*c517771aSPrabhakar Kushwaha /* 638*c517771aSPrabhakar Kushwaha TODO: PHY MDIO information 639*c517771aSPrabhakar Kushwaha priv->bus = info->bus; 640*c517771aSPrabhakar Kushwaha priv->phyaddr = info->phy_addr; 641*c517771aSPrabhakar Kushwaha priv->enet_if = info->enet_if; 642*c517771aSPrabhakar Kushwaha */ 643*c517771aSPrabhakar Kushwaha 644*c517771aSPrabhakar Kushwaha if (init_phy(net_dev)) 645*c517771aSPrabhakar Kushwaha return 0; 646*c517771aSPrabhakar Kushwaha 647*c517771aSPrabhakar Kushwaha err = eth_register(net_dev); 648*c517771aSPrabhakar Kushwaha if (err < 0) { 649*c517771aSPrabhakar Kushwaha printf("eth_register() = %d\n", err); 650*c517771aSPrabhakar Kushwaha return err; 651*c517771aSPrabhakar Kushwaha } 652*c517771aSPrabhakar Kushwaha 653*c517771aSPrabhakar Kushwaha return 0; 654*c517771aSPrabhakar Kushwaha } 655*c517771aSPrabhakar Kushwaha 656*c517771aSPrabhakar Kushwaha int ldpaa_eth_init(struct dprc_obj_desc obj_desc) 657*c517771aSPrabhakar Kushwaha { 658*c517771aSPrabhakar Kushwaha struct eth_device *net_dev = NULL; 659*c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = NULL; 660*c517771aSPrabhakar Kushwaha int err = 0; 661*c517771aSPrabhakar Kushwaha 662*c517771aSPrabhakar Kushwaha 663*c517771aSPrabhakar Kushwaha /* Net device */ 664*c517771aSPrabhakar Kushwaha net_dev = (struct eth_device *)malloc(sizeof(struct eth_device)); 665*c517771aSPrabhakar Kushwaha if (!net_dev) { 666*c517771aSPrabhakar Kushwaha printf("eth_device malloc() failed\n"); 667*c517771aSPrabhakar Kushwaha return -ENOMEM; 668*c517771aSPrabhakar Kushwaha } 669*c517771aSPrabhakar Kushwaha memset(net_dev, 0, sizeof(struct eth_device)); 670*c517771aSPrabhakar Kushwaha 671*c517771aSPrabhakar Kushwaha /* alloc the ldpaa ethernet private struct */ 672*c517771aSPrabhakar Kushwaha priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv)); 673*c517771aSPrabhakar Kushwaha if (!priv) { 674*c517771aSPrabhakar Kushwaha printf("ldpaa_eth_priv malloc() failed\n"); 675*c517771aSPrabhakar Kushwaha return -ENOMEM; 676*c517771aSPrabhakar Kushwaha } 677*c517771aSPrabhakar Kushwaha memset(priv, 0, sizeof(struct ldpaa_eth_priv)); 678*c517771aSPrabhakar Kushwaha 679*c517771aSPrabhakar Kushwaha net_dev->priv = (void *)priv; 680*c517771aSPrabhakar Kushwaha priv->net_dev = (struct eth_device *)net_dev; 681*c517771aSPrabhakar Kushwaha priv->dpni_id = obj_desc.id; 682*c517771aSPrabhakar Kushwaha 683*c517771aSPrabhakar Kushwaha err = ldpaa_eth_netdev_init(net_dev); 684*c517771aSPrabhakar Kushwaha if (err) 685*c517771aSPrabhakar Kushwaha goto err_netdev_init; 686*c517771aSPrabhakar Kushwaha 687*c517771aSPrabhakar Kushwaha debug("ldpaa ethernet: Probed interface %s\n", net_dev->name); 688*c517771aSPrabhakar Kushwaha return 0; 689*c517771aSPrabhakar Kushwaha 690*c517771aSPrabhakar Kushwaha err_netdev_init: 691*c517771aSPrabhakar Kushwaha free(priv); 692*c517771aSPrabhakar Kushwaha net_dev->priv = NULL; 693*c517771aSPrabhakar Kushwaha free(net_dev); 694*c517771aSPrabhakar Kushwaha 695*c517771aSPrabhakar Kushwaha return err; 696*c517771aSPrabhakar Kushwaha } 697