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> 15*c919ab9eSPrabhakar 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 27c517771aSPrabhakar Kushwaha static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv, 28c517771aSPrabhakar Kushwaha const struct dpaa_fd *fd) 29c517771aSPrabhakar Kushwaha { 30c517771aSPrabhakar Kushwaha u64 fd_addr; 31c517771aSPrabhakar Kushwaha uint16_t fd_offset; 32c517771aSPrabhakar Kushwaha uint32_t fd_length; 33c517771aSPrabhakar Kushwaha struct ldpaa_fas *fas; 34c517771aSPrabhakar Kushwaha uint32_t status, err; 3556c57cf7SPrabhakar Kushwaha u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; 3656c57cf7SPrabhakar Kushwaha u32 time_start; 37c517771aSPrabhakar Kushwaha struct qbman_release_desc releasedesc; 38c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 39c517771aSPrabhakar Kushwaha 40c517771aSPrabhakar Kushwaha fd_addr = ldpaa_fd_get_addr(fd); 41c517771aSPrabhakar Kushwaha fd_offset = ldpaa_fd_get_offset(fd); 42c517771aSPrabhakar Kushwaha fd_length = ldpaa_fd_get_len(fd); 43c517771aSPrabhakar Kushwaha 44c517771aSPrabhakar Kushwaha debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length); 45c517771aSPrabhakar Kushwaha 46c517771aSPrabhakar Kushwaha if (fd->simple.frc & LDPAA_FD_FRC_FASV) { 47c517771aSPrabhakar Kushwaha /* Read the frame annotation status word and check for errors */ 48c517771aSPrabhakar Kushwaha fas = (struct ldpaa_fas *) 49c517771aSPrabhakar Kushwaha ((uint8_t *)(fd_addr) + 50*c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.private_data_size); 51c517771aSPrabhakar Kushwaha status = le32_to_cpu(fas->status); 52c517771aSPrabhakar Kushwaha if (status & LDPAA_ETH_RX_ERR_MASK) { 53c517771aSPrabhakar Kushwaha printf("Rx frame error(s): 0x%08x\n", 54c517771aSPrabhakar Kushwaha status & LDPAA_ETH_RX_ERR_MASK); 55c517771aSPrabhakar Kushwaha goto error; 56c517771aSPrabhakar Kushwaha } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) { 57c517771aSPrabhakar Kushwaha printf("Unsupported feature in bitmask: 0x%08x\n", 58c517771aSPrabhakar Kushwaha status & LDPAA_ETH_RX_UNSUPP_MASK); 59c517771aSPrabhakar Kushwaha goto error; 60c517771aSPrabhakar Kushwaha } 61c517771aSPrabhakar Kushwaha } 62c517771aSPrabhakar Kushwaha 63c517771aSPrabhakar Kushwaha debug("Rx frame: To Upper layer\n"); 64c517771aSPrabhakar Kushwaha net_process_received_packet((uint8_t *)(fd_addr) + fd_offset, 65c517771aSPrabhakar Kushwaha fd_length); 66c517771aSPrabhakar Kushwaha 67c517771aSPrabhakar Kushwaha error: 685753b0f1SPrabhakar Kushwaha flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE); 69c517771aSPrabhakar Kushwaha qbman_release_desc_clear(&releasedesc); 70c517771aSPrabhakar Kushwaha qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 7156c57cf7SPrabhakar Kushwaha time_start = get_timer(0); 72c517771aSPrabhakar Kushwaha do { 73c517771aSPrabhakar Kushwaha /* Release buffer into the QBMAN */ 74c517771aSPrabhakar Kushwaha err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); 7556c57cf7SPrabhakar Kushwaha } while (get_timer(time_start) < timeo && err == -EBUSY); 7656c57cf7SPrabhakar Kushwaha 7756c57cf7SPrabhakar Kushwaha if (err == -EBUSY) 7856c57cf7SPrabhakar Kushwaha printf("Rx frame: QBMAN buffer release fails\n"); 7956c57cf7SPrabhakar Kushwaha 80c517771aSPrabhakar Kushwaha return; 81c517771aSPrabhakar Kushwaha } 82c517771aSPrabhakar Kushwaha 83c517771aSPrabhakar Kushwaha static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) 84c517771aSPrabhakar Kushwaha { 85c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; 86c517771aSPrabhakar Kushwaha const struct ldpaa_dq *dq; 87c517771aSPrabhakar Kushwaha const struct dpaa_fd *fd; 88b4c3a35dSPrabhakar Kushwaha int i = 5, err = 0, status; 89b4c3a35dSPrabhakar Kushwaha u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; 90b4c3a35dSPrabhakar Kushwaha u32 time_start; 91c517771aSPrabhakar Kushwaha static struct qbman_pull_desc pulldesc; 92c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 93c517771aSPrabhakar Kushwaha 945753b0f1SPrabhakar Kushwaha while (--i) { 95c517771aSPrabhakar Kushwaha qbman_pull_desc_clear(&pulldesc); 96c517771aSPrabhakar Kushwaha qbman_pull_desc_set_numframes(&pulldesc, 1); 97c517771aSPrabhakar Kushwaha qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid); 98c517771aSPrabhakar Kushwaha 99c517771aSPrabhakar Kushwaha err = qbman_swp_pull(swp, &pulldesc); 100c517771aSPrabhakar Kushwaha if (err < 0) { 101c517771aSPrabhakar Kushwaha printf("Dequeue frames error:0x%08x\n", err); 102c517771aSPrabhakar Kushwaha continue; 103c517771aSPrabhakar Kushwaha } 104c517771aSPrabhakar Kushwaha 105b4c3a35dSPrabhakar Kushwaha time_start = get_timer(0); 1065753b0f1SPrabhakar Kushwaha 107b4c3a35dSPrabhakar Kushwaha do { 108b4c3a35dSPrabhakar Kushwaha dq = qbman_swp_dqrr_next(swp); 109b4c3a35dSPrabhakar Kushwaha } while (get_timer(time_start) < timeo && !dq); 1105753b0f1SPrabhakar Kushwaha 111c517771aSPrabhakar Kushwaha if (dq) { 112c517771aSPrabhakar Kushwaha /* Check for valid frame. If not sent a consume 113c517771aSPrabhakar Kushwaha * confirmation to QBMAN otherwise give it to NADK 114c517771aSPrabhakar Kushwaha * application and then send consume confirmation to 115c517771aSPrabhakar Kushwaha * QBMAN. 116c517771aSPrabhakar Kushwaha */ 117c517771aSPrabhakar Kushwaha status = (uint8_t)ldpaa_dq_flags(dq); 118c517771aSPrabhakar Kushwaha if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) { 119c517771aSPrabhakar Kushwaha debug("Dequeue RX frames:"); 120c517771aSPrabhakar Kushwaha debug("No frame delivered\n"); 121c517771aSPrabhakar Kushwaha 122c517771aSPrabhakar Kushwaha qbman_swp_dqrr_consume(swp, dq); 1230c7c87a4SPrabhakar Kushwaha continue; 124c517771aSPrabhakar Kushwaha } 125c517771aSPrabhakar Kushwaha 126c517771aSPrabhakar Kushwaha fd = ldpaa_dq_fd(dq); 127c517771aSPrabhakar Kushwaha 128c517771aSPrabhakar Kushwaha /* Obtain FD and process it */ 129c517771aSPrabhakar Kushwaha ldpaa_eth_rx(priv, fd); 130c517771aSPrabhakar Kushwaha qbman_swp_dqrr_consume(swp, dq); 131c517771aSPrabhakar Kushwaha break; 132b4c3a35dSPrabhakar Kushwaha } else { 133b4c3a35dSPrabhakar Kushwaha err = -ENODATA; 134b4c3a35dSPrabhakar Kushwaha debug("No DQRR entries\n"); 135b4c3a35dSPrabhakar Kushwaha break; 136c517771aSPrabhakar Kushwaha } 137c517771aSPrabhakar Kushwaha } 138c517771aSPrabhakar Kushwaha 139c517771aSPrabhakar Kushwaha return err; 140c517771aSPrabhakar Kushwaha } 141c517771aSPrabhakar Kushwaha 142c517771aSPrabhakar Kushwaha static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) 143c517771aSPrabhakar Kushwaha { 144c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 145c517771aSPrabhakar Kushwaha struct dpaa_fd fd; 146c517771aSPrabhakar Kushwaha u64 buffer_start; 147c517771aSPrabhakar Kushwaha int data_offset, err; 148e48df52bSPrabhakar Kushwaha u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; 149e48df52bSPrabhakar Kushwaha u32 time_start; 150c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 151c517771aSPrabhakar Kushwaha struct qbman_eq_desc ed; 152e48df52bSPrabhakar Kushwaha struct qbman_release_desc releasedesc; 153c517771aSPrabhakar Kushwaha 154c517771aSPrabhakar Kushwaha /* Setup the FD fields */ 155c517771aSPrabhakar Kushwaha memset(&fd, 0, sizeof(fd)); 156c517771aSPrabhakar Kushwaha 157c517771aSPrabhakar Kushwaha data_offset = priv->tx_data_offset; 158c517771aSPrabhakar Kushwaha 159c517771aSPrabhakar Kushwaha do { 160c517771aSPrabhakar Kushwaha err = qbman_swp_acquire(dflt_dpio->sw_portal, 161c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.bpid, 162c517771aSPrabhakar Kushwaha &buffer_start, 1); 163c517771aSPrabhakar Kushwaha } while (err == -EBUSY); 164c517771aSPrabhakar Kushwaha 165c517771aSPrabhakar Kushwaha if (err < 0) { 166c517771aSPrabhakar Kushwaha printf("qbman_swp_acquire() failed\n"); 167c517771aSPrabhakar Kushwaha return -ENOMEM; 168c517771aSPrabhakar Kushwaha } 169c517771aSPrabhakar Kushwaha 170c517771aSPrabhakar Kushwaha debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start); 171c517771aSPrabhakar Kushwaha 172c517771aSPrabhakar Kushwaha memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len); 173c517771aSPrabhakar Kushwaha 1745753b0f1SPrabhakar Kushwaha flush_dcache_range(buffer_start, buffer_start + 1755753b0f1SPrabhakar Kushwaha LDPAA_ETH_RX_BUFFER_SIZE); 176c517771aSPrabhakar Kushwaha 177c517771aSPrabhakar Kushwaha ldpaa_fd_set_addr(&fd, (u64)buffer_start); 178c517771aSPrabhakar Kushwaha ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset)); 179c517771aSPrabhakar Kushwaha ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid); 180c517771aSPrabhakar Kushwaha ldpaa_fd_set_len(&fd, len); 181c517771aSPrabhakar Kushwaha 182c517771aSPrabhakar Kushwaha fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA | 183c517771aSPrabhakar Kushwaha LDPAA_FD_CTRL_PTV1; 184c517771aSPrabhakar Kushwaha 185c517771aSPrabhakar Kushwaha qbman_eq_desc_clear(&ed); 186c517771aSPrabhakar Kushwaha qbman_eq_desc_set_no_orp(&ed, 0); 187c517771aSPrabhakar Kushwaha qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0); 188e48df52bSPrabhakar Kushwaha 189e48df52bSPrabhakar Kushwaha time_start = get_timer(0); 190e48df52bSPrabhakar Kushwaha 191e48df52bSPrabhakar Kushwaha while (get_timer(time_start) < timeo) { 192e48df52bSPrabhakar Kushwaha err = qbman_swp_enqueue(swp, &ed, 193e48df52bSPrabhakar Kushwaha (const struct qbman_fd *)(&fd)); 194e48df52bSPrabhakar Kushwaha if (err != -EBUSY) 195e48df52bSPrabhakar Kushwaha break; 196e48df52bSPrabhakar Kushwaha } 197e48df52bSPrabhakar Kushwaha 198e48df52bSPrabhakar Kushwaha if (err < 0) { 199c517771aSPrabhakar Kushwaha printf("error enqueueing Tx frame\n"); 200e48df52bSPrabhakar Kushwaha goto error; 201e48df52bSPrabhakar Kushwaha } 202c517771aSPrabhakar Kushwaha 203c517771aSPrabhakar Kushwaha return err; 204e48df52bSPrabhakar Kushwaha 205e48df52bSPrabhakar Kushwaha error: 206e48df52bSPrabhakar Kushwaha qbman_release_desc_clear(&releasedesc); 207e48df52bSPrabhakar Kushwaha qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 208e48df52bSPrabhakar Kushwaha time_start = get_timer(0); 209e48df52bSPrabhakar Kushwaha do { 210e48df52bSPrabhakar Kushwaha /* Release buffer into the QBMAN */ 211e48df52bSPrabhakar Kushwaha err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1); 212e48df52bSPrabhakar Kushwaha } while (get_timer(time_start) < timeo && err == -EBUSY); 213e48df52bSPrabhakar Kushwaha 214e48df52bSPrabhakar Kushwaha if (err == -EBUSY) 215e48df52bSPrabhakar Kushwaha printf("TX data: QBMAN buffer release fails\n"); 216e48df52bSPrabhakar Kushwaha 217e48df52bSPrabhakar Kushwaha return err; 218c517771aSPrabhakar Kushwaha } 219c517771aSPrabhakar Kushwaha 220c517771aSPrabhakar Kushwaha static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) 221c517771aSPrabhakar Kushwaha { 222c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 223c517771aSPrabhakar Kushwaha struct dpni_queue_attr rx_queue_attr; 224*c919ab9eSPrabhakar Kushwaha struct dpmac_link_state dpmac_link_state = { 0 }; 225c517771aSPrabhakar Kushwaha int err; 226c517771aSPrabhakar Kushwaha 227c517771aSPrabhakar Kushwaha if (net_dev->state == ETH_STATE_ACTIVE) 228c517771aSPrabhakar Kushwaha return 0; 229c517771aSPrabhakar Kushwaha 230*c919ab9eSPrabhakar Kushwaha if (get_mc_boot_status() != 0) { 231*c919ab9eSPrabhakar Kushwaha printf("ERROR (MC is not booted)\n"); 232*c919ab9eSPrabhakar Kushwaha return -ENODEV; 233*c919ab9eSPrabhakar Kushwaha } 234*c919ab9eSPrabhakar Kushwaha 235*c919ab9eSPrabhakar Kushwaha if (get_dpl_apply_status() == 0) { 236*c919ab9eSPrabhakar Kushwaha printf("ERROR (DPL is deployed. No device available)\n"); 237*c919ab9eSPrabhakar Kushwaha return -ENODEV; 238*c919ab9eSPrabhakar Kushwaha } 239*c919ab9eSPrabhakar Kushwaha /* DPMAC initialization */ 240*c919ab9eSPrabhakar Kushwaha err = ldpaa_dpmac_setup(priv); 241*c919ab9eSPrabhakar Kushwaha if (err < 0) 242*c919ab9eSPrabhakar Kushwaha goto err_dpmac_setup; 243*c919ab9eSPrabhakar Kushwaha 244*c919ab9eSPrabhakar Kushwaha /* DPMAC binding DPNI */ 245*c919ab9eSPrabhakar Kushwaha err = ldpaa_dpmac_bind(priv); 246*c919ab9eSPrabhakar Kushwaha if (err) 247*c919ab9eSPrabhakar Kushwaha goto err_dpamc_bind; 248*c919ab9eSPrabhakar Kushwaha 249c517771aSPrabhakar Kushwaha /* DPNI initialization */ 250c517771aSPrabhakar Kushwaha err = ldpaa_dpni_setup(priv); 251c517771aSPrabhakar Kushwaha if (err < 0) 252c517771aSPrabhakar Kushwaha goto err_dpni_setup; 253c517771aSPrabhakar Kushwaha 254c517771aSPrabhakar Kushwaha err = ldpaa_dpbp_setup(); 255c517771aSPrabhakar Kushwaha if (err < 0) 256c517771aSPrabhakar Kushwaha goto err_dpbp_setup; 257c517771aSPrabhakar Kushwaha 258c517771aSPrabhakar Kushwaha /* DPNI binding DPBP */ 259c517771aSPrabhakar Kushwaha err = ldpaa_dpni_bind(priv); 260c517771aSPrabhakar Kushwaha if (err) 261*c919ab9eSPrabhakar Kushwaha goto err_dpni_bind; 262c517771aSPrabhakar Kushwaha 2637b2edb8bSPrabhakar Kushwaha err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, 264*c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, net_dev->enetaddr); 265c517771aSPrabhakar Kushwaha if (err) { 2667b2edb8bSPrabhakar Kushwaha printf("dpni_add_mac_addr() failed\n"); 267c517771aSPrabhakar Kushwaha return err; 268c517771aSPrabhakar Kushwaha } 269c517771aSPrabhakar Kushwaha 270c517771aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB 271c517771aSPrabhakar Kushwaha /* TODO Check this path */ 2725753b0f1SPrabhakar Kushwaha err = phy_startup(priv->phydev); 2735753b0f1SPrabhakar Kushwaha if (err) { 274c517771aSPrabhakar Kushwaha printf("%s: Could not initialize\n", priv->phydev->dev->name); 2755753b0f1SPrabhakar Kushwaha return err; 276c517771aSPrabhakar Kushwaha } 277c517771aSPrabhakar Kushwaha #else 278c517771aSPrabhakar Kushwaha priv->phydev->speed = SPEED_1000; 279c517771aSPrabhakar Kushwaha priv->phydev->link = 1; 280c517771aSPrabhakar Kushwaha priv->phydev->duplex = DUPLEX_FULL; 281c517771aSPrabhakar Kushwaha #endif 282c517771aSPrabhakar Kushwaha 283*c919ab9eSPrabhakar Kushwaha err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 284c517771aSPrabhakar Kushwaha if (err < 0) { 285c517771aSPrabhakar Kushwaha printf("dpni_enable() failed\n"); 286c517771aSPrabhakar Kushwaha return err; 287c517771aSPrabhakar Kushwaha } 288c517771aSPrabhakar Kushwaha 289*c919ab9eSPrabhakar Kushwaha dpmac_link_state.rate = SPEED_1000; 290*c919ab9eSPrabhakar Kushwaha dpmac_link_state.options = DPMAC_LINK_OPT_AUTONEG; 291*c919ab9eSPrabhakar Kushwaha dpmac_link_state.up = 1; 292*c919ab9eSPrabhakar Kushwaha err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, 293*c919ab9eSPrabhakar Kushwaha priv->dpmac_handle, &dpmac_link_state); 294*c919ab9eSPrabhakar Kushwaha if (err < 0) { 295*c919ab9eSPrabhakar Kushwaha printf("dpmac_set_link_state() failed\n"); 296*c919ab9eSPrabhakar Kushwaha return err; 297*c919ab9eSPrabhakar Kushwaha } 298c517771aSPrabhakar Kushwaha /* TODO: support multiple Rx flows */ 299*c919ab9eSPrabhakar Kushwaha err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, 300*c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr); 301c517771aSPrabhakar Kushwaha if (err) { 302c517771aSPrabhakar Kushwaha printf("dpni_get_rx_flow() failed\n"); 303c517771aSPrabhakar Kushwaha goto err_rx_flow; 304c517771aSPrabhakar Kushwaha } 305c517771aSPrabhakar Kushwaha 306c517771aSPrabhakar Kushwaha priv->rx_dflt_fqid = rx_queue_attr.fqid; 307c517771aSPrabhakar Kushwaha 308*c919ab9eSPrabhakar Kushwaha err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, 30987457d11SPrabhakar Kushwaha &priv->tx_qdid); 310c517771aSPrabhakar Kushwaha if (err) { 311c517771aSPrabhakar Kushwaha printf("dpni_get_qdid() failed\n"); 312c517771aSPrabhakar Kushwaha goto err_qdid; 313c517771aSPrabhakar Kushwaha } 314c517771aSPrabhakar Kushwaha 315c517771aSPrabhakar Kushwaha if (!priv->phydev->link) 316c517771aSPrabhakar Kushwaha printf("%s: No link.\n", priv->phydev->dev->name); 317c517771aSPrabhakar Kushwaha 318c517771aSPrabhakar Kushwaha return priv->phydev->link ? 0 : -1; 319c517771aSPrabhakar Kushwaha 320c517771aSPrabhakar Kushwaha err_qdid: 321c517771aSPrabhakar Kushwaha err_rx_flow: 322*c919ab9eSPrabhakar Kushwaha dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 323*c919ab9eSPrabhakar Kushwaha err_dpni_bind: 324c517771aSPrabhakar Kushwaha ldpaa_dpbp_free(); 325c517771aSPrabhakar Kushwaha err_dpbp_setup: 326*c919ab9eSPrabhakar Kushwaha err_dpamc_bind: 327*c919ab9eSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 328c517771aSPrabhakar Kushwaha err_dpni_setup: 329*c919ab9eSPrabhakar Kushwaha err_dpmac_setup: 330c517771aSPrabhakar Kushwaha return err; 331c517771aSPrabhakar Kushwaha } 332c517771aSPrabhakar Kushwaha 333c517771aSPrabhakar Kushwaha static void ldpaa_eth_stop(struct eth_device *net_dev) 334c517771aSPrabhakar Kushwaha { 335c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 336c517771aSPrabhakar Kushwaha int err = 0; 337c517771aSPrabhakar Kushwaha 3385753b0f1SPrabhakar Kushwaha if ((net_dev->state == ETH_STATE_PASSIVE) || 3395753b0f1SPrabhakar Kushwaha (net_dev->state == ETH_STATE_INIT)) 340c517771aSPrabhakar Kushwaha return; 341*c919ab9eSPrabhakar Kushwaha 342*c919ab9eSPrabhakar Kushwaha err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS, 343*c919ab9eSPrabhakar Kushwaha dflt_dprc_handle, &dpmac_endpoint); 344*c919ab9eSPrabhakar Kushwaha if (err < 0) 345*c919ab9eSPrabhakar Kushwaha printf("dprc_disconnect() failed dpmac_endpoint\n"); 346*c919ab9eSPrabhakar Kushwaha 347*c919ab9eSPrabhakar Kushwaha err = dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); 348*c919ab9eSPrabhakar Kushwaha if (err < 0) 349*c919ab9eSPrabhakar Kushwaha printf("dpmac_destroy() failed\n"); 350*c919ab9eSPrabhakar Kushwaha 351c517771aSPrabhakar Kushwaha /* Stop Tx and Rx traffic */ 352*c919ab9eSPrabhakar Kushwaha err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 353c517771aSPrabhakar Kushwaha if (err < 0) 354c517771aSPrabhakar Kushwaha printf("dpni_disable() failed\n"); 355c517771aSPrabhakar Kushwaha 356c517771aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB 357c517771aSPrabhakar Kushwaha phy_shutdown(priv->phydev); 358c517771aSPrabhakar Kushwaha #endif 359c517771aSPrabhakar Kushwaha 360c517771aSPrabhakar Kushwaha ldpaa_dpbp_free(); 361*c919ab9eSPrabhakar Kushwaha dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 362*c919ab9eSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 363c517771aSPrabhakar Kushwaha } 364c517771aSPrabhakar Kushwaha 365c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain_cnt(int count) 366c517771aSPrabhakar Kushwaha { 367c517771aSPrabhakar Kushwaha uint64_t buf_array[7]; 368c517771aSPrabhakar Kushwaha void *addr; 369c517771aSPrabhakar Kushwaha int ret, i; 370c517771aSPrabhakar Kushwaha 371c517771aSPrabhakar Kushwaha BUG_ON(count > 7); 372c517771aSPrabhakar Kushwaha 373c517771aSPrabhakar Kushwaha do { 374c517771aSPrabhakar Kushwaha ret = qbman_swp_acquire(dflt_dpio->sw_portal, 375c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.bpid, 376c517771aSPrabhakar Kushwaha buf_array, count); 377c517771aSPrabhakar Kushwaha if (ret < 0) { 378c517771aSPrabhakar Kushwaha printf("qbman_swp_acquire() failed\n"); 379c517771aSPrabhakar Kushwaha return; 380c517771aSPrabhakar Kushwaha } 381c517771aSPrabhakar Kushwaha for (i = 0; i < ret; i++) { 382c517771aSPrabhakar Kushwaha addr = (void *)buf_array[i]; 383c517771aSPrabhakar Kushwaha debug("Free: buffer addr =0x%p\n", addr); 384c517771aSPrabhakar Kushwaha free(addr); 385c517771aSPrabhakar Kushwaha } 386c517771aSPrabhakar Kushwaha } while (ret); 387c517771aSPrabhakar Kushwaha } 388c517771aSPrabhakar Kushwaha 389c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain(void) 390c517771aSPrabhakar Kushwaha { 391c517771aSPrabhakar Kushwaha int i; 392c517771aSPrabhakar Kushwaha for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) 393c517771aSPrabhakar Kushwaha ldpaa_dpbp_drain_cnt(7); 394c517771aSPrabhakar Kushwaha } 395c517771aSPrabhakar Kushwaha 396c517771aSPrabhakar Kushwaha static int ldpaa_bp_add_7(uint16_t bpid) 397c517771aSPrabhakar Kushwaha { 398c517771aSPrabhakar Kushwaha uint64_t buf_array[7]; 399c517771aSPrabhakar Kushwaha u8 *addr; 400c517771aSPrabhakar Kushwaha int i; 401c517771aSPrabhakar Kushwaha struct qbman_release_desc rd; 402c517771aSPrabhakar Kushwaha 403c517771aSPrabhakar Kushwaha for (i = 0; i < 7; i++) { 404c517771aSPrabhakar Kushwaha addr = memalign(L1_CACHE_BYTES, LDPAA_ETH_RX_BUFFER_SIZE); 405c517771aSPrabhakar Kushwaha if (!addr) { 406c517771aSPrabhakar Kushwaha printf("addr allocation failed\n"); 407c517771aSPrabhakar Kushwaha goto err_alloc; 408c517771aSPrabhakar Kushwaha } 409c517771aSPrabhakar Kushwaha memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE); 4105753b0f1SPrabhakar Kushwaha flush_dcache_range((u64)addr, 4115753b0f1SPrabhakar Kushwaha (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE)); 412c517771aSPrabhakar Kushwaha 413c517771aSPrabhakar Kushwaha buf_array[i] = (uint64_t)addr; 414c517771aSPrabhakar Kushwaha debug("Release: buffer addr =0x%p\n", addr); 415c517771aSPrabhakar Kushwaha } 416c517771aSPrabhakar Kushwaha 417c517771aSPrabhakar Kushwaha release_bufs: 418c517771aSPrabhakar Kushwaha /* In case the portal is busy, retry until successful. 419c517771aSPrabhakar Kushwaha * This function is guaranteed to succeed in a reasonable amount 420c517771aSPrabhakar Kushwaha * of time. 421c517771aSPrabhakar Kushwaha */ 422c517771aSPrabhakar Kushwaha 423c517771aSPrabhakar Kushwaha do { 424c517771aSPrabhakar Kushwaha mdelay(1); 425c517771aSPrabhakar Kushwaha qbman_release_desc_clear(&rd); 426c517771aSPrabhakar Kushwaha qbman_release_desc_set_bpid(&rd, bpid); 427c517771aSPrabhakar Kushwaha } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i)); 428c517771aSPrabhakar Kushwaha 429c517771aSPrabhakar Kushwaha return i; 430c517771aSPrabhakar Kushwaha 431c517771aSPrabhakar Kushwaha err_alloc: 432c517771aSPrabhakar Kushwaha if (i) 433c517771aSPrabhakar Kushwaha goto release_bufs; 434c517771aSPrabhakar Kushwaha 435c517771aSPrabhakar Kushwaha return 0; 436c517771aSPrabhakar Kushwaha } 437c517771aSPrabhakar Kushwaha 438c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_seed(uint16_t bpid) 439c517771aSPrabhakar Kushwaha { 440c517771aSPrabhakar Kushwaha int i; 441c517771aSPrabhakar Kushwaha int count; 442c517771aSPrabhakar Kushwaha 443c517771aSPrabhakar Kushwaha for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) { 444c517771aSPrabhakar Kushwaha count = ldpaa_bp_add_7(bpid); 445c517771aSPrabhakar Kushwaha if (count < 7) 446c517771aSPrabhakar Kushwaha printf("Buffer Seed= %d\n", count); 447c517771aSPrabhakar Kushwaha } 448c517771aSPrabhakar Kushwaha 449c517771aSPrabhakar Kushwaha return 0; 450c517771aSPrabhakar Kushwaha } 451c517771aSPrabhakar Kushwaha 452c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_setup(void) 453c517771aSPrabhakar Kushwaha { 454c517771aSPrabhakar Kushwaha int err; 455c517771aSPrabhakar Kushwaha 45687457d11SPrabhakar Kushwaha err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, 457c517771aSPrabhakar Kushwaha &dflt_dpbp->dpbp_handle); 458c517771aSPrabhakar Kushwaha if (err) { 459c517771aSPrabhakar Kushwaha printf("dpbp_open() failed\n"); 460c517771aSPrabhakar Kushwaha goto err_open; 461c517771aSPrabhakar Kushwaha } 462c517771aSPrabhakar Kushwaha 46387457d11SPrabhakar Kushwaha err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 464c517771aSPrabhakar Kushwaha if (err) { 465c517771aSPrabhakar Kushwaha printf("dpbp_enable() failed\n"); 466c517771aSPrabhakar Kushwaha goto err_enable; 467c517771aSPrabhakar Kushwaha } 468c517771aSPrabhakar Kushwaha 46987457d11SPrabhakar Kushwaha err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 47087457d11SPrabhakar Kushwaha dflt_dpbp->dpbp_handle, 471c517771aSPrabhakar Kushwaha &dflt_dpbp->dpbp_attr); 472c517771aSPrabhakar Kushwaha if (err) { 473c517771aSPrabhakar Kushwaha printf("dpbp_get_attributes() failed\n"); 474c517771aSPrabhakar Kushwaha goto err_get_attr; 475c517771aSPrabhakar Kushwaha } 476c517771aSPrabhakar Kushwaha 477c517771aSPrabhakar Kushwaha err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid); 478c517771aSPrabhakar Kushwaha if (err) { 479c517771aSPrabhakar Kushwaha printf("Buffer seeding failed for DPBP %d (bpid=%d)\n", 480c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid); 481c517771aSPrabhakar Kushwaha goto err_seed; 482c517771aSPrabhakar Kushwaha } 483c517771aSPrabhakar Kushwaha 484c517771aSPrabhakar Kushwaha return 0; 485c517771aSPrabhakar Kushwaha 486c517771aSPrabhakar Kushwaha err_seed: 487c517771aSPrabhakar Kushwaha err_get_attr: 48887457d11SPrabhakar Kushwaha dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 489c517771aSPrabhakar Kushwaha err_enable: 49087457d11SPrabhakar Kushwaha dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 491c517771aSPrabhakar Kushwaha err_open: 492c517771aSPrabhakar Kushwaha return err; 493c517771aSPrabhakar Kushwaha } 494c517771aSPrabhakar Kushwaha 495c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_free(void) 496c517771aSPrabhakar Kushwaha { 497c517771aSPrabhakar Kushwaha ldpaa_dpbp_drain(); 49887457d11SPrabhakar Kushwaha dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 49987457d11SPrabhakar Kushwaha dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 50087457d11SPrabhakar Kushwaha dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 501c517771aSPrabhakar Kushwaha } 502c517771aSPrabhakar Kushwaha 503*c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv) 504*c919ab9eSPrabhakar Kushwaha { 505*c919ab9eSPrabhakar Kushwaha int err = 0; 506*c919ab9eSPrabhakar Kushwaha struct dpmac_cfg dpmac_cfg; 507*c919ab9eSPrabhakar Kushwaha 508*c919ab9eSPrabhakar Kushwaha dpmac_cfg.mac_id = priv->dpmac_id; 509*c919ab9eSPrabhakar Kushwaha err = dpmac_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpmac_cfg, 510*c919ab9eSPrabhakar Kushwaha &priv->dpmac_handle); 511*c919ab9eSPrabhakar Kushwaha if (err) 512*c919ab9eSPrabhakar Kushwaha printf("dpmac_create() failed\n"); 513*c919ab9eSPrabhakar Kushwaha return err; 514*c919ab9eSPrabhakar Kushwaha } 515*c919ab9eSPrabhakar Kushwaha 516*c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv) 517*c919ab9eSPrabhakar Kushwaha { 518*c919ab9eSPrabhakar Kushwaha int err = 0; 519*c919ab9eSPrabhakar Kushwaha struct dprc_connection_cfg dprc_connection_cfg = { 520*c919ab9eSPrabhakar Kushwaha /* If both rates are zero the connection */ 521*c919ab9eSPrabhakar Kushwaha /* will be configured in "best effort" mode. */ 522*c919ab9eSPrabhakar Kushwaha .committed_rate = 0, 523*c919ab9eSPrabhakar Kushwaha .max_rate = 0 524*c919ab9eSPrabhakar Kushwaha }; 525*c919ab9eSPrabhakar Kushwaha 526*c919ab9eSPrabhakar Kushwaha memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint)); 527*c919ab9eSPrabhakar Kushwaha sprintf(dpmac_endpoint.type, "dpmac"); 528*c919ab9eSPrabhakar Kushwaha dpmac_endpoint.id = priv->dpmac_id; 529*c919ab9eSPrabhakar Kushwaha 530*c919ab9eSPrabhakar Kushwaha memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint)); 531*c919ab9eSPrabhakar Kushwaha sprintf(dpni_endpoint.type, "dpni"); 532*c919ab9eSPrabhakar Kushwaha dpni_endpoint.id = dflt_dpni->dpni_id; 533*c919ab9eSPrabhakar Kushwaha 534*c919ab9eSPrabhakar Kushwaha err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS, 535*c919ab9eSPrabhakar Kushwaha dflt_dprc_handle, 536*c919ab9eSPrabhakar Kushwaha &dpmac_endpoint, 537*c919ab9eSPrabhakar Kushwaha &dpni_endpoint, 538*c919ab9eSPrabhakar Kushwaha &dprc_connection_cfg); 539*c919ab9eSPrabhakar Kushwaha return err; 540*c919ab9eSPrabhakar Kushwaha } 541*c919ab9eSPrabhakar Kushwaha 542c517771aSPrabhakar Kushwaha static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) 543c517771aSPrabhakar Kushwaha { 544c517771aSPrabhakar Kushwaha int err; 545c517771aSPrabhakar Kushwaha 546c517771aSPrabhakar Kushwaha /* and get a handle for the DPNI this interface is associate with */ 547*c919ab9eSPrabhakar Kushwaha err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, 548*c919ab9eSPrabhakar Kushwaha &dflt_dpni->dpni_handle); 549c517771aSPrabhakar Kushwaha if (err) { 550c517771aSPrabhakar Kushwaha printf("dpni_open() failed\n"); 551c517771aSPrabhakar Kushwaha goto err_open; 552c517771aSPrabhakar Kushwaha } 553c517771aSPrabhakar Kushwaha 55487457d11SPrabhakar Kushwaha err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 555*c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 556*c919ab9eSPrabhakar Kushwaha &dflt_dpni->dpni_attrs); 557c517771aSPrabhakar Kushwaha if (err) { 558c517771aSPrabhakar Kushwaha printf("dpni_get_attributes() failed (err=%d)\n", err); 559c517771aSPrabhakar Kushwaha goto err_get_attr; 560c517771aSPrabhakar Kushwaha } 561c517771aSPrabhakar Kushwaha 562c517771aSPrabhakar Kushwaha /* Configure our buffers' layout */ 563*c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | 564c517771aSPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | 565c517771aSPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; 566*c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.pass_parser_result = true; 567*c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.pass_frame_status = true; 568*c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE; 569c517771aSPrabhakar Kushwaha /* ...rx, ... */ 57087457d11SPrabhakar Kushwaha err = dpni_set_rx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 571*c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 572*c919ab9eSPrabhakar Kushwaha &dflt_dpni->buf_layout); 573c517771aSPrabhakar Kushwaha if (err) { 574c517771aSPrabhakar Kushwaha printf("dpni_set_rx_buffer_layout() failed"); 575c517771aSPrabhakar Kushwaha goto err_buf_layout; 576c517771aSPrabhakar Kushwaha } 577c517771aSPrabhakar Kushwaha 578c517771aSPrabhakar Kushwaha /* ... tx, ... */ 579*c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PARSER_RESULT; 58087457d11SPrabhakar Kushwaha err = dpni_set_tx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 581*c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 582*c919ab9eSPrabhakar Kushwaha &dflt_dpni->buf_layout); 583c517771aSPrabhakar Kushwaha if (err) { 584c517771aSPrabhakar Kushwaha printf("dpni_set_tx_buffer_layout() failed"); 585c517771aSPrabhakar Kushwaha goto err_buf_layout; 586c517771aSPrabhakar Kushwaha } 587c517771aSPrabhakar Kushwaha 588c517771aSPrabhakar Kushwaha /* ... tx-confirm. */ 589*c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; 59087457d11SPrabhakar Kushwaha err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 591*c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 592*c919ab9eSPrabhakar Kushwaha &dflt_dpni->buf_layout); 593c517771aSPrabhakar Kushwaha if (err) { 594c517771aSPrabhakar Kushwaha printf("dpni_set_tx_conf_buffer_layout() failed"); 595c517771aSPrabhakar Kushwaha goto err_buf_layout; 596c517771aSPrabhakar Kushwaha } 597c517771aSPrabhakar Kushwaha 598c517771aSPrabhakar Kushwaha /* Now that we've set our tx buffer layout, retrieve the minimum 599c517771aSPrabhakar Kushwaha * required tx data offset. 600c517771aSPrabhakar Kushwaha */ 60187457d11SPrabhakar Kushwaha err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS, 602*c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 603*c919ab9eSPrabhakar Kushwaha &priv->tx_data_offset); 604c517771aSPrabhakar Kushwaha if (err) { 605c517771aSPrabhakar Kushwaha printf("dpni_get_tx_data_offset() failed\n"); 606c517771aSPrabhakar Kushwaha goto err_data_offset; 607c517771aSPrabhakar Kushwaha } 608c517771aSPrabhakar Kushwaha 609c517771aSPrabhakar Kushwaha /* Warn in case TX data offset is not multiple of 64 bytes. */ 610c517771aSPrabhakar Kushwaha WARN_ON(priv->tx_data_offset % 64); 611c517771aSPrabhakar Kushwaha 612c517771aSPrabhakar Kushwaha /* Accomodate SWA space. */ 613c517771aSPrabhakar Kushwaha priv->tx_data_offset += LDPAA_ETH_SWA_SIZE; 614c517771aSPrabhakar Kushwaha debug("priv->tx_data_offset=%d\n", priv->tx_data_offset); 615c517771aSPrabhakar Kushwaha 616c517771aSPrabhakar Kushwaha return 0; 617c517771aSPrabhakar Kushwaha 618c517771aSPrabhakar Kushwaha err_data_offset: 619c517771aSPrabhakar Kushwaha err_buf_layout: 620c517771aSPrabhakar Kushwaha err_get_attr: 621*c919ab9eSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 622c517771aSPrabhakar Kushwaha err_open: 623c517771aSPrabhakar Kushwaha return err; 624c517771aSPrabhakar Kushwaha } 625c517771aSPrabhakar Kushwaha 626c517771aSPrabhakar Kushwaha static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) 627c517771aSPrabhakar Kushwaha { 628c517771aSPrabhakar Kushwaha struct dpni_pools_cfg pools_params; 629c517771aSPrabhakar Kushwaha struct dpni_tx_flow_cfg dflt_tx_flow; 630c517771aSPrabhakar Kushwaha int err = 0; 631c517771aSPrabhakar Kushwaha 632c517771aSPrabhakar Kushwaha pools_params.num_dpbp = 1; 633c517771aSPrabhakar Kushwaha pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id; 634c517771aSPrabhakar Kushwaha pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE; 635*c919ab9eSPrabhakar Kushwaha err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS, 636*c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, &pools_params); 637c517771aSPrabhakar Kushwaha if (err) { 638c517771aSPrabhakar Kushwaha printf("dpni_set_pools() failed\n"); 639c517771aSPrabhakar Kushwaha return err; 640c517771aSPrabhakar Kushwaha } 641c517771aSPrabhakar Kushwaha 642c517771aSPrabhakar Kushwaha priv->tx_flow_id = DPNI_NEW_FLOW_ID; 643c517771aSPrabhakar Kushwaha memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow)); 644c517771aSPrabhakar Kushwaha 6450c7c87a4SPrabhakar Kushwaha dflt_tx_flow.options = DPNI_TX_FLOW_OPT_ONLY_TX_ERROR; 6460c7c87a4SPrabhakar Kushwaha dflt_tx_flow.conf_err_cfg.use_default_queue = 0; 6470c7c87a4SPrabhakar Kushwaha dflt_tx_flow.conf_err_cfg.errors_only = 1; 648*c919ab9eSPrabhakar Kushwaha err = dpni_set_tx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, 649*c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, &priv->tx_flow_id, 650*c919ab9eSPrabhakar Kushwaha &dflt_tx_flow); 651c517771aSPrabhakar Kushwaha if (err) { 652c517771aSPrabhakar Kushwaha printf("dpni_set_tx_flow() failed\n"); 653c517771aSPrabhakar Kushwaha return err; 654c517771aSPrabhakar Kushwaha } 655c517771aSPrabhakar Kushwaha 656c517771aSPrabhakar Kushwaha return 0; 657c517771aSPrabhakar Kushwaha } 658c517771aSPrabhakar Kushwaha 659*c919ab9eSPrabhakar Kushwaha static int ldpaa_eth_netdev_init(struct eth_device *net_dev, 660*c919ab9eSPrabhakar Kushwaha phy_interface_t enet_if) 661c517771aSPrabhakar Kushwaha { 662c517771aSPrabhakar Kushwaha int err; 663c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 664c517771aSPrabhakar Kushwaha 665*c919ab9eSPrabhakar Kushwaha sprintf(net_dev->name, "DPMAC%d@%s", priv->dpmac_id, 666*c919ab9eSPrabhakar Kushwaha phy_interface_strings[enet_if]); 667c517771aSPrabhakar Kushwaha 668c517771aSPrabhakar Kushwaha net_dev->iobase = 0; 669c517771aSPrabhakar Kushwaha net_dev->init = ldpaa_eth_open; 670c517771aSPrabhakar Kushwaha net_dev->halt = ldpaa_eth_stop; 671c517771aSPrabhakar Kushwaha net_dev->send = ldpaa_eth_tx; 672c517771aSPrabhakar Kushwaha net_dev->recv = ldpaa_eth_pull_dequeue_rx; 673c517771aSPrabhakar Kushwaha /* 674c517771aSPrabhakar Kushwaha TODO: PHY MDIO information 675c517771aSPrabhakar Kushwaha priv->bus = info->bus; 676c517771aSPrabhakar Kushwaha priv->phyaddr = info->phy_addr; 677c517771aSPrabhakar Kushwaha priv->enet_if = info->enet_if; 678c517771aSPrabhakar Kushwaha */ 679c517771aSPrabhakar Kushwaha 680c517771aSPrabhakar Kushwaha if (init_phy(net_dev)) 681c517771aSPrabhakar Kushwaha return 0; 682c517771aSPrabhakar Kushwaha 683c517771aSPrabhakar Kushwaha err = eth_register(net_dev); 684c517771aSPrabhakar Kushwaha if (err < 0) { 685c517771aSPrabhakar Kushwaha printf("eth_register() = %d\n", err); 686c517771aSPrabhakar Kushwaha return err; 687c517771aSPrabhakar Kushwaha } 688c517771aSPrabhakar Kushwaha 689c517771aSPrabhakar Kushwaha return 0; 690c517771aSPrabhakar Kushwaha } 691c517771aSPrabhakar Kushwaha 692*c919ab9eSPrabhakar Kushwaha int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if) 693c517771aSPrabhakar Kushwaha { 694c517771aSPrabhakar Kushwaha struct eth_device *net_dev = NULL; 695c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = NULL; 696c517771aSPrabhakar Kushwaha int err = 0; 697c517771aSPrabhakar Kushwaha 698c517771aSPrabhakar Kushwaha 699c517771aSPrabhakar Kushwaha /* Net device */ 700c517771aSPrabhakar Kushwaha net_dev = (struct eth_device *)malloc(sizeof(struct eth_device)); 701c517771aSPrabhakar Kushwaha if (!net_dev) { 702c517771aSPrabhakar Kushwaha printf("eth_device malloc() failed\n"); 703c517771aSPrabhakar Kushwaha return -ENOMEM; 704c517771aSPrabhakar Kushwaha } 705c517771aSPrabhakar Kushwaha memset(net_dev, 0, sizeof(struct eth_device)); 706c517771aSPrabhakar Kushwaha 707c517771aSPrabhakar Kushwaha /* alloc the ldpaa ethernet private struct */ 708c517771aSPrabhakar Kushwaha priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv)); 709c517771aSPrabhakar Kushwaha if (!priv) { 710c517771aSPrabhakar Kushwaha printf("ldpaa_eth_priv malloc() failed\n"); 711c517771aSPrabhakar Kushwaha return -ENOMEM; 712c517771aSPrabhakar Kushwaha } 713c517771aSPrabhakar Kushwaha memset(priv, 0, sizeof(struct ldpaa_eth_priv)); 714c517771aSPrabhakar Kushwaha 715c517771aSPrabhakar Kushwaha net_dev->priv = (void *)priv; 716c517771aSPrabhakar Kushwaha priv->net_dev = (struct eth_device *)net_dev; 717*c919ab9eSPrabhakar Kushwaha priv->dpmac_id = dpmac_id; 718*c919ab9eSPrabhakar Kushwaha debug("%s dpmac_id=%d\n", __func__, dpmac_id); 719c517771aSPrabhakar Kushwaha 720*c919ab9eSPrabhakar Kushwaha err = ldpaa_eth_netdev_init(net_dev, enet_if); 721c517771aSPrabhakar Kushwaha if (err) 722c517771aSPrabhakar Kushwaha goto err_netdev_init; 723c517771aSPrabhakar Kushwaha 724c517771aSPrabhakar Kushwaha debug("ldpaa ethernet: Probed interface %s\n", net_dev->name); 725c517771aSPrabhakar Kushwaha return 0; 726c517771aSPrabhakar Kushwaha 727c517771aSPrabhakar Kushwaha err_netdev_init: 728c517771aSPrabhakar Kushwaha free(priv); 729c517771aSPrabhakar Kushwaha net_dev->priv = NULL; 730c517771aSPrabhakar Kushwaha free(net_dev); 731c517771aSPrabhakar Kushwaha 732c517771aSPrabhakar Kushwaha return err; 733c517771aSPrabhakar Kushwaha } 734