Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers same70_eth.c Source File

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