⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fec.c

📁 Freescale MCF5445evb 参考测试代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * File:    fec.c * Purpose: Driver for the Fast Ethernet Controller (FEC) * * Notes: */#include "common.h"#include "fec.h"/********************************************************************//* * Log of FEC events */FEC_EVENT_LOG fec_log[2];/* * Queues for FEC buffers */QUEUE txbd_queue[2];QUEUE rxbd_queue[2];QUEUE send_queue[2];/********************************************************************//* * 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. */intfec_mii_write(int ch, int phy_addr, int reg_addr, int 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 write */    MCF_FEC_MMFR = 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 < MII_TIMEOUT; timeout++)    {        if (MCF_FEC_EIR & MCF_FEC_EIR_MII)            break;    }    if(timeout == MII_TIMEOUT)        return 0;    /* Clear the MII interrupt bit */    MCF_FEC_EIR = MCF_FEC_EIR_MII;    /* Restore the EIMR */    MCF_FEC_EIMR = eimr;    return 1;}/********************************************************************//* * 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. */intfec_mii_read(int ch, 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 = 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 < MII_TIMEOUT; timeout++)    {        if (MCF_FEC_EIR & MCF_FEC_EIR_MII)            break;    }    if(timeout == 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;}/********************************************************************//* * Initialize the MII interface controller * * Parameters: *  ch      FEC channel *  sys_clk System Clock Frequency (in MHz) */voidfec_mii_init(int ch, int sys_clk){    /*     * Initialize the MII clock (EMDC) frequency     *     * Desired MII clock is 2.5MHz     * MII Speed Setting = System_Clock / (2.5MHz * 2)     * (plus 1 to make sure we round up)     */    MCF_FEC_MSCR = MCF_FEC_MSCR_MII_SPEED((sys_clk/5)+1);    /*     * Make sure the external interface signals are enabled     */    MCF_GPIO_PNQPAR = MCF_GPIO_PNQPAR_IRQ3_FEC_MDIO					| MCF_GPIO_PNQPAR_IRQ5_FEC_MDC;}/********************************************************************//* Initialize the MIB counters * * Parameters: *  ch      FEC channel */voidfec_mib_init(int ch){//To do	MCF_FEC_MIBC |= MCF_FEC_MIBC_MIB_DISABLE;		 	 MCF_FEC_RMON_T_DROP  =             	 MCF_FEC_RMON_T_PACKETS  =             	 MCF_FEC_RMON_T_BC_PKT   =             	 MCF_FEC_RMON_T_MC_PKT  =           	 MCF_FEC_RMON_T_CRC_ALIGN    =       	 MCF_FEC_RMON_T_UNDERSIZE    =        	 MCF_FEC_RMON_T_OVERSIZE      =      	 MCF_FEC_RMON_T_FRAG           =  	 MCF_FEC_RMON_T_JAB             = 	 MCF_FEC_RMON_T_COL              =	 MCF_FEC_RMON_T_P64               =    	 MCF_FEC_RMON_T_P65TO127           =   	 MCF_FEC_RMON_T_P128TO255           = 	 MCF_FEC_RMON_T_P256TO511            = 	 MCF_FEC_RMON_T_P512TO1023           =	 MCF_FEC_RMON_T_P1024TO2047           =	 MCF_FEC_RMON_T_P_GTE2048            =	 MCF_FEC_RMON_T_OCTETS              =	 MCF_FEC_IEEE_T_DROP                 =	 MCF_FEC_IEEE_T_FRAME_OK             =	 MCF_FEC_IEEE_T_1COL                 =	 MCF_FEC_IEEE_T_MCOL                 =	 MCF_FEC_IEEE_T_DEF                  =	 MCF_FEC_IEEE_T_LCOL                 =	 MCF_FEC_IEEE_T_EXCOL                =	 MCF_FEC_IEEE_T_MACERR               =	 MCF_FEC_IEEE_T_CSERR                =	 MCF_FEC_IEEE_T_SQE                  =	 MCF_FEC_IEEE_T_FDXFC                =	 MCF_FEC_IEEE_T_OCTETS_OK           =	 MCF_FEC_RMON_R_PACKETS              =	 MCF_FEC_RMON_R_BC_PKT               =	 MCF_FEC_RMON_R_MC_PKT               =	 MCF_FEC_RMON_R_CRC_ALIGN             =	 MCF_FEC_RMON_R_UNDERSIZE           =	 MCF_FEC_RMON_R_OVERSIZE            =	 MCF_FEC_RMON_R_FRAG                =	 MCF_FEC_RMON_R_JAB                 =	 MCF_FEC_RMON_R_RESVD_0             =	 MCF_FEC_RMON_R_P64                 =	 MCF_FEC_RMON_R_P65TO127            =	 MCF_FEC_RMON_R_P128TO255           =	 MCF_FEC_RMON_R_P256TO511            =	 MCF_FEC_RMON_R_P512TO1023          =	 MCF_FEC_RMON_R_P1024TO2047         =	 MCF_FEC_RMON_R_P_GTE2048            =	 MCF_FEC_RMON_R_OCTETS               =	 MCF_FEC_IEEE_R_DROP                 =	 MCF_FEC_IEEE_R_FRAME_OK             =	 MCF_FEC_IEEE_R_CRC                   =	 MCF_FEC_IEEE_R_ALIGN                 =	 MCF_FEC_IEEE_R_MACERR               =	 MCF_FEC_IEEE_R_FDXFC                =	 MCF_FEC_IEEE_R_OCTETS_OK    = 0;	 	MCF_FEC_MIBC &= ~MCF_FEC_MIBC_MIB_DISABLE;}/********************************************************************//* Display the MIB counters * * Parameters: *  ch      FEC channel */voidfec_mib_dump(int ch){//To do	printf("\n   MIB%d RMON Counters\n---------------\n",ch);    printf("MCF_FEC_RMON_T_DROP: %4d\n",MCF_FEC_RMON_T_DROP);    printf("MCF_FEC_RMON_T_PACKETS:  %4d\n",MCF_FEC_RMON_T_PACKETS);    printf("MCF_FEC_RMON_T_BC_PKT:   %4d\n",MCF_FEC_RMON_T_BC_PKT);    printf("MCF_FEC_RMON_T_MC_PKT:   %4d\n",MCF_FEC_RMON_T_MC_PKT);    printf("MCF_FEC_RMON_T_CRC_ALIGN:    %4d\n",MCF_FEC_RMON_T_CRC_ALIGN);    printf("MCF_FEC_RMON_T_UNDERSIZE:    %4d\n",MCF_FEC_RMON_T_UNDERSIZE);    printf("MCF_FEC_RMON_T_OVERSIZE:    %4d\n",MCF_FEC_RMON_T_OVERSIZE);    printf("MCF_FEC_RMON_T_FRAG:    %4d\n",MCF_FEC_RMON_T_FRAG);    printf("MCF_FEC_RMON_T_JAB:     %4d\n",MCF_FEC_RMON_T_JAB);    printf("MCF_FEC_RMON_T_COL:     %4d\n",MCF_FEC_RMON_T_COL);    printf("MCF_FEC_RMON_T_P64:     %4d\n",MCF_FEC_RMON_T_P64);    printf("MCF_FEC_RMON_T_P65TO127:    %4d\n",MCF_FEC_RMON_T_P65TO127);    printf("MCF_FEC_RMON_T_P128TO255:      %4d\n",MCF_FEC_RMON_T_P128TO255);    printf("MCF_FEC_RMON_T_P256TO511:     %4d\n",MCF_FEC_RMON_T_P256TO511);    printf("MCF_FEC_RMON_T_P512TO1023:     %4d\n",MCF_FEC_RMON_T_P512TO1023);    printf("MCF_FEC_RMON_T_P1024TO2047:     %4d\n",MCF_FEC_RMON_T_P1024TO2047);    printf("MCF_FEC_RMON_T_P_GTE2048:     %4d\n",MCF_FEC_RMON_T_P_GTE2048);    printf("MCF_FEC_RMON_T_OCTETS:     %4d\n",MCF_FEC_RMON_T_OCTETS);    printf("MCF_FEC_RMON_R_PACKETS:     %4d\n",MCF_FEC_RMON_R_PACKETS);    printf("MCF_FEC_RMON_R_BC_PKT:     %4d\n",MCF_FEC_RMON_R_BC_PKT);    printf("---------------\n\n");}/********************************************************************//* Initialize the FEC log * * Parameters: *  ch      FEC channel */voidfec_log_init(int ch){    memset(&fec_log[ch],0,sizeof(FEC_EVENT_LOG));}/********************************************************************//* Display the FEC log * * Parameters: *  ch      FEC channel */voidfec_log_dump(int ch){  //  #ifdef DEBUG_PRINT    printf("\n   FEC%d Log\n---------------\n",ch);    printf("Errors: %4d\n",fec_log[ch].errors);    printf("hberr:  %4d\n",fec_log[ch].hberr);    printf("babr:   %4d\n",fec_log[ch].babr);    printf("babt:   %4d\n",fec_log[ch].babt);    printf("gra:    %4d\n",fec_log[ch].gra);    printf("txf:    %4d\n",fec_log[ch].txf);    printf("rxf:    %4d\n",fec_log[ch].rxf);    printf("mii:    %4d\n",fec_log[ch].mii);    printf("lc:     %4d\n",fec_log[ch].lc);    printf("rl:     %4d\n",fec_log[ch].rl);    printf("\nRFSW:\n");    printf("inv:    %4d\n",fec_log[ch].rfsw_inv);    printf("m:      %4d\n",fec_log[ch].rfsw_m);    printf("bc:     %4d\n",fec_log[ch].rfsw_bc);    printf("mc:     %4d\n",fec_log[ch].rfsw_mc);    printf("lg:     %4d\n",fec_log[ch].rfsw_lg);    printf("no:     %4d\n",fec_log[ch].rfsw_no);    printf("cr:     %4d\n",fec_log[ch].rfsw_cr);    printf("ov:     %4d\n",fec_log[ch].rfsw_ov);    printf("tr:     %4d\n",fec_log[ch].rfsw_tr);   // printf("---------------\n\n"); //   #endif}/********************************************************************//* * Display some of the registers for debugging * * Parameters: *  ch      FEC channel */voidfec_reg_dump(int ch){    #ifdef DEBUG_PRINT    printf("\n------------- FEC%d -------------\n",ch);    printf("to be completed...\n");    printf("--------------------------------\n\n");    #endif}/********************************************************************//* * Set the duplex on the selected FEC controller * * Parameters: *  ch      FEC channel *  duplex  FEC_MII_FULL_DUPLEX or FEC_MII_HALF_DUPLEX */voidfec_duplex (int ch, MII_DUPLEX duplex){    switch (duplex)    {        case MII_HDX:            MCF_FEC_RCR |= MCF_FEC_RCR_DRT;            MCF_FEC_TCR &= (uint32)~MCF_FEC_TCR_FDEN;            break;        case MII_FDX:        default:            MCF_FEC_RCR &= (uint32)~MCF_FEC_RCR_DRT;            MCF_FEC_TCR |= MCF_FEC_TCR_FDEN;            break;    }}/********************************************************************//* * Set the speed on the selected FEC controller * * Parameters: *  ch      FEC channel *  speed   MII_10BASE_T or MII_100BASE_TX */voidfec_rmii_speed (int ch, MII_SPEED speed){    switch (speed)    {        case MII_10BASE_T:            MCF_FEC_RCR |= MCF_FEC_RCR_MII_MODE;            break;        case MII_100BASE_TX:        default:            break;    }}/********************************************************************//* * Generate the hash table settings for the given address * * Parameters: *  addr    48-bit (6 byte) Address to generate the hash for * * Return Value: *  The 6 most significant bits of the 32-bit CRC result */uint8fec_hash_address(const uint8* addr){    uint32 crc;    uint8 byte;    int i, j;    crc = 0xFFFFFFFF;    for(i=0; i<6; ++i)    {        byte = addr[i];        for(j=0; j<8; ++j)        {            if((byte & 0x01)^(crc & 0x01))            {                crc >>= 1;                crc = crc ^ 0xEDB88320;            }            else                crc >>= 1;            byte >>= 1;        }    }    return (uint8)(crc >> 26);}/********************************************************************//* * Set the Physical (Hardware) Address and the Individual Address * Hash in the selected FEC * * Parameters: *  ch  FEC channel *  pa  Physical (Hardware) Address for the selected FEC */voidfec_set_address (int ch, const uint8 *pa){    uint8 crc;    /*     * Set the Physical Address

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -