@ -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 200 MHz 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 out puts */
DM9000_iow ( DM9000_GPCR , 0x0F ) ;
/* DEBUG: Make all GPIO0 outputs, all others in puts */
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 ) ;