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 <ya...@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 7a2527c..f65108d 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(phy_addr) davinci_eth_gigabit_enable(phy_addr) #else @@ -440,7 +461,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; @@ -493,7 +514,7 @@ static int davinci_eth_open(struct eth_device *dev, bd_t *bis) emac_gigabit_enable(active_phy_addr[index]); /* 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"); @@ -611,7 +632,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) { @@ -655,14 +676,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; @@ -680,7 +701,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; @@ -688,10 +709,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.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot