X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fldpaa_eth%2Fldpaa_eth.c;h=4de7586408e48171ab030e5bad711c3d15c93a90;hb=87457d118f77b6d4de4de83118360fb0eade491c;hp=d4be1bada96128ac8a1069460676a8a2a93aedc5;hpb=5753b0f1b0ec504e3a76a46a62ccfe619e426f21;p=oweals%2Fu-boot.git diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index d4be1bada9..4de7586408 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -31,6 +31,8 @@ static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv, uint32_t fd_length; struct ldpaa_fas *fas; uint32_t status, err; + u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; + u32 time_start; struct qbman_release_desc releasedesc; struct qbman_swp *swp = dflt_dpio->sw_portal; @@ -65,10 +67,15 @@ error: flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE); qbman_release_desc_clear(&releasedesc); qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); + time_start = get_timer(0); do { /* Release buffer into the QBMAN */ err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); - } while (err == -EBUSY); + } while (get_timer(time_start) < timeo && err == -EBUSY); + + if (err == -EBUSY) + printf("Rx frame: QBMAN buffer release fails\n"); + return; } @@ -77,7 +84,9 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; const struct ldpaa_dq *dq; const struct dpaa_fd *fd; - int i = 5, err = 0, status, loop = 20; + int i = 5, err = 0, status; + u32 timeo = (CONFIG_SYS_HZ * 2) / 1000; + u32 time_start; static struct qbman_pull_desc pulldesc; struct qbman_swp *swp = dflt_dpio->sw_portal; @@ -92,13 +101,11 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) continue; } - do { - loop--; - dq = qbman_swp_dqrr_next(swp); + time_start = get_timer(0); - if (!loop) - break; - } while (!dq); + do { + dq = qbman_swp_dqrr_next(swp); + } while (get_timer(time_start) < timeo && !dq); if (dq) { /* Check for valid frame. If not sent a consume @@ -112,7 +119,7 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) debug("No frame delivered\n"); qbman_swp_dqrr_consume(swp, dq); - break; + continue; } fd = ldpaa_dq_fd(dq); @@ -121,92 +128,9 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) ldpaa_eth_rx(priv, fd); qbman_swp_dqrr_consume(swp, dq); break; - } - } - - return err; -} - -static void ldpaa_eth_tx_conf(struct ldpaa_eth_priv *priv, - const struct dpaa_fd *fd) -{ - uint64_t fd_addr; - struct ldpaa_fas *fas; - uint32_t status, err; - struct qbman_release_desc releasedesc; - struct qbman_swp *swp = dflt_dpio->sw_portal; - - fd_addr = ldpaa_fd_get_addr(fd); - - - debug("TX Conf frame:data addr=0x%p\n", (u64 *)fd_addr); - - /* Check the status from the Frame Annotation */ - if (fd->simple.frc & LDPAA_FD_FRC_FASV) { - fas = (struct ldpaa_fas *) - ((uint8_t *)(fd_addr) + - priv->buf_layout.private_data_size); - status = le32_to_cpu(fas->status); - if (status & LDPAA_ETH_TXCONF_ERR_MASK) { - printf("TxConf frame error(s): 0x%08x\n", - status & LDPAA_ETH_TXCONF_ERR_MASK); - } - } - - qbman_release_desc_clear(&releasedesc); - qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); - do { - /* Release buffer into the QBMAN */ - err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); - } while (err == -EBUSY); -} - -static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv) -{ - const struct ldpaa_dq *dq; - const struct dpaa_fd *fd; - int err = 0; - int i = 5, status, loop = 20; - static struct qbman_pull_desc pulldesc; - struct qbman_swp *swp = dflt_dpio->sw_portal; - - while (--i) { - qbman_pull_desc_clear(&pulldesc); - qbman_pull_desc_set_numframes(&pulldesc, 1); - qbman_pull_desc_set_fq(&pulldesc, priv->tx_conf_fqid); - - err = qbman_swp_pull(swp, &pulldesc); - if (err < 0) { - printf("Dequeue TX conf frames error:0x%08x\n", err); - continue; - } - - do { - loop--; - dq = qbman_swp_dqrr_next(swp); - - if (!loop) - break; - } while (!dq); - - if (dq) { - /* Check for valid frame. If not sent a consume - * confirmation to QBMAN otherwise give it to NADK - * application and then send consume confirmation to - * QBMAN. - */ - status = (uint8_t)ldpaa_dq_flags(dq); - if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) { - debug("Dequeue TX conf frames:"); - debug("No frame is delivered\n"); - - qbman_swp_dqrr_consume(swp, dq); - break; - } - fd = ldpaa_dq_fd(dq); - - ldpaa_eth_tx_conf(priv, fd); - qbman_swp_dqrr_consume(swp, dq); + } else { + err = -ENODATA; + debug("No DQRR entries\n"); break; } } @@ -220,8 +144,11 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) struct dpaa_fd fd; u64 buffer_start; int data_offset, err; + u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; + u32 time_start; struct qbman_swp *swp = dflt_dpio->sw_portal; struct qbman_eq_desc ed; + struct qbman_release_desc releasedesc; /* Setup the FD fields */ memset(&fd, 0, sizeof(fd)); @@ -257,15 +184,34 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) qbman_eq_desc_clear(&ed); qbman_eq_desc_set_no_orp(&ed, 0); qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0); - err = qbman_swp_enqueue(swp, &ed, (const struct qbman_fd *)(&fd)); - if (err < 0) + + time_start = get_timer(0); + + while (get_timer(time_start) < timeo) { + err = qbman_swp_enqueue(swp, &ed, + (const struct qbman_fd *)(&fd)); + if (err != -EBUSY) + break; + } + + if (err < 0) { printf("error enqueueing Tx frame\n"); + goto error; + } + + return err; - mdelay(1); +error: + qbman_release_desc_clear(&releasedesc); + qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); + time_start = get_timer(0); + do { + /* Release buffer into the QBMAN */ + err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1); + } while (get_timer(time_start) < timeo && err == -EBUSY); - err = ldpaa_eth_pull_dequeue_tx_conf(priv); - if (err < 0) - printf("error Tx Conf frame\n"); + if (err == -EBUSY) + printf("TX data: QBMAN buffer release fails\n"); return err; } @@ -274,7 +220,6 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) { struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; struct dpni_queue_attr rx_queue_attr; - struct dpni_tx_flow_attr tx_flow_attr; uint8_t mac_addr[6]; int err; @@ -295,8 +240,8 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) if (err) goto err_bind; - err = dpni_get_primary_mac_addr(dflt_mc_io, priv->dpni_handle, - mac_addr); + err = dpni_get_primary_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpni_handle, mac_addr); if (err) { printf("dpni_get_primary_mac_addr() failed\n"); return err; @@ -323,15 +268,15 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) priv->phydev->duplex = DUPLEX_FULL; #endif - err = dpni_enable(dflt_mc_io, priv->dpni_handle); + err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpni_handle); if (err < 0) { printf("dpni_enable() failed\n"); return err; } /* TODO: support multiple Rx flows */ - err = dpni_get_rx_flow(dflt_mc_io, priv->dpni_handle, 0, 0, - &rx_queue_attr); + err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpni_handle, + 0, 0, &rx_queue_attr); if (err) { printf("dpni_get_rx_flow() failed\n"); goto err_rx_flow; @@ -339,34 +284,25 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) priv->rx_dflt_fqid = rx_queue_attr.fqid; - err = dpni_get_qdid(dflt_mc_io, priv->dpni_handle, &priv->tx_qdid); + err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpni_handle, + &priv->tx_qdid); if (err) { printf("dpni_get_qdid() failed\n"); goto err_qdid; } - err = dpni_get_tx_flow(dflt_mc_io, priv->dpni_handle, priv->tx_flow_id, - &tx_flow_attr); - if (err) { - printf("dpni_get_tx_flow() failed\n"); - goto err_tx_flow; - } - - priv->tx_conf_fqid = tx_flow_attr.conf_err_attr.queue_attr.fqid; - if (!priv->phydev->link) printf("%s: No link.\n", priv->phydev->dev->name); return priv->phydev->link ? 0 : -1; -err_tx_flow: err_qdid: err_rx_flow: - dpni_disable(dflt_mc_io, priv->dpni_handle); + dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpni_handle); err_bind: ldpaa_dpbp_free(); err_dpbp_setup: - dpni_close(dflt_mc_io, priv->dpni_handle); + dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpni_handle); err_dpni_setup: return err; } @@ -380,7 +316,7 @@ static void ldpaa_eth_stop(struct eth_device *net_dev) (net_dev->state == ETH_STATE_INIT)) return; /* Stop Tx and Rx traffic */ - err = dpni_disable(dflt_mc_io, priv->dpni_handle); + err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpni_handle); if (err < 0) printf("dpni_disable() failed\n"); @@ -389,8 +325,8 @@ static void ldpaa_eth_stop(struct eth_device *net_dev) #endif ldpaa_dpbp_free(); - dpni_reset(dflt_mc_io, priv->dpni_handle); - dpni_close(dflt_mc_io, priv->dpni_handle); + dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpni_handle); + dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpni_handle); } static void ldpaa_dpbp_drain_cnt(int count) @@ -484,20 +420,21 @@ static int ldpaa_dpbp_setup(void) { int err; - err = dpbp_open(dflt_mc_io, dflt_dpbp->dpbp_attr.id, + err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id, &dflt_dpbp->dpbp_handle); if (err) { printf("dpbp_open() failed\n"); goto err_open; } - err = dpbp_enable(dflt_mc_io, dflt_dpbp->dpbp_handle); + err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); if (err) { printf("dpbp_enable() failed\n"); goto err_enable; } - err = dpbp_get_attributes(dflt_mc_io, dflt_dpbp->dpbp_handle, + err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, + dflt_dpbp->dpbp_handle, &dflt_dpbp->dpbp_attr); if (err) { printf("dpbp_get_attributes() failed\n"); @@ -515,9 +452,9 @@ static int ldpaa_dpbp_setup(void) err_seed: err_get_attr: - dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle); + dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); err_enable: - dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle); + dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); err_open: return err; } @@ -525,9 +462,9 @@ err_open: static void ldpaa_dpbp_free(void) { ldpaa_dpbp_drain(); - dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle); - dpbp_reset(dflt_mc_io, dflt_dpbp->dpbp_handle); - dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle); + dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); + dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); + dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle); } static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) @@ -535,14 +472,15 @@ static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) int err; /* and get a handle for the DPNI this interface is associate with */ - err = dpni_open(dflt_mc_io, priv->dpni_id, &priv->dpni_handle); + err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpni_id, + &priv->dpni_handle); if (err) { printf("dpni_open() failed\n"); goto err_open; } - err = dpni_get_attributes(dflt_mc_io, priv->dpni_handle, - &priv->dpni_attrs); + err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpni_handle, &priv->dpni_attrs); if (err) { printf("dpni_get_attributes() failed (err=%d)\n", err); goto err_get_attr; @@ -556,8 +494,8 @@ static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) priv->buf_layout.pass_frame_status = true; priv->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE; /* ...rx, ... */ - err = dpni_set_rx_buffer_layout(dflt_mc_io, priv->dpni_handle, - &priv->buf_layout); + err = dpni_set_rx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpni_handle, &priv->buf_layout); if (err) { printf("dpni_set_rx_buffer_layout() failed"); goto err_buf_layout; @@ -565,8 +503,8 @@ static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) /* ... tx, ... */ priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PARSER_RESULT; - err = dpni_set_tx_buffer_layout(dflt_mc_io, priv->dpni_handle, - &priv->buf_layout); + err = dpni_set_tx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpni_handle, &priv->buf_layout); if (err) { printf("dpni_set_tx_buffer_layout() failed"); goto err_buf_layout; @@ -574,7 +512,8 @@ static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) /* ... tx-confirm. */ priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; - err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, priv->dpni_handle, + err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpni_handle, &priv->buf_layout); if (err) { printf("dpni_set_tx_conf_buffer_layout() failed"); @@ -584,8 +523,8 @@ static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) /* Now that we've set our tx buffer layout, retrieve the minimum * required tx data offset. */ - err = dpni_get_tx_data_offset(dflt_mc_io, priv->dpni_handle, - &priv->tx_data_offset); + err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpni_handle, &priv->tx_data_offset); if (err) { printf("dpni_get_tx_data_offset() failed\n"); goto err_data_offset; @@ -603,7 +542,7 @@ static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) err_data_offset: err_buf_layout: err_get_attr: - dpni_close(dflt_mc_io, priv->dpni_handle); + dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpni_handle); err_open: return err; } @@ -617,7 +556,8 @@ static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) pools_params.num_dpbp = 1; pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id; pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE; - err = dpni_set_pools(dflt_mc_io, priv->dpni_handle, &pools_params); + err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpni_handle, + &pools_params); if (err) { printf("dpni_set_pools() failed\n"); return err; @@ -626,7 +566,10 @@ static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) priv->tx_flow_id = DPNI_NEW_FLOW_ID; memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow)); - err = dpni_set_tx_flow(dflt_mc_io, priv->dpni_handle, + dflt_tx_flow.options = DPNI_TX_FLOW_OPT_ONLY_TX_ERROR; + dflt_tx_flow.conf_err_cfg.use_default_queue = 0; + dflt_tx_flow.conf_err_cfg.errors_only = 1; + err = dpni_set_tx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpni_handle, &priv->tx_flow_id, &dflt_tx_flow); if (err) { printf("dpni_set_tx_flow() failed\n");