summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/qemu-mips/qemu-mips.c6
-rw-r--r--board/renesas/r7780mp/r7780mp.c3
-rw-r--r--board/shmin/shmin.c6
-rw-r--r--drivers/net/ne2000_base.c99
-rw-r--r--include/netdev.h1
5 files changed, 86 insertions, 29 deletions
diff --git a/board/qemu-mips/qemu-mips.c b/board/qemu-mips/qemu-mips.c
index 7a69a00f99a..2b3a1d6b099 100644
--- a/board/qemu-mips/qemu-mips.c
+++ b/board/qemu-mips/qemu-mips.c
@@ -25,6 +25,7 @@
#include <command.h>
#include <asm/mipsregs.h>
#include <asm/io.h>
+#include <netdev.h>
phys_size_t initdram(int board_type)
{
@@ -87,3 +88,8 @@ int misc_init_r(void)
set_io_port_base(0);
return 0;
}
+
+int board_eth_init(bd_t *bis)
+{
+ return ne2k_register();
+}
diff --git a/board/renesas/r7780mp/r7780mp.c b/board/renesas/r7780mp/r7780mp.c
index 0b800990479..82cef025ade 100644
--- a/board/renesas/r7780mp/r7780mp.c
+++ b/board/renesas/r7780mp/r7780mp.c
@@ -81,5 +81,6 @@ void pci_init_board(void)
int board_eth_init(bd_t *bis)
{
- return pci_eth_init(bis);
+ /* return >= 0 if a chip is found, the board's AX88796L is n2k-based */
+ return ne2k_register() + pci_eth_init(bis);
}
diff --git a/board/shmin/shmin.c b/board/shmin/shmin.c
index 8742f102182..7348f52aa62 100644
--- a/board/shmin/shmin.c
+++ b/board/shmin/shmin.c
@@ -28,6 +28,7 @@
#include <common.h>
#include <asm/io.h>
#include <asm/processor.h>
+#include <netdev.h>
int checkboard(void)
{
@@ -55,6 +56,11 @@ int dram_init(void)
return 0;
}
+int board_eth_init(bd_t *bis)
+{
+ return ne2k_register();
+}
+
void led_set_state(unsigned short value)
{
diff --git a/drivers/net/ne2000_base.c b/drivers/net/ne2000_base.c
index f0cd2b62eb3..88f2b379f37 100644
--- a/drivers/net/ne2000_base.c
+++ b/drivers/net/ne2000_base.c
@@ -94,8 +94,12 @@ void uboot_push_tx_done(int key, int val);
static dp83902a_priv_data_t nic; /* just one instance of the card supported */
+/**
+ * This function reads the MAC address from the serial EEPROM,
+ * used if PROM read fails. Does nothing for ax88796 chips (sh boards)
+ */
static bool
-dp83902a_init(void)
+dp83902a_init(unsigned char *enetaddr)
{
dp83902a_priv_data_t *dp = &nic;
u8* base;
@@ -129,6 +133,7 @@ dp83902a_init(void)
dp->esa[4],
dp->esa[5] );
+ memcpy(enetaddr, dp->esa, 6); /* Use MAC from serial EEPROM */
#endif /* NE2000_BASIC_INIT */
return true;
}
@@ -161,6 +166,8 @@ dp83902a_start(u8 * enaddr)
u8 *base = dp->base;
int i;
+ debug("The MAC is %pM\n", enaddr);
+
DEBUG_FUNCTION();
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
@@ -665,12 +672,16 @@ void uboot_push_tx_done(int key, int val) {
pkey = key;
}
-int eth_init(bd_t *bd) {
- int r;
- u8 dev_addr[6];
- char ethaddr[20];
-
- PRINTK("### eth_init\n");
+/**
+ * Setup the driver and init MAC address according to doc/README.enetaddr
+ * Called by ne2k_register() before registering the driver @eth layer
+ *
+ * @param struct ethdevice of this instance of the driver for dev->enetaddr
+ * @return 0 on success, -1 on error (causing caller to print error msg)
+ */
+static int ne2k_setup_driver(struct eth_device *dev)
+{
+ PRINTK("### ne2k_setup_driver\n");
if (!pbuf) {
pbuf = malloc(2000);
@@ -692,49 +703,56 @@ int eth_init(bd_t *bd) {
nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE;
- r = get_prom(dev_addr, nic.base);
- if (!r)
- return -1;
-
- sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
- dev_addr[0], dev_addr[1],
- dev_addr[2], dev_addr[3],
- dev_addr[4], dev_addr[5]) ;
- PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr);
- setenv ("ethaddr", ethaddr);
-
nic.data = nic.base + DP_DATA;
nic.tx_buf1 = START_PG;
nic.tx_buf2 = START_PG2;
nic.rx_buf_start = RX_START;
nic.rx_buf_end = RX_END;
- if (dp83902a_init() == false)
- return -1;
+ /*
+ * According to doc/README.enetaddr, drivers shall give priority
+ * to the MAC address value in the environment, so we do not read
+ * it from the prom or eeprom if it is specified in the environment.
+ */
+ if (!eth_getenv_enetaddr("ethaddr", dev->enetaddr)) {
+ /* If the MAC address is not in the environment, get it: */
+ if (!get_prom(dev->enetaddr, nic.base)) /* get MAC from prom */
+ dp83902a_init(dev->enetaddr); /* fallback: seeprom */
+ /* And write it into the environment otherwise eth_write_hwaddr
+ * returns -1 due to eth_getenv_enetaddr_by_index() failing,
+ * and this causes "Warning: failed to set MAC address", and
+ * cmd_bdinfo has no ethaddr value which it can show: */
+ eth_setenv_enetaddr("ethaddr", dev->enetaddr);
+ }
+ return 0;
+}
- dp83902a_start(dev_addr);
+static int ne2k_init(struct eth_device *dev, bd_t *bd)
+{
+ dp83902a_start(dev->enetaddr);
initialized = 1;
-
return 0;
}
-void eth_halt() {
-
- PRINTK("### eth_halt\n");
+static void ne2k_halt(struct eth_device *dev)
+{
+ debug("### ne2k_halt\n");
if(initialized)
dp83902a_stop();
initialized = 0;
}
-int eth_rx() {
+static int ne2k_recv(struct eth_device *dev)
+{
dp83902a_poll();
return 1;
}
-int eth_send(volatile void *packet, int length) {
+static int ne2k_send(struct eth_device *dev, volatile void *packet, int length)
+{
int tmo;
- PRINTK("### eth_send\n");
+ debug("### ne2k_send\n");
pkey = -1;
@@ -754,3 +772,28 @@ int eth_send(volatile void *packet, int length) {
}
return 0;
}
+
+/**
+ * Setup the driver for use and register it with the eth layer
+ * @return 0 on success, -1 on error (causing caller to print error msg)
+ */
+int ne2k_register(void)
+{
+ struct eth_device *dev;
+
+ dev = calloc(sizeof(*dev), 1);
+ if (dev == NULL)
+ return -1;
+
+ if (ne2k_setup_driver(dev))
+ return -1;
+
+ dev->init = ne2k_init;
+ dev->halt = ne2k_halt;
+ dev->send = ne2k_send;
+ dev->recv = ne2k_recv;
+
+ sprintf(dev->name, "NE2000");
+
+ return eth_register(dev);
+}
diff --git a/include/netdev.h b/include/netdev.h
index 04d9f75b771..150fa8e4d59 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -80,6 +80,7 @@ int mpc8220_fec_initialize(bd_t *bis);
int mpc82xx_scc_enet_initialize(bd_t *bis);
int mvgbe_initialize(bd_t *bis);
int natsemi_initialize(bd_t *bis);
+int ne2k_register(void);
int npe_initialize(bd_t *bis);
int ns8382x_initialize(bd_t *bis);
int pcnet_initialize(bd_t *bis);