diff mbox

[U-Boot] Add support for ASIX's AX88783 ethernet chip

Message ID 1296495758-17784-1-git-send-email-lgxue@hotmail.com
State Superseded
Headers show

Commit Message

Joe Xue Jan. 31, 2011, 5:42 p.m. UTC
for more information about this chip, please check:
http://www.asix.com.tw/products.php?op=pItemdetail&PItemID=98;65;86&PLine=65

Signed-off-by: Joe Xue <lgxue@hotmail.com>

---
 README               |    7 +++++++
 drivers/net/Makefile |    1 +
 include/netdev.h     |    1 +
 3 files changed, 9 insertions(+), 0 deletions(-)

Comments

Stefano Babic Feb. 2, 2011, 6:02 p.m. UTC | #1
On 01/31/2011 06:42 PM, Joe Xue wrote:
> for more information about this chip, please check:
> http://www.asix.com.tw/products.php?op=pItemdetail&PItemID=98;65;86&PLine=65
> 
> Signed-off-by: Joe Xue <lgxue@hotmail.com>
> 

Please add a version number to your patch to make easier tracking which
is your last version.

Do not forget to add always the net Maintainer to CC (Wolfgang Denk), I
added him now.

> --- /dev/null
> +++ b/drivers/net/ax88783.c
> @@ -0,0 +1,297 @@
> +/*
> + *

You should drop this line

> +
> +static int ax88183_phy_initial(struct eth_device *dev)

You forget to replace the name of the function. It has still ax88183_

> +	/* phy init */
> +	tmp = readl(&reg->pcr);
> +	tmp |= PCR_PHY0_RESET_CLEAR;
> +
> +	writel(tmp, &reg->pcr);
> +	udelay(100000);

you already explained why you need such a long delay. It is not bad to
add your explanation as comment here, so everyone knows your answer.

> +static void ax88783_halt(struct eth_device *dev)
> +{
> +	unsigned int tmp;
> +	struct ax88783_reg *reg = (struct ax88783_reg *)dev->iobase;
> +	tmp = readl(&reg->pcr);
> +	writel((tmp | PCR_LOOP_BACK), &reg->pcr);
> +}

From the name it seems you set the controller in loopback, instead of
disabling it. Is it correct ?

> +
> +	res = eth_getenv_enetaddr("ethaddr", dev->enetaddr);
> +	if (!res) {
> +		puts("Please set your MAC address!");
> +		free(dev);
> +		return 0;
> +	}

This is wrong. A network driver should not call directly
eth_getenv_enetaddr, and you do not need. If you want to check the mac
addrsss, use is_valid_ether_addr() inside ax88783_init() before copying
the mac to the hardware.

> +
> +	res = ax88183_phy_initial(dev);

Name must be changed.

> diff --git a/drivers/net/ax88783.h b/drivers/net/ax88783.h
> new file mode 100644
> index 0000000..09ac9ed
> --- /dev/null
> +++ b/drivers/net/ax88783.h
> @@ -0,0 +1,100 @@
> +/*
> + *

As explained, all headers start with copyright on the second line. Drop
this line.

Best regards,
Stefano Babic
Joe Xue Feb. 4, 2011, 2:47 p.m. UTC | #2
Than you Stefano.

> Date: Wed, 2 Feb 2011 19:02:11 +0100
> From: sbabic@denx.de
> To: lgxue@hotmail.com
> CC: u-boot@lists.denx.de; wd@denx.de
> Subject: Re: [U-Boot] [PATCH] Add support for ASIX's AX88783 ethernet chip
> 
> On 01/31/2011 06:42 PM, Joe Xue wrote:
> > for more information about this chip, please check:
> > http://www.asix.com.tw/products.php?op=pItemdetail&PItemID=98;65;86&PLine=65
> > 
> > Signed-off-by: Joe Xue <lgxue@hotmail.com>
> > 
> 
> Please add a version number to your patch to make easier tracking which
> is your last version.
> 
Will add it.
> Do not forget to add always the net Maintainer to CC (Wolfgang Denk), I
> added him now.
> 
Not exactly understand your meaning. You mean I should add wd as maintainer to my code or just add him in mail.
> > --- /dev/null
> > +++ b/drivers/net/ax88783.c
> > @@ -0,0 +1,297 @@
> > +/*
> > + *
> 
> You should drop this line
> 
will drop it.
> > +
> > +static int ax88183_phy_initial(struct eth_device *dev)
> 
> You forget to replace the name of the function. It has still ax88183_
> 
will change, sorry for it.
> > +	/* phy init */
> > +	tmp = readl(&reg->pcr);
> > +	tmp |= PCR_PHY0_RESET_CLEAR;
> > +
> > +	writel(tmp, &reg->pcr);
> > +	udelay(100000);
> 
> you already explained why you need such a long delay. It is not bad to
> add your explanation as comment here, so everyone knows your answer.
> 
will do.
> > +static void ax88783_halt(struct eth_device *dev)
> > +{
> > +	unsigned int tmp;
> > +	struct ax88783_reg *reg = (struct ax88783_reg *)dev->iobase;
> > +	tmp = readl(&reg->pcr);
> > +	writel((tmp | PCR_LOOP_BACK), &reg->pcr);
> > +}
> 
> From the name it seems you set the controller in loopback, instead of
> disabling it. Is it correct ?
> 
mmn. I just make it can't receive the data outside.The other way is make it into sleep mode.
> > +
> > +	res = eth_getenv_enetaddr("ethaddr", dev->enetaddr);
> > +	if (!res) {
> > +		puts("Please set your MAC address!");
> > +		free(dev);
> > +		return 0;
> > +	}
> 
> This is wrong. A network driver should not call directly
> eth_getenv_enetaddr, and you do not need. If you want to check the mac
> addrsss, use is_valid_ether_addr() inside ax88783_init() before copying
> the mac to the hardware.
> 
I refer to the newest net driver patch ftgmac100.c, it uses this function to getmac address from environmental setting. and I checked the code eth_getenv_enetaddralso call the is_valid_ether_addr(). 
Anyway, will change it according to your advice.
> > +
> > +	res = ax88183_phy_initial(dev);
> 
> Name must be changed.
> 
will change.
> > diff --git a/drivers/net/ax88783.h b/drivers/net/ax88783.h
> > new file mode 100644
> > index 0000000..09ac9ed
> > --- /dev/null
> > +++ b/drivers/net/ax88783.h
> > @@ -0,0 +1,100 @@
> > +/*
> > + *
> 
> As explained, all headers start with copyright on the second line. Drop
> this line.
> 
Yes, thank you for your patience :-) 

> Best regards,
> Stefano Babic
Best wishes,
Joe
> 
> -- 
> =====================================================================
> DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office@denx.de
> =====================================================================
Stefano Babic Feb. 4, 2011, 3:23 p.m. UTC | #3
On 02/04/2011 03:47 PM, Joe XUE wrote:
>> Do not forget to add always the net Maintainer to CC (Wolfgang Denk), I
>> added him now.
>> 
> 
> Not exactly understand your meaning. You mean I should add wd as
> maintainer to my code or 
> just add him in mail.

Only add him in mail. He is the maintainer for net code.

>> From the name it seems you set the controller in loopback, instead of
>> disabling it. Is it correct ?
>> 
> 
> mmn. I just make it can't receive the data outside.
> The other way is make it into sleep mode.

I do not know your chip, I cannot help. However, this function is
thought to put the controller in a not operative state. It is a good law
to leave your hardware disable and let the kernel to reinitialize it
again when your system boots.

> I refer to the newest net driver patch ftgmac100.c, it uses this
> function to get
> mac address from environmental setting. and I checked the
> code eth_getenv_enetaddr
> also call the is_valid_ether_addr(). 

I checked this driver, too.IMHO it is wrong, and I do not know why in
ftgmac100_set_mac_from_env() is called getenv instead of using directly
the values in dev->enetaddr. Anyway, I missed my chance to send my
comments ;-)

You can check in other drivers in drivers/net, most of them do not call
getenv, because the net subsystem is responsible to do this.

Best regards,
Stefano Babic
Wolfgang Denk Feb. 4, 2011, 3:59 p.m. UTC | #4
Dear Joe XUE,

In message <SNT105-W339861012AB3A9EDCC0DDAACE60@phx.gbl> you wrote:
>
> > > Signed-off-by: Joe Xue <lgxue@hotmail.com>
> > > 
> > 
> > Please add a version number to your patch to make easier tracking which
> > is your last version.
> > 
> Will add it.
> > Do not forget to add always the net Maintainer to CC (Wolfgang Denk), I
> > added him now.
> > 
> Not exactly understand your meaning. You mean I should add wd as maintainer to my code or just add him in mail.

Only email, please.

An easy way to not forget this is to add a "Cc:" line below your
Signed-off-by: line - then "git send-email" will automatically
generate the needed Cc:s


> > > +static void ax88783_halt(struct eth_device *dev)
> > > +{
> > > +	unsigned int tmp;
> > > +	struct ax88783_reg *reg = (struct ax88783_reg *)dev->iobase;
> > > +	tmp = readl(&reg->pcr);
> > > +	writel((tmp | PCR_LOOP_BACK), &reg->pcr);
> > > +}
> > 
> > From the name it seems you set the controller in loopback, instead of
> > disabling it. Is it correct ?
> > 
> mmn. I just make it can't receive the data outside.The other way is make it into sleep mode.

Please put it in sleep mode, then.

Best regards,

Wolfgang Denk
diff mbox

Patch

diff --git a/README b/README
index 755d17c..c9657d8 100644
--- a/README
+++ b/README
@@ -892,6 +892,13 @@  The following options need to be configured:
 			automatically converts one 32 bit word to two 16 bit
 			words you may also try CONFIG_SMC911X_32_BIT.
 
+		CONFIG_DRIVER_AX88783
+		Support for ASIX's AX88783 chip
+
+			CONFIG_AX88783_BASE
+			Define this to hold the physical address
+			of the device (I/O space)
+
 - USB Support:
 		At the moment only the UHCI host controller is
 		supported (PIP405, MIP405, MPC5200); define
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index fd9d0b4..7cd6e2c 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -30,6 +30,7 @@  COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
 COBJS-$(CONFIG_ALTERA_TSE) += altera_tse.o
 COBJS-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
 COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o
+COBJS-$(CONFIG_DRIVER_AX88783) += ax88783.o
 COBJS-$(CONFIG_BCM570x) += bcm570x.o
 COBJS-$(CONFIG_BCM570x) += bcm570x_autoneg.o
 COBJS-$(CONFIG_BCM570x) += 5701rls.o
diff --git a/drivers/net/ax88783.c b/drivers/net/ax88783.c
new file mode 100644
index 0000000..4eae949
--- /dev/null
+++ b/drivers/net/ax88783.c
@@ -0,0 +1,297 @@ 
+/*
+ *
+ * (C) Copyright 2011 Joe Xue <lgxue@hotmail.com>
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+/*
+ * AX88783 has two ethernet ports, this driver uses port 0 in u-boot
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <linux/mii.h>
+#include <miiphy.h>
+#include <config.h>
+#include <asm/io.h>
+#include "ax88783.h"
+
+static int ax88183_phy_initial(struct eth_device *dev)
+{
+	int i;
+	int reg_num;
+	unsigned int tmp;
+	struct ax88783_reg * reg = (struct ax88783_reg *)dev->iobase;
+
+	/* reset chip */
+	tmp = readl(&reg->cr);
+	writel((tmp & ~CR_CHIP_RESET), &reg->cr);
+	udelay(1000);
+
+	writel((tmp | CR_CHIP_RESET), &reg->cr);
+
+	/* phy init */
+	tmp = readl(&reg->pcr);
+	tmp |= PCR_PHY0_RESET_CLEAR;
+
+	writel(tmp, &reg->pcr);
+	udelay(100000);
+
+	tmp = readl(&reg->pollcr);
+	tmp &= POLLCR_PORT0_PHYID_MASK;
+	tmp |= POLLCR_PORT0_PHYID(0x10);
+	writel(tmp, &reg->pollcr);
+
+	/* write MII mode */
+	tmp = readl(&reg->miicr) & 0xFF;
+	tmp &= (~MIICR_PORT0_MII_CLK_GEN);
+	tmp &= (~MIICR_PORT0_PHY_RMII);
+	writel(tmp, &reg->miicr);
+
+	/* set LED mode */
+	tmp = readl(&reg->ledcr);
+	tmp |= LEDCR_PORT_LED_ON(0) | LEDCR_LED0(PHY_LED_RX | PHY_LED_TX);
+	tmp |= LEDCR_PORT_LED_ON(1) | LEDCR_LED1(PHY_LED_LINK);
+	writel(tmp, &reg->ledcr);
+
+	/* set auto polling */
+	tmp = readl(&reg->pollcr);
+	tmp |= (POLLCR_PORT0_AUTO_POOLING);
+	writel(tmp, &reg->pollcr);
+
+	/* set link speed */
+	for (i = 0; i < 2; i++) {
+		reg_num = i*8+16;
+		tmp = MDCR_READ | MDCR_PHY_ID(0x10) | MDCR_PHY_REG(reg_num);
+		writel(tmp, &reg->mdcr);
+		tmp = readl(&reg->mdcr);
+		if (tmp & MDCR_VALID) {
+			puts("link speed init failed!");
+			return 1;
+		}
+
+		tmp = readl(&reg->mdcr) & MDCR_VALUE_MASK;
+		tmp = tmp | 0x1000 | MDCR_WRITE | \
+		      MDCR_PHY_ID(0x10) | MDCR_PHY_REG(reg_num);
+		writel(tmp, &reg->mdcr);
+		tmp = readl(&reg->mdcr);
+		if (tmp & MDCR_VALID) {
+			puts("link speed init failed!");
+			return 1;
+		}
+	}
+
+	/* media init */
+	tmp = MDCR_READ | MDCR_PHY_ID(0x10) | MDCR_PHY_REG(MII_ADVERTISE);
+	writel(tmp, &reg->mdcr);
+	tmp = readl(&reg->mdcr);
+	if (tmp & MDCR_VALID) {
+		puts("media init failed!");
+		return 1;
+	}
+
+	tmp = readl(&reg->mdcr) & MDCR_VALUE_MASK;
+	tmp &= (~ADVERTISE_ALL);
+	tmp |= ADVERTISE_ALL | 0x400;
+	tmp = tmp | MDCR_WRITE | MDCR_PHY_ID(0x10);
+
+	writel(tmp, &reg->mdcr);
+	tmp = readl(&reg->mdcr);
+	if (tmp & MDCR_VALID) {
+		puts("media init failed!");
+		return 1;
+	}
+
+	tmp = MDCR_WRITE | MDCR_PHY_ID(0x10) | \
+	      MDCR_PHY_REG(MII_BMCR)| \
+	      BMCR_ANRESTART | BMCR_ANENABLE;
+
+	writel(tmp, &reg->mdcr);
+	tmp = readl(&reg->mdcr);
+	if (tmp & MDCR_VALID) {
+		puts("media init failed!");
+		return 1;
+	}
+
+	return 0;
+}
+
+static int ax88783_init(struct eth_device *dev, bd_t * bd)
+{
+	unsigned int tmp;
+	struct ax88783_reg *reg = (struct ax88783_reg *)dev->iobase;
+	unsigned char mactmp[4];
+	unsigned int * mac = (unsigned int *)mactmp;
+
+	/* disable interrupt */
+	writel(IMSR_MASK_ALL, &reg->imsr);
+
+	/* set mac address*/
+	mactmp[0] = dev->enetaddr[5];
+	mactmp[1] = dev->enetaddr[4];
+	mactmp[2] = dev->enetaddr[3];
+	mactmp[3] = dev->enetaddr[2];
+	writel(*mac, &reg->p0mac0);
+
+	mactmp[0] = dev->enetaddr[1];
+	mactmp[1] = dev->enetaddr[0];
+	writel(*mac, &reg->p0mac1);
+
+	/* write mac to forward entry */
+	mactmp[0] = dev->enetaddr[3];
+	mactmp[1] = dev->enetaddr[2];
+	mactmp[2] = dev->enetaddr[1];
+	mactmp[3] = dev->enetaddr[0];
+	writel(*mac, &reg->ftdata);
+
+	tmp = dev->enetaddr[4] | (dev->enetaddr[5]<<8) | \
+	      FTCMD_FT_PORT(0x2) | FTCMD_FT_STATIC | \
+	      FTCMD_WRITE_FT;
+	writel(tmp, &reg->ftcmd);
+
+	/* packet order */
+	writel(BORDER_LITTLE, &reg->border);
+
+	/* local bus cpi */
+	tmp = readl(&reg->l2psr);
+	tmp |= L2PSR_CPIO_ON;
+	writel(tmp, &reg->l2psr);
+
+	tmp = readl(&reg->pcr);
+	writel(tmp & ~PCR_LOOP_BACK, &reg->pcr);
+	return 0;
+
+}
+
+static void ax88783_halt(struct eth_device *dev)
+{
+	unsigned int tmp;
+	struct ax88783_reg *reg = (struct ax88783_reg *)dev->iobase;
+	tmp = readl(&reg->pcr);
+	writel((tmp | PCR_LOOP_BACK), &reg->pcr);
+}
+
+/* Get a data block via Ethernet */
+static int ax88783_recv(struct eth_device *dev)
+{
+	char *buf;
+	unsigned int i;
+	unsigned int tmp;
+	unsigned long length, reverse_length;
+	struct ax88783_reg * reg = (struct ax88783_reg *)dev->iobase;
+
+	tmp = readl(&reg->imsr);
+	while (tmp & IMSR_INT_CPO_EMPTY) {
+		tmp = readl(&reg->imsr);
+		writel(tmp, &reg->imsr);
+		writel(CSCR_CPO_START, &reg->cscr);
+
+		tmp = readl(&reg->dataport);
+		tmp = be32_to_cpu(tmp);
+		if (tmp == 0)
+			continue;
+
+		length = tmp & 0xffff;
+		reverse_length = (~(tmp>>16))&0xffff;
+		if (length != reverse_length) {
+			/* reset CPO */
+			tmp = readl(&reg->cr);
+			tmp &= ~CR_CPO_RESET;
+			writel(tmp, &reg->cr);
+			continue;
+		}
+
+		length = length & 0x7ff;
+		/* align the length */
+		length = ((length+3)/4)*4;
+
+		buf = NetRxPackets[0];
+		for (i = 0; i < length; i += 4) {
+			tmp = readl(&reg->dataport);
+			buf[i] = (unsigned char)(tmp & 0xff);
+			buf[i+1] = (unsigned char)((tmp >> 8) & 0xff);
+			buf[i+2] = (unsigned char)((tmp >> 16) & 0xff);
+			buf[i+3] = (unsigned char)((tmp >> 24) & 0xff);
+		}
+
+		/* pass to up level */
+		NetReceive(NetRxPackets[0], (unsigned short) length);
+		tmp = readl(&reg->imsr);
+	}
+
+	return (int) length;
+}
+
+/* Send a data block via Ethernet. */
+	static int
+ax88783_send(struct eth_device *dev, volatile void *packet, int length)
+{
+	unsigned int pkt_header, tmp, i;
+	unsigned char *buf = (unsigned char *)packet;
+	struct ax88783_reg * reg = (struct ax88783_reg *)dev->iobase;
+	tmp = length;
+	tmp = (~tmp << 16) | tmp;
+	pkt_header = cpu_to_be32(tmp);
+	writel(CSCR_CPI_START, &reg->cscr);
+	writel(pkt_header, &reg->dataport);
+
+	for (i = 0; i < length; i += 4) {
+		tmp = (unsigned int)*(buf + i) | \
+		      (((unsigned int)*(buf + i + 1)) << 8) | \
+		      (((unsigned int)*(buf + i + 2)) << 16) | \
+		      (((unsigned int)*(buf + i + 3)) << 24);
+		writel(tmp, &reg->dataport);
+	}
+
+	return 0;
+}
+
+int ax88783_initialize(bd_t *bis)
+{
+	struct eth_device *dev;
+	int res;
+	dev = (struct eth_device *)malloc(sizeof *dev);
+
+	if (NULL == dev)
+		return 0;
+
+	memset(dev, 0, sizeof *dev);
+
+	sprintf(dev->name, "AX88783");
+	dev->iobase = CONFIG_AX88783_BASE;
+	dev->init = ax88783_init;
+	dev->halt = ax88783_halt;
+	dev->send = ax88783_send;
+	dev->recv = ax88783_recv;
+
+	res = eth_getenv_enetaddr("ethaddr", dev->enetaddr);
+	if (!res) {
+		puts("Please set your MAC address!");
+		free(dev);
+		return 0;
+	}
+
+	res = ax88183_phy_initial(dev);
+	if (res != 0) {
+		free(dev);
+		return 0;
+	}
+	eth_register(dev);
+
+	return 1;
+}
+
diff --git a/drivers/net/ax88783.h b/drivers/net/ax88783.h
new file mode 100644
index 0000000..09ac9ed
--- /dev/null
+++ b/drivers/net/ax88783.h
@@ -0,0 +1,100 @@ 
+/*
+ *
+ * (C) Copyright 2011 Joe Xue <lgxue@hotmail.com>
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __AX88783_H__
+#define __AX88783_H__
+
+struct ax88783_reg {
+	unsigned int cr;
+	unsigned int pcr;
+	unsigned int pad0[2];
+	unsigned int l2psr;
+	unsigned int pad1[1];
+	unsigned int ftdata;
+	unsigned int ftcmd;
+	unsigned int pad2[7];
+	unsigned int mdcr;
+	unsigned int pad3[3];
+	unsigned int dataport;
+	unsigned int pad4[32];
+	unsigned int border;
+	unsigned int cscr;
+	unsigned int pad5[1];
+	unsigned int ledcr;
+	unsigned int pad6[6];
+	unsigned int imsr;
+	unsigned int pad7[17];
+	unsigned int pollcr;
+	unsigned int pad8[43];
+	unsigned int miicr;
+	unsigned int pad9[15];
+	unsigned int p0mac0;
+	unsigned int p0mac1;
+	unsigned int pad10[1];
+};
+
+#define CR_CPI_RESET                   (1 << 26)
+#define CR_CPO_RESET                   (1 << 27)
+#define CR_CHIP_RESET                  (1 << 31)
+
+#define PCR_PHY0_RESET_CLEAR           (1)
+#define PCR_LOOP_BACK                  (8)
+
+#define L2PSR_CPIO_ON                  (1 << 9)
+
+#define FTCMD_WRITE_FT                 (1 << 31)
+#define FTCMD_FT_STATIC                (1 << 20)
+#define FTCMD_FT_PORT(x)               (x << 16)
+
+#define MDCR_WRITE                     (1 << 31)
+#define MDCR_READ                      (1 << 30)
+#define MDCR_VALID                     (1 << 29)
+#define MDCR_PHY_ID(x)                 (x << 24)
+#define MDCR_PHY_REG(x)                (x << 16)
+#define MDCR_VALUE_MASK                (0xFFFF)
+
+#define BORDER_BIG                     (0)
+#define BORDER_LITTLE                  (1)
+
+#define CSCR_CPI_START                 (1 << 15)
+#define CSCR_CPO_START                 (1 << 31)
+
+#define LEDCR_LED0(x)                  (x)
+#define LEDCR_LED1(x)                  (x << 8)
+#define LEDCR_LED2(x)                  (x << 16)
+#define LEDCR_PORT_LED_ON(Port)        (1 << (24 + Port))
+#define PHY_LED_SPEED                  (1 << 0)
+#define PHY_LED_DUPLEX                 (1 << 1)
+#define PHY_LED_LINK                   (1 << 2)
+#define PHY_LED_RX                     (1 << 3)
+#define PHY_LED_TX                     (1 << 4)
+#define PHY_LED_COLLISION              (1 << 5)
+
+#define IMSR_INT_CPO_EMPTY             (1 << 3)
+#define IMSR_MASK_ALL                  0xFFFF0000
+
+#define POLLCR_PORT0_PHYID_MASK        (0xFFFFFFE0)
+#define POLLCR_PORT0_PHYID(x)          (x)
+#define POLLCR_PORT0_AUTO_POOLING      0x11000000
+
+#define MIICR_PORT0_MII_CLK_GEN        (1 << 0)
+#define MIICR_PORT0_PHY_RMII           (1 << 4)
+
+#endif
+
diff --git a/include/netdev.h b/include/netdev.h
index 1a542e8..fddc64d 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -44,6 +44,7 @@  int cpu_eth_init(bd_t *bis);
 int altera_tse_initialize(u8 dev_num, int mac_base,
 			  int sgdma_rx_base, int sgdma_tx_base);
 int ax88180_initialize(bd_t *bis);
+int ax88783_initialize(bd_t *bis);
 int au1x00_enet_initialize(bd_t*);
 int at91emac_register(bd_t *bis, unsigned long iobase);
 int bfin_EMAC_initialize(bd_t *bis);