
Hi Prabhakar,
On Sat, Jun 27, 2015 at 11:38 PM, Prabhakar Kushwaha prabhakar@freescale.com wrote:
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
driver/ldpaa_eth:Avoid infinite loop in QBMAN buf release
Change infinite loop mechanism to timer based polling.
Changes for v2: Sending as it is for patchset Changes for v3: Incorporated Joe Hershberger's comments - Squash with "driver/ldpaa_eth:Avoid infinite loop in QBMAN buf release" - use err instead of calling get_timer() again
drivers/net/ldpaa_eth/ldpaa_eth.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 5636511..275e316 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");
I asked you to squash the "fix to ldpaa_eth_tx", not this otherwise-unrelated change to ldpaa_eth_rx(). Please put this part back in a separate patch.
return;
}
@@ -221,8 +228,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 +268,18 @@ 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));
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");
You no longer have any place that you indicate this error to the user... It seems you should have this either here or below in the error: case.
goto error; mdelay(1);
@@ -269,6 +288,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)
1.9.1
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot