@ -12,18 +12,19 @@
# include <dm.h>
# include <malloc.h>
# include <memalign.h>
# include <miiphy.h>
# include <net.h>
# include <netdev.h>
# include <miiphy.h>
# include "fec_mxc.h"
# include <asm/arch/clock.h>
# include <asm/arch/imx-regs.h>
# include <asm/imx-common/sys_proto.h>
# include <asm/io.h>
# include <linux/errno.h>
# include <linux/compiler.h>
# include <asm/arch/clock.h>
# include <asm/arch/imx-regs.h>
# include <asm/imx-common/sys_proto.h>
DECLARE_GLOBAL_DATA_PTR ;
/*
@ -80,11 +81,9 @@ static void swap_packet(uint32_t *packet, int length)
}
# endif
/*
* MII - interface related functions
*/
static int fec_mdio_read ( struct ethernet_regs * eth , uint8_t phyAddr ,
uint8_t regAddr )
/* MII-interface related functions */
static int fec_mdio_read ( struct ethernet_regs * eth , uint8_t phyaddr ,
uint8_t regaddr )
{
uint32_t reg ; /* convenient holder for the PHY register */
uint32_t phy ; /* convenient holder for the PHY */
@ -96,15 +95,13 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr,
* programming the FEC ' s MII data register .
*/
writel ( FEC_IEVENT_MII , & eth - > ievent ) ;
reg = regA ddr < < FEC_MII_DATA_RA_SHIFT ;
phy = phyA ddr < < FEC_MII_DATA_PA_SHIFT ;
reg = rega ddr < < FEC_MII_DATA_RA_SHIFT ;
phy = phya ddr < < FEC_MII_DATA_PA_SHIFT ;
writel ( FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA |
phy | reg , & eth - > mii_data ) ;
/*
* wait for the related interrupt
*/
/* wait for the related interrupt */
start = get_timer ( 0 ) ;
while ( ! ( readl ( & eth - > ievent ) & FEC_IEVENT_MII ) ) {
if ( get_timer ( start ) > ( CONFIG_SYS_HZ / 1000 ) ) {
@ -113,17 +110,13 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr,
}
}
/*
* clear mii interrupt bit
*/
/* clear mii interrupt bit */
writel ( FEC_IEVENT_MII , & eth - > ievent ) ;
/*
* it ' s now safe to read the PHY ' s register
*/
/* it's now safe to read the PHY's register */
val = ( unsigned short ) readl ( & eth - > mii_data ) ;
debug ( " %s: phy: %02x reg:%02x val:%#x \n " , __func__ , phyA ddr ,
regA ddr , val ) ;
debug ( " %s: phy: %02x reg:%02x val:%#x \n " , __func__ , phyaddr ,
rega ddr , val ) ;
return val ;
}
@ -154,22 +147,20 @@ static void fec_mii_setspeed(struct ethernet_regs *eth)
debug ( " %s: mii_speed %08x \n " , __func__ , readl ( & eth - > mii_speed ) ) ;
}
static int fec_mdio_write ( struct ethernet_regs * eth , uint8_t phyA ddr ,
uint8_t regA ddr , uint16_t data )
static int fec_mdio_write ( struct ethernet_regs * eth , uint8_t phya ddr ,
uint8_t rega ddr , uint16_t data )
{
uint32_t reg ; /* convenient holder for the PHY register */
uint32_t phy ; /* convenient holder for the PHY */
uint32_t start ;
reg = regA ddr < < FEC_MII_DATA_RA_SHIFT ;
phy = phyA ddr < < FEC_MII_DATA_PA_SHIFT ;
reg = rega ddr < < FEC_MII_DATA_RA_SHIFT ;
phy = phya ddr < < FEC_MII_DATA_PA_SHIFT ;
writel ( FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR |
FEC_MII_DATA_TA | phy | reg | data , & eth - > mii_data ) ;
/*
* wait for the MII interrupt
*/
/* wait for the MII interrupt */
start = get_timer ( 0 ) ;
while ( ! ( readl ( & eth - > ievent ) & FEC_IEVENT_MII ) ) {
if ( get_timer ( start ) > ( CONFIG_SYS_HZ / 1000 ) ) {
@ -178,26 +169,24 @@ static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr,
}
}
/*
* clear MII interrupt bit
*/
/* clear MII interrupt bit */
writel ( FEC_IEVENT_MII , & eth - > ievent ) ;
debug ( " %s: phy: %02x reg:%02x val:%#x \n " , __func__ , phyA ddr ,
regA ddr , data ) ;
debug ( " %s: phy: %02x reg:%02x val:%#x \n " , __func__ , phyaddr ,
rega ddr , data ) ;
return 0 ;
}
static int fec_phy_read ( struct mii_dev * bus , int phyA ddr , int dev_addr ,
int regA ddr )
static int fec_phy_read ( struct mii_dev * bus , int phya ddr , int dev_addr ,
int rega ddr )
{
return fec_mdio_read ( bus - > priv , phyAddr , regA ddr ) ;
return fec_mdio_read ( bus - > priv , phyaddr , rega ddr ) ;
}
static int fec_phy_write ( struct mii_dev * bus , int phyA ddr , int dev_addr ,
int regA ddr , u16 data )
static int fec_phy_write ( struct mii_dev * bus , int phya ddr , int dev_addr ,
int rega ddr , u16 data )
{
return fec_mdio_write ( bus - > priv , phyAddr , regA ddr , data ) ;
return fec_mdio_write ( bus - > priv , phyaddr , rega ddr , data ) ;
}
# ifndef CONFIG_PHYLIB
@ -218,14 +207,12 @@ static int miiphy_restart_aneg(struct eth_device *dev)
fec_mdio_write ( eth , fec - > phy_id , MII_BMCR , BMCR_RESET ) ;
udelay ( 1000 ) ;
/*
* Set the auto - negotiation advertisement register bits
*/
/* Set the auto-negotiation advertisement register bits */
fec_mdio_write ( eth , fec - > phy_id , MII_ADVERTISE ,
LPA_100FULL | LPA_100HALF | LPA_10FULL |
LPA_10HALF | PHY_ANLPAR_PSB_802_3 ) ;
LPA_100FULL | LPA_100HALF | LPA_10FULL |
LPA_10HALF | PHY_ANLPAR_PSB_802_3 ) ;
fec_mdio_write ( eth , fec - > phy_id , MII_BMCR ,
BMCR_ANENABLE | BMCR_ANRESTART ) ;
BMCR_ANENABLE | BMCR_ANRESTART ) ;
if ( fec - > mii_postcall )
ret = fec - > mii_postcall ( fec - > phy_id ) ;
@ -242,9 +229,7 @@ static int miiphy_wait_aneg(struct eth_device *dev)
struct fec_priv * fec = ( struct fec_priv * ) dev - > priv ;
struct ethernet_regs * eth = fec - > bus - > priv ;
/*
* Wait for AN completion
*/
/* Wait for AN completion */
start = get_timer ( 0 ) ;
do {
if ( get_timer ( start ) > ( CONFIG_SYS_HZ * 5 ) ) {
@ -255,7 +240,7 @@ static int miiphy_wait_aneg(struct eth_device *dev)
status = fec_mdio_read ( eth , fec - > phy_id , MII_BMSR ) ;
if ( status < 0 ) {
printf ( " %s: Autonegotiation failed. status: %d \n " ,
dev - > name , status ) ;
dev - > name , status ) ;
return - 1 ;
}
} while ( ! ( status & BMSR_LSTATUS ) ) ;
@ -352,15 +337,15 @@ static void fec_tbd_init(struct fec_priv *fec)
/**
* Mark the given read buffer descriptor as free
* @ param [ in ] last 1 if this is the last buffer descriptor in the chain , else 0
* @ param [ in ] pR bd buffer descriptor to mark free again
* @ param [ in ] pr bd buffer descriptor to mark free again
*/
static void fec_rbd_clean ( int last , struct fec_bd * pR bd )
static void fec_rbd_clean ( int last , struct fec_bd * pr bd )
{
unsigned short flags = FEC_RBD_EMPTY ;
if ( last )
flags | = FEC_RBD_WRAP ;
writew ( flags , & pR bd - > status ) ;
writew ( 0 , & pR bd - > data_length ) ;
writew ( flags , & pr bd - > status ) ;
writew ( 0 , & pr bd - > data_length ) ;
}
static int fec_get_hwaddr ( int dev_id , unsigned char * mac )
@ -389,37 +374,26 @@ static int fec_set_hwaddr(struct eth_device *dev)
writel ( 0 , & fec - > eth - > gaddr1 ) ;
writel ( 0 , & fec - > eth - > gaddr2 ) ;
/*
* Set physical address
*/
/* Set physical address */
writel ( ( mac [ 0 ] < < 24 ) + ( mac [ 1 ] < < 16 ) + ( mac [ 2 ] < < 8 ) + mac [ 3 ] ,
& fec - > eth - > paddr1 ) ;
& fec - > eth - > paddr1 ) ;
writel ( ( mac [ 4 ] < < 24 ) + ( mac [ 5 ] < < 16 ) + 0x8808 , & fec - > eth - > paddr2 ) ;
return 0 ;
}
/*
* Do initial configuration of the FEC registers
*/
/* Do initial configuration of the FEC registers */
static void fec_reg_setup ( struct fec_priv * fec )
{
uint32_t rcntrl ;
/*
* Set interrupt mask register
*/
/* Set interrupt mask register */
writel ( 0x00000000 , & fec - > eth - > imask ) ;
/*
* Clear FEC - Lite interrupt event register ( IEVENT )
*/
/* Clear FEC-Lite interrupt event register(IEVENT) */
writel ( 0xffffffff , & fec - > eth - > ievent ) ;
/*
* Set FEC - Lite receive control register ( R_CNTRL ) :
*/
/* Set FEC-Lite receive control register(R_CNTRL): */
/* Start with frame length = 1518, common for all modes. */
rcntrl = PKTSIZE < < FEC_RCNTRL_MAX_FL_SHIFT ;
@ -471,22 +445,19 @@ static int fec_open(struct eth_device *edev)
# ifdef FEC_QUIRK_ENET_MAC
/* Enable ENET HW endian SWAP */
writel ( readl ( & fec - > eth - > ecntrl ) | FEC_ECNTRL_DBSWAP ,
& fec - > eth - > ecntrl ) ;
& fec - > eth - > ecntrl ) ;
/* Enable ENET store and forward mode */
writel ( readl ( & fec - > eth - > x_wmrk ) | FEC_X_WMRK_STRFWD ,
& fec - > eth - > x_wmrk ) ;
& fec - > eth - > x_wmrk ) ;
# endif
/*
* Enable FEC - Lite controller
*/
/* Enable FEC-Lite controller */
writel ( readl ( & fec - > eth - > ecntrl ) | FEC_ECNTRL_ETHER_EN ,
& fec - > eth - > ecntrl ) ;
& fec - > eth - > ecntrl ) ;
# if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL)
udelay ( 100 ) ;
/*
* setup the MII gasket for RMII mode
*/
/* setup the MII gasket for RMII mode */
/* disable the gasket */
writew ( 0 , & fec - > eth - > miigsk_enr ) ;
@ -544,9 +515,7 @@ static int fec_open(struct eth_device *edev)
# endif
debug ( " %s:Speed=%i \n " , __func__ , speed ) ;
/*
* Enable SmartDMA receive task
*/
/* Enable SmartDMA receive task */
fec_rx_task_enable ( fec ) ;
udelay ( 100000 ) ;
@ -556,7 +525,7 @@ static int fec_open(struct eth_device *edev)
# ifdef CONFIG_DM_ETH
static int fecmxc_init ( struct udevice * dev )
# else
static int fec_init ( struct eth_device * dev , bd_t * bd )
static int fec_init ( struct eth_device * dev , bd_t * bd )
# endif
{
# ifdef CONFIG_DM_ETH
@ -574,9 +543,7 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
fec_set_hwaddr ( dev ) ;
# endif
/*
* Setup transmit descriptors , there are two in total .
*/
/* Setup transmit descriptors, there are two in total. */
fec_tbd_init ( fec ) ;
/* Setup receive descriptors. */
@ -587,18 +554,14 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
if ( fec - > xcv_type ! = SEVENWIRE )
fec_mii_setspeed ( fec - > bus - > priv ) ;
/*
* Set Opcode / Pause Duration Register
*/
/* Set Opcode/Pause Duration Register */
writel ( 0x00010020 , & fec - > eth - > op_pause ) ; /* FIXME 0xffff0020; */
writel ( 0x2 , & fec - > eth - > x_wmrk ) ;
/*
* Set multicast address filter
*/
/* Set multicast address filter */
writel ( 0x00000000 , & fec - > eth - > gaddr1 ) ;
writel ( 0x00000000 , & fec - > eth - > gaddr2 ) ;
/* Do not access reserved register for i.MX6UL */
if ( ! is_mx6ul ( ) ) {
/* clear MIB RAM */
@ -639,22 +602,16 @@ static void fec_halt(struct eth_device *dev)
# endif
int counter = 0xffff ;
/*
* issue graceful stop command to the FEC transmitter if necessary
*/
/* issue graceful stop command to the FEC transmitter if necessary */
writel ( FEC_TCNTRL_GTS | readl ( & fec - > eth - > x_cntrl ) ,
& fec - > eth - > x_cntrl ) ;
& fec - > eth - > x_cntrl ) ;
debug ( " eth_halt: wait for stop regs \n " ) ;
/*
* wait for graceful stop to register
*/
/* wait for graceful stop to register */
while ( ( counter - - ) & & ( ! ( readl ( & fec - > eth - > ievent ) & FEC_IEVENT_GRA ) ) )
udelay ( 1 ) ;
/*
* Disable SmartDMA tasks
*/
/* Disable SmartDMA tasks */
fec_tx_task_disable ( fec ) ;
fec_rx_task_disable ( fec ) ;
@ -663,7 +620,7 @@ static void fec_halt(struct eth_device *dev)
* Note : this will also reset the BD index counter !
*/
writel ( readl ( & fec - > eth - > ecntrl ) & ~ FEC_ECNTRL_ETHER_EN ,
& fec - > eth - > ecntrl ) ;
& fec - > eth - > ecntrl ) ;
fec - > rbd_index = 0 ;
fec - > tbd_index = 0 ;
debug ( " eth_halt: done \n " ) ;
@ -766,9 +723,7 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
*/
readl ( addr + size - 4 ) ;
/*
* Enable SmartDMA transmit task
*/
/* Enable SmartDMA transmit task */
fec_tx_task_enable ( fec ) ;
/*
@ -813,8 +768,8 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
out :
debug ( " fec_send: status 0x%x index %d ret %i \n " ,
readw ( & fec - > tbd_base [ fec - > tbd_index ] . status ) ,
fec - > tbd_index , ret ) ;
readw ( & fec - > tbd_base [ fec - > tbd_index ] . status ) ,
fec - > tbd_index , ret ) ;
/* for next transmission use the other buffer */
if ( fec - > tbd_index )
fec - > tbd_index = 0 ;
@ -848,9 +803,7 @@ static int fec_recv(struct eth_device *dev)
int i ;
ALLOC_CACHE_ALIGN_BUFFER ( uchar , buff , FEC_MAX_PKT_SIZE ) ;
/*
* Check if any critical events have happened
*/
/* Check if any critical events have happened */
ievent = readl ( & fec - > eth - > ievent ) ;
writel ( ievent , & fec - > eth - > ievent ) ;
debug ( " fec_recv: ievent 0x%lx \n " , ievent ) ;
@ -868,7 +821,7 @@ static int fec_recv(struct eth_device *dev)
if ( ievent & FEC_IEVENT_HBERR ) {
/* Heartbeat error */
writel ( 0x00000001 | readl ( & fec - > eth - > x_cntrl ) ,
& fec - > eth - > x_cntrl ) ;
& fec - > eth - > x_cntrl ) ;
}
if ( ievent & FEC_IEVENT_GRA ) {
/* Graceful stop complete */
@ -879,7 +832,7 @@ static int fec_recv(struct eth_device *dev)
fec_halt ( dev ) ;
# endif
writel ( ~ 0x00000001 & readl ( & fec - > eth - > x_cntrl ) ,
& fec - > eth - > x_cntrl ) ;
& fec - > eth - > x_cntrl ) ;
# ifdef CONFIG_DM_ETH
fecmxc_init ( dev ) ;
# else
@ -911,22 +864,16 @@ static int fec_recv(struct eth_device *dev)
if ( ! ( bd_status & FEC_RBD_EMPTY ) ) {
if ( ( bd_status & FEC_RBD_LAST ) & & ! ( bd_status & FEC_RBD_ERR ) & &
( ( readw ( & rbd - > data_length ) - 4 ) > 14 ) ) {
/*
* Get buffer address and size
*/
( ( readw ( & rbd - > data_length ) - 4 ) > 14 ) ) {
/* Get buffer address and size */
addr = readl ( & rbd - > data_pointer ) ;
frame_length = readw ( & rbd - > data_length ) - 4 ;
/*
* Invalidate data cache over the buffer
*/
/* Invalidate data cache over the buffer */
end = roundup ( addr + frame_length , ARCH_DMA_MINALIGN ) ;
addr & = ~ ( ARCH_DMA_MINALIGN - 1 ) ;
invalidate_dcache_range ( addr , end ) ;
/*
* Fill the buffer and pass it to upper layers
*/
/* Fill the buffer and pass it to upper layers */
# ifdef CONFIG_FEC_MXC_SWAP_PACKET
swap_packet ( ( uint32_t * ) addr , frame_length ) ;
# endif
@ -954,7 +901,7 @@ static int fec_recv(struct eth_device *dev)
& fec - > rbd_base [ i ] ) ;
}
flush_dcache_range ( addr ,
addr + ARCH_DMA_MINALIGN ) ;
addr + ARCH_DMA_MINALIGN ) ;
}
fec_rx_task_enable ( fec ) ;
@ -1273,7 +1220,8 @@ static int fecmxc_probe(struct udevice *dev)
goto err_phy ;
/* Reset chip. */
writel ( readl ( & priv - > eth - > ecntrl ) | FEC_ECNTRL_RESET , & priv - > eth - > ecntrl ) ;
writel ( readl ( & priv - > eth - > ecntrl ) | FEC_ECNTRL_RESET ,
& priv - > eth - > ecntrl ) ;
start = get_timer ( 0 ) ;
while ( readl ( & priv - > eth - > ecntrl ) & FEC_ECNTRL_RESET ) {
if ( get_timer ( start ) > ( CONFIG_SYS_HZ * 5 ) ) {