diff options
| -rw-r--r-- | drivers/net/dm9000x.c | 159 | ||||
| -rw-r--r-- | drivers/net/dm9000x.h | 21 | 
2 files changed, 36 insertions, 144 deletions
| diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index e7365fe06..3a61b802e 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -55,8 +55,7 @@ v1.2   03/18/2003       Weilun Huang <weilun_huang@davicom.com.tw>:  			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. +TODO: external MII is not functional, only internal at the moment.  */  #include <common.h> @@ -68,9 +67,6 @@ TODO: Homerun NIC and longrun NIC are not functional, only internal at the  /* Board/System/Debug information/definition ---------------- */ -#define DM9801_NOISE_FLOOR	0x08 -#define DM9802_NOISE_FLOOR	0x05 -  /* #define CONFIG_DM9000_DEBUG */  #ifdef CONFIG_DM9000_DEBUG @@ -90,13 +86,6 @@ TODO: Homerun NIC and longrun NIC are not functional, only internal at the  #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 -}; -enum DM9000_NIC_TYPE { FASTETHER_NIC = 0, HOMERUN_NIC = 1, LONGRUN_NIC = 2 -}; -  /* Structure/enum declaration ------------------------------- */  typedef struct board_info {  	u32 runt_length_counter;	/* counter: RX length < 64byte */ @@ -109,7 +98,6 @@ typedef struct board_info {  	u16 dbug_cnt;  	u8 phy_addr;  	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); @@ -117,10 +105,6 @@ typedef struct board_info {  } board_info_t;  static board_info_t dm9000_info; -/* For module input parameter */ -static int media_mode = DM9000_AUTO; -static u8 nfloor = 0; -  /* function declaration ------------------------------------- */  int eth_init(bd_t * bd);  int eth_send(volatile void *, int); @@ -260,114 +244,6 @@ dm9000_probe(void)  	}  } -/* Set PHY operationg mode -*/ -static void -set_PHY_mode(void) -{ -	u16 phy_reg4 = 0x01e1, phy_reg0 = 0x1000; -	if (!(media_mode & DM9000_AUTO)) { -		switch (media_mode) { -		case DM9000_10MHD: -			phy_reg4 = 0x21; -			phy_reg0 = 0x0000; -			break; -		case DM9000_10MFD: -			phy_reg4 = 0x41; -			phy_reg0 = 0x1100; -			break; -		case DM9000_100MHD: -			phy_reg4 = 0x81; -			phy_reg0 = 0x2000; -			break; -		case DM9000_100MFD: -			phy_reg4 = 0x101; -			phy_reg0 = 0x3100; -			break; -		} -		phy_write(4, phy_reg4);	/* Set PHY media mode */ -		phy_write(0, phy_reg0);	/*  Tmp */ -	} -	DM9000_iow(DM9000_GPCR, 0x01);	/* Let GPIO0 output */ -	DM9000_iow(DM9000_GPR, 0x00);	/* Enable PHY */ -} - -/* -	Init HomeRun DM9801 -*/ -static void -program_dm9801(u16 HPNA_rev) -{ -	__u16 reg16, reg17, reg24, reg25; -	if (!nfloor) -		nfloor = DM9801_NOISE_FLOOR; -	reg16 = phy_read(16); -	reg17 = phy_read(17); -	reg24 = phy_read(24); -	reg25 = phy_read(25); -	switch (HPNA_rev) { -	case 0xb900:		/* DM9801 E3 */ -		reg16 |= 0x1000; -		reg25 = ((reg24 + nfloor) & 0x00ff) | 0xf000; -		break; -	case 0xb901:		/* DM9801 E4 */ -		reg25 = ((reg24 + nfloor) & 0x00ff) | 0xc200; -		reg17 = (reg17 & 0xfff0) + nfloor + 3; -		break; -	case 0xb902:		/* DM9801 E5 */ -	case 0xb903:		/* DM9801 E6 */ -	default: -		reg16 |= 0x1000; -		reg25 = ((reg24 + nfloor - 3) & 0x00ff) | 0xc200; -		reg17 = (reg17 & 0xfff0) + nfloor; -	} -	phy_write(16, reg16); -	phy_write(17, reg17); -	phy_write(25, reg25); -} - -/* -	Init LongRun DM9802 -*/ -static void -program_dm9802(void) -{ -	__u16 reg25; -	if (!nfloor) -		nfloor = DM9802_NOISE_FLOOR; -	reg25 = phy_read(25); -	reg25 = (reg25 & 0xff00) + nfloor; -	phy_write(25, reg25); -} - -/* Identify NIC type -*/ -static void -identify_nic(void) -{ -	struct board_info *db = &dm9000_info; -	u16 phy_reg3; -	DM9000_iow(DM9000_NCR, NCR_EXT_PHY); -	phy_reg3 = phy_read(3); -	switch (phy_reg3 & 0xfff0) { -	case 0xb900: -		if (phy_read(31) == 0x4404) { -			db->nic_type = HOMERUN_NIC; -			program_dm9801(phy_reg3); -			DM9000_DBG("found homerun NIC\n"); -		} else { -			db->nic_type = LONGRUN_NIC; -			DM9000_DBG("found longrun NIC\n"); -			program_dm9802(); -		} -		break; -	default: -		db->nic_type = FASTETHER_NIC; -		break; -	} -	DM9000_iow(DM9000_NCR, 0); -} -  /* General Purpose dm9000 reset routine */  static void  dm9000_reset(void) @@ -377,12 +253,12 @@ dm9000_reset(void)  	/* Reset DM9000,  	   see DM9000 Application Notes V1.22 Jun 11, 2004 page 29 */ -	/* DEBUG: Make all GPIO pins outputs */ -	DM9000_iow(DM9000_GPCR, 0x0F); +	/* DEBUG: Make all GPIO0 outputs, all others inputs */ +	DM9000_iow(DM9000_GPCR, GPCR_GPIO0_OUT);  	/* 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); +	DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));  	do {  		DM9000_DBG("resetting the DM9000, 1st reset\n"); @@ -390,7 +266,7 @@ dm9000_reset(void)  	} while (DM9000_ior(DM9000_NCR) & 1);  	DM9000_iow(DM9000_NCR, 0); -	DM9000_iow(DM9000_NCR, 3); /* Issue a second reset */ +	DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); /* Issue a second reset */  	do {  		DM9000_DBG("resetting the DM9000, 2nd reset\n"); @@ -416,7 +292,9 @@ eth_init(bd_t * bd)  	/* RESET device */  	dm9000_reset(); -	dm9000_probe(); + +	if (dm9000_probe() < 0) +		return -1;  	/* Auto-detect 8/16/32 bit mode, ISR Bit 6+7 indicate bus width */  	io_mode = DM9000_ior(DM9000_ISR) >> 6; @@ -449,21 +327,12 @@ eth_init(bd_t * bd)  		break;  	} -	/* NIC Type: FASTETHER, HOMERUN, LONGRUN */ -	identify_nic(); - -	/* GPIO0 on pre-activate PHY */ -	DM9000_iow(DM9000_GPR, 0x00);	/*REG_1F bit0 activate phyxcer */ - -	/* Set PHY */ -	set_PHY_mode(); - -	/* Program operating register, only intern phy supported by now */ +	/* Program operating register, only internal phy supported */  	DM9000_iow(DM9000_NCR, 0x0);  	/* TX Polling clear */  	DM9000_iow(DM9000_TCR, 0);  	/* Less 3Kb, 200us */ -	DM9000_iow(DM9000_BPTR, 0x3f); +	DM9000_iow(DM9000_BPTR, BPTR_BPHW(3) | BPTR_JPT_600US);  	/* Flow Control : High/Low Water */  	DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));  	/* SH FIXME: This looks strange! Flow Control */ @@ -473,10 +342,10 @@ eth_init(bd_t * bd)  	/* clear TX status */  	DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);  	/* Clear interrupt status */ -	DM9000_iow(DM9000_ISR, 0x0f); +	DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS);  	/* Set Node address */ -#ifndef CONFIG_AT91SAM9261EK +#if !defined(CONFIG_AT91SAM9261EK)  	for (i = 0; i < 6; i++)  		((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i);  #endif @@ -498,7 +367,9 @@ eth_init(bd_t * bd)  	printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", bd->bi_enetaddr[0],  	       bd->bi_enetaddr[1], bd->bi_enetaddr[2], bd->bi_enetaddr[3],  	       bd->bi_enetaddr[4], bd->bi_enetaddr[5]); -	for (i = 0, oft = 0x10; i < 6; i++, oft++) + +	/* fill device MAC address registers */ +	for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)  		DM9000_iow(oft, bd->bi_enetaddr[i]);  	for (i = 0, oft = 0x16; i < 8; i++, oft++)  		DM9000_iow(oft, 0xff); diff --git a/drivers/net/dm9000x.h b/drivers/net/dm9000x.h index f47ff8cb3..0d123e2e1 100644 --- a/drivers/net/dm9000x.h +++ b/drivers/net/dm9000x.h @@ -66,6 +66,8 @@  #define NCR_FCOL		(1<<4)  #define NCR_FDX			(1<<3)  #define NCR_LBK			(3<<1) +#define NCR_LBK_INT_MAC		(1<<1) +#define NCR_LBK_INT_PHY		(2<<1)  #define NCR_RST			(1<<0)  #define NSR_SPEED		(1<<7) @@ -107,13 +109,32 @@  #define RSR_CE			(1<<1)  #define RSR_FOE			(1<<0) +#define EPCR_EPOS_PHY		(1<<3) +#define EPCR_EPOS_EE		(0<<3) +#define EPCR_ERPRR		(1<<2) +#define EPCR_ERPRW		(1<<1) +#define EPCR_ERRE		(1<<0) +  #define FCTR_HWOT(ot)	(( ot & 0xf ) << 4 )  #define FCTR_LWOT(ot)	( ot & 0xf ) +#define BPTR_BPHW(x)	((x) << 4) +#define BPTR_JPT_200US		(0x07) +#define BPTR_JPT_600US		(0x0f) +  #define IMR_PAR			(1<<7)  #define IMR_ROOM		(1<<3)  #define IMR_ROM			(1<<2)  #define IMR_PTM			(1<<1)  #define IMR_PRM			(1<<0) +#define ISR_ROOS		(1<<3) +#define ISR_ROS			(1<<2) +#define ISR_PTS			(1<<1) +#define ISR_PRS			(1<<0) + +#define GPCR_GPIO0_OUT		(1<<0) + +#define GPR_PHY_PWROFF		(1<<0) +  #endif |