Hello,
appriciate your help!
We use C6747 and TLK105 (hardware),DSP/BIOS5.42 and NDK2.0(Software) for ethernet communiction. The development environment is CCS5.5.The ndk/src/hal/evm6747/eth_c6747/cls_mdio.c (and cls_mdio.h) had been reconstucted for TLK105.However no data transmited to pc and no data received on DSP side. The deep observation are:
1) PHY link is setuped, but no data received on dsp side and pc side;
2) Only one transmit action on dsp is observed in void HwTxInt(void) function in file etherdriver.c;
3) Can not found HwRxInt(void) function (in file etherdriver.c) was trigered;
4) The dsp EMAC reg RXALIGNCODEERRORS and NETOCTETS is not zero;
5) MDC and MDIO function is normal, and can write and read the PHY reg;
6) The data signal of TXD[1:0] and RXD[1:0] between the MAC and PHY can be observed;
7) The TLK105 pin PFBOUT is 1.56v, the pin RBIAS is 1.22v;
I am newbie for ethernet development, cannot find the reason and resolution. Please help me. Thanks a lot!!!
The PHY regs' dump is:
PHY REG BMCR: 1000
PHY REG BMSR: 786d
PHY REG PHYIDR1: 2000
PHY REG PHYIDR2: a211
PHY REG ANAR: 1e1
PHY REG ANLPAR: cc61
PHY REG ANER: f
PHY REG ANNPTR: 2001
PHY REG ANLNPTR: 0
PHY REG CR1: 3801
PHY REG CR2: 104
PHY REG CR3: 0
PHY REG REGCR: 0
PHY REG ADDAR: 0
PHY REG PHYSTS: 17
PHY REG PHYSCR: 108
PHY REG MISR1: 2400
PHY REG MISR2: 2000
PHY REG FCSCR: 0
PHY REG RECR: 0
PHY REG BISCR: 100
PHY REG RCSR: 21
PHY REG PHYCR: 1e
PHY REG 10BTSCR: 0
PHY REG BICSR1: 7d
PHY REG BICSR2: 5ee
PHY REG TXCPSR: 2000
PHY REG PWRBOCR: 0
PHY REG VRCR: 17
The hardware schematic is as follow:
/* ============================================================================ * Copyright (c) Texas Instruments Inc 2002, 2003, 2004, 2005, 2006 * * Use of this software is controlled by the terms and conditions found in the * license agreement under which this software has been supplied. * =========================================================================== */ /** ============================================================================ * @file csl_mdio.c * * PATH: \$(CSLPATH)\\src\\mdio * * @brief MDIO CSL Implementation on DSP side * */ /* ============================================================================= * Revision History * =============== * 25-Aug-03 xxx Modified to introduce ~(100 to 200) ms delay in PHY reset. * Also checks ACK value on reading back PHY reset status * 10-Mar-06 xxx Ported to TCI6488 * ============================================================================= */ //#include <evmc6747.h> ///added for UINT32 BY QCW #include <csl_mdio.h> #include <stdio.h> #include "hal_c6747_tlk105cfg.h" /** * \brief Tick counts for timeout of each state * * Note that NWAYSTART falls through to NWAYWAIT which falls through * to LINKWAIT. The timeout is not reset progressing from one state * to the next, so the system has 5 seconds total to find a link. */ extern LOG_Obj trace; static Uint32 PhyStateTimeout[] = { 2, /**< PHYSTATE_MDIOINIT - min-delay */ 6, /**< PHYSTATE_RESET - 0.5 sec max*/ 41, /**< PHYSTATE_NWAYSTART - 4 seconds */ 41, /**< PHYSTATE_NWAYWAIT - 4 seconds */ 51, /**< PHYSTATE_LINKWAIT - 5 seconds */ 0 /**< PHYSTATE_LINKED - no timeout */ }; static void MDIO_initStateMachine( MDIO_Device *pd ); static Uint32 MDIO_initContinue( MDIO_Device *pd ); /**< Curent selection of MAC */ static Uint32 macsel = RMII; /**< MDIO/EMAC are clocked by SYSCLK4 on this board(EVM6747) = 300 Mhz / 4 */ #define VBUSCLK 75 static void MDIO_initStateMachine( MDIO_Device *pd ) { /* Setup the state machine defaults */ pd->phyAddr = 0; /* The next PHY to try */ pd->phyState = PHYSTATE_MDIOINIT; /* PHY State */ pd->phyStateTicks = 0; /* Ticks elapsed */ pd->LinkStatus = MDIO_LINKSTATUS_NOLINK; } Handle MDIO_open( Uint32 mdioModeFlags ) { /* * Note: In a multi-instance environment, we'd have to allocate "localDev" */ static MDIO_Device localDev; /* Find out what interface we are working with */ //macsel = CSL_FEXT(DEV_REGS->DEVSTAT, DEV_DEVSTAT_MACSEL); /* Get the mode flags from the user - clear our reserved flag */ localDev.ModeFlags = mdioModeFlags & ~MDIO_MODEFLG_NWAYACTIVE; /* Setup the MDIO state machine */ MDIO_initStateMachine( &localDev ); /* Enable MDIO and setup divider */ // 操作DSP MDIO 寄存器,控制使能 MDIO_REGS->CONTROL = CSL_FMKT(MDIO_CONTROL_ENABLE,YES) | CSL_FMK(MDIO_CONTROL_CLKDIV,VBUSCLK) ; /* We're done for now - all the rest is done via MDIO_event() */ return( &localDev ); } void MDIO_close( Handle hMDIO ) { Uint32 ltmp1; Uint32 i; (void)hMDIO; /* * We really don't care what state anything is in at this point, * but to be safe, we'll isolate all the PHY devices. */ ltmp1 = MDIO_REGS->ALIVE; for( i=0; ltmp1; i++,ltmp1>>=1 ) { if( ltmp1 & 1 ) { // PHYREG_write( PHYREG_CONTROL, i, PHYREG_CONTROL_ISOLATE | //comment // PHYREG_CONTROL_POWERDOWN ); PHYREG_write( PHYREG_MODE_CTR_BMCR, i, PHY_BMCR_ISOLATE_EN | PHY_BMCR_IEEE_POWER_DOWN ); PHYREG_wait(); } } } void MDIO_getStatus( Handle hMDIO, Uint32 *pPhy, Uint32 *pLinkStatus ) { MDIO_Device *pd = (MDIO_Device *)hMDIO; if( pPhy ) *pPhy = pd->phyAddr; if( pLinkStatus ) *pLinkStatus = pd->LinkStatus; } static Uint32 tick_count=0; Uint32 MDIO_timerTick( Handle hMDIO ) { MDIO_Device *pd = (MDIO_Device *)hMDIO; Uint16 tmp1,tmp2,tmp1gig = 0, tmp2gig = 0, ack; volatile Uint32 ltmp1; Uint32 RetVal = MDIO_EVENT_NOCHANGE; /* * If we are linked, we just check to see if we lost link. Otherwise; * we keep treking through our state machine. */ if( pd->phyState == PHYSTATE_LINKED ) { /* * Here we check for a "link-change" status indication or a link * down indication. */ ltmp1 = MDIO_REGS->LINKINTRAW & 1; MDIO_REGS->LINKINTRAW = ltmp1; if( ltmp1 || !(MDIO_REGS->LINK)&(1<<pd->phyAddr) ) { /* * There has been a change in link (or it is down) * If we do not auto-neg, then we just wait for a new link * Otherwise, we enter NWAYSTART or NWAYWAIT */ pd->LinkStatus = MDIO_LINKSTATUS_NOLINK; RetVal = MDIO_EVENT_LINKDOWN; pd->phyStateTicks = 0; /* Reset timeout */ /* If not NWAY, just wait for link */ if( !(pd->ModeFlags & MDIO_MODEFLG_NWAYACTIVE) ) pd->phyState = PHYSTATE_LINKWAIT; else { /* Handle NWAY condition */ /* First see if link is really down */ //PHYREG_read( PHYREG_STATUS, pd->phyAddr ); //comment PHYREG_read( PHYREG_MODE_STATUS_BMSR, pd->phyAddr ); PHYREG_wait(); //PHYREG_read( PHYREG_STATUS, pd->phyAddr ); //comment PHYREG_read( PHYREG_MODE_STATUS_BMSR, pd->phyAddr ); PHYREG_waitResultsAck( tmp1, ack ); if( !ack ) { /* No PHY response, maybe it was unplugged */ MDIO_initStateMachine( pd ); } //else if( !(tmp1 & PHYREG_STATUS_LINKSTATUS) ) //comment else if( !(tmp1 & PHY_BMSR_LINK_VALID) ) { /* No Link - restart NWAY */ pd->phyState = PHYSTATE_NWAYSTART; /* PHYREG_write( PHYREG_CONTROL, pd->phyAddr, PHYREG_CONTROL_AUTONEGEN | PHYREG_CONTROL_AUTORESTART ); */ //comment PHYREG_write( PHYREG_MODE_CTR_BMCR, pd->phyAddr, PHY_BMCR_AUTO_NEG_EN | PHY_BMCR_RESTART_AUTO_NEG_EN ); PHYREG_wait(); } else { /* We have a Link - re-read NWAY params */ pd->phyState = PHYSTATE_NWAYWAIT; } } } } /* * If running in a non-linked state, execute the next * state of the state machine. */ if( pd->phyState != PHYSTATE_LINKED ) { /* Bump the time counter */ pd->phyStateTicks++; /* Process differently based on state */ switch( pd->phyState ) { case PHYSTATE_RESET: /* Don't try to read reset status for the first 100 to 200 ms */ if( pd->phyStateTicks < 2 ) break; /* See if the PHY has come out of reset */ //PHYREG_read( PHYREG_CONTROL, pd->phyAddr ); //comment PHYREG_read( PHYREG_MODE_CTR_BMCR, pd->phyAddr ); PHYREG_waitResultsAck( tmp1, ack ); //if( ack && !(tmp1 & PHYREG_CONTROL_RESET) ) //comment if( ack && !(tmp1 & PHY_BMCR_RESET) ) { /* PHY is not reset. If the PHY init is going well, break out */ if( MDIO_initContinue( pd ) ) break; /* Else, this PHY is toast. Manually trigger a timeout */ pd->phyStateTicks = PhyStateTimeout[pd->phyState]; } /* Fall through to timeout check */ case PHYSTATE_MDIOINIT: CheckTimeout: /* Here we just check timeout and try to find a PHY */ if( pd->phyStateTicks >= PhyStateTimeout[pd->phyState] ) { // Try the next PHY if anything but a MDIOINIT condition if( pd->phyState != PHYSTATE_MDIOINIT ) if( ++pd->phyAddr == 32 ) pd->phyAddr = 0; ltmp1 = MDIO_REGS->ALIVE; for( tmp1=0; tmp1<32; tmp1++ ) { if( ltmp1 & (1<<pd->phyAddr) ) { if( MDIO_initPHY( pd, pd->phyAddr ) ) break; } if( ++pd->phyAddr == 32 ) pd->phyAddr = 0; } // If we didn't find a PHY, try again if( tmp1 == 32 ) { pd->phyAddr = 0; pd->phyState = PHYSTATE_MDIOINIT; pd->phyStateTicks = 0; RetVal = MDIO_EVENT_PHYERROR; } } break; case PHYSTATE_NWAYSTART: /* * Here we started NWAY. We check to see if NWAY is done. * If not done and timeout occured, we find another PHY. */ /* Read the CONTROL reg to verify "restart" is not set */ //PHYREG_read( PHYREG_CONTROL, pd->phyAddr ); // comment PHYREG_read( PHYREG_MODE_CTR_BMCR, pd->phyAddr ); PHYREG_waitResultsAck( tmp1, ack ); if( !ack ) { MDIO_initStateMachine( pd ); break; } //if( tmp1 & PHYREG_CONTROL_AUTORESTART ) //comment if( tmp1 & PHY_BMCR_RESTART_AUTO_NEG_EN ) goto CheckTimeout; /* Flush latched "link status" from the STATUS reg */ //PHYREG_read( PHYREG_STATUS, pd->phyAddr ); //comment PHYREG_read( PHYREG_MODE_STATUS_BMSR, pd->phyAddr ); PHYREG_wait(); pd->phyState = PHYSTATE_NWAYWAIT; /* Fallthrough */ case PHYSTATE_NWAYWAIT: /* * Here we are waiting for NWAY to complete. */ /* Read the STATUS reg to check for "complete" */ //PHYREG_read( PHYREG_STATUS, pd->phyAddr ); //comment PHYREG_read( PHYREG_MODE_STATUS_BMSR, pd->phyAddr ); PHYREG_waitResultsAck( tmp1, ack ); //tmp1=30829 if( !ack ) { MDIO_initStateMachine( pd ); break; } //if( !(tmp1 & PHYREG_STATUS_AUTOCOMPLETE) ) //comment if( !(tmp1 & PHY_BMSR_AUTO_NEG_COMPLETE) ) goto CheckTimeout; //PHYREG_read( PHYREG_ADVERTISE, pd->phyAddr ); //comment PHYREG_read( PHYREG_AUTO_NEG_ANAR, pd->phyAddr ); PHYREG_waitResults( tmp1 ); //PHYREG_read( PHYREG_PARTNER, pd->phyAddr ); // comment PHYREG_read( PHYREG_AUTO_NEG_PARTNER_ANLPAR, pd->phyAddr ); PHYREG_waitResults( tmp2 ); /* * Use the "best" results */ tmp2 &= tmp1; /* Check first for 1 Gigabit */ //if( (tmp1gig & PHYREG_ADVERTISE_FD1000) && (tmp2gig & PHYREG_PARTNER_FD1000) ) // pd->PendingStatus = MDIO_LINKSTATUS_FD1000; //else if( tmp2 & PHYREG_ADVERTISE_FD100 ) //comment , no support Gigabit //if( tmp2 & PHYREG_ADVERTISE_FD100 ) //comment if( tmp2 & PHY_ANAR_100TXFD ) pd->PendingStatus = MDIO_LINKSTATUS_FD100; //else if( tmp2 & PHYREG_ADVERTISE_HD100 ) //comment else if( tmp2 & PHY_ANAR_100TX ) pd->PendingStatus = MDIO_LINKSTATUS_HD100; //else if( tmp2 & PHYREG_ADVERTISE_FD10 ) //comment else if( tmp2 & PHY_ANAR_10TFD ) pd->PendingStatus = MDIO_LINKSTATUS_FD10; //else if( tmp2 & PHYREG_ADVERTISE_HD10 ) //comment else if( tmp2 & PHY_ANAR_10T ) pd->PendingStatus = MDIO_LINKSTATUS_HD10; /* * If we get here the negotiation failed * We just use HD 100 or 10 - the best we think we can do */ //else if( tmp1 & PHYREG_ADVERTISE_HD100 ) //comment else if( tmp1 & PHY_ANAR_100TX ) pd->PendingStatus = MDIO_LINKSTATUS_HD100; else pd->PendingStatus = MDIO_LINKSTATUS_HD10; pd->phyState = PHYSTATE_LINKWAIT; /* Fallthrough */ case PHYSTATE_LINKWAIT: /* * Here we are waiting for LINK */ /* Read the STATUS reg to check for "link" */ //PHYREG_read( PHYREG_STATUS, pd->phyAddr ); //comment PHYREG_read( PHYREG_MODE_STATUS_BMSR, pd->phyAddr ); PHYREG_waitResultsAck( tmp1, ack ); if( !ack ) { MDIO_initStateMachine( pd ); break; } //if( !(tmp1 & PHYREG_STATUS_LINKSTATUS) ) //comment if( !(tmp1 & PHY_BMSR_LINK_VALID) ) goto CheckTimeout; /* Make sure we're linked in the MDIO module as well */ ltmp1 = MDIO_REGS->LINK; if( !(ltmp1&(1<<pd->phyAddr)) ) goto CheckTimeout; /* Start monitoring this PHY */ MDIO_REGS->USERPHYSEL0 = pd->phyAddr; /* Clear the link change flag so we can detect a "re-link" later */ MDIO_REGS->LINKINTRAW = 1; /* Setup our linked state */ pd->phyState = PHYSTATE_LINKED; pd->LinkStatus = pd->PendingStatus; RetVal = MDIO_EVENT_LINKUP; break; } } return( RetVal ); } Uint32 MDIO_initPHY( Handle hMDIO, volatile Uint32 phyAddr ) { MDIO_Device *pd = (MDIO_Device *)hMDIO; Uint32 ltmp1; Uint32 i,ack; /* Switch the PHY */ pd->phyAddr = phyAddr; /* There will be no link when we're done with this PHY */ pd->LinkStatus = MDIO_LINKSTATUS_NOLINK; /* Shutdown all other PHYs */ #if 0 ltmp1 = MDIO_REGS->ALIVE ; for( i=0; ltmp1; i++,ltmp1>>=1 ) { if( (ltmp1 & 1) && (i != phyAddr) ) { PHYREG_write( PHYREG_CONTROL, i, PHYREG_CONTROL_ISOLATE | PHYREG_CONTROL_POWERDOWN ); PHYREG_wait(); } } #endif /* Reset the PHY we plan to use */ //PHYREG_write( PHYREG_CONTROL, phyAddr, PHYREG_CONTROL_RESET ); //comment PHYREG_write( PHYREG_MODE_CTR_BMCR, phyAddr, PHY_BMCR_RESET ); PHYREG_waitResultsAck( i, ack ); /* If the PHY did not ACK the write, return zero */ if( !ack ) return(0); /* Setup for our next state */ pd->phyState = PHYSTATE_RESET; pd->phyStateTicks = 0; /* Reset timeout */ return(1); } static Uint32 MDIO_initContinue( MDIO_Device *pd ) { Uint16 tmp1,tmp2; Uint16 tmp1gig = 0; { static Uint16 StatusRegister[32]; int index = 0; for (index =0; index < 32; index++) StatusRegister [index] = 0xDEAD; /* Now we read the status register */ for (index =0; index < 32;index++) { //PHYREG_read( PHYREG_STATUS, index ); // comment PHYREG_read( PHYREG_MODE_STATUS_BMSR, index ); PHYREG_waitResults( tmp1 ); /* Copy the Status value into the Status. */ StatusRegister [index] = tmp1; } } /* Read the STATUS reg to check autonegotiation capability */ //PHYREG_read( PHYREG_STATUS, pd->phyAddr ); //comment PHYREG_read( PHYREG_MODE_STATUS_BMSR, pd->phyAddr ); PHYREG_waitResults( tmp1 ); if ( (macsel == GMII) || (macsel == RGMII) ) // macsel = RMII; { //PHYREG_read( PHYREG_EXTSTATUS, pd->phyAddr ); PHYREG_read( PHYREG_STATUS_PHYSTS, pd->phyAddr ); PHYREG_waitResults( tmp1gig ); } /* See if we auto-neg or not */ if( (pd->ModeFlags & MDIO_MODEFLG_AUTONEG) && (tmp1 & PHY_BMSR_AUTO_NEG_ABLE) ) // (tmp1 & PHYREG_STATUS_AUTOCAPABLE) ) { /* We will use NWAY */ /* Advertise 1000 for supported interfaces */ /* if ( (macsel == GMII) || (macsel == RGMII) ) { tmp1gig >>= 4; tmp1gig &= PHYREG_ADVERTISE_FD1000; PHYREG_write( PHYREG_1000CONTROL, pd->phyAddr, tmp1gig ); } */ //comment, no Gigabit /* Shift down the capability bits */ tmp1 >>= 6; // /* Mask with the capabilities */ /* tmp1 &= ( PHYREG_ADVERTISE_FD100 | PHYREG_ADVERTISE_HD100 | PHYREG_ADVERTISE_FD10 | PHYREG_ADVERTISE_HD10 ); */ //comment tmp1 &= ( PHY_ANAR_100TXFD | PHY_ANAR_100TX | PHY_ANAR_10TFD | PHY_ANAR_10T ); /* Set Ethernet message bit */ //tmp1 |= PHYREG_ADVERTISE_MSG; //comment , protocol selection tmp1 |= PHY_PROTOCOL_SEL_8023U; /* Write out advertisement */ //PHYREG_write( PHYREG_ADVERTISE, pd->phyAddr, tmp1 ); // comment PHYREG_write( PHYREG_AUTO_NEG_ANAR, pd->phyAddr, tmp1 ); PHYREG_wait(); /* Start NWAY */ //PHYREG_write( PHYREG_CONTROL, pd->phyAddr, PHYREG_CONTROL_AUTONEGEN ); //comment PHYREG_write( PHYREG_MODE_CTR_BMCR, pd->phyAddr, PHY_BMCR_AUTO_NEG_EN ); PHYREG_wait(); // added by qcw PHYREG_write( PHYREG_MODE_CTR_BMCR, pd->phyAddr, PHY_BMCR_SPEED_SEL_100 ); PHYREG_wait(); PHYREG_write( PHYREG_MODE_CTR_BMCR, pd->phyAddr, PHY_BMCR_DUPLEX_MODE ); PHYREG_wait(); PHYREG_write(PHYREG_BIST_CTRL_BICSR1,pd->phyAddr,0x5dcu); PHYREG_wait(); //end adding //PHYREG_write( PHYREG_CONTROL, pd->phyAddr, // PHYREG_CONTROL_AUTONEGEN|PHYREG_CONTROL_AUTORESTART ); PHYREG_write( PHYREG_MODE_CTR_BMCR, pd->phyAddr, PHY_BMCR_AUTO_NEG_EN|PHY_BMCR_RESTART_AUTO_NEG_EN); PHYREG_wait(); /* Setup current state */ pd->ModeFlags |= MDIO_MODEFLG_NWAYACTIVE; pd->phyState = PHYSTATE_NWAYSTART; pd->phyStateTicks = 0; /* Reset timeout */ } else { /* We will use a fixed configuration */ /* Shift down the capability bits */ tmp1 >>= 10; /* Mask with possible modes */ tmp1 &= ( MDIO_MODEFLG_HD10 | MDIO_MODEFLG_FD10 | MDIO_MODEFLG_HD100 | MDIO_MODEFLG_FD100 ); if ( (macsel == GMII) || (macsel == RGMII) ) { tmp1gig >>= 8; tmp1gig&= MDIO_MODEFLG_FD1000; /* Mask with what the User wants to allow */ tmp1gig &= pd->ModeFlags; } /* Mask with what the User wants to allow */ tmp1 &= pd->ModeFlags; /* If nothing if left, move on */ if( (!tmp1) && (!tmp1gig) ) return(0); /* Setup Control word and pending status */ /* if( tmp1gig ) { tmp2 = PHYREG_CONTROL_SPEEDMSB | PHYREG_CONTROL_DUPLEXFULL; pd->PendingStatus = MDIO_LINKSTATUS_FD1000; } else */ //comment , no Gigabyte if( tmp1 & MDIO_MODEFLG_FD100 ) { //tmp2 = PHYREG_CONTROL_SPEEDLSB | PHYREG_CONTROL_DUPLEXFULL;//comment tmp2 = PHY_BMCR_SPEED_SEL_100 | PHY_BMCR_DUPLEX_MODE; pd->PendingStatus = MDIO_LINKSTATUS_FD100; } else if( tmp1 & MDIO_MODEFLG_HD100 ) { //tmp2 = PHYREG_CONTROL_SPEEDLSB; //comment by qcw tmp2 = PHY_BMCR_SPEED_SEL_100; pd->PendingStatus = MDIO_LINKSTATUS_HD100; } else if( tmp1 & MDIO_MODEFLG_FD10 ) { //tmp2 = PHYREG_CONTROL_DUPLEXFULL; //comment tmp2 = PHY_BMCR_DUPLEX_MODE; pd->PendingStatus = MDIO_LINKSTATUS_FD10; } else { tmp2 = 0; pd->PendingStatus = MDIO_LINKSTATUS_HD10; } /* Add in internal phy loopback if user wanted it */ if( pd->ModeFlags & MDIO_MODEFLG_LOOPBACK ) //tmp2 |= PHYREG_CONTROL_LOOPBACK; //comment tmp2 |= PHY_BMCR_MII_LOOPBACK_EN; /* Configure PHY */ //PHYREG_write( PHYREG_CONTROL, pd->phyAddr, tmp2 ); //comment PHYREG_write( PHYREG_MODE_CTR_BMCR, pd->phyAddr, tmp2 ); PHYREG_wait(); /* Add in external phy loopback with plug if user wanted it */ /* if( pd->ModeFlags & MDIO_MODEFLG_EXTLOOPBACK ) { PHYREG_write( PHYREG_SHADOW, pd->phyAddr, PHYREG_SHADOW_EXTLOOPBACK ); PHYREG_wait(); } */ //comment, no shadow /* Setup current state */ pd->ModeFlags &= ~MDIO_MODEFLG_NWAYACTIVE; pd->phyState = PHYSTATE_LINKWAIT; pd->phyStateTicks = 0; /* Reset timeout */ } return(1); } Uint32 MDIO_phyRegRead( volatile Uint32 phyIdx, volatile Uint32 phyReg, Uint16 *pData ) { Uint32 data,ack; PHYREG_read( phyReg, phyIdx ); PHYREG_waitResultsAck( data, ack ); if( !ack ) return(0); if( pData ) *pData = data; return(1); } Uint32 MDIO_phyRegWrite( volatile Uint32 phyIdx, volatile Uint32 phyReg, Uint16 data ) { Uint32 ack; PHYREG_write( phyReg, phyIdx, data ); PHYREG_waitResultsAck( data, ack ); if( !ack ) return(0); return(1); }