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; 26*1a048cd6SPankaj Bansal int phy_addr, phy_num; 27*1a048cd6SPankaj Bansal int ret = 0; 28c517771aSPrabhakar Kushwaha 296c2b520aSPrabhakar Kushwaha bus = wriop_get_mdio(priv->dpmac_id); 306c2b520aSPrabhakar Kushwaha if (bus == NULL) 31c517771aSPrabhakar Kushwaha return 0; 326c2b520aSPrabhakar Kushwaha 33*1a048cd6SPankaj Bansal for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { 34*1a048cd6SPankaj Bansal phy_addr = wriop_get_phy_address(priv->dpmac_id, phy_num); 35*1a048cd6SPankaj Bansal if (phy_addr < 0) 36*1a048cd6SPankaj Bansal continue; 37*1a048cd6SPankaj Bansal 38*1a048cd6SPankaj Bansal phydev = phy_connect(bus, phy_addr, dev, 39*1a048cd6SPankaj Bansal wriop_get_enet_if(priv->dpmac_id)); 406c2b520aSPrabhakar Kushwaha if (!phydev) { 416c2b520aSPrabhakar Kushwaha printf("Failed to connect\n"); 42*1a048cd6SPankaj Bansal ret = -ENODEV; 43*1a048cd6SPankaj Bansal break; 44*1a048cd6SPankaj Bansal } 45*1a048cd6SPankaj Bansal wriop_set_phy_dev(priv->dpmac_id, phy_num, phydev); 46*1a048cd6SPankaj Bansal ret = phy_config(phydev); 47*1a048cd6SPankaj Bansal if (ret) 48*1a048cd6SPankaj Bansal break; 49c517771aSPrabhakar Kushwaha } 50c517771aSPrabhakar Kushwaha 51f259c43dSPankaj Bansal if (ret) { 52*1a048cd6SPankaj Bansal for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { 53*1a048cd6SPankaj Bansal phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num); 54*1a048cd6SPankaj Bansal if (!phydev) 55*1a048cd6SPankaj Bansal continue; 56*1a048cd6SPankaj Bansal 57f259c43dSPankaj Bansal free(phydev); 58*1a048cd6SPankaj Bansal wriop_set_phy_dev(priv->dpmac_id, phy_num, NULL); 59*1a048cd6SPankaj Bansal } 60f259c43dSPankaj Bansal } 61f259c43dSPankaj Bansal 62f259c43dSPankaj Bansal return ret; 636c2b520aSPrabhakar Kushwaha } 646c2b520aSPrabhakar Kushwaha #endif 656c2b520aSPrabhakar Kushwaha 665038d3e5SPrabhakar Kushwaha #ifdef DEBUG 672557c5a9SYogesh Gaur 682557c5a9SYogesh Gaur #define DPNI_STATS_PER_PAGE 6 692557c5a9SYogesh Gaur 702557c5a9SYogesh Gaur static const char *dpni_statistics[][DPNI_STATS_PER_PAGE] = { 712557c5a9SYogesh Gaur { 722557c5a9SYogesh Gaur "DPNI_CNT_ING_ALL_FRAMES", 732557c5a9SYogesh Gaur "DPNI_CNT_ING_ALL_BYTES", 742557c5a9SYogesh Gaur "DPNI_CNT_ING_MCAST_FRAMES", 752557c5a9SYogesh Gaur "DPNI_CNT_ING_MCAST_BYTES", 762557c5a9SYogesh Gaur "DPNI_CNT_ING_BCAST_FRAMES", 772557c5a9SYogesh Gaur "DPNI_CNT_ING_BCAST_BYTES", 782557c5a9SYogesh Gaur }, { 792557c5a9SYogesh Gaur "DPNI_CNT_EGR_ALL_FRAMES", 802557c5a9SYogesh Gaur "DPNI_CNT_EGR_ALL_BYTES", 812557c5a9SYogesh Gaur "DPNI_CNT_EGR_MCAST_FRAMES", 822557c5a9SYogesh Gaur "DPNI_CNT_EGR_MCAST_BYTES", 832557c5a9SYogesh Gaur "DPNI_CNT_EGR_BCAST_FRAMES", 842557c5a9SYogesh Gaur "DPNI_CNT_EGR_BCAST_BYTES", 852557c5a9SYogesh Gaur }, { 862557c5a9SYogesh Gaur "DPNI_CNT_ING_FILTERED_FRAMES", 872557c5a9SYogesh Gaur "DPNI_CNT_ING_DISCARDED_FRAMES", 882557c5a9SYogesh Gaur "DPNI_CNT_ING_NOBUFFER_DISCARDS", 892557c5a9SYogesh Gaur "DPNI_CNT_EGR_DISCARDED_FRAMES", 902557c5a9SYogesh Gaur "DPNI_CNT_EGR_CNF_FRAMES", 912557c5a9SYogesh Gaur "" 922557c5a9SYogesh Gaur }, 932557c5a9SYogesh Gaur }; 942557c5a9SYogesh Gaur 952557c5a9SYogesh Gaur static void print_dpni_stats(const char *strings[], 962557c5a9SYogesh Gaur struct dpni_statistics dpni_stats) 972557c5a9SYogesh Gaur { 982557c5a9SYogesh Gaur uint64_t *stat; 992557c5a9SYogesh Gaur int i; 1002557c5a9SYogesh Gaur 1012557c5a9SYogesh Gaur stat = (uint64_t *)&dpni_stats; 1022557c5a9SYogesh Gaur for (i = 0; i < DPNI_STATS_PER_PAGE; i++) { 1032557c5a9SYogesh Gaur if (strcmp(strings[i], "\0") == 0) 1042557c5a9SYogesh Gaur break; 1052557c5a9SYogesh Gaur printf("%s= %llu\n", strings[i], *stat); 1062557c5a9SYogesh Gaur stat++; 1072557c5a9SYogesh Gaur } 1082557c5a9SYogesh Gaur } 1092557c5a9SYogesh Gaur 1105038d3e5SPrabhakar Kushwaha static void ldpaa_eth_get_dpni_counter(void) 1115038d3e5SPrabhakar Kushwaha { 1125038d3e5SPrabhakar Kushwaha int err = 0; 1132557c5a9SYogesh Gaur unsigned int page = 0; 1142557c5a9SYogesh Gaur struct dpni_statistics dpni_stats; 1155038d3e5SPrabhakar Kushwaha 1162557c5a9SYogesh Gaur printf("DPNI counters ..\n"); 1172557c5a9SYogesh Gaur for (page = 0; page < 3; page++) { 1182557c5a9SYogesh Gaur err = dpni_get_statistics(dflt_mc_io, MC_CMD_NO_FLAGS, 1192557c5a9SYogesh Gaur dflt_dpni->dpni_handle, page, 1202557c5a9SYogesh Gaur &dpni_stats); 1215038d3e5SPrabhakar Kushwaha if (err < 0) { 1222557c5a9SYogesh Gaur printf("dpni_get_statistics: failed:"); 1232557c5a9SYogesh Gaur printf("%d for page[%d]\n", err, page); 1245038d3e5SPrabhakar Kushwaha return; 1255038d3e5SPrabhakar Kushwaha } 1262557c5a9SYogesh Gaur print_dpni_stats(dpni_statistics[page], dpni_stats); 1275038d3e5SPrabhakar Kushwaha } 1285038d3e5SPrabhakar Kushwaha } 12944b2036eSPrabhakar Kushwaha 13044b2036eSPrabhakar Kushwaha static void ldpaa_eth_get_dpmac_counter(struct eth_device *net_dev) 13144b2036eSPrabhakar Kushwaha { 13244b2036eSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 13344b2036eSPrabhakar Kushwaha int err = 0; 13444b2036eSPrabhakar Kushwaha u64 value; 13544b2036eSPrabhakar Kushwaha 13644b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 13744b2036eSPrabhakar Kushwaha priv->dpmac_handle, 13844b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_BYTE, 13944b2036eSPrabhakar Kushwaha &value); 14044b2036eSPrabhakar Kushwaha if (err < 0) { 14144b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n"); 14244b2036eSPrabhakar Kushwaha return; 14344b2036eSPrabhakar Kushwaha } 1442557c5a9SYogesh Gaur printf("\nDPMAC counters ..\n"); 14544b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_BYTE=%lld\n", value); 14644b2036eSPrabhakar Kushwaha 14744b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 14844b2036eSPrabhakar Kushwaha priv->dpmac_handle, 14944b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_FRAME_DISCARD, 15044b2036eSPrabhakar Kushwaha &value); 15144b2036eSPrabhakar Kushwaha if (err < 0) { 15244b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n"); 15344b2036eSPrabhakar Kushwaha return; 15444b2036eSPrabhakar Kushwaha } 15544b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_FRAME_DISCARD=%lld\n", value); 15644b2036eSPrabhakar Kushwaha 15744b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 15844b2036eSPrabhakar Kushwaha priv->dpmac_handle, 15944b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_ALIGN_ERR, 16044b2036eSPrabhakar Kushwaha &value); 16144b2036eSPrabhakar Kushwaha if (err < 0) { 16244b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n"); 16344b2036eSPrabhakar Kushwaha return; 16444b2036eSPrabhakar Kushwaha } 16544b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_ALIGN_ERR =%lld\n", value); 16644b2036eSPrabhakar Kushwaha 16744b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 16844b2036eSPrabhakar Kushwaha priv->dpmac_handle, 16944b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_BYTE, 17044b2036eSPrabhakar Kushwaha &value); 17144b2036eSPrabhakar Kushwaha if (err < 0) { 17244b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n"); 17344b2036eSPrabhakar Kushwaha return; 17444b2036eSPrabhakar Kushwaha } 17544b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_BYTE=%lld\n", value); 17644b2036eSPrabhakar Kushwaha 17744b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 17844b2036eSPrabhakar Kushwaha priv->dpmac_handle, 17944b2036eSPrabhakar Kushwaha DPMAC_CNT_ING_ERR_FRAME, 18044b2036eSPrabhakar Kushwaha &value); 18144b2036eSPrabhakar Kushwaha if (err < 0) { 18244b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n"); 18344b2036eSPrabhakar Kushwaha return; 18444b2036eSPrabhakar Kushwaha } 18544b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_ING_ERR_FRAME=%lld\n", value); 18644b2036eSPrabhakar Kushwaha 18744b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 18844b2036eSPrabhakar Kushwaha priv->dpmac_handle, 18944b2036eSPrabhakar Kushwaha DPMAC_CNT_EGR_BYTE , 19044b2036eSPrabhakar Kushwaha &value); 19144b2036eSPrabhakar Kushwaha if (err < 0) { 19244b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n"); 19344b2036eSPrabhakar Kushwaha return; 19444b2036eSPrabhakar Kushwaha } 19544b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_EGR_BYTE =%lld\n", value); 19644b2036eSPrabhakar Kushwaha 19744b2036eSPrabhakar Kushwaha err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS, 19844b2036eSPrabhakar Kushwaha priv->dpmac_handle, 19944b2036eSPrabhakar Kushwaha DPMAC_CNT_EGR_ERR_FRAME , 20044b2036eSPrabhakar Kushwaha &value); 20144b2036eSPrabhakar Kushwaha if (err < 0) { 20244b2036eSPrabhakar Kushwaha printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n"); 20344b2036eSPrabhakar Kushwaha return; 20444b2036eSPrabhakar Kushwaha } 20544b2036eSPrabhakar Kushwaha printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value); 20644b2036eSPrabhakar Kushwaha } 2075038d3e5SPrabhakar Kushwaha #endif 2085038d3e5SPrabhakar Kushwaha 209c517771aSPrabhakar Kushwaha static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv, 210c517771aSPrabhakar Kushwaha const struct dpaa_fd *fd) 211c517771aSPrabhakar Kushwaha { 212c517771aSPrabhakar Kushwaha u64 fd_addr; 213c517771aSPrabhakar Kushwaha uint16_t fd_offset; 214c517771aSPrabhakar Kushwaha uint32_t fd_length; 215c517771aSPrabhakar Kushwaha struct ldpaa_fas *fas; 216c517771aSPrabhakar Kushwaha uint32_t status, err; 21756c57cf7SPrabhakar Kushwaha u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; 21856c57cf7SPrabhakar Kushwaha u32 time_start; 219c517771aSPrabhakar Kushwaha struct qbman_release_desc releasedesc; 220c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 221c517771aSPrabhakar Kushwaha 222c517771aSPrabhakar Kushwaha fd_addr = ldpaa_fd_get_addr(fd); 223c517771aSPrabhakar Kushwaha fd_offset = ldpaa_fd_get_offset(fd); 224c517771aSPrabhakar Kushwaha fd_length = ldpaa_fd_get_len(fd); 225c517771aSPrabhakar Kushwaha 226c517771aSPrabhakar Kushwaha debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length); 227c517771aSPrabhakar Kushwaha 228c517771aSPrabhakar Kushwaha if (fd->simple.frc & LDPAA_FD_FRC_FASV) { 229c517771aSPrabhakar Kushwaha /* Read the frame annotation status word and check for errors */ 230c517771aSPrabhakar Kushwaha fas = (struct ldpaa_fas *) 231c517771aSPrabhakar Kushwaha ((uint8_t *)(fd_addr) + 232c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.private_data_size); 233c517771aSPrabhakar Kushwaha status = le32_to_cpu(fas->status); 234c517771aSPrabhakar Kushwaha if (status & LDPAA_ETH_RX_ERR_MASK) { 235c517771aSPrabhakar Kushwaha printf("Rx frame error(s): 0x%08x\n", 236c517771aSPrabhakar Kushwaha status & LDPAA_ETH_RX_ERR_MASK); 237c517771aSPrabhakar Kushwaha goto error; 238c517771aSPrabhakar Kushwaha } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) { 239c517771aSPrabhakar Kushwaha printf("Unsupported feature in bitmask: 0x%08x\n", 240c517771aSPrabhakar Kushwaha status & LDPAA_ETH_RX_UNSUPP_MASK); 241c517771aSPrabhakar Kushwaha goto error; 242c517771aSPrabhakar Kushwaha } 243c517771aSPrabhakar Kushwaha } 244c517771aSPrabhakar Kushwaha 245c517771aSPrabhakar Kushwaha debug("Rx frame: To Upper layer\n"); 246c517771aSPrabhakar Kushwaha net_process_received_packet((uint8_t *)(fd_addr) + fd_offset, 247c517771aSPrabhakar Kushwaha fd_length); 248c517771aSPrabhakar Kushwaha 249c517771aSPrabhakar Kushwaha error: 2505753b0f1SPrabhakar Kushwaha flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE); 251c517771aSPrabhakar Kushwaha qbman_release_desc_clear(&releasedesc); 252c517771aSPrabhakar Kushwaha qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 25356c57cf7SPrabhakar Kushwaha time_start = get_timer(0); 254c517771aSPrabhakar Kushwaha do { 255c517771aSPrabhakar Kushwaha /* Release buffer into the QBMAN */ 256c517771aSPrabhakar Kushwaha err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); 25756c57cf7SPrabhakar Kushwaha } while (get_timer(time_start) < timeo && err == -EBUSY); 25856c57cf7SPrabhakar Kushwaha 25956c57cf7SPrabhakar Kushwaha if (err == -EBUSY) 26056c57cf7SPrabhakar Kushwaha printf("Rx frame: QBMAN buffer release fails\n"); 26156c57cf7SPrabhakar Kushwaha 262c517771aSPrabhakar Kushwaha return; 263c517771aSPrabhakar Kushwaha } 264c517771aSPrabhakar Kushwaha 265c517771aSPrabhakar Kushwaha static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) 266c517771aSPrabhakar Kushwaha { 267c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; 268c517771aSPrabhakar Kushwaha const struct ldpaa_dq *dq; 269c517771aSPrabhakar Kushwaha const struct dpaa_fd *fd; 270b4c3a35dSPrabhakar Kushwaha int i = 5, err = 0, status; 271b4c3a35dSPrabhakar Kushwaha u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; 272b4c3a35dSPrabhakar Kushwaha u32 time_start; 273c517771aSPrabhakar Kushwaha static struct qbman_pull_desc pulldesc; 274c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 275c517771aSPrabhakar Kushwaha 2765753b0f1SPrabhakar Kushwaha while (--i) { 277c517771aSPrabhakar Kushwaha qbman_pull_desc_clear(&pulldesc); 278c517771aSPrabhakar Kushwaha qbman_pull_desc_set_numframes(&pulldesc, 1); 279c517771aSPrabhakar Kushwaha qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid); 280c517771aSPrabhakar Kushwaha 281c517771aSPrabhakar Kushwaha err = qbman_swp_pull(swp, &pulldesc); 282c517771aSPrabhakar Kushwaha if (err < 0) { 283c517771aSPrabhakar Kushwaha printf("Dequeue frames error:0x%08x\n", err); 284c517771aSPrabhakar Kushwaha continue; 285c517771aSPrabhakar Kushwaha } 286c517771aSPrabhakar Kushwaha 287b4c3a35dSPrabhakar Kushwaha time_start = get_timer(0); 2885753b0f1SPrabhakar Kushwaha 289b4c3a35dSPrabhakar Kushwaha do { 290b4c3a35dSPrabhakar Kushwaha dq = qbman_swp_dqrr_next(swp); 291b4c3a35dSPrabhakar Kushwaha } while (get_timer(time_start) < timeo && !dq); 2925753b0f1SPrabhakar Kushwaha 293c517771aSPrabhakar Kushwaha if (dq) { 294c517771aSPrabhakar Kushwaha /* Check for valid frame. If not sent a consume 295c517771aSPrabhakar Kushwaha * confirmation to QBMAN otherwise give it to NADK 296c517771aSPrabhakar Kushwaha * application and then send consume confirmation to 297c517771aSPrabhakar Kushwaha * QBMAN. 298c517771aSPrabhakar Kushwaha */ 299c517771aSPrabhakar Kushwaha status = (uint8_t)ldpaa_dq_flags(dq); 300c517771aSPrabhakar Kushwaha if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) { 301c517771aSPrabhakar Kushwaha debug("Dequeue RX frames:"); 302c517771aSPrabhakar Kushwaha debug("No frame delivered\n"); 303c517771aSPrabhakar Kushwaha 304c517771aSPrabhakar Kushwaha qbman_swp_dqrr_consume(swp, dq); 3050c7c87a4SPrabhakar Kushwaha continue; 306c517771aSPrabhakar Kushwaha } 307c517771aSPrabhakar Kushwaha 308c517771aSPrabhakar Kushwaha fd = ldpaa_dq_fd(dq); 309c517771aSPrabhakar Kushwaha 310c517771aSPrabhakar Kushwaha /* Obtain FD and process it */ 311c517771aSPrabhakar Kushwaha ldpaa_eth_rx(priv, fd); 312c517771aSPrabhakar Kushwaha qbman_swp_dqrr_consume(swp, dq); 313c517771aSPrabhakar Kushwaha break; 314b4c3a35dSPrabhakar Kushwaha } else { 315b4c3a35dSPrabhakar Kushwaha err = -ENODATA; 316b4c3a35dSPrabhakar Kushwaha debug("No DQRR entries\n"); 317b4c3a35dSPrabhakar Kushwaha break; 318c517771aSPrabhakar Kushwaha } 319c517771aSPrabhakar Kushwaha } 320c517771aSPrabhakar Kushwaha 321c517771aSPrabhakar Kushwaha return err; 322c517771aSPrabhakar Kushwaha } 323c517771aSPrabhakar Kushwaha 324c517771aSPrabhakar Kushwaha static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) 325c517771aSPrabhakar Kushwaha { 326c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 327c517771aSPrabhakar Kushwaha struct dpaa_fd fd; 328c517771aSPrabhakar Kushwaha u64 buffer_start; 329c517771aSPrabhakar Kushwaha int data_offset, err; 330e48df52bSPrabhakar Kushwaha u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; 331e48df52bSPrabhakar Kushwaha u32 time_start; 332c517771aSPrabhakar Kushwaha struct qbman_swp *swp = dflt_dpio->sw_portal; 333c517771aSPrabhakar Kushwaha struct qbman_eq_desc ed; 334e48df52bSPrabhakar Kushwaha struct qbman_release_desc releasedesc; 335c517771aSPrabhakar Kushwaha 336c517771aSPrabhakar Kushwaha /* Setup the FD fields */ 337c517771aSPrabhakar Kushwaha memset(&fd, 0, sizeof(fd)); 338c517771aSPrabhakar Kushwaha 339c517771aSPrabhakar Kushwaha data_offset = priv->tx_data_offset; 340c517771aSPrabhakar Kushwaha 341c517771aSPrabhakar Kushwaha do { 342c517771aSPrabhakar Kushwaha err = qbman_swp_acquire(dflt_dpio->sw_portal, 343c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.bpid, 344c517771aSPrabhakar Kushwaha &buffer_start, 1); 345c517771aSPrabhakar Kushwaha } while (err == -EBUSY); 346c517771aSPrabhakar Kushwaha 3475e9445daSAshish Kumar if (err <= 0) { 348c517771aSPrabhakar Kushwaha printf("qbman_swp_acquire() failed\n"); 349c517771aSPrabhakar Kushwaha return -ENOMEM; 350c517771aSPrabhakar Kushwaha } 351c517771aSPrabhakar Kushwaha 352c517771aSPrabhakar Kushwaha debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start); 353c517771aSPrabhakar Kushwaha 354c517771aSPrabhakar Kushwaha memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len); 355c517771aSPrabhakar Kushwaha 3565753b0f1SPrabhakar Kushwaha flush_dcache_range(buffer_start, buffer_start + 3575753b0f1SPrabhakar Kushwaha LDPAA_ETH_RX_BUFFER_SIZE); 358c517771aSPrabhakar Kushwaha 359c517771aSPrabhakar Kushwaha ldpaa_fd_set_addr(&fd, (u64)buffer_start); 360c517771aSPrabhakar Kushwaha ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset)); 361c517771aSPrabhakar Kushwaha ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid); 362c517771aSPrabhakar Kushwaha ldpaa_fd_set_len(&fd, len); 363c517771aSPrabhakar Kushwaha 364c517771aSPrabhakar Kushwaha fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA | 365c517771aSPrabhakar Kushwaha LDPAA_FD_CTRL_PTV1; 366c517771aSPrabhakar Kushwaha 367c517771aSPrabhakar Kushwaha qbman_eq_desc_clear(&ed); 368c517771aSPrabhakar Kushwaha qbman_eq_desc_set_no_orp(&ed, 0); 369c517771aSPrabhakar Kushwaha qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0); 370e48df52bSPrabhakar Kushwaha 371e48df52bSPrabhakar Kushwaha time_start = get_timer(0); 372e48df52bSPrabhakar Kushwaha 373e48df52bSPrabhakar Kushwaha while (get_timer(time_start) < timeo) { 374e48df52bSPrabhakar Kushwaha err = qbman_swp_enqueue(swp, &ed, 375e48df52bSPrabhakar Kushwaha (const struct qbman_fd *)(&fd)); 376e48df52bSPrabhakar Kushwaha if (err != -EBUSY) 377e48df52bSPrabhakar Kushwaha break; 378e48df52bSPrabhakar Kushwaha } 379e48df52bSPrabhakar Kushwaha 380e48df52bSPrabhakar Kushwaha if (err < 0) { 381c517771aSPrabhakar Kushwaha printf("error enqueueing Tx frame\n"); 382e48df52bSPrabhakar Kushwaha goto error; 383e48df52bSPrabhakar Kushwaha } 384c517771aSPrabhakar Kushwaha 385c517771aSPrabhakar Kushwaha return err; 386e48df52bSPrabhakar Kushwaha 387e48df52bSPrabhakar Kushwaha error: 388e48df52bSPrabhakar Kushwaha qbman_release_desc_clear(&releasedesc); 389e48df52bSPrabhakar Kushwaha qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); 390e48df52bSPrabhakar Kushwaha time_start = get_timer(0); 391e48df52bSPrabhakar Kushwaha do { 392e48df52bSPrabhakar Kushwaha /* Release buffer into the QBMAN */ 393e48df52bSPrabhakar Kushwaha err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1); 394e48df52bSPrabhakar Kushwaha } while (get_timer(time_start) < timeo && err == -EBUSY); 395e48df52bSPrabhakar Kushwaha 396e48df52bSPrabhakar Kushwaha if (err == -EBUSY) 397e48df52bSPrabhakar Kushwaha printf("TX data: QBMAN buffer release fails\n"); 398e48df52bSPrabhakar Kushwaha 399e48df52bSPrabhakar Kushwaha return err; 400c517771aSPrabhakar Kushwaha } 401c517771aSPrabhakar Kushwaha 402a3cb5340SPankaj Bansal static int ldpaa_get_dpmac_state(struct ldpaa_eth_priv *priv, 403a3cb5340SPankaj Bansal struct dpmac_link_state *state) 404a3cb5340SPankaj Bansal { 405a3cb5340SPankaj Bansal struct phy_device *phydev = NULL; 406a3cb5340SPankaj Bansal phy_interface_t enet_if; 407*1a048cd6SPankaj Bansal int phy_num, phys_detected; 408a3cb5340SPankaj Bansal int err; 409a3cb5340SPankaj Bansal 410*1a048cd6SPankaj Bansal /* let's start off with maximum capabilities */ 411a3cb5340SPankaj Bansal enet_if = wriop_get_enet_if(priv->dpmac_id); 412a3cb5340SPankaj Bansal switch (enet_if) { 413a3cb5340SPankaj Bansal case PHY_INTERFACE_MODE_XGMII: 414a3cb5340SPankaj Bansal state->rate = SPEED_10000; 415a3cb5340SPankaj Bansal break; 416a3cb5340SPankaj Bansal default: 417a3cb5340SPankaj Bansal state->rate = SPEED_1000; 418a3cb5340SPankaj Bansal break; 419a3cb5340SPankaj Bansal } 420a3cb5340SPankaj Bansal state->up = 1; 421a3cb5340SPankaj Bansal 422*1a048cd6SPankaj Bansal phys_detected = 0; 423a3cb5340SPankaj Bansal #ifdef CONFIG_PHYLIB 424a3cb5340SPankaj Bansal state->options |= DPMAC_LINK_OPT_AUTONEG; 425a3cb5340SPankaj Bansal 426*1a048cd6SPankaj Bansal /* start the phy devices one by one and update the dpmac state */ 427*1a048cd6SPankaj Bansal for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { 428*1a048cd6SPankaj Bansal phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num); 429*1a048cd6SPankaj Bansal if (!phydev) 430*1a048cd6SPankaj Bansal continue; 431*1a048cd6SPankaj Bansal 432*1a048cd6SPankaj Bansal phys_detected++; 433a3cb5340SPankaj Bansal err = phy_startup(phydev); 434a3cb5340SPankaj Bansal if (err) { 435a3cb5340SPankaj Bansal printf("%s: Could not initialize\n", phydev->dev->name); 436a3cb5340SPankaj Bansal state->up = 0; 437*1a048cd6SPankaj Bansal break; 438a3cb5340SPankaj Bansal } 439a3cb5340SPankaj Bansal if (phydev->link) { 440a3cb5340SPankaj Bansal state->rate = min(state->rate, (uint32_t)phydev->speed); 441a3cb5340SPankaj Bansal if (!phydev->duplex) 442a3cb5340SPankaj Bansal state->options |= DPMAC_LINK_OPT_HALF_DUPLEX; 443a3cb5340SPankaj Bansal if (!phydev->autoneg) 444a3cb5340SPankaj Bansal state->options &= ~DPMAC_LINK_OPT_AUTONEG; 445a3cb5340SPankaj Bansal } else { 446*1a048cd6SPankaj Bansal /* break out of loop even if one phy is down */ 447a3cb5340SPankaj Bansal state->up = 0; 448*1a048cd6SPankaj Bansal break; 449a3cb5340SPankaj Bansal } 450a3cb5340SPankaj Bansal } 451a3cb5340SPankaj Bansal #endif 452*1a048cd6SPankaj Bansal if (!phys_detected) 453a3cb5340SPankaj Bansal state->options &= ~DPMAC_LINK_OPT_AUTONEG; 454a3cb5340SPankaj Bansal 455a3cb5340SPankaj Bansal if (!state->up) { 456a3cb5340SPankaj Bansal state->rate = 0; 457a3cb5340SPankaj Bansal state->options = 0; 458a3cb5340SPankaj Bansal return -ENOLINK; 459a3cb5340SPankaj Bansal } 460a3cb5340SPankaj Bansal 461a3cb5340SPankaj Bansal return 0; 462a3cb5340SPankaj Bansal } 463a3cb5340SPankaj Bansal 464c517771aSPrabhakar Kushwaha static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) 465c517771aSPrabhakar Kushwaha { 466c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 467c919ab9eSPrabhakar Kushwaha struct dpmac_link_state dpmac_link_state = { 0 }; 4685038d3e5SPrabhakar Kushwaha #ifdef DEBUG 4695038d3e5SPrabhakar Kushwaha struct dpni_link_state link_state; 4705038d3e5SPrabhakar Kushwaha #endif 4716c2b520aSPrabhakar Kushwaha int err = 0; 4722557c5a9SYogesh Gaur struct dpni_queue d_queue; 473c517771aSPrabhakar Kushwaha 474c517771aSPrabhakar Kushwaha if (net_dev->state == ETH_STATE_ACTIVE) 475c517771aSPrabhakar Kushwaha return 0; 476c517771aSPrabhakar Kushwaha 477c919ab9eSPrabhakar Kushwaha if (get_mc_boot_status() != 0) { 478c919ab9eSPrabhakar Kushwaha printf("ERROR (MC is not booted)\n"); 479c919ab9eSPrabhakar Kushwaha return -ENODEV; 480c919ab9eSPrabhakar Kushwaha } 481c919ab9eSPrabhakar Kushwaha 482c919ab9eSPrabhakar Kushwaha if (get_dpl_apply_status() == 0) { 483c919ab9eSPrabhakar Kushwaha printf("ERROR (DPL is deployed. No device available)\n"); 484c919ab9eSPrabhakar Kushwaha return -ENODEV; 485c919ab9eSPrabhakar Kushwaha } 4866c2b520aSPrabhakar Kushwaha 487c919ab9eSPrabhakar Kushwaha /* DPMAC initialization */ 488c919ab9eSPrabhakar Kushwaha err = ldpaa_dpmac_setup(priv); 489c919ab9eSPrabhakar Kushwaha if (err < 0) 490c919ab9eSPrabhakar Kushwaha goto err_dpmac_setup; 491c919ab9eSPrabhakar Kushwaha 492a3cb5340SPankaj Bansal err = ldpaa_get_dpmac_state(priv, &dpmac_link_state); 493a3cb5340SPankaj Bansal if (err < 0) 494afd6c6b4SPankaj Bansal goto err_dpmac_bind; 4956c2b520aSPrabhakar Kushwaha 496c919ab9eSPrabhakar Kushwaha /* DPMAC binding DPNI */ 497c919ab9eSPrabhakar Kushwaha err = ldpaa_dpmac_bind(priv); 498c919ab9eSPrabhakar Kushwaha if (err) 499afd6c6b4SPankaj Bansal goto err_dpmac_bind; 500c919ab9eSPrabhakar Kushwaha 501c517771aSPrabhakar Kushwaha /* DPNI initialization */ 502c517771aSPrabhakar Kushwaha err = ldpaa_dpni_setup(priv); 503c517771aSPrabhakar Kushwaha if (err < 0) 504c517771aSPrabhakar Kushwaha goto err_dpni_setup; 505c517771aSPrabhakar Kushwaha 506c517771aSPrabhakar Kushwaha err = ldpaa_dpbp_setup(); 507c517771aSPrabhakar Kushwaha if (err < 0) 508c517771aSPrabhakar Kushwaha goto err_dpbp_setup; 509c517771aSPrabhakar Kushwaha 510c517771aSPrabhakar Kushwaha /* DPNI binding DPBP */ 511c517771aSPrabhakar Kushwaha err = ldpaa_dpni_bind(priv); 512c517771aSPrabhakar Kushwaha if (err) 513c919ab9eSPrabhakar Kushwaha goto err_dpni_bind; 514c517771aSPrabhakar Kushwaha 5157b2edb8bSPrabhakar Kushwaha err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, 516c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, net_dev->enetaddr); 517c517771aSPrabhakar Kushwaha if (err) { 5187b2edb8bSPrabhakar Kushwaha printf("dpni_add_mac_addr() failed\n"); 519c517771aSPrabhakar Kushwaha return err; 520c517771aSPrabhakar Kushwaha } 521c517771aSPrabhakar Kushwaha 522c919ab9eSPrabhakar Kushwaha err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 523c517771aSPrabhakar Kushwaha if (err < 0) { 524c517771aSPrabhakar Kushwaha printf("dpni_enable() failed\n"); 525c517771aSPrabhakar Kushwaha return err; 526c517771aSPrabhakar Kushwaha } 527c517771aSPrabhakar Kushwaha 528c919ab9eSPrabhakar Kushwaha err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, 529c919ab9eSPrabhakar Kushwaha priv->dpmac_handle, &dpmac_link_state); 530c919ab9eSPrabhakar Kushwaha if (err < 0) { 531c919ab9eSPrabhakar Kushwaha printf("dpmac_set_link_state() failed\n"); 532c919ab9eSPrabhakar Kushwaha return err; 533c919ab9eSPrabhakar Kushwaha } 5345038d3e5SPrabhakar Kushwaha 5355038d3e5SPrabhakar Kushwaha #ifdef DEBUG 5362557c5a9SYogesh Gaur printf("DPMAC link status: %d - ", dpmac_link_state.up); 5372557c5a9SYogesh Gaur dpmac_link_state.up == 0 ? printf("down\n") : 5382557c5a9SYogesh Gaur dpmac_link_state.up == 1 ? printf("up\n") : printf("error state\n"); 5392557c5a9SYogesh Gaur 5405038d3e5SPrabhakar Kushwaha err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, 5415038d3e5SPrabhakar Kushwaha dflt_dpni->dpni_handle, &link_state); 5425038d3e5SPrabhakar Kushwaha if (err < 0) { 5435038d3e5SPrabhakar Kushwaha printf("dpni_get_link_state() failed\n"); 5445038d3e5SPrabhakar Kushwaha return err; 5455038d3e5SPrabhakar Kushwaha } 5465038d3e5SPrabhakar Kushwaha 5472557c5a9SYogesh Gaur printf("DPNI link status: %d - ", link_state.up); 5485038d3e5SPrabhakar Kushwaha link_state.up == 0 ? printf("down\n") : 5495038d3e5SPrabhakar Kushwaha link_state.up == 1 ? printf("up\n") : printf("error state\n"); 5505038d3e5SPrabhakar Kushwaha #endif 5515038d3e5SPrabhakar Kushwaha 5522557c5a9SYogesh Gaur memset(&d_queue, 0, sizeof(struct dpni_queue)); 5532557c5a9SYogesh Gaur err = dpni_get_queue(dflt_mc_io, MC_CMD_NO_FLAGS, 5542557c5a9SYogesh Gaur dflt_dpni->dpni_handle, DPNI_QUEUE_RX, 5552557c5a9SYogesh Gaur 0, 0, &d_queue); 556c517771aSPrabhakar Kushwaha if (err) { 5572557c5a9SYogesh Gaur printf("dpni_get_queue failed\n"); 5582557c5a9SYogesh Gaur goto err_get_queue; 559c517771aSPrabhakar Kushwaha } 560c517771aSPrabhakar Kushwaha 5612557c5a9SYogesh Gaur priv->rx_dflt_fqid = d_queue.fqid; 562c517771aSPrabhakar Kushwaha 563c919ab9eSPrabhakar Kushwaha err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, 56487457d11SPrabhakar Kushwaha &priv->tx_qdid); 565c517771aSPrabhakar Kushwaha if (err) { 566c517771aSPrabhakar Kushwaha printf("dpni_get_qdid() failed\n"); 567c517771aSPrabhakar Kushwaha goto err_qdid; 568c517771aSPrabhakar Kushwaha } 569c517771aSPrabhakar Kushwaha 570a3cb5340SPankaj Bansal return dpmac_link_state.up; 571c517771aSPrabhakar Kushwaha 572c517771aSPrabhakar Kushwaha err_qdid: 5732557c5a9SYogesh Gaur err_get_queue: 574c919ab9eSPrabhakar Kushwaha dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 575c919ab9eSPrabhakar Kushwaha err_dpni_bind: 576c517771aSPrabhakar Kushwaha ldpaa_dpbp_free(); 577c517771aSPrabhakar Kushwaha err_dpbp_setup: 578c919ab9eSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 579c517771aSPrabhakar Kushwaha err_dpni_setup: 580afd6c6b4SPankaj Bansal err_dpmac_bind: 5812557c5a9SYogesh Gaur dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); 5822557c5a9SYogesh Gaur dpmac_destroy(dflt_mc_io, 5832557c5a9SYogesh Gaur dflt_dprc_handle, 5842557c5a9SYogesh Gaur MC_CMD_NO_FLAGS, priv->dpmac_id); 585c919ab9eSPrabhakar Kushwaha err_dpmac_setup: 586c517771aSPrabhakar Kushwaha return err; 587c517771aSPrabhakar Kushwaha } 588c517771aSPrabhakar Kushwaha 589c517771aSPrabhakar Kushwaha static void ldpaa_eth_stop(struct eth_device *net_dev) 590c517771aSPrabhakar Kushwaha { 591c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 592c517771aSPrabhakar Kushwaha int err = 0; 593d75e81d9SPankaj Bansal struct phy_device *phydev = NULL; 594*1a048cd6SPankaj Bansal int phy_num; 595c517771aSPrabhakar Kushwaha 5965753b0f1SPrabhakar Kushwaha if ((net_dev->state == ETH_STATE_PASSIVE) || 5975753b0f1SPrabhakar Kushwaha (net_dev->state == ETH_STATE_INIT)) 598c517771aSPrabhakar Kushwaha return; 599c919ab9eSPrabhakar Kushwaha 6005038d3e5SPrabhakar Kushwaha #ifdef DEBUG 6015038d3e5SPrabhakar Kushwaha ldpaa_eth_get_dpni_counter(); 60244b2036eSPrabhakar Kushwaha ldpaa_eth_get_dpmac_counter(net_dev); 6035038d3e5SPrabhakar Kushwaha #endif 6045038d3e5SPrabhakar Kushwaha 605c919ab9eSPrabhakar Kushwaha err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS, 606c919ab9eSPrabhakar Kushwaha dflt_dprc_handle, &dpmac_endpoint); 607c919ab9eSPrabhakar Kushwaha if (err < 0) 608c919ab9eSPrabhakar Kushwaha printf("dprc_disconnect() failed dpmac_endpoint\n"); 609c919ab9eSPrabhakar Kushwaha 6102557c5a9SYogesh Gaur err = dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); 6112557c5a9SYogesh Gaur if (err < 0) 6122557c5a9SYogesh Gaur printf("dpmac_close() failed\n"); 6132557c5a9SYogesh Gaur 6142557c5a9SYogesh Gaur err = dpmac_destroy(dflt_mc_io, 6152557c5a9SYogesh Gaur dflt_dprc_handle, 6162557c5a9SYogesh Gaur MC_CMD_NO_FLAGS, 6172557c5a9SYogesh Gaur priv->dpmac_id); 618c919ab9eSPrabhakar Kushwaha if (err < 0) 619c919ab9eSPrabhakar Kushwaha printf("dpmac_destroy() failed\n"); 620c919ab9eSPrabhakar Kushwaha 621c517771aSPrabhakar Kushwaha /* Stop Tx and Rx traffic */ 622c919ab9eSPrabhakar Kushwaha err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 623c517771aSPrabhakar Kushwaha if (err < 0) 624c517771aSPrabhakar Kushwaha printf("dpni_disable() failed\n"); 625c517771aSPrabhakar Kushwaha 626c517771aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB 627*1a048cd6SPankaj Bansal for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { 628*1a048cd6SPankaj Bansal phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num); 629a3cb5340SPankaj Bansal if (phydev) 630d75e81d9SPankaj Bansal phy_shutdown(phydev); 631*1a048cd6SPankaj Bansal } 632c517771aSPrabhakar Kushwaha #endif 633c517771aSPrabhakar Kushwaha 6342557c5a9SYogesh Gaur /* Free DPBP handle and reset. */ 635c517771aSPrabhakar Kushwaha ldpaa_dpbp_free(); 6362557c5a9SYogesh Gaur 637c919ab9eSPrabhakar Kushwaha dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 6382557c5a9SYogesh Gaur if (err < 0) 6392557c5a9SYogesh Gaur printf("dpni_reset() failed\n"); 6402557c5a9SYogesh Gaur 641c919ab9eSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 6422557c5a9SYogesh Gaur if (err < 0) 6432557c5a9SYogesh Gaur printf("dpni_close() failed\n"); 644c517771aSPrabhakar Kushwaha } 645c517771aSPrabhakar Kushwaha 646c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain_cnt(int count) 647c517771aSPrabhakar Kushwaha { 648c517771aSPrabhakar Kushwaha uint64_t buf_array[7]; 649c517771aSPrabhakar Kushwaha void *addr; 650c517771aSPrabhakar Kushwaha int ret, i; 651c517771aSPrabhakar Kushwaha 652c517771aSPrabhakar Kushwaha BUG_ON(count > 7); 653c517771aSPrabhakar Kushwaha 654c517771aSPrabhakar Kushwaha do { 655c517771aSPrabhakar Kushwaha ret = qbman_swp_acquire(dflt_dpio->sw_portal, 656c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.bpid, 657c517771aSPrabhakar Kushwaha buf_array, count); 658c517771aSPrabhakar Kushwaha if (ret < 0) { 659c517771aSPrabhakar Kushwaha printf("qbman_swp_acquire() failed\n"); 660c517771aSPrabhakar Kushwaha return; 661c517771aSPrabhakar Kushwaha } 662c517771aSPrabhakar Kushwaha for (i = 0; i < ret; i++) { 663c517771aSPrabhakar Kushwaha addr = (void *)buf_array[i]; 664c517771aSPrabhakar Kushwaha debug("Free: buffer addr =0x%p\n", addr); 665c517771aSPrabhakar Kushwaha free(addr); 666c517771aSPrabhakar Kushwaha } 667c517771aSPrabhakar Kushwaha } while (ret); 668c517771aSPrabhakar Kushwaha } 669c517771aSPrabhakar Kushwaha 670c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain(void) 671c517771aSPrabhakar Kushwaha { 672c517771aSPrabhakar Kushwaha int i; 673c517771aSPrabhakar Kushwaha for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) 674c517771aSPrabhakar Kushwaha ldpaa_dpbp_drain_cnt(7); 675c517771aSPrabhakar Kushwaha } 676c517771aSPrabhakar Kushwaha 677c517771aSPrabhakar Kushwaha static int ldpaa_bp_add_7(uint16_t bpid) 678c517771aSPrabhakar Kushwaha { 679c517771aSPrabhakar Kushwaha uint64_t buf_array[7]; 680c517771aSPrabhakar Kushwaha u8 *addr; 681c517771aSPrabhakar Kushwaha int i; 682c517771aSPrabhakar Kushwaha struct qbman_release_desc rd; 683c517771aSPrabhakar Kushwaha 684c517771aSPrabhakar Kushwaha for (i = 0; i < 7; i++) { 68514480454SPrabhakar Kushwaha addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE); 686c517771aSPrabhakar Kushwaha if (!addr) { 687c517771aSPrabhakar Kushwaha printf("addr allocation failed\n"); 688c517771aSPrabhakar Kushwaha goto err_alloc; 689c517771aSPrabhakar Kushwaha } 690c517771aSPrabhakar Kushwaha memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE); 6915753b0f1SPrabhakar Kushwaha flush_dcache_range((u64)addr, 6925753b0f1SPrabhakar Kushwaha (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE)); 693c517771aSPrabhakar Kushwaha 694c517771aSPrabhakar Kushwaha buf_array[i] = (uint64_t)addr; 695c517771aSPrabhakar Kushwaha debug("Release: buffer addr =0x%p\n", addr); 696c517771aSPrabhakar Kushwaha } 697c517771aSPrabhakar Kushwaha 698c517771aSPrabhakar Kushwaha release_bufs: 699c517771aSPrabhakar Kushwaha /* In case the portal is busy, retry until successful. 700c517771aSPrabhakar Kushwaha * This function is guaranteed to succeed in a reasonable amount 701c517771aSPrabhakar Kushwaha * of time. 702c517771aSPrabhakar Kushwaha */ 703c517771aSPrabhakar Kushwaha 704c517771aSPrabhakar Kushwaha do { 705c517771aSPrabhakar Kushwaha mdelay(1); 706c517771aSPrabhakar Kushwaha qbman_release_desc_clear(&rd); 707c517771aSPrabhakar Kushwaha qbman_release_desc_set_bpid(&rd, bpid); 708c517771aSPrabhakar Kushwaha } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i)); 709c517771aSPrabhakar Kushwaha 710c517771aSPrabhakar Kushwaha return i; 711c517771aSPrabhakar Kushwaha 712c517771aSPrabhakar Kushwaha err_alloc: 713c517771aSPrabhakar Kushwaha if (i) 714c517771aSPrabhakar Kushwaha goto release_bufs; 715c517771aSPrabhakar Kushwaha 716c517771aSPrabhakar Kushwaha return 0; 717c517771aSPrabhakar Kushwaha } 718c517771aSPrabhakar Kushwaha 719c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_seed(uint16_t bpid) 720c517771aSPrabhakar Kushwaha { 721c517771aSPrabhakar Kushwaha int i; 722c517771aSPrabhakar Kushwaha int count; 723c517771aSPrabhakar Kushwaha 724c517771aSPrabhakar Kushwaha for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) { 725c517771aSPrabhakar Kushwaha count = ldpaa_bp_add_7(bpid); 726c517771aSPrabhakar Kushwaha if (count < 7) 727c517771aSPrabhakar Kushwaha printf("Buffer Seed= %d\n", count); 728c517771aSPrabhakar Kushwaha } 729c517771aSPrabhakar Kushwaha 730c517771aSPrabhakar Kushwaha return 0; 731c517771aSPrabhakar Kushwaha } 732c517771aSPrabhakar Kushwaha 733c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_setup(void) 734c517771aSPrabhakar Kushwaha { 735c517771aSPrabhakar Kushwaha int err; 736c517771aSPrabhakar Kushwaha 73787457d11SPrabhakar Kushwaha err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, 738c517771aSPrabhakar Kushwaha &dflt_dpbp->dpbp_handle); 739c517771aSPrabhakar Kushwaha if (err) { 740c517771aSPrabhakar Kushwaha printf("dpbp_open() failed\n"); 741c517771aSPrabhakar Kushwaha goto err_open; 742c517771aSPrabhakar Kushwaha } 743c517771aSPrabhakar Kushwaha 74487457d11SPrabhakar Kushwaha err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 745c517771aSPrabhakar Kushwaha if (err) { 746c517771aSPrabhakar Kushwaha printf("dpbp_enable() failed\n"); 747c517771aSPrabhakar Kushwaha goto err_enable; 748c517771aSPrabhakar Kushwaha } 749c517771aSPrabhakar Kushwaha 75087457d11SPrabhakar Kushwaha err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 75187457d11SPrabhakar Kushwaha dflt_dpbp->dpbp_handle, 752c517771aSPrabhakar Kushwaha &dflt_dpbp->dpbp_attr); 753c517771aSPrabhakar Kushwaha if (err) { 754c517771aSPrabhakar Kushwaha printf("dpbp_get_attributes() failed\n"); 755c517771aSPrabhakar Kushwaha goto err_get_attr; 756c517771aSPrabhakar Kushwaha } 757c517771aSPrabhakar Kushwaha 758c517771aSPrabhakar Kushwaha err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid); 7592557c5a9SYogesh Gaur 760c517771aSPrabhakar Kushwaha if (err) { 761c517771aSPrabhakar Kushwaha printf("Buffer seeding failed for DPBP %d (bpid=%d)\n", 762c517771aSPrabhakar Kushwaha dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid); 763c517771aSPrabhakar Kushwaha goto err_seed; 764c517771aSPrabhakar Kushwaha } 765c517771aSPrabhakar Kushwaha 766c517771aSPrabhakar Kushwaha return 0; 767c517771aSPrabhakar Kushwaha 768c517771aSPrabhakar Kushwaha err_seed: 769c517771aSPrabhakar Kushwaha err_get_attr: 77087457d11SPrabhakar Kushwaha dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 771c517771aSPrabhakar Kushwaha err_enable: 77287457d11SPrabhakar Kushwaha dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 773c517771aSPrabhakar Kushwaha err_open: 774c517771aSPrabhakar Kushwaha return err; 775c517771aSPrabhakar Kushwaha } 776c517771aSPrabhakar Kushwaha 777c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_free(void) 778c517771aSPrabhakar Kushwaha { 779c517771aSPrabhakar Kushwaha ldpaa_dpbp_drain(); 78087457d11SPrabhakar Kushwaha dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 78187457d11SPrabhakar Kushwaha dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 78287457d11SPrabhakar Kushwaha dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); 783c517771aSPrabhakar Kushwaha } 784c517771aSPrabhakar Kushwaha 7859a696f56SPrabhakar Kushwaha static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io, 7869a696f56SPrabhakar Kushwaha struct ldpaa_eth_priv *priv) 7879a696f56SPrabhakar Kushwaha { 7889a696f56SPrabhakar Kushwaha int error; 7892557c5a9SYogesh Gaur uint16_t major_ver, minor_ver; 7909a696f56SPrabhakar Kushwaha 7912557c5a9SYogesh Gaur error = dpmac_get_api_version(dflt_mc_io, 0, 7922557c5a9SYogesh Gaur &major_ver, 7932557c5a9SYogesh Gaur &minor_ver); 7942557c5a9SYogesh Gaur if ((major_ver < DPMAC_VER_MAJOR) || 7952557c5a9SYogesh Gaur (major_ver == DPMAC_VER_MAJOR && minor_ver < DPMAC_VER_MINOR)) { 7969a696f56SPrabhakar Kushwaha printf("DPMAC version mismatch found %u.%u,", 7972557c5a9SYogesh Gaur major_ver, minor_ver); 7989a696f56SPrabhakar Kushwaha printf("supported version is %u.%u\n", 7999a696f56SPrabhakar Kushwaha DPMAC_VER_MAJOR, DPMAC_VER_MINOR); 8002557c5a9SYogesh Gaur return error; 8019a696f56SPrabhakar Kushwaha } 8029a696f56SPrabhakar Kushwaha 8039a696f56SPrabhakar Kushwaha return error; 8049a696f56SPrabhakar Kushwaha } 8059a696f56SPrabhakar Kushwaha 806c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv) 807c919ab9eSPrabhakar Kushwaha { 808c919ab9eSPrabhakar Kushwaha int err = 0; 809c919ab9eSPrabhakar Kushwaha struct dpmac_cfg dpmac_cfg; 810c919ab9eSPrabhakar Kushwaha 811c919ab9eSPrabhakar Kushwaha dpmac_cfg.mac_id = priv->dpmac_id; 8122557c5a9SYogesh Gaur 8132557c5a9SYogesh Gaur err = dpmac_create(dflt_mc_io, 8142557c5a9SYogesh Gaur dflt_dprc_handle, 8152557c5a9SYogesh Gaur MC_CMD_NO_FLAGS, &dpmac_cfg, 8162557c5a9SYogesh Gaur &priv->dpmac_id); 817c919ab9eSPrabhakar Kushwaha if (err) 818c919ab9eSPrabhakar Kushwaha printf("dpmac_create() failed\n"); 8199a696f56SPrabhakar Kushwaha 8209a696f56SPrabhakar Kushwaha err = ldpaa_dpmac_version_check(dflt_mc_io, priv); 8212557c5a9SYogesh Gaur if (err < 0) { 8229a696f56SPrabhakar Kushwaha printf("ldpaa_dpmac_version_check() failed: %d\n", err); 8232557c5a9SYogesh Gaur goto err_version_check; 8242557c5a9SYogesh Gaur } 8252557c5a9SYogesh Gaur 8262557c5a9SYogesh Gaur err = dpmac_open(dflt_mc_io, 8272557c5a9SYogesh Gaur MC_CMD_NO_FLAGS, 8282557c5a9SYogesh Gaur priv->dpmac_id, 8292557c5a9SYogesh Gaur &priv->dpmac_handle); 8302557c5a9SYogesh Gaur if (err < 0) { 8312557c5a9SYogesh Gaur printf("dpmac_open() failed: %d\n", err); 8322557c5a9SYogesh Gaur goto err_open; 8332557c5a9SYogesh Gaur } 8342557c5a9SYogesh Gaur 8352557c5a9SYogesh Gaur return err; 8362557c5a9SYogesh Gaur 8372557c5a9SYogesh Gaur err_open: 8382557c5a9SYogesh Gaur err_version_check: 8392557c5a9SYogesh Gaur dpmac_destroy(dflt_mc_io, 8402557c5a9SYogesh Gaur dflt_dprc_handle, 8412557c5a9SYogesh Gaur MC_CMD_NO_FLAGS, priv->dpmac_id); 8429a696f56SPrabhakar Kushwaha 843c919ab9eSPrabhakar Kushwaha return err; 844c919ab9eSPrabhakar Kushwaha } 845c919ab9eSPrabhakar Kushwaha 846c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv) 847c919ab9eSPrabhakar Kushwaha { 848c919ab9eSPrabhakar Kushwaha int err = 0; 849c919ab9eSPrabhakar Kushwaha struct dprc_connection_cfg dprc_connection_cfg = { 850c919ab9eSPrabhakar Kushwaha /* If both rates are zero the connection */ 851c919ab9eSPrabhakar Kushwaha /* will be configured in "best effort" mode. */ 852c919ab9eSPrabhakar Kushwaha .committed_rate = 0, 853c919ab9eSPrabhakar Kushwaha .max_rate = 0 854c919ab9eSPrabhakar Kushwaha }; 855c919ab9eSPrabhakar Kushwaha 8565038d3e5SPrabhakar Kushwaha #ifdef DEBUG 8575038d3e5SPrabhakar Kushwaha struct dprc_endpoint dbg_endpoint; 8585038d3e5SPrabhakar Kushwaha int state = 0; 8595038d3e5SPrabhakar Kushwaha #endif 8605038d3e5SPrabhakar Kushwaha 861c919ab9eSPrabhakar Kushwaha memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint)); 862192bc694SBen Whitten strcpy(dpmac_endpoint.type, "dpmac"); 863c919ab9eSPrabhakar Kushwaha dpmac_endpoint.id = priv->dpmac_id; 864c919ab9eSPrabhakar Kushwaha 865c919ab9eSPrabhakar Kushwaha memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint)); 866192bc694SBen Whitten strcpy(dpni_endpoint.type, "dpni"); 867c919ab9eSPrabhakar Kushwaha dpni_endpoint.id = dflt_dpni->dpni_id; 868c919ab9eSPrabhakar Kushwaha 869c919ab9eSPrabhakar Kushwaha err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS, 870c919ab9eSPrabhakar Kushwaha dflt_dprc_handle, 871c919ab9eSPrabhakar Kushwaha &dpmac_endpoint, 872c919ab9eSPrabhakar Kushwaha &dpni_endpoint, 873c919ab9eSPrabhakar Kushwaha &dprc_connection_cfg); 8745038d3e5SPrabhakar Kushwaha if (err) 8755038d3e5SPrabhakar Kushwaha printf("dprc_connect() failed\n"); 8765038d3e5SPrabhakar Kushwaha 8775038d3e5SPrabhakar Kushwaha #ifdef DEBUG 8785038d3e5SPrabhakar Kushwaha err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 8795038d3e5SPrabhakar Kushwaha dflt_dprc_handle, &dpni_endpoint, 8805038d3e5SPrabhakar Kushwaha &dbg_endpoint, &state); 8815038d3e5SPrabhakar Kushwaha printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type); 8825038d3e5SPrabhakar Kushwaha printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id); 8835038d3e5SPrabhakar Kushwaha printf("%s, DPMAC State= %d\n", __func__, state); 8845038d3e5SPrabhakar Kushwaha 8855038d3e5SPrabhakar Kushwaha memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint)); 8865038d3e5SPrabhakar Kushwaha err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS, 8875038d3e5SPrabhakar Kushwaha dflt_dprc_handle, &dpmac_endpoint, 8885038d3e5SPrabhakar Kushwaha &dbg_endpoint, &state); 8895038d3e5SPrabhakar Kushwaha printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type); 8905038d3e5SPrabhakar Kushwaha printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id); 8915038d3e5SPrabhakar Kushwaha printf("%s, DPNI State= %d\n", __func__, state); 8925038d3e5SPrabhakar Kushwaha #endif 893c919ab9eSPrabhakar Kushwaha return err; 894c919ab9eSPrabhakar Kushwaha } 895c919ab9eSPrabhakar Kushwaha 896c517771aSPrabhakar Kushwaha static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) 897c517771aSPrabhakar Kushwaha { 898c517771aSPrabhakar Kushwaha int err; 899c517771aSPrabhakar Kushwaha 900c517771aSPrabhakar Kushwaha /* and get a handle for the DPNI this interface is associate with */ 901c919ab9eSPrabhakar Kushwaha err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id, 902c919ab9eSPrabhakar Kushwaha &dflt_dpni->dpni_handle); 903c517771aSPrabhakar Kushwaha if (err) { 904c517771aSPrabhakar Kushwaha printf("dpni_open() failed\n"); 905c517771aSPrabhakar Kushwaha goto err_open; 906c517771aSPrabhakar Kushwaha } 90787457d11SPrabhakar Kushwaha err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, 908c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 909c919ab9eSPrabhakar Kushwaha &dflt_dpni->dpni_attrs); 910c517771aSPrabhakar Kushwaha if (err) { 911c517771aSPrabhakar Kushwaha printf("dpni_get_attributes() failed (err=%d)\n", err); 912c517771aSPrabhakar Kushwaha goto err_get_attr; 913c517771aSPrabhakar Kushwaha } 914c517771aSPrabhakar Kushwaha 915c517771aSPrabhakar Kushwaha /* Configure our buffers' layout */ 916c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | 917c517771aSPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | 91814480454SPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE | 91914480454SPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_DATA_ALIGN; 920c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.pass_parser_result = true; 921c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.pass_frame_status = true; 922c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE; 92314480454SPrabhakar Kushwaha /* HW erratum mandates data alignment in multiples of 256 */ 92414480454SPrabhakar Kushwaha dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN; 9252557c5a9SYogesh Gaur 926c517771aSPrabhakar Kushwaha /* ...rx, ... */ 9272557c5a9SYogesh Gaur err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 928c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 9292557c5a9SYogesh Gaur &dflt_dpni->buf_layout, DPNI_QUEUE_RX); 930c517771aSPrabhakar Kushwaha if (err) { 9312557c5a9SYogesh Gaur printf("dpni_set_buffer_layout() failed"); 932c517771aSPrabhakar Kushwaha goto err_buf_layout; 933c517771aSPrabhakar Kushwaha } 934c517771aSPrabhakar Kushwaha 935c517771aSPrabhakar Kushwaha /* ... tx, ... */ 93614480454SPrabhakar Kushwaha /* remove Rx-only options */ 93714480454SPrabhakar Kushwaha dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN | 93814480454SPrabhakar Kushwaha DPNI_BUF_LAYOUT_OPT_PARSER_RESULT); 9392557c5a9SYogesh Gaur err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 940c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 9412557c5a9SYogesh Gaur &dflt_dpni->buf_layout, DPNI_QUEUE_TX); 942c517771aSPrabhakar Kushwaha if (err) { 9432557c5a9SYogesh Gaur printf("dpni_set_buffer_layout() failed"); 944c517771aSPrabhakar Kushwaha goto err_buf_layout; 945c517771aSPrabhakar Kushwaha } 946c517771aSPrabhakar Kushwaha 947c517771aSPrabhakar Kushwaha /* ... tx-confirm. */ 948c919ab9eSPrabhakar Kushwaha dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; 9492557c5a9SYogesh Gaur err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, 950c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 9512557c5a9SYogesh Gaur &dflt_dpni->buf_layout, 9522557c5a9SYogesh Gaur DPNI_QUEUE_TX_CONFIRM); 953c517771aSPrabhakar Kushwaha if (err) { 9542557c5a9SYogesh Gaur printf("dpni_set_buffer_layout() failed"); 955c517771aSPrabhakar Kushwaha goto err_buf_layout; 956c517771aSPrabhakar Kushwaha } 957c517771aSPrabhakar Kushwaha 958c517771aSPrabhakar Kushwaha /* Now that we've set our tx buffer layout, retrieve the minimum 959c517771aSPrabhakar Kushwaha * required tx data offset. 960c517771aSPrabhakar Kushwaha */ 96187457d11SPrabhakar Kushwaha err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS, 962c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, 963c919ab9eSPrabhakar Kushwaha &priv->tx_data_offset); 964c517771aSPrabhakar Kushwaha if (err) { 965c517771aSPrabhakar Kushwaha printf("dpni_get_tx_data_offset() failed\n"); 966c517771aSPrabhakar Kushwaha goto err_data_offset; 967c517771aSPrabhakar Kushwaha } 968c517771aSPrabhakar Kushwaha 969c517771aSPrabhakar Kushwaha /* Warn in case TX data offset is not multiple of 64 bytes. */ 970c517771aSPrabhakar Kushwaha WARN_ON(priv->tx_data_offset % 64); 971c517771aSPrabhakar Kushwaha 972c517771aSPrabhakar Kushwaha /* Accomodate SWA space. */ 973c517771aSPrabhakar Kushwaha priv->tx_data_offset += LDPAA_ETH_SWA_SIZE; 974c517771aSPrabhakar Kushwaha debug("priv->tx_data_offset=%d\n", priv->tx_data_offset); 975c517771aSPrabhakar Kushwaha 976c517771aSPrabhakar Kushwaha return 0; 977c517771aSPrabhakar Kushwaha 978c517771aSPrabhakar Kushwaha err_data_offset: 979c517771aSPrabhakar Kushwaha err_buf_layout: 980c517771aSPrabhakar Kushwaha err_get_attr: 981c919ab9eSPrabhakar Kushwaha dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); 982c517771aSPrabhakar Kushwaha err_open: 983c517771aSPrabhakar Kushwaha return err; 984c517771aSPrabhakar Kushwaha } 985c517771aSPrabhakar Kushwaha 986c517771aSPrabhakar Kushwaha static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) 987c517771aSPrabhakar Kushwaha { 988c517771aSPrabhakar Kushwaha struct dpni_pools_cfg pools_params; 9892557c5a9SYogesh Gaur struct dpni_queue tx_queue; 990c517771aSPrabhakar Kushwaha int err = 0; 991c517771aSPrabhakar Kushwaha 99231a48cf4SPrabhakar Kushwaha memset(&pools_params, 0, sizeof(pools_params)); 993c517771aSPrabhakar Kushwaha pools_params.num_dpbp = 1; 994c517771aSPrabhakar Kushwaha pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id; 995c517771aSPrabhakar Kushwaha pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE; 996c919ab9eSPrabhakar Kushwaha err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS, 997c919ab9eSPrabhakar Kushwaha dflt_dpni->dpni_handle, &pools_params); 998c517771aSPrabhakar Kushwaha if (err) { 999c517771aSPrabhakar Kushwaha printf("dpni_set_pools() failed\n"); 1000c517771aSPrabhakar Kushwaha return err; 1001c517771aSPrabhakar Kushwaha } 1002c517771aSPrabhakar Kushwaha 10032557c5a9SYogesh Gaur memset(&tx_queue, 0, sizeof(struct dpni_queue)); 1004c517771aSPrabhakar Kushwaha 10052557c5a9SYogesh Gaur err = dpni_set_queue(dflt_mc_io, MC_CMD_NO_FLAGS, 10062557c5a9SYogesh Gaur dflt_dpni->dpni_handle, 10072557c5a9SYogesh Gaur DPNI_QUEUE_TX, 0, 0, &tx_queue); 10082557c5a9SYogesh Gaur 1009c517771aSPrabhakar Kushwaha if (err) { 10102557c5a9SYogesh Gaur printf("dpni_set_queue() failed\n"); 1011c517771aSPrabhakar Kushwaha return err; 1012c517771aSPrabhakar Kushwaha } 1013c517771aSPrabhakar Kushwaha 10142557c5a9SYogesh Gaur err = dpni_set_tx_confirmation_mode(dflt_mc_io, MC_CMD_NO_FLAGS, 10156073548aSPrabhakar Kushwaha dflt_dpni->dpni_handle, 10162557c5a9SYogesh Gaur DPNI_CONF_DISABLE); 10176073548aSPrabhakar Kushwaha if (err) { 10182557c5a9SYogesh Gaur printf("dpni_set_tx_confirmation_mode() failed\n"); 10196073548aSPrabhakar Kushwaha return err; 10206073548aSPrabhakar Kushwaha } 10216073548aSPrabhakar Kushwaha 1022c517771aSPrabhakar Kushwaha return 0; 1023c517771aSPrabhakar Kushwaha } 1024c517771aSPrabhakar Kushwaha 1025c919ab9eSPrabhakar Kushwaha static int ldpaa_eth_netdev_init(struct eth_device *net_dev, 1026c919ab9eSPrabhakar Kushwaha phy_interface_t enet_if) 1027c517771aSPrabhakar Kushwaha { 1028c517771aSPrabhakar Kushwaha int err; 1029c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; 1030c517771aSPrabhakar Kushwaha 1031c022ec03SPankaj Bansal snprintf(net_dev->name, ETH_NAME_LEN, "DPMAC%d@%s", priv->dpmac_id, 1032c919ab9eSPrabhakar Kushwaha phy_interface_strings[enet_if]); 1033c517771aSPrabhakar Kushwaha 1034c517771aSPrabhakar Kushwaha net_dev->iobase = 0; 1035c517771aSPrabhakar Kushwaha net_dev->init = ldpaa_eth_open; 1036c517771aSPrabhakar Kushwaha net_dev->halt = ldpaa_eth_stop; 1037c517771aSPrabhakar Kushwaha net_dev->send = ldpaa_eth_tx; 1038c517771aSPrabhakar Kushwaha net_dev->recv = ldpaa_eth_pull_dequeue_rx; 1039c517771aSPrabhakar Kushwaha 10406c2b520aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB 10416c2b520aSPrabhakar Kushwaha err = init_phy(net_dev); 10426c2b520aSPrabhakar Kushwaha if (err < 0) 10436c2b520aSPrabhakar Kushwaha return err; 10446c2b520aSPrabhakar Kushwaha #endif 1045c517771aSPrabhakar Kushwaha 1046c517771aSPrabhakar Kushwaha err = eth_register(net_dev); 1047c517771aSPrabhakar Kushwaha if (err < 0) { 1048c517771aSPrabhakar Kushwaha printf("eth_register() = %d\n", err); 1049c517771aSPrabhakar Kushwaha return err; 1050c517771aSPrabhakar Kushwaha } 1051c517771aSPrabhakar Kushwaha 1052c517771aSPrabhakar Kushwaha return 0; 1053c517771aSPrabhakar Kushwaha } 1054c517771aSPrabhakar Kushwaha 1055c919ab9eSPrabhakar Kushwaha int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if) 1056c517771aSPrabhakar Kushwaha { 1057c517771aSPrabhakar Kushwaha struct eth_device *net_dev = NULL; 1058c517771aSPrabhakar Kushwaha struct ldpaa_eth_priv *priv = NULL; 1059c517771aSPrabhakar Kushwaha int err = 0; 1060c517771aSPrabhakar Kushwaha 1061c517771aSPrabhakar Kushwaha /* Net device */ 1062c517771aSPrabhakar Kushwaha net_dev = (struct eth_device *)malloc(sizeof(struct eth_device)); 1063c517771aSPrabhakar Kushwaha if (!net_dev) { 1064c517771aSPrabhakar Kushwaha printf("eth_device malloc() failed\n"); 1065c517771aSPrabhakar Kushwaha return -ENOMEM; 1066c517771aSPrabhakar Kushwaha } 1067c517771aSPrabhakar Kushwaha memset(net_dev, 0, sizeof(struct eth_device)); 1068c517771aSPrabhakar Kushwaha 1069c517771aSPrabhakar Kushwaha /* alloc the ldpaa ethernet private struct */ 1070c517771aSPrabhakar Kushwaha priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv)); 1071c517771aSPrabhakar Kushwaha if (!priv) { 1072c517771aSPrabhakar Kushwaha printf("ldpaa_eth_priv malloc() failed\n"); 1073c517771aSPrabhakar Kushwaha return -ENOMEM; 1074c517771aSPrabhakar Kushwaha } 1075c517771aSPrabhakar Kushwaha memset(priv, 0, sizeof(struct ldpaa_eth_priv)); 1076c517771aSPrabhakar Kushwaha 1077c517771aSPrabhakar Kushwaha net_dev->priv = (void *)priv; 1078c517771aSPrabhakar Kushwaha priv->net_dev = (struct eth_device *)net_dev; 1079c919ab9eSPrabhakar Kushwaha priv->dpmac_id = dpmac_id; 1080c919ab9eSPrabhakar Kushwaha debug("%s dpmac_id=%d\n", __func__, dpmac_id); 1081c517771aSPrabhakar Kushwaha 1082c919ab9eSPrabhakar Kushwaha err = ldpaa_eth_netdev_init(net_dev, enet_if); 1083c517771aSPrabhakar Kushwaha if (err) 1084c517771aSPrabhakar Kushwaha goto err_netdev_init; 1085c517771aSPrabhakar Kushwaha 1086c517771aSPrabhakar Kushwaha debug("ldpaa ethernet: Probed interface %s\n", net_dev->name); 1087c517771aSPrabhakar Kushwaha return 0; 1088c517771aSPrabhakar Kushwaha 1089c517771aSPrabhakar Kushwaha err_netdev_init: 1090c517771aSPrabhakar Kushwaha free(priv); 1091c517771aSPrabhakar Kushwaha net_dev->priv = NULL; 1092c517771aSPrabhakar Kushwaha free(net_dev); 1093c517771aSPrabhakar Kushwaha 1094c517771aSPrabhakar Kushwaha return err; 1095c517771aSPrabhakar Kushwaha } 1096