183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2c517771aSPrabhakar Kushwaha /* 3a6f2a6eaSYogesh Gaur * Copyright 2014-2016 Freescale Semiconductor, Inc. 42557c5a9SYogesh Gaur * Copyright 2017 NXP 5c517771aSPrabhakar Kushwaha */ 6c517771aSPrabhakar Kushwaha 7c517771aSPrabhakar Kushwaha #include <common.h> 8c517771aSPrabhakar Kushwaha #include <asm/io.h> 9c517771aSPrabhakar Kushwaha #include <asm/types.h> 10c517771aSPrabhakar Kushwaha #include <malloc.h> 11c517771aSPrabhakar Kushwaha #include <net.h> 12c517771aSPrabhakar Kushwaha #include <hwconfig.h> 13c517771aSPrabhakar Kushwaha #include <phy.h> 14c517771aSPrabhakar Kushwaha #include <linux/compat.h> 15c919ab9eSPrabhakar Kushwaha #include <fsl-mc/fsl_dpmac.h> 16c517771aSPrabhakar Kushwaha 176c2b520aSPrabhakar Kushwaha #include <fsl-mc/ldpaa_wriop.h> 18c517771aSPrabhakar Kushwaha #include "ldpaa_eth.h" 19c517771aSPrabhakar Kushwaha 206c2b520aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB 21c517771aSPrabhakar Kushwaha static int init_phy(struct eth_device *dev) 22c517771aSPrabhakar Kushwaha { 236c2b520aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; 246c2b520aSPrabhakar Kushwaha struct phy_device *phydev = NULL; 256c2b520aSPrabhakar Kushwaha struct mii_dev *bus; 26c517771aSPrabhakar Kushwaha 276c2b520aSPrabhakar Kushwaha bus = wriop_get_mdio(priv->dpmac_id); 286c2b520aSPrabhakar Kushwaha if (bus == NULL) 29c517771aSPrabhakar Kushwaha return 0; 306c2b520aSPrabhakar Kushwaha 316c2b520aSPrabhakar Kushwaha phydev = phy_connect(bus, wriop_get_phy_address(priv->dpmac_id), 326c2b520aSPrabhakar Kushwaha dev, wriop_get_enet_if(priv->dpmac_id)); 336c2b520aSPrabhakar Kushwaha if (!phydev) { 346c2b520aSPrabhakar Kushwaha printf("Failed to connect\n"); 356c2b520aSPrabhakar Kushwaha return -1; 36c517771aSPrabhakar Kushwaha } 37c517771aSPrabhakar Kushwaha 38*d75e81d9SPankaj Bansal wriop_set_phy_dev(priv->dpmac_id, phydev); 396c2b520aSPrabhakar Kushwaha 406c2b520aSPrabhakar Kushwaha return phy_config(phydev); 416c2b520aSPrabhakar Kushwaha } 426c2b520aSPrabhakar Kushwaha #endif 436c2b520aSPrabhakar Kushwaha 445038d3e5SPrabhakar Kushwaha #ifdef DEBUG 452557c5a9SYogesh Gaur 462557c5a9SYogesh Gaur #define DPNI_STATS_PER_PAGE 6 472557c5a9SYogesh Gaur 482557c5a9SYogesh Gaur static const char *dpni_statistics[][DPNI_STATS_PER_PAGE] = { 492557c5a9SYogesh Gaur { 502557c5a9SYogesh Gaur "DPNI_CNT_ING_ALL_FRAMES", 512557c5a9SYogesh Gaur "DPNI_CNT_ING_ALL_BYTES", 522557c5a9SYogesh Gaur "DPNI_CNT_ING_MCAST_FRAMES", 532557c5a9SYogesh Gaur "DPNI_CNT_ING_MCAST_BYTES", 542557c5a9SYogesh Gaur "DPNI_CNT_ING_BCAST_FRAMES", 552557c5a9SYogesh Gaur "DPNI_CNT_ING_BCAST_BYTES", 562557c5a9SYogesh Gaur }, { 572557c5a9SYogesh Gaur "DPNI_CNT_EGR_ALL_FRAMES", 582557c5a9SYogesh Gaur "DPNI_CNT_EGR_ALL_BYTES", 592557c5a9SYogesh Gaur "DPNI_CNT_EGR_MCAST_FRAMES", 602557c5a9SYogesh Gaur "DPNI_CNT_EGR_MCAST_BYTES", 612557c5a9SYogesh Gaur "DPNI_CNT_EGR_BCAST_FRAMES", 622557c5a9SYogesh Gaur "DPNI_CNT_EGR_BCAST_BYTES", 632557c5a9SYogesh Gaur }, { 642557c5a9SYogesh Gaur "DPNI_CNT_ING_FILTERED_FRAMES", 652557c5a9SYogesh Gaur "DPNI_CNT_ING_DISCARDED_FRAMES", 662557c5a9SYogesh Gaur "DPNI_CNT_ING_NOBUFFER_DISCARDS", 672557c5a9SYogesh Gaur "DPNI_CNT_EGR_DISCARDED_FRAMES", 682557c5a9SYogesh Gaur "DPNI_CNT_EGR_CNF_FRAMES", 692557c5a9SYogesh Gaur "" 702557c5a9SYogesh Gaur }, 712557c5a9SYogesh Gaur }; 722557c5a9SYogesh Gaur 732557c5a9SYogesh Gaur static void print_dpni_stats(const char *strings[], 742557c5a9SYogesh Gaur struct dpni_statistics dpni_stats) 752557c5a9SYogesh Gaur { 762557c5a9SYogesh Gaur uint64_t *stat; 772557c5a9SYogesh Gaur int i; 782557c5a9SYogesh Gaur 792557c5a9SYogesh Gaur stat = (uint64_t *)&dpni_stats; 802557c5a9SYogesh Gaur for (i = 0; i < DPNI_STATS_PER_PAGE; i++) { 812557c5a9SYogesh Gaur if (strcmp(strings[i], "\0") == 0) 822557c5a9SYogesh Gaur break; 832557c5a9SYogesh Gaur printf("%s= %llu\n", strings[i], *stat); 842557c5a9SYogesh Gaur stat++; 852557c5a9SYogesh Gaur } 862557c5a9SYogesh Gaur } 872557c5a9SYogesh Gaur 885038d3e5SPrabhakar Kushwaha static void ldpaa_eth_get_dpni_counter(void) 895038d3e5SPrabhakar Kushwaha { 905038d3e5SPrabhakar Kushwaha int err = 0; 912557c5a9SYogesh Gaur unsigned int page = 0; 922557c5a9SYogesh Gaur struct dpni_statistics dpni_stats; 935038d3e5SPrabhakar Kushwaha 942557c5a9SYogesh Gaur printf("DPNI counters ..\n"); 952557c5a9SYogesh Gaur for (page = 0; page < 3; page++) { 962557c5a9SYogesh Gaur err = dpni_get_statistics(dflt_mc_io, MC_CMD_NO_FLAGS, 972557c5a9SYogesh Gaur dflt_dpni->dpni_handle, page, 982557c5a9SYogesh Gaur &dpni_stats); 995038d3e5SPrabhakar Kushwaha if (err < 0) { 1002557c5a9SYogesh Gaur printf("dpni_get_statistics: failed:"); 1012557c5a9SYogesh Gaur printf("%d for page[%d]\n", err, page); 1025038d3e5SPrabhakar Kushwaha return; 1035038d3e5SPrabhakar Kushwaha } 1042557c5a9SYogesh Gaur print_dpni_stats(dpni_statistics[page], dpni_stats); 1055038d3e5SPrabhakar Kushwaha } 1065038d3e5SPrabhakar Kushwaha } 10744b2036eSPrabhakar Kushwaha 10844b2036eSPrabhakar Kushwaha static void ldpaa_eth_get_dpmac_counter(struct eth_device *net_dev) 10944b2036eSPrabhakar Kushwaha { 11044b2036eSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 11144b2036eSPrabhakar Kushwaha int err = 0; 11244b2036eSPrabhakar Kushwaha u64 value; 11344b2036eSPrabhakar Kushwaha 11444b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 11544b2036eSPrabhakar Kushwaha priv->dpmac_handle, 11644b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_BYTE, 11744b2036eSPrabhakar Kushwaha &value); 11844b2036eSPrabhakar Kushwaha if (err < 0) { 11944b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n"); 12044b2036eSPrabhakar Kushwaha return; 12144b2036eSPrabhakar Kushwaha } 1222557c5a9SYogesh Gaur printf("\nDPMAC counters ..\n"); 12344b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_BYTE=%lld\n", value); 12444b2036eSPrabhakar Kushwaha 12544b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 12644b2036eSPrabhakar Kushwaha priv->dpmac_handle, 12744b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_FRAME_DISCARD, 12844b2036eSPrabhakar Kushwaha &value); 12944b2036eSPrabhakar Kushwaha if (err < 0) { 13044b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n"); 13144b2036eSPrabhakar Kushwaha return; 13244b2036eSPrabhakar Kushwaha } 13344b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_FRAME_DISCARD=%lld\n", value); 13444b2036eSPrabhakar Kushwaha 13544b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 13644b2036eSPrabhakar Kushwaha priv->dpmac_handle, 13744b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_ALIGN_ERR, 13844b2036eSPrabhakar Kushwaha &value); 13944b2036eSPrabhakar Kushwaha if (err < 0) { 14044b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n"); 14144b2036eSPrabhakar Kushwaha return; 14244b2036eSPrabhakar Kushwaha } 14344b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_ALIGN_ERR =%lld\n", value); 14444b2036eSPrabhakar Kushwaha 14544b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 14644b2036eSPrabhakar Kushwaha priv->dpmac_handle, 14744b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_BYTE, 14844b2036eSPrabhakar Kushwaha &value); 14944b2036eSPrabhakar Kushwaha if (err < 0) { 15044b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n"); 15144b2036eSPrabhakar Kushwaha return; 15244b2036eSPrabhakar Kushwaha } 15344b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_BYTE=%lld\n", value); 15444b2036eSPrabhakar Kushwaha 15544b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 15644b2036eSPrabhakar Kushwaha priv->dpmac_handle, 15744b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_ERR_FRAME, 15844b2036eSPrabhakar Kushwaha &value); 15944b2036eSPrabhakar Kushwaha if (err < 0) { 16044b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n"); 16144b2036eSPrabhakar Kushwaha return; 16244b2036eSPrabhakar Kushwaha } 16344b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_ERR_FRAME=%lld\n", value); 16444b2036eSPrabhakar Kushwaha 16544b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 16644b2036eSPrabhakar Kushwaha priv->dpmac_handle, 16744b2036eSPrabhakar Kushwaha DPMAC_CNT_EGR_BYTE , 16844b2036eSPrabhakar Kushwaha &value); 16944b2036eSPrabhakar Kushwaha if (err < 0) { 17044b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n"); 17144b2036eSPrabhakar Kushwaha return; 17244b2036eSPrabhakar Kushwaha } 17344b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_EGR_BYTE =%lld\n", value); 17444b2036eSPrabhakar Kushwaha 17544b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 17644b2036eSPrabhakar Kushwaha priv->dpmac_handle, 17744b2036eSPrabhakar Kushwaha DPMAC_CNT_EGR_ERR_FRAME , 17844b2036eSPrabhakar Kushwaha &value); 17944b2036eSPrabhakar Kushwaha if (err < 0) { 18044b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n"); 18144b2036eSPrabhakar Kushwaha return; 18244b2036eSPrabhakar Kushwaha } 18344b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value); 18444b2036eSPrabhakar Kushwaha } 1855038d3e5SPrabhakar Kushwaha #endif 1865038d3e5SPrabhakar Kushwaha 187c517771aSPrabhakar Kushwaha static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv, 188c517771aSPrabhakar Kushwaha const struct dpaa_fd *fd) 189c517771aSPrabhakar Kushwaha { 190c517771aSPrabhakar Kushwaha u64 fd_addr; 191c517771aSPrabhakar Kushwaha uint16_t fd_offset; 192c517771aSPrabhakar Kushwaha uint32_t fd_length; 193c517771aSPrabhakar Kushwaha struct ldpaa_fas *fas; 194c517771aSPrabhakar Kushwaha uint32_t status, err; 19556c57cf7SPrabhakar Kushwaha u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; 19656c57cf7SPrabhakar Kushwaha u32 time_start; 197c517771aSPrabhakar Kushwaha struct qbman_release_desc releasedesc; 198c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 199c517771aSPrabhakar Kushwaha 200c517771aSPrabhakar Kushwaha fd_addr = ldpaa_fd_get_addr(fd); 201c517771aSPrabhakar Kushwaha fd_offset = ldpaa_fd_get_offset(fd); 202c517771aSPrabhakar Kushwaha fd_length = ldpaa_fd_get_len(fd); 203c517771aSPrabhakar Kushwaha 204c517771aSPrabhakar Kushwaha debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length); 205c517771aSPrabhakar Kushwaha 206c517771aSPrabhakar Kushwaha if (fd->simple.frc & LDPAA_FD_FRC_FASV) { 207c517771aSPrabhakar Kushwaha /* Read the frame annotation status word and check for errors */ 208c517771aSPrabhakar Kushwaha fas = (struct ldpaa_fas *) 209c517771aSPrabhakar Kushwaha ((uint8_t *)(fd_addr) + 210c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.private_data_size); 211c517771aSPrabhakar Kushwaha status = le32_to_cpu(fas->status); 212c517771aSPrabhakar Kushwaha if (status & LDPAA_ETH_RX_ERR_MASK) { 213c517771aSPrabhakar Kushwaha printf("Rx frame error(s): 0x%08x\n", 214c517771aSPrabhakar Kushwaha status & LDPAA_ETH_RX_ERR_MASK); 215c517771aSPrabhakar Kushwaha goto error; 216c517771aSPrabhakar Kushwaha } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) { 217c517771aSPrabhakar Kushwaha printf("Unsupported feature in bitmask: 0x%08x\n", 218c517771aSPrabhakar Kushwaha status & LDPAA_ETH_RX_UNSUPP_MASK); 219c517771aSPrabhakar Kushwaha goto error; 220c517771aSPrabhakar Kushwaha } 221c517771aSPrabhakar Kushwaha } 222c517771aSPrabhakar Kushwaha 223c517771aSPrabhakar Kushwaha debug("Rx frame: To Upper layer\n"); 224c517771aSPrabhakar Kushwaha net_process_received_packet((uint8_t *)(fd_addr) + fd_offset, 225c517771aSPrabhakar Kushwaha fd_length); 226c517771aSPrabhakar Kushwaha 227c517771aSPrabhakar Kushwaha error: 2285753b0f1SPrabhakar Kushwaha flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE); 229c517771aSPrabhakar Kushwaha qbman_release_desc_clear(&releasedesc); 230c517771aSPrabhakar Kushwaha qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 23156c57cf7SPrabhakar Kushwaha time_start = get_timer(0); 232c517771aSPrabhakar Kushwaha do { 233c517771aSPrabhakar Kushwaha /* Release buffer into the QBMAN */ 234c517771aSPrabhakar Kushwaha err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); 23556c57cf7SPrabhakar Kushwaha } while (get_timer(time_start) < timeo && err == -EBUSY); 23656c57cf7SPrabhakar Kushwaha 23756c57cf7SPrabhakar Kushwaha if (err == -EBUSY) 23856c57cf7SPrabhakar Kushwaha printf("Rx frame: QBMAN buffer release fails\n"); 23956c57cf7SPrabhakar Kushwaha 240c517771aSPrabhakar Kushwaha return; 241c517771aSPrabhakar Kushwaha } 242c517771aSPrabhakar Kushwaha 243c517771aSPrabhakar Kushwaha static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) 244c517771aSPrabhakar Kushwaha { 245c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; 246c517771aSPrabhakar Kushwaha const struct ldpaa_dq *dq; 247c517771aSPrabhakar Kushwaha const struct dpaa_fd *fd; 248b4c3a35dSPrabhakar Kushwaha int i = 5, err = 0, status; 249b4c3a35dSPrabhakar Kushwaha u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; 250b4c3a35dSPrabhakar Kushwaha u32 time_start; 251c517771aSPrabhakar Kushwaha static struct qbman_pull_desc pulldesc; 252c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 253c517771aSPrabhakar Kushwaha 2545753b0f1SPrabhakar Kushwaha while (--i) { 255c517771aSPrabhakar Kushwaha qbman_pull_desc_clear(&pulldesc); 256c517771aSPrabhakar Kushwaha qbman_pull_desc_set_numframes(&pulldesc, 1); 257c517771aSPrabhakar Kushwaha qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid); 258c517771aSPrabhakar Kushwaha 259c517771aSPrabhakar Kushwaha err = qbman_swp_pull(swp, &pulldesc); 260c517771aSPrabhakar Kushwaha if (err < 0) { 261c517771aSPrabhakar Kushwaha printf("Dequeue frames error:0x%08x\n", err); 262c517771aSPrabhakar Kushwaha continue; 263c517771aSPrabhakar Kushwaha } 264c517771aSPrabhakar Kushwaha 265b4c3a35dSPrabhakar Kushwaha time_start = get_timer(0); 2665753b0f1SPrabhakar Kushwaha 267b4c3a35dSPrabhakar Kushwaha do { 268b4c3a35dSPrabhakar Kushwaha dq = qbman_swp_dqrr_next(swp); 269b4c3a35dSPrabhakar Kushwaha } while (get_timer(time_start) < timeo && !dq); 2705753b0f1SPrabhakar Kushwaha 271c517771aSPrabhakar Kushwaha if (dq) { 272c517771aSPrabhakar Kushwaha /* Check for valid frame. If not sent a consume 273c517771aSPrabhakar Kushwaha * confirmation to QBMAN otherwise give it to NADK 274c517771aSPrabhakar Kushwaha * application and then send consume confirmation to 275c517771aSPrabhakar Kushwaha * QBMAN. 276c517771aSPrabhakar Kushwaha */ 277c517771aSPrabhakar Kushwaha status = (uint8_t)ldpaa_dq_flags(dq); 278c517771aSPrabhakar Kushwaha if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) { 279c517771aSPrabhakar Kushwaha debug("Dequeue RX frames:"); 280c517771aSPrabhakar Kushwaha debug("No frame delivered\n"); 281c517771aSPrabhakar Kushwaha 282c517771aSPrabhakar Kushwaha qbman_swp_dqrr_consume(swp, dq); 2830c7c87a4SPrabhakar Kushwaha continue; 284c517771aSPrabhakar Kushwaha } 285c517771aSPrabhakar Kushwaha 286c517771aSPrabhakar Kushwaha fd = ldpaa_dq_fd(dq); 287c517771aSPrabhakar Kushwaha 288c517771aSPrabhakar Kushwaha /* Obtain FD and process it */ 289c517771aSPrabhakar Kushwaha ldpaa_eth_rx(priv, fd); 290c517771aSPrabhakar Kushwaha qbman_swp_dqrr_consume(swp, dq); 291c517771aSPrabhakar Kushwaha break; 292b4c3a35dSPrabhakar Kushwaha } else { 293b4c3a35dSPrabhakar Kushwaha err = -ENODATA; 294b4c3a35dSPrabhakar Kushwaha debug("No DQRR entries\n"); 295b4c3a35dSPrabhakar Kushwaha break; 296c517771aSPrabhakar Kushwaha } 297c517771aSPrabhakar Kushwaha } 298c517771aSPrabhakar Kushwaha 299c517771aSPrabhakar Kushwaha return err; 300c517771aSPrabhakar Kushwaha } 301c517771aSPrabhakar Kushwaha 302c517771aSPrabhakar Kushwaha static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) 303c517771aSPrabhakar Kushwaha { 304c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 305c517771aSPrabhakar Kushwaha struct dpaa_fd fd; 306c517771aSPrabhakar Kushwaha u64 buffer_start; 307c517771aSPrabhakar Kushwaha int data_offset, err; 308e48df52bSPrabhakar Kushwaha u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; 309e48df52bSPrabhakar Kushwaha u32 time_start; 310c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 311c517771aSPrabhakar Kushwaha struct qbman_eq_desc ed; 312e48df52bSPrabhakar Kushwaha struct qbman_release_desc releasedesc; 313c517771aSPrabhakar Kushwaha 314c517771aSPrabhakar Kushwaha /* Setup the FD fields */ 315c517771aSPrabhakar Kushwaha memset(&fd, 0, sizeof(fd)); 316c517771aSPrabhakar Kushwaha 317c517771aSPrabhakar Kushwaha data_offset = priv->tx_data_offset; 318c517771aSPrabhakar Kushwaha 319c517771aSPrabhakar Kushwaha do { 320c517771aSPrabhakar Kushwaha err = qbman_swp_acquire(dflt_dpio->sw_portal, 321c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.bpid, 322c517771aSPrabhakar Kushwaha &buffer_start, 1); 323c517771aSPrabhakar Kushwaha } while (err == -EBUSY); 324c517771aSPrabhakar Kushwaha 3255e9445daSAshish Kumar if (err <= 0) { 326c517771aSPrabhakar Kushwaha printf("qbman_swp_acquire() failed\n"); 327c517771aSPrabhakar Kushwaha return -ENOMEM; 328c517771aSPrabhakar Kushwaha } 329c517771aSPrabhakar Kushwaha 330c517771aSPrabhakar Kushwaha debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start); 331c517771aSPrabhakar Kushwaha 332c517771aSPrabhakar Kushwaha memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len); 333c517771aSPrabhakar Kushwaha 3345753b0f1SPrabhakar Kushwaha flush_dcache_range(buffer_start, buffer_start + 3355753b0f1SPrabhakar Kushwaha LDPAA_ETH_RX_BUFFER_SIZE); 336c517771aSPrabhakar Kushwaha 337c517771aSPrabhakar Kushwaha ldpaa_fd_set_addr(&fd, (u64)buffer_start); 338c517771aSPrabhakar Kushwaha ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset)); 339c517771aSPrabhakar Kushwaha ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid); 340c517771aSPrabhakar Kushwaha ldpaa_fd_set_len(&fd, len); 341c517771aSPrabhakar Kushwaha 342c517771aSPrabhakar Kushwaha fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA | 343c517771aSPrabhakar Kushwaha LDPAA_FD_CTRL_PTV1; 344c517771aSPrabhakar Kushwaha 345c517771aSPrabhakar Kushwaha qbman_eq_desc_clear(&ed); 346c517771aSPrabhakar Kushwaha qbman_eq_desc_set_no_orp(&ed, 0); 347c517771aSPrabhakar Kushwaha qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0); 348e48df52bSPrabhakar Kushwaha 349e48df52bSPrabhakar Kushwaha time_start = get_timer(0); 350e48df52bSPrabhakar Kushwaha 351e48df52bSPrabhakar Kushwaha while (get_timer(time_start) < timeo) { 352e48df52bSPrabhakar Kushwaha err = qbman_swp_enqueue(swp, &ed, 353e48df52bSPrabhakar Kushwaha (const struct qbman_fd *)(&fd)); 354e48df52bSPrabhakar Kushwaha if (err != -EBUSY) 355e48df52bSPrabhakar Kushwaha break; 356e48df52bSPrabhakar Kushwaha } 357e48df52bSPrabhakar Kushwaha 358e48df52bSPrabhakar Kushwaha if (err < 0) { 359c517771aSPrabhakar Kushwaha printf("error enqueueing Tx frame\n"); 360e48df52bSPrabhakar Kushwaha goto error; 361e48df52bSPrabhakar Kushwaha } 362c517771aSPrabhakar Kushwaha 363c517771aSPrabhakar Kushwaha return err; 364e48df52bSPrabhakar Kushwaha 365e48df52bSPrabhakar Kushwaha error: 366e48df52bSPrabhakar Kushwaha qbman_release_desc_clear(&releasedesc); 367e48df52bSPrabhakar Kushwaha qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 368e48df52bSPrabhakar Kushwaha time_start = get_timer(0); 369e48df52bSPrabhakar Kushwaha do { 370e48df52bSPrabhakar Kushwaha /* Release buffer into the QBMAN */ 371e48df52bSPrabhakar Kushwaha err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1); 372e48df52bSPrabhakar Kushwaha } while (get_timer(time_start) < timeo && err == -EBUSY); 373e48df52bSPrabhakar Kushwaha 374e48df52bSPrabhakar Kushwaha if (err == -EBUSY) 375e48df52bSPrabhakar Kushwaha printf("TX data: QBMAN buffer release fails\n"); 376e48df52bSPrabhakar Kushwaha 377e48df52bSPrabhakar Kushwaha return err; 378c517771aSPrabhakar Kushwaha } 379c517771aSPrabhakar Kushwaha 380c517771aSPrabhakar Kushwaha static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) 381c517771aSPrabhakar Kushwaha { 382c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 383c919ab9eSPrabhakar Kushwaha struct dpmac_link_state dpmac_link_state = { 0 }; 3845038d3e5SPrabhakar Kushwaha #ifdef DEBUG 3855038d3e5SPrabhakar Kushwaha struct dpni_link_state link_state; 3865038d3e5SPrabhakar Kushwaha #endif 3876c2b520aSPrabhakar Kushwaha int err = 0; 3886c2b520aSPrabhakar Kushwaha struct mii_dev *bus; 3896c2b520aSPrabhakar Kushwaha phy_interface_t enet_if; 3902557c5a9SYogesh Gaur struct dpni_queue d_queue; 391*d75e81d9SPankaj Bansal struct phy_device *phydev = NULL; 392c517771aSPrabhakar Kushwaha 393c517771aSPrabhakar Kushwaha if (net_dev->state == ETH_STATE_ACTIVE) 394c517771aSPrabhakar Kushwaha return 0; 395c517771aSPrabhakar Kushwaha 396c919ab9eSPrabhakar Kushwaha if (get_mc_boot_status() != 0) { 397c919ab9eSPrabhakar Kushwaha printf("ERROR (MC is not booted)\n"); 398c919ab9eSPrabhakar Kushwaha return -ENODEV; 399c919ab9eSPrabhakar Kushwaha } 400c919ab9eSPrabhakar Kushwaha 401c919ab9eSPrabhakar Kushwaha if (get_dpl_apply_status() == 0) { 402c919ab9eSPrabhakar Kushwaha printf("ERROR (DPL is deployed. No device available)\n"); 403c919ab9eSPrabhakar Kushwaha return -ENODEV; 404c919ab9eSPrabhakar Kushwaha } 4056c2b520aSPrabhakar Kushwaha 406c919ab9eSPrabhakar Kushwaha /* DPMAC initialization */ 407c919ab9eSPrabhakar Kushwaha err = ldpaa_dpmac_setup(priv); 408c919ab9eSPrabhakar Kushwaha if (err < 0) 409c919ab9eSPrabhakar Kushwaha goto err_dpmac_setup; 410c919ab9eSPrabhakar Kushwaha 4116c2b520aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB 412*d75e81d9SPankaj Bansal phydev = wriop_get_phy_dev(priv->dpmac_id); 413*d75e81d9SPankaj Bansal if (phydev) { 414*d75e81d9SPankaj Bansal err = phy_startup(phydev); 4156c2b520aSPrabhakar Kushwaha if (err) { 4166c2b520aSPrabhakar Kushwaha printf("%s: Could not initialize\n", 417*d75e81d9SPankaj Bansal phydev->dev->name); 418afd6c6b4SPankaj Bansal goto err_dpmac_bind; 4196c2b520aSPrabhakar Kushwaha } 420b7401d09SPriyanka Jain } 4216c2b520aSPrabhakar Kushwaha #else 422*d75e81d9SPankaj Bansal phydev = (struct phy_device *)malloc(sizeof(struct phy_device)); 423*d75e81d9SPankaj Bansal memset(phydev, 0, sizeof(struct phy_device)); 424*d75e81d9SPankaj Bansal wriop_set_phy_dev(priv->dpmac_id, phydev); 4256c2b520aSPrabhakar Kushwaha 426*d75e81d9SPankaj Bansal phydev->speed = SPEED_1000; 427*d75e81d9SPankaj Bansal phydev->link = 1; 428*d75e81d9SPankaj Bansal phydev->duplex = DUPLEX_FULL; 4296c2b520aSPrabhakar Kushwaha #endif 4306c2b520aSPrabhakar Kushwaha 4316c2b520aSPrabhakar Kushwaha bus = wriop_get_mdio(priv->dpmac_id); 4326c2b520aSPrabhakar Kushwaha enet_if = wriop_get_enet_if(priv->dpmac_id); 4336c2b520aSPrabhakar Kushwaha if ((bus == NULL) && 4346c2b520aSPrabhakar Kushwaha (enet_if == PHY_INTERFACE_MODE_XGMII)) { 435*d75e81d9SPankaj Bansal phydev = (struct phy_device *) 4366c2b520aSPrabhakar Kushwaha malloc(sizeof(struct phy_device)); 437*d75e81d9SPankaj Bansal memset(phydev, 0, sizeof(struct phy_device)); 438*d75e81d9SPankaj Bansal wriop_set_phy_dev(priv->dpmac_id, phydev); 4396c2b520aSPrabhakar Kushwaha 440*d75e81d9SPankaj Bansal phydev->speed = SPEED_10000; 441*d75e81d9SPankaj Bansal phydev->link = 1; 442*d75e81d9SPankaj Bansal phydev->duplex = DUPLEX_FULL; 4436c2b520aSPrabhakar Kushwaha } 4446c2b520aSPrabhakar Kushwaha 445*d75e81d9SPankaj Bansal if (!phydev->link) { 446*d75e81d9SPankaj Bansal printf("%s: No link.\n", phydev->dev->name); 4476c2b520aSPrabhakar Kushwaha err = -1; 448afd6c6b4SPankaj Bansal goto err_dpmac_bind; 4496c2b520aSPrabhakar Kushwaha } 4506c2b520aSPrabhakar Kushwaha 451c919ab9eSPrabhakar Kushwaha /* DPMAC binding DPNI */ 452c919ab9eSPrabhakar Kushwaha err = ldpaa_dpmac_bind(priv); 453c919ab9eSPrabhakar Kushwaha if (err) 454afd6c6b4SPankaj Bansal goto err_dpmac_bind; 455c919ab9eSPrabhakar Kushwaha 456c517771aSPrabhakar Kushwaha /* DPNI initialization */ 457c517771aSPrabhakar Kushwaha err = ldpaa_dpni_setup(priv); 458c517771aSPrabhakar Kushwaha if (err < 0) 459c517771aSPrabhakar Kushwaha goto err_dpni_setup; 460c517771aSPrabhakar Kushwaha 461c517771aSPrabhakar Kushwaha err = ldpaa_dpbp_setup(); 462c517771aSPrabhakar Kushwaha if (err < 0) 463c517771aSPrabhakar Kushwaha goto err_dpbp_setup; 464c517771aSPrabhakar Kushwaha 465c517771aSPrabhakar Kushwaha /* DPNI binding DPBP */ 466c517771aSPrabhakar Kushwaha err = ldpaa_dpni_bind(priv); 467c517771aSPrabhakar Kushwaha if (err) 468c919ab9eSPrabhakar Kushwaha goto err_dpni_bind; 469c517771aSPrabhakar Kushwaha 4707b2edb8bSPrabhakar Kushwaha err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, 471c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, net_dev->enetaddr); 472c517771aSPrabhakar Kushwaha if (err) { 4737b2edb8bSPrabhakar Kushwaha printf("dpni_add_mac_addr() failed\n"); 474c517771aSPrabhakar Kushwaha return err; 475c517771aSPrabhakar Kushwaha } 476c517771aSPrabhakar Kushwaha 477c919ab9eSPrabhakar Kushwaha err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 478c517771aSPrabhakar Kushwaha if (err < 0) { 479c517771aSPrabhakar Kushwaha printf("dpni_enable() failed\n"); 480c517771aSPrabhakar Kushwaha return err; 481c517771aSPrabhakar Kushwaha } 482c517771aSPrabhakar Kushwaha 483*d75e81d9SPankaj Bansal dpmac_link_state.rate = phydev->speed; 4846c2b520aSPrabhakar Kushwaha 485*d75e81d9SPankaj Bansal if (phydev->autoneg == AUTONEG_DISABLE) 4866c2b520aSPrabhakar Kushwaha dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG; 4876c2b520aSPrabhakar Kushwaha else 4886c2b520aSPrabhakar Kushwaha dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG; 4896c2b520aSPrabhakar Kushwaha 490*d75e81d9SPankaj Bansal if (phydev->duplex == DUPLEX_HALF) 4916c2b520aSPrabhakar Kushwaha dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX; 4926c2b520aSPrabhakar Kushwaha 493*d75e81d9SPankaj Bansal dpmac_link_state.up = phydev->link; 4946c2b520aSPrabhakar Kushwaha 495c919ab9eSPrabhakar Kushwaha err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, 496c919ab9eSPrabhakar Kushwaha priv->dpmac_handle, &dpmac_link_state); 497c919ab9eSPrabhakar Kushwaha if (err < 0) { 498c919ab9eSPrabhakar Kushwaha printf("dpmac_set_link_state() failed\n"); 499c919ab9eSPrabhakar Kushwaha return err; 500c919ab9eSPrabhakar Kushwaha } 5015038d3e5SPrabhakar Kushwaha 5025038d3e5SPrabhakar Kushwaha #ifdef DEBUG 5032557c5a9SYogesh Gaur printf("DPMAC link status: %d - ", dpmac_link_state.up); 5042557c5a9SYogesh Gaur dpmac_link_state.up == 0 ? printf("down\n") : 5052557c5a9SYogesh Gaur dpmac_link_state.up == 1 ? printf("up\n") : printf("error state\n"); 5062557c5a9SYogesh Gaur 5075038d3e5SPrabhakar Kushwaha err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, 5085038d3e5SPrabhakar Kushwaha dflt_dpni->dpni_handle, &link_state); 5095038d3e5SPrabhakar Kushwaha if (err < 0) { 5105038d3e5SPrabhakar Kushwaha printf("dpni_get_link_state() failed\n"); 5115038d3e5SPrabhakar Kushwaha return err; 5125038d3e5SPrabhakar Kushwaha } 5135038d3e5SPrabhakar Kushwaha 5142557c5a9SYogesh Gaur printf("DPNI link status: %d - ", link_state.up); 5155038d3e5SPrabhakar Kushwaha link_state.up == 0 ? printf("down\n") : 5165038d3e5SPrabhakar Kushwaha link_state.up == 1 ? printf("up\n") : printf("error state\n"); 5175038d3e5SPrabhakar Kushwaha #endif 5185038d3e5SPrabhakar Kushwaha 5192557c5a9SYogesh Gaur memset(&d_queue, 0, sizeof(struct dpni_queue)); 5202557c5a9SYogesh Gaur err = dpni_get_queue(dflt_mc_io, MC_CMD_NO_FLAGS, 5212557c5a9SYogesh Gaur dflt_dpni->dpni_handle, DPNI_QUEUE_RX, 5222557c5a9SYogesh Gaur 0, 0, &d_queue); 523c517771aSPrabhakar Kushwaha if (err) { 5242557c5a9SYogesh Gaur printf("dpni_get_queue failed\n"); 5252557c5a9SYogesh Gaur goto err_get_queue; 526c517771aSPrabhakar Kushwaha } 527c517771aSPrabhakar Kushwaha 5282557c5a9SYogesh Gaur priv->rx_dflt_fqid = d_queue.fqid; 529c517771aSPrabhakar Kushwaha 530c919ab9eSPrabhakar Kushwaha err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, 53187457d11SPrabhakar Kushwaha &priv->tx_qdid); 532c517771aSPrabhakar Kushwaha if (err) { 533c517771aSPrabhakar Kushwaha printf("dpni_get_qdid() failed\n"); 534c517771aSPrabhakar Kushwaha goto err_qdid; 535c517771aSPrabhakar Kushwaha } 536c517771aSPrabhakar Kushwaha 537*d75e81d9SPankaj Bansal return phydev->link; 538c517771aSPrabhakar Kushwaha 539c517771aSPrabhakar Kushwaha err_qdid: 5402557c5a9SYogesh Gaur err_get_queue: 541c919ab9eSPrabhakar Kushwaha dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 542c919ab9eSPrabhakar Kushwaha err_dpni_bind: 543c517771aSPrabhakar Kushwaha ldpaa_dpbp_free(); 544c517771aSPrabhakar Kushwaha err_dpbp_setup: 545c919ab9eSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 546c517771aSPrabhakar Kushwaha err_dpni_setup: 547afd6c6b4SPankaj Bansal err_dpmac_bind: 5482557c5a9SYogesh Gaur dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); 5492557c5a9SYogesh Gaur dpmac_destroy(dflt_mc_io, 5502557c5a9SYogesh Gaur dflt_dprc_handle, 5512557c5a9SYogesh Gaur MC_CMD_NO_FLAGS, priv->dpmac_id); 552c919ab9eSPrabhakar Kushwaha err_dpmac_setup: 553c517771aSPrabhakar Kushwaha return err; 554c517771aSPrabhakar Kushwaha } 555c517771aSPrabhakar Kushwaha 556c517771aSPrabhakar Kushwaha static void ldpaa_eth_stop(struct eth_device *net_dev) 557c517771aSPrabhakar Kushwaha { 558c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 559c517771aSPrabhakar Kushwaha int err = 0; 5606c2b520aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB 5616c2b520aSPrabhakar Kushwaha struct mii_dev *bus = wriop_get_mdio(priv->dpmac_id); 5626c2b520aSPrabhakar Kushwaha #endif 563*d75e81d9SPankaj Bansal struct phy_device *phydev = NULL; 564c517771aSPrabhakar Kushwaha 5655753b0f1SPrabhakar Kushwaha if ((net_dev->state == ETH_STATE_PASSIVE) || 5665753b0f1SPrabhakar Kushwaha (net_dev->state == ETH_STATE_INIT)) 567c517771aSPrabhakar Kushwaha return; 568c919ab9eSPrabhakar Kushwaha 5695038d3e5SPrabhakar Kushwaha #ifdef DEBUG 5705038d3e5SPrabhakar Kushwaha ldpaa_eth_get_dpni_counter(); 57144b2036eSPrabhakar Kushwaha ldpaa_eth_get_dpmac_counter(net_dev); 5725038d3e5SPrabhakar Kushwaha #endif 5735038d3e5SPrabhakar Kushwaha 574c919ab9eSPrabhakar Kushwaha err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS, 575c919ab9eSPrabhakar Kushwaha dflt_dprc_handle, &dpmac_endpoint); 576c919ab9eSPrabhakar Kushwaha if (err < 0) 577c919ab9eSPrabhakar Kushwaha printf("dprc_disconnect() failed dpmac_endpoint\n"); 578c919ab9eSPrabhakar Kushwaha 5792557c5a9SYogesh Gaur err = dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); 5802557c5a9SYogesh Gaur if (err < 0) 5812557c5a9SYogesh Gaur printf("dpmac_close() failed\n"); 5822557c5a9SYogesh Gaur 5832557c5a9SYogesh Gaur err = dpmac_destroy(dflt_mc_io, 5842557c5a9SYogesh Gaur dflt_dprc_handle, 5852557c5a9SYogesh Gaur MC_CMD_NO_FLAGS, 5862557c5a9SYogesh Gaur priv->dpmac_id); 587c919ab9eSPrabhakar Kushwaha if (err < 0) 588c919ab9eSPrabhakar Kushwaha printf("dpmac_destroy() failed\n"); 589c919ab9eSPrabhakar Kushwaha 590c517771aSPrabhakar Kushwaha /* Stop Tx and Rx traffic */ 591c919ab9eSPrabhakar Kushwaha err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 592c517771aSPrabhakar Kushwaha if (err < 0) 593c517771aSPrabhakar Kushwaha printf("dpni_disable() failed\n"); 594c517771aSPrabhakar Kushwaha 595c517771aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB 596*d75e81d9SPankaj Bansal phydev = wriop_get_phy_dev(priv->dpmac_id); 597*d75e81d9SPankaj Bansal if (phydev && bus) { 598*d75e81d9SPankaj Bansal phy_shutdown(phydev); 599*d75e81d9SPankaj Bansal } else { 600*d75e81d9SPankaj Bansal free(phydev); 601*d75e81d9SPankaj Bansal wriop_set_phy_dev(priv->dpmac_id, NULL); 602a5fe87e8SPrabhakar Kushwaha } 603c517771aSPrabhakar Kushwaha #endif 604c517771aSPrabhakar Kushwaha 6052557c5a9SYogesh Gaur /* Free DPBP handle and reset. */ 606c517771aSPrabhakar Kushwaha ldpaa_dpbp_free(); 6072557c5a9SYogesh Gaur 608c919ab9eSPrabhakar Kushwaha dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 6092557c5a9SYogesh Gaur if (err < 0) 6102557c5a9SYogesh Gaur printf("dpni_reset() failed\n"); 6112557c5a9SYogesh Gaur 612c919ab9eSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 6132557c5a9SYogesh Gaur if (err < 0) 6142557c5a9SYogesh Gaur printf("dpni_close() failed\n"); 615c517771aSPrabhakar Kushwaha } 616c517771aSPrabhakar Kushwaha 617c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain_cnt(int count) 618c517771aSPrabhakar Kushwaha { 619c517771aSPrabhakar Kushwaha uint64_t buf_array[7]; 620c517771aSPrabhakar Kushwaha void *addr; 621c517771aSPrabhakar Kushwaha int ret, i; 622c517771aSPrabhakar Kushwaha 623c517771aSPrabhakar Kushwaha BUG_ON(count > 7); 624c517771aSPrabhakar Kushwaha 625c517771aSPrabhakar Kushwaha do { 626c517771aSPrabhakar Kushwaha ret = qbman_swp_acquire(dflt_dpio->sw_portal, 627c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.bpid, 628c517771aSPrabhakar Kushwaha buf_array, count); 629c517771aSPrabhakar Kushwaha if (ret < 0) { 630c517771aSPrabhakar Kushwaha printf("qbman_swp_acquire() failed\n"); 631c517771aSPrabhakar Kushwaha return; 632c517771aSPrabhakar Kushwaha } 633c517771aSPrabhakar Kushwaha for (i = 0; i < ret; i++) { 634c517771aSPrabhakar Kushwaha addr = (void *)buf_array[i]; 635c517771aSPrabhakar Kushwaha debug("Free: buffer addr =0x%p\n", addr); 636c517771aSPrabhakar Kushwaha free(addr); 637c517771aSPrabhakar Kushwaha } 638c517771aSPrabhakar Kushwaha } while (ret); 639c517771aSPrabhakar Kushwaha } 640c517771aSPrabhakar Kushwaha 641c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain(void) 642c517771aSPrabhakar Kushwaha { 643c517771aSPrabhakar Kushwaha int i; 644c517771aSPrabhakar Kushwaha for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) 645c517771aSPrabhakar Kushwaha ldpaa_dpbp_drain_cnt(7); 646c517771aSPrabhakar Kushwaha } 647c517771aSPrabhakar Kushwaha 648c517771aSPrabhakar Kushwaha static int ldpaa_bp_add_7(uint16_t bpid) 649c517771aSPrabhakar Kushwaha { 650c517771aSPrabhakar Kushwaha uint64_t buf_array[7]; 651c517771aSPrabhakar Kushwaha u8 *addr; 652c517771aSPrabhakar Kushwaha int i; 653c517771aSPrabhakar Kushwaha struct qbman_release_desc rd; 654c517771aSPrabhakar Kushwaha 655c517771aSPrabhakar Kushwaha for (i = 0; i < 7; i++) { 65614480454SPrabhakar Kushwaha addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE); 657c517771aSPrabhakar Kushwaha if (!addr) { 658c517771aSPrabhakar Kushwaha printf("addr allocation failed\n"); 659c517771aSPrabhakar Kushwaha goto err_alloc; 660c517771aSPrabhakar Kushwaha } 661c517771aSPrabhakar Kushwaha memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE); 6625753b0f1SPrabhakar Kushwaha flush_dcache_range((u64)addr, 6635753b0f1SPrabhakar Kushwaha (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE)); 664c517771aSPrabhakar Kushwaha 665c517771aSPrabhakar Kushwaha buf_array[i] = (uint64_t)addr; 666c517771aSPrabhakar Kushwaha debug("Release: buffer addr =0x%p\n", addr); 667c517771aSPrabhakar Kushwaha } 668c517771aSPrabhakar Kushwaha 669c517771aSPrabhakar Kushwaha release_bufs: 670c517771aSPrabhakar Kushwaha /* In case the portal is busy, retry until successful. 671c517771aSPrabhakar Kushwaha * This function is guaranteed to succeed in a reasonable amount 672c517771aSPrabhakar Kushwaha * of time. 673c517771aSPrabhakar Kushwaha */ 674c517771aSPrabhakar Kushwaha 675c517771aSPrabhakar Kushwaha do { 676c517771aSPrabhakar Kushwaha mdelay(1); 677c517771aSPrabhakar Kushwaha qbman_release_desc_clear(&rd); 678c517771aSPrabhakar Kushwaha qbman_release_desc_set_bpid(&rd, bpid); 679c517771aSPrabhakar Kushwaha } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i)); 680c517771aSPrabhakar Kushwaha 681c517771aSPrabhakar Kushwaha return i; 682c517771aSPrabhakar Kushwaha 683c517771aSPrabhakar Kushwaha err_alloc: 684c517771aSPrabhakar Kushwaha if (i) 685c517771aSPrabhakar Kushwaha goto release_bufs; 686c517771aSPrabhakar Kushwaha 687c517771aSPrabhakar Kushwaha return 0; 688c517771aSPrabhakar Kushwaha } 689c517771aSPrabhakar Kushwaha 690c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_seed(uint16_t bpid) 691c517771aSPrabhakar Kushwaha { 692c517771aSPrabhakar Kushwaha int i; 693c517771aSPrabhakar Kushwaha int count; 694c517771aSPrabhakar Kushwaha 695c517771aSPrabhakar Kushwaha for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) { 696c517771aSPrabhakar Kushwaha count = ldpaa_bp_add_7(bpid); 697c517771aSPrabhakar Kushwaha if (count < 7) 698c517771aSPrabhakar Kushwaha printf("Buffer Seed= %d\n", count); 699c517771aSPrabhakar Kushwaha } 700c517771aSPrabhakar Kushwaha 701c517771aSPrabhakar Kushwaha return 0; 702c517771aSPrabhakar Kushwaha } 703c517771aSPrabhakar Kushwaha 704c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_setup(void) 705c517771aSPrabhakar Kushwaha { 706c517771aSPrabhakar Kushwaha int err; 707c517771aSPrabhakar Kushwaha 70887457d11SPrabhakar Kushwaha err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, 709c517771aSPrabhakar Kushwaha &dflt_dpbp->dpbp_handle); 710c517771aSPrabhakar Kushwaha if (err) { 711c517771aSPrabhakar Kushwaha printf("dpbp_open() failed\n"); 712c517771aSPrabhakar Kushwaha goto err_open; 713c517771aSPrabhakar Kushwaha } 714c517771aSPrabhakar Kushwaha 71587457d11SPrabhakar Kushwaha err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 716c517771aSPrabhakar Kushwaha if (err) { 717c517771aSPrabhakar Kushwaha printf("dpbp_enable() failed\n"); 718c517771aSPrabhakar Kushwaha goto err_enable; 719c517771aSPrabhakar Kushwaha } 720c517771aSPrabhakar Kushwaha 72187457d11SPrabhakar Kushwaha err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 72287457d11SPrabhakar Kushwaha dflt_dpbp->dpbp_handle, 723c517771aSPrabhakar Kushwaha &dflt_dpbp->dpbp_attr); 724c517771aSPrabhakar Kushwaha if (err) { 725c517771aSPrabhakar Kushwaha printf("dpbp_get_attributes() failed\n"); 726c517771aSPrabhakar Kushwaha goto err_get_attr; 727c517771aSPrabhakar Kushwaha } 728c517771aSPrabhakar Kushwaha 729c517771aSPrabhakar Kushwaha err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid); 7302557c5a9SYogesh Gaur 731c517771aSPrabhakar Kushwaha if (err) { 732c517771aSPrabhakar Kushwaha printf("Buffer seeding failed for DPBP %d (bpid=%d)\n", 733c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid); 734c517771aSPrabhakar Kushwaha goto err_seed; 735c517771aSPrabhakar Kushwaha } 736c517771aSPrabhakar Kushwaha 737c517771aSPrabhakar Kushwaha return 0; 738c517771aSPrabhakar Kushwaha 739c517771aSPrabhakar Kushwaha err_seed: 740c517771aSPrabhakar Kushwaha err_get_attr: 74187457d11SPrabhakar Kushwaha dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 742c517771aSPrabhakar Kushwaha err_enable: 74387457d11SPrabhakar Kushwaha dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 744c517771aSPrabhakar Kushwaha err_open: 745c517771aSPrabhakar Kushwaha return err; 746c517771aSPrabhakar Kushwaha } 747c517771aSPrabhakar Kushwaha 748c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_free(void) 749c517771aSPrabhakar Kushwaha { 750c517771aSPrabhakar Kushwaha ldpaa_dpbp_drain(); 75187457d11SPrabhakar Kushwaha dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 75287457d11SPrabhakar Kushwaha dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 75387457d11SPrabhakar Kushwaha dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 754c517771aSPrabhakar Kushwaha } 755c517771aSPrabhakar Kushwaha 7569a696f56SPrabhakar Kushwaha static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io, 7579a696f56SPrabhakar Kushwaha struct ldpaa_eth_priv *priv) 7589a696f56SPrabhakar Kushwaha { 7599a696f56SPrabhakar Kushwaha int error; 7602557c5a9SYogesh Gaur uint16_t major_ver, minor_ver; 7619a696f56SPrabhakar Kushwaha 7622557c5a9SYogesh Gaur error = dpmac_get_api_version(dflt_mc_io, 0, 7632557c5a9SYogesh Gaur &major_ver, 7642557c5a9SYogesh Gaur &minor_ver); 7652557c5a9SYogesh Gaur if ((major_ver < DPMAC_VER_MAJOR) || 7662557c5a9SYogesh Gaur (major_ver == DPMAC_VER_MAJOR && minor_ver < DPMAC_VER_MINOR)) { 7679a696f56SPrabhakar Kushwaha printf("DPMAC version mismatch found %u.%u,", 7682557c5a9SYogesh Gaur major_ver, minor_ver); 7699a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 7709a696f56SPrabhakar Kushwaha DPMAC_VER_MAJOR, DPMAC_VER_MINOR); 7712557c5a9SYogesh Gaur return error; 7729a696f56SPrabhakar Kushwaha } 7739a696f56SPrabhakar Kushwaha 7749a696f56SPrabhakar Kushwaha return error; 7759a696f56SPrabhakar Kushwaha } 7769a696f56SPrabhakar Kushwaha 777c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv) 778c919ab9eSPrabhakar Kushwaha { 779c919ab9eSPrabhakar Kushwaha int err = 0; 780c919ab9eSPrabhakar Kushwaha struct dpmac_cfg dpmac_cfg; 781c919ab9eSPrabhakar Kushwaha 782c919ab9eSPrabhakar Kushwaha dpmac_cfg.mac_id = priv->dpmac_id; 7832557c5a9SYogesh Gaur 7842557c5a9SYogesh Gaur err = dpmac_create(dflt_mc_io, 7852557c5a9SYogesh Gaur dflt_dprc_handle, 7862557c5a9SYogesh Gaur MC_CMD_NO_FLAGS, &dpmac_cfg, 7872557c5a9SYogesh Gaur &priv->dpmac_id); 788c919ab9eSPrabhakar Kushwaha if (err) 789c919ab9eSPrabhakar Kushwaha printf("dpmac_create() failed\n"); 7909a696f56SPrabhakar Kushwaha 7919a696f56SPrabhakar Kushwaha err = ldpaa_dpmac_version_check(dflt_mc_io, priv); 7922557c5a9SYogesh Gaur if (err < 0) { 7939a696f56SPrabhakar Kushwaha printf("ldpaa_dpmac_version_check() failed: %d\n", err); 7942557c5a9SYogesh Gaur goto err_version_check; 7952557c5a9SYogesh Gaur } 7962557c5a9SYogesh Gaur 7972557c5a9SYogesh Gaur err = dpmac_open(dflt_mc_io, 7982557c5a9SYogesh Gaur MC_CMD_NO_FLAGS, 7992557c5a9SYogesh Gaur priv->dpmac_id, 8002557c5a9SYogesh Gaur &priv->dpmac_handle); 8012557c5a9SYogesh Gaur if (err < 0) { 8022557c5a9SYogesh Gaur printf("dpmac_open() failed: %d\n", err); 8032557c5a9SYogesh Gaur goto err_open; 8042557c5a9SYogesh Gaur } 8052557c5a9SYogesh Gaur 8062557c5a9SYogesh Gaur return err; 8072557c5a9SYogesh Gaur 8082557c5a9SYogesh Gaur err_open: 8092557c5a9SYogesh Gaur err_version_check: 8102557c5a9SYogesh Gaur dpmac_destroy(dflt_mc_io, 8112557c5a9SYogesh Gaur dflt_dprc_handle, 8122557c5a9SYogesh Gaur MC_CMD_NO_FLAGS, priv->dpmac_id); 8139a696f56SPrabhakar Kushwaha 814c919ab9eSPrabhakar Kushwaha return err; 815c919ab9eSPrabhakar Kushwaha } 816c919ab9eSPrabhakar Kushwaha 817c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv) 818c919ab9eSPrabhakar Kushwaha { 819c919ab9eSPrabhakar Kushwaha int err = 0; 820c919ab9eSPrabhakar Kushwaha struct dprc_connection_cfg dprc_connection_cfg = { 821c919ab9eSPrabhakar Kushwaha /* If both rates are zero the connection */ 822c919ab9eSPrabhakar Kushwaha /* will be configured in "best effort" mode. */ 823c919ab9eSPrabhakar Kushwaha .committed_rate = 0, 824c919ab9eSPrabhakar Kushwaha .max_rate = 0 825c919ab9eSPrabhakar Kushwaha }; 826c919ab9eSPrabhakar Kushwaha 8275038d3e5SPrabhakar Kushwaha #ifdef DEBUG 8285038d3e5SPrabhakar Kushwaha struct dprc_endpoint dbg_endpoint; 8295038d3e5SPrabhakar Kushwaha int state = 0; 8305038d3e5SPrabhakar Kushwaha #endif 8315038d3e5SPrabhakar Kushwaha 832c919ab9eSPrabhakar Kushwaha memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint)); 833192bc694SBen Whitten strcpy(dpmac_endpoint.type, "dpmac"); 834c919ab9eSPrabhakar Kushwaha dpmac_endpoint.id = priv->dpmac_id; 835c919ab9eSPrabhakar Kushwaha 836c919ab9eSPrabhakar Kushwaha memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint)); 837192bc694SBen Whitten strcpy(dpni_endpoint.type, "dpni"); 838c919ab9eSPrabhakar Kushwaha dpni_endpoint.id = dflt_dpni->dpni_id; 839c919ab9eSPrabhakar Kushwaha 840c919ab9eSPrabhakar Kushwaha err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS, 841c919ab9eSPrabhakar Kushwaha dflt_dprc_handle, 842c919ab9eSPrabhakar Kushwaha &dpmac_endpoint, 843c919ab9eSPrabhakar Kushwaha &dpni_endpoint, 844c919ab9eSPrabhakar Kushwaha &dprc_connection_cfg); 8455038d3e5SPrabhakar Kushwaha if (err) 8465038d3e5SPrabhakar Kushwaha printf("dprc_connect() failed\n"); 8475038d3e5SPrabhakar Kushwaha 8485038d3e5SPrabhakar Kushwaha #ifdef DEBUG 8495038d3e5SPrabhakar Kushwaha err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 8505038d3e5SPrabhakar Kushwaha dflt_dprc_handle, &dpni_endpoint, 8515038d3e5SPrabhakar Kushwaha &dbg_endpoint, &state); 8525038d3e5SPrabhakar Kushwaha printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type); 8535038d3e5SPrabhakar Kushwaha printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id); 8545038d3e5SPrabhakar Kushwaha printf("%s, DPMAC State= %d\n", __func__, state); 8555038d3e5SPrabhakar Kushwaha 8565038d3e5SPrabhakar Kushwaha memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint)); 8575038d3e5SPrabhakar Kushwaha err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 8585038d3e5SPrabhakar Kushwaha dflt_dprc_handle, &dpmac_endpoint, 8595038d3e5SPrabhakar Kushwaha &dbg_endpoint, &state); 8605038d3e5SPrabhakar Kushwaha printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type); 8615038d3e5SPrabhakar Kushwaha printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id); 8625038d3e5SPrabhakar Kushwaha printf("%s, DPNI State= %d\n", __func__, state); 8635038d3e5SPrabhakar Kushwaha #endif 864c919ab9eSPrabhakar Kushwaha return err; 865c919ab9eSPrabhakar Kushwaha } 866c919ab9eSPrabhakar Kushwaha 867c517771aSPrabhakar Kushwaha static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) 868c517771aSPrabhakar Kushwaha { 869c517771aSPrabhakar Kushwaha int err; 870c517771aSPrabhakar Kushwaha 871c517771aSPrabhakar Kushwaha /* and get a handle for the DPNI this interface is associate with */ 872c919ab9eSPrabhakar Kushwaha err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, 873c919ab9eSPrabhakar Kushwaha &dflt_dpni->dpni_handle); 874c517771aSPrabhakar Kushwaha if (err) { 875c517771aSPrabhakar Kushwaha printf("dpni_open() failed\n"); 876c517771aSPrabhakar Kushwaha goto err_open; 877c517771aSPrabhakar Kushwaha } 87887457d11SPrabhakar Kushwaha err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 879c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 880c919ab9eSPrabhakar Kushwaha &dflt_dpni->dpni_attrs); 881c517771aSPrabhakar Kushwaha if (err) { 882c517771aSPrabhakar Kushwaha printf("dpni_get_attributes() failed (err=%d)\n", err); 883c517771aSPrabhakar Kushwaha goto err_get_attr; 884c517771aSPrabhakar Kushwaha } 885c517771aSPrabhakar Kushwaha 886c517771aSPrabhakar Kushwaha /* Configure our buffers' layout */ 887c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | 888c517771aSPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | 88914480454SPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE | 89014480454SPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_DATA_ALIGN; 891c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.pass_parser_result = true; 892c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.pass_frame_status = true; 893c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE; 89414480454SPrabhakar Kushwaha /* HW erratum mandates data alignment in multiples of 256 */ 89514480454SPrabhakar Kushwaha dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN; 8962557c5a9SYogesh Gaur 897c517771aSPrabhakar Kushwaha /* ...rx, ... */ 8982557c5a9SYogesh Gaur err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 899c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 9002557c5a9SYogesh Gaur &dflt_dpni->buf_layout, DPNI_QUEUE_RX); 901c517771aSPrabhakar Kushwaha if (err) { 9022557c5a9SYogesh Gaur printf("dpni_set_buffer_layout() failed"); 903c517771aSPrabhakar Kushwaha goto err_buf_layout; 904c517771aSPrabhakar Kushwaha } 905c517771aSPrabhakar Kushwaha 906c517771aSPrabhakar Kushwaha /* ... tx, ... */ 90714480454SPrabhakar Kushwaha /* remove Rx-only options */ 90814480454SPrabhakar Kushwaha dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN | 90914480454SPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_PARSER_RESULT); 9102557c5a9SYogesh Gaur err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 911c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 9122557c5a9SYogesh Gaur &dflt_dpni->buf_layout, DPNI_QUEUE_TX); 913c517771aSPrabhakar Kushwaha if (err) { 9142557c5a9SYogesh Gaur printf("dpni_set_buffer_layout() failed"); 915c517771aSPrabhakar Kushwaha goto err_buf_layout; 916c517771aSPrabhakar Kushwaha } 917c517771aSPrabhakar Kushwaha 918c517771aSPrabhakar Kushwaha /* ... tx-confirm. */ 919c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; 9202557c5a9SYogesh Gaur err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 921c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 9222557c5a9SYogesh Gaur &dflt_dpni->buf_layout, 9232557c5a9SYogesh Gaur DPNI_QUEUE_TX_CONFIRM); 924c517771aSPrabhakar Kushwaha if (err) { 9252557c5a9SYogesh Gaur printf("dpni_set_buffer_layout() failed"); 926c517771aSPrabhakar Kushwaha goto err_buf_layout; 927c517771aSPrabhakar Kushwaha } 928c517771aSPrabhakar Kushwaha 929c517771aSPrabhakar Kushwaha /* Now that we've set our tx buffer layout, retrieve the minimum 930c517771aSPrabhakar Kushwaha * required tx data offset. 931c517771aSPrabhakar Kushwaha */ 93287457d11SPrabhakar Kushwaha err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS, 933c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 934c919ab9eSPrabhakar Kushwaha &priv->tx_data_offset); 935c517771aSPrabhakar Kushwaha if (err) { 936c517771aSPrabhakar Kushwaha printf("dpni_get_tx_data_offset() failed\n"); 937c517771aSPrabhakar Kushwaha goto err_data_offset; 938c517771aSPrabhakar Kushwaha } 939c517771aSPrabhakar Kushwaha 940c517771aSPrabhakar Kushwaha /* Warn in case TX data offset is not multiple of 64 bytes. */ 941c517771aSPrabhakar Kushwaha WARN_ON(priv->tx_data_offset % 64); 942c517771aSPrabhakar Kushwaha 943c517771aSPrabhakar Kushwaha /* Accomodate SWA space. */ 944c517771aSPrabhakar Kushwaha priv->tx_data_offset += LDPAA_ETH_SWA_SIZE; 945c517771aSPrabhakar Kushwaha debug("priv->tx_data_offset=%d\n", priv->tx_data_offset); 946c517771aSPrabhakar Kushwaha 947c517771aSPrabhakar Kushwaha return 0; 948c517771aSPrabhakar Kushwaha 949c517771aSPrabhakar Kushwaha err_data_offset: 950c517771aSPrabhakar Kushwaha err_buf_layout: 951c517771aSPrabhakar Kushwaha err_get_attr: 952c919ab9eSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 953c517771aSPrabhakar Kushwaha err_open: 954c517771aSPrabhakar Kushwaha return err; 955c517771aSPrabhakar Kushwaha } 956c517771aSPrabhakar Kushwaha 957c517771aSPrabhakar Kushwaha static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) 958c517771aSPrabhakar Kushwaha { 959c517771aSPrabhakar Kushwaha struct dpni_pools_cfg pools_params; 9602557c5a9SYogesh Gaur struct dpni_queue tx_queue; 961c517771aSPrabhakar Kushwaha int err = 0; 962c517771aSPrabhakar Kushwaha 96331a48cf4SPrabhakar Kushwaha memset(&pools_params, 0, sizeof(pools_params)); 964c517771aSPrabhakar Kushwaha pools_params.num_dpbp = 1; 965c517771aSPrabhakar Kushwaha pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id; 966c517771aSPrabhakar Kushwaha pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE; 967c919ab9eSPrabhakar Kushwaha err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS, 968c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, &pools_params); 969c517771aSPrabhakar Kushwaha if (err) { 970c517771aSPrabhakar Kushwaha printf("dpni_set_pools() failed\n"); 971c517771aSPrabhakar Kushwaha return err; 972c517771aSPrabhakar Kushwaha } 973c517771aSPrabhakar Kushwaha 9742557c5a9SYogesh Gaur memset(&tx_queue, 0, sizeof(struct dpni_queue)); 975c517771aSPrabhakar Kushwaha 9762557c5a9SYogesh Gaur err = dpni_set_queue(dflt_mc_io, MC_CMD_NO_FLAGS, 9772557c5a9SYogesh Gaur dflt_dpni->dpni_handle, 9782557c5a9SYogesh Gaur DPNI_QUEUE_TX, 0, 0, &tx_queue); 9792557c5a9SYogesh Gaur 980c517771aSPrabhakar Kushwaha if (err) { 9812557c5a9SYogesh Gaur printf("dpni_set_queue() failed\n"); 982c517771aSPrabhakar Kushwaha return err; 983c517771aSPrabhakar Kushwaha } 984c517771aSPrabhakar Kushwaha 9852557c5a9SYogesh Gaur err = dpni_set_tx_confirmation_mode(dflt_mc_io, MC_CMD_NO_FLAGS, 9866073548aSPrabhakar Kushwaha dflt_dpni->dpni_handle, 9872557c5a9SYogesh Gaur DPNI_CONF_DISABLE); 9886073548aSPrabhakar Kushwaha if (err) { 9892557c5a9SYogesh Gaur printf("dpni_set_tx_confirmation_mode() failed\n"); 9906073548aSPrabhakar Kushwaha return err; 9916073548aSPrabhakar Kushwaha } 9926073548aSPrabhakar Kushwaha 993c517771aSPrabhakar Kushwaha return 0; 994c517771aSPrabhakar Kushwaha } 995c517771aSPrabhakar Kushwaha 996c919ab9eSPrabhakar Kushwaha static int ldpaa_eth_netdev_init(struct eth_device *net_dev, 997c919ab9eSPrabhakar Kushwaha phy_interface_t enet_if) 998c517771aSPrabhakar Kushwaha { 999c517771aSPrabhakar Kushwaha int err; 1000c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 1001c517771aSPrabhakar Kushwaha 1002c022ec03SPankaj Bansal snprintf(net_dev->name, ETH_NAME_LEN, "DPMAC%d@%s", priv->dpmac_id, 1003c919ab9eSPrabhakar Kushwaha phy_interface_strings[enet_if]); 1004c517771aSPrabhakar Kushwaha 1005c517771aSPrabhakar Kushwaha net_dev->iobase = 0; 1006c517771aSPrabhakar Kushwaha net_dev->init = ldpaa_eth_open; 1007c517771aSPrabhakar Kushwaha net_dev->halt = ldpaa_eth_stop; 1008c517771aSPrabhakar Kushwaha net_dev->send = ldpaa_eth_tx; 1009c517771aSPrabhakar Kushwaha net_dev->recv = ldpaa_eth_pull_dequeue_rx; 1010c517771aSPrabhakar Kushwaha 10116c2b520aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB 10126c2b520aSPrabhakar Kushwaha err = init_phy(net_dev); 10136c2b520aSPrabhakar Kushwaha if (err < 0) 10146c2b520aSPrabhakar Kushwaha return err; 10156c2b520aSPrabhakar Kushwaha #endif 1016c517771aSPrabhakar Kushwaha 1017c517771aSPrabhakar Kushwaha err = eth_register(net_dev); 1018c517771aSPrabhakar Kushwaha if (err < 0) { 1019c517771aSPrabhakar Kushwaha printf("eth_register() = %d\n", err); 1020c517771aSPrabhakar Kushwaha return err; 1021c517771aSPrabhakar Kushwaha } 1022c517771aSPrabhakar Kushwaha 1023c517771aSPrabhakar Kushwaha return 0; 1024c517771aSPrabhakar Kushwaha } 1025c517771aSPrabhakar Kushwaha 1026c919ab9eSPrabhakar Kushwaha int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if) 1027c517771aSPrabhakar Kushwaha { 1028c517771aSPrabhakar Kushwaha struct eth_device *net_dev = NULL; 1029c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = NULL; 1030c517771aSPrabhakar Kushwaha int err = 0; 1031c517771aSPrabhakar Kushwaha 1032c517771aSPrabhakar Kushwaha /* Net device */ 1033c517771aSPrabhakar Kushwaha net_dev = (struct eth_device *)malloc(sizeof(struct eth_device)); 1034c517771aSPrabhakar Kushwaha if (!net_dev) { 1035c517771aSPrabhakar Kushwaha printf("eth_device malloc() failed\n"); 1036c517771aSPrabhakar Kushwaha return -ENOMEM; 1037c517771aSPrabhakar Kushwaha } 1038c517771aSPrabhakar Kushwaha memset(net_dev, 0, sizeof(struct eth_device)); 1039c517771aSPrabhakar Kushwaha 1040c517771aSPrabhakar Kushwaha /* alloc the ldpaa ethernet private struct */ 1041c517771aSPrabhakar Kushwaha priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv)); 1042c517771aSPrabhakar Kushwaha if (!priv) { 1043c517771aSPrabhakar Kushwaha printf("ldpaa_eth_priv malloc() failed\n"); 1044c517771aSPrabhakar Kushwaha return -ENOMEM; 1045c517771aSPrabhakar Kushwaha } 1046c517771aSPrabhakar Kushwaha memset(priv, 0, sizeof(struct ldpaa_eth_priv)); 1047c517771aSPrabhakar Kushwaha 1048c517771aSPrabhakar Kushwaha net_dev->priv = (void *)priv; 1049c517771aSPrabhakar Kushwaha priv->net_dev = (struct eth_device *)net_dev; 1050c919ab9eSPrabhakar Kushwaha priv->dpmac_id = dpmac_id; 1051c919ab9eSPrabhakar Kushwaha debug("%s dpmac_id=%d\n", __func__, dpmac_id); 1052c517771aSPrabhakar Kushwaha 1053c919ab9eSPrabhakar Kushwaha err = ldpaa_eth_netdev_init(net_dev, enet_if); 1054c517771aSPrabhakar Kushwaha if (err) 1055c517771aSPrabhakar Kushwaha goto err_netdev_init; 1056c517771aSPrabhakar Kushwaha 1057c517771aSPrabhakar Kushwaha debug("ldpaa ethernet: Probed interface %s\n", net_dev->name); 1058c517771aSPrabhakar Kushwaha return 0; 1059c517771aSPrabhakar Kushwaha 1060c517771aSPrabhakar Kushwaha err_netdev_init: 1061c517771aSPrabhakar Kushwaha free(priv); 1062c517771aSPrabhakar Kushwaha net_dev->priv = NULL; 1063c517771aSPrabhakar Kushwaha free(net_dev); 1064c517771aSPrabhakar Kushwaha 1065c517771aSPrabhakar Kushwaha return err; 1066c517771aSPrabhakar Kushwaha } 1067