Răsfoiți Sursa

davinci_emac: use internal addresses in buffer descriptors

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@emcraft.com>
Ilya Yanok 13 ani în urmă
părinte
comite
82b772178d
1 a modificat fișierele cu 30 adăugiri și 9 ștergeri
  1. 30 9
      drivers/net/davinci_emac.c

+ 30 - 9
drivers/net/davinci_emac.c

@@ -48,6 +48,27 @@
 unsigned int	emac_dbg = 0;
 unsigned int	emac_dbg = 0;
 #define debug_emac(fmt,args...)	if (emac_dbg) printf(fmt,##args)
 #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
 #ifdef DAVINCI_EMAC_GIG_ENABLE
 #define emac_gigabit_enable(phy_addr)	davinci_eth_gigabit_enable(phy_addr)
 #define emac_gigabit_enable(phy_addr)	davinci_eth_gigabit_enable(phy_addr)
 #else
 #else
@@ -448,7 +469,7 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	/* Create RX queue and set receive process in place */
 	/* Create RX queue and set receive process in place */
 	emac_rx_active_head = emac_rx_desc;
 	emac_rx_active_head = emac_rx_desc;
 	for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
 	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->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->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
 		rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
 		rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
@@ -501,7 +522,7 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
 	emac_gigabit_enable(active_phy_addr[index]);
 	emac_gigabit_enable(active_phy_addr[index]);
 
 
 	/* Start receive process */
 	/* 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");
 	debug_emac("- emac_open\n");
 
 
@@ -619,7 +640,7 @@ static int davinci_eth_send_packet (struct eth_device *dev,
 				      EMAC_CPPI_OWNERSHIP_BIT |
 				      EMAC_CPPI_OWNERSHIP_BIT |
 				      EMAC_CPPI_EOP_BIT);
 				      EMAC_CPPI_EOP_BIT);
 	/* Send the packet */
 	/* 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 */
 	/* Wait for packet to complete or link down */
 	while (1) {
 	while (1) {
@@ -663,14 +684,14 @@ static int davinci_eth_rcv_packet (struct eth_device *dev)
 		}
 		}
 
 
 		/* Ack received packet descriptor */
 		/* 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;
 		curr_desc = rx_curr_desc;
 		emac_rx_active_head =
 		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 (status & EMAC_CPPI_EOQ_BIT) {
 			if (emac_rx_active_head) {
 			if (emac_rx_active_head) {
-				writel((unsigned long)emac_rx_active_head,
+				writel(BD_TO_HW((ulong)emac_rx_active_head),
 				       &adap_emac->RX0HDP);
 				       &adap_emac->RX0HDP);
 			} else {
 			} else {
 				emac_rx_queue_active = 0;
 				emac_rx_queue_active = 0;
@@ -688,7 +709,7 @@ static int davinci_eth_rcv_packet (struct eth_device *dev)
 			emac_rx_active_head = curr_desc;
 			emac_rx_active_head = curr_desc;
 			emac_rx_active_tail = curr_desc;
 			emac_rx_active_tail = curr_desc;
 			if (emac_rx_queue_active != 0) {
 			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);
 				       &adap_emac->RX0HDP);
 				printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
 				printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
 				emac_rx_queue_active = 1;
 				emac_rx_queue_active = 1;
@@ -696,10 +717,10 @@ static int davinci_eth_rcv_packet (struct eth_device *dev)
 		} else {
 		} else {
 			tail_desc = emac_rx_active_tail;
 			tail_desc = emac_rx_active_tail;
 			emac_rx_active_tail = curr_desc;
 			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;
 			status = tail_desc->pkt_flag_len;
 			if (status & EMAC_CPPI_EOQ_BIT) {
 			if (status & EMAC_CPPI_EOQ_BIT) {
-				writel((unsigned long)curr_desc,
+				writel(BD_TO_HW((ulong)curr_desc),
 				       &adap_emac->RX0HDP);
 				       &adap_emac->RX0HDP);
 				status &= ~EMAC_CPPI_EOQ_BIT;
 				status &= ~EMAC_CPPI_EOQ_BIT;
 				tail_desc->pkt_flag_len = status;
 				tail_desc->pkt_flag_len = status;