Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
same70_eth.c
Go to the documentation of this file.
00001 /** 00002 * @file same70_eth.c 00003 * @brief SAME70 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 <limits.h> 00034 #include "same70.h" 00035 #include "core/net.h" 00036 #include "drivers/same70_eth.h" 00037 #include "debug.h" 00038 00039 //Underlying network interface 00040 static NetInterface *nicDriverInterface; 00041 00042 //IAR EWARM compiler? 00043 #if defined(__ICCARM__) 00044 00045 //TX buffer 00046 #pragma data_alignment = 8 00047 #pragma location = ".ram_no_cache" 00048 static uint8_t txBuffer[SAME70_ETH_TX_BUFFER_COUNT][SAME70_ETH_TX_BUFFER_SIZE]; 00049 //RX buffer 00050 #pragma data_alignment = 8 00051 #pragma location = ".ram_no_cache" 00052 static uint8_t rxBuffer[SAME70_ETH_RX_BUFFER_COUNT][SAME70_ETH_RX_BUFFER_SIZE]; 00053 //TX buffer descriptors 00054 #pragma data_alignment = 4 00055 #pragma location = ".ram_no_cache" 00056 static Same70TxBufferDesc txBufferDesc[SAME70_ETH_TX_BUFFER_COUNT]; 00057 //RX buffer descriptors 00058 #pragma data_alignment = 4 00059 #pragma location = ".ram_no_cache" 00060 static Same70RxBufferDesc rxBufferDesc[SAME70_ETH_RX_BUFFER_COUNT]; 00061 00062 //Dummy TX buffer 00063 #pragma data_alignment = 8 00064 #pragma location = ".ram_no_cache" 00065 static uint8_t dummyTxBuffer[SAME70_ETH_DUMMY_BUFFER_COUNT][SAME70_ETH_DUMMY_BUFFER_SIZE]; 00066 //Dummy RX buffer 00067 #pragma data_alignment = 8 00068 #pragma location = ".ram_no_cache" 00069 static uint8_t dummyRxBuffer[SAME70_ETH_DUMMY_BUFFER_COUNT][SAME70_ETH_DUMMY_BUFFER_SIZE]; 00070 //Dummy TX buffer descriptors 00071 #pragma data_alignment = 4 00072 #pragma location = ".ram_no_cache" 00073 static Same70TxBufferDesc dummyTxBufferDesc[SAME70_ETH_DUMMY_BUFFER_COUNT]; 00074 //Dummy RX buffer descriptors 00075 #pragma data_alignment = 4 00076 #pragma location = ".ram_no_cache" 00077 static Same70RxBufferDesc dummyRxBufferDesc[SAME70_ETH_DUMMY_BUFFER_COUNT]; 00078 00079 //Keil MDK-ARM or GCC compiler? 00080 #else 00081 00082 //TX buffer 00083 static uint8_t txBuffer[SAME70_ETH_TX_BUFFER_COUNT][SAME70_ETH_TX_BUFFER_SIZE] 00084 __attribute__((aligned(8), __section__(".ram_no_cache"))); 00085 //RX buffer 00086 static uint8_t rxBuffer[SAME70_ETH_RX_BUFFER_COUNT][SAME70_ETH_RX_BUFFER_SIZE] 00087 __attribute__((aligned(8), __section__(".ram_no_cache"))); 00088 //TX buffer descriptors 00089 static Same70TxBufferDesc txBufferDesc[SAME70_ETH_TX_BUFFER_COUNT] 00090 __attribute__((aligned(4), __section__(".ram_no_cache"))); 00091 //RX buffer descriptors 00092 static Same70RxBufferDesc rxBufferDesc[SAME70_ETH_RX_BUFFER_COUNT] 00093 __attribute__((aligned(4), __section__(".ram_no_cache"))); 00094 00095 //Dummy TX buffer 00096 static uint8_t dummyTxBuffer[SAME70_ETH_DUMMY_BUFFER_COUNT][SAME70_ETH_DUMMY_BUFFER_SIZE] 00097 __attribute__((aligned(8), __section__(".ram_no_cache"))); 00098 //Dummy RX buffer 00099 static uint8_t dummyRxBuffer[SAME70_ETH_DUMMY_BUFFER_COUNT][SAME70_ETH_DUMMY_BUFFER_SIZE] 00100 __attribute__((aligned(8), __section__(".ram_no_cache"))); 00101 //Dummy TX buffer descriptors 00102 static Same70TxBufferDesc dummyTxBufferDesc[SAME70_ETH_DUMMY_BUFFER_COUNT] 00103 __attribute__((aligned(4), __section__(".ram_no_cache"))); 00104 //Dummy RX buffer descriptors 00105 static Same70RxBufferDesc dummyRxBufferDesc[SAME70_ETH_DUMMY_BUFFER_COUNT] 00106 __attribute__((aligned(4), __section__(".ram_no_cache"))); 00107 00108 #endif 00109 00110 //TX buffer index 00111 static uint_t txBufferIndex; 00112 //RX buffer index 00113 static uint_t rxBufferIndex; 00114 00115 00116 /** 00117 * @brief SAME70 Ethernet MAC driver 00118 **/ 00119 00120 const NicDriver same70EthDriver = 00121 { 00122 NIC_TYPE_ETHERNET, 00123 ETH_MTU, 00124 same70EthInit, 00125 same70EthTick, 00126 same70EthEnableIrq, 00127 same70EthDisableIrq, 00128 same70EthEventHandler, 00129 same70EthSendPacket, 00130 same70EthSetMulticastFilter, 00131 same70EthUpdateMacConfig, 00132 same70EthWritePhyReg, 00133 same70EthReadPhyReg, 00134 TRUE, 00135 TRUE, 00136 TRUE, 00137 FALSE 00138 }; 00139 00140 00141 /** 00142 * @brief SAME70 Ethernet MAC initialization 00143 * @param[in] interface Underlying network interface 00144 * @return Error code 00145 **/ 00146 00147 error_t same70EthInit(NetInterface *interface) 00148 { 00149 error_t error; 00150 volatile uint32_t status; 00151 00152 //Debug message 00153 TRACE_INFO("Initializing SAME70 Ethernet MAC...\r\n"); 00154 00155 //Save underlying network interface 00156 nicDriverInterface = interface; 00157 00158 //Enable GMAC peripheral clock 00159 PMC->PMC_PCER1 = (1 << (ID_GMAC - 32)); 00160 00161 //GPIO configuration 00162 same70EthInitGpio(interface); 00163 00164 //Configure MDC clock speed 00165 GMAC->GMAC_NCFGR = GMAC_NCFGR_CLK_MCK_96; 00166 //Enable management port (MDC and MDIO) 00167 GMAC->GMAC_NCR |= GMAC_NCR_MPE; 00168 00169 //PHY transceiver initialization 00170 error = interface->phyDriver->init(interface); 00171 //Failed to initialize PHY transceiver? 00172 if(error) 00173 return error; 00174 00175 //Set the MAC address 00176 GMAC->GMAC_SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16); 00177 GMAC->GMAC_SA[0].GMAC_SAT = interface->macAddr.w[2]; 00178 00179 //Configure the receive filter 00180 GMAC->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN | GMAC_NCFGR_MTIHEN; 00181 00182 //DMA configuration 00183 GMAC->GMAC_DCFGR = GMAC_DCFGR_DRBS(SAME70_ETH_RX_BUFFER_SIZE / 64) | 00184 GMAC_DCFGR_TXPBMS | GMAC_DCFGR_RXBMS_FULL | GMAC_DCFGR_FBLDO_INCR4; 00185 00186 GMAC->GMAC_RBSRPQ[0] = GMAC_RBSRPQ_RBS(SAME70_ETH_DUMMY_BUFFER_SIZE / 64); 00187 GMAC->GMAC_RBSRPQ[1] = GMAC_RBSRPQ_RBS(SAME70_ETH_DUMMY_BUFFER_SIZE / 64); 00188 00189 //Initialize hash table 00190 GMAC->GMAC_HRB = 0; 00191 GMAC->GMAC_HRT = 0; 00192 00193 //Initialize buffer descriptors 00194 same70EthInitBufferDesc(interface); 00195 00196 //Clear transmit status register 00197 GMAC->GMAC_TSR = GMAC_TSR_HRESP | GMAC_TSR_TXCOMP | GMAC_TSR_TFC | 00198 GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR; 00199 //Clear receive status register 00200 GMAC->GMAC_RSR = GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA; 00201 00202 //First disable all GMAC interrupts 00203 GMAC->GMAC_IDR = 0xFFFFFFFF; 00204 GMAC->GMAC_IDRPQ[0] = 0xFFFFFFFF; 00205 GMAC->GMAC_IDRPQ[1] = 0xFFFFFFFF; 00206 00207 //Only the desired ones are enabled 00208 GMAC->GMAC_IER = GMAC_IER_HRESP | GMAC_IER_ROVR | GMAC_IER_TCOMP | GMAC_IER_TFC | 00209 GMAC_IER_RLEX | GMAC_IER_TUR | GMAC_IER_RXUBR | GMAC_IER_RCOMP; 00210 00211 //Read GMAC ISR register to clear any pending interrupt 00212 status = GMAC->GMAC_ISR; 00213 00214 //Set priority grouping (3 bits for pre-emption priority, no bits for subpriority) 00215 NVIC_SetPriorityGrouping(SAME70_ETH_IRQ_PRIORITY_GROUPING); 00216 00217 //Configure GMAC interrupt priority 00218 NVIC_SetPriority(GMAC_IRQn, NVIC_EncodePriority(SAME70_ETH_IRQ_PRIORITY_GROUPING, 00219 SAME70_ETH_IRQ_GROUP_PRIORITY, SAME70_ETH_IRQ_SUB_PRIORITY)); 00220 00221 //Enable the GMAC to transmit and receive data 00222 GMAC->GMAC_NCR |= GMAC_NCR_TXEN | GMAC_NCR_RXEN; 00223 00224 //Accept any packets from the upper layer 00225 osSetEvent(&interface->nicTxEvent); 00226 00227 //Successful initialization 00228 return NO_ERROR; 00229 } 00230 00231 00232 //SAME70-Xplained evaluation board? 00233 #if defined(USE_SAME70_XPLAINED) 00234 00235 /** 00236 * @brief GPIO configuration 00237 * @param[in] interface Underlying network interface 00238 **/ 00239 00240 void same70EthInitGpio(NetInterface *interface) 00241 { 00242 //Enable PIO peripheral clocks 00243 PMC->PMC_PCER0 = (1 << ID_PIOC) | (1 << ID_PIOD); 00244 00245 //Disable pull-up resistors on RMII pins 00246 PIOD->PIO_PUDR = GMAC_RMII_MASK; 00247 //Disable interrupts-on-change 00248 PIOD->PIO_IDR = GMAC_RMII_MASK; 00249 //Assign RMII pins to peripheral A function 00250 PIOD->PIO_ABCDSR[0] &= ~GMAC_RMII_MASK; 00251 PIOD->PIO_ABCDSR[1] &= ~GMAC_RMII_MASK; 00252 //Disable the PIO from controlling the corresponding pins 00253 PIOD->PIO_PDR = GMAC_RMII_MASK; 00254 00255 //Select RMII operation mode 00256 GMAC->GMAC_UR &= ~GMAC_UR_RMII; 00257 00258 //Configure PHY_RESET as an output 00259 PIOC->PIO_PER = PIO_PC10; 00260 PIOC->PIO_OER = PIO_PC10; 00261 00262 //Reset PHY transceiver 00263 PIOC->PIO_CODR = PIO_PC10; 00264 sleep(10); 00265 00266 //Take the PHY transceiver out of reset 00267 PIOC->PIO_SODR = PIO_PC10; 00268 sleep(10); 00269 } 00270 00271 #endif 00272 00273 00274 /** 00275 * @brief Initialize buffer descriptors 00276 * @param[in] interface Underlying network interface 00277 **/ 00278 00279 void same70EthInitBufferDesc(NetInterface *interface) 00280 { 00281 uint_t i; 00282 uint32_t address; 00283 00284 //Initialize TX buffer descriptors 00285 for(i = 0; i < SAME70_ETH_TX_BUFFER_COUNT; i++) 00286 { 00287 //Calculate the address of the current TX buffer 00288 address = (uint32_t) txBuffer[i]; 00289 //Write the address to the descriptor entry 00290 txBufferDesc[i].address = address; 00291 //Initialize status field 00292 txBufferDesc[i].status = GMAC_TX_USED; 00293 } 00294 00295 //Mark the last descriptor entry with the wrap flag 00296 txBufferDesc[i - 1].status |= GMAC_TX_WRAP; 00297 //Initialize TX buffer index 00298 txBufferIndex = 0; 00299 00300 //Initialize RX buffer descriptors 00301 for(i = 0; i < SAME70_ETH_RX_BUFFER_COUNT; i++) 00302 { 00303 //Calculate the address of the current RX buffer 00304 address = (uint32_t) rxBuffer[i]; 00305 //Write the address to the descriptor entry 00306 rxBufferDesc[i].address = address & GMAC_RX_ADDRESS; 00307 //Clear status field 00308 rxBufferDesc[i].status = 0; 00309 } 00310 00311 //Mark the last descriptor entry with the wrap flag 00312 rxBufferDesc[i - 1].address |= GMAC_RX_WRAP; 00313 //Initialize RX buffer index 00314 rxBufferIndex = 0; 00315 00316 //Initialize dummy TX buffer descriptors 00317 for(i = 0; i < SAME70_ETH_DUMMY_BUFFER_COUNT; i++) 00318 { 00319 //Calculate the address of the current TX buffer 00320 address = (uint32_t) dummyTxBuffer[i]; 00321 //Write the address to the descriptor entry 00322 dummyTxBufferDesc[i].address = address; 00323 //Initialize status field 00324 dummyTxBufferDesc[i].status = GMAC_TX_USED; 00325 } 00326 00327 //Mark the last descriptor entry with the wrap flag 00328 dummyTxBufferDesc[i - 1].status |= GMAC_TX_WRAP; 00329 00330 //Initialize dummy RX buffer descriptors 00331 for(i = 0; i < SAME70_ETH_DUMMY_BUFFER_COUNT; i++) 00332 { 00333 //Calculate the address of the current RX buffer 00334 address = (uint32_t) dummyRxBuffer[i]; 00335 //Write the address to the descriptor entry 00336 dummyRxBufferDesc[i].address = (address & GMAC_RX_ADDRESS) | GMAC_RX_OWNERSHIP; 00337 //Clear status field 00338 dummyRxBufferDesc[i].status = 0; 00339 } 00340 00341 //Mark the last descriptor entry with the wrap flag 00342 dummyRxBufferDesc[i - 1].address |= GMAC_RX_WRAP; 00343 00344 //Start location of the TX descriptor list 00345 GMAC->GMAC_TBQB = (uint32_t) txBufferDesc; 00346 GMAC->GMAC_TBQBAPQ[0] = (uint32_t) dummyTxBufferDesc; 00347 GMAC->GMAC_TBQBAPQ[1] = (uint32_t) dummyTxBufferDesc; 00348 00349 //Start location of the RX descriptor list 00350 GMAC->GMAC_RBQB = (uint32_t) rxBufferDesc; 00351 GMAC->GMAC_RBQBAPQ[0] = (uint32_t) dummyRxBufferDesc; 00352 GMAC->GMAC_RBQBAPQ[1] = (uint32_t) dummyRxBufferDesc; 00353 } 00354 00355 00356 /** 00357 * @brief SAME70 Ethernet MAC timer handler 00358 * 00359 * This routine is periodically called by the TCP/IP stack to 00360 * handle periodic operations such as polling the link state 00361 * 00362 * @param[in] interface Underlying network interface 00363 **/ 00364 00365 void same70EthTick(NetInterface *interface) 00366 { 00367 //Handle periodic operations 00368 interface->phyDriver->tick(interface); 00369 } 00370 00371 00372 /** 00373 * @brief Enable interrupts 00374 * @param[in] interface Underlying network interface 00375 **/ 00376 00377 void same70EthEnableIrq(NetInterface *interface) 00378 { 00379 //Enable Ethernet MAC interrupts 00380 NVIC_EnableIRQ(GMAC_IRQn); 00381 //Enable Ethernet PHY interrupts 00382 interface->phyDriver->enableIrq(interface); 00383 } 00384 00385 00386 /** 00387 * @brief Disable interrupts 00388 * @param[in] interface Underlying network interface 00389 **/ 00390 00391 void same70EthDisableIrq(NetInterface *interface) 00392 { 00393 //Disable Ethernet MAC interrupts 00394 NVIC_DisableIRQ(GMAC_IRQn); 00395 //Disable Ethernet PHY interrupts 00396 interface->phyDriver->disableIrq(interface); 00397 } 00398 00399 00400 /** 00401 * @brief SAME70 Ethernet MAC interrupt service routine 00402 **/ 00403 00404 void GMAC_Handler(void) 00405 { 00406 bool_t flag; 00407 volatile uint32_t isr; 00408 volatile uint32_t tsr; 00409 volatile uint32_t rsr; 00410 00411 //Enter interrupt service routine 00412 osEnterIsr(); 00413 00414 //This flag will be set if a higher priority task must be woken 00415 flag = FALSE; 00416 00417 //Each time the software reads GMAC_ISR, it has to check the 00418 //contents of GMAC_TSR, GMAC_RSR and GMAC_NSR 00419 isr = GMAC->GMAC_ISRPQ[0]; 00420 isr = GMAC->GMAC_ISRPQ[1]; 00421 isr = GMAC->GMAC_ISR; 00422 tsr = GMAC->GMAC_TSR; 00423 rsr = GMAC->GMAC_RSR; 00424 00425 //A packet has been transmitted? 00426 if(tsr & (GMAC_TSR_HRESP | GMAC_TSR_TXCOMP | GMAC_TSR_TFC | 00427 GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR)) 00428 { 00429 //Only clear TSR flags that are currently set 00430 GMAC->GMAC_TSR = tsr; 00431 00432 //Check whether the TX buffer is available for writing 00433 if(txBufferDesc[txBufferIndex].status & GMAC_TX_USED) 00434 { 00435 //Notify the TCP/IP stack that the transmitter is ready to send 00436 flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent); 00437 } 00438 } 00439 00440 //A packet has been received? 00441 if(rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA)) 00442 { 00443 //Set event flag 00444 nicDriverInterface->nicEvent = TRUE; 00445 //Notify the TCP/IP stack of the event 00446 flag |= osSetEventFromIsr(&netEvent); 00447 } 00448 00449 //Leave interrupt service routine 00450 osExitIsr(flag); 00451 } 00452 00453 00454 /** 00455 * @brief SAME70 Ethernet MAC event handler 00456 * @param[in] interface Underlying network interface 00457 **/ 00458 00459 void same70EthEventHandler(NetInterface *interface) 00460 { 00461 error_t error; 00462 uint32_t rsr; 00463 00464 //Read receive status 00465 rsr = GMAC->GMAC_RSR; 00466 00467 //Packet received? 00468 if(rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA)) 00469 { 00470 //Only clear RSR flags that are currently set 00471 GMAC->GMAC_RSR = rsr; 00472 00473 //Process all pending packets 00474 do 00475 { 00476 //Read incoming packet 00477 error = same70EthReceivePacket(interface); 00478 00479 //No more data in the receive buffer? 00480 } while(error != ERROR_BUFFER_EMPTY); 00481 } 00482 } 00483 00484 00485 /** 00486 * @brief Send a packet 00487 * @param[in] interface Underlying network interface 00488 * @param[in] buffer Multi-part buffer containing the data to send 00489 * @param[in] offset Offset to the first data byte 00490 * @return Error code 00491 **/ 00492 00493 error_t same70EthSendPacket(NetInterface *interface, 00494 const NetBuffer *buffer, size_t offset) 00495 { 00496 static uint8_t temp[SAME70_ETH_TX_BUFFER_SIZE]; 00497 size_t length; 00498 00499 //Retrieve the length of the packet 00500 length = netBufferGetLength(buffer) - offset; 00501 00502 //Check the frame length 00503 if(length > SAME70_ETH_TX_BUFFER_SIZE) 00504 { 00505 //The transmitter can accept another packet 00506 osSetEvent(&interface->nicTxEvent); 00507 //Report an error 00508 return ERROR_INVALID_LENGTH; 00509 } 00510 00511 //Make sure the current buffer is available for writing 00512 if(!(txBufferDesc[txBufferIndex].status & GMAC_TX_USED)) 00513 return ERROR_FAILURE; 00514 00515 //Copy user data to the transmit buffer 00516 netBufferRead(temp, buffer, offset, length); 00517 memcpy(txBuffer[txBufferIndex], temp, (length + 3) & ~3UL); 00518 00519 //Set the necessary flags in the descriptor entry 00520 if(txBufferIndex < (SAME70_ETH_TX_BUFFER_COUNT - 1)) 00521 { 00522 //Write the status word 00523 txBufferDesc[txBufferIndex].status = 00524 GMAC_TX_LAST | (length & GMAC_TX_LENGTH); 00525 00526 //Point to the next buffer 00527 txBufferIndex++; 00528 } 00529 else 00530 { 00531 //Write the status word 00532 txBufferDesc[txBufferIndex].status = GMAC_TX_WRAP | 00533 GMAC_TX_LAST | (length & GMAC_TX_LENGTH); 00534 00535 //Wrap around 00536 txBufferIndex = 0; 00537 } 00538 00539 //Data synchronization barrier 00540 __DSB(); 00541 00542 //Set the TSTART bit to initiate transmission 00543 GMAC->GMAC_NCR |= GMAC_NCR_TSTART; 00544 00545 //Check whether the next buffer is available for writing 00546 if(txBufferDesc[txBufferIndex].status & GMAC_TX_USED) 00547 { 00548 //The transmitter can accept another packet 00549 osSetEvent(&interface->nicTxEvent); 00550 } 00551 00552 //Successful processing 00553 return NO_ERROR; 00554 } 00555 00556 00557 /** 00558 * @brief Receive a packet 00559 * @param[in] interface Underlying network interface 00560 * @return Error code 00561 **/ 00562 00563 error_t same70EthReceivePacket(NetInterface *interface) 00564 { 00565 static uint8_t temp[ETH_MAX_FRAME_SIZE]; 00566 error_t error; 00567 uint_t i; 00568 uint_t j; 00569 uint_t sofIndex; 00570 uint_t eofIndex; 00571 size_t n; 00572 size_t size; 00573 size_t length; 00574 00575 //Initialize SOF and EOF indices 00576 sofIndex = UINT_MAX; 00577 eofIndex = UINT_MAX; 00578 00579 //Search for SOF and EOF flags 00580 for(i = 0; i < SAME70_ETH_RX_BUFFER_COUNT; i++) 00581 { 00582 //Point to the current entry 00583 j = rxBufferIndex + i; 00584 00585 //Wrap around to the beginning of the buffer if necessary 00586 if(j >= SAME70_ETH_RX_BUFFER_COUNT) 00587 j -= SAME70_ETH_RX_BUFFER_COUNT; 00588 00589 //No more entries to process? 00590 if(!(rxBufferDesc[j].address & GMAC_RX_OWNERSHIP)) 00591 { 00592 //Stop processing 00593 break; 00594 } 00595 //A valid SOF has been found? 00596 if(rxBufferDesc[j].status & GMAC_RX_SOF) 00597 { 00598 //Save the position of the SOF 00599 sofIndex = i; 00600 } 00601 //A valid EOF has been found? 00602 if((rxBufferDesc[j].status & GMAC_RX_EOF) && sofIndex != UINT_MAX) 00603 { 00604 //Save the position of the EOF 00605 eofIndex = i; 00606 //Retrieve the length of the frame 00607 size = rxBufferDesc[j].status & GMAC_RX_LENGTH; 00608 //Limit the number of data to read 00609 size = MIN(size, ETH_MAX_FRAME_SIZE); 00610 //Stop processing since we have reached the end of the frame 00611 break; 00612 } 00613 } 00614 00615 //Determine the number of entries to process 00616 if(eofIndex != UINT_MAX) 00617 j = eofIndex + 1; 00618 else if(sofIndex != UINT_MAX) 00619 j = sofIndex; 00620 else 00621 j = i; 00622 00623 //Total number of bytes that have been copied from the receive buffer 00624 length = 0; 00625 00626 //Process incoming frame 00627 for(i = 0; i < j; i++) 00628 { 00629 //Any data to copy from current buffer? 00630 if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex) 00631 { 00632 //Calculate the number of bytes to read at a time 00633 n = MIN(size, SAME70_ETH_RX_BUFFER_SIZE); 00634 //Copy data from receive buffer 00635 memcpy(temp + length, rxBuffer[rxBufferIndex], (n + 3) & ~3UL); 00636 //Update byte counters 00637 length += n; 00638 size -= n; 00639 } 00640 00641 //Mark the current buffer as free 00642 rxBufferDesc[rxBufferIndex].address &= ~GMAC_RX_OWNERSHIP; 00643 00644 //Point to the following entry 00645 rxBufferIndex++; 00646 00647 //Wrap around to the beginning of the buffer if necessary 00648 if(rxBufferIndex >= SAME70_ETH_RX_BUFFER_COUNT) 00649 rxBufferIndex = 0; 00650 } 00651 00652 //Any packet to process? 00653 if(length > 0) 00654 { 00655 //Pass the packet to the upper layer 00656 nicProcessPacket(interface, temp, length); 00657 //Valid packet received 00658 error = NO_ERROR; 00659 } 00660 else 00661 { 00662 //No more data in the receive buffer 00663 error = ERROR_BUFFER_EMPTY; 00664 } 00665 00666 //Return status code 00667 return error; 00668 } 00669 00670 00671 /** 00672 * @brief Configure multicast MAC address filtering 00673 * @param[in] interface Underlying network interface 00674 * @return Error code 00675 **/ 00676 00677 error_t same70EthSetMulticastFilter(NetInterface *interface) 00678 { 00679 uint_t i; 00680 uint_t k; 00681 uint8_t *p; 00682 uint32_t hashTable[2]; 00683 MacFilterEntry *entry; 00684 00685 //Debug message 00686 TRACE_DEBUG("Updating SAME70 hash table...\r\n"); 00687 00688 //Clear hash table 00689 hashTable[0] = 0; 00690 hashTable[1] = 0; 00691 00692 //The MAC filter table contains the multicast MAC addresses 00693 //to accept when receiving an Ethernet frame 00694 for(i = 0; i < MAC_MULTICAST_FILTER_SIZE; i++) 00695 { 00696 //Point to the current entry 00697 entry = &interface->macMulticastFilter[i]; 00698 00699 //Valid entry? 00700 if(entry->refCount > 0) 00701 { 00702 //Point to the MAC address 00703 p = entry->addr.b; 00704 00705 //Apply the hash function 00706 k = (p[0] >> 6) ^ p[0]; 00707 k ^= (p[1] >> 4) ^ (p[1] << 2); 00708 k ^= (p[2] >> 2) ^ (p[2] << 4); 00709 k ^= (p[3] >> 6) ^ p[3]; 00710 k ^= (p[4] >> 4) ^ (p[4] << 2); 00711 k ^= (p[5] >> 2) ^ (p[5] << 4); 00712 00713 //The hash value is reduced to a 6-bit index 00714 k &= 0x3F; 00715 00716 //Update hash table contents 00717 hashTable[k / 32] |= (1 << (k % 32)); 00718 } 00719 } 00720 00721 //Write the hash table 00722 GMAC->GMAC_HRB = hashTable[0]; 00723 GMAC->GMAC_HRT = hashTable[1]; 00724 00725 //Debug message 00726 TRACE_DEBUG(" HRB = %08" PRIX32 "\r\n", GMAC->GMAC_HRB); 00727 TRACE_DEBUG(" HRT = %08" PRIX32 "\r\n", GMAC->GMAC_HRT); 00728 00729 //Successful processing 00730 return NO_ERROR; 00731 } 00732 00733 00734 /** 00735 * @brief Adjust MAC configuration parameters for proper operation 00736 * @param[in] interface Underlying network interface 00737 * @return Error code 00738 **/ 00739 00740 error_t same70EthUpdateMacConfig(NetInterface *interface) 00741 { 00742 uint32_t config; 00743 00744 //Read network configuration register 00745 config = GMAC->GMAC_NCFGR; 00746 00747 //10BASE-T or 100BASE-TX operation mode? 00748 if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS) 00749 config |= GMAC_NCFGR_SPD; 00750 else 00751 config &= ~GMAC_NCFGR_SPD; 00752 00753 //Half-duplex or full-duplex mode? 00754 if(interface->duplexMode == NIC_FULL_DUPLEX_MODE) 00755 config |= GMAC_NCFGR_FD; 00756 else 00757 config &= ~GMAC_NCFGR_FD; 00758 00759 //Write configuration value back to NCFGR register 00760 GMAC->GMAC_NCFGR = config; 00761 00762 //Successful processing 00763 return NO_ERROR; 00764 } 00765 00766 00767 /** 00768 * @brief Write PHY register 00769 * @param[in] phyAddr PHY address 00770 * @param[in] regAddr Register address 00771 * @param[in] data Register value 00772 **/ 00773 00774 void same70EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data) 00775 { 00776 uint32_t value; 00777 00778 //Set up a write operation 00779 value = GMAC_MAN_CLTTO | GMAC_MAN_OP(1) | GMAC_MAN_WTN(2); 00780 //PHY address 00781 value |= GMAC_MAN_PHYA(phyAddr); 00782 //Register address 00783 value |= GMAC_MAN_REGA(regAddr); 00784 //Register value 00785 value |= GMAC_MAN_DATA(data); 00786 00787 //Start a write operation 00788 GMAC->GMAC_MAN = value; 00789 //Wait for the write to complete 00790 while(!(GMAC->GMAC_NSR & GMAC_NSR_IDLE)); 00791 } 00792 00793 00794 /** 00795 * @brief Read PHY register 00796 * @param[in] phyAddr PHY address 00797 * @param[in] regAddr Register address 00798 * @return Register value 00799 **/ 00800 00801 uint16_t same70EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr) 00802 { 00803 uint32_t value; 00804 00805 //Set up a read operation 00806 value = GMAC_MAN_CLTTO | GMAC_MAN_OP(2) | GMAC_MAN_WTN(2); 00807 //PHY address 00808 value |= GMAC_MAN_PHYA(phyAddr); 00809 //Register address 00810 value |= GMAC_MAN_REGA(regAddr); 00811 00812 //Start a read operation 00813 GMAC->GMAC_MAN = value; 00814 //Wait for the read to complete 00815 while(!(GMAC->GMAC_NSR & GMAC_NSR_IDLE)); 00816 00817 //Return PHY register contents 00818 return GMAC->GMAC_MAN & GMAC_MAN_DATA_Msk; 00819 } 00820
Generated on Tue Jul 12 2022 17:10:16 by
