From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marek Vasut Date: Thu, 21 Aug 2014 18:22:33 +0200 Subject: [U-Boot] [PATCH v3 2/2] net: fec_mxc: Poll FEC_TBD_READY after polling TDAR In-Reply-To: <1408637529-31170-2-git-send-email-fabio.estevam@freescale.com> References: <1408637529-31170-1-git-send-email-fabio.estevam@freescale.com> <1408637529-31170-2-git-send-email-fabio.estevam@freescale.com> Message-ID: <201408211822.33946.marex@denx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On Thursday, August 21, 2014 at 06:12:09 PM, Fabio Estevam wrote: > When testing the FEC driver on a mx6solox we noticed that the TDAR bit gets > always cleared prior then the READY bit is set in the last BD, which causes > FEC transmission to fail. > > As explained by Ye Li: > > "The TDAR bit is set when the descriptors are all out from TX ring, but the > descriptor properly is in transmitting not READY. These are two signals, > and in Ic simulation, we found the TDAR always clear prior than the READY > bit of last BD. In mx6solox, we use a latest version of FEC IP. It looks > the intrinsic behave of TDAR bit is changed in this FEC version, not any > bug in mx6sx." > > Fix this by polling the READY bit of BD after the TDAR polling, which > covers the mx6solox case and does not harm for the other SoCs. > > Signed-off-by: Fabio Estevam > --- > Changes since v2: > - Poll FEC_TBD_READY after polling TDAR > > drivers/net/fec_mxc.c | 14 ++++++++++++-- > 1 file changed, 12 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c > index 56178d4..3050e58 100644 > --- a/drivers/net/fec_mxc.c > +++ b/drivers/net/fec_mxc.c > @@ -719,12 +719,22 @@ static int fec_send(struct eth_device *dev, void > *packet, int length) break; > } > > + if (!timeout) { > + ret = -EINVAL; > + goto out; > + } > + > + timeout = FEC_XFER_TIMEOUT; > + while (--timeout) { > + if (!(readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY)) This will never work, because you never invalidate the memory over the DMA descriptor here. > + break; > + } > + > if (!timeout) > ret = -EINVAL; > > +out: > invalidate_dcache_range(addr, addr + size); And here you invalidate it for no reason ;-) > - if (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) > - ret = -EINVAL; > > debug("fec_send: status 0x%x index %d ret %i\n", > readw(&fec->tbd_base[fec->tbd_index].status), Best regards, Marek Vasut