[U-Boot] [PATCH 2/8] davinci_emac: use internal addresses in buffer descriptors

Ilya Yanok yanok at emcraft.com
Thu Oct 13 23:11:46 CEST 2011


On AM35xx CPPI RAM had different addresses when accessed from the CPU
and from the EMAC. We need to account this to deal with the buffer
descriptors correctly.

Signed-off-by: Ilya Yanok <yanok at emcraft.com>
---
 drivers/net/davinci_emac.c |   39 ++++++++++++++++++++++++++++++---------
 1 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 0e980ec..3c442c4 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -48,6 +48,27 @@
 unsigned int	emac_dbg = 0;
 #define debug_emac(fmt,args...)	if (emac_dbg) printf(fmt,##args)
 
+#ifdef EMAC_HW_RAM_ADDR
+static inline unsigned long BD_TO_HW(unsigned long x)
+{
+	if (x == 0)
+		return 0;
+
+	return x - EMAC_WRAPPER_RAM_ADDR + EMAC_HW_RAM_ADDR;
+}
+
+static inline unsigned long HW_TO_BD(unsigned long x)
+{
+	if (x == 0)
+		return 0;
+
+	return x - EMAC_HW_RAM_ADDR + EMAC_WRAPPER_RAM_ADDR;
+}
+#else
+#define BD_TO_HW(x)	(x)
+#define HW_TO_BD(x)	(x)
+#endif
+
 #ifdef DAVINCI_EMAC_GIG_ENABLE
 #define emac_gigabit_enable()	davinci_eth_gigabit_enable()
 #else
@@ -389,7 +410,7 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	/* Create RX queue and set receive process in place */
 	emac_rx_active_head = emac_rx_desc;
 	for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
-		rx_desc->next = (u_int32_t)(rx_desc + 1);
+		rx_desc->next = BD_TO_HW((u_int32_t)(rx_desc + 1));
 		rx_desc->buffer = &emac_rx_buffers[cnt * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
 		rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
 		rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
@@ -441,7 +462,7 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	emac_gigabit_enable();
 
 	/* Start receive process */
-	writel((u_int32_t)emac_rx_desc, &adap_emac->RX0HDP);
+	writel(BD_TO_HW((u_int32_t)emac_rx_desc), &adap_emac->RX0HDP);
 
 	debug_emac("- emac_open\n");
 
@@ -559,7 +580,7 @@ static int davinci_eth_send_packet (struct eth_device *dev,
 				      EMAC_CPPI_OWNERSHIP_BIT |
 				      EMAC_CPPI_EOP_BIT);
 	/* Send the packet */
-	writel((unsigned long)emac_tx_desc, &adap_emac->TX0HDP);
+	writel(BD_TO_HW((unsigned long)emac_tx_desc), &adap_emac->TX0HDP);
 
 	/* Wait for packet to complete or link down */
 	while (1) {
@@ -603,14 +624,14 @@ static int davinci_eth_rcv_packet (struct eth_device *dev)
 		}
 
 		/* Ack received packet descriptor */
-		writel((unsigned long)rx_curr_desc, &adap_emac->RX0CP);
+		writel(BD_TO_HW((ulong)rx_curr_desc), &adap_emac->RX0CP);
 		curr_desc = rx_curr_desc;
 		emac_rx_active_head =
-			(volatile emac_desc *) rx_curr_desc->next;
+			(volatile emac_desc *) (HW_TO_BD(rx_curr_desc->next));
 
 		if (status & EMAC_CPPI_EOQ_BIT) {
 			if (emac_rx_active_head) {
-				writel((unsigned long)emac_rx_active_head,
+				writel(BD_TO_HW((ulong)emac_rx_active_head),
 				       &adap_emac->RX0HDP);
 			} else {
 				emac_rx_queue_active = 0;
@@ -628,7 +649,7 @@ static int davinci_eth_rcv_packet (struct eth_device *dev)
 			emac_rx_active_head = curr_desc;
 			emac_rx_active_tail = curr_desc;
 			if (emac_rx_queue_active != 0) {
-				writel((unsigned long)emac_rx_active_head,
+				writel(BD_TO_HW((ulong)emac_rx_active_head),
 				       &adap_emac->RX0HDP);
 				printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
 				emac_rx_queue_active = 1;
@@ -636,10 +657,10 @@ static int davinci_eth_rcv_packet (struct eth_device *dev)
 		} else {
 			tail_desc = emac_rx_active_tail;
 			emac_rx_active_tail = curr_desc;
-			tail_desc->next = (unsigned int) curr_desc;
+			tail_desc->next = BD_TO_HW((ulong) curr_desc);
 			status = tail_desc->pkt_flag_len;
 			if (status & EMAC_CPPI_EOQ_BIT) {
-				writel((unsigned long)curr_desc,
+				writel(BD_TO_HW((ulong)curr_desc),
 				       &adap_emac->RX0HDP);
 				status &= ~EMAC_CPPI_EOQ_BIT;
 				tail_desc->pkt_flag_len = status;
-- 
1.7.6.2



More information about the U-Boot mailing list