diff options
| author | Wolfgang Denk <wd@denx.de> | 2009-02-01 21:31:37 +0100 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2009-02-01 21:31:37 +0100 | 
| commit | ee924e00300bd1136589b2d5f8ad1f008df01bd4 (patch) | |
| tree | 4f517ecc2faf55dbaa3145835eef2eac2e0a4033 | |
| parent | f4b6f45dcba989f5a900edc07ececae80c79abdf (diff) | |
| parent | fc01ea1e27d5b124f0a1868d0ce569f156d58dfe (diff) | |
| download | olio-uboot-2014.01-ee924e00300bd1136589b2d5f8ad1f008df01bd4.tar.xz olio-uboot-2014.01-ee924e00300bd1136589b2d5f8ad1f008df01bd4.zip | |
Merge branch 'master' of git://git.denx.de/u-boot-net
| -rw-r--r-- | board/bf537-stamp/bf537-stamp.c | 16 | ||||
| -rw-r--r-- | cpu/mpc8260/Makefile | 8 | ||||
| -rw-r--r-- | cpu/mpc8260/cpu.c | 3 | ||||
| -rw-r--r-- | cpu/mpc8260/ether_scc.c | 50 | ||||
| -rw-r--r-- | cpu/sh4/cpu.c | 8 | ||||
| -rw-r--r-- | drivers/net/Makefile | 4 | ||||
| -rw-r--r-- | drivers/net/macb.c | 31 | ||||
| -rw-r--r-- | drivers/net/sh_eth.c | 355 | ||||
| -rw-r--r-- | drivers/net/sh_eth.h | 10 | ||||
| -rw-r--r-- | drivers/net/smc911x.c | 79 | ||||
| -rw-r--r-- | drivers/net/tsec.c | 4 | ||||
| -rw-r--r-- | drivers/qe/uec_phy.c | 59 | ||||
| -rw-r--r-- | include/configs/sh7763rdp.h | 1 | ||||
| -rw-r--r-- | include/net.h | 16 | ||||
| -rw-r--r-- | include/netdev.h | 2 | ||||
| -rw-r--r-- | net/net.c | 2 | 
16 files changed, 446 insertions, 202 deletions
| diff --git a/board/bf537-stamp/bf537-stamp.c b/board/bf537-stamp/bf537-stamp.c index 63992f609..5b619be11 100644 --- a/board/bf537-stamp/bf537-stamp.c +++ b/board/bf537-stamp/bf537-stamp.c @@ -34,22 +34,6 @@  #include <asm/mach-common/bits/bootrom.h>  #include <netdev.h> -/** - * is_valid_ether_addr - Determine if the given Ethernet address is valid - * @addr: Pointer to a six-byte array containing the Ethernet address - * - * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not - * a multicast address, and is not FF:FF:FF:FF:FF:FF. - * - * Return true if the address is valid. - */ -static inline int is_valid_ether_addr(const u8 * addr) -{ -	/* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to -	 * explicitly check for it here. */ -	return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr); -} -  DECLARE_GLOBAL_DATA_PTR;  #define POST_WORD_ADDR 0xFF903FFC diff --git a/cpu/mpc8260/Makefile b/cpu/mpc8260/Makefile index 80d785229..9f0c2dd50 100644 --- a/cpu/mpc8260/Makefile +++ b/cpu/mpc8260/Makefile @@ -1,5 +1,5 @@  # -# (C) Copyright 2000-2006 +# (C) Copyright 2000-2008  # Wolfgang Denk, DENX Software Engineering, wd@denx.de.  #  # See file CREDITS for list of people who contributed to this @@ -27,9 +27,13 @@ LIB	= $(obj)lib$(CPU).a  START	= start.o kgdb.o  COBJS	= traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \ -	  interrupts.o ether_scc.o ether_fcc.o i2c.o commproc.o \ +	  interrupts.o ether_fcc.o i2c.o commproc.o \  	  bedbug_603e.o pci.o spi.o +COBJS-$(CONFIG_ETHER_ON_SCC) = ether_scc.o + +COBJS	+= $(COBJS-y) +  SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))  START	:= $(addprefix $(obj),$(START)) diff --git a/cpu/mpc8260/cpu.c b/cpu/mpc8260/cpu.c index b9e748ab8..f4beca55b 100644 --- a/cpu/mpc8260/cpu.c +++ b/cpu/mpc8260/cpu.c @@ -326,5 +326,8 @@ int cpu_eth_init(bd_t *bis)  #if defined(CONFIG_ETHER_ON_FCC)  	fec_initialize(bis);  #endif +#if defined(CONFIG_ETHER_ON_SCC) +	mpc82xx_scc_enet_initialize(bd); +#endif  	return 0;  } diff --git a/cpu/mpc8260/ether_scc.c b/cpu/mpc8260/ether_scc.c index c65f0e068..3671ef1df 100644 --- a/cpu/mpc8260/ether_scc.c +++ b/cpu/mpc8260/ether_scc.c @@ -10,6 +10,12 @@   * Advent Networks, Inc. <http://www.adventnetworks.com>   * Jay Monkman <jtm@smoothsmoothie.com>   * + * Modified so that it plays nicely when more than one ETHERNET interface + * is in use a la ether_fcc.c. + * (C) Copyright 2008 + * DENX Software Engineerin GmbH + * Gary Jennejohn <garyj@denx.de> + *   * See file CREDITS for list of people who contributed to this   * project.   * @@ -32,11 +38,14 @@  #include <common.h>  #include <asm/cpm_8260.h>  #include <mpc8260.h> +#include <malloc.h>  #include <net.h>  #include <command.h>  #include <config.h> -#if defined(CONFIG_ETHER_ON_SCC) && defined(CONFIG_CMD_NET) +#ifndef CONFIG_NET_MULTI +#error "CONFIG_NET_MULTI must be defined." +#endif  #if (CONFIG_ETHER_INDEX == 1)  #  define PROFF_ENET            PROFF_SCC1 @@ -100,7 +109,7 @@ typedef volatile struct CommonBufferDescriptor {  static RTXBD *rtx; -int eth_send(volatile void *packet, int length) +static int sec_send(struct eth_device *dev, volatile void *packet, int length)  {      int i;      int result = 0; @@ -137,7 +146,7 @@ int eth_send(volatile void *packet, int length)  } -int eth_rx(void) +static int sec_rx(struct eth_device *dev)  {      int length; @@ -184,7 +193,7 @@ int eth_rx(void)   *   *************************************************************/ -int eth_init(bd_t *bis) +static int sec_init(struct eth_device *dev, bd_t *bis)  {      int i;      volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; @@ -194,9 +203,14 @@ int eth_init(bd_t *bis)      rxIdx = 0;      txIdx = 0; -    /* assign static pointer to BD area */ -    dpaddr = m8260_cpm_dpalloc(sizeof(RTXBD) + 2, 16); -    rtx = (RTXBD *)&immr->im_dprambase[dpaddr]; +    /* +     * Assign static pointer to BD area. +     * Avoid exhausting DPRAM, which would cause a panic. +     */ +    if (rtx == NULL) { +	    dpaddr = m8260_cpm_dpalloc(sizeof(RTXBD) + 2, 16); +	    rtx = (RTXBD *)&immr->im_dprambase[dpaddr]; +    }      /* 24.21 - (1-3): ioports have been set up already */ @@ -338,7 +352,7 @@ int eth_init(bd_t *bis)  } -void eth_halt(void) +static void sec_halt(struct eth_device *dev)  {      volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;      immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl &= ~(SCC_GSMRL_ENR | @@ -346,7 +360,7 @@ void eth_halt(void)  }  #if 0 -void restart(void) +static void sec_restart(void)  {      volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;      immr->im_cpm.cp_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl |= (SCC_GSMRL_ENR | @@ -354,4 +368,20 @@ void restart(void)  }  #endif -#endif +int mpc82xx_scc_enet_initialize(bd_t *bis) +{ +	struct eth_device *dev; + +	dev = (struct eth_device *) malloc(sizeof *dev); +	memset(dev, 0, sizeof *dev); + +	sprintf(dev->name, "SCC ETHERNET"); +	dev->init   = sec_init; +	dev->halt   = sec_halt; +	dev->send   = sec_send; +	dev->recv   = sec_rx; + +	eth_register(dev); + +	return 1; +} diff --git a/cpu/sh4/cpu.c b/cpu/sh4/cpu.c index d94e13981..52b6cfd68 100644 --- a/cpu/sh4/cpu.c +++ b/cpu/sh4/cpu.c @@ -82,3 +82,11 @@ int dcache_status (void)  {  	return 0;  } + +int cpu_eth_init(bd_t *bis) +{ +#ifdef CONFIG_SH_ETHER +	sh_eth_initialize(bis); +#endif +	return 0; +} diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 631336ab4..128dc11ac 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk  LIB	:= $(obj)libnet.a  COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o +COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o  COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o  COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o  COBJS-$(CONFIG_BFIN_MAC) += bfin_mac.o @@ -54,11 +55,11 @@ COBJS-$(CONFIG_NS8382X) += ns8382x.o  COBJS-$(CONFIG_DRIVER_NS9750_ETHERNET) += ns9750_eth.o  COBJS-$(CONFIG_PCNET) += pcnet.o  COBJS-$(CONFIG_PLB2800_ETHER) += plb2800_eth.o -COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o  COBJS-$(CONFIG_DRIVER_RTL8019) += rtl8019.o  COBJS-$(CONFIG_RTL8139) += rtl8139.o  COBJS-$(CONFIG_RTL8169) += rtl8169.o  COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o +COBJS-$(CONFIG_SH_ETHER) += sh_eth.o  COBJS-$(CONFIG_DRIVER_SMC91111) += smc91111.o  COBJS-$(CONFIG_DRIVER_SMC911X) += smc911x.o  COBJS-$(CONFIG_TIGON3) += tigon3.o bcm570x_autoneg.o 5701rls.o @@ -68,7 +69,6 @@ COBJS-$(CONFIG_ULI526X) += uli526x.o  COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o  COBJS-$(CONFIG_XILINX_EMAC) += xilinx_emac.o  COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o -COBJS-$(CONFIG_SH_ETHER) += sh_eth.o  COBJS	:= $(COBJS-y)  SRCS	:= $(COBJS:.o=.c) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 98e8c73ca..af0409bd2 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -317,6 +317,30 @@ static void macb_phy_reset(struct macb_device *macb)  		       netdev->name, status);  } +#ifdef CONFIG_MACB_SEARCH_PHY +static int macb_phy_find(struct macb_device *macb) +{ +	int i; +	u16 phy_id; + +	/* Search for PHY... */ +	for (i = 0; i < 32; i++) { +		macb->phy_addr = i; +		phy_id = macb_mdio_read(macb, MII_PHYSID1); +		if (phy_id != 0xffff) { +			printf("%s: PHY present at %d\n", macb->netdev.name, i); +			return 1; +		} +	} + +	/* PHY isn't up to snuff */ +	printf("%s: PHY not found", macb->netdev.name); + +	return 0; +} +#endif /* CONFIG_MACB_SEARCH_PHY */ + +  static int macb_phy_init(struct macb_device *macb)  {  	struct eth_device *netdev = &macb->netdev; @@ -325,6 +349,13 @@ static int macb_phy_init(struct macb_device *macb)  	int media, speed, duplex;  	int i; +#ifdef CONFIG_MACB_SEARCH_PHY +	/* Auto-detect phy_addr */ +	if (!macb_phy_find(macb)) { +		return 0; +	} +#endif /* CONFIG_MACB_SEARCH_PHY */ +  	/* Check if the PHY is up to snuff... */  	phy_id = macb_mdio_read(macb, MII_PHYSID1);  	if (phy_id == 0xffff) { diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 9e3cf98b3..ebe858894 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -24,6 +24,7 @@  #include <common.h>  #include <malloc.h>  #include <net.h> +#include <netdev.h>  #include <asm/errno.h>  #include <asm/io.h> @@ -36,12 +37,7 @@  # error "Please define CONFIG_SH_ETHER_PHY_ADDR"  #endif -extern int eth_init(bd_t *bd); -extern void eth_halt(void); -extern int eth_rx(void); -extern int eth_send(volatile void *packet, int length); - -static struct dev_info_s *dev; +#define SH_ETH_PHY_DELAY 50000  /*   * Bits are written to the PHY serially using the @@ -89,7 +85,7 @@ static void sh_eth_mii_ind_bus_release(int port)  	udelay(1);  } -static int sh_eth_mii_read_phy_bits(int port, u32 * val, int len) +static void sh_eth_mii_read_phy_bits(int port, u32 *val, int len)  {  	int i;  	u32 pir; @@ -106,8 +102,6 @@ static int sh_eth_mii_read_phy_bits(int port, u32 * val, int len)  		outl(0, PIR(port));  		udelay(1);  	} - -	return 0;  }  #define PHY_INIT	0xFFFFFFFF @@ -183,26 +177,23 @@ static void sh_eth_mii_write_phy_reg(int port, u8 phy_addr, int reg, u16 val)  	sh_eth_mii_ind_bus_release(port);  } -void eth_halt(void) -{ -} - -int eth_send(volatile void *packet, int len) +int sh_eth_send(struct eth_device *dev, volatile void *packet, int len)  { -	int port = dev->port; -	struct port_info_s *port_info = &dev->port_info[port]; -	int timeout; -	int rc = 0; +	struct sh_eth_dev *eth = dev->priv; +	int port = eth->port, ret = 0, timeout; +	struct sh_eth_info *port_info = ð->port_info[port];  	if (!packet || len > 0xffff) { -		printf("eth_send: Invalid argument\n"); -		return -EINVAL; +		printf(SHETHER_NAME ": %s: Invalid argument\n", __func__); +		ret = -EINVAL; +		goto err;  	}  	/* packet must be a 4 byte boundary */  	if ((int)packet & (4 - 1)) { -		printf("eth_send: packet not 4 byte alligned\n"); -		return -EFAULT; +		printf(SHETHER_NAME ": %s: packet not 4 byte alligned\n", __func__); +		ret = -EFAULT; +		goto err;  	}  	/* Update tx descriptor */ @@ -224,24 +215,25 @@ int eth_send(volatile void *packet, int len)  		udelay(100);  	if (timeout < 0) { -		printf("eth_send: transmit timeout\n"); -		rc = -1; +		printf(SHETHER_NAME ": transmit timeout\n"); +		ret = -ETIMEDOUT;  		goto err;  	} -err:  	port_info->tx_desc_cur++;  	if (port_info->tx_desc_cur >= port_info->tx_desc_base + NUM_TX_DESC)  		port_info->tx_desc_cur = port_info->tx_desc_base; -	return rc; +	return ret; +err: +	return ret;  } -int eth_rx(void) +int sh_eth_recv(struct eth_device *dev)  { -	int port = dev->port; -	struct port_info_s *port_info = &dev->port_info[port]; -	int len = 0; +	struct sh_eth_dev *eth = dev->priv; +	int port = eth->port, len = 0; +	struct sh_eth_info *port_info = ð->port_info[port];  	volatile u8 *packet;  	/* Check if the rx descriptor is ready */ @@ -275,10 +267,10 @@ int eth_rx(void)  }  #define EDMR_INIT_CNT 1000 -static int sh_eth_reset(struct dev_info_s *dev) +static int sh_eth_reset(struct sh_eth_dev *eth)  { -	int port = dev->port; -	int i; +	int port = eth->port; +	int ret = 0, i;  	/* Start e-dmac transmitter and receiver */  	outl(EDSR_ENALL, EDSR(port)); @@ -292,33 +284,36 @@ static int sh_eth_reset(struct dev_info_s *dev)  	}  	if (i == EDMR_INIT_CNT) { -		printf("Error: Software reset timeout\n"); -		return -1; +		printf(SHETHER_NAME  ": Software reset timeout\n"); +		ret = -EIO;  	} -	return 0; + +	return ret;  } -static int sh_eth_tx_desc_init(struct dev_info_s *dev) +static int sh_eth_tx_desc_init(struct sh_eth_dev *eth)  { -	int port = dev->port; -	struct port_info_s *port_info = &dev->port_info[port]; +	int port = eth->port, i, ret = 0;  	u32 tmp_addr; +	struct sh_eth_info *port_info = ð->port_info[port];  	struct tx_desc_s *cur_tx_desc; -	int i; -	/* Allocate tx descriptors. They must be TX_DESC_SIZE bytes -	   aligned */ -	if (!(port_info->tx_desc_malloc = malloc(NUM_TX_DESC * +	/* +	 * Allocate tx descriptors. They must be TX_DESC_SIZE bytes aligned +	 */ +	port_info->tx_desc_malloc = malloc(NUM_TX_DESC *  						 sizeof(struct tx_desc_s) + -						 TX_DESC_SIZE - 1))) { -		printf("Error: malloc failed\n"); -		return -ENOMEM; +						 TX_DESC_SIZE - 1); +	if (!port_info->tx_desc_malloc) { +		printf(SHETHER_NAME ": malloc failed\n"); +		ret = -ENOMEM; +		goto err;  	} +  	tmp_addr = (u32) (((int)port_info->tx_desc_malloc + TX_DESC_SIZE - 1) &  			  ~(TX_DESC_SIZE - 1));  	/* Make sure we use a P2 address (non-cacheable) */  	port_info->tx_desc_base = (struct tx_desc_s *)ADDR_TO_P2(tmp_addr); -  	port_info->tx_desc_cur = port_info->tx_desc_base;  	/* Initialize all descriptors */ @@ -340,26 +335,30 @@ static int sh_eth_tx_desc_init(struct dev_info_s *dev)  	outl(ADDR_TO_PHY(cur_tx_desc), TDFXR(port));  	outl(0x01, TDFFR(port));/* Last discriptor bit */ -	return 0; +err: +	return ret;  } -static int sh_eth_rx_desc_init(struct dev_info_s *dev) +static int sh_eth_rx_desc_init(struct sh_eth_dev *eth)  { -	int port = dev->port; -	struct port_info_s *port_info = &dev->port_info[port]; -	u32 tmp_addr; +	int port = eth->port, i , ret = 0; +	struct sh_eth_info *port_info = ð->port_info[port];  	struct rx_desc_s *cur_rx_desc; +	u32 tmp_addr;  	u8 *rx_buf; -	int i; -	/* Allocate rx descriptors. They must be RX_DESC_SIZE bytes -	   aligned */ -	if (!(port_info->rx_desc_malloc = malloc(NUM_RX_DESC * +	/* +	 * Allocate rx descriptors. They must be RX_DESC_SIZE bytes aligned +	 */ +	port_info->rx_desc_malloc = malloc(NUM_RX_DESC *  						 sizeof(struct rx_desc_s) + -						 RX_DESC_SIZE - 1))) { -		printf("Error: malloc failed\n"); -		return -ENOMEM; +						 RX_DESC_SIZE - 1); +	if (!port_info->rx_desc_malloc) { +		printf(SHETHER_NAME ": malloc failed\n"); +		ret = -ENOMEM; +		goto err;  	} +  	tmp_addr = (u32) (((int)port_info->rx_desc_malloc + RX_DESC_SIZE - 1) &  			  ~(RX_DESC_SIZE - 1));  	/* Make sure we use a P2 address (non-cacheable) */ @@ -367,15 +366,17 @@ static int sh_eth_rx_desc_init(struct dev_info_s *dev)  	port_info->rx_desc_cur = port_info->rx_desc_base; -	/* Allocate rx data buffers. They must be 32 bytes aligned  and in -	   P2 area */ -	if (!(port_info->rx_buf_malloc = malloc(NUM_RX_DESC * MAX_BUF_SIZE + -						31))) { -		printf("Error: malloc failed\n"); -		free(port_info->rx_desc_malloc); -		port_info->rx_desc_malloc = NULL; -		return -ENOMEM; +	/* +	 * Allocate rx data buffers. They must be 32 bytes aligned  and in +	 * P2 area +	 */ +	port_info->rx_buf_malloc = malloc(NUM_RX_DESC * MAX_BUF_SIZE + 31); +	if (!port_info->rx_buf_malloc) { +		printf(SHETHER_NAME ": malloc failed\n"); +		ret = -ENOMEM; +		goto err_buf_malloc;  	} +  	tmp_addr = (u32)(((int)port_info->rx_buf_malloc + (32 - 1)) &  			  ~(32 - 1));  	port_info->rx_buf_base = (u8 *)ADDR_TO_P2(tmp_addr); @@ -399,18 +400,31 @@ static int sh_eth_rx_desc_init(struct dev_info_s *dev)  	outl(ADDR_TO_PHY(cur_rx_desc), RDFXR(port));  	outl(RDFFR_RDLF, RDFFR(port)); -	return 0; +	return ret; + +err_buf_malloc: +	free(port_info->rx_desc_malloc); +	port_info->rx_desc_malloc = NULL; + +err: +	return ret;  } -static void sh_eth_desc_free(struct dev_info_s *dev) +static void sh_eth_tx_desc_free(struct sh_eth_dev *eth)  { -	int port = dev->port; -	struct port_info_s *port_info = &dev->port_info[port]; +	int port = eth->port; +	struct sh_eth_info *port_info = ð->port_info[port];  	if (port_info->tx_desc_malloc) {  		free(port_info->tx_desc_malloc);  		port_info->tx_desc_malloc = NULL;  	} +} + +static void sh_eth_rx_desc_free(struct sh_eth_dev *eth) +{ +	int port = eth->port; +	struct sh_eth_info *port_info = ð->port_info[port];  	if (port_info->rx_desc_malloc) {  		free(port_info->rx_desc_malloc); @@ -423,36 +437,48 @@ static void sh_eth_desc_free(struct dev_info_s *dev)  	}  } -static int sh_eth_desc_init(struct dev_info_s *dev) +static int sh_eth_desc_init(struct sh_eth_dev *eth)  { -	int rc; +	int ret = 0; -	if ((rc = sh_eth_tx_desc_init(dev)) || (rc = sh_eth_rx_desc_init(dev))) { -		sh_eth_desc_free(dev); -		return rc; -	} +	ret = sh_eth_tx_desc_init(eth); +	if (ret) +		goto err_tx_init; -	return 0; +	ret = sh_eth_rx_desc_init(eth); +	if (ret) +		goto err_rx_init; + +	return ret; +err_rx_init: +	sh_eth_tx_desc_free(eth); + +err_tx_init: +	return ret;  } -static int sh_eth_phy_config(struct dev_info_s *dev) +static int sh_eth_phy_config(struct sh_eth_dev *eth)  { -	int port = dev->port; -	struct port_info_s *port_info = &dev->port_info[port]; -	int timeout; +	int port = eth->port, timeout, ret = 0; +	struct sh_eth_info *port_info = ð->port_info[port];  	u32 val; +  	/* Reset phy */ -	sh_eth_mii_write_phy_reg(port, port_info->phy_addr, PHY_CTRL, PHY_C_RESET); +	sh_eth_mii_write_phy_reg +		(port, port_info->phy_addr, PHY_CTRL, PHY_C_RESET);  	timeout = 10;  	while (timeout--) { -		val = sh_eth_mii_read_phy_reg(port, port_info->phy_addr, PHY_CTRL); +		val = sh_eth_mii_read_phy_reg(port, +				port_info->phy_addr, PHY_CTRL);  		if (!(val & PHY_C_RESET))  			break; -		udelay(50000); +		udelay(SH_ETH_PHY_DELAY);  	} +  	if (timeout < 0) { -		printf("%s phy reset timeout\n", __func__); -		return -1; +		printf(SHETHER_NAME ": phy reset timeout\n"); +		ret = -EIO; +		goto err_tout;  	}  	/* Advertise 100/10 baseT full/half duplex */ @@ -467,23 +493,27 @@ static int sh_eth_phy_config(struct dev_info_s *dev)  		val = sh_eth_mii_read_phy_reg(port, port_info->phy_addr, 1);  		if (val & PHY_S_ANEGC)  			break; -		udelay(50000); + +		udelay(SH_ETH_PHY_DELAY);  	} +  	if (timeout < 0) { -		printf("sh_eth_phy_config() phy auto-negotiation failed\n"); -		return -1; +		printf(SHETHER_NAME ": phy auto-negotiation failed\n"); +		ret = -ETIMEDOUT; +		goto err_tout;  	} -	return 0; +	return ret; + +err_tout: +	return ret;  } -static int sh_eth_config(struct dev_info_s *dev, bd_t * bd) +static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd)  { -	int port = dev->port; -	struct port_info_s *port_info = &dev->port_info[port]; -	u32 val; -	u32 phy_status; -	int rc; +	int port = eth->port, ret = 0; +	u32 val,  phy_status; +	struct sh_eth_info *port_info = ð->port_info[port];  	/* Configure e-dmac registers */  	outl((inl(EDMR(port)) & ~EMDR_DESC_R) | EDMR_EL, EDMR(port)); @@ -513,20 +543,20 @@ static int sh_eth_config(struct dev_info_s *dev, bd_t * bd)  	outl(TPAUSER_TPAUSE, TPAUSER(port));  	/* Configure phy */ -	if ((rc = sh_eth_phy_config(dev))) -		return rc; - +	ret = sh_eth_phy_config(eth); +	if (ret) { +		printf(SHETHER_NAME ":i phy config timeout\n"); +		goto err_phy_cfg; +	}  	/* Read phy status to finish configuring the e-mac */ -	phy_status = sh_eth_mii_read_phy_reg(dev->port, -					     dev->port_info[dev->port].phy_addr, -					     1); +	phy_status = sh_eth_mii_read_phy_reg(port, port_info->phy_addr, 1);  	/* Set the transfer speed */  	if (phy_status & (PHY_S_100X_F|PHY_S_100X_H)) { -		printf("100Base/"); +		printf(SHETHER_NAME ": 100Base/");  		outl(GECMR_100B, GECMR(port));  	} else { -		printf("10Base/"); +		printf(SHETHER_NAME ": 10Base/");  		outl(GECMR_10B, GECMR(port));  	} @@ -538,27 +568,34 @@ static int sh_eth_config(struct dev_info_s *dev, bd_t * bd)  		printf("Half\n");  		outl((ECMR_CHG_DM|ECMR_RE|ECMR_TE),  ECMR(port));  	} -	return 0; + +	return ret; + +err_phy_cfg: +	return ret;  } -static int sh_eth_start(struct dev_info_s *dev) +static void sh_eth_start(struct sh_eth_dev *eth)  {  	/*  	 * Enable the e-dmac receiver only. The transmitter will be enabled when  	 * we have something to transmit  	 */ -	outl(EDRRR_R, EDRRR(dev->port)); +	outl(EDRRR_R, EDRRR(eth->port)); +} -	return 0; +static void sh_eth_stop(struct sh_eth_dev *eth) +{ +	outl(~EDRRR_R, EDRRR(eth->port));  }  static int sh_eth_get_mac(bd_t *bd)  {  	char *s, *e; -	int i;  	s = getenv("ethaddr");  	if (s != NULL) { +		int i;  		for (i = 0; i < 6; ++i) {  			bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0;  			if (s) @@ -570,34 +607,92 @@ static int sh_eth_get_mac(bd_t *bd)  	return 0;  } -int eth_init(bd_t *bd) +int sh_eth_init(struct eth_device *dev, bd_t *bd)  { -	int rc; -	/* Allocate main device information structure */ -	if (!(dev = malloc(sizeof(*dev)))) { -		printf("eth_init: malloc failed\n"); -		return -ENOMEM; -	} +	int ret = 0; +	struct sh_eth_dev *eth = dev->priv; -	memset(dev, 0, sizeof(*dev)); +	ret = sh_eth_reset(eth); +	if (ret) +		goto err; -	dev->port = CONFIG_SH_ETHER_USE_PORT; -	dev->port_info[dev->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR; +	ret = sh_eth_desc_init(eth); +	if (ret) +		goto err; -	sh_eth_get_mac(bd); +	ret = sh_eth_config(eth, bd); +	if (ret) +		goto err_config; + +	sh_eth_start(eth); + +	return ret; -	if ((rc = sh_eth_reset(dev)) || (rc = sh_eth_desc_init(dev))) +err_config: +	sh_eth_tx_desc_free(eth); +	sh_eth_rx_desc_free(eth); + +err: +	return ret; +} + +void sh_eth_halt(struct eth_device *dev) +{ +	struct sh_eth_dev *eth = dev->priv; + +	sh_eth_reset(eth); +	sh_eth_stop(eth); +} + +int sh_eth_initialize(bd_t *bd) +{ +    int ret = 0; +	struct sh_eth_dev *eth = NULL; +    struct eth_device *dev = NULL; + +    eth = (struct sh_eth_dev *)malloc(sizeof(struct sh_eth_dev)); +	if (!eth) { +		printf(SHETHER_NAME ": %s: malloc failed\n", __func__); +		ret = -ENOMEM; +		goto err; +	} + +    dev = (struct eth_device *)malloc(sizeof(struct eth_device)); +	if (!dev) { +		printf(SHETHER_NAME ": %s: malloc failed\n", __func__); +		ret = -ENOMEM;  		goto err; +	} +    memset(dev, 0, sizeof(struct eth_device)); +    memset(eth, 0, sizeof(struct sh_eth_dev)); -	if ((rc = sh_eth_config(dev, bd)) || (rc = sh_eth_start(dev))) -		goto err_desc; +	eth->port = CONFIG_SH_ETHER_USE_PORT; +	eth->port_info[eth->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR; -	return 0; +    dev->priv = (void *)eth; +    dev->iobase = 0; +    dev->init = sh_eth_init; +    dev->halt = sh_eth_halt; +    dev->send = sh_eth_send; +    dev->recv = sh_eth_recv; +    eth->port_info[eth->port].dev = dev; + +	sprintf(dev->name, SHETHER_NAME); + +    /* Register Device to EtherNet subsystem  */ +    eth_register(dev); + +	sh_eth_get_mac(bd); + +	return ret; -err_desc: -	sh_eth_desc_free(dev);  err: -	free(dev); -	printf("eth_init: Failed\n"); -	return rc; +	if (dev) +		free(dev); + +	if (eth) +		free(eth); + +	printf(SHETHER_NAME ": Failed\n"); +	return ret;  } diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index 9cf0ea0b9..a13fff02c 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -20,6 +20,7 @@   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */ +#include <netdev.h>  #include <asm/types.h>  #define SHETHER_NAME "sh_eth" @@ -48,7 +49,7 @@  #define TX_DESC_PADDING		4  #define TX_DESC_SIZE		(12 + TX_DESC_PADDING) -/* Tx descriptor. We always use 4 bytes of padding */ +/* Tx descriptor. We always use 3 bytes of padding */  struct tx_desc_s {  	volatile u32 td0;  	u32 td1; @@ -72,7 +73,7 @@ struct rx_desc_s {  	u32 padding;  }; -struct port_info_s { +struct sh_eth_info {  	struct tx_desc_s *tx_desc_malloc;  	struct tx_desc_s *tx_desc_base;  	struct tx_desc_s *tx_desc_cur; @@ -83,11 +84,12 @@ struct port_info_s {  	u8 *rx_buf_base;  	u8 mac_addr[6];  	u8 phy_addr; +	struct eth_device *dev;  }; -struct dev_info_s { +struct sh_eth_dev {  	int port; -	struct port_info_s port_info[MAX_PORT_NUM]; +	struct sh_eth_info port_info[MAX_PORT_NUM];  };  /* Register Address */ diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 648c94cbb..9cc4fce00 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -34,21 +34,24 @@  #endif  #if defined (CONFIG_DRIVER_SMC911X_32_BIT) -static inline u32 reg_read(u32 addr) +static inline u32 __smc911x_reg_read(u32 addr)  {  	return *(volatile u32*)addr;  } -static inline void reg_write(u32 addr, u32 val) +u32 smc911x_reg_read(u32 addr) __attribute__((weak, alias("__smc911x_reg_read"))); + +static inline void __smc911x_reg_write(u32 addr, u32 val)  {  	*(volatile u32*)addr = val;  } +void smc911x_reg_write(u32 addr, u32 val) __attribute__((weak, alias("__smc911x_reg_write")));  #elif defined (CONFIG_DRIVER_SMC911X_16_BIT) -static inline u32 reg_read(u32 addr) +static inline u32 smc911x_reg_read(u32 addr)  {  	volatile u16 *addr_16 = (u16 *)addr;  	return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16));  } -static inline void reg_write(u32 addr, u32 val) +static inline void smc911x_reg_write(u32 addr, u32 val)  {  	*(volatile u16*)addr = (u16)val;  	*(volatile u16*)(addr + 2) = (u16)(val >> 16); @@ -58,9 +61,9 @@ static inline void reg_write(u32 addr, u32 val)  #endif /* CONFIG_DRIVER_SMC911X_16_BIT */  u32 pkt_data_pull(u32 addr) \ -	__attribute__ ((weak, alias ("reg_read"))); +	__attribute__ ((weak, alias ("smc911x_reg_read")));  void pkt_data_push(u32 addr, u32 val) \ -	__attribute__ ((weak, alias ("reg_write"))); +	__attribute__ ((weak, alias ("smc911x_reg_write")));  #define mdelay(n)       udelay((n)*1000) @@ -381,6 +384,7 @@ void pkt_data_push(u32 addr, u32 val) \  #define CHIP_9116	0x116  #define CHIP_9117	0x117  #define CHIP_9118	0x118 +#define CHIP_9211	0x9211  #define CHIP_9215	0x115a  #define CHIP_9216	0x116a  #define CHIP_9217	0x117a @@ -396,6 +400,7 @@ static const struct chip_id chip_ids[] =  {  	{ CHIP_9116, "LAN9116" },  	{ CHIP_9117, "LAN9117" },  	{ CHIP_9118, "LAN9118" }, +	{ CHIP_9211, "LAN9211" },  	{ CHIP_9215, "LAN9215" },  	{ CHIP_9216, "LAN9216" },  	{ CHIP_9217, "LAN9217" }, @@ -407,22 +412,22 @@ static const struct chip_id chip_ids[] =  {  u32 smc911x_get_mac_csr(u8 reg)  { -	while (reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) +	while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)  		; -	reg_write(MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg); -	while (reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) +	smc911x_reg_write(MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg); +	while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)  		; -	return reg_read(MAC_CSR_DATA); +	return smc911x_reg_read(MAC_CSR_DATA);  }  void smc911x_set_mac_csr(u8 reg, u32 data)  { -	while (reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) +	while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)  		; -	reg_write(MAC_CSR_DATA, data); -	reg_write(MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg); -	while (reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) +	smc911x_reg_write(MAC_CSR_DATA, data); +	smc911x_reg_write(MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg); +	while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)  		;  } @@ -496,10 +501,10 @@ static int smc911x_phy_reset(void)  {  	u32 reg; -	reg = reg_read(PMT_CTRL); +	reg = smc911x_reg_read(PMT_CTRL);  	reg &= ~0xfffff030;  	reg |= PMT_CTRL_PHY_RST; -	reg_write(PMT_CTRL, reg); +	smc911x_reg_write(PMT_CTRL, reg);  	mdelay(100); @@ -541,13 +546,13 @@ static void smc911x_reset(void)  	int timeout;  	/* Take out of PM setting first */ -	if (reg_read(PMT_CTRL) & PMT_CTRL_READY) { +	if (smc911x_reg_read(PMT_CTRL) & PMT_CTRL_READY) {  		/* Write to the bytetest will take out of powerdown */ -		reg_write(BYTE_TEST, 0x0); +		smc911x_reg_write(BYTE_TEST, 0x0);  		timeout = 10; -		while (timeout-- && !(reg_read(PMT_CTRL) & PMT_CTRL_READY)) +		while (timeout-- && !(smc911x_reg_read(PMT_CTRL) & PMT_CTRL_READY))  			udelay(10);  		if (!timeout) {  			printf(DRIVERNAME @@ -557,12 +562,12 @@ static void smc911x_reset(void)  	}  	/* Disable interrupts */ -	reg_write(INT_EN, 0); +	smc911x_reg_write(INT_EN, 0); -	reg_write(HW_CFG, HW_CFG_SRST); +	smc911x_reg_write(HW_CFG, HW_CFG_SRST);  	timeout = 1000; -	while (timeout-- && reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY) +	while (timeout-- && smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY)  		udelay(10);  	if (!timeout) { @@ -572,23 +577,23 @@ static void smc911x_reset(void)  	/* Reset the FIFO level and flow control settings */  	smc911x_set_mac_csr(FLOW, FLOW_FCPT | FLOW_FCEN); -	reg_write(AFC_CFG, 0x0050287F); +	smc911x_reg_write(AFC_CFG, 0x0050287F);  	/* Set to LED outputs */ -	reg_write(GPIO_CFG, 0x70070000); +	smc911x_reg_write(GPIO_CFG, 0x70070000);  }  static void smc911x_enable(void)  {  	/* Enable TX */ -	reg_write(HW_CFG, 8 << 16 | HW_CFG_SF); +	smc911x_reg_write(HW_CFG, 8 << 16 | HW_CFG_SF); -	reg_write(GPT_CFG, GPT_CFG_TIMER_EN | 10000); +	smc911x_reg_write(GPT_CFG, GPT_CFG_TIMER_EN | 10000); -	reg_write(TX_CFG, TX_CFG_TX_ON); +	smc911x_reg_write(TX_CFG, TX_CFG_TX_ON);  	/* no padding to start of packets */ -	reg_write(RX_CFG, 0); +	smc911x_reg_write(RX_CFG, 0);  	smc911x_set_mac_csr(MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN | MAC_CR_HBDIS); @@ -600,13 +605,13 @@ int eth_init(bd_t *bd)  	printf(DRIVERNAME ": initializing\n"); -	val = reg_read(BYTE_TEST); +	val = smc911x_reg_read(BYTE_TEST);  	if (val != 0x87654321) {  		printf(DRIVERNAME ": Invalid chip endian 0x%08lx\n", val);  		goto err_out;  	} -	val = reg_read(ID_REV) >> 16; +	val = smc911x_reg_read(ID_REV) >> 16;  	for (i = 0; chip_ids[i].id != 0; i++) {  		if (chip_ids[i].id == val) break;  	} @@ -640,8 +645,8 @@ int eth_send(volatile void *packet, int length)  	u32 tmplen;  	u32 status; -	reg_write(TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | TX_CMD_A_INT_LAST_SEG | length); -	reg_write(TX_DATA_FIFO, length); +	smc911x_reg_write(TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | TX_CMD_A_INT_LAST_SEG | length); +	smc911x_reg_write(TX_DATA_FIFO, length);  	tmplen = (length + 3) / 4; @@ -649,12 +654,12 @@ int eth_send(volatile void *packet, int length)  		pkt_data_push(TX_DATA_FIFO, *data++);  	/* wait for transmission */ -	while (!((reg_read(TX_FIFO_INF) & TX_FIFO_INF_TSUSED) >> 16)); +	while (!((smc911x_reg_read(TX_FIFO_INF) & TX_FIFO_INF_TSUSED) >> 16));  	/* get status. Ignore 'no carrier' error, it has no meaning for  	 * full duplex operation  	 */ -	status = reg_read(TX_STATUS_FIFO) & (TX_STS_LOC | TX_STS_LATE_COLL | +	status = smc911x_reg_read(TX_STATUS_FIFO) & (TX_STS_LOC | TX_STS_LATE_COLL |  		TX_STS_MANY_COLL | TX_STS_MANY_DEFER | TX_STS_UNDERRUN);  	if (!status) @@ -681,11 +686,11 @@ int eth_rx(void)  	u32 pktlen, tmplen;  	u32 status; -	if ((reg_read(RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) { -		status = reg_read(RX_STATUS_FIFO); +	if ((smc911x_reg_read(RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) { +		status = smc911x_reg_read(RX_STATUS_FIFO);  		pktlen = (status & RX_STS_PKT_LEN) >> 16; -		reg_write(RX_CFG, 0); +		smc911x_reg_write(RX_CFG, 0);  		tmplen = (pktlen + 2+ 3) / 4;  		while (tmplen--) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index fbc9a6dd0..dc90f2385 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -1141,6 +1141,9 @@ struct phy_info phy_info_M88E1118 = {  		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},  		{0x16, 0x0002, NULL}, /* Change Page Number */  		{0x15, 0x1070, NULL}, /* Delay RGMII TX and RX */ +		{0x16, 0x0003, NULL}, /* Change Page Number */ +		{0x10, 0x021e, NULL}, /* Adjust LED control */ +		{0x16, 0x0000, NULL}, /* Change Page Number */  		{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},  		{MIIM_ANAR, MIIM_ANAR_INIT, NULL},  		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, @@ -1152,6 +1155,7 @@ struct phy_info phy_info_M88E1118 = {  		/* Status is read once to clear old link state */  		{MIIM_STATUS, miim_read, NULL},  		/* Auto-negotiate */ +		{MIIM_STATUS, miim_read, &mii_parse_sr},  		/* Read the status */  		{MIIM_88E1011_PHY_STATUS, miim_read,  		 &mii_parse_88E1011_psr}, diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c index 829f08285..d613f3e4c 100644 --- a/drivers/qe/uec_phy.c +++ b/drivers/qe/uec_phy.c @@ -603,6 +603,55 @@ static int fixed_phy_read_status (struct uec_mii_info *mii_info)  	return 0;  } +static int smsc_config_aneg (struct uec_mii_info *mii_info) +{ +	return 0; +} + +static int smsc_read_status (struct uec_mii_info *mii_info) +{ +	u16 status; +	int err; + +	/* Update the link, but return if there +	 * was an error */ +	err = genmii_update_link (mii_info); +	if (err) +		return err; + +	/* If the link is up, read the speed and duplex */ +	/* If we aren't autonegotiating, assume speeds +	 * are as set */ +	if (mii_info->autoneg && mii_info->link) { +		int	val; + +		status = phy_read (mii_info, 0x1f); +		val = (status & 0x1c) >> 2; + +		switch (val) { +			case 1: +				mii_info->duplex = DUPLEX_HALF; +				mii_info->speed = SPEED_10; +				break; +			case 5: +				mii_info->duplex = DUPLEX_FULL; +				mii_info->speed = SPEED_10; +				break; +			case 2: +				mii_info->duplex = DUPLEX_HALF; +				mii_info->speed = SPEED_100; +				break; +			case 6: +				mii_info->duplex = DUPLEX_FULL; +				mii_info->speed = SPEED_100; +				break; +		} +		mii_info->pause = 0; +	} + +	return 0; +} +  static struct phy_info phy_info_dm9161 = {  	.phy_id = 0x0181b880,  	.phy_id_mask = 0x0ffffff0, @@ -655,6 +704,15 @@ static struct phy_info phy_info_fixedphy = {  	.read_status = fixed_phy_read_status,  }; +static struct phy_info phy_info_smsclan8700 = { +	.phy_id = 0x0007c0c0, +	.phy_id_mask = 0xfffffff0, +	.name = "SMSC LAN8700", +	.features = MII_BASIC_FEATURES, +	.config_aneg = smsc_config_aneg, +	.read_status = smsc_read_status, +}; +  static struct phy_info phy_info_genmii = {  	.phy_id = 0x00000000,  	.phy_id_mask = 0x00000000, @@ -669,6 +727,7 @@ static struct phy_info *phy_info[] = {  	&phy_info_dm9161a,  	&phy_info_marvell,  	&phy_info_bcm5481, +	&phy_info_smsclan8700,  	&phy_info_fixedphy,  	&phy_info_genmii,  	NULL diff --git a/include/configs/sh7763rdp.h b/include/configs/sh7763rdp.h index 8a76dad5d..4ea79cf33 100644 --- a/include/configs/sh7763rdp.h +++ b/include/configs/sh7763rdp.h @@ -118,6 +118,7 @@  #define CONFIG_SYS_HZ				(CONFIG_SYS_CLK_FREQ / TMU_CLK_DIVIDER)  /* Ether */ +#define CONFIG_NET_MULTI 1  #define CONFIG_SH_ETHER 1  #define CONFIG_SH_ETHER_USE_PORT (1)  #define CONFIG_SH_ETHER_PHY_ADDR (0x01) diff --git a/include/net.h b/include/net.h index d2d394f0d..bbe0d4b5a 100644 --- a/include/net.h +++ b/include/net.h @@ -474,6 +474,22 @@ static inline int is_multicast_ether_addr(const u8 *addr)  	return (0x01 & addr[0]);  } +/** + * is_valid_ether_addr - Determine if the given Ethernet address is valid + * @addr: Pointer to a six-byte array containing the Ethernet address + * + * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not + * a multicast address, and is not FF:FF:FF:FF:FF:FF. + * + * Return true if the address is valid. + */ +static inline int is_valid_ether_addr(const u8 * addr) +{ +	/* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to +	 * explicitly check for it here. */ +	return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr); +} +  /* Convert an IP address to a string */  extern void	ip_to_string (IPaddr_t x, char *s); diff --git a/include/netdev.h b/include/netdev.h index 751f0dab5..ce1ecbd8e 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -57,6 +57,7 @@ int mcffec_initialize(bd_t *bis);  int mpc512x_fec_initialize(bd_t *bis);  int mpc5xxx_fec_initialize(bd_t *bis);  int mpc8220_fec_initialize(bd_t *bis); +int mpc82xx_scc_enet_initialize(bd_t *bis);  int natsemi_initialize(bd_t *bis);  int npe_initialize(bd_t *bis);  int ns8382x_initialize(bd_t *bis); @@ -70,6 +71,7 @@ int skge_initialize(bd_t *bis);  int tsi108_eth_initialize(bd_t *bis);  int uec_initialize(int index);  int uli526x_initialize(bd_t *bis); +int sh_eth_initialize(bd_t *bis);  /* Boards with PCI network controllers can call this from their board_eth_init()   * function to initialize whatever's on board. @@ -1684,7 +1684,7 @@ NetSetEther(volatile uchar * xet, uchar * addr, uint prot)  void  NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len)  { -	volatile IP_t *ip = (IP_t *)xip; +	IP_t *ip = (IP_t *)xip;  	/*  	 *	If the data is an odd number of bytes, zero the |