[U-Boot] [PATCH v2] ne2000: Convert to new net-multi model, fixes build of three boards

Bernhard Kaindl bernhard.kaindl at gmx.net
Thu Oct 20 22:56:59 CEST 2011


This fixes the build of the two sh boards shmin and r7780mp and qemu-mips
which currently fail to build due to dropped pre-CONFIG_NET_MULTI code.

This v2 patch minimizes the number of lines in the diff for easy review
and to eliminate any possible accidential changes resulting from moving
lines of code in the file. This also makes the register function very easy.

Any cleanups and improvements are intentionally deferred to follow-up patches
to keep this patch as simple and as easy to review as possible.

A new driver register function, ne2k_register() calls the existing
one-time setup part of the old init function and calls eth_register().

Changes to shmin, r7780mp and qemu-mips:
- Call the new ne2k_register() from board_eth_init() of the boards.

- Tested using qemu-mips board,
- Tested the two renesas / sh boards r7780mp and shmin to compile again,
  and should work.

checkpatch-clean when "--ignore VOLATILE" is added to .checkpatch.conf,
and no warnings introduced in none of the three boards using this driver.

Signed-off-by: Bernhard Kaindl <bernhard.kaindl at gmx.net>
---
 board/qemu-mips/qemu-mips.c     |    6 ++
 board/renesas/r7780mp/r7780mp.c |    3 +-
 board/shmin/shmin.c             |    6 ++
 drivers/net/ne2000_base.c       |   99 ++++++++++++++++++++++++++++-----------
 include/netdev.h                |    1 +
 5 files changed, 86 insertions(+), 29 deletions(-)

diff --git a/board/qemu-mips/qemu-mips.c b/board/qemu-mips/qemu-mips.c
index 7a69a00..2b3a1d6 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 0b80099..82cef02 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 8742f10..7348f52 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 f93f932..ad8437d 100644
--- a/drivers/net/ne2000_base.c
+++ b/drivers/net/ne2000_base.c
@@ -95,8 +95,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;
@@ -130,6 +134,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;
 }
@@ -162,6 +167,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 */
@@ -666,12 +673,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);
@@ -693,49 +704,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;
 
@@ -755,3 +773,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 669f60b..38308e4 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -79,6 +79,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);
-- 
1.7.3.4



More information about the U-Boot mailing list