summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorIlya Yanok <yanok@emcraft.com>2011-11-28 06:37:30 +0000
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2011-12-06 23:59:35 +0100
commit82b772178d0f3d7f3cb246138197028795edf004 (patch)
tree4ef56c896e756904350f42929f40a6e19b7222fd /drivers
parent7c587d320d110e41008bc7b658655d22485d05a6 (diff)
downloadu-boot-imx-82b772178d0f3d7f3cb246138197028795edf004.zip
u-boot-imx-82b772178d0f3d7f3cb246138197028795edf004.tar.gz
u-boot-imx-82b772178d0f3d7f3cb246138197028795edf004.tar.bz2
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/davinci_emac.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 43c4373..2ac6874 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
@@ -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 */
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;
@@ -501,7 +522,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");
@@ -619,7 +640,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) {
@@ -663,14 +684,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;
@@ -688,7 +709,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;
@@ -696,10 +717,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;