[U-Boot] [PATCH 3/3] net: xilinx_axi_emac: Add support for non processor mode

Michal Simek michal.simek at xilinx.com
Thu Nov 9 15:27:14 UTC 2017


From: Siva Durga Prasad Paladugu <sivadur at xilinx.com>

Add support for non processor mode, this mode doesn't have
access to some of the registers and hence this patch
bypasses it and also length has to be calculated from
status instead of app4 in this mode.

Signed-off-by: Siva Durga Prasad Paladugu <sivadur at xilinx.com>
Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

 drivers/net/xilinx_axi_emac.c | 41 +++++++++++++++++++++++++++++------------
 1 file changed, 29 insertions(+), 12 deletions(-)

diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c
index 4f2cef8a38d0..7761cd5d4e41 100644
--- a/drivers/net/xilinx_axi_emac.c
+++ b/drivers/net/xilinx_axi_emac.c
@@ -51,6 +51,8 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #define XAE_MDIO_DIV_DFT	29	/* Default MDIO clock divisor */
 
+#define XAXIDMA_BD_STS_ACTUAL_LEN_MASK	0x007FFFFF /* Actual len */
+
 /* DMA macros */
 /* Bitmasks of XAXIDMA_CR_OFFSET register */
 #define XAXIDMA_CR_RUNSTOP_MASK	0x00000001 /* Start/stop DMA channel */
@@ -90,6 +92,7 @@ struct axidma_priv {
 	phy_interface_t interface;
 	struct phy_device *phydev;
 	struct mii_dev *bus;
+	u8 eth_hasnobuf;
 };
 
 /* BD descriptors */
@@ -359,17 +362,23 @@ static int axi_ethernet_init(struct axidma_priv *priv)
 	 * for the Sgmii and 1000BaseX PHY interfaces. No other register reads
 	 * will be valid until this bit is valid.
 	 * The bit is always a 1 for all other PHY interfaces.
+	 * Interrupt status and enable registers are not available in non
+	 * processor mode and hence bypass in this mode
 	 */
-	err = wait_for_bit(__func__, (const u32 *)&regs->is,
-			   XAE_INT_MGTRDY_MASK, true, 200, false);
-	if (err) {
-		printf("%s: Timeout\n", __func__);
-		return 1;
-	}
+	if (!priv->eth_hasnobuf) {
+		err = wait_for_bit(__func__, (const u32 *)&regs->is,
+				   XAE_INT_MGTRDY_MASK, true, 200, false);
+		if (err) {
+			printf("%s: Timeout\n", __func__);
+			return 1;
+		}
 
-	/* Stop the device and reset HW */
-	/* Disable interrupts */
-	out_be32(&regs->ie, 0);
+		/*
+		 * Stop the device and reset HW
+		 * Disable interrupts
+		 */
+		out_be32(&regs->ie, 0);
+	}
 
 	/* Disable the receiver */
 	out_be32(&regs->rcw1, in_be32(&regs->rcw1) & ~XAE_RCW1_RX_MASK);
@@ -378,8 +387,10 @@ static int axi_ethernet_init(struct axidma_priv *priv)
 	 * Stopping the receiver in mid-packet causes a dropped packet
 	 * indication from HW. Clear it.
 	 */
-	/* Set the interrupt status register to clear the interrupt */
-	out_be32(&regs->is, XAE_INT_RXRJECT_MASK);
+	if (!priv->eth_hasnobuf) {
+		/* Set the interrupt status register to clear the interrupt */
+		out_be32(&regs->is, XAE_INT_RXRJECT_MASK);
+	}
 
 	/* Setup HW */
 	/* Set default MDIO divisor */
@@ -579,8 +590,11 @@ static int axiemac_recv(struct udevice *dev, int flags, uchar **packetp)
 	temp = in_be32(&priv->dmarx->control);
 	temp &= ~XAXIDMA_IRQ_ALL_MASK;
 	out_be32(&priv->dmarx->control, temp);
+	if (!priv->eth_hasnobuf)
+		length = rx_bd.app4 & 0xFFFF; /* max length mask */
+	else
+		length = rx_bd.status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK;
 
-	length = rx_bd.app4 & 0xFFFF; /* max length mask */
 #ifdef DEBUG
 	print_buffer(&rxframe, &rxframe[0], 1, length, 16);
 #endif
@@ -718,6 +732,9 @@ static int axi_emac_ofdata_to_platdata(struct udevice *dev)
 	}
 	priv->interface = pdata->phy_interface;
 
+	priv->eth_hasnobuf = fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
+					     "xlnx,eth-hasnobuf");
+
 	printf("AXI EMAC: %lx, phyaddr %d, interface %s\n", (ulong)priv->iobase,
 	       priv->phyaddr, phy_string_for_interface(priv->interface));
 
-- 
1.9.1



More information about the U-Boot mailing list