diff options
Diffstat (limited to 'drivers/net/ne2000_base.c')
| -rw-r--r-- | drivers/net/ne2000_base.c | 99 | 
1 files changed, 71 insertions, 28 deletions
| diff --git a/drivers/net/ne2000_base.c b/drivers/net/ne2000_base.c index f0cd2b62e..88f2b379f 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); +} |