@ -35,13 +35,17 @@
# include <asm/errno.h>
# include <asm/types.h>
# include <asm/byteorder.h>
# if defined(CONFIG_KIRKWOOD)
# include <asm/arch/kirkwood.h>
# endif
# include "mvgbe.h"
DECLARE_GLOBAL_DATA_PTR ;
# define KIRKWOOD _PHY_ADR_REQUEST 0xee
# define KWGBE_SMI_REG (((struct kwgbe_registers *)KW_EGIGA 0_BASE)->smi)
# define MV _PHY_ADR_REQUEST 0xee
# define MVGBE_SMI_REG (((struct mvgbe_registers *)MVGBE 0_BASE)->smi)
/*
* smi_reg_read - miiphy_read callback function .
@ -51,16 +55,16 @@ DECLARE_GLOBAL_DATA_PTR;
static int smi_reg_read ( char * devname , u8 phy_adr , u8 reg_ofs , u16 * data )
{
struct eth_device * dev = eth_get_dev_by_name ( devname ) ;
struct kwgbe_device * dkwgbe = to_dkw gbe( dev ) ;
struct kw gbe_registers * regs = dkw gbe - > regs ;
struct mvgbe_device * dmvgbe = to_mv gbe( dev ) ;
struct mv gbe_registers * regs = dmv gbe - > regs ;
u32 smi_reg ;
u32 timeout ;
/* Phyadr read request */
if ( phy_adr = = KIRKWOOD _PHY_ADR_REQUEST & &
reg_ofs = = KIRKWOOD _PHY_ADR_REQUEST) {
if ( phy_adr = = MV _PHY_ADR_REQUEST & &
reg_ofs = = MV _PHY_ADR_REQUEST) {
/* */
* data = ( u16 ) ( KWGBE REG_RD( regs - > phyadr ) & PHYADR_MASK ) ;
* data = ( u16 ) ( MVGBE_ REG_RD( regs - > phyadr ) & PHYADR_MASK ) ;
return 0 ;
}
/* check parameters */
@ -75,42 +79,43 @@ static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
return - EFAULT ;
}
timeout = KW GBE_PHY_SMI_TIMEOUT;
timeout = MV GBE_PHY_SMI_TIMEOUT;
/* wait till the SMI is not busy */
do {
/* read smi register */
smi_reg = KWGBEREG_RD ( KW GBE_SMI_REG) ;
smi_reg = MVGBE_REG_RD ( MV GBE_SMI_REG) ;
if ( timeout - - = = 0 ) {
printf ( " Err..(%s) SMI busy timeout \n " , __FUNCTION__ ) ;
return - EFAULT ;
}
} while ( smi_reg & KW GBE_PHY_SMI_BUSY_MASK) ;
} while ( smi_reg & MV GBE_PHY_SMI_BUSY_MASK) ;
/* fill the phy address and regiser offset and read opcode */
smi_reg = ( phy_adr < < KW GBE_PHY_SMI_DEV_ADDR_OFFS)
| ( reg_ofs < < KW GBE_SMI_REG_ADDR_OFFS)
| KW GBE_PHY_SMI_OPCODE_READ;
smi_reg = ( phy_adr < < MV GBE_PHY_SMI_DEV_ADDR_OFFS)
| ( reg_ofs < < MV GBE_SMI_REG_ADDR_OFFS)
| MV GBE_PHY_SMI_OPCODE_READ;
/* write the smi register */
KWGBEREG_WR ( KW GBE_SMI_REG, smi_reg ) ;
MVGBE_REG_WR ( MV GBE_SMI_REG, smi_reg ) ;
/*wait till read value is ready */
timeout = KW GBE_PHY_SMI_TIMEOUT;
timeout = MV GBE_PHY_SMI_TIMEOUT;
do {
/* read smi register */
smi_reg = KWGBEREG_RD ( KW GBE_SMI_REG) ;
smi_reg = MVGBE_REG_RD ( MV GBE_SMI_REG) ;
if ( timeout - - = = 0 ) {
printf ( " Err..(%s) SMI read ready timeout \n " ,
__FUNCTION__ ) ;
return - EFAULT ;
}
} while ( ! ( smi_reg & KW GBE_PHY_SMI_READ_VALID_MASK) ) ;
} while ( ! ( smi_reg & MV GBE_PHY_SMI_READ_VALID_MASK) ) ;
/* Wait for the data to update in the SMI register */
for ( timeout = 0 ; timeout < KWGBE_PHY_SMI_TIMEOUT ; timeout + + ) ;
for ( timeout = 0 ; timeout < MVGBE_PHY_SMI_TIMEOUT ; timeout + + )
;
* data = ( u16 ) ( KWGBEREG_RD ( KWGBE_SMI_REG ) & KW GBE_PHY_SMI_DATA_MASK) ;
* data = ( u16 ) ( MVGBE_REG_RD ( MVGBE_SMI_REG ) & MV GBE_PHY_SMI_DATA_MASK) ;
debug ( " %s:(adr %d, off %d) value= %04x \n " , __FUNCTION__ , phy_adr ,
reg_ofs , * data ) ;
@ -127,15 +132,15 @@ static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
static int smi_reg_write ( char * devname , u8 phy_adr , u8 reg_ofs , u16 data )
{
struct eth_device * dev = eth_get_dev_by_name ( devname ) ;
struct kwgbe_device * dkwgbe = to_dkw gbe( dev ) ;
struct kw gbe_registers * regs = dkw gbe - > regs ;
struct mvgbe_device * dmvgbe = to_mv gbe( dev ) ;
struct mv gbe_registers * regs = dmv gbe - > regs ;
u32 smi_reg ;
u32 timeout ;
/* Phyadr write request*/
if ( phy_adr = = KIRKWOOD _PHY_ADR_REQUEST & &
reg_ofs = = KIRKWOOD _PHY_ADR_REQUEST) {
KWGBE REG_WR( regs - > phyadr , data ) ;
if ( phy_adr = = MV _PHY_ADR_REQUEST & &
reg_ofs = = MV _PHY_ADR_REQUEST) {
MVGBE_ REG_WR( regs - > phyadr , data ) ;
return 0 ;
}
@ -150,24 +155,24 @@ static int smi_reg_write(char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
}
/* wait till the SMI is not busy */
timeout = KW GBE_PHY_SMI_TIMEOUT;
timeout = MV GBE_PHY_SMI_TIMEOUT;
do {
/* read smi register */
smi_reg = KWGBEREG_RD ( KW GBE_SMI_REG) ;
smi_reg = MVGBE_REG_RD ( MV GBE_SMI_REG) ;
if ( timeout - - = = 0 ) {
printf ( " Err..(%s) SMI busy timeout \n " , __FUNCTION__ ) ;
return - ETIME ;
}
} while ( smi_reg & KW GBE_PHY_SMI_BUSY_MASK) ;
} while ( smi_reg & MV GBE_PHY_SMI_BUSY_MASK) ;
/* fill the phy addr and reg offset and write opcode and data */
smi_reg = ( data < < KW GBE_PHY_SMI_DATA_OFFS) ;
smi_reg | = ( phy_adr < < KW GBE_PHY_SMI_DEV_ADDR_OFFS)
| ( reg_ofs < < KW GBE_SMI_REG_ADDR_OFFS) ;
smi_reg & = ~ KW GBE_PHY_SMI_OPCODE_READ;
smi_reg = ( data < < MV GBE_PHY_SMI_DATA_OFFS) ;
smi_reg | = ( phy_adr < < MV GBE_PHY_SMI_DEV_ADDR_OFFS)
| ( reg_ofs < < MV GBE_SMI_REG_ADDR_OFFS) ;
smi_reg & = ~ MV GBE_PHY_SMI_OPCODE_READ;
/* write the smi register */
KWGBEREG_WR ( KW GBE_SMI_REG, smi_reg ) ;
MVGBE_REG_WR ( MV GBE_SMI_REG, smi_reg ) ;
return 0 ;
}
@ -204,46 +209,46 @@ static void stop_queue(u32 * qreg)
* @ regs Register struct pointer .
* @ param Address decode parameter struct .
*/
static void set_access_control ( struct kw gbe_registers * regs ,
struct kw gbe_winparam * param )
static void set_access_control ( struct mv gbe_registers * regs ,
struct mv gbe_winparam * param )
{
u32 access_prot_reg ;
/* Set access control register */
access_prot_reg = KWGBE REG_RD( regs - > epap ) ;
access_prot_reg = MVGBE_ REG_RD( regs - > epap ) ;
/* clear window permission */
access_prot_reg & = ( ~ ( 3 < < ( param - > win * 2 ) ) ) ;
access_prot_reg | = ( param - > access_ctrl < < ( param - > win * 2 ) ) ;
KWGBE REG_WR( regs - > epap , access_prot_reg ) ;
MVGBE_ REG_WR( regs - > epap , access_prot_reg ) ;
/* Set window Size reg (SR) */
KWGBE REG_WR( regs - > barsz [ param - > win ] . size ,
MVGBE_ REG_WR( regs - > barsz [ param - > win ] . size ,
( ( ( param - > size / 0x10000 ) - 1 ) < < 16 ) ) ;
/* Set window Base address reg (BA) */
KWGBE REG_WR( regs - > barsz [ param - > win ] . bar ,
MVGBE_ REG_WR( regs - > barsz [ param - > win ] . bar ,
( param - > target | param - > attrib | param - > base_addr ) ) ;
/* High address remap reg (HARR) */
if ( param - > win < 4 )
KWGBE REG_WR( regs - > ha_remap [ param - > win ] , param - > high_addr ) ;
MVGBE_ REG_WR( regs - > ha_remap [ param - > win ] , param - > high_addr ) ;
/* Base address enable reg (BARER) */
if ( param - > enable = = 1 )
KWGBE REG_BITS_RESET( regs - > bare , ( 1 < < param - > win ) ) ;
MVGBE_ REG_BITS_RESET( regs - > bare , ( 1 < < param - > win ) ) ;
else
KWGBE REG_BITS_SET( regs - > bare , ( 1 < < param - > win ) ) ;
MVGBE_ REG_BITS_SET( regs - > bare , ( 1 < < param - > win ) ) ;
}
static void set_dram_access ( struct kw gbe_registers * regs )
static void set_dram_access ( struct mv gbe_registers * regs )
{
struct kw gbe_winparam win_param ;
struct mv gbe_winparam win_param ;
int i ;
for ( i = 0 ; i < CONFIG_NR_DRAM_BANKS ; i + + ) {
/* Set access parameters for DRAM bank i */
win_param . win = i ; /* Use Ethernet window i */
/* Window target - DDR */
win_param . target = KW GBE_TARGET_DRAM;
win_param . target = MV GBE_TARGET_DRAM;
/* Enable full access */
win_param . access_ctrl = EWIN_ACCESS_FULL ;
win_param . high_addr = 0 ;
@ -286,19 +291,19 @@ static void set_dram_access(struct kwgbe_registers *regs)
* Go through all the DA filter tables ( Unicast , Special Multicast & Other
* Multicast ) and set each entry to 0.
*/
static void port_init_mac_tables ( struct kw gbe_registers * regs )
static void port_init_mac_tables ( struct mv gbe_registers * regs )
{
int table_index ;
/* Clear DA filter unicast table (Ex_dFUT) */
for ( table_index = 0 ; table_index < 4 ; + + table_index )
KWGBE REG_WR( regs - > dfut [ table_index ] , 0 ) ;
MVGBE_ REG_WR( regs - > dfut [ table_index ] , 0 ) ;
for ( table_index = 0 ; table_index < 64 ; + + table_index ) {
/* Clear DA filter special multicast table (Ex_dFSMT) */
KWGBE REG_WR( regs - > dfsmt [ table_index ] , 0 ) ;
MVGBE_ REG_WR( regs - > dfsmt [ table_index ] , 0 ) ;
/* Clear DA filter other multicast table (Ex_dFOMT) */
KWGBE REG_WR( regs - > dfomt [ table_index ] , 0 ) ;
MVGBE_ REG_WR( regs - > dfomt [ table_index ] , 0 ) ;
}
}
@ -316,7 +321,7 @@ static void port_init_mac_tables(struct kwgbe_registers *regs)
*
* RETURN : 1 if output succeeded . 0 if option parameter is invalid .
*/
static int port_uc_addr ( struct kw gbe_registers * regs , u8 uc_nibble ,
static int port_uc_addr ( struct mv gbe_registers * regs , u8 uc_nibble ,
int option )
{
u32 unicast_reg ;
@ -336,16 +341,16 @@ static int port_uc_addr(struct kwgbe_registers *regs, u8 uc_nibble,
* Clear accepts frame bit at specified unicast
* DA table entry
*/
unicast_reg = KWGBE REG_RD( regs - > dfut [ tbl_offset ] ) ;
unicast_reg = MVGBE_ REG_RD( regs - > dfut [ tbl_offset ] ) ;
unicast_reg & = ( 0xFF < < ( 8 * reg_offset ) ) ;
KWGBE REG_WR( regs - > dfut [ tbl_offset ] , unicast_reg ) ;
MVGBE_ REG_WR( regs - > dfut [ tbl_offset ] , unicast_reg ) ;
break ;
case ACCEPT_MAC_ADDR :
/* Set accepts frame bit at unicast DA filter table entry */
unicast_reg = KWGBE REG_RD( regs - > dfut [ tbl_offset ] ) ;
unicast_reg = MVGBE_ REG_RD( regs - > dfut [ tbl_offset ] ) ;
unicast_reg & = ( 0xFF < < ( 8 * reg_offset ) ) ;
unicast_reg | = ( ( 0x01 | ( RXUQ < < 1 ) ) < < ( 8 * reg_offset ) ) ;
KWGBE REG_WR( regs - > dfut [ tbl_offset ] , unicast_reg ) ;
MVGBE_ REG_WR( regs - > dfut [ tbl_offset ] , unicast_reg ) ;
break ;
default :
return 0 ;
@ -356,7 +361,7 @@ static int port_uc_addr(struct kwgbe_registers *regs, u8 uc_nibble,
/*
* port_uc_addr_set - This function Set the port Unicast address .
*/
static void port_uc_addr_set ( struct kw gbe_registers * regs , u8 * p_addr )
static void port_uc_addr_set ( struct mv gbe_registers * regs , u8 * p_addr )
{
u32 mac_h ;
u32 mac_l ;
@ -365,94 +370,95 @@ static void port_uc_addr_set(struct kwgbe_registers *regs, u8 * p_addr)
mac_h = ( p_addr [ 0 ] < < 24 ) | ( p_addr [ 1 ] < < 16 ) | ( p_addr [ 2 ] < < 8 ) |
( p_addr [ 3 ] < < 0 ) ;
KWGBE REG_WR( regs - > macal , mac_l ) ;
KWGBE REG_WR( regs - > macah , mac_h ) ;
MVGBE_ REG_WR( regs - > macal , mac_l ) ;
MVGBE_ REG_WR( regs - > macah , mac_h ) ;
/* Accept frames of this address */
port_uc_addr ( regs , p_addr [ 5 ] , ACCEPT_MAC_ADDR ) ;
}
/*
* kw gbe_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory .
* mv gbe_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory .
*/
static void kwgbe_init_rx_desc_ring ( struct kwgbe_device * dkw gbe)
static void mvgbe_init_rx_desc_ring ( struct mvgbe_device * dmv gbe)
{
struct kw gbe_rxdesc * p_rx_desc ;
struct mv gbe_rxdesc * p_rx_desc ;
int i ;
/* initialize the Rx descriptors ring */
p_rx_desc = dkw gbe - > p_rxdesc ;
p_rx_desc = dmv gbe - > p_rxdesc ;
for ( i = 0 ; i < RINGSZ ; i + + ) {
p_rx_desc - > cmd_sts =
KWGBE_BUFFER_OWNED_BY_DMA | KW GBE_RX_EN_INTERRUPT;
MVGBE_BUFFER_OWNED_BY_DMA | MV GBE_RX_EN_INTERRUPT;
p_rx_desc - > buf_size = PKTSIZE_ALIGN ;
p_rx_desc - > byte_cnt = 0 ;
p_rx_desc - > buf_ptr = dkw gbe - > p_rxbuf + i * PKTSIZE_ALIGN ;
p_rx_desc - > buf_ptr = dmv gbe - > p_rxbuf + i * PKTSIZE_ALIGN ;
if ( i = = ( RINGSZ - 1 ) )
p_rx_desc - > nxtdesc_p = dkw gbe - > p_rxdesc ;
p_rx_desc - > nxtdesc_p = dmv gbe - > p_rxdesc ;
else {
p_rx_desc - > nxtdesc_p = ( struct kw gbe_rxdesc * )
( ( u32 ) p_rx_desc + KW _RXQ_DESC_ALIGNED_SIZE) ;
p_rx_desc - > nxtdesc_p = ( struct mv gbe_rxdesc * )
( ( u32 ) p_rx_desc + MV _RXQ_DESC_ALIGNED_SIZE) ;
p_rx_desc = p_rx_desc - > nxtdesc_p ;
}
}
dkw gbe - > p_rxdesc_curr = dkw gbe - > p_rxdesc ;
dmv gbe - > p_rxdesc_curr = dmv gbe - > p_rxdesc ;
}
static int kw gbe_init( struct eth_device * dev )
static int mv gbe_init( struct eth_device * dev )
{
struct kwgbe_device * dkwgbe = to_dkw gbe( dev ) ;
struct kw gbe_registers * regs = dkw gbe - > regs ;
struct mvgbe_device * dmvgbe = to_mv gbe( dev ) ;
struct mv gbe_registers * regs = dmv gbe - > regs ;
# if (defined (CONFIG_MII) || defined (CONFIG_CMD_MII)) \
& & defined ( CONFIG_SYS_FAULT_ECHO_LINK_DOWN )
int i ;
# endif
/* setup RX rings */
kwgbe_init_rx_desc_ring ( dkw gbe) ;
mvgbe_init_rx_desc_ring ( dmv gbe) ;
/* Clear the ethernet port interrupts */
KWGBE REG_WR( regs - > ic , 0 ) ;
KWGBE REG_WR( regs - > ice , 0 ) ;
MVGBE_ REG_WR( regs - > ic , 0 ) ;
MVGBE_ REG_WR( regs - > ice , 0 ) ;
/* Unmask RX buffer and TX end interrupt */
KWGBE REG_WR( regs - > pim , INT_CAUSE_UNMASK_ALL ) ;
MVGBE_ REG_WR( regs - > pim , INT_CAUSE_UNMASK_ALL ) ;
/* Unmask phy and link status changes interrupts */
KWGBE REG_WR( regs - > peim , INT_CAUSE_UNMASK_ALL_EXT ) ;
MVGBE_ REG_WR( regs - > peim , INT_CAUSE_UNMASK_ALL_EXT ) ;
set_dram_access ( regs ) ;
port_init_mac_tables ( regs ) ;
port_uc_addr_set ( regs , dkw gbe - > dev . enetaddr ) ;
port_uc_addr_set ( regs , dmv gbe - > dev . enetaddr ) ;
/* Assign port configuration and command. */
KWGBE REG_WR( regs - > pxc , PRT_CFG_VAL ) ;
KWGBE REG_WR( regs - > pxcx , PORT_CFG_EXTEND_VALUE ) ;
KWGBE REG_WR( regs - > psc0 , PORT_SERIAL_CONTROL_VALUE ) ;
MVGBE_ REG_WR( regs - > pxc , PRT_CFG_VAL ) ;
MVGBE_ REG_WR( regs - > pxcx , PORT_CFG_EXTEND_VALUE ) ;
MVGBE_ REG_WR( regs - > psc0 , PORT_SERIAL_CONTROL_VALUE ) ;
/* Assign port SDMA configuration */
KWGBEREG_WR ( regs - > sdc , PORT_SDMA_CFG_VALUE ) ;
KWGBEREG_WR ( regs - > tqx [ 0 ] . qxttbc , QTKNBKT_DEF_VAL ) ;
KWGBEREG_WR ( regs - > tqx [ 0 ] . tqxtbc , ( QMTBS_DEF_VAL < < 16 ) | QTKNRT_DEF_VAL ) ;
MVGBE_REG_WR ( regs - > sdc , PORT_SDMA_CFG_VALUE ) ;
MVGBE_REG_WR ( regs - > tqx [ 0 ] . qxttbc , QTKNBKT_DEF_VAL ) ;
MVGBE_REG_WR ( regs - > tqx [ 0 ] . tqxtbc ,
( QMTBS_DEF_VAL < < 16 ) | QTKNRT_DEF_VAL ) ;
/* Turn off the port/RXUQ bandwidth limitation */
KWGBE REG_WR( regs - > pmtu , 0 ) ;
MVGBE_ REG_WR( regs - > pmtu , 0 ) ;
/* Set maximum receive buffer to 9700 bytes */
KWGBE REG_WR( regs - > psc0 , KW GBE_MAX_RX_PACKET_9700BYTE
| ( KWGBE REG_RD( regs - > psc0 ) & MRU_MASK ) ) ;
MVGBE_ REG_WR( regs - > psc0 , MV GBE_MAX_RX_PACKET_9700BYTE
| ( MVGBE_ REG_RD( regs - > psc0 ) & MRU_MASK ) ) ;
/* Enable port initially */
KWGBE REG_BITS_SET( regs - > psc0 , KW GBE_SERIAL_PORT_EN) ;
MVGBE_ REG_BITS_SET( regs - > psc0 , MV GBE_SERIAL_PORT_EN) ;
/*
* Set ethernet MTU for leaky bucket mechanism to 0 - this will
* disable the leaky bucket mechanism .
*/
KWGBE REG_WR( regs - > pmtu , 0 ) ;
MVGBE_ REG_WR( regs - > pmtu , 0 ) ;
/* Assignment of Rx CRDB of given RXUQ */
KWGBE REG_WR( regs - > rxcdp [ RXUQ ] , ( u32 ) dkw gbe - > p_rxdesc_curr ) ;
MVGBE_ REG_WR( regs - > rxcdp [ RXUQ ] , ( u32 ) dmv gbe - > p_rxdesc_curr ) ;
/* ensure previous write is done before enabling Rx DMA */
isb ( ) ;
/* Enable port Rx. */
KWGBE REG_WR( regs - > rqc , ( 1 < < RXUQ ) ) ;
MVGBE_ REG_WR( regs - > rqc , ( 1 < < RXUQ ) ) ;
# if (defined (CONFIG_MII) || defined (CONFIG_CMD_MII)) \
& & defined ( CONFIG_SYS_FAULT_ECHO_LINK_DOWN )
@ -460,8 +466,8 @@ static int kwgbe_init(struct eth_device *dev)
for ( i = 0 ; i < 5 ; i + + ) {
u16 phyadr ;
miiphy_read ( dev - > name , KIRKWOOD _PHY_ADR_REQUEST,
KIRKWOOD _PHY_ADR_REQUEST, & phyadr ) ;
miiphy_read ( dev - > name , MV _PHY_ADR_REQUEST,
MV _PHY_ADR_REQUEST, & phyadr ) ;
/* Return if we get link up */
if ( miiphy_link ( dev - > name , phyadr ) )
return 0 ;
@ -474,50 +480,50 @@ static int kwgbe_init(struct eth_device *dev)
return 0 ;
}
static int kw gbe_halt( struct eth_device * dev )
static int mv gbe_halt( struct eth_device * dev )
{
struct kwgbe_device * dkwgbe = to_dkw gbe( dev ) ;
struct kw gbe_registers * regs = dkw gbe - > regs ;
struct mvgbe_device * dmvgbe = to_mv gbe( dev ) ;
struct mv gbe_registers * regs = dmv gbe - > regs ;
/* Disable all gigE address decoder */
KWGBE REG_WR( regs - > bare , 0x3f ) ;
MVGBE_ REG_WR( regs - > bare , 0x3f ) ;
stop_queue ( & regs - > tqc ) ;
stop_queue ( & regs - > rqc ) ;
/* Disable port */
KWGBE REG_BITS_RESET( regs - > psc0 , KW GBE_SERIAL_PORT_EN) ;
MVGBE_ REG_BITS_RESET( regs - > psc0 , MV GBE_SERIAL_PORT_EN) ;
/* Set port is not reset */
KWGBE REG_BITS_RESET( regs - > psc1 , 1 < < 4 ) ;
MVGBE_ REG_BITS_RESET( regs - > psc1 , 1 < < 4 ) ;
# ifdef CONFIG_SYS_MII_MODE
/* Set MMI interface up */
KWGBE REG_BITS_RESET( regs - > psc1 , 1 < < 3 ) ;
MVGBE_ REG_BITS_RESET( regs - > psc1 , 1 < < 3 ) ;
# endif
/* Disable & mask ethernet port interrupts */
KWGBE REG_WR( regs - > ic , 0 ) ;
KWGBE REG_WR( regs - > ice , 0 ) ;
KWGBE REG_WR( regs - > pim , 0 ) ;
KWGBE REG_WR( regs - > peim , 0 ) ;
MVGBE_ REG_WR( regs - > ic , 0 ) ;
MVGBE_ REG_WR( regs - > ice , 0 ) ;
MVGBE_ REG_WR( regs - > pim , 0 ) ;
MVGBE_ REG_WR( regs - > peim , 0 ) ;
return 0 ;
}
static int kw gbe_write_hwaddr( struct eth_device * dev )
static int mv gbe_write_hwaddr( struct eth_device * dev )
{
struct kwgbe_device * dkwgbe = to_dkw gbe( dev ) ;
struct kw gbe_registers * regs = dkw gbe - > regs ;
struct mvgbe_device * dmvgbe = to_mv gbe( dev ) ;
struct mv gbe_registers * regs = dmv gbe - > regs ;
/* Programs net device MAC address after initialization */
port_uc_addr_set ( regs , dkw gbe - > dev . enetaddr ) ;
port_uc_addr_set ( regs , dmv gbe - > dev . enetaddr ) ;
return 0 ;
}
static int kw gbe_send( struct eth_device * dev , volatile void * dataptr ,
static int mv gbe_send( struct eth_device * dev , void * dataptr ,
int datasize )
{
struct kwgbe_device * dkwgbe = to_dkw gbe( dev ) ;
struct kw gbe_registers * regs = dkw gbe - > regs ;
struct kw gbe_txdesc * p_txdesc = dkw gbe - > p_txdesc ;
struct mvgbe_device * dmvgbe = to_mv gbe( dev ) ;
struct mv gbe_registers * regs = dmv gbe - > regs ;
struct mv gbe_txdesc * p_txdesc = dmv gbe - > p_txdesc ;
void * p = ( void * ) dataptr ;
u32 cmd_sts ;
@ -529,35 +535,35 @@ static int kwgbe_send(struct eth_device *dev, volatile void *dataptr,
return - 1 ;
}
memcpy ( dkw gbe - > p_aligned_txbuf , p , datasize ) ;
p = dkw gbe - > p_aligned_txbuf ;
memcpy ( dmv gbe - > p_aligned_txbuf , p , datasize ) ;
p = dmv gbe - > p_aligned_txbuf ;
}
p_txdesc - > cmd_sts = KWGBE_ZERO_PADDING | KW GBE_GEN_CRC;
p_txdesc - > cmd_sts | = KWGBE_TX_FIRST_DESC | KW GBE_TX_LAST_DESC;
p_txdesc - > cmd_sts | = KW GBE_BUFFER_OWNED_BY_DMA;
p_txdesc - > cmd_sts | = KW GBE_TX_EN_INTERRUPT;
p_txdesc - > cmd_sts = MVGBE_ZERO_PADDING | MV GBE_GEN_CRC;
p_txdesc - > cmd_sts | = MVGBE_TX_FIRST_DESC | MV GBE_TX_LAST_DESC;
p_txdesc - > cmd_sts | = MV GBE_BUFFER_OWNED_BY_DMA;
p_txdesc - > cmd_sts | = MV GBE_TX_EN_INTERRUPT;
p_txdesc - > buf_ptr = ( u8 * ) p ;
p_txdesc - > byte_cnt = datasize ;
/* Set this tc desc as zeroth TXUQ */
KWGBE REG_WR( regs - > tcqdp [ TXUQ ] , ( u32 ) p_txdesc ) ;
MVGBE_ REG_WR( regs - > tcqdp [ TXUQ ] , ( u32 ) p_txdesc ) ;
/* ensure tx desc writes above are performed before we start Tx DMA */
isb ( ) ;
/* Apply send command using zeroth TXUQ */
KWGBE REG_WR( regs - > tqc , ( 1 < < TXUQ ) ) ;
MVGBE_ REG_WR( regs - > tqc , ( 1 < < TXUQ ) ) ;
/*
* wait for packet xmit completion
*/
cmd_sts = readl ( & p_txdesc - > cmd_sts ) ;
while ( cmd_sts & KW GBE_BUFFER_OWNED_BY_DMA) {
while ( cmd_sts & MV GBE_BUFFER_OWNED_BY_DMA) {
/* return fail if error is detected */
if ( ( cmd_sts & ( KWGBE_ERROR_SUMMARY | KW GBE_TX_LAST_FRAME) ) = =
( KWGBE_ERROR_SUMMARY | KW GBE_TX_LAST_FRAME) & &
cmd_sts & ( KWGBE_UR_ERROR | KW GBE_RL_ERROR) ) {
if ( ( cmd_sts & ( MVGBE_ERROR_SUMMARY | MV GBE_TX_LAST_FRAME) ) = =
( MVGBE_ERROR_SUMMARY | MV GBE_TX_LAST_FRAME) & &
cmd_sts & ( MVGBE_UR_ERROR | MV GBE_RL_ERROR) ) {
printf ( " Err..(%s) in xmit packet \n " , __FUNCTION__ ) ;
return - 1 ;
}
@ -566,22 +572,22 @@ static int kwgbe_send(struct eth_device *dev, volatile void *dataptr,
return 0 ;
}
static int kw gbe_recv( struct eth_device * dev )
static int mv gbe_recv( struct eth_device * dev )
{
struct kwgbe_device * dkwgbe = to_dkw gbe( dev ) ;
struct kw gbe_rxdesc * p_rxdesc_curr = dkw gbe - > p_rxdesc_curr ;
struct mvgbe_device * dmvgbe = to_mv gbe( dev ) ;
struct mv gbe_rxdesc * p_rxdesc_curr = dmv gbe - > p_rxdesc_curr ;
u32 cmd_sts ;
u32 timeout = 0 ;
/* wait untill rx packet available or timeout */
do {
if ( timeout < KW GBE_PHY_SMI_TIMEOUT)
if ( timeout < MV GBE_PHY_SMI_TIMEOUT)
timeout + + ;
else {
debug ( " %s time out... \n " , __FUNCTION__ ) ;
return - 1 ;
}
} while ( readl ( & p_rxdesc_curr - > cmd_sts ) & KW GBE_BUFFER_OWNED_BY_DMA) ;
} while ( readl ( & p_rxdesc_curr - > cmd_sts ) & MV GBE_BUFFER_OWNED_BY_DMA) ;
if ( p_rxdesc_curr - > byte_cnt ! = 0 ) {
debug ( " %s: Received %d byte Packet @ 0x%x (cmd_sts= %08x) \n " ,
@ -598,13 +604,13 @@ static int kwgbe_recv(struct eth_device *dev)
cmd_sts = readl ( & p_rxdesc_curr - > cmd_sts ) ;
if ( ( cmd_sts &
( KWGBE_RX_FIRST_DESC | KW GBE_RX_LAST_DESC) )
! = ( KWGBE_RX_FIRST_DESC | KW GBE_RX_LAST_DESC) ) {
( MVGBE_RX_FIRST_DESC | MV GBE_RX_LAST_DESC) )
! = ( MVGBE_RX_FIRST_DESC | MV GBE_RX_LAST_DESC) ) {
printf ( " Err..(%s) Dropping packet spread on "
" multiple descriptors \n " , __FUNCTION__ ) ;
} else if ( cmd_sts & KW GBE_ERROR_SUMMARY) {
} else if ( cmd_sts & MV GBE_ERROR_SUMMARY) {
printf ( " Err..(%s) Dropping packet with errors \n " ,
__FUNCTION__ ) ;
@ -622,62 +628,72 @@ static int kwgbe_recv(struct eth_device *dev)
* free these descriptors and point next in the ring
*/
p_rxdesc_curr - > cmd_sts =
KWGBE_BUFFER_OWNED_BY_DMA | KW GBE_RX_EN_INTERRUPT;
MVGBE_BUFFER_OWNED_BY_DMA | MV GBE_RX_EN_INTERRUPT;
p_rxdesc_curr - > buf_size = PKTSIZE_ALIGN ;
p_rxdesc_curr - > byte_cnt = 0 ;
writel ( ( unsigned ) p_rxdesc_curr - > nxtdesc_p , ( u32 ) & dkwgbe - > p_rxdesc_curr ) ;
writel ( ( unsigned ) p_rxdesc_curr - > nxtdesc_p ,
( u32 ) & dmvgbe - > p_rxdesc_curr ) ;
return 0 ;
}
int kirkwood_egiga _initialize( bd_t * bis )
int mvgbe _initialize( bd_t * bis )
{
struct kwgbe_device * dkw gbe;
struct mvgbe_device * dmv gbe;
struct eth_device * dev ;
int devnum ;
char * s ;
u8 used_ports [ MAX_KWGBE_DEVS ] = CONFIG_KIRKWOOD_EGIGA _PORTS ;
u8 used_ports [ MAX_MVGBE_DEVS ] = CONFIG_MVGBE _PORTS ;
for ( devnum = 0 ; devnum < MAX_KW GBE_DEVS ; devnum + + ) {
for ( devnum = 0 ; devnum < MAX_MV GBE_DEVS ; devnum + + ) {
/*skip if port is configured not to use */
if ( used_ports [ devnum ] = = 0 )
continue ;
if ( ! ( dkwgbe = malloc ( sizeof ( struct kwgbe_device ) ) ) )
dmvgbe = malloc ( sizeof ( struct mvgbe_device ) ) ;
if ( ! dmvgbe )
goto error1 ;
memset ( dkw gbe , 0 , sizeof ( struct kw gbe_device) ) ;
memset ( dmv gbe , 0 , sizeof ( struct mv gbe_device) ) ;
if ( ! ( dkwgbe - > p_rxdesc =
( struct kwgbe_rxdesc * ) memalign ( PKTALIGN ,
KW_RXQ_DESC_ALIGNED_SIZE
* RINGSZ + 1 ) ) )
dmvgbe - > p_rxdesc =
( struct mvgbe_rxdesc * ) memalign ( PKTALIGN ,
MV_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1 ) ;
if ( ! dmvgbe - > p_rxdesc )
goto error2 ;
if ( ! ( dkwgbe - > p_rxbuf = ( u8 * ) memalign ( PKTALIGN , RINGSZ
* PKTSIZE_ALIGN + 1 ) ) )
dmvgbe - > p_rxbuf = ( u8 * ) memalign ( PKTALIGN ,
RINGSZ * PKTSIZE_ALIGN + 1 ) ;
if ( ! dmvgbe - > p_rxbuf )
goto error3 ;
if ( ! ( dkwgbe - > p_aligned_txbuf = memalign ( 8 , PKTSIZE_ALIGN ) ) )
dmvgbe - > p_aligned_txbuf = memalign ( 8 , PKTSIZE_ALIGN ) ;
if ( ! dmvgbe - > p_aligned_txbuf )
goto error4 ;
if ( ! ( dkwgbe - > p_txdesc = ( struct kwgbe_txdesc * )
memalign ( PKTALIGN , sizeof ( struct kwgbe_txdesc ) + 1 ) ) ) {
free ( dkwgbe - > p_aligned_txbuf ) ;
error4 :
free ( dkwgbe - > p_rxbuf ) ;
error3 :
free ( dkwgbe - > p_rxdesc ) ;
error2 :
free ( dkwgbe ) ;
error1 :
dmvgbe - > p_txdesc = ( struct mvgbe_txdesc * ) memalign (
PKTALIGN , sizeof ( struct mvgbe_txdesc ) + 1 ) ;
if ( ! dmvgbe - > p_txdesc ) {
free ( dmvgbe - > p_aligned_txbuf ) ;
error4 :
free ( dmvgbe - > p_rxbuf ) ;
error3 :
free ( dmvgbe - > p_rxdesc ) ;
error2 :
free ( dmvgbe ) ;
error1 :
printf ( " Err.. %s Failed to allocate memory \n " ,
__FUNCTION__ ) ;
return - 1 ;
}
dev = & dkw gbe - > dev ;
dev = & dmv gbe - > dev ;
/* must be less than NAMESIZE (16) */
sprintf ( dev - > name , " egiga%d " , devnum ) ;
@ -685,13 +701,15 @@ int kirkwood_egiga_initialize(bd_t * bis)
/* Extract the MAC address from the environment */
switch ( devnum ) {
case 0 :
dkw gbe - > regs = ( void * ) KW_EGIGA 0_BASE;
dmv gbe - > regs = ( void * ) MVGBE 0_BASE;
s = " ethaddr " ;
break ;
# if defined(MVGBE1_BASE)
case 1 :
dkw gbe - > regs = ( void * ) KW_EGIGA 1_BASE;
dmv gbe - > regs = ( void * ) MVGBE 1_BASE;
s = " eth1addr " ;
break ;
# endif
default : /* this should never happen */
printf ( " Err..(%s) Invalid device number %d \n " ,
__FUNCTION__ , devnum ) ;
@ -717,19 +735,19 @@ int kirkwood_egiga_initialize(bd_t * bis)
eth_setenv_enetaddr ( s , dev - > enetaddr ) ;
}
dev - > init = ( void * ) kw gbe_init;
dev - > halt = ( void * ) kw gbe_halt;
dev - > send = ( void * ) kw gbe_send;
dev - > recv = ( void * ) kw gbe_recv;
dev - > write_hwaddr = ( void * ) kw gbe_write_hwaddr;
dev - > init = ( void * ) mv gbe_init;
dev - > halt = ( void * ) mv gbe_halt;
dev - > send = ( void * ) mv gbe_send;
dev - > recv = ( void * ) mv gbe_recv;
dev - > write_hwaddr = ( void * ) mv gbe_write_hwaddr;
eth_register ( dev ) ;
# if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register ( dev - > name , smi_reg_read , smi_reg_write ) ;
/* Set phy address of the port */
miiphy_write ( dev - > name , KIRKWOOD _PHY_ADR_REQUEST,
KIRKWOOD _PHY_ADR_REQUEST, PHY_BASE_ADR + devnum ) ;
miiphy_write ( dev - > name , MV _PHY_ADR_REQUEST,
MV _PHY_ADR_REQUEST, PHY_BASE_ADR + devnum ) ;
# endif
}
return 0 ;