diff mbox

[U-Boot] Add support for AX88183 ethernet chip

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

Commit Message

root Jan. 29, 2011, 2:03 a.m. UTC
Signed-off-by: Joe Xue <lgxue@hotmail.com>
	modified:   README
	modified:   drivers/net/Makefile
	new file:   drivers/net/ax88183.c
	new file:   drivers/net/ax88183.h
	modified:   include/netdev.h
---
 README                |    7 +
 drivers/net/Makefile  |    1 +
 drivers/net/ax88183.c |  293 +++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/ax88183.h |  118 ++++++++++++++++++++
 include/netdev.h      |    1 +
 5 files changed, 420 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/ax88183.c
 create mode 100644 drivers/net/ax88183.h

Comments

Stefano Babic Jan. 30, 2011, 6:42 p.m. UTC | #1
Am 29.01.2011 03:03, schrieb Joe Xue:

Hi Joe,

> Signed-off-by: Joe Xue <lgxue@hotmail.com>
> 	modified:   README
> 	modified:   drivers/net/Makefile
> 	new file:   drivers/net/ax88183.c
> 	new file:   drivers/net/ax88183.h
> 	modified:   include/netdev.h

You do not need to add this stuff in the commit message. They are
already reported under the "---" line and can be easy find with git
commands. Instead, add here which chip is supported (you do not mention
it is an Asix chip in the commit id), how do you tested, and some
general info you can find useful for any reader who finds your driver
and what to know something more. Is ax88183 the right name for the chip
? I cannot find it on the Asix's website.

> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index fd9d0b4..393d5f3 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -84,6 +84,7 @@ COBJS-$(CONFIG_TSI108_ETH) += tsi108_eth.o
>  COBJS-$(CONFIG_ULI526X) += uli526x.o
>  COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o
>  COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
> +COBJS-$(CONFIG_DRIVER_AX88183) += ax88183.o

The list is not *alfabetically* sorted, as it is before your patch. You
have to put your driver after the ax88180 driver.

> +
> +/*
> + * AX88783 has two ethernet ports, this driver uses port 0 in u-boot
> + */

Is there a way to make this configurable ? I mean, the driver supports
always one port, but which one could be configurable in the bard
configuration file.

> +
> +#include <common.h>
> +#include <command.h>
> +#include <net.h>
> +#include <linux/mii.h>
> +#include <miiphy.h>
> +#include <config.h>
> +#include <asm/io.h>
> +#include "ax88183.h"
> +
> +static int ax88180_phy_initial(struct eth_device *dev)
> +{
> +	int i;
> +	unsigned int tmp;
> +	struct ax88183_reg * reg = (struct ax88183_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);

This is a very long time (100mSec). Why do we need ?

> +
> +	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++) {
> +		int reg_num = i*8+16;
> +		tmp = MDCR_READ | MDCR_PHY_ID(0x10) | MDCR_PHY_REG(reg_num);
> +		writel(tmp, &reg->mdcr);
> +		while (1) {
> +			tmp = readl(&reg->mdcr);
> +			if (tmp & MDCR_VALID)
> +				break;
> +		}
> +
> +		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);
> +		while (1) {
> +			tmp = readl(&reg->mdcr);
> +			if (tmp & MDCR_VALID)

No timeout here ? If it does not work, system hangs without printing

> +	while (1) {
> +		tmp = readl(&reg->mdcr);
> +		if (tmp & MDCR_VALID)

Ditto. It should be fixed globally.


> +static int ax88183_init(struct eth_device *dev, bd_t * bd)
> +{
> +	unsigned int tmp;
> +	struct ax88183_reg *reg = (struct ax88183_reg *)dev->iobase;
> +
> +	/* disable interrupt */
> +
> +	writel(IMSR_MASK_ALL, &reg->imsr);
> +	/* set mac address*/
> +	unsigned char mactmp[4];
> +	unsigned int * mac = (unsigned int *)mactmp;

Why are these variabled defined here and not at the beginning of the
funtion ?

> +static void ax88183_halt(struct eth_device *dev)
> +{
> +	;

This is not needed, and should be dropped. However, you should disable
the device in this function.

> +/* Send a data block via Ethernet. */
> +static int
> +ax88183_send(struct eth_device *dev, volatile void *packet, int length)
> +{
> +	unsigned int pkt_header, tmp, i;
> +	unsigned char *buf = (unsigned char *)packet;
> +	struct ax88183_reg * reg = (struct ax88183_reg *)dev->iobase;
> +	tmp = length;
> +	tmp = (~tmp << 16) | tmp;
> +	pkt_header = ((tmp & 0xff000000) >> 24) | \
> +				 ((tmp & 0x00ff0000) >> 8) | \
> +				 ((tmp & 0x0000ff00) << 8) | \
> +				 ((tmp & 0x000000ff) << 24);

It seems to me you this are due to adapt the endianess. In this case you
should use acceesors (cpu_to_le32, cpu_to_be32).

> +struct ax88183_reg {
> +	unsigned int cr;        /* 0x0000 */
> +	unsigned int pcr;       /* 0x0004 */

I think the offset as comment is not very useful, I suggest to remove it.

> +#define P0MAC0 0x0230
> +
> +#define P0MAC1 0x0234

These two defines seem to me obsolete and should be removed.

Best regards,
Stefano Babic
diff mbox

Patch

diff --git a/README b/README
index 755d17c..951baee 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_AX88183
+		Support for ASIX's AX88183 chip
+
+			CONFIG_AX88183_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..393d5f3 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -84,6 +84,7 @@  COBJS-$(CONFIG_TSI108_ETH) += tsi108_eth.o
 COBJS-$(CONFIG_ULI526X) += uli526x.o
 COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o
 COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
+COBJS-$(CONFIG_DRIVER_AX88183) += ax88183.o
 
 COBJS	:= $(sort $(COBJS-y))
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/net/ax88183.c b/drivers/net/ax88183.c
new file mode 100644
index 0000000..0543a40
--- /dev/null
+++ b/drivers/net/ax88183.c
@@ -0,0 +1,293 @@ 
+/*
+ *
+ * (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 "ax88183.h"
+
+static int ax88180_phy_initial(struct eth_device *dev)
+{
+	int i;
+	unsigned int tmp;
+	struct ax88183_reg * reg = (struct ax88183_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++) {
+		int reg_num = i*8+16;
+		tmp = MDCR_READ | MDCR_PHY_ID(0x10) | MDCR_PHY_REG(reg_num);
+		writel(tmp, &reg->mdcr);
+		while (1) {
+			tmp = readl(&reg->mdcr);
+			if (tmp & MDCR_VALID)
+				break;
+		}
+
+		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);
+		while (1) {
+			tmp = readl(&reg->mdcr);
+			if (tmp & MDCR_VALID)
+				break;
+		}
+	}
+
+	/* media init */
+	tmp = MDCR_READ | MDCR_PHY_ID(0x10) | MDCR_PHY_REG(MII_ADVERTISE);
+	writel(tmp, &reg->mdcr);
+	while (1) {
+		tmp = readl(&reg->mdcr);
+		if (tmp & MDCR_VALID)
+			break;
+	}
+
+	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);
+	while (1) {
+		tmp = readl(&reg->mdcr);
+		if (tmp & MDCR_VALID)
+			break;
+	}
+
+	tmp = MDCR_WRITE | MDCR_PHY_ID(0x10) | \
+		MDCR_PHY_REG(MII_BMCR)| \
+		BMCR_ANRESTART | BMCR_ANENABLE;
+
+	writel(tmp, &reg->mdcr);
+	while (1) {
+		tmp = readl(&reg->mdcr);
+		if (tmp & MDCR_VALID)
+			break;
+	}
+
+	return 0;
+}
+
+static int ax88183_init(struct eth_device *dev, bd_t * bd)
+{
+	unsigned int tmp;
+	struct ax88183_reg *reg = (struct ax88183_reg *)dev->iobase;
+
+	/* disable interrupt */
+
+	writel(IMSR_MASK_ALL, &reg->imsr);
+	/* set mac address*/
+	unsigned char mactmp[4];
+	unsigned int * mac = (unsigned int *)mactmp;
+	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);
+
+	return 0;
+
+}
+
+static void ax88183_halt(struct eth_device *dev)
+{
+	;
+}
+
+/* Get a data block via Ethernet */
+static int ax88183_recv(struct eth_device *dev)
+{
+	unsigned int i;
+	unsigned int tmp;
+	unsigned long length, reverse_length;
+	struct ax88183_reg * reg = (struct ax88183_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 = ((tmp & 0xFF000000) >> 24) |
+			((tmp & 0x00FF0000) >> 8) |
+			((tmp & 0x0000FF00) << 8) |
+			((tmp & 0x000000FF) << 24);
+		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;
+
+		char *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
+ax88183_send(struct eth_device *dev, volatile void *packet, int length)
+{
+	unsigned int pkt_header, tmp, i;
+	unsigned char *buf = (unsigned char *)packet;
+	struct ax88183_reg * reg = (struct ax88183_reg *)dev->iobase;
+	tmp = length;
+	tmp = (~tmp << 16) | tmp;
+	pkt_header = ((tmp & 0xff000000) >> 24) | \
+				 ((tmp & 0x00ff0000) >> 8) | \
+				 ((tmp & 0x0000ff00) << 8) | \
+				 ((tmp & 0x000000ff) << 24);
+
+	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 ax88183_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, "AX88183");
+	dev->iobase = CONFIG_AX88183_BASE;
+	dev->init = ax88183_init;
+	dev->halt = ax88183_halt;
+	dev->send = ax88183_send;
+	dev->recv = ax88183_recv;
+
+	res = eth_getenv_enetaddr("ethaddr", dev->enetaddr);
+	if (!res) {
+		puts("Please set your MAC address!");
+		return 1;
+	}
+
+	eth_register(dev);
+
+	res = ax88180_phy_initial(dev);
+
+	return res;
+}
+
diff --git a/drivers/net/ax88183.h b/drivers/net/ax88183.h
new file mode 100644
index 0000000..bda2174
--- /dev/null
+++ b/drivers/net/ax88183.h
@@ -0,0 +1,118 @@ 
+/*
+ *
+ * (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 __AX88183_H__
+#define __AX88183_H__
+
+struct ax88183_reg {
+	unsigned int cr;        /* 0x0000 */
+	unsigned int pcr;       /* 0x0004 */
+	unsigned int pad0[2];
+	unsigned int l2psr;     /* 0x0010 */
+	unsigned int pad1[1];
+	unsigned int ftdata;    /* 0x0018 */
+	unsigned int ftcmd;     /* 0x001c */
+	unsigned int pad2[7];
+	unsigned int mdcr;      /* 0x003c */
+	unsigned int pad3[3];
+	unsigned int dataport;  /* 0x004c */
+	unsigned int pad4[32];
+	unsigned int border;   /* 0x00d0 */
+	unsigned int cscr;      /* 0x00d4 */
+	unsigned int pad5[1];
+	unsigned int ledcr;     /* 0x00dc */
+	unsigned int pad6[6];
+	unsigned int imsr;      /* 0x00f8 */
+	unsigned int pad7[17];
+	unsigned int pollcr;    /* 0x0140 */
+	unsigned int pad8[43];
+	unsigned int miicr;     /* 0x01f0 */
+	unsigned int pad9[15];
+	unsigned int p0mac0;    /* 0x0230 */
+	unsigned int p0mac1;    /* 0x0234 */
+	unsigned int pad10[1];
+};
+
+#define CR 0x0000
+#define CR_CPI_RESET                   (1 << 26)
+#define CR_CPO_RESET                   (1 << 27)
+#define CR_CHIP_RESET                  (1 << 31)
+
+#define PCR 0x0004
+#define PCR_PHY0_RESET_CLEAR           (1)
+
+#define L2PSR 0x0010
+#define L2PSR_CPIO_ON                  (1 << 9)
+
+#define FTDATA 0x0018
+
+#define FTCMD 0x001c
+#define FTCMD_WRITE_FT                 (1 << 31)
+#define FTCMD_FT_STATIC                (1 << 20)
+#define FTCMD_FT_PORT(x)               (x << 16)
+
+#define MDCR 0x003c
+#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 DATAPORT 0x004c
+
+#define BORDER 0x00D0
+#define BORDER_BIG                     (0)
+#define BORDER_LITTLE                  (1)
+
+#define CSCR 0x00D4
+#define CSCR_CPI_START                 (1 << 15)
+#define CSCR_CPO_START                 (1 << 31)
+
+#define LEDCR 0x00DC
+#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 0x00F8
+#define IMSR_INT_CPO_EMPTY             (1 << 3)
+#define IMSR_MASK_ALL                  0xFFFF0000
+
+#define POLLCR 0x0140
+#define POLLCR_PORT0_PHYID_MASK        (0xFFFFFFE0)
+#define POLLCR_PORT0_PHYID(x)          (x)
+#define POLLCR_PORT0_AUTO_POOLING      0x11000000
+
+#define MIICR 0x01F0
+#define MIICR_PORT0_MII_CLK_GEN        (1 << 0)
+#define MIICR_PORT0_PHY_RMII           (1 << 4)
+
+#define P0MAC0 0x0230
+
+#define P0MAC1 0x0234
+
+#endif
+
diff --git a/include/netdev.h b/include/netdev.h
index 1a542e8..6416223 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 ax88183_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);