diff options
| -rw-r--r-- | README | 15 | ||||
| -rw-r--r-- | drivers/net/dm9000x.c | 387 | ||||
| -rw-r--r-- | drivers/net/e1000.c | 2 | ||||
| -rw-r--r-- | drivers/net/e1000.h | 3 | ||||
| -rw-r--r-- | drivers/net/mcffec.c | 6 | ||||
| -rw-r--r-- | drivers/net/smc911x.c | 21 | ||||
| -rw-r--r-- | drivers/net/tsec.c | 31 | ||||
| -rw-r--r-- | include/configs/scb9328.h | 4 | ||||
| -rw-r--r-- | include/configs/trizepsiv.h | 4 | ||||
| -rw-r--r-- | include/pci_ids.h | 3 | ||||
| -rw-r--r-- | net/net.c | 4 | 
11 files changed, 345 insertions, 135 deletions
| @@ -786,6 +786,21 @@ The following options need to be configured:  			Define this to use i/o functions instead of macros  			(some hardware wont work with macros) +		CONFIG_DRIVER_SMC911X +		Support for SMSC's LAN911x and LAN921x chips + +			CONFIG_DRIVER_SMC911X_BASE +			Define this to hold the physical address +			of the device (I/O space) + +			CONFIG_DRIVER_SMC911X_32_BIT +			Define this if data bus is 32 bits + +			CONFIG_DRIVER_SMC911X_16_BIT +			Define this if data bus is 16 bits. If your processor +			automatically converts one 32 bit word to two 16 bit +			words you may also try CONFIG_DRIVER_SMC911X_32_BIT. +  - USB Support:  		At the moment only the UHCI host controller is  		supported (PIP405, MIP405, MPC5200); define diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 68901cd81..fa95a730c 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -36,7 +36,24 @@ v1.2   03/18/2003       Weilun Huang <weilun_huang@davicom.com.tw>:  -------------------------------------- -       12/15/2003       Initial port to u-boot by Sascha Hauer <saschahauer@web.de> +       12/15/2003       Initial port to u-boot by +       			Sascha Hauer <saschahauer@web.de> + +       06/03/2008	Remy Bohmer <linux@bohmer.net> +			- Fixed the driver to work with DM9000A. +			  (check on ISR receive status bit before reading the +			  FIFO as described in DM9000 programming guide and +			  application notes) +			- Added autodetect of databus width. +			- Made debug code compile again. +			- Adapt eth_send such that it matches the DM9000* +			  application notes. Needed to make it work properly +			  for DM9000A. +			- Adapted reset procedure to match DM9000 application +			  notes (i.e. double reset) +			- some minor code cleanups +			These changes are tested with DM9000{A,EP,E} together +			with a 200MHz Atmel AT91SAM92161 core  TODO: Homerun NIC and longrun NIC are not functional, only internal at the        moment. @@ -59,10 +76,22 @@ TODO: Homerun NIC and longrun NIC are not functional, only internal at the  /* #define CONFIG_DM9000_DEBUG */  #ifdef CONFIG_DM9000_DEBUG -#define DM9000_DBG(fmt,args...) printf(fmt ,##args) -#else				/*  */ +#define DM9000_DBG(fmt,args...) printf(fmt, ##args) +#define DM9000_DMP_PACKET(func,packet,length)  \ +	do { \ +		int i; 							\ +		printf(func ": length: %d\n", length);			\ +		for (i = 0; i < length; i++) {				\ +			if (i % 8 == 0)					\ +				printf("\n%s: %02x: ", func, i);	\ +			printf("%02x ", ((unsigned char *) packet)[i]);	\ +		} printf("\n");						\ +	} while(0) +#else  #define DM9000_DBG(fmt,args...) -#endif				/*  */ +#define DM9000_DMP_PACKET(func,packet,length) +#endif +  enum DM9000_PHY_mode { DM9000_10MHD = 0, DM9000_100MHD =  	    1, DM9000_10MFD = 4, DM9000_100MFD = 5, DM9000_AUTO =  	    8, DM9000_1M_HPNA = 0x10 @@ -84,8 +113,11 @@ typedef struct board_info {  	u8 device_wait_reset;	/* device state */  	u8 nic_type;		/* NIC type */  	unsigned char srom[128]; +	void (*outblk)(volatile void *data_ptr, int count); +	void (*inblk)(void *data_ptr, int count); +	void (*rx_status)(u16 *RxStatus, u16 *RxLen);  } board_info_t; -board_info_t dmfe_info; +static board_info_t dm9000_info;  /* For module input parameter */  static int media_mode = DM9000_AUTO; @@ -124,10 +156,85 @@ dump_regs(void)  	DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4));  	DM9000_DBG("RCR   (0x05): %02x\n", DM9000_ior(5));  	DM9000_DBG("RSR   (0x06): %02x\n", DM9000_ior(6)); -	DM9000_DBG("ISR   (0xFE): %02x\n", DM9000_ior(ISR)); +	DM9000_DBG("ISR   (0xFE): %02x\n", DM9000_ior(DM9000_ISR));  	DM9000_DBG("\n");  } -#endif				/*  */ +#endif + +static void dm9000_outblk_8bit(volatile void *data_ptr, int count) +{ +	int i; +	for (i = 0; i < count; i++) +		DM9000_outb((((u8 *) data_ptr)[i] & 0xff), DM9000_DATA); +} + +static void dm9000_outblk_16bit(volatile void *data_ptr, int count) +{ +	int i; +	u32 tmplen = (count + 1) / 2; + +	for (i = 0; i < tmplen; i++) +		DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA); +} +static void dm9000_outblk_32bit(volatile void *data_ptr, int count) +{ +	int i; +	u32 tmplen = (count + 3) / 4; + +	for (i = 0; i < tmplen; i++) +		DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA); +} + +static void dm9000_inblk_8bit(void *data_ptr, int count) +{ +	int i; +	for (i = 0; i < count; i++) +		((u8 *) data_ptr)[i] = DM9000_inb(DM9000_DATA); +} + +static void dm9000_inblk_16bit(void *data_ptr, int count) +{ +	int i; +	u32 tmplen = (count + 1) / 2; + +	for (i = 0; i < tmplen; i++) +		((u16 *) data_ptr)[i] = DM9000_inw(DM9000_DATA); +} +static void dm9000_inblk_32bit(void *data_ptr, int count) +{ +	int i; +	u32 tmplen = (count + 3) / 4; + +	for (i = 0; i < tmplen; i++) +		((u32 *) data_ptr)[i] = DM9000_inl(DM9000_DATA); +} + +static void dm9000_rx_status_32bit(u16 *RxStatus, u16 *RxLen) +{ +	u32 tmpdata; + +	DM9000_outb(DM9000_MRCMD, DM9000_IO); + +	tmpdata = DM9000_inl(DM9000_DATA); +	*RxStatus = tmpdata; +	*RxLen = tmpdata >> 16; +} + +static void dm9000_rx_status_16bit(u16 *RxStatus, u16 *RxLen) +{ +	DM9000_outb(DM9000_MRCMD, DM9000_IO); + +	*RxStatus = DM9000_inw(DM9000_DATA); +	*RxLen = DM9000_inw(DM9000_DATA); +} + +static void dm9000_rx_status_8bit(u16 *RxStatus, u16 *RxLen) +{ +	DM9000_outb(DM9000_MRCMD, DM9000_IO); + +	*RxStatus = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8); +	*RxLen = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8); +}  /*    Search DM9000 board, allocate space and register it @@ -236,7 +343,7 @@ program_dm9802(void)  static void  identify_nic(void)  { -	struct board_info *db = &dmfe_info;	/* Point a board information structure */ +	struct board_info *db = &dm9000_info;  	u16 phy_reg3;  	DM9000_iow(DM9000_NCR, NCR_EXT_PHY);  	phy_reg3 = phy_read(3); @@ -263,9 +370,35 @@ identify_nic(void)  static void  dm9000_reset(void)  { -	DM9000_DBG("resetting\n"); -	DM9000_iow(DM9000_NCR, NCR_RST); -	udelay(1000);		/* delay 1ms */ +	DM9000_DBG("resetting DM9000\n"); + +	/* Reset DM9000, +	   see DM9000 Application Notes V1.22 Jun 11, 2004 page 29 */ + +	/* DEBUG: Make all GPIO pins outputs */ +	DM9000_iow(DM9000_GPCR, 0x0F); +	/* Step 1: Power internal PHY by writing 0 to GPIO0 pin */ +	DM9000_iow(DM9000_GPR, 0); +	/* Step 2: Software reset */ +	DM9000_iow(DM9000_NCR, 3); + +	do { +		DM9000_DBG("resetting the DM9000, 1st reset\n"); +		udelay(25); /* Wait at least 20 us */ +	} while (DM9000_ior(DM9000_NCR) & 1); + +	DM9000_iow(DM9000_NCR, 0); +	DM9000_iow(DM9000_NCR, 3); /* Issue a second reset */ + +	do { +		DM9000_DBG("resetting the DM9000, 2nd reset\n"); +		udelay(25); /* Wait at least 20 us */ +	} while (DM9000_ior(DM9000_NCR) & 1); + +	/* Check whether the ethernet controller is present */ +	if ((DM9000_ior(DM9000_PIDL) != 0x0) || +	    (DM9000_ior(DM9000_PIDH) != 0x90)) +		printf("ERROR: resetting DM9000 -> not responding\n");  }  /* Initilize dm9000 board @@ -274,12 +407,46 @@ int  eth_init(bd_t * bd)  {  	int i, oft, lnk; +	u8 io_mode; +	struct board_info *db = &dm9000_info; +  	DM9000_DBG("eth_init()\n");  	/* RESET device */  	dm9000_reset();  	dm9000_probe(); +	/* Auto-detect 8/16/32 bit mode, ISR Bit 6+7 indicate bus width */ +	io_mode = DM9000_ior(DM9000_ISR) >> 6; + +	switch (io_mode) { +	case 0x0:  /* 16-bit mode */ +		printf("DM9000: running in 16 bit mode\n"); +		db->outblk    = dm9000_outblk_16bit; +		db->inblk     = dm9000_inblk_16bit; +		db->rx_status = dm9000_rx_status_16bit; +		break; +	case 0x01:  /* 32-bit mode */ +		printf("DM9000: running in 32 bit mode\n"); +		db->outblk    = dm9000_outblk_32bit; +		db->inblk     = dm9000_inblk_32bit; +		db->rx_status = dm9000_rx_status_32bit; +		break; +	case 0x02: /* 8 bit mode */ +		printf("DM9000: running in 8 bit mode\n"); +		db->outblk    = dm9000_outblk_8bit; +		db->inblk     = dm9000_inblk_8bit; +		db->rx_status = dm9000_rx_status_8bit; +		break; +	default: +		/* Assume 8 bit mode, will probably not work anyway */ +		printf("DM9000: Undefined IO-mode:0x%x\n", io_mode); +		db->outblk    = dm9000_outblk_8bit; +		db->inblk     = dm9000_inblk_8bit; +		db->rx_status = dm9000_rx_status_8bit; +		break; +	} +  	/* NIC Type: FASTETHER, HOMERUN, LONGRUN */  	identify_nic(); @@ -289,15 +456,22 @@ eth_init(bd_t * bd)  	/* Set PHY */  	set_PHY_mode(); -	/* Program operating register */ -	DM9000_iow(DM9000_NCR, 0x0);	/* only intern phy supported by now */ -	DM9000_iow(DM9000_TCR, 0);	/* TX Polling clear */ -	DM9000_iow(DM9000_BPTR, 0x3f);	/* Less 3Kb, 200us */ -	DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));	/* Flow Control : High/Low Water */ -	DM9000_iow(DM9000_FCR, 0x0);	/* SH FIXME: This looks strange! Flow Control */ -	DM9000_iow(DM9000_SMCR, 0);	/* Special Mode */ -	DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);	/* clear TX status */ -	DM9000_iow(DM9000_ISR, 0x0f);	/* Clear interrupt status */ +	/* Program operating register, only intern phy supported by now */ +	DM9000_iow(DM9000_NCR, 0x0); +	/* TX Polling clear */ +	DM9000_iow(DM9000_TCR, 0); +	/* Less 3Kb, 200us */ +	DM9000_iow(DM9000_BPTR, 0x3f); +	/* Flow Control : High/Low Water */ +	DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); +	/* SH FIXME: This looks strange! Flow Control */ +	DM9000_iow(DM9000_FCR, 0x0); +	/* Special Mode */ +	DM9000_iow(DM9000_SMCR, 0); +	/* clear TX status */ +	DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); +	/* Clear interrupt status */ +	DM9000_iow(DM9000_ISR, 0x0f);  	/* Set Node address */  #ifndef CONFIG_AT91SAM9261EK @@ -333,8 +507,11 @@ eth_init(bd_t * bd)  	DM9000_DBG("\n");  	/* Activate DM9000 */ -	DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);	/* RX enable */ -	DM9000_iow(DM9000_IMR, IMR_PAR);	/* Enable TX/RX interrupt mask */ +	/* RX enable */ +	DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); +	/* Enable TX/RX interrupt mask */ +	DM9000_iow(DM9000_IMR, IMR_PAR); +  	i = 0;  	while (!(phy_read(1) & 0x20)) {	/* autonegation complete bit */  		udelay(1000); @@ -376,54 +553,37 @@ eth_init(bd_t * bd)  int  eth_send(volatile void *packet, int length)  { -	char *data_ptr; -	u32 tmplen, i;  	int tmo; -	DM9000_DBG("eth_send: length: %d\n", length); -	for (i = 0; i < length; i++) { -		if (i % 8 == 0) -			DM9000_DBG("\nSend: 02x: ", i); -		DM9000_DBG("%02x ", ((unsigned char *) packet)[i]); -	} DM9000_DBG("\n"); - -	/* Move data to DM9000 TX RAM */ -	data_ptr = (char *) packet; -	DM9000_outb(DM9000_MWCMD, DM9000_IO); +	struct board_info *db = &dm9000_info; -#ifdef CONFIG_DM9000_USE_8BIT -	/* Byte mode */ -	for (i = 0; i < length; i++) -		DM9000_outb((data_ptr[i] & 0xff), DM9000_DATA); +	DM9000_DMP_PACKET("eth_send", packet, length); -#endif				/*  */ -#ifdef CONFIG_DM9000_USE_16BIT -	tmplen = (length + 1) / 2; -	for (i = 0; i < tmplen; i++) -		DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA); +	DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ -#endif				/*  */ -#ifdef CONFIG_DM9000_USE_32BIT -	tmplen = (length + 3) / 4; -	for (i = 0; i < tmplen; i++) -		DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA); +	/* Move data to DM9000 TX RAM */ +	DM9000_outb(DM9000_MWCMD, DM9000_IO); /* Prepare for TX-data */ -#endif				/*  */ +	/* push the data to the TX-fifo */ +	(db->outblk)(packet, length);  	/* Set TX length to DM9000 */  	DM9000_iow(DM9000_TXPLL, length & 0xff);  	DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff);  	/* Issue TX polling command */ -	DM9000_iow(DM9000_TCR, TCR_TXREQ);	/* Cleared after TX complete */ +	DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */  	/* wait for end of transmission */  	tmo = get_timer(0) + 5 * CFG_HZ; -	while (DM9000_ior(DM9000_TCR) & TCR_TXREQ) { +	while ( !(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) || +		!(DM9000_ior(DM9000_ISR) & IMR_PTM) ) {  		if (get_timer(0) >= tmo) {  			printf("transmission timeout\n");  			break;  		}  	} +	DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ +  	DM9000_DBG("transmit done\n\n");  	return 0;  } @@ -452,86 +612,67 @@ eth_rx(void)  {  	u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0];  	u16 RxStatus, RxLen = 0; -	u32 tmplen, i; -#ifdef CONFIG_DM9000_USE_32BIT -	u32 tmpdata; -#endif +	struct board_info *db = &dm9000_info; -	/* Check packet ready or not */ -	DM9000_ior(DM9000_MRCMDX);	/* Dummy read */ -	rxbyte = DM9000_inb(DM9000_DATA);	/* Got most updated data */ -	if (rxbyte == 0) +	/* Check packet ready or not, we must check +	   the ISR status first for DM9000A */ +	if (!(DM9000_ior(DM9000_ISR) & 0x01)) /* Rx-ISR bit must be set. */  		return 0; -	/* Status check: this byte must be 0 or 1 */ -	if (rxbyte > 1) { -		DM9000_iow(DM9000_RCR, 0x00);	/* Stop Device */ -		DM9000_iow(DM9000_ISR, 0x80);	/* Stop INT request */ -		DM9000_DBG("rx status check: %d\n", rxbyte); -	} -	DM9000_DBG("receiving packet\n"); +	DM9000_iow(DM9000_ISR, 0x01); /* clear PR status latched in bit 0 */ -	/* A packet ready now  & Get status/length */ -	DM9000_outb(DM9000_MRCMD, DM9000_IO); +	/* There is _at least_ 1 package in the fifo, read them all */ +	for (;;) { +		DM9000_ior(DM9000_MRCMDX);	/* Dummy read */ + +		/* Get most updated data, +		   only look at bits 0:1, See application notes DM9000 */ +		rxbyte = DM9000_inb(DM9000_DATA) & 0x03; -#ifdef CONFIG_DM9000_USE_8BIT -	RxStatus = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8); -	RxLen = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8); +		/* Status check: this byte must be 0 or 1 */ +		if (rxbyte > DM9000_PKT_RDY) { +			DM9000_iow(DM9000_RCR, 0x00);	/* Stop Device */ +			DM9000_iow(DM9000_ISR, 0x80);	/* Stop INT request */ +			printf("DM9000 error: status check fail: 0x%x\n", +				rxbyte); +			return 0; +		} -#endif				/*  */ -#ifdef CONFIG_DM9000_USE_16BIT -	RxStatus = DM9000_inw(DM9000_DATA); -	RxLen = DM9000_inw(DM9000_DATA); +		if (rxbyte != DM9000_PKT_RDY) +			return 0; /* No packet received, ignore */ -#endif				/*  */ -#ifdef CONFIG_DM9000_USE_32BIT -	tmpdata = DM9000_inl(DM9000_DATA); -	RxStatus = tmpdata; -	RxLen = tmpdata >> 16; +		DM9000_DBG("receiving packet\n"); -#endif				/*  */ -	DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen); +		/* A packet ready now  & Get status/length */ +		(db->rx_status)(&RxStatus, &RxLen); -	/* Move data from DM9000 */ -	/* Read received packet from RX SRAM */ -#ifdef CONFIG_DM9000_USE_8BIT -	for (i = 0; i < RxLen; i++) -		rdptr[i] = DM9000_inb(DM9000_DATA); +		DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen); -#endif				/*  */ -#ifdef CONFIG_DM9000_USE_16BIT -	tmplen = (RxLen + 1) / 2; -	for (i = 0; i < tmplen; i++) -		((u16 *) rdptr)[i] = DM9000_inw(DM9000_DATA); +		/* Move data from DM9000 */ +		/* Read received packet from RX SRAM */ +		(db->inblk)(rdptr, RxLen); -#endif				/*  */ -#ifdef CONFIG_DM9000_USE_32BIT -	tmplen = (RxLen + 3) / 4; -	for (i = 0; i < tmplen; i++) -		((u32 *) rdptr)[i] = DM9000_inl(DM9000_DATA); +		if ((RxStatus & 0xbf00) || (RxLen < 0x40) +			|| (RxLen > DM9000_PKT_MAX)) { +			if (RxStatus & 0x100) { +				printf("rx fifo error\n"); +			} +			if (RxStatus & 0x200) { +				printf("rx crc error\n"); +			} +			if (RxStatus & 0x8000) { +				printf("rx length error\n"); +			} +			if (RxLen > DM9000_PKT_MAX) { +				printf("rx length too big\n"); +				dm9000_reset(); +			} +		} else { +			DM9000_DMP_PACKET("eth_rx", rdptr, RxLen); -#endif				/*  */ -	if ((RxStatus & 0xbf00) || (RxLen < 0x40) -	    || (RxLen > DM9000_PKT_MAX)) { -		if (RxStatus & 0x100) { -			printf("rx fifo error\n"); +			DM9000_DBG("passing packet to upper layer\n"); +			NetReceive(NetRxPackets[0], RxLen);  		} -		if (RxStatus & 0x200) { -			printf("rx crc error\n"); -		} -		if (RxStatus & 0x8000) { -			printf("rx length error\n"); -		} -		if (RxLen > DM9000_PKT_MAX) { -			printf("rx length too big\n"); -			dm9000_reset(); -		} -	} else { - -		/* Pass to upper layer */ -		DM9000_DBG("passing packet to upper layer\n"); -		NetReceive(NetRxPackets[0], RxLen); -		return RxLen;  	}  	return 0;  } @@ -592,12 +733,12 @@ phy_read(int reg)  	/* Fill the phyxcer register into REG_0C */  	DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);  	DM9000_iow(DM9000_EPCR, 0xc);	/* Issue phyxcer read command */ -	udelay(100);		/* Wait read complete */ +	udelay(100);			/* Wait read complete */  	DM9000_iow(DM9000_EPCR, 0x0);	/* Clear phyxcer read command */  	val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);  	/* The read data keeps on REG_0D & REG_0E */ -	DM9000_DBG("phy_read(%d): %d\n", reg, val); +	DM9000_DBG("phy_read(0x%x): 0x%x\n", reg, val);  	return val;  } @@ -615,8 +756,8 @@ phy_write(int reg, u16 value)  	DM9000_iow(DM9000_EPDRL, (value & 0xff));  	DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));  	DM9000_iow(DM9000_EPCR, 0xa);	/* Issue phyxcer write command */ -	udelay(500);		/* Wait write complete */ +	udelay(500);			/* Wait write complete */  	DM9000_iow(DM9000_EPCR, 0x0);	/* Clear phyxcer write command */ -	DM9000_DBG("phy_write(reg:%d, value:%d)\n", reg, value); +	DM9000_DBG("phy_write(reg:0x%x, value:0x%x)\n", reg, value);  } -#endif				/* CONFIG_DRIVER_DM9000 */ +#endif	/* CONFIG_DRIVER_DM9000 */ diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index c53c226d2..40a781fad 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -83,6 +83,7 @@ static struct pci_device_id supported[] = {  	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER},  	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM},  	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541GI_LF},  };  /* Function forward declarations */ @@ -646,6 +647,7 @@ e1000_set_mac_type(struct e1000_hw *hw)  		hw->mac_type = e1000_82546;  		break;  	case E1000_DEV_ID_82541ER: +	case E1000_DEV_ID_82541GI_LF:  		hw->mac_type = e1000_82541_rev_2;  		break;  	default: diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h index 851467d81..23b2eb9b4 100644 --- a/drivers/net/e1000.h +++ b/drivers/net/e1000.h @@ -222,7 +222,8 @@ struct e1000_phy_stats {  #define E1000_DEV_ID_82546EB_COPPER 0x1010  #define E1000_DEV_ID_82546EB_FIBER  0x1012  #define E1000_DEV_ID_82541ER	    0x1078 -#define NUM_DEV_IDS 14 +#define E1000_DEV_ID_82541GI_LF	    0x107C +#define NUM_DEV_IDS 15  #define NODE_ADDRESS_SIZE 6  #define ETH_LENGTH_OF_ADDRESS 6 diff --git a/drivers/net/mcffec.c b/drivers/net/mcffec.c index 5ab4726ff..8d4e24843 100644 --- a/drivers/net/mcffec.c +++ b/drivers/net/mcffec.c @@ -125,11 +125,17 @@ void setFecDuplexSpeed(volatile fec_t * fecp, bd_t * bd, int dup_spd)  	}  	if ((dup_spd & 0xFFFF) == _100BASET) { +#ifdef CONFIG_MCF5445x +		fecp->rcr &= ~0x200;	/* disabled 10T base */ +#endif  #ifdef MII_DEBUG  		printf("100Mbps\n");  #endif  		bd->bi_ethspeed = 100;  	} else { +#ifdef CONFIG_MCF5445x +		fecp->rcr |= 0x200;	/* enabled 10T base */ +#endif  #ifdef MII_DEBUG  		printf("10Mbps\n");  #endif diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 5302cb522..6d93bf074 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -30,6 +30,12 @@  #include <net.h>  #include <miiphy.h> +#if defined (CONFIG_DRIVER_SMC911X_32_BIT) && \ +	defined (CONFIG_DRIVER_SMC911X_16_BIT) +#error "SMC911X: Only one of CONFIG_DRIVER_SMC911X_32_BIT and \ +	CONFIG_DRIVER_SMC911X_16_BIT shall be set" +#endif +  #ifdef CONFIG_DRIVER_SMC911X_32_BIT  static inline u32 reg_read(u32 addr)  { @@ -39,9 +45,20 @@ static inline void reg_write(u32 addr, u32 val)  {  	*(volatile u32*)addr = val;  } +#elif CONFIG_DRIVER_SMC911X_16_BIT +static inline u32 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) +{ +	*(volatile u16*)addr = (u16)val; +	*(volatile u16*)(addr + 2) = (u16)(val >> 16); +}  #else -#error "SMC911X: Only 32-bit bus is supported" -#endif +#error "SMC911X: undefined bus width" +#endif /* CONFIG_DRIVER_SMC911X_16_BIT */  #define mdelay(n)       udelay((n)*1000) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index c7af930b6..397ae7162 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -1128,6 +1128,36 @@ struct phy_info phy_info_M88E1111S = {  			   },  }; +struct phy_info phy_info_M88E1118 = { +	0x01410e1, +	"Marvell 88E1118", +	4, +	(struct phy_cmd[]){	/* config */ +		/* Reset and configure the PHY */ +		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, +		{0x16, 0x0002, NULL}, /* Change Page Number */ +		{0x15, 0x1070, NULL}, /* Delay RGMII TX and RX */ +		{MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, +		{MIIM_ANAR, MIIM_ANAR_INIT, NULL}, +		{MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, +		{MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, +		{miim_end,} +		}, +	(struct phy_cmd[]){	/* startup */ +		{0x16, 0x0000, NULL}, /* Change Page Number */ +		/* Status is read once to clear old link state */ +		{MIIM_STATUS, miim_read, NULL}, +		/* Auto-negotiate */ +		/* Read the status */ +		{MIIM_88E1011_PHY_STATUS, miim_read, +		 &mii_parse_88E1011_psr}, +		{miim_end,} +		}, +	(struct phy_cmd[]){	/* shutdown */ +		{miim_end,} +		}, +}; +  static unsigned int m88e1145_setmode(uint mii_reg, struct tsec_private *priv)  {  	uint mii_data = read_phy_reg(priv, mii_reg); @@ -1492,6 +1522,7 @@ struct phy_info *phy_info[] = {  	&phy_info_BCM5464S,  	&phy_info_M88E1011S,  	&phy_info_M88E1111S, +	&phy_info_M88E1118,  	&phy_info_M88E1145,  	&phy_info_M88E1149S,  	&phy_info_dm9161, diff --git a/include/configs/scb9328.h b/include/configs/scb9328.h index d140241bf..4ae25adde 100644 --- a/include/configs/scb9328.h +++ b/include/configs/scb9328.h @@ -257,13 +257,9 @@  #define CFG_CS5L_VAL 0x00000D03  #define CONFIG_DRIVER_DM9000		1 -#define CONFIG_DRIVER_DM9000		1  #define CONFIG_DM9000_BASE		0x16000000  #define DM9000_IO			CONFIG_DM9000_BASE  #define DM9000_DATA			(CONFIG_DM9000_BASE+4) -/* #define CONFIG_DM9000_USE_8BIT */ -#define CONFIG_DM9000_USE_16BIT -/* #define CONFIG_DM9000_USE_32BIT */  /* f_{dpll}=2*f{ref}*(MFI+MFN/(MFD+1))/(PD+1)     f_ref=16,777MHz diff --git a/include/configs/trizepsiv.h b/include/configs/trizepsiv.h index 25155ad34..f77dd14f1 100644 --- a/include/configs/trizepsiv.h +++ b/include/configs/trizepsiv.h @@ -276,13 +276,9 @@  #define CFG_MCIO1_VAL		0x0000c108  #define CONFIG_DRIVER_DM9000		1 -#define CONFIG_DRIVER_DM9000		1  #define CONFIG_DM9000_BASE	0x08000000  #define DM9000_IO			CONFIG_DM9000_BASE  #define DM9000_DATA			(CONFIG_DM9000_BASE+0x8004) -/* #define CONFIG_DM9000_USE_8BIT */ -/* #define CONFIG_DM9000_USE_16BIT */ -#define CONFIG_DM9000_USE_32BIT  #define CONFIG_USB_OHCI_NEW	1  #define CFG_USB_OHCI_BOARD_INIT	1 diff --git a/include/pci_ids.h b/include/pci_ids.h index 61c22031e..d06101791 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -1812,7 +1812,8 @@  #define PCI_DEVICE_ID_INTEL_82434	0x04a3  #define PCI_DEVICE_ID_INTEL_I960	0x0960  #define PCI_DEVICE_ID_INTEL_I960RM	0x0962 -#define PCI_DEVICE_ID_INTEL_82541ER 0x1078 +#define PCI_DEVICE_ID_INTEL_82541ER	0x1078 +#define PCI_DEVICE_ID_INTEL_82541GI_LF	0x107c  #define PCI_DEVICE_ID_INTEL_82542	0x1000  #define PCI_DEVICE_ID_INTEL_82543GC_FIBER	0x1001  #define PCI_DEVICE_ID_INTEL_82543GC_COPPER	0x1004 @@ -1407,6 +1407,10 @@ NetReceive(volatile uchar * inpkt, int len)  		if (ip->ip_off & htons(0x1fff)) { /* Can't deal w/ fragments */  			return;  		} +		/* can't deal with headers > 20 bytes */ +		if ((ip->ip_hl_v & 0x0f) > 0x05) { +			return; +		}  		if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2)) {  			puts ("checksum bad\n");  			return; |