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