/* * Read a value from a PHY's MII register. * * Parameters: * phy_addr Address of the PHY. * reg_addr Address of the register in the PHY. * data Pointer to storage for the Data to be read * from the PHY register (passed by reference) * * Return Values: * 0 on failure * 1 on success. * * Please refer to your PHY manual for registers and their meanings. * mii_read() polls for the FEC's MII interrupt event and clears it. * If after a suitable amount of time the event isn't triggered, a * value of 0 is returned. */ int fec_mii_read(int phy_addr, int reg_addr, uint16* data) { int timeout; uint32 eimr; /* Clear the MII interrupt bit */ MCF_FEC_EIR = MCF_FEC_EIR_MII; /* Mask the MII interrupt */ eimr = MCF_FEC_EIMR; MCF_FEC_EIMR &= ~MCF_FEC_EIMR_MII; /* Write to the MII Management Frame Register to kick-off the MII read */ MCF_FEC_MMFR = (vuint32)(0 | MCF_FEC_MMFR_ST_01 | MCF_FEC_MMFR_OP_READ | MCF_FEC_MMFR_PA(phy_addr) | MCF_FEC_MMFR_RA(reg_addr) | MCF_FEC_MMFR_TA_10); /* Poll for the MII interrupt (interrupt should be masked) */ for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) { if (MCF_FEC_EIR & MCF_FEC_EIR_MII) break; } if(timeout == FEC_MII_TIMEOUT) return 0; /* Clear the MII interrupt bit */ MCF_FEC_EIR = MCF_FEC_EIR_MII; /* Restore the EIMR */ MCF_FEC_EIMR = eimr; *data = (uint16)(MCF_FEC_MMFR & 0x0000FFFF); return 1; }
/* * Write a value to a PHY's MII register. * * Parameters: * phy_addr Address of the PHY. * reg_addr Address of the register in the PHY. * data Data to be written to the PHY register. * * Return Values: * 0 on failure * 1 on success. * * Please refer to your PHY manual for registers and their meanings. * mii_write() polls for the FEC's MII interrupt event and clears it. * If after a suitable amount of time the event isn't triggered, a * value of 0 is returned. */ int fec_mii_write(int phy_addr, int reg_addr, int data) { int timeout; uint32 eimr; /* Clear the MII interrupt bit */ MCF_FEC_EIR(ETH_PORT) = MCF_FEC_EIR_MII; /* Mask the MII interrupt */ eimr = MCF_FEC_EIMR(ETH_PORT); MCF_FEC_EIMR(ETH_PORT) &= ~MCF_FEC_EIMR_MII; /* Write to the MII Management Frame Register to kick-off the MII write */ MCF_FEC_MMFR(ETH_PORT) = (vuint32)(0 | MCF_FEC_MMFR_ST_01 | MCF_FEC_MMFR_OP_WRITE | MCF_FEC_MMFR_PA(phy_addr) | MCF_FEC_MMFR_RA(reg_addr) | MCF_FEC_MMFR_TA_10 | MCF_FEC_MMFR_DATA(data)); /* Poll for the MII interrupt (interrupt should be masked) */ for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) { if (MCF_FEC_EIR(ETH_PORT) & MCF_FEC_EIR_MII) break; } if(timeout == FEC_MII_TIMEOUT) return 0; /* Clear the MII interrupt bit */ MCF_FEC_EIR(ETH_PORT) = MCF_FEC_EIR_MII; /* Restore the EIMR */ MCF_FEC_EIMR(ETH_PORT) = eimr; return 1; }
u16_t smi_read(u8_t phy_addr,u8_t reg_addr) { MCF_FEC_MMFR = MCF_FEC_MMFR_ST(0x1) | MCF_FEC_MMFR_OP_READ | (MCF_FEC_MMFR_PA(phy_addr)) | MCF_FEC_MMFR_RA(reg_addr) | MCF_FEC_MMFR_TA_10; smi_init(bsp_get_CPU_clock_speed()); /* enable MII clock speed after MMFR is written */ while ((MCF_FEC_EIR & MCF_FEC_EIR_MII) == 0) { __asm__ ("nop"); } smi_init(0); /* MII frame sent, disable clock until next operation */ MCF_FEC_EIR |= MCF_FEC_EIR_MII; return MCF_FEC_MMFR&0xFFFF; }
void smi_write(u8_t phy_addr,u8_t reg_addr,u16_t data) { MCF_FEC_MMFR = MCF_FEC_MMFR_ST(0x1) | MCF_FEC_MMFR_OP_WRITE | (MCF_FEC_MMFR_PA(phy_addr)) | MCF_FEC_MMFR_RA(reg_addr) | MCF_FEC_MMFR_TA_10 | data; smi_init(bsp_get_CPU_clock_speed()); /* enable MII clock speed after MMFR is written */ while ((MCF_FEC_EIR & MCF_FEC_EIR_MII) == 0) { __asm__ ("nop"); } smi_init(0); /* MII frame sent, disable clock until next operation */ MCF_FEC_EIR |= MCF_FEC_EIR_MII; }
/* * FUNCTION ADAPTED FROM FREESCALE SUPPLIED SOURCE * * Read a value from a PHY's MII register. * * Parameters: * ch FEC channel * phy_addr Address of the PHY. * reg_addr Address of the register in the PHY. * data Pointer to storage for the Data to be read * from the PHY register (passed by reference) * * Return Values: * 0 on failure * 1 on success. * * Please refer to your PHY manual for registers and their meanings. * mii_read() polls for the FEC's MII interrupt event and clears it. * If after a suitable amount of time the event isn't triggered, a * value of 0 is returned. */ static int fec_mii_read( int phy_addr, int reg_addr, unsigned portSHORT* data ) { int timeout, iReturn; uint32 eimr; /* Clear the MII interrupt bit */ MCF_FEC_EIR = MCF_FEC_EIR_MII; /* Mask the MII interrupt */ eimr = MCF_FEC_EIMR; MCF_FEC_EIMR &= ~MCF_FEC_EIMR_MII; /* Write to the MII Management Frame Register to kick-off the MII read */ MCF_FEC_MMFR = MCF_FEC_MMFR_ST_01 | MCF_FEC_MMFR_OP_READ | MCF_FEC_MMFR_PA(phy_addr) | MCF_FEC_MMFR_RA(reg_addr) | MCF_FEC_MMFR_TA_10; /* Poll for the MII interrupt (interrupt should be masked) */ for( timeout = 0; timeout < fecMAX_POLLS; timeout++ ) { if (MCF_FEC_EIR & MCF_FEC_EIR_MII) { break; } else { vTaskDelay( fecMII_DELAY ); } } if( timeout == fecMAX_POLLS ) { iReturn = 0; } else { *data = (uint16)(MCF_FEC_MMFR & 0x0000FFFF); iReturn = 1; } /* Clear the MII interrupt bit */ MCF_FEC_EIR = MCF_FEC_EIR_MII; /* Restore the EIMR */ MCF_FEC_EIMR = eimr; return iReturn; }
/* * FUNCTION ADAPTED FROM FREESCALE SUPPLIED SOURCE * * Write a value to a PHY's MII register. * * Parameters: * ch FEC channel * phy_addr Address of the PHY. * reg_addr Address of the register in the PHY. * data Data to be written to the PHY register. * * Return Values: * 0 on failure * 1 on success. * * Please refer to your PHY manual for registers and their meanings. * mii_write() polls for the FEC's MII interrupt event and clears it. * If after a suitable amount of time the event isn't triggered, a * value of 0 is returned. */ static int fec_mii_write( int phy_addr, int reg_addr, int data ) { int timeout, iReturn; uint32 eimr; /* Clear the MII interrupt bit */ MCF_FEC_EIR = MCF_FEC_EIR_MII; /* Mask the MII interrupt */ eimr = MCF_FEC_EIMR; MCF_FEC_EIMR &= ~MCF_FEC_EIMR_MII; /* Write to the MII Management Frame Register to kick-off the MII write */ MCF_FEC_MMFR = MCF_FEC_MMFR_ST_01 | MCF_FEC_MMFR_OP_WRITE | MCF_FEC_MMFR_PA(phy_addr) | MCF_FEC_MMFR_RA(reg_addr) | MCF_FEC_MMFR_TA_10 | MCF_FEC_MMFR_DATA( data ); /* Poll for the MII interrupt (interrupt should be masked) */ for( timeout = 0; timeout < fecMAX_POLLS; timeout++ ) { if( MCF_FEC_EIR & MCF_FEC_EIR_MII ) { break; } else { vTaskDelay( fecMII_DELAY ); } } if( timeout == fecMAX_POLLS ) { iReturn = 0; } else { iReturn = 1; } /* Clear the MII interrupt bit */ MCF_FEC_EIR = MCF_FEC_EIR_MII; /* Restore the EIMR */ MCF_FEC_EIMR = eimr; return iReturn; }