*/
#include <common.h>
-#if defined(CONFIG_MACB) \
- && (defined(CONFIG_CMD_NET) || defined(CONFIG_CMD_MII))
-
/*
* The u-boot networking stack is a little weird. It seems like the
* networking core allocates receive buffers up front without any
* allocate our own, but we need one such buffer in case a packet
* wraps around the DMA ring so that we have to copy it.
*
- * Therefore, define CFG_RX_ETH_BUFFER to 1 in the board-specific
+ * Therefore, define CONFIG_SYS_RX_ETH_BUFFER to 1 in the board-specific
* configuration header. This way, the core allocates one RX buffer
* and one TX buffer, each of which can hold a ethernet packet of
* maximum size.
*/
#include <net.h>
+#include <netdev.h>
#include <malloc.h>
#include <linux/mii.h>
#define barrier() asm volatile("" ::: "memory")
-#define CFG_MACB_RX_BUFFER_SIZE 4096
-#define CFG_MACB_RX_RING_SIZE (CFG_MACB_RX_BUFFER_SIZE / 128)
-#define CFG_MACB_TX_RING_SIZE 16
-#define CFG_MACB_TX_TIMEOUT 1000
-#define CFG_MACB_AUTONEG_TIMEOUT 5000000
+#define CONFIG_SYS_MACB_RX_BUFFER_SIZE 4096
+#define CONFIG_SYS_MACB_RX_RING_SIZE (CONFIG_SYS_MACB_RX_BUFFER_SIZE / 128)
+#define CONFIG_SYS_MACB_TX_RING_SIZE 16
+#define CONFIG_SYS_MACB_TX_TIMEOUT 1000
+#define CONFIG_SYS_MACB_AUTONEG_TIMEOUT 5000000
struct macb_dma_desc {
u32 addr;
ctrl = length & TXBUF_FRMLEN_MASK;
ctrl |= TXBUF_FRAME_END;
- if (tx_head == (CFG_MACB_TX_RING_SIZE - 1)) {
+ if (tx_head == (CONFIG_SYS_MACB_TX_RING_SIZE - 1)) {
ctrl |= TXBUF_WRAP;
macb->tx_head = 0;
} else
* I guess this is necessary because the networking core may
* re-use the transmit buffer as soon as we return...
*/
- for (i = 0; i <= CFG_MACB_TX_TIMEOUT; i++) {
+ for (i = 0; i <= CONFIG_SYS_MACB_TX_TIMEOUT; i++) {
barrier();
ctrl = macb->tx_ring[tx_head].ctrl;
if (ctrl & TXBUF_USED)
dma_unmap_single(packet, length, paddr);
- if (i <= CFG_MACB_TX_TIMEOUT) {
+ if (i <= CONFIG_SYS_MACB_TX_TIMEOUT) {
if (ctrl & TXBUF_UNDERRUN)
printf("%s: TX underrun\n", netdev->name);
if (ctrl & TXBUF_EXHAUSTED)
while (i > new_tail) {
macb->rx_ring[i].addr &= ~RXADDR_USED;
i++;
- if (i > CFG_MACB_RX_RING_SIZE)
+ if (i > CONFIG_SYS_MACB_RX_RING_SIZE)
i = 0;
}
if (wrapped) {
unsigned int headlen, taillen;
- headlen = 128 * (CFG_MACB_RX_RING_SIZE
+ headlen = 128 * (CONFIG_SYS_MACB_RX_RING_SIZE
- macb->rx_tail);
taillen = length - headlen;
memcpy((void *)NetRxPackets[0],
}
NetReceive(buffer, length);
- if (++rx_tail >= CFG_MACB_RX_RING_SIZE)
+ if (++rx_tail >= CONFIG_SYS_MACB_RX_RING_SIZE)
rx_tail = 0;
reclaim_rx_buffers(macb, rx_tail);
} else {
- if (++rx_tail >= CFG_MACB_RX_RING_SIZE) {
+ if (++rx_tail >= CONFIG_SYS_MACB_RX_RING_SIZE) {
wrapped = 1;
rx_tail = 0;
}
macb_mdio_write(macb, MII_BMCR, (BMCR_ANENABLE
| BMCR_ANRESTART));
- for (i = 0; i < CFG_MACB_AUTONEG_TIMEOUT / 100; i++) {
+ for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) {
status = macb_mdio_read(macb, MII_BMSR);
if (status & BMSR_ANEGCOMPLETE)
break;
netdev->name, status);
}
+#ifdef CONFIG_MACB_SEARCH_PHY
+static int macb_phy_find(struct macb_device *macb)
+{
+ int i;
+ u16 phy_id;
+
+ /* Search for PHY... */
+ for (i = 0; i < 32; i++) {
+ macb->phy_addr = i;
+ phy_id = macb_mdio_read(macb, MII_PHYSID1);
+ if (phy_id != 0xffff) {
+ printf("%s: PHY present at %d\n", macb->netdev.name, i);
+ return 1;
+ }
+ }
+
+ /* PHY isn't up to snuff */
+ printf("%s: PHY not found", macb->netdev.name);
+
+ return 0;
+}
+#endif /* CONFIG_MACB_SEARCH_PHY */
+
+
static int macb_phy_init(struct macb_device *macb)
{
struct eth_device *netdev = &macb->netdev;
int media, speed, duplex;
int i;
+#ifdef CONFIG_MACB_SEARCH_PHY
+ /* Auto-detect phy_addr */
+ if (!macb_phy_find(macb)) {
+ return 0;
+ }
+#endif /* CONFIG_MACB_SEARCH_PHY */
+
/* Check if the PHY is up to snuff... */
phy_id = macb_mdio_read(macb, MII_PHYSID1);
if (phy_id == 0xffff) {
/* Try to re-negotiate if we don't have link already. */
macb_phy_reset(macb);
- for (i = 0; i < CFG_MACB_AUTONEG_TIMEOUT / 100; i++) {
+ for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) {
status = macb_mdio_read(macb, MII_BMSR);
if (status & BMSR_LSTATUS)
break;
/* initialize DMA descriptors */
paddr = macb->rx_buffer_dma;
- for (i = 0; i < CFG_MACB_RX_RING_SIZE; i++) {
- if (i == (CFG_MACB_RX_RING_SIZE - 1))
+ for (i = 0; i < CONFIG_SYS_MACB_RX_RING_SIZE; i++) {
+ if (i == (CONFIG_SYS_MACB_RX_RING_SIZE - 1))
paddr |= RXADDR_WRAP;
macb->rx_ring[i].addr = paddr;
macb->rx_ring[i].ctrl = 0;
paddr += 128;
}
- for (i = 0; i < CFG_MACB_TX_RING_SIZE; i++) {
+ for (i = 0; i < CONFIG_SYS_MACB_TX_RING_SIZE; i++) {
macb->tx_ring[i].addr = 0;
- if (i == (CFG_MACB_TX_RING_SIZE - 1))
+ if (i == (CONFIG_SYS_MACB_TX_RING_SIZE - 1))
macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP;
else
macb->tx_ring[i].ctrl = TXBUF_USED;
/* choose RMII or MII mode. This depends on the board */
#ifdef CONFIG_RMII
-#ifdef CONFIG_AT91CAP9ADK
+#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \
+ defined(CONFIG_AT91SAM9263) || defined(CONFIG_AT91SAM9G20) || \
+ defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45)
macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN));
#else
macb_writel(macb, USRIO, 0);
#endif
#else
-#ifdef CONFIG_AT91CAP9ADK
+#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \
+ defined(CONFIG_AT91SAM9263) || defined(CONFIG_AT91SAM9G20) || \
+ defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45)
macb_writel(macb, USRIO, MACB_BIT(CLKEN));
#else
macb_writel(macb, USRIO, MACB_BIT(MII));
netdev = &macb->netdev;
- macb->rx_buffer = dma_alloc_coherent(CFG_MACB_RX_BUFFER_SIZE,
+ macb->rx_buffer = dma_alloc_coherent(CONFIG_SYS_MACB_RX_BUFFER_SIZE,
&macb->rx_buffer_dma);
- macb->rx_ring = dma_alloc_coherent(CFG_MACB_RX_RING_SIZE
+ macb->rx_ring = dma_alloc_coherent(CONFIG_SYS_MACB_RX_RING_SIZE
* sizeof(struct macb_dma_desc),
&macb->rx_ring_dma);
- macb->tx_ring = dma_alloc_coherent(CFG_MACB_TX_RING_SIZE
+ macb->tx_ring = dma_alloc_coherent(CONFIG_SYS_MACB_TX_RING_SIZE
* sizeof(struct macb_dma_desc),
&macb->tx_ring_dma);
}
#endif
-
-#endif /* CONFIG_MACB */