summaryrefslogtreecommitdiff
path: root/drivers/net/ne2000_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ne2000_base.c')
-rw-r--r--drivers/net/ne2000_base.c99
1 files changed, 71 insertions, 28 deletions
diff --git a/drivers/net/ne2000_base.c b/drivers/net/ne2000_base.c
index f0cd2b6..88f2b37 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);
+}