@ -41,10 +41,13 @@
* Modified to use le32_to_cpu and cpu_to_le32 properly
*/
# include <common.h>
# include <dm.h>
# include <errno.h>
# include <malloc.h>
# include <net.h>
# ifndef CONFIG_DM_ETH
# include <netdev.h>
# endif
# include <asm/io.h>
# include <pci.h>
@ -281,6 +284,8 @@ struct RxDesc {
u32 buf_Haddr ;
} ;
static unsigned char rxdata [ RX_BUF_LEN ] ;
# define RTL8169_DESC_SIZE 16
# if ARCH_DMA_MINALIGN > 256
@ -299,7 +304,8 @@ struct RxDesc {
* the driver to allocate descriptors from a pool of non - cached memory .
*/
# if RTL8169_DESC_SIZE < ARCH_DMA_MINALIGN
# if !defined(CONFIG_SYS_NONCACHED_MEMORY) && !defined(CONFIG_SYS_DCACHE_OFF)
# if !defined(CONFIG_SYS_NONCACHED_MEMORY) && \
! defined ( CONFIG_SYS_DCACHE_OFF ) & & ! defined ( CONFIG_X86 )
# warning cache-line size is larger than descriptor size
# endif
# endif
@ -317,6 +323,7 @@ DEFINE_ALIGN_BUFFER(u8, txb, NUM_TX_DESC * RX_BUF_SIZE, RTL8169_ALIGN);
DEFINE_ALIGN_BUFFER ( u8 , rxb , NUM_RX_DESC * RX_BUF_SIZE , RTL8169_ALIGN ) ;
struct rtl8169_private {
ulong iobase ;
void * mmio_addr ; /* memory map physical address */
int chipset ;
unsigned long cur_rx ; /* Index into the Rx descriptor buffer of next Rx pkt. */
@ -338,9 +345,9 @@ static const unsigned int rtl8169_rx_config =
( RX_FIFO_THRESH < < RxCfgFIFOShift ) | ( RX_DMA_BURST < < RxCfgDMAShift ) ;
static struct pci_device_id supported [ ] = {
{ PCI_VENDOR_ID_REALTEK , 0x8167 } ,
{ PCI_VENDOR_ID_REALTEK , 0x8168 } ,
{ PCI_VENDOR_ID_REALTEK , 0x8169 } ,
{ PCI_DEVICE ( PCI_VENDOR_ID_REALTEK , 0x8167 ) } ,
{ PCI_DEVICE ( PCI_VENDOR_ID_REALTEK , 0x8168 ) } ,
{ PCI_DEVICE ( PCI_VENDOR_ID_REALTEK , 0x8169 ) } ,
{ }
} ;
@ -380,7 +387,7 @@ int mdio_read(int RegAddr)
return value ;
}
static int rtl8169_init_board ( struct eth_device * dev )
static int rtl8169_init_board ( unsigned long dev_iobase , const char * name )
{
int i ;
u32 tmp ;
@ -388,7 +395,7 @@ static int rtl8169_init_board(struct eth_device *dev)
# ifdef DEBUG_RTL8169
printf ( " %s \n " , __FUNCTION__ ) ;
# endif
ioaddr = dev - > iobase ;
ioaddr = dev_ iobase ;
/* Soft reset the chip. */
RTL_W8 ( ChipCmd , CmdReset ) ;
@ -412,7 +419,8 @@ static int rtl8169_init_board(struct eth_device *dev)
}
/* if unknown chip, assume array element #0, original RTL-8169 in this case */
printf ( " PCI device %s: unknown chip version, assuming RTL-8169 \n " , dev - > name ) ;
printf ( " PCI device %s: unknown chip version, assuming RTL-8169 \n " ,
name ) ;
printf ( " PCI device: TxConfig = 0x%lX \n " , ( unsigned long ) RTL_R32 ( TxConfig ) ) ;
tpc - > chipset = 0 ;
@ -504,7 +512,8 @@ static void rtl_flush_buffer(void *buf, size_t size)
/**************************************************************************
RECV - Receive a frame
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int rtl_recv ( struct eth_device * dev )
static int rtl_recv_common ( pci_dev_t bdf , unsigned long dev_iobase ,
uchar * * packetp )
{
/* return true if there's an ethernet packet ready to read */
/* nic->packet should contain data on return */
@ -515,7 +524,7 @@ static int rtl_recv(struct eth_device *dev)
# ifdef DEBUG_RTL8169_RX
printf ( " %s \n " , __FUNCTION__ ) ;
# endif
ioaddr = dev - > iobase ;
ioaddr = dev_ iobase ;
cur_rx = tpc - > cur_rx ;
@ -523,7 +532,6 @@ static int rtl_recv(struct eth_device *dev)
if ( ( le32_to_cpu ( tpc - > RxDescArray [ cur_rx ] . status ) & OWNbit ) = = 0 ) {
if ( ! ( le32_to_cpu ( tpc - > RxDescArray [ cur_rx ] . status ) & RxRES ) ) {
unsigned char rxdata [ RX_BUF_LEN ] ;
length = ( int ) ( le32_to_cpu ( tpc - > RxDescArray [ cur_rx ] .
status ) & 0x00001FFF ) - 4 ;
@ -536,17 +544,22 @@ static int rtl_recv(struct eth_device *dev)
else
tpc - > RxDescArray [ cur_rx ] . status =
cpu_to_le32 ( OWNbit + RX_BUF_SIZE ) ;
tpc - > RxDescArray [ cur_rx ] . buf_addr =
cpu_to_le32 ( bus_to_phys ( tpc - > RxBufferRing [ cur_rx ] ) ) ;
tpc - > RxDescArray [ cur_rx ] . buf_addr = cpu_to_le32 (
pci_mem_to_phys ( bdf , ( pci_addr_t ) ( unsigned long )
tpc - > RxBufferRing [ cur_rx ] ) ) ;
rtl_flush_rx_desc ( & tpc - > RxDescArray [ cur_rx ] ) ;
# ifdef CONFIG_DM_ETH
* packetp = rxdata ;
# else
net_process_received_packet ( rxdata , length ) ;
# endif
} else {
puts ( " Error Rx " ) ;
length = - EIO ;
}
cur_rx = ( cur_rx + 1 ) % NUM_RX_DESC ;
tpc - > cur_rx = cur_rx ;
return 1 ;
return length ;
} else {
ushort sts = RTL_R8 ( IntrStatus ) ;
@ -557,11 +570,26 @@ static int rtl_recv(struct eth_device *dev)
return ( 0 ) ; /* initially as this is called to flush the input */
}
# ifdef CONFIG_DM_ETH
int rtl8169_eth_recv ( struct udevice * dev , int flags , uchar * * packetp )
{
struct rtl8169_private * priv = dev_get_priv ( dev ) ;
return rtl_recv_common ( pci_get_bdf ( dev ) , priv - > iobase , packetp ) ;
}
# else
static int rtl_recv ( struct eth_device * dev )
{
return rtl_recv_common ( ( pci_dev_t ) dev - > priv , dev - > iobase , NULL ) ;
}
# endif /* nCONFIG_DM_ETH */
# define HZ 1000
/**************************************************************************
SEND - Transmit a frame
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int rtl_send ( struct eth_device * dev , void * packet , int length )
static int rtl_send_common ( pci_dev_t bdf , unsigned long dev_iobase ,
void * packet , int length )
{
/* send the packet to destination */
@ -577,7 +605,7 @@ static int rtl_send(struct eth_device *dev, void *packet, int length)
printf ( " sending %d bytes \n " , len ) ;
# endif
ioaddr = dev - > iobase ;
ioaddr = dev_ iobase ;
/* point to the current txb incase multiple tx_rings are used */
ptxb = tpc - > Tx_skbuff [ entry * MAX_ETH_FRAME_SIZE ] ;
@ -588,7 +616,8 @@ static int rtl_send(struct eth_device *dev, void *packet, int length)
ptxb [ len + + ] = ' \0 ' ;
tpc - > TxDescArray [ entry ] . buf_Haddr = 0 ;
tpc - > TxDescArray [ entry ] . buf_addr = cpu_to_le32 ( bus_to_phys ( ptxb ) ) ;
tpc - > TxDescArray [ entry ] . buf_addr = cpu_to_le32 (
pci_mem_to_phys ( bdf , ( pci_addr_t ) ( unsigned long ) ptxb ) ) ;
if ( entry ! = ( NUM_TX_DESC - 1 ) ) {
tpc - > TxDescArray [ entry ] . status =
cpu_to_le32 ( ( OWNbit | FSbit | LSbit ) |
@ -625,7 +654,23 @@ static int rtl_send(struct eth_device *dev, void *packet, int length)
return ret ;
}
static void rtl8169_set_rx_mode ( struct eth_device * dev )
# ifdef CONFIG_DM_ETH
int rtl8169_eth_send ( struct udevice * dev , void * packet , int length )
{
struct rtl8169_private * priv = dev_get_priv ( dev ) ;
return rtl_send_common ( pci_get_bdf ( dev ) , priv - > iobase , packet , length ) ;
}
# else
static int rtl_send ( struct eth_device * dev , void * packet , int length )
{
return rtl_send_common ( ( pci_dev_t ) dev - > priv , dev - > iobase , packet ,
length ) ;
}
# endif
static void rtl8169_set_rx_mode ( void )
{
u32 mc_filter [ 2 ] ; /* Multicast hash filter */
int rx_mode ;
@ -648,7 +693,7 @@ static void rtl8169_set_rx_mode(struct eth_device *dev)
RTL_W32 ( MAR0 + 4 , mc_filter [ 1 ] ) ;
}
static void rtl8169_hw_start ( struct eth_device * dev )
static void rtl8169_hw_start ( pci_dev_t bdf )
{
u32 i ;
@ -693,9 +738,11 @@ static void rtl8169_hw_start(struct eth_device *dev)
tpc - > cur_rx = 0 ;
RTL_W32 ( TxDescStartAddrLow , bus_to_phys ( tpc - > TxDescArray ) ) ;
RTL_W32 ( TxDescStartAddrLow , pci_mem_to_phys ( bdf ,
( pci_addr_t ) ( unsigned long ) tpc - > TxDescArray ) ) ;
RTL_W32 ( TxDescStartAddrHigh , ( unsigned long ) 0 ) ;
RTL_W32 ( RxDescStartAddrLow , bus_to_phys ( tpc - > RxDescArray ) ) ;
RTL_W32 ( RxDescStartAddrLow , pci_mem_to_phys (
bdf , ( pci_addr_t ) ( unsigned long ) tpc - > RxDescArray ) ) ;
RTL_W32 ( RxDescStartAddrHigh , ( unsigned long ) 0 ) ;
/* RTL-8169sc/8110sc or later version */
@ -707,7 +754,7 @@ static void rtl8169_hw_start(struct eth_device *dev)
RTL_W32 ( RxMissed , 0 ) ;
rtl8169_set_rx_mode ( dev ) ;
rtl8169_set_rx_mode ( ) ;
/* no early-rx interrupts */
RTL_W16 ( MultiIntr , RTL_R16 ( MultiIntr ) & 0xF000 ) ;
@ -717,7 +764,7 @@ static void rtl8169_hw_start(struct eth_device *dev)
# endif
}
static void rtl8169_init_ring ( struct eth_device * dev )
static void rtl8169_init_ring ( pci_dev_t bdf )
{
int i ;
@ -745,8 +792,8 @@ static void rtl8169_init_ring(struct eth_device *dev)
cpu_to_le32 ( OWNbit + RX_BUF_SIZE ) ;
tpc - > RxBufferRing [ i ] = & rxb [ i * RX_BUF_SIZE ] ;
tpc - > RxDescArray [ i ] . buf_addr =
cpu_to_le32 ( bus_to_phys ( tpc - > RxBufferRing [ i ] ) ) ;
tpc - > RxDescArray [ i ] . buf_addr = cpu_to_le32 ( pci_mem_to_phys (
bdf , ( pci_addr_t ) ( unsigned long ) tpc - > RxBufferRing [ i ] ) ) ;
rtl_flush_rx_desc ( & tpc - > RxDescArray [ i ] ) ;
}
@ -755,10 +802,7 @@ static void rtl8169_init_ring(struct eth_device *dev)
# endif
}
/**************************************************************************
RESET - Finish setting up the ethernet interface
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int rtl_reset ( struct eth_device * dev , bd_t * bis )
static void rtl8169_common_start ( pci_dev_t bdf , unsigned char * enetaddr )
{
int i ;
@ -767,30 +811,47 @@ static int rtl_reset(struct eth_device *dev, bd_t *bis)
printf ( " %s \n " , __FUNCTION__ ) ;
# endif
rtl8169_init_ring ( dev ) ;
rtl8169_hw_start ( dev ) ;
rtl8169_init_ring ( bdf ) ;
rtl8169_hw_start ( bdf ) ;
/* Construct a perfect filter frame with the mac address as first match
* and broadcast for all others */
for ( i = 0 ; i < 192 ; i + + )
txb [ i ] = 0xFF ;
txb [ 0 ] = dev - > enetaddr [ 0 ] ;
txb [ 1 ] = dev - > enetaddr [ 1 ] ;
txb [ 2 ] = dev - > enetaddr [ 2 ] ;
txb [ 3 ] = dev - > enetaddr [ 3 ] ;
txb [ 4 ] = dev - > enetaddr [ 4 ] ;
txb [ 5 ] = dev - > enetaddr [ 5 ] ;
txb [ 0 ] = enetaddr [ 0 ] ;
txb [ 1 ] = enetaddr [ 1 ] ;
txb [ 2 ] = enetaddr [ 2 ] ;
txb [ 3 ] = enetaddr [ 3 ] ;
txb [ 4 ] = enetaddr [ 4 ] ;
txb [ 5 ] = enetaddr [ 5 ] ;
# ifdef DEBUG_RTL8169
printf ( " %s elapsed time : %lu \n " , __func__ , currticks ( ) - stime ) ;
# endif
return 0 ;
}
# ifdef CONFIG_DM_ETH
static int rtl8169_eth_start ( struct udevice * dev )
{
struct eth_pdata * plat = dev_get_platdata ( dev ) ;
rtl8169_common_start ( pci_get_bdf ( dev ) , plat - > enetaddr ) ;
return 0 ;
}
# else
/**************************************************************************
HALT - Turn off ethernet interface
RESET - Finish setting up the ethernet interface
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void rtl_halt ( struct eth_device * dev )
static int rtl_reset ( struct eth_device * dev , bd_t * bis )
{
rtl8169_common_start ( ( pci_dev_t ) dev - > priv , dev - > enetaddr ) ;
return 0 ;
}
# endif /* nCONFIG_DM_ETH */
static void rtl_halt_common ( unsigned long dev_iobase )
{
int i ;
@ -798,7 +859,7 @@ static void rtl_halt(struct eth_device *dev)
printf ( " %s \n " , __FUNCTION__ ) ;
# endif
ioaddr = dev - > iobase ;
ioaddr = dev_ iobase ;
/* Stop the chip's Tx and Rx DMA processes. */
RTL_W8 ( ChipCmd , 0x00 ) ;
@ -813,13 +874,31 @@ static void rtl_halt(struct eth_device *dev)
}
}
# ifdef CONFIG_DM_ETH
void rtl8169_eth_stop ( struct udevice * dev )
{
struct rtl8169_private * priv = dev_get_priv ( dev ) ;
rtl_halt_common ( priv - > iobase ) ;
}
# else
/**************************************************************************
HALT - Turn off ethernet interface
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void rtl_halt ( struct eth_device * dev )
{
rtl_halt_common ( dev - > iobase ) ;
}
# endif
/**************************************************************************
INIT - Look for an adapter , this routine ' s visible to the outside
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define board_found 1
# define valid_link 0
static int rtl_init ( struct eth_device * dev , bd_t * bis )
static int rtl_init ( unsigned long dev_ioaddr , const char * name ,
unsigned char * enetaddr )
{
static int board_idx = - 1 ;
int i , rc ;
@ -828,33 +907,32 @@ static int rtl_init(struct eth_device *dev, bd_t *bis)
# ifdef DEBUG_RTL8169
printf ( " %s \n " , __FUNCTION__ ) ;
# endif
ioaddr = dev - > iobase ;
ioaddr = dev_ioaddr ;
board_idx + + ;
/* point to private storage */
tpc = & tpx ;
rc = rtl8169_init_board ( dev ) ;
rc = rtl8169_init_board ( ioa ddr , nam e) ;
if ( rc )
return rc ;
/* Get MAC address. FIXME: read EEPROM */
for ( i = 0 ; i < MAC_ADDR_LEN ; i + + )
dev - > enetaddr [ i ] = RTL_R8 ( MAC0 + i ) ;
enetaddr [ i ] = RTL_R8 ( MAC0 + i ) ;
# ifdef DEBUG_RTL8169
printf ( " chipset = %d \n " , tpc - > chipset ) ;
printf ( " MAC Address " ) ;
for ( i = 0 ; i < MAC_ADDR_LEN ; i + + )
printf ( " :%02x " , dev - > enetaddr [ i ] ) ;
printf ( " :%02x " , enetaddr [ i ] ) ;
putc ( ' \n ' ) ;
# endif
# ifdef DEBUG_RTL8169
/* Print out some hardware info */
printf ( " %s: at ioaddr 0x%lx \n " , dev - > name , ioaddr ) ;
printf ( " %s: at ioaddr 0x%lx \n " , name , ioaddr ) ;
# endif
/* if TBI is not endbled */
@ -964,6 +1042,7 @@ static int rtl_init(struct eth_device *dev, bd_t *bis)
return 0 ;
}
# ifndef CONFIG_DM_ETH
int rtl8169_initialize ( bd_t * bis )
{
pci_dev_t devno ;
@ -1014,7 +1093,7 @@ int rtl8169_initialize(bd_t *bis)
dev - > send = rtl_send ;
dev - > recv = rtl_recv ;
err = rtl_init ( dev , bis ) ;
err = rtl_init ( dev - > iobase , dev - > name , dev - > enetaddr ) ;
if ( err < 0 ) {
printf ( pr_fmt ( " failed to initialize card: %d \n " ) , err ) ;
free ( dev ) ;
@ -1027,3 +1106,62 @@ int rtl8169_initialize(bd_t *bis)
}
return card_number ;
}
# endif
# ifdef CONFIG_DM_ETH
static int rtl8169_eth_probe ( struct udevice * dev )
{
struct pci_child_platdata * pplat = dev_get_parent_platdata ( dev ) ;
struct rtl8169_private * priv = dev_get_priv ( dev ) ;
struct eth_pdata * plat = dev_get_platdata ( dev ) ;
u32 iobase ;
int region ;
int ret ;
debug ( " rtl8169: REALTEK RTL8169 @0x%x \n " , iobase ) ;
switch ( pplat - > device ) {
case 0x8168 :
region = 2 ;
break ;
default :
region = 1 ;
break ;
}
pci_read_config32 ( pci_get_bdf ( dev ) , PCI_BASE_ADDRESS_0 + region * 4 ,
& iobase ) ;
iobase & = ~ 0xf ;
priv - > iobase = ( int ) pci_mem_to_phys ( pci_get_bdf ( dev ) , iobase ) ;
ret = rtl_init ( priv - > iobase , dev - > name , plat - > enetaddr ) ;
if ( ret < 0 ) {
printf ( pr_fmt ( " failed to initialize card: %d \n " ) , ret ) ;
return ret ;
}
return 0 ;
}
static const struct eth_ops rtl8169_eth_ops = {
. start = rtl8169_eth_start ,
. send = rtl8169_eth_send ,
. recv = rtl8169_eth_recv ,
. stop = rtl8169_eth_stop ,
} ;
static const struct udevice_id rtl8169_eth_ids [ ] = {
{ . compatible = " realtek,rtl8169 " } ,
{ }
} ;
U_BOOT_DRIVER ( eth_rtl8169 ) = {
. name = " eth_rtl8169 " ,
. id = UCLASS_ETH ,
. of_match = rtl8169_eth_ids ,
. probe = rtl8169_eth_probe ,
. ops = & rtl8169_eth_ops ,
. priv_auto_alloc_size = sizeof ( struct rtl8169_private ) ,
. platdata_auto_alloc_size = sizeof ( struct eth_pdata ) ,
} ;
U_BOOT_PCI_DEVICE ( eth_rtl8169 , supported ) ;
# endif