#include <net.h>
#include <netdev.h>
#include <malloc.h>
+#include <miiphy.h>
#include <linux/mii.h>
#include <asm/io.h>
return MACB_BFEXT(DATA, frame);
}
+#if defined(CONFIG_CMD_MII)
+
+int macb_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value)
+{
+ struct eth_device *dev = eth_get_dev_by_name(devname);
+ struct macb_device *macb = to_macb(dev);
+
+ if ( macb->phy_addr != phy_adr )
+ return -1;
+
+ *value = macb_mdio_read(macb, reg);
+
+ return 0;
+}
+
+int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value)
+{
+ struct eth_device *dev = eth_get_dev_by_name(devname);
+ struct macb_device *macb = to_macb(dev);
+
+ if ( macb->phy_addr != phy_adr )
+ return -1;
+
+ macb_mdio_write(macb, reg, value);
+
+ return 0;
+}
+#endif
+
+
#if defined(CONFIG_CMD_NET)
static int macb_send(struct eth_device *netdev, volatile void *packet,
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) {
{
struct macb_device *macb = to_macb(netdev);
unsigned long paddr;
- u32 hwaddr_bottom;
- u16 hwaddr_top;
int i;
/*
macb_writel(macb, RBQP, macb->rx_ring_dma);
macb_writel(macb, TBQP, macb->tx_ring_dma);
- /* set hardware address */
- hwaddr_bottom = cpu_to_le32(*((u32 *)netdev->enetaddr));
- macb_writel(macb, SA1B, hwaddr_bottom);
- hwaddr_top = cpu_to_le16(*((u16 *)(netdev->enetaddr + 4)));
- macb_writel(macb, SA1T, hwaddr_top);
-
/* choose RMII or MII mode. This depends on the board */
#ifdef CONFIG_RMII
-#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \
- defined(CONFIG_AT91SAM9263)
+#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \
+ defined(CONFIG_AT91SAM9263) || defined(CONFIG_AT91SAM9G20) || \
+ defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) || \
+ defined(CONFIG_AT91SAM9XE)
macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN));
#else
macb_writel(macb, USRIO, 0);
#endif
#else
-#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \
- defined(CONFIG_AT91SAM9263)
+#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \
+ defined(CONFIG_AT91SAM9263) || defined(CONFIG_AT91SAM9G20) || \
+ defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) || \
+ defined(CONFIG_AT91SAM9XE)
macb_writel(macb, USRIO, MACB_BIT(CLKEN));
#else
macb_writel(macb, USRIO, MACB_BIT(MII));
macb_writel(macb, NCR, MACB_BIT(CLRSTAT));
}
+static int macb_write_hwaddr(struct eth_device *dev)
+{
+ struct macb_device *macb = to_macb(dev);
+ u32 hwaddr_bottom;
+ u16 hwaddr_top;
+
+ /* set hardware address */
+ hwaddr_bottom = dev->enetaddr[0] | dev->enetaddr[1] << 8 |
+ dev->enetaddr[2] << 16 | dev->enetaddr[3] << 24;
+ macb_writel(macb, SA1B, hwaddr_bottom);
+ hwaddr_top = dev->enetaddr[4] | dev->enetaddr[5] << 8;
+ macb_writel(macb, SA1T, hwaddr_top);
+ return 0;
+}
+
int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
{
struct macb_device *macb;
netdev->halt = macb_halt;
netdev->send = macb_send;
netdev->recv = macb_recv;
+ netdev->write_hwaddr = macb_write_hwaddr;
/*
* Do some basic initialization so that we at least can talk
eth_register(netdev);
- return 0;
-}
-
-#endif
-
#if defined(CONFIG_CMD_MII)
-
-int miiphy_read(unsigned char addr, unsigned char reg, unsigned short *value)
-{
- unsigned long netctl;
- unsigned long netstat;
- unsigned long frame;
- int iflag;
-
- iflag = disable_interrupts();
- netctl = macb_readl(&macb, EMACB_NCR);
- netctl |= MACB_BIT(MPE);
- macb_writel(&macb, EMACB_NCR, netctl);
- if (iflag)
- enable_interrupts();
-
- frame = (MACB_BF(SOF, 1)
- | MACB_BF(RW, 2)
- | MACB_BF(PHYA, addr)
- | MACB_BF(REGA, reg)
- | MACB_BF(CODE, 2));
- macb_writel(&macb, EMACB_MAN, frame);
-
- do {
- netstat = macb_readl(&macb, EMACB_NSR);
- } while (!(netstat & MACB_BIT(IDLE)));
-
- frame = macb_readl(&macb, EMACB_MAN);
- *value = MACB_BFEXT(DATA, frame);
-
- iflag = disable_interrupts();
- netctl = macb_readl(&macb, EMACB_NCR);
- netctl &= ~MACB_BIT(MPE);
- macb_writel(&macb, EMACB_NCR, netctl);
- if (iflag)
- enable_interrupts();
-
- return 0;
-}
-
-int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value)
-{
- unsigned long netctl;
- unsigned long netstat;
- unsigned long frame;
- int iflag;
-
- iflag = disable_interrupts();
- netctl = macb_readl(&macb, EMACB_NCR);
- netctl |= MACB_BIT(MPE);
- macb_writel(&macb, EMACB_NCR, netctl);
- if (iflag)
- enable_interrupts();
-
- frame = (MACB_BF(SOF, 1)
- | MACB_BF(RW, 1)
- | MACB_BF(PHYA, addr)
- | MACB_BF(REGA, reg)
- | MACB_BF(CODE, 2)
- | MACB_BF(DATA, value));
- macb_writel(&macb, EMACB_MAN, frame);
-
- do {
- netstat = macb_readl(&macb, EMACB_NSR);
- } while (!(netstat & MACB_BIT(IDLE)));
-
- iflag = disable_interrupts();
- netctl = macb_readl(&macb, EMACB_NCR);
- netctl &= ~MACB_BIT(MPE);
- macb_writel(&macb, EMACB_NCR, netctl);
- if (iflag)
- enable_interrupts();
-
+ miiphy_register(netdev->name, macb_miiphy_read, macb_miiphy_write);
+#endif
return 0;
}