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 e7365fe..3a61b80 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 f47ff8c..0d123e2 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 |