|
@@ -82,6 +82,8 @@
|
|
#include <net.h>
|
|
#include <net.h>
|
|
#include <asm/processor.h>
|
|
#include <asm/processor.h>
|
|
#include <asm/io.h>
|
|
#include <asm/io.h>
|
|
|
|
+#include <asm/cache.h>
|
|
|
|
+#include <asm/mmu.h>
|
|
#include <commproc.h>
|
|
#include <commproc.h>
|
|
#include <ppc4xx.h>
|
|
#include <ppc4xx.h>
|
|
#include <ppc4xx_enet.h>
|
|
#include <ppc4xx_enet.h>
|
|
@@ -189,6 +191,10 @@ struct eth_device *emac0_dev = NULL;
|
|
#define ETH_IRQ_NUM(dev) (VECNUM_ETH0 + ((dev) * 2))
|
|
#define ETH_IRQ_NUM(dev) (VECNUM_ETH0 + ((dev) * 2))
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+#define MAL_RX_DESC_SIZE 2048
|
|
|
|
+#define MAL_TX_DESC_SIZE 2048
|
|
|
|
+#define MAL_ALLOC_SIZE (MAL_TX_DESC_SIZE + MAL_RX_DESC_SIZE)
|
|
|
|
+
|
|
/*-----------------------------------------------------------------------------+
|
|
/*-----------------------------------------------------------------------------+
|
|
* Prototypes and externals.
|
|
* Prototypes and externals.
|
|
*-----------------------------------------------------------------------------*/
|
|
*-----------------------------------------------------------------------------*/
|
|
@@ -354,8 +360,8 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
|
|
/* Ensure we setup mdio for this devnum and ONLY this devnum */
|
|
/* Ensure we setup mdio for this devnum and ONLY this devnum */
|
|
zmiifer |= (ZMII_FER_MDI) << ZMII_FER_V(devnum);
|
|
zmiifer |= (ZMII_FER_MDI) << ZMII_FER_V(devnum);
|
|
|
|
|
|
- out_be32(ZMII_FER, zmiifer);
|
|
|
|
- out_be32(RGMII_FER, rmiifer);
|
|
|
|
|
|
+ out_be32((void *)ZMII_FER, zmiifer);
|
|
|
|
+ out_be32((void *)RGMII_FER, rmiifer);
|
|
|
|
|
|
return ((int)pfc1);
|
|
return ((int)pfc1);
|
|
}
|
|
}
|
|
@@ -446,9 +452,15 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
|
|
}
|
|
}
|
|
#endif /* CONFIG_405EX */
|
|
#endif /* CONFIG_405EX */
|
|
|
|
|
|
|
|
+static inline void *malloc_aligned(u32 size, u32 align)
|
|
|
|
+{
|
|
|
|
+ return (void *)(((u32)malloc(size + align) + align - 1) &
|
|
|
|
+ ~(align - 1));
|
|
|
|
+}
|
|
|
|
+
|
|
static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
|
|
static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
|
|
{
|
|
{
|
|
- int i, j;
|
|
|
|
|
|
+ int i;
|
|
unsigned long reg = 0;
|
|
unsigned long reg = 0;
|
|
unsigned long msr;
|
|
unsigned long msr;
|
|
unsigned long speed;
|
|
unsigned long speed;
|
|
@@ -473,6 +485,8 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
|
|
defined(CONFIG_405EX)
|
|
defined(CONFIG_405EX)
|
|
unsigned long mfr;
|
|
unsigned long mfr;
|
|
#endif
|
|
#endif
|
|
|
|
+ u32 bd_cached;
|
|
|
|
+ u32 bd_uncached = 0;
|
|
|
|
|
|
EMAC_4XX_HW_PST hw_p = dev->priv;
|
|
EMAC_4XX_HW_PST hw_p = dev->priv;
|
|
|
|
|
|
@@ -768,11 +782,11 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* Set ZMII/RGMII speed according to the phy link speed */
|
|
/* Set ZMII/RGMII speed according to the phy link speed */
|
|
- reg = in_be32(ZMII_SSR);
|
|
|
|
|
|
+ reg = in_be32((void *)ZMII_SSR);
|
|
if ( (speed == 100) || (speed == 1000) )
|
|
if ( (speed == 100) || (speed == 1000) )
|
|
- out_be32(ZMII_SSR, reg | (ZMII_SSR_SP << ZMII_SSR_V (devnum)));
|
|
|
|
|
|
+ out_be32((void *)ZMII_SSR, reg | (ZMII_SSR_SP << ZMII_SSR_V (devnum)));
|
|
else
|
|
else
|
|
- out_be32(ZMII_SSR, reg & (~(ZMII_SSR_SP << ZMII_SSR_V (devnum))));
|
|
|
|
|
|
+ out_be32((void *)ZMII_SSR, reg & (~(ZMII_SSR_SP << ZMII_SSR_V (devnum))));
|
|
|
|
|
|
if ((devnum == 2) || (devnum == 3)) {
|
|
if ((devnum == 2) || (devnum == 3)) {
|
|
if (speed == 1000)
|
|
if (speed == 1000)
|
|
@@ -785,7 +799,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
|
|
printf("Error in RGMII Speed\n");
|
|
printf("Error in RGMII Speed\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
- out_be32(RGMII_SSR, reg);
|
|
|
|
|
|
+ out_be32((void *)RGMII_SSR, reg);
|
|
}
|
|
}
|
|
#endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */
|
|
#endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */
|
|
|
|
|
|
@@ -819,91 +833,60 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- /* Free "old" buffers */
|
|
|
|
- if (hw_p->alloc_tx_buf)
|
|
|
|
- free (hw_p->alloc_tx_buf);
|
|
|
|
- if (hw_p->alloc_rx_buf)
|
|
|
|
- free (hw_p->alloc_rx_buf);
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Malloc MAL buffer desciptors, make sure they are
|
|
* Malloc MAL buffer desciptors, make sure they are
|
|
* aligned on cache line boundary size
|
|
* aligned on cache line boundary size
|
|
* (401/403/IOP480 = 16, 405 = 32)
|
|
* (401/403/IOP480 = 16, 405 = 32)
|
|
* and doesn't cross cache block boundaries.
|
|
* and doesn't cross cache block boundaries.
|
|
*/
|
|
*/
|
|
- hw_p->alloc_tx_buf =
|
|
|
|
- (mal_desc_t *) malloc ((sizeof (mal_desc_t) * NUM_TX_BUFF) +
|
|
|
|
- ((2 * CFG_CACHELINE_SIZE) - 2));
|
|
|
|
- if (NULL == hw_p->alloc_tx_buf)
|
|
|
|
- return -1;
|
|
|
|
- if (((int) hw_p->alloc_tx_buf & CACHELINE_MASK) != 0) {
|
|
|
|
- hw_p->tx =
|
|
|
|
- (mal_desc_t *) ((int) hw_p->alloc_tx_buf +
|
|
|
|
- CFG_CACHELINE_SIZE -
|
|
|
|
- ((int) hw_p->
|
|
|
|
- alloc_tx_buf & CACHELINE_MASK));
|
|
|
|
- } else {
|
|
|
|
- hw_p->tx = hw_p->alloc_tx_buf;
|
|
|
|
- }
|
|
|
|
|
|
+ if (hw_p->first_init == 0) {
|
|
|
|
+ debug("*** Allocating descriptor memory ***\n");
|
|
|
|
|
|
- hw_p->alloc_rx_buf =
|
|
|
|
- (mal_desc_t *) malloc ((sizeof (mal_desc_t) * NUM_RX_BUFF) +
|
|
|
|
- ((2 * CFG_CACHELINE_SIZE) - 2));
|
|
|
|
- if (NULL == hw_p->alloc_rx_buf) {
|
|
|
|
- free(hw_p->alloc_tx_buf);
|
|
|
|
- hw_p->alloc_tx_buf = NULL;
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
|
|
+ bd_cached = (u32)malloc_aligned(MAL_ALLOC_SIZE, 4096);
|
|
|
|
+ if (!bd_cached) {
|
|
|
|
+ printf("%s: Error allocating MAL descriptor buffers!\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
|
|
- if (((int) hw_p->alloc_rx_buf & CACHELINE_MASK) != 0) {
|
|
|
|
- hw_p->rx =
|
|
|
|
- (mal_desc_t *) ((int) hw_p->alloc_rx_buf +
|
|
|
|
- CFG_CACHELINE_SIZE -
|
|
|
|
- ((int) hw_p->
|
|
|
|
- alloc_rx_buf & CACHELINE_MASK));
|
|
|
|
- } else {
|
|
|
|
- hw_p->rx = hw_p->alloc_rx_buf;
|
|
|
|
|
|
+#ifdef CONFIG_4xx_DCACHE
|
|
|
|
+ flush_dcache_range(bd_cached, bd_cached + MAL_ALLOC_SIZE);
|
|
|
|
+ hw_p->tx_phys = bd_cached;
|
|
|
|
+ hw_p->rx_phys = bd_cached + MAL_TX_DESC_SIZE;
|
|
|
|
+ bd_uncached = bis->bi_memsize;
|
|
|
|
+ program_tlb(bd_cached, bd_uncached, MAL_ALLOC_SIZE,
|
|
|
|
+ TLB_WORD2_I_ENABLE);
|
|
|
|
+#else
|
|
|
|
+ bd_uncached = bd_cached;
|
|
|
|
+#endif
|
|
|
|
+ hw_p->tx_phys = bd_cached;
|
|
|
|
+ hw_p->rx_phys = bd_cached + MAL_TX_DESC_SIZE;
|
|
|
|
+ hw_p->tx = (mal_desc_t *)(bd_uncached);
|
|
|
|
+ hw_p->rx = (mal_desc_t *)(bd_uncached + MAL_TX_DESC_SIZE);
|
|
|
|
+ debug("hw_p->tx=%08x, hw_p->rx=%08x\n", hw_p->tx, hw_p->rx);
|
|
}
|
|
}
|
|
|
|
|
|
for (i = 0; i < NUM_TX_BUFF; i++) {
|
|
for (i = 0; i < NUM_TX_BUFF; i++) {
|
|
hw_p->tx[i].ctrl = 0;
|
|
hw_p->tx[i].ctrl = 0;
|
|
hw_p->tx[i].data_len = 0;
|
|
hw_p->tx[i].data_len = 0;
|
|
- if (hw_p->first_init == 0) {
|
|
|
|
- hw_p->txbuf_ptr =
|
|
|
|
- (char *) malloc (ENET_MAX_MTU_ALIGNED);
|
|
|
|
- if (NULL == hw_p->txbuf_ptr) {
|
|
|
|
- free(hw_p->alloc_rx_buf);
|
|
|
|
- free(hw_p->alloc_tx_buf);
|
|
|
|
- hw_p->alloc_rx_buf = NULL;
|
|
|
|
- hw_p->alloc_tx_buf = NULL;
|
|
|
|
- for(j = 0; j < i; j++) {
|
|
|
|
- free(hw_p->tx[i].data_ptr);
|
|
|
|
- hw_p->tx[i].data_ptr = NULL;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ if (hw_p->first_init == 0)
|
|
|
|
+ hw_p->txbuf_ptr = malloc_aligned(MAL_ALLOC_SIZE,
|
|
|
|
+ L1_CACHE_BYTES);
|
|
hw_p->tx[i].data_ptr = hw_p->txbuf_ptr;
|
|
hw_p->tx[i].data_ptr = hw_p->txbuf_ptr;
|
|
if ((NUM_TX_BUFF - 1) == i)
|
|
if ((NUM_TX_BUFF - 1) == i)
|
|
hw_p->tx[i].ctrl |= MAL_TX_CTRL_WRAP;
|
|
hw_p->tx[i].ctrl |= MAL_TX_CTRL_WRAP;
|
|
hw_p->tx_run[i] = -1;
|
|
hw_p->tx_run[i] = -1;
|
|
-#if 0
|
|
|
|
- printf ("TX_BUFF %d @ 0x%08lx\n", i,
|
|
|
|
- (ulong) hw_p->tx[i].data_ptr);
|
|
|
|
-#endif
|
|
|
|
|
|
+ debug("TX_BUFF %d @ 0x%08lx\n", i, (u32)hw_p->tx[i].data_ptr);
|
|
}
|
|
}
|
|
|
|
|
|
for (i = 0; i < NUM_RX_BUFF; i++) {
|
|
for (i = 0; i < NUM_RX_BUFF; i++) {
|
|
hw_p->rx[i].ctrl = 0;
|
|
hw_p->rx[i].ctrl = 0;
|
|
hw_p->rx[i].data_len = 0;
|
|
hw_p->rx[i].data_len = 0;
|
|
- /* rx[i].data_ptr = (char *) &rx_buff[i]; */
|
|
|
|
- hw_p->rx[i].data_ptr = (char *) NetRxPackets[i];
|
|
|
|
|
|
+ hw_p->rx[i].data_ptr = (char *)NetRxPackets[i];
|
|
if ((NUM_RX_BUFF - 1) == i)
|
|
if ((NUM_RX_BUFF - 1) == i)
|
|
hw_p->rx[i].ctrl |= MAL_RX_CTRL_WRAP;
|
|
hw_p->rx[i].ctrl |= MAL_RX_CTRL_WRAP;
|
|
hw_p->rx[i].ctrl |= MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR;
|
|
hw_p->rx[i].ctrl |= MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR;
|
|
hw_p->rx_ready[i] = -1;
|
|
hw_p->rx_ready[i] = -1;
|
|
-#if 0
|
|
|
|
- printf ("RX_BUFF %d @ 0x%08lx\n", i, (ulong) hw_p->rx[i].data_ptr);
|
|
|
|
-#endif
|
|
|
|
|
|
+ debug("RX_BUFF %d @ 0x%08lx\n", i, (u32)hw_p->rx[i].data_ptr);
|
|
}
|
|
}
|
|
|
|
|
|
reg = 0x00000000;
|
|
reg = 0x00000000;
|
|
@@ -929,15 +912,15 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
|
|
case 1:
|
|
case 1:
|
|
/* setup MAL tx & rx channel pointers */
|
|
/* setup MAL tx & rx channel pointers */
|
|
#if defined (CONFIG_405EP) || defined (CONFIG_440EP) || defined (CONFIG_440GR)
|
|
#if defined (CONFIG_405EP) || defined (CONFIG_440EP) || defined (CONFIG_440GR)
|
|
- mtdcr (maltxctp2r, hw_p->tx);
|
|
|
|
|
|
+ mtdcr (maltxctp2r, hw_p->tx_phys);
|
|
#else
|
|
#else
|
|
- mtdcr (maltxctp1r, hw_p->tx);
|
|
|
|
|
|
+ mtdcr (maltxctp1r, hw_p->tx_phys);
|
|
#endif
|
|
#endif
|
|
#if defined(CONFIG_440)
|
|
#if defined(CONFIG_440)
|
|
mtdcr (maltxbattr, 0x0);
|
|
mtdcr (maltxbattr, 0x0);
|
|
mtdcr (malrxbattr, 0x0);
|
|
mtdcr (malrxbattr, 0x0);
|
|
#endif
|
|
#endif
|
|
- mtdcr (malrxctp1r, hw_p->rx);
|
|
|
|
|
|
+ mtdcr (malrxctp1r, hw_p->rx_phys);
|
|
/* set RX buffer size */
|
|
/* set RX buffer size */
|
|
mtdcr (malrcbs1, ENET_MAX_MTU_ALIGNED / 16);
|
|
mtdcr (malrcbs1, ENET_MAX_MTU_ALIGNED / 16);
|
|
break;
|
|
break;
|
|
@@ -946,17 +929,17 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
|
|
/* setup MAL tx & rx channel pointers */
|
|
/* setup MAL tx & rx channel pointers */
|
|
mtdcr (maltxbattr, 0x0);
|
|
mtdcr (maltxbattr, 0x0);
|
|
mtdcr (malrxbattr, 0x0);
|
|
mtdcr (malrxbattr, 0x0);
|
|
- mtdcr (maltxctp2r, hw_p->tx);
|
|
|
|
- mtdcr (malrxctp2r, hw_p->rx);
|
|
|
|
|
|
+ mtdcr (maltxctp2r, hw_p->tx_phys);
|
|
|
|
+ mtdcr (malrxctp2r, hw_p->rx_phys);
|
|
/* set RX buffer size */
|
|
/* set RX buffer size */
|
|
mtdcr (malrcbs2, ENET_MAX_MTU_ALIGNED / 16);
|
|
mtdcr (malrcbs2, ENET_MAX_MTU_ALIGNED / 16);
|
|
break;
|
|
break;
|
|
case 3:
|
|
case 3:
|
|
/* setup MAL tx & rx channel pointers */
|
|
/* setup MAL tx & rx channel pointers */
|
|
mtdcr (maltxbattr, 0x0);
|
|
mtdcr (maltxbattr, 0x0);
|
|
- mtdcr (maltxctp3r, hw_p->tx);
|
|
|
|
|
|
+ mtdcr (maltxctp3r, hw_p->tx_phys);
|
|
mtdcr (malrxbattr, 0x0);
|
|
mtdcr (malrxbattr, 0x0);
|
|
- mtdcr (malrxctp3r, hw_p->rx);
|
|
|
|
|
|
+ mtdcr (malrxctp3r, hw_p->rx_phys);
|
|
/* set RX buffer size */
|
|
/* set RX buffer size */
|
|
mtdcr (malrcbs3, ENET_MAX_MTU_ALIGNED / 16);
|
|
mtdcr (malrcbs3, ENET_MAX_MTU_ALIGNED / 16);
|
|
break;
|
|
break;
|
|
@@ -968,8 +951,8 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
|
|
mtdcr (maltxbattr, 0x0);
|
|
mtdcr (maltxbattr, 0x0);
|
|
mtdcr (malrxbattr, 0x0);
|
|
mtdcr (malrxbattr, 0x0);
|
|
#endif
|
|
#endif
|
|
- mtdcr (maltxctp0r, hw_p->tx);
|
|
|
|
- mtdcr (malrxctp0r, hw_p->rx);
|
|
|
|
|
|
+ mtdcr (maltxctp0r, hw_p->tx_phys);
|
|
|
|
+ mtdcr (malrxctp0r, hw_p->rx_phys);
|
|
/* set RX buffer size */
|
|
/* set RX buffer size */
|
|
mtdcr (malrcbs0, ENET_MAX_MTU_ALIGNED / 16);
|
|
mtdcr (malrcbs0, ENET_MAX_MTU_ALIGNED / 16);
|
|
break;
|
|
break;
|
|
@@ -1083,6 +1066,7 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr,
|
|
|
|
|
|
/* memcpy ((void *) &tx_buff[tx_slot], (const void *) ptr, len); */
|
|
/* memcpy ((void *) &tx_buff[tx_slot], (const void *) ptr, len); */
|
|
memcpy ((void *) hw_p->txbuf_ptr, (const void *) ptr, len);
|
|
memcpy ((void *) hw_p->txbuf_ptr, (const void *) ptr, len);
|
|
|
|
+ flush_dcache_range((u32)hw_p->txbuf_ptr, (u32)hw_p->txbuf_ptr + len);
|
|
|
|
|
|
/*-----------------------------------------------------------------------+
|
|
/*-----------------------------------------------------------------------+
|
|
* set TX Buffer busy, and send it
|
|
* set TX Buffer busy, and send it
|
|
@@ -1582,6 +1566,9 @@ static int ppc_4xx_eth_rx (struct eth_device *dev)
|
|
/* Pass the packet up to the protocol layers. */
|
|
/* Pass the packet up to the protocol layers. */
|
|
/* NetReceive(NetRxPackets[rxIdx], length - 4); */
|
|
/* NetReceive(NetRxPackets[rxIdx], length - 4); */
|
|
/* NetReceive(NetRxPackets[i], length); */
|
|
/* NetReceive(NetRxPackets[i], length); */
|
|
|
|
+ invalidate_dcache_range((u32)hw_p->rx[user_index].data_ptr,
|
|
|
|
+ (u32)hw_p->rx[user_index].data_ptr +
|
|
|
|
+ length - 4);
|
|
NetReceive (NetRxPackets[user_index], length - 4);
|
|
NetReceive (NetRxPackets[user_index], length - 4);
|
|
/* Free Recv Buffer */
|
|
/* Free Recv Buffer */
|
|
hw_p->rx[user_index].ctrl |= MAL_RX_CTRL_EMPTY;
|
|
hw_p->rx[user_index].ctrl |= MAL_RX_CTRL_EMPTY;
|