diff options
author | Prabhakar Kushwaha <prabhakar@freescale.com> | 2015-07-02 11:29:05 +0530 |
---|---|---|
committer | York Sun <yorksun@freescale.com> | 2015-07-20 11:44:37 -0700 |
commit | e48df52b69069dac7f00841fc89701604c5f1bef (patch) | |
tree | 97c1f5307056476dfef673364132f636ba4c2078 | |
parent | 70e52d211533c45f0d26c4d87cbeee31560fbe04 (diff) | |
download | u-boot-imx-e48df52b69069dac7f00841fc89701604c5f1bef.zip u-boot-imx-e48df52b69069dac7f00841fc89701604c5f1bef.tar.gz u-boot-imx-e48df52b69069dac7f00841fc89701604c5f1bef.tar.bz2 |
driver/ldpaa_eth: Retry enqueue if portal was busy
Do not immediately return if the enqueue function returns -EBUSY; re-try
mulitple times.
if timeout occures, release the buffer.
Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Reviewed-by: York Sun <yorksun@freescale.com>
-rw-r--r-- | drivers/net/ldpaa_eth/ldpaa_eth.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 5636511..82c0ce7 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -221,8 +221,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)); @@ -258,9 +261,20 @@ 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; + } mdelay(1); @@ -269,6 +283,20 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) printf("error Tx Conf frame\n"); return err; + +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); + + if (err == -EBUSY) + printf("TX data: QBMAN buffer release fails\n"); + + return err; } static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) |