int InitPhy(PHY_cfg *cfg) { u32 d; // Check PHY presence d=MDIO_read(cfg, PHY_REG_IDH); if(d!=M88E1111_IDH) return -1; // Enable RGMII clock delay d=MDIO_read(cfg, PHY_REG_EPSC); d|=PHY_REG_EPSC_RRTC|PHY_REG_EPSC_RTTC; MDIO_write(cfg, PHY_REG_EPSC, d); //d=MDIO_read(cfg, PHY_REG_PSCR); //d|=PHY_REG_PSCR_TFD_MAX | PHY_REG_PSCR_RFD_MAX; //d|=PHY_REG_PSCR_EXT; //MDIO_write(cfg, PHY_REG_PSCR, d); d=0xFFFF; MDIO_write(cfg, PHY_REG_IER, d); d=PHY_REG_LEDC_DISABLE; MDIO_write(cfg, PHY_REG_LEDC, d); // Soft Reset d=MDIO_read(cfg, PHY_REG_CTRL); d|=PHY_REG_CTRL_RST; MDIO_write(cfg, PHY_REG_CTRL, d); return 0; }
/***************************************************************************//** * Resets the PHY. */ void PHY_reset( void ) { MDIO_write( PHYREG_MIIMCR, MIIMCR_RESET ); MDIO_write( PHYREG_MIIMCR, MIIMCR_ENABLE_AUTONEGOTIATION | MIIMCR_RESTART_AUTONEGOTIATION | MIIMCR_COLLISION_TEST ); }
/***************************************************************************//** * Restarts PHY auto-negotiation and wait until it's over. */ void PHY_auto_negotiate( void ) { int32_t a; uint16_t reg; int32_t exit = 1; reg = MDIO_read( PHYREG_MIIMCR ); MDIO_write( PHYREG_MIIMCR, (uint16_t)( MIIMCR_ENABLE_AUTONEGOTIATION | MIIMCR_RESTART_AUTONEGOTIATION | reg) ); for(a=0; (a<1000) && (exit); a++) { reg = MDIO_read( PHYREG_MIIMSR ); if( (reg & MIIMSR_ANC) != 0 ) { exit = 0; } } }
/***************************************************************************//** * Sets link type. */ void PHY_set_link_type ( uint8_t type ) { uint16_t reg; reg = MDIO_read( PHYREG_ANAR ); reg |= ANAR_100FD | ANAR_100HD | ANAR_10FD | ANAR_10HD; if( (type & MSS_MAC_LINK_STATUS_100MB) == 0 ) { reg &= ~(ANAR_100FD | ANAR_100HD); } if( (type & MSS_MAC_LINK_STATUS_FDX) == 0 ) { reg &= ~(ANAR_100FD | ANAR_10FD); } MDIO_write( PHYREG_ANAR, reg ); }
/***************************************************************************//** * Puts the Phy in Loopback mode */ uint16_t PHY_set_loopback ( uint8_t enable ) { uint16_t reg = 0; reg = MDIO_read( PHYREG_MIIMCR ); // If set to one we need to set the LOCAL Phy loopback if(enable == 1) reg |= MIIMCR_LOOPBACK; else // else we want to clear the bit.. reg ^= MIIMCR_LOOPBACK; MDIO_write( PHYREG_MIIMCR,reg ); reg = MDIO_read( PHYREG_MIIMCR ); return reg; }