@ -198,6 +198,7 @@
# define BI_PHYMODE_RMII 8
# define BI_PHYMODE_RMII 8
# endif
# endif
# endif
# endif
# define BI_PHYMODE_SGMII 9
# if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
# if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
defined ( CONFIG_440EPX ) | | defined ( CONFIG_440GRX ) | | \
defined ( CONFIG_440EPX ) | | defined ( CONFIG_440GRX ) | | \
@ -216,6 +217,52 @@
# define MAL_RX_CHAN_MUL 1
# define MAL_RX_CHAN_MUL 1
# endif
# endif
/*--------------------------------------------------------------------+
* Fixed PHY ( PHY - less ) support for Ethernet Ports .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
* Some boards do not have a PHY for each ethernet port . These ports
* are known as Fixed PHY ( or PHY - less ) ports . For such ports , set
* the appropriate CONFIG_PHY_ADDR equal to CONFIG_FIXED_PHY and
* then define CFG_FIXED_PHY_PORTS to define what the speed and
* duplex should be for these ports in the board configuration
* file .
*
* For Example :
* # define CONFIG_FIXED_PHY 0xFFFFFFFF
*
* # define CONFIG_PHY_ADDR CONFIG_FIXED_PHY
* # define CONFIG_PHY1_ADDR 1
* # define CONFIG_PHY2_ADDR CONFIG_FIXED_PHY
* # define CONFIG_PHY3_ADDR 3
*
* # define CFG_FIXED_PHY_PORT ( devnum , speed , duplex ) \
* { devnum , speed , duplex } ,
*
* # define CFG_FIXED_PHY_PORTS \
* CFG_FIXED_PHY_PORT ( 0 , 1000 , FULL ) \
* CFG_FIXED_PHY_PORT ( 2 , 100 , HALF )
*/
# ifndef CONFIG_FIXED_PHY
# define CONFIG_FIXED_PHY 0xFFFFFFFF /* Fixed PHY (PHY-less) */
# endif
# ifndef CFG_FIXED_PHY_PORTS
# define CFG_FIXED_PHY_PORTS /* default is an empty array */
# endif
struct fixed_phy_port {
unsigned int devnum ; /* ethernet port */
unsigned int speed ; /* specified speed 10,100 or 1000 */
unsigned int duplex ; /* specified duplex FULL or HALF */
} ;
static const struct fixed_phy_port fixed_phy_port [ ] = {
CFG_FIXED_PHY_PORTS /* defined in board configuration file */
} ;
/*-----------------------------------------------------------------------------+
/*-----------------------------------------------------------------------------+
* Global variables . TX and RX descriptors and buffers .
* Global variables . TX and RX descriptors and buffers .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
@ -611,8 +658,17 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
# if defined(CONFIG_460EX)
# if defined(CONFIG_460EX)
mode = 9 ;
mode = 9 ;
mfsdr ( SDR0_ETH_CFG , eth_cfg ) ;
if ( ( ( eth_cfg & SDR0_ETH_CFG_SGMII0_ENABLE ) > 0 ) & &
( ( eth_cfg & SDR0_ETH_CFG_SGMII1_ENABLE ) > 0 ) )
mode = 11 ; /* config SGMII */
# else
# else
mode = 10 ;
mode = 10 ;
mfsdr ( SDR0_ETH_CFG , eth_cfg ) ;
if ( ( ( eth_cfg & SDR0_ETH_CFG_SGMII0_ENABLE ) > 0 ) & &
( ( eth_cfg & SDR0_ETH_CFG_SGMII1_ENABLE ) > 0 ) & &
( ( eth_cfg & SDR0_ETH_CFG_SGMII2_ENABLE ) > 0 ) )
mode = 12 ; /* config SGMII */
# endif
# endif
/* TODO:
/* TODO:
@ -635,6 +691,8 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
/*
/*
* Right now only 2 * RGMII is supported . Please extend when needed .
* Right now only 2 * RGMII is supported . Please extend when needed .
* sr - 2008 - 02 - 19
* sr - 2008 - 02 - 19
* Add SGMII support .
* vg - 2008 - 07 - 28
*/
*/
switch ( mode ) {
switch ( mode ) {
case 1 :
case 1 :
@ -761,6 +819,20 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
bis - > bi_phymode [ 2 ] = BI_PHYMODE_RGMII ;
bis - > bi_phymode [ 2 ] = BI_PHYMODE_RGMII ;
bis - > bi_phymode [ 3 ] = BI_PHYMODE_RGMII ;
bis - > bi_phymode [ 3 ] = BI_PHYMODE_RGMII ;
break ;
break ;
case 11 :
/* 2 SGMII - 460EX */
bis - > bi_phymode [ 0 ] = BI_PHYMODE_SGMII ;
bis - > bi_phymode [ 1 ] = BI_PHYMODE_SGMII ;
bis - > bi_phymode [ 2 ] = BI_PHYMODE_NONE ;
bis - > bi_phymode [ 3 ] = BI_PHYMODE_NONE ;
break ;
case 12 :
/* 3 SGMII - 460GT */
bis - > bi_phymode [ 0 ] = BI_PHYMODE_SGMII ;
bis - > bi_phymode [ 1 ] = BI_PHYMODE_SGMII ;
bis - > bi_phymode [ 2 ] = BI_PHYMODE_SGMII ;
bis - > bi_phymode [ 3 ] = BI_PHYMODE_NONE ;
break ;
default :
default :
break ;
break ;
}
}
@ -945,6 +1017,48 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
out_be32 ( ( void * ) EMAC_M1 + hw_p - > hw_addr , mode_reg ) ;
out_be32 ( ( void * ) EMAC_M1 + hw_p - > hw_addr , mode_reg ) ;
# endif /* defined(CONFIG_440GX) || defined(CONFIG_440SP) */
# endif /* defined(CONFIG_440GX) || defined(CONFIG_440SP) */
# if defined(CONFIG_GPCS_PHY_ADDR) || defined(CONFIG_GPCS_PHY1_ADDR) || \
defined ( CONFIG_GPCS_PHY2_ADDR ) | | defined ( CONFIG_GPCS_PHY3_ADDR )
if ( bis - > bi_phymode [ devnum ] = = BI_PHYMODE_SGMII ) {
/*
* In SGMII mode , GPCS access is needed for
* communication with the internal SGMII SerDes .
*/
switch ( devnum ) {
# if defined(CONFIG_GPCS_PHY_ADDR)
case 0 :
reg = CONFIG_GPCS_PHY_ADDR ;
break ;
# endif
# if defined(CONFIG_GPCS_PHY1_ADDR)
case 1 :
reg = CONFIG_GPCS_PHY1_ADDR ;
break ;
# endif
# if defined(CONFIG_GPCS_PHY2_ADDR)
case 2 :
reg = CONFIG_GPCS_PHY2_ADDR ;
break ;
# endif
# if defined(CONFIG_GPCS_PHY3_ADDR)
case 3 :
reg = CONFIG_GPCS_PHY3_ADDR ;
break ;
# endif
}
mode_reg = in_be32 ( ( void * ) EMAC_M1 + hw_p - > hw_addr ) ;
mode_reg | = EMAC_M1_MF_1000GPCS | EMAC_M1_IPPA_SET ( reg ) ;
out_be32 ( ( void * ) EMAC_M1 + hw_p - > hw_addr , mode_reg ) ;
/* Configure GPCS interface to recommended setting for SGMII */
miiphy_reset ( dev - > name , reg ) ;
miiphy_write ( dev - > name , reg , 0x04 , 0x8120 ) ; /* AsymPause, FDX */
miiphy_write ( dev - > name , reg , 0x07 , 0x2801 ) ; /* msg_pg, toggle */
miiphy_write ( dev - > name , reg , 0x00 , 0x0140 ) ; /* 1Gbps, FDX */
}
# endif /* defined(CONFIG_GPCS_PHY_ADDR) */
/* wait for PHY to complete auto negotiation */
/* wait for PHY to complete auto negotiation */
reg_short = 0 ;
reg_short = 0 ;
# ifndef CONFIG_CS8952_PHY
# ifndef CONFIG_CS8952_PHY
@ -974,6 +1088,9 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
bis - > bi_phynum [ devnum ] = reg ;
bis - > bi_phynum [ devnum ] = reg ;
if ( reg = = CONFIG_FIXED_PHY )
goto get_speed ;
# if defined(CONFIG_PHY_RESET)
# if defined(CONFIG_PHY_RESET)
/*
/*
* Reset the phy , only if its the first time through
* Reset the phy , only if its the first time through
@ -986,6 +1103,27 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
miiphy_write ( dev - > name , reg , 0x09 , 0x0e00 ) ;
miiphy_write ( dev - > name , reg , 0x09 , 0x0e00 ) ;
miiphy_write ( dev - > name , reg , 0x04 , 0x01e1 ) ;
miiphy_write ( dev - > name , reg , 0x04 , 0x01e1 ) ;
# endif
# endif
# if defined(CONFIG_M88E1112_PHY)
if ( bis - > bi_phymode [ devnum ] = = BI_PHYMODE_SGMII ) {
/*
* Marvell 88E1112 PHY needs to have the SGMII MAC
* interace ( page 2 ) properly configured to
* communicate with the 460 EX / GT GPCS interface .
*/
/* Set access to Page 2 */
miiphy_write ( dev - > name , reg , 0x16 , 0x0002 ) ;
miiphy_write ( dev - > name , reg , 0x00 , 0x0040 ) ; /* 1Gbps */
miiphy_read ( dev - > name , reg , 0x1a , & reg_short ) ;
reg_short | = 0x8000 ; /* bypass Auto-Negotiation */
miiphy_write ( dev - > name , reg , 0x1a , reg_short ) ;
miiphy_reset ( dev - > name , reg ) ; /* reset MAC interface */
/* Reset access to Page 0 */
miiphy_write ( dev - > name , reg , 0x16 , 0x0000 ) ;
}
# endif /* defined(CONFIG_M88E1112_PHY) */
miiphy_reset ( dev - > name , reg ) ;
miiphy_reset ( dev - > name , reg ) ;
# if defined(CONFIG_440GX) || \
# if defined(CONFIG_440GX) || \
@ -1080,8 +1218,25 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
}
}
# endif /* #ifndef CONFIG_CS8952_PHY */
# endif /* #ifndef CONFIG_CS8952_PHY */
speed = miiphy_speed ( dev - > name , reg ) ;
get_speed :
duplex = miiphy_duplex ( dev - > name , reg ) ;
if ( reg = = CONFIG_FIXED_PHY ) {
for ( i = 0 ; i < ARRAY_SIZE ( fixed_phy_port ) ; i + + ) {
if ( devnum = = fixed_phy_port [ i ] . devnum ) {
speed = fixed_phy_port [ i ] . speed ;
duplex = fixed_phy_port [ i ] . duplex ;
break ;
}
}
if ( i = = ARRAY_SIZE ( fixed_phy_port ) ) {
printf ( " ERROR: PHY (%s) not configured correctly! \n " ,
dev - > name ) ;
return - 1 ;
}
} else {
speed = miiphy_speed ( dev - > name , reg ) ;
duplex = miiphy_duplex ( dev - > name , reg ) ;
}
if ( hw_p - > print_speed ) {
if ( hw_p - > print_speed ) {
hw_p - > print_speed = 0 ;
hw_p - > print_speed = 0 ;