Sergey Pastor / 1

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mcf5225x_eth.c Source File

mcf5225x_eth.c

Go to the documentation of this file.
00001 /**
00002  * @file mcf5225x_eth.c
00003  * @brief Coldfire V2 MCF5225x Ethernet MAC controller
00004  *
00005  * @section License
00006  *
00007  * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
00008  *
00009  * This file is part of CycloneTCP Open.
00010  *
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License
00013  * as published by the Free Software Foundation; either version 2
00014  * of the License, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software Foundation,
00023  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00024  *
00025  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00026  * @version 1.7.6
00027  **/
00028 
00029 //Switch to the appropriate trace level
00030 #define TRACE_LEVEL NIC_TRACE_LEVEL
00031 
00032 //Dependencies
00033 #include "mcf52259.h"
00034 #include "core/net.h"
00035 #include "drivers/mcf5225x_eth.h"
00036 #include "debug.h"
00037 
00038 //Underlying network interface
00039 static NetInterface *nicDriverInterface;
00040 
00041 //TX buffer
00042 static uint8_t txBuffer[MCF5225X_ETH_TX_BUFFER_COUNT][MCF5225X_ETH_TX_BUFFER_SIZE];
00043 //RX buffer
00044 static uint8_t rxBuffer[MCF5225X_ETH_RX_BUFFER_COUNT][MCF5225X_ETH_RX_BUFFER_SIZE];
00045 //TX buffer descriptors
00046 static Mcf5225xTxBufferDesc txBufferDesc[MCF5225X_ETH_TX_BUFFER_COUNT];
00047 //RX buffer descriptors
00048 static Mcf5225xRxBufferDesc rxBufferDesc[MCF5225X_ETH_RX_BUFFER_COUNT];
00049 
00050 //TX buffer index
00051 static uint_t txBufferIndex;
00052 //RX buffer index
00053 static uint_t rxBufferIndex;
00054 
00055 
00056 /**
00057  * @brief MCF5225x Ethernet MAC driver
00058  **/
00059 
00060 const NicDriver mcf5225xEthDriver =
00061 {
00062    NIC_TYPE_ETHERNET,
00063    ETH_MTU,
00064    mcf5225xEthInit,
00065    mcf5225xEthTick,
00066    mcf5225xEthEnableIrq,
00067    mcf5225xEthDisableIrq,
00068    mcf5225xEthEventHandler,
00069    mcf5225xEthSendPacket,
00070    mcf5225xEthSetMulticastFilter,
00071    mcf5225xEthUpdateMacConfig,
00072    mcf5225xEthWritePhyReg,
00073    mcf5225xEthReadPhyReg,
00074    TRUE,
00075    TRUE,
00076    TRUE,
00077    FALSE
00078 };
00079 
00080 
00081 /**
00082  * @brief MCF5225x Ethernet MAC initialization
00083  * @param[in] interface Underlying network interface
00084  * @return Error code
00085  **/
00086 
00087 error_t mcf5225xEthInit(NetInterface *interface)
00088 {
00089    error_t error;
00090    uint_t i;
00091    uint32_t value;
00092 
00093    //Debug message
00094    TRACE_INFO("Initializing MCF5225x Ethernet MAC...\r\n");
00095 
00096    //Save underlying network interface
00097    nicDriverInterface = interface;
00098 
00099    //GPIO configuration
00100    mcf5225xEthInitGpio(interface);
00101 
00102    //Reset FEC module
00103    MCF_FEC_ECR = MCF_FEC_ECR_RESET;
00104    //Wait for the reset to complete
00105    while(MCF_FEC_ECR & MCF_FEC_ECR_RESET);
00106 
00107    //Reveive control register
00108    MCF_FEC_RCR = MCF_FEC_RCR_MAX_FL(1518) | MCF_FEC_RCR_MII_MODE;
00109    //Transmit control register
00110    MCF_FEC_TCR = 0;
00111    //Configure MDC clock frequency
00112    MCF_FEC_MSCR = MCF_FEC_MSCR_MII_SPEED(19);
00113 
00114    //PHY transceiver initialization
00115    error = interface->phyDriver->init(interface);
00116    //Failed to initialize PHY transceiver?
00117    if(error)
00118       return error;
00119 
00120    //Set the MAC address (upper 16 bits)
00121    value = interface->macAddr.b[5];
00122    value |= (interface->macAddr.b[4] << 8);
00123    MCF_FEC_PAUR = MCF_FEC_PAUR_PADDR2(value) | MCF_FEC_PAUR_TYPE(0x8808);
00124 
00125    //Set the MAC address (lower 32 bits)
00126    value = interface->macAddr.b[3];
00127    value |= (interface->macAddr.b[2] << 8);
00128    value |= (interface->macAddr.b[1] << 16);
00129    value |= (interface->macAddr.b[0] << 24);
00130    MCF_FEC_PALR = MCF_FEC_PALR_PADDR1(value);
00131 
00132    //Hash table for unicast address filtering
00133    MCF_FEC_IALR = 0;
00134    MCF_FEC_IAUR = 0;
00135    //Hash table for multicast address filtering
00136    MCF_FEC_GALR = 0;
00137    MCF_FEC_GAUR = 0;
00138 
00139    //Initialize buffer descriptors
00140    mcf5225xEthInitBufferDesc(interface);
00141 
00142    //Clear any pending interrupts
00143    MCF_FEC_EIR = MCF_FEC_EIR_CLEAR_ALL;
00144 
00145    //Enable desired interrupts
00146    MCF_FEC_EIMR = MCF_FEC_EIMR_TXF | MCF_FEC_EIMR_TXB |
00147       MCF_FEC_EIMR_RXF | MCF_FEC_EIMR_RXB | MCF_FEC_EIMR_EBERR;
00148 
00149    //Set the priority of FEC interrupts
00150    for(i = 23; i <= 35; i++)
00151    {
00152       MCF_INTC0_ICR(i) = MCF_INTC_ICR_IL(MCF5225X_ETH_IRQ_LEVEL) |
00153          MCF_INTC_ICR_IP(MCF5225X_ETH_IRQ_PRIORITY);
00154    }
00155 
00156    //Enable Ethernet MAC
00157    MCF_FEC_ECR |= MCF_FEC_ECR_ETHER_EN;
00158    //Instruct the DMA to poll the receive descriptor list
00159    MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
00160 
00161    //Accept any packets from the upper layer
00162    osSetEvent(&interface->nicTxEvent);
00163 
00164    //Successful initialization
00165    return NO_ERROR;
00166 }
00167 
00168 
00169 //TWR-MCF5225X evaluation board?
00170 #if defined(USE_TWR_MCF5225X)
00171 
00172 /**
00173  * @brief GPIO configuration
00174  * @param[in] interface Underlying network interface
00175  **/
00176 
00177 void mcf5225xEthInitGpio(NetInterface *interface)
00178 {
00179    uint8_t temp;
00180 
00181    //Configure FEC_COL (PTI0), FEC_CRS (PTI1), FEC_RXCLK (PTI2), FEC_RXD0 (PTI3),
00182    //FEC_RXD1 (PTI4), FEC_RXD2 (PTI5), FEC_RXD3 (PTI6) and FEC_RXDV (PTI7)
00183    MCF_GPIO_PTIPAR |= MCF_GPIO_PTIPAR_FEC_COL_FEC_COL | MCF_GPIO_PTIPAR_FEC_CRS_FEC_CRS |
00184       MCF_GPIO_PTIPAR_FEC_RXCLK_FEC_RXCLK | MCF_GPIO_PTIPAR_FEC_RXD0_FEC_RXD0 |
00185       MCF_GPIO_PTIPAR_FEC_RXD1_FEC_RXD1 | MCF_GPIO_PTIPAR_FEC_RXD2_FEC_RXD2 |
00186       MCF_GPIO_PTIPAR_FEC_RXD3_FEC_RXD3 | MCF_GPIO_PTIPAR_FEC_RXDV_FEC_RXDV;
00187 
00188    //Configure FEC_RXER (PTJ0), FEC_TXCLK (PTJ1), FEC_TXD0 (PTJ2), FEC_TXD1 (PTJ3)
00189    //FEC_TXD2 (PTJ4), FEC_TXD3 (PTJ5), FEC_TXEN (PTJ6) and FEC_TXER (PTJ7)
00190    MCF_GPIO_PTJPAR |= MCF_GPIO_PTJPAR_FEC_RXER_FEC_RXER | MCF_GPIO_PTJPAR_FEC_TXCLK_FEC_TXCLK |
00191       MCF_GPIO_PTJPAR_FEC_TXD0_FEC_TXD0 | MCF_GPIO_PTJPAR_FEC_TXD1_FEC_TXD1 |
00192       MCF_GPIO_PTJPAR_FEC_TXD2_FEC_TXD2 | MCF_GPIO_PTJPAR_FEC_TXD3_FEC_TXD3 |
00193       MCF_GPIO_PTJPAR_FEC_TXEN_FEC_TXEN | MCF_GPIO_PTJPAR_FEC_TXER_FEC_TXER;
00194 
00195    //Configure FEC_MDIO (PNQ3)
00196    temp = MCF_GPIO_PNQPAR & ~MCF_GPIO_PNQPAR_PNQPAR3(3);
00197    MCF_GPIO_PNQPAR = temp | MCF_GPIO_PNQPAR_IRQ3_FEC_MDIO;
00198 
00199    //Configure FEC_MDC (PNQ5)
00200    temp = MCF_GPIO_PNQPAR & ~MCF_GPIO_PNQPAR_PNQPAR5(3);
00201    MCF_GPIO_PNQPAR = temp | MCF_GPIO_PNQPAR_IRQ5_FEC_MDC;
00202 
00203    //Reset PHY transceiver
00204    MCF_RCM_RCR |= MCF_RCM_RCR_FRCRSTOUT;
00205    sleep(10);
00206 
00207    //Take the PHY transceiver out of reset
00208    MCF_RCM_RCR &= ~MCF_RCM_RCR_FRCRSTOUT;
00209    sleep(10);
00210 }
00211 
00212 #endif
00213 
00214 
00215 /**
00216  * @brief Initialize buffer descriptors
00217  * @param[in] interface Underlying network interface
00218  **/
00219 
00220 void mcf5225xEthInitBufferDesc(NetInterface *interface)
00221 {
00222    uint_t i;
00223 
00224    //Initialize TX buffer descriptors
00225    for(i = 0; i < MCF5225X_ETH_TX_BUFFER_COUNT; i++)
00226    {
00227       //The descriptor is initially owned by the software
00228       txBufferDesc[i].status = 0;
00229       //Transmit buffer length
00230       txBufferDesc[i].length = 0;
00231       //Transmit buffer address
00232       txBufferDesc[i].address = (uint32_t) FEC_ALIGN16(txBuffer[i]);
00233    }
00234 
00235    //Mark the last descriptor entry with the wrap flag
00236    txBufferDesc[i - 1].status |= FEC_TX_BD_W;
00237    //Initialize TX buffer index
00238    txBufferIndex = 0;
00239 
00240    //Initialize RX buffer descriptors
00241    for(i = 0; i < MCF5225X_ETH_RX_BUFFER_COUNT; i++)
00242    {
00243       //The descriptor is initially owned by the DMA
00244       rxBufferDesc[i].status = FEC_RX_BD_E;
00245       //Receive buffer length
00246       rxBufferDesc[i].length = 0;
00247       //Receive buffer address
00248       rxBufferDesc[i].address = (uint32_t) FEC_ALIGN16(rxBuffer[i]);
00249    }
00250 
00251    //Mark the last descriptor entry with the wrap flag
00252    rxBufferDesc[i - 1].status |= FEC_RX_BD_W;
00253    //Initialize RX buffer index
00254    rxBufferIndex = 0;
00255 
00256    //Start location of the TX descriptor list
00257    MCF_FEC_ETSDR = (uint32_t) txBufferDesc;
00258    //Start location of the RX descriptor list
00259    MCF_FEC_ERDSR = (uint32_t) rxBufferDesc;
00260    //Maximum receive buffer size
00261    MCF_FEC_EMRBR = MCF5225X_ETH_RX_BUFFER_SIZE;
00262 }
00263 
00264 
00265 /**
00266  * @brief MCF5225x Ethernet MAC timer handler
00267  *
00268  * This routine is periodically called by the TCP/IP stack to
00269  * handle periodic operations such as polling the link state
00270  *
00271  * @param[in] interface Underlying network interface
00272  **/
00273 
00274 void mcf5225xEthTick(NetInterface *interface)
00275 {
00276    //Handle periodic operations
00277    interface->phyDriver->tick(interface);
00278 }
00279 
00280 
00281 /**
00282  * @brief Enable interrupts
00283  * @param[in] interface Underlying network interface
00284  **/
00285 
00286 void mcf5225xEthEnableIrq(NetInterface *interface)
00287 {
00288    //Enable Ethernet MAC interrupts
00289    MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK23 |
00290       MCF_INTC_IMRL_INT_MASK24 | MCF_INTC_IMRL_INT_MASK25 |
00291       MCF_INTC_IMRL_INT_MASK26 | MCF_INTC_IMRL_INT_MASK27 |
00292       MCF_INTC_IMRL_INT_MASK28 | MCF_INTC_IMRL_INT_MASK29 |
00293       MCF_INTC_IMRL_INT_MASK30 | MCF_INTC_IMRL_INT_MASK31);
00294 
00295    MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK33 |
00296       MCF_INTC_IMRH_INT_MASK34| MCF_INTC_IMRH_INT_MASK35);
00297 
00298    //Enable Ethernet PHY interrupts
00299    interface->phyDriver->enableIrq(interface);
00300 }
00301 
00302 
00303 /**
00304  * @brief Disable interrupts
00305  * @param[in] interface Underlying network interface
00306  **/
00307 
00308 void mcf5225xEthDisableIrq(NetInterface *interface)
00309 {
00310    //Disable Ethernet MAC interrupts
00311    MCF_INTC0_IMRL |= MCF_INTC_IMRL_INT_MASK23 |
00312       MCF_INTC_IMRL_INT_MASK24 | MCF_INTC_IMRL_INT_MASK25 |
00313       MCF_INTC_IMRL_INT_MASK26 | MCF_INTC_IMRL_INT_MASK27 |
00314       MCF_INTC_IMRL_INT_MASK28 | MCF_INTC_IMRL_INT_MASK29 |
00315       MCF_INTC_IMRL_INT_MASK30 | MCF_INTC_IMRL_INT_MASK31;
00316 
00317    MCF_INTC0_IMRH |= MCF_INTC_IMRH_INT_MASK33 |
00318       MCF_INTC_IMRH_INT_MASK34| MCF_INTC_IMRH_INT_MASK35;
00319 
00320    //Disable Ethernet PHY interrupts
00321    interface->phyDriver->disableIrq(interface);
00322 }
00323 
00324 
00325 /**
00326  * @brief Ethernet MAC interrupt
00327  **/
00328 
00329 __declspec(interrupt) void mcf5225xEthIrqHandler(void)
00330 {
00331    bool_t flag;
00332    uint32_t events;
00333 
00334    //Enter interrupt service routine
00335    osEnterIsr();
00336 
00337    //This flag will be set if a higher priority task must be woken
00338    flag = FALSE;
00339    //Read interrupt event register
00340    events = MCF_FEC_EIR;
00341 
00342    //A packet has been transmitted?
00343    if(events & (MCF_FEC_EIR_TXF | MCF_FEC_EIR_TXB))
00344    {
00345       //Clear TXF and TXB interrupt flags
00346       MCF_FEC_EIR = MCF_FEC_EIR_TXF | MCF_FEC_EIR_TXB;
00347 
00348       //Check whether the TX buffer is available for writing
00349       if(!(txBufferDesc[txBufferIndex].status & FEC_TX_BD_R))
00350       {
00351          //Notify the TCP/IP stack that the transmitter is ready to send
00352          flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
00353       }
00354 
00355       //Instruct the DMA to poll the transmit descriptor list
00356       MCF_FEC_TDAR = MCF_FEC_TDAR_X_DES_ACTIVE;
00357    }
00358 
00359    //A packet has been received?
00360    if(events & (MCF_FEC_EIR_RXF | MCF_FEC_EIR_RXB))
00361    {
00362       //Disable RXF and RXB interrupts
00363       MCF_FEC_EIMR &= ~(MCF_FEC_EIMR_RXF | MCF_FEC_EIMR_RXB);
00364 
00365       //Set event flag
00366       nicDriverInterface->nicEvent = TRUE;
00367       //Notify the TCP/IP stack of the event
00368       flag |= osSetEventFromIsr(&netEvent);
00369    }
00370 
00371    //System bus error?
00372    if(events & MCF_FEC_EIR_EBERR)
00373    {
00374       //Disable EBERR interrupt
00375       MCF_FEC_EIMR &= ~MCF_FEC_EIMR_EBERR;
00376 
00377       //Set event flag
00378       nicDriverInterface->nicEvent = TRUE;
00379       //Notify the TCP/IP stack of the event
00380       flag |= osSetEventFromIsr(&netEvent);
00381    }
00382 
00383    //Any other event?
00384    if(events & (MCF_FEC_EIR_HBERR | MCF_FEC_EIR_BABR | MCF_FEC_EIR_BABT | MCF_FEC_EIR_GRA |
00385       MCF_FEC_EIR_MII | MCF_FEC_EIR_LC | MCF_FEC_EIR_RL | MCF_FEC_EIR_UN))
00386    {
00387       //Clear interrupt flags
00388       MCF_FEC_EIR = MCF_FEC_EIR_HBERR | MCF_FEC_EIR_BABR | MCF_FEC_EIR_BABT | MCF_FEC_EIR_GRA |
00389          MCF_FEC_EIR_MII | MCF_FEC_EIR_LC | MCF_FEC_EIR_RL | MCF_FEC_EIR_UN;
00390    }
00391 
00392    //Leave interrupt service routine
00393    osExitIsr(flag);
00394 }
00395 
00396 
00397 /**
00398  * @brief MCF5225x Ethernet MAC event handler
00399  * @param[in] interface Underlying network interface
00400  **/
00401 
00402 void mcf5225xEthEventHandler(NetInterface *interface)
00403 {
00404    error_t error;
00405    uint32_t status;
00406 
00407    //Read interrupt event register
00408    status = MCF_FEC_EIR;
00409 
00410    //Packet received?
00411    if(status & (MCF_FEC_EIR_RXF | MCF_FEC_EIR_RXB))
00412    {
00413       //Clear RXF and RXB interrupt flag
00414       MCF_FEC_EIR = MCF_FEC_EIR_RXF | MCF_FEC_EIR_RXB;
00415 
00416       //Process all pending packets
00417       do
00418       {
00419          //Read incoming packet
00420          error = mcf5225xEthReceivePacket(interface);
00421 
00422          //No more data in the receive buffer?
00423       } while(error != ERROR_BUFFER_EMPTY);
00424    }
00425 
00426    //System bus error?
00427    if(status & MCF_FEC_EIR_EBERR)
00428    {
00429       //Clear EBERR interrupt flag
00430       MCF_FEC_EIR = MCF_FEC_EIR_EBERR;
00431 
00432       //Disable Ethernet MAC
00433       MCF_FEC_ECR &= ~MCF_FEC_ECR_ETHER_EN;
00434       //Reset buffer descriptors
00435       mcf5225xEthInitBufferDesc(interface);
00436       //Resume normal operation
00437       MCF_FEC_ECR |= MCF_FEC_ECR_ETHER_EN;
00438       //Instruct the DMA to poll the receive descriptor list
00439       MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
00440    }
00441 
00442    //Re-enable Ethernet MAC interrupts
00443    MCF_FEC_EIMR = MCF_FEC_EIMR_TXF | MCF_FEC_EIMR_TXB |
00444       MCF_FEC_EIMR_RXF | MCF_FEC_EIMR_RXB | MCF_FEC_EIMR_EBERR;
00445 }
00446 
00447 
00448 /**
00449  * @brief Send a packet
00450  * @param[in] interface Underlying network interface
00451  * @param[in] buffer Multi-part buffer containing the data to send
00452  * @param[in] offset Offset to the first data byte
00453  * @return Error code
00454  **/
00455 
00456 error_t mcf5225xEthSendPacket(NetInterface *interface,
00457    const NetBuffer *buffer, size_t offset)
00458 {
00459    size_t length;
00460 
00461    //Retrieve the length of the packet
00462    length = netBufferGetLength(buffer) - offset;
00463 
00464    //Check the frame length
00465    if(length > MCF5225X_ETH_TX_BUFFER_SIZE)
00466    {
00467       //The transmitter can accept another packet
00468       osSetEvent(&interface->nicTxEvent);
00469       //Report an error
00470       return ERROR_INVALID_LENGTH;
00471    }
00472 
00473    //Make sure the current buffer is available for writing
00474    if(txBufferDesc[txBufferIndex].status & FEC_TX_BD_R)
00475       return ERROR_FAILURE;
00476 
00477    //Copy user data to the transmit buffer
00478    netBufferRead(FEC_ALIGN16(txBuffer[txBufferIndex]), buffer, offset, length);
00479 
00480    //Set frame length
00481    txBufferDesc[txBufferIndex].length = length;
00482 
00483    //Check current index
00484    if(txBufferIndex < (MCF5225X_ETH_TX_BUFFER_COUNT - 1))
00485    {
00486       //Give the ownership of the descriptor to the DMA engine
00487       txBufferDesc[txBufferIndex].status = FEC_TX_BD_R |
00488          FEC_TX_BD_L | FEC_TX_BD_TC;
00489 
00490       //Point to the next buffer
00491       txBufferIndex++;
00492    }
00493    else
00494    {
00495       //Give the ownership of the descriptor to the DMA engine
00496       txBufferDesc[txBufferIndex].status = FEC_TX_BD_R |
00497          FEC_TX_BD_W | FEC_TX_BD_L | FEC_TX_BD_TC;
00498 
00499       //Wrap around
00500       txBufferIndex = 0;
00501    }
00502 
00503    //Instruct the DMA to poll the transmit descriptor list
00504    MCF_FEC_TDAR = MCF_FEC_TDAR_X_DES_ACTIVE;
00505 
00506    //Check whether the next buffer is available for writing
00507    if(!(txBufferDesc[txBufferIndex].status & FEC_TX_BD_R))
00508    {
00509       //The transmitter can accept another packet
00510       osSetEvent(&interface->nicTxEvent);
00511    }
00512 
00513    //Successful processing
00514    return NO_ERROR;
00515 }
00516 
00517 
00518 /**
00519  * @brief Receive a packet
00520  * @param[in] interface Underlying network interface
00521  * @return Error code
00522  **/
00523 
00524 error_t mcf5225xEthReceivePacket(NetInterface *interface)
00525 {
00526    error_t error;
00527    size_t n;
00528 
00529    //Make sure the current buffer is available for reading
00530    if(!(rxBufferDesc[rxBufferIndex].status & FEC_RX_BD_E))
00531    {
00532       //The frame should not span multiple buffers
00533       if(rxBufferDesc[rxBufferIndex].status & FEC_RX_BD_L)
00534       {
00535          //Check whether an error occurred
00536          if(!(rxBufferDesc[rxBufferIndex].status & (FEC_RX_BD_LG |
00537             FEC_RX_BD_NO | FEC_RX_BD_CR | FEC_RX_BD_OV | FEC_RX_BD_TR)))
00538          {
00539             //Retrieve the length of the frame
00540             n = rxBufferDesc[rxBufferIndex].length;
00541             //Limit the number of data to read
00542             n = MIN(n, MCF5225X_ETH_RX_BUFFER_SIZE);
00543 
00544             //Pass the packet to the upper layer
00545             nicProcessPacket(interface, FEC_ALIGN16(rxBuffer[rxBufferIndex]), n);
00546 
00547             //Valid packet received
00548             error = NO_ERROR;
00549          }
00550          else
00551          {
00552             //The received packet contains an error
00553             error = ERROR_INVALID_PACKET;
00554          }
00555       }
00556       else
00557       {
00558          //The packet is not valid
00559          error = ERROR_INVALID_PACKET;
00560       }
00561 
00562       //Check current index
00563       if(rxBufferIndex < (MCF5225X_ETH_RX_BUFFER_COUNT - 1))
00564       {
00565          //Give the ownership of the descriptor back to the DMA engine
00566          rxBufferDesc[rxBufferIndex].status = FEC_RX_BD_E;
00567          //Point to the next buffer
00568          rxBufferIndex++;
00569       }
00570       else
00571       {
00572          //Give the ownership of the descriptor back to the DMA engine
00573          rxBufferDesc[rxBufferIndex].status = FEC_RX_BD_E | FEC_RX_BD_W;
00574          //Wrap around
00575          rxBufferIndex = 0;
00576       }
00577 
00578       //Instruct the DMA to poll the receive descriptor list
00579       MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
00580    }
00581    else
00582    {
00583       //No more data in the receive buffer
00584       error = ERROR_BUFFER_EMPTY;
00585    }
00586 
00587    //Return status code
00588    return error;
00589 }
00590 
00591 
00592 /**
00593  * @brief Configure multicast MAC address filtering
00594  * @param[in] interface Underlying network interface
00595  * @return Error code
00596  **/
00597 
00598 error_t mcf5225xEthSetMulticastFilter(NetInterface *interface)
00599 {
00600    uint_t i;
00601    uint_t k;
00602    uint32_t crc;
00603    uint32_t hashTable[2];
00604    MacFilterEntry *entry;
00605 
00606    //Debug message
00607    TRACE_DEBUG("Updating MCF5225x hash table...\r\n");
00608 
00609    //Clear hash table
00610    hashTable[0] = 0;
00611    hashTable[1] = 0;
00612 
00613    //The MAC filter table contains the multicast MAC addresses
00614    //to accept when receiving an Ethernet frame
00615    for(i = 0; i < MAC_MULTICAST_FILTER_SIZE; i++)
00616    {
00617       //Point to the current entry
00618       entry = &interface->macMulticastFilter[i];
00619 
00620       //Valid entry?
00621       if(entry->refCount > 0)
00622       {
00623          //Compute CRC over the current MAC address
00624          crc = mcf5225xEthCalcCrc(&entry->addr, sizeof(MacAddr));
00625 
00626          //The upper 6 bits in the CRC register are used to index the
00627          //contents of the hash table
00628          k = (crc >> 26) & 0x3F;
00629 
00630          //Update hash table contents
00631          hashTable[k / 32] |= (1 << (k % 32));
00632       }
00633    }
00634 
00635    //Write the hash table
00636    MCF_FEC_GALR = hashTable[0];
00637    MCF_FEC_GAUR = hashTable[1];
00638 
00639    //Debug message
00640    TRACE_DEBUG("  GALR = %08" PRIX32 "\r\n", MCF_FEC_GALR);
00641    TRACE_DEBUG("  GAUR = %08" PRIX32 "\r\n", MCF_FEC_GAUR);
00642 
00643    //Successful processing
00644    return NO_ERROR;
00645 }
00646 
00647 
00648 /**
00649  * @brief Adjust MAC configuration parameters for proper operation
00650  * @param[in] interface Underlying network interface
00651  * @return Error code
00652  **/
00653 
00654 error_t mcf5225xEthUpdateMacConfig(NetInterface *interface)
00655 {
00656    //Disable Ethernet MAC while modifying configuration registers
00657    MCF_FEC_ECR &= ~MCF_FEC_ECR_ETHER_EN;
00658 
00659    //Half-duplex or full-duplex mode?
00660    if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
00661    {
00662       //Full-duplex mode
00663       MCF_FEC_TCR |= MCF_FEC_TCR_FDEN;
00664       //Receive path operates independently of transmit
00665       MCF_FEC_RCR &= ~MCF_FEC_RCR_DRT;
00666    }
00667    else
00668    {
00669       //Half-duplex mode
00670       MCF_FEC_TCR &= ~MCF_FEC_TCR_FDEN;
00671       //Disable reception of frames while transmitting
00672       MCF_FEC_RCR |= MCF_FEC_RCR_DRT;
00673    }
00674 
00675    //Reset buffer descriptors
00676    mcf5225xEthInitBufferDesc(interface);
00677 
00678    //Re-enable Ethernet MAC
00679    MCF_FEC_ECR |= MCF_FEC_ECR_ETHER_EN;
00680    //Instruct the DMA to poll the receive descriptor list
00681    MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
00682 
00683    //Successful processing
00684    return NO_ERROR;
00685 }
00686 
00687 
00688 /**
00689  * @brief Write PHY register
00690  * @param[in] phyAddr PHY address
00691  * @param[in] regAddr Register address
00692  * @param[in] data Register value
00693  **/
00694 
00695 void mcf5225xEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
00696 {
00697    uint32_t value;
00698 
00699    //Set up a write operation
00700    value = MCF_FEC_MMFR_ST(1) | MCF_FEC_MMFR_OP(1) | MCF_FEC_MMFR_TA(2);
00701    //PHY address
00702    value |= MCF_FEC_MMFR_PA(phyAddr);
00703    //Register address
00704    value |= MCF_FEC_MMFR_RA(regAddr);
00705    //Register value
00706    value |= MCF_FEC_MMFR_DATA(data);
00707 
00708    //Clear MII interrupt flag
00709    MCF_FEC_EIR = MCF_FEC_EIR_MII;
00710    //Start a write operation
00711    MCF_FEC_MMFR = value;
00712    //Wait for the write to complete
00713    while(!(MCF_FEC_EIR & MCF_FEC_EIR_MII));
00714 }
00715 
00716 
00717 /**
00718  * @brief Read PHY register
00719  * @param[in] phyAddr PHY address
00720  * @param[in] regAddr Register address
00721  * @return Register value
00722  **/
00723 
00724 uint16_t mcf5225xEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
00725 {
00726    uint32_t value;
00727 
00728    //Set up a read operation
00729    value = MCF_FEC_MMFR_ST(1) | MCF_FEC_MMFR_OP(2) | MCF_FEC_MMFR_TA(2);
00730    //PHY address
00731    value |= MCF_FEC_MMFR_PA(phyAddr);
00732    //Register address
00733    value |= MCF_FEC_MMFR_RA(regAddr);
00734 
00735    //Clear MII interrupt flag
00736    MCF_FEC_EIR = MCF_FEC_EIR_MII;
00737    //Start a read operation
00738    MCF_FEC_MMFR = value;
00739    //Wait for the read to complete
00740    while(!(MCF_FEC_EIR & MCF_FEC_EIR_MII));
00741 
00742    //Return PHY register contents
00743    return MCF_FEC_MMFR;
00744 }
00745 
00746 
00747 /**
00748  * @brief CRC calculation
00749  * @param[in] data Pointer to the data over which to calculate the CRC
00750  * @param[in] length Number of bytes to process
00751  * @return Resulting CRC value
00752  **/
00753 
00754 uint32_t mcf5225xEthCalcCrc(const void *data, size_t length)
00755 {
00756    uint_t i;
00757    uint_t j;
00758 
00759    //Point to the data over which to calculate the CRC
00760    const uint8_t *p = (uint8_t *) data;
00761    //CRC preset value
00762    uint32_t crc = 0xFFFFFFFF;
00763 
00764    //Loop through data
00765    for(i = 0; i < length; i++)
00766    {
00767       //Update CRC value
00768       crc ^= p[i];
00769       //The message is processed bit by bit
00770       for(j = 0; j < 8; j++)
00771       {
00772          if(crc & 0x00000001)
00773             crc = (crc >> 1) ^ 0xEDB88320;
00774          else
00775             crc = crc >> 1;
00776       }
00777    }
00778 
00779    //Return CRC value
00780    return crc;
00781 }
00782