mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-05-05 12:46:14 +02:00
net: zynq_gem: reinitialize RX BDs on every init
Reinitialize RX BDs and rewrite rxqbase on every init instead of only on the first init. This ensures a clean BD state on every init for all GEM configurations. For AMD Versal Gen 2 10GBE this is required since the USX block resets the RX DMA pointer to rxqbase on each init, so BDs must be rebuilt each time to stay in sync with hardware. Signed-off-by: Pranav Tilak <pranav.vinaytilak@amd.com> Signed-off-by: Michal Simek <michal.simek@amd.com> Link: https://lore.kernel.org/r/20260410093018.1461732-4-pranav.vinaytilak@amd.com
This commit is contained in:
parent
0443deb428
commit
89c269154b
@ -474,28 +474,6 @@ static int zynq_gem_init(struct udevice *dev)
|
||||
for (i = 0; i < STAT_SIZE; i++)
|
||||
readl(®s->stat[i]);
|
||||
|
||||
/* Setup RxBD space */
|
||||
memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd));
|
||||
|
||||
for (i = 0; i < RX_BUF; i++) {
|
||||
priv->rx_bd[i].status = 0xF0000000;
|
||||
priv->rx_bd[i].addr =
|
||||
(lower_32_bits((ulong)(priv->rxbuffers)
|
||||
+ (i * PKTSIZE_ALIGN)));
|
||||
#if defined(CONFIG_PHYS_64BIT)
|
||||
priv->rx_bd[i].addr_hi =
|
||||
(upper_32_bits((ulong)(priv->rxbuffers)
|
||||
+ (i * PKTSIZE_ALIGN)));
|
||||
#endif
|
||||
}
|
||||
/* WRAP bit to last BD */
|
||||
priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
|
||||
/* Write RxBDs to IP */
|
||||
writel(lower_32_bits((ulong)priv->rx_bd), ®s->rxqbase);
|
||||
#if defined(CONFIG_PHYS_64BIT)
|
||||
writel(upper_32_bits((ulong)priv->rx_bd), ®s->upper_rxqbase);
|
||||
#endif
|
||||
|
||||
/* Setup for DMA Configuration register */
|
||||
writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr);
|
||||
|
||||
@ -524,6 +502,35 @@ static int zynq_gem_init(struct udevice *dev)
|
||||
priv->init++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reinitialize RX BDs on every init. The 10GBE USX block asserts
|
||||
* RX_SYNC_RESET during setup which resets the GEM RX DMA pointer
|
||||
* back to rxqbase, so BDs and rxqbase must be refreshed each time
|
||||
* to keep the hardware and driver ring indices in sync.
|
||||
*/
|
||||
priv->rxbd_current = 0;
|
||||
priv->rx_first_buf = 0;
|
||||
memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd));
|
||||
for (i = 0; i < RX_BUF; i++) {
|
||||
priv->rx_bd[i].status = 0xF0000000;
|
||||
priv->rx_bd[i].addr =
|
||||
(lower_32_bits((ulong)(priv->rxbuffers)
|
||||
+ (i * PKTSIZE_ALIGN)));
|
||||
#if defined(CONFIG_PHYS_64BIT)
|
||||
priv->rx_bd[i].addr_hi =
|
||||
(upper_32_bits((ulong)(priv->rxbuffers)
|
||||
+ (i * PKTSIZE_ALIGN)));
|
||||
#endif
|
||||
}
|
||||
/* WRAP bit to last BD */
|
||||
priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
|
||||
|
||||
/* Write RxBDs to IP */
|
||||
writel(lower_32_bits((ulong)priv->rx_bd), ®s->rxqbase);
|
||||
#if defined(CONFIG_PHYS_64BIT)
|
||||
writel(upper_32_bits((ulong)priv->rx_bd), ®s->upper_rxqbase);
|
||||
#endif
|
||||
|
||||
ret = phy_startup(priv->phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user