Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers avr32_eth.c Source File

avr32_eth.c

Go to the documentation of this file.
00001 /**
00002  * @file avr32_eth.c
00003  * @brief AVR32 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 <avr32/io.h>
00035 #include "interrupt.h"
00036 #include "intc.h"
00037 #include "core/net.h"
00038 #include "drivers/avr32_eth.h"
00039 #include "debug.h"
00040 
00041 //Underlying network interface
00042 static NetInterface *nicDriverInterface;
00043 
00044 //IAR EWARM compiler?
00045 #if defined(__ICCARM__)
00046 
00047 //TX buffer
00048 #pragma data_alignment = 4
00049 static uint8_t txBuffer[AVR32_ETH_TX_BUFFER_COUNT][AVR32_ETH_TX_BUFFER_SIZE];
00050 //RX buffer
00051 #pragma data_alignment = 4
00052 static uint8_t rxBuffer[AVR32_ETH_RX_BUFFER_COUNT][AVR32_ETH_RX_BUFFER_SIZE];
00053 //TX buffer descriptors
00054 #pragma data_alignment = 8
00055 static Avr32TxBufferDesc txBufferDesc[AVR32_ETH_TX_BUFFER_COUNT];
00056 //RX buffer descriptors
00057 #pragma data_alignment = 8
00058 static Avr32RxBufferDesc rxBufferDesc[AVR32_ETH_RX_BUFFER_COUNT];
00059 
00060 //GCC compiler?
00061 #else
00062 
00063 //TX buffer
00064 static uint8_t txBuffer[AVR32_ETH_TX_BUFFER_COUNT][AVR32_ETH_TX_BUFFER_SIZE]
00065    __attribute__((aligned(4)));
00066 //RX buffer
00067 static uint8_t rxBuffer[AVR32_ETH_RX_BUFFER_COUNT][AVR32_ETH_RX_BUFFER_SIZE]
00068    __attribute__((aligned(4)));
00069 //TX buffer descriptors
00070 static Avr32TxBufferDesc txBufferDesc[AVR32_ETH_TX_BUFFER_COUNT]
00071    __attribute__((aligned(8)));
00072 //RX buffer descriptors
00073 static Avr32RxBufferDesc rxBufferDesc[AVR32_ETH_RX_BUFFER_COUNT]
00074    __attribute__((aligned(8)));
00075 
00076 #endif
00077 
00078 //TX buffer index
00079 static uint_t txBufferIndex;
00080 //RX buffer index
00081 static uint_t rxBufferIndex;
00082 
00083 
00084 /**
00085  * @brief AVR32 Ethernet MAC driver
00086  **/
00087 
00088 const NicDriver avr32EthDriver =
00089 {
00090    NIC_TYPE_ETHERNET,
00091    ETH_MTU,
00092    avr32EthInit,
00093    avr32EthTick,
00094    avr32EthEnableIrq,
00095    avr32EthDisableIrq,
00096    avr32EthEventHandler,
00097    avr32EthSendPacket,
00098    avr32EthSetMulticastFilter,
00099    avr32EthUpdateMacConfig,
00100    avr32EthWritePhyReg,
00101    avr32EthReadPhyReg,
00102    TRUE,
00103    TRUE,
00104    TRUE,
00105    FALSE
00106 };
00107 
00108 
00109 /**
00110  * @brief AVR32 Ethernet MAC initialization
00111  * @param[in] interface Underlying network interface
00112  * @return Error code
00113  **/
00114 
00115 error_t avr32EthInit(NetInterface *interface)
00116 {
00117    error_t error;
00118    volatile uint32_t status;
00119 
00120    //Debug message
00121    TRACE_INFO("Initializing AVR32 Ethernet MAC...\r\n");
00122 
00123    //Save underlying network interface
00124    nicDriverInterface = interface;
00125 
00126    //GPIO configuration
00127    avr32EthInitGpio(interface);
00128 
00129    //Configure MDC clock speed
00130    AVR32_MACB.ncfgr = AVR32_MACB_NCFGR_CLK_DIV64;
00131    //Enable management port (MDC and MDIO)
00132    AVR32_MACB.ncr |= AVR32_MACB_NCR_MPE_MASK;
00133 
00134    //PHY transceiver initialization
00135    error = interface->phyDriver->init(interface);
00136    //Failed to initialize PHY transceiver?
00137    if(error)
00138       return error;
00139 
00140    //Set the MAC address
00141    AVR32_MACB.sa1b = interface->macAddr.b[0] |
00142       (interface->macAddr.b[1] << 8) |
00143       (interface->macAddr.b[2] << 16) |
00144       (interface->macAddr.b[3] << 24);
00145 
00146    AVR32_MACB.sa1t = interface->macAddr.b[4] |
00147       (interface->macAddr.b[5] << 8);
00148 
00149    //Configure the receive filter
00150    AVR32_MACB.ncfgr |= AVR32_MACB_NCFGR_UNI_MASK | AVR32_MACB_NCFGR_MTI_MASK;
00151 
00152    //Initialize hash table
00153    AVR32_MACB.hrb = 0;
00154    AVR32_MACB.hrt = 0;
00155 
00156    //Initialize buffer descriptors
00157    avr32EthInitBufferDesc(interface);
00158 
00159    //Clear transmit status register
00160    AVR32_MACB.tsr = AVR32_MACB_TSR_UND_MASK | AVR32_MACB_TSR_COMP_MASK | AVR32_MACB_TSR_BEX_MASK |
00161       AVR32_MACB_TSR_TGO_MASK | AVR32_MACB_TSR_RLE_MASK | AVR32_MACB_TSR_COL_MASK | AVR32_MACB_TSR_UBR_MASK;
00162    //Clear receive status register
00163    AVR32_MACB.rsr = AVR32_MACB_RSR_OVR_MASK | AVR32_MACB_RSR_REC_MASK | AVR32_MACB_RSR_BNA_MASK;
00164 
00165    //First disable all EMAC interrupts
00166    AVR32_MACB.idr = 0xFFFFFFFF;
00167    //Only the desired ones are enabled
00168    AVR32_MACB.ier = AVR32_MACB_IER_ROVR_MASK | AVR32_MACB_IER_TCOMP_MASK | AVR32_MACB_IER_TXERR_MASK |
00169       AVR32_MACB_IER_RLE_MASK | AVR32_MACB_IER_TUND_MASK | AVR32_MACB_IER_RXUBR_MASK | AVR32_MACB_IER_RCOMP_MASK;
00170 
00171    //Read EMAC ISR register to clear any pending interrupt
00172    status = AVR32_MACB.isr;
00173 
00174    //Register interrupt handler
00175    INTC_register_interrupt(avr32EthIrqWrapper, AVR32_MACB_IRQ, AVR32_ETH_IRQ_PRIORITY);
00176 
00177    //Enable the EMAC to transmit and receive data
00178    AVR32_MACB.ncr |= AVR32_MACB_NCR_TE_MASK | AVR32_MACB_NCR_RE_MASK;
00179 
00180    //Accept any packets from the upper layer
00181    osSetEvent(&interface->nicTxEvent);
00182 
00183    //Successful initialization
00184    return NO_ERROR;
00185 }
00186 
00187 
00188 //EVK1105 evaluation board?
00189 #if defined(USE_EVK1105)
00190 
00191 /**
00192  * @brief GPIO configuration
00193  * @param[in] interface Underlying network interface
00194  **/
00195 
00196 void avr32EthInitGpio(NetInterface *interface)
00197 {
00198    //Assign RMII pins to peripheral A function
00199    AVR32_GPIO.port[1].pmr0c = MACB_RMII_MASK;
00200    AVR32_GPIO.port[1].pmr1c =MACB_RMII_MASK;
00201 
00202    //Disable the PIO from controlling the corresponding pins
00203    AVR32_GPIO.port[1].gperc = MACB_RMII_MASK;
00204 
00205    //Select RMII operation mode
00206    AVR32_MACB.usrio &= ~AVR32_MACB_USRIO_RMII_MASK;
00207 }
00208 
00209 #endif
00210 
00211 
00212 /**
00213  * @brief Initialize buffer descriptors
00214  * @param[in] interface Underlying network interface
00215  **/
00216 
00217 void avr32EthInitBufferDesc(NetInterface *interface)
00218 {
00219    uint_t i;
00220    uint32_t address;
00221 
00222    //Initialize TX buffer descriptors
00223    for(i = 0; i < AVR32_ETH_TX_BUFFER_COUNT; i++)
00224    {
00225       //Calculate the address of the current TX buffer
00226       address = (uint32_t) txBuffer[i];
00227       //Write the address to the descriptor entry
00228       txBufferDesc[i].address = address;
00229       //Initialize status field
00230       txBufferDesc[i].status = MACB_TX_USED;
00231    }
00232 
00233    //Mark the last descriptor entry with the wrap flag
00234    txBufferDesc[i - 1].status |= MACB_TX_WRAP;
00235    //Initialize TX buffer index
00236    txBufferIndex = 0;
00237 
00238    //Initialize RX buffer descriptors
00239    for(i = 0; i < AVR32_ETH_RX_BUFFER_COUNT; i++)
00240    {
00241       //Calculate the address of the current RX buffer
00242       address = (uint32_t) rxBuffer[i];
00243       //Write the address to the descriptor entry
00244       rxBufferDesc[i].address = address & MACB_RX_ADDRESS;
00245       //Clear status field
00246       rxBufferDesc[i].status = 0;
00247    }
00248 
00249    //Mark the last descriptor entry with the wrap flag
00250    rxBufferDesc[i - 1].address |= MACB_RX_WRAP;
00251    //Initialize RX buffer index
00252    rxBufferIndex = 0;
00253 
00254    //Start location of the TX descriptor list
00255    AVR32_MACB.tbqp = (uint32_t) txBufferDesc;
00256    //Start location of the RX descriptor list
00257    AVR32_MACB.rbqp = (uint32_t) rxBufferDesc;
00258 }
00259 
00260 
00261 /**
00262  * @brief AVR32 Ethernet MAC timer handler
00263  *
00264  * This routine is periodically called by the TCP/IP stack to
00265  * handle periodic operations such as polling the link state
00266  *
00267  * @param[in] interface Underlying network interface
00268  **/
00269 
00270 void avr32EthTick(NetInterface *interface)
00271 {
00272    //Handle periodic operations
00273    interface->phyDriver->tick(interface);
00274 }
00275 
00276 
00277 /**
00278  * @brief Enable interrupts
00279  * @param[in] interface Underlying network interface
00280  **/
00281 
00282 void avr32EthEnableIrq(NetInterface *interface)
00283 {
00284    //Enable Ethernet MAC interrupts
00285    Enable_global_interrupt();
00286    //Enable Ethernet PHY interrupts
00287    interface->phyDriver->enableIrq(interface);
00288 }
00289 
00290 
00291 /**
00292  * @brief Disable interrupts
00293  * @param[in] interface Underlying network interface
00294  **/
00295 
00296 void avr32EthDisableIrq(NetInterface *interface)
00297 {
00298    //Disable Ethernet MAC interrupts
00299    Disable_global_interrupt();
00300    //Disable Ethernet PHY interrupts
00301    interface->phyDriver->disableIrq(interface);
00302 }
00303 
00304 
00305 /**
00306  * @brief AVR32 Ethernet MAC interrupt wrapper
00307  **/
00308 
00309 __attribute__((naked)) void avr32EthIrqWrapper(void)
00310 {
00311    //Enter interrupt service routine
00312    osEnterIsr();
00313 
00314    //Call Ethernet MAC interrupt handler
00315    avr32EthIrqHandler();
00316 
00317    //Leave interrupt service routine
00318    osExitIsr(flag);
00319 }
00320 
00321 
00322 /**
00323  * @brief AVR32 Ethernet MAC interrupt service routine
00324  * @return TRUE if a higher priority task must be woken. Else FALSE is returned
00325  **/
00326 
00327 bool_t avr32EthIrqHandler(void)
00328 {
00329    bool_t flag;
00330    volatile uint32_t isr;
00331    volatile uint32_t tsr;
00332    volatile uint32_t rsr;
00333 
00334    //This flag will be set if a higher priority task must be woken
00335    flag = FALSE;
00336 
00337    //Each time the software reads EMAC_ISR, it has to check the
00338    //contents of EMAC_TSR, EMAC_RSR and EMAC_NSR
00339    isr = AVR32_MACB.isr;
00340    tsr = AVR32_MACB.tsr;
00341    rsr = AVR32_MACB.rsr;
00342 
00343    //A packet has been transmitted?
00344    if(tsr & (AVR32_MACB_TSR_UND_MASK | AVR32_MACB_TSR_COMP_MASK | AVR32_MACB_TSR_BEX_MASK |
00345       AVR32_MACB_TSR_TGO_MASK | AVR32_MACB_TSR_RLE_MASK | AVR32_MACB_TSR_COL_MASK | AVR32_MACB_TSR_UBR_MASK))
00346    {
00347       //Only clear TSR flags that are currently set
00348       AVR32_MACB.tsr = tsr;
00349 
00350       //Check whether the TX buffer is available for writing
00351       if(txBufferDesc[txBufferIndex].status & MACB_TX_USED)
00352       {
00353          //Notify the TCP/IP stack that the transmitter is ready to send
00354          flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
00355       }
00356    }
00357 
00358    //A packet has been received?
00359    if(rsr & (AVR32_MACB_RSR_OVR_MASK | AVR32_MACB_RSR_REC_MASK | AVR32_MACB_RSR_BNA_MASK))
00360    {
00361       //Set event flag
00362       nicDriverInterface->nicEvent = TRUE;
00363       //Notify the TCP/IP stack of the event
00364       flag |= osSetEventFromIsr(&netEvent);
00365    }
00366 
00367    //A higher priority task must be woken?
00368    return flag;
00369 }
00370 
00371 
00372 /**
00373  * @brief AVR32 Ethernet MAC event handler
00374  * @param[in] interface Underlying network interface
00375  **/
00376 
00377 void avr32EthEventHandler(NetInterface *interface)
00378 {
00379    error_t error;
00380    uint32_t rsr;
00381 
00382    //Read receive status
00383    rsr = AVR32_MACB.rsr;
00384 
00385    //Packet received?
00386    if(rsr & (AVR32_MACB_RSR_OVR_MASK | AVR32_MACB_RSR_REC_MASK | AVR32_MACB_RSR_BNA_MASK))
00387    {
00388       //Only clear RSR flags that are currently set
00389       AVR32_MACB.rsr = rsr;
00390 
00391       //Process all pending packets
00392       do
00393       {
00394          //Read incoming packet
00395          error = avr32EthReceivePacket(interface);
00396 
00397          //No more data in the receive buffer?
00398       } while(error != ERROR_BUFFER_EMPTY);
00399    }
00400 }
00401 
00402 
00403 /**
00404  * @brief Send a packet
00405  * @param[in] interface Underlying network interface
00406  * @param[in] buffer Multi-part buffer containing the data to send
00407  * @param[in] offset Offset to the first data byte
00408  * @return Error code
00409  **/
00410 
00411 error_t avr32EthSendPacket(NetInterface *interface,
00412    const NetBuffer *buffer, size_t offset)
00413 {
00414    size_t length;
00415 
00416    //Retrieve the length of the packet
00417    length = netBufferGetLength(buffer) - offset;
00418 
00419    //Check the frame length
00420    if(length > AVR32_ETH_TX_BUFFER_SIZE)
00421    {
00422       //The transmitter can accept another packet
00423       osSetEvent(&interface->nicTxEvent);
00424       //Report an error
00425       return ERROR_INVALID_LENGTH;
00426    }
00427 
00428    //Make sure the current buffer is available for writing
00429    if(!(txBufferDesc[txBufferIndex].status & MACB_TX_USED))
00430       return ERROR_FAILURE;
00431 
00432    //Copy user data to the transmit buffer
00433    netBufferRead(txBuffer[txBufferIndex], buffer, offset, length);
00434 
00435    //Set the necessary flags in the descriptor entry
00436    if(txBufferIndex < (AVR32_ETH_TX_BUFFER_COUNT - 1))
00437    {
00438       //Write the status word
00439       txBufferDesc[txBufferIndex].status =
00440          MACB_TX_LAST | (length & MACB_TX_LENGTH);
00441 
00442       //Point to the next buffer
00443       txBufferIndex++;
00444    }
00445    else
00446    {
00447       //Write the status word
00448       txBufferDesc[txBufferIndex].status = MACB_TX_WRAP |
00449          MACB_TX_LAST | (length & MACB_TX_LENGTH);
00450 
00451       //Wrap around
00452       txBufferIndex = 0;
00453    }
00454 
00455    //Set the TSTART bit to initiate transmission
00456    AVR32_MACB.ncr |= AVR32_MACB_NCR_TSTART_MASK;
00457 
00458    //Check whether the next buffer is available for writing
00459    if(txBufferDesc[txBufferIndex].status & MACB_TX_USED)
00460    {
00461       //The transmitter can accept another packet
00462       osSetEvent(&interface->nicTxEvent);
00463    }
00464 
00465    //Successful processing
00466    return NO_ERROR;
00467 }
00468 
00469 
00470 /**
00471  * @brief Receive a packet
00472  * @param[in] interface Underlying network interface
00473  * @return Error code
00474  **/
00475 
00476 uint_t avr32EthReceivePacket(NetInterface *interface)
00477 {
00478    static uint8_t temp[ETH_MAX_FRAME_SIZE];
00479    error_t error;
00480    uint_t i;
00481    uint_t j;
00482    uint_t sofIndex;
00483    uint_t eofIndex;
00484    size_t n;
00485    size_t size;
00486    size_t length;
00487 
00488    //Initialize SOF and EOF indices
00489    sofIndex = UINT_MAX;
00490    eofIndex = UINT_MAX;
00491 
00492    //Search for SOF and EOF flags
00493    for(i = 0; i < AVR32_ETH_RX_BUFFER_COUNT; i++)
00494    {
00495       //Point to the current entry
00496       j = rxBufferIndex + i;
00497 
00498       //Wrap around to the beginning of the buffer if necessary
00499       if(j >= AVR32_ETH_RX_BUFFER_COUNT)
00500          j -= AVR32_ETH_RX_BUFFER_COUNT;
00501 
00502       //No more entries to process?
00503       if(!(rxBufferDesc[j].address & MACB_RX_OWNERSHIP))
00504       {
00505          //Stop processing
00506          break;
00507       }
00508       //A valid SOF has been found?
00509       if(rxBufferDesc[j].status & MACB_RX_SOF)
00510       {
00511          //Save the position of the SOF
00512          sofIndex = i;
00513       }
00514       //A valid EOF has been found?
00515       if((rxBufferDesc[j].status & MACB_RX_EOF) && sofIndex != UINT_MAX)
00516       {
00517          //Save the position of the EOF
00518          eofIndex = i;
00519          //Retrieve the length of the frame
00520          size = rxBufferDesc[j].status & MACB_RX_LENGTH;
00521          //Limit the number of data to read
00522          size = MIN(size, ETH_MAX_FRAME_SIZE);
00523          //Stop processing since we have reached the end of the frame
00524          break;
00525       }
00526    }
00527 
00528    //Determine the number of entries to process
00529    if(eofIndex != UINT_MAX)
00530       j = eofIndex + 1;
00531    else if(sofIndex != UINT_MAX)
00532       j = sofIndex;
00533    else
00534       j = i;
00535 
00536    //Total number of bytes that have been copied from the receive buffer
00537    length = 0;
00538 
00539    //Process incoming frame
00540    for(i = 0; i < j; i++)
00541    {
00542       //Any data to copy from current buffer?
00543       if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
00544       {
00545          //Calculate the number of bytes to read at a time
00546          n = MIN(size, AVR32_ETH_RX_BUFFER_SIZE);
00547          //Copy data from receive buffer
00548          memcpy(temp + length, rxBuffer[rxBufferIndex], n);
00549          //Update byte counters
00550          length += n;
00551          size -= n;
00552       }
00553 
00554       //Mark the current buffer as free
00555       rxBufferDesc[rxBufferIndex].address &= ~MACB_RX_OWNERSHIP;
00556 
00557       //Point to the following entry
00558       rxBufferIndex++;
00559 
00560       //Wrap around to the beginning of the buffer if necessary
00561       if(rxBufferIndex >= AVR32_ETH_RX_BUFFER_COUNT)
00562          rxBufferIndex = 0;
00563    }
00564 
00565    //Any packet to process?
00566    if(length > 0)
00567    {
00568       //Pass the packet to the upper layer
00569       nicProcessPacket(interface, temp, length);
00570       //Valid packet received
00571       error = NO_ERROR;
00572    }
00573    else
00574    {
00575       //No more data in the receive buffer
00576       error = ERROR_BUFFER_EMPTY;
00577    }
00578 
00579    //Return status code
00580    return error;
00581 }
00582 
00583 
00584 /**
00585  * @brief Configure multicast MAC address filtering
00586  * @param[in] interface Underlying network interface
00587  * @return Error code
00588  **/
00589 
00590 error_t avr32EthSetMulticastFilter(NetInterface *interface)
00591 {
00592    uint_t i;
00593    uint_t k;
00594    uint8_t *p;
00595    uint32_t hashTable[2];
00596    MacFilterEntry *entry;
00597 
00598    //Debug message
00599    TRACE_DEBUG("Updating AVR32 hash table...\r\n");
00600 
00601    //Clear hash table
00602    hashTable[0] = 0;
00603    hashTable[1] = 0;
00604 
00605    //The MAC filter table contains the multicast MAC addresses
00606    //to accept when receiving an Ethernet frame
00607    for(i = 0; i < MAC_MULTICAST_FILTER_SIZE; i++)
00608    {
00609       //Point to the current entry
00610       entry = &interface->macMulticastFilter[i];
00611 
00612       //Valid entry?
00613       if(entry->refCount > 0)
00614       {
00615          //Point to the MAC address
00616          p = entry->addr.b;
00617 
00618          //Apply the hash function
00619          k = (p[0] >> 6) ^ p[0];
00620          k ^= (p[1] >> 4) ^ (p[1] << 2);
00621          k ^= (p[2] >> 2) ^ (p[2] << 4);
00622          k ^= (p[3] >> 6) ^ p[3];
00623          k ^= (p[4] >> 4) ^ (p[4] << 2);
00624          k ^= (p[5] >> 2) ^ (p[5] << 4);
00625 
00626          //The hash value is reduced to a 6-bit index
00627          k &= 0x3F;
00628 
00629          //Update hash table contents
00630          hashTable[k / 32] |= (1 << (k % 32));
00631       }
00632    }
00633 
00634    //Write the hash table
00635    AVR32_MACB.hrb = hashTable[0];
00636    AVR32_MACB.hrt = hashTable[1];
00637 
00638    //Debug message
00639    TRACE_DEBUG("  HRB = %08" PRIX32 "\r\n", AVR32_MACB.hrb);
00640    TRACE_DEBUG("  HRT = %08" PRIX32 "\r\n", AVR32_MACB.hrt);
00641 
00642    //Successful processing
00643    return NO_ERROR;
00644 }
00645 
00646 
00647 /**
00648  * @brief Adjust MAC configuration parameters for proper operation
00649  * @param[in] interface Underlying network interface
00650  * @return Error code
00651  **/
00652 
00653 error_t avr32EthUpdateMacConfig(NetInterface *interface)
00654 {
00655    uint32_t config;
00656 
00657    //Read network configuration register
00658    config = AVR32_MACB.ncfgr;
00659 
00660    //10BASE-T or 100BASE-TX operation mode?
00661    if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
00662       config |= AVR32_MACB_NCFGR_SPD_MASK;
00663    else
00664       config &= ~AVR32_MACB_NCFGR_SPD_MASK;
00665 
00666    //Half-duplex or full-duplex mode?
00667    if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
00668       config |= AVR32_MACB_NCFGR_FD_MASK;
00669    else
00670       config &= ~AVR32_MACB_NCFGR_FD_MASK;
00671 
00672    //Write configuration value back to NCFGR register
00673    AVR32_MACB.ncfgr = config;
00674 
00675    //Successful processing
00676    return NO_ERROR;
00677 }
00678 
00679 
00680 /**
00681  * @brief Write PHY register
00682  * @param[in] phyAddr PHY address
00683  * @param[in] regAddr Register address
00684  * @param[in] data Register value
00685  **/
00686 
00687 void avr32EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
00688 {
00689    uint32_t value;
00690 
00691    //Set up a write operation
00692    value = MACB_MAN_SOF_01 | MACB_MAN_RW_01 | MACB_MAN_CODE_10;
00693    //PHY address
00694    value |= (phyAddr << AVR32_MACB_MAN_PHYA_OFFSET) & AVR32_MACB_MAN_PHYA_MASK;
00695    //Register address
00696    value |= (regAddr << AVR32_MACB_MAN_REGA_OFFSET) & AVR32_MACB_MAN_REGA_MASK;
00697    //Register value
00698    value |= data & AVR32_MACB_MAN_DATA_MASK;
00699 
00700    //Start a write operation
00701    AVR32_MACB.man = value;
00702    //Wait for the write to complete
00703    while(!(AVR32_MACB.nsr & AVR32_MACB_NSR_IDLE_MASK));
00704 }
00705 
00706 
00707 /**
00708  * @brief Read PHY register
00709  * @param[in] phyAddr PHY address
00710  * @param[in] regAddr Register address
00711  * @return Register value
00712  **/
00713 
00714 uint16_t avr32EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
00715 {
00716    uint32_t value;
00717 
00718    //Set up a read operation
00719    value = MACB_MAN_SOF_01 | MACB_MAN_RW_10 | MACB_MAN_CODE_10;
00720    //PHY address
00721    value |= (phyAddr << AVR32_MACB_MAN_PHYA_OFFSET) & AVR32_MACB_MAN_PHYA_MASK;
00722    //Register address
00723    value |= (regAddr << AVR32_MACB_MAN_REGA_OFFSET) & AVR32_MACB_MAN_REGA_MASK;
00724 
00725    //Start a read operation
00726    AVR32_MACB.man = value;
00727    //Wait for the read to complete
00728    while(!(AVR32_MACB.nsr & AVR32_MACB_NSR_IDLE_MASK));
00729 
00730    //Return PHY register contents
00731    return AVR32_MACB.man & AVR32_MACB_MAN_DATA_MASK;
00732 }
00733