summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorPrabhakar Kushwaha <prabhakar@freescale.com>2015-07-02 11:29:05 +0530
committerYork Sun <yorksun@freescale.com>2015-07-20 11:44:37 -0700
commite48df52b69069dac7f00841fc89701604c5f1bef (patch)
tree97c1f5307056476dfef673364132f636ba4c2078 /drivers/net
parent70e52d211533c45f0d26c4d87cbeee31560fbe04 (diff)
downloadu-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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_eth.c32
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)