[U-Boot] [PATCH v2 2/3] net: add higmacv300 Ethernet driver for HiSilicon platform
Shawn Guo
shawn.guo at linaro.org
Thu Mar 7 08:29:20 UTC 2019
On Wed, Mar 06, 2019 at 08:48:40PM +0000, Joe Hershberger wrote:
> On Tue, Mar 5, 2019 at 7:42 PM Shawn Guo <shawn.guo at linaro.org> wrote:
> >
> > On Tue, Mar 05, 2019 at 11:58:26PM +0000, Joe Hershberger wrote:
> > > > +static int higmac_recv(struct udevice *dev, int flags, uchar **packetp)
> > > > +{
> > > > + struct higmac_priv *priv = dev_get_priv(dev);
> > > > + struct higmac_desc *fqd = priv->rxfq;
> > > > + struct higmac_desc *bqd = priv->rxbq;
> > > > + int fqw_pos, fqr_pos, bqw_pos, bqr_pos;
> > > > + int timeout = 100000;
> > > > + int len = 0;
> > > > + int space;
> > > > + int i;
> > > > +
> > > > + fqw_pos = DESC_CNT(readl(priv->base + RX_FQ_WR_ADDR));
> > > > + fqr_pos = DESC_CNT(readl(priv->base + RX_FQ_RD_ADDR));
> > > > +
> > > > + if (fqw_pos >= fqr_pos)
> > > > + space = RX_DESC_NUM - (fqw_pos - fqr_pos);
> > > > + else
> > > > + space = fqr_pos - fqw_pos;
> > > > +
> > > > + /* Leave one free to distinguish full filled from empty buffer */
> > > > + for (i = 0; i < space - 1; i++) {
> > > > + fqd = priv->rxfq + fqw_pos;
> > > > + invalidate_dcache_range(fqd->buf_addr,
> > > > + fqd->buf_addr + MAC_MAX_FRAME_SIZE);
> > > > +
> > > > + if (++fqw_pos >= RX_DESC_NUM)
> > > > + fqw_pos = 0;
> > > > +
> > > > + writel(DESC_BYTE(fqw_pos), priv->base + RX_FQ_WR_ADDR);
> > > > + }
> > > > +
> > > > + bqr_pos = DESC_CNT(readl(priv->base + RX_BQ_RD_ADDR));
> > > > + bqd += bqr_pos;
> > > > + /* BQ is only ever written by GMAC */
> > > > + invalidate_desc(bqd);
> > > > +
> > > > + do {
> > > > + bqw_pos = DESC_CNT(readl(priv->base + RX_BQ_WR_ADDR));
> > > > + udelay(1);
> > > > + } while (--timeout && bqw_pos == bqr_pos);
> > >
> > > Did you look into using wait bit macros?
> >
> > I may miss your point, but this is not a loop waiting for some bits set
> > or clear. It's waiting for a given number.
>
> OK, I see that, thanks. Should you make these "breakable" in the same
> way that wait_for_bit_* does? The timeout seems quite long.
I assume that you mean the "breakable" as user interaction (CTRL-C)?
I'm not sure 100000 us (0.1 s) is so long for user to break.
<snip>
> > > > + reset_assert(&priv->rst_phy);
> > > > + mdelay(30);
> > >
> > > Why is this reasserted?
> >
> > I have to admit this is a bit hackish. Ideally, the reset sequence
> > should be: deassert -> assert -> deassert. But this reset signal gets
> > an opposite polarity than others that reset driver handles. I can add a
> > comment to explain it if you can tolerate this little hack, or I will
> > add polarity support to reset driver to handle this phy reset quirk.
> > Please let me know your preference.
>
> I would prefer a polarity to be defined in the DT for this reset.
OK, I will implement it in v3. Thanks for the comment.
Shawn
More information about the U-Boot
mailing list