Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mcf5225x_eth.c
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
Generated on Tue Jul 12 2022 17:10:14 by
1.7.2