32 #define TRACE_LEVEL NIC_TRACE_LEVEL
37 #include "peripherals/aic.h"
38 #include "peripherals/pio.h"
47 #if defined(__ICCARM__)
50 #pragma data_alignment = 8
51 #pragma location = SAMA5D2_ETH_RAM_SECTION
54 #pragma data_alignment = 8
55 #pragma location = SAMA5D2_ETH_RAM_SECTION
58 #pragma data_alignment = 4
59 #pragma location = SAMA5D2_ETH_RAM_SECTION
62 #pragma data_alignment = 4
63 #pragma location = SAMA5D2_ETH_RAM_SECTION
67 #pragma data_alignment = 8
68 #pragma location = SAMA5D2_ETH_RAM_SECTION
71 #pragma data_alignment = 8
72 #pragma location = SAMA5D2_ETH_RAM_SECTION
75 #pragma data_alignment = 4
76 #pragma location = SAMA5D2_ETH_RAM_SECTION
79 #pragma data_alignment = 4
80 #pragma location = SAMA5D2_ETH_RAM_SECTION
115 static uint_t txBufferIndex;
117 static uint_t rxBufferIndex;
154 volatile uint32_t status;
157 TRACE_INFO(
"Initializing SAMA5D2 Ethernet MAC...\r\n");
160 nicDriverInterface = interface;
163 PMC->PMC_PCER0 = (1 << ID_GMAC0);
172 GMAC0->GMAC_NCFGR = GMAC_NCFGR_CLK_MCK_96;
174 GMAC0->GMAC_NCR |= GMAC_NCR_MPE;
177 if(interface->phyDriver != NULL)
180 error = interface->phyDriver->init(interface);
182 else if(interface->switchDriver != NULL)
185 error = interface->switchDriver->init(interface);
200 GMAC0->GMAC_SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
201 GMAC0->GMAC_SA[0].GMAC_SAT = interface->macAddr.w[2];
204 GMAC0->GMAC_SA[1].GMAC_SAB = 0;
205 GMAC0->GMAC_SA[2].GMAC_SAB = 0;
206 GMAC0->GMAC_SA[3].GMAC_SAB = 0;
213 GMAC0->GMAC_NCFGR |= GMAC_NCFGR_MAXFS | GMAC_NCFGR_MTIHEN;
217 GMAC_DCFGR_TXPBMS | GMAC_DCFGR_RXBMS_FULL | GMAC_DCFGR_FBLDO_INCR4;
226 GMAC0->GMAC_TSR = GMAC_TSR_HRESP | GMAC_TSR_TXCOMP | GMAC_TSR_TFC |
227 GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR;
230 GMAC0->GMAC_RSR = GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC |
234 GMAC0->GMAC_IDR = 0xFFFFFFFF;
235 GMAC0->GMAC_IDRPQ[0] = 0xFFFFFFFF;
236 GMAC0->GMAC_IDRPQ[1] = 0xFFFFFFFF;
239 GMAC0->GMAC_IER = GMAC_IER_HRESP | GMAC_IER_ROVR | GMAC_IER_TCOMP |
240 GMAC_IER_TFC | GMAC_IER_RLEX | GMAC_IER_TUR | GMAC_IER_RXUBR |
244 status = GMAC0->GMAC_ISR;
245 status = GMAC0->GMAC_ISRPQ[0];
246 status = GMAC0->GMAC_ISRPQ[1];
253 aic_configure(ID_GMAC0, AIC_SMR_SRCTYPE_INT_LEVEL_SENSITIVE |
257 GMAC0->GMAC_NCR |= GMAC_NCR_TXEN | GMAC_NCR_RXEN;
275 #if defined(CONFIG_BOARD_SAMA5D2_XPLAINED)
276 struct _pin rmiiPins[] = PINS_GMAC_RMII_IOS3;
279 pio_configure(rmiiPins,
arraysize(rmiiPins));
282 GMAC0->GMAC_UR = GMAC_UR_RMII;
321 rxBufferDesc[i].
status = 0;
333 address = (uint32_t) dummyTxBuffer[i];
347 address = (uint32_t) dummyRxBuffer[i];
351 dummyRxBufferDesc[i].
status = 0;
358 GMAC0->GMAC_TBQB = (uint32_t) txBufferDesc;
359 GMAC0->GMAC_TBQBAPQ[0] = (uint32_t) dummyTxBufferDesc;
360 GMAC0->GMAC_TBQBAPQ[1] = (uint32_t) dummyTxBufferDesc;
363 GMAC0->GMAC_RBQB = (uint32_t) rxBufferDesc;
364 GMAC0->GMAC_RBQBAPQ[0] = (uint32_t) dummyRxBufferDesc;
365 GMAC0->GMAC_RBQBAPQ[1] = (uint32_t) dummyRxBufferDesc;
381 if(interface->phyDriver != NULL)
384 interface->phyDriver->tick(interface);
386 else if(interface->switchDriver != NULL)
389 interface->switchDriver->tick(interface);
406 aic_enable(ID_GMAC0);
409 if(interface->phyDriver != NULL)
412 interface->phyDriver->enableIrq(interface);
414 else if(interface->switchDriver != NULL)
417 interface->switchDriver->enableIrq(interface);
434 aic_disable(ID_GMAC0);
437 if(interface->phyDriver != NULL)
440 interface->phyDriver->disableIrq(interface);
442 else if(interface->switchDriver != NULL)
445 interface->switchDriver->disableIrq(interface);
461 volatile uint32_t isr;
462 volatile uint32_t tsr;
463 volatile uint32_t rsr;
473 isr = GMAC0->GMAC_ISRPQ[0];
474 isr = GMAC0->GMAC_ISRPQ[1];
475 isr = GMAC0->GMAC_ISR;
476 tsr = GMAC0->GMAC_TSR;
477 rsr = GMAC0->GMAC_RSR;
481 if((tsr & (GMAC_TSR_HRESP | GMAC_TSR_TXCOMP | GMAC_TSR_TFC |
482 GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR)) != 0)
485 GMAC0->GMAC_TSR = tsr;
488 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) != 0)
496 if((rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA)) != 0)
499 nicDriverInterface->nicEvent =
TRUE;
523 rsr = GMAC0->GMAC_RSR;
526 if((rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA)) != 0)
529 GMAC0->GMAC_RSR = rsr;
571 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) == 0)
603 GMAC0->GMAC_NCR |= GMAC_NCR_TSTART;
606 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) != 0)
644 j = rxBufferIndex + i;
667 if((rxBufferDesc[j].status &
GMAC_RX_EOF) != 0 && sofIndex != UINT_MAX)
681 if(eofIndex != UINT_MAX)
685 else if(sofIndex != UINT_MAX)
698 for(i = 0; i < j; i++)
701 if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
761 uint32_t hashTable[2];
769 GMAC0->GMAC_SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
770 GMAC0->GMAC_SA[0].GMAC_SAT = interface->macAddr.w[2];
786 entry = &interface->macAddrFilter[i];
798 k = (
p[0] >> 6) ^
p[0];
799 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
800 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
801 k ^= (
p[3] >> 6) ^
p[3];
802 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
803 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
809 hashTable[k / 32] |= (1 << (k % 32));
817 unicastMacAddr[j++] = entry->
addr;
827 GMAC0->GMAC_SA[1].GMAC_SAB = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
828 GMAC0->GMAC_SA[1].GMAC_SAT = unicastMacAddr[0].w[2];
833 GMAC0->GMAC_SA[1].GMAC_SAB = 0;
840 GMAC0->GMAC_SA[2].GMAC_SAB = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
841 GMAC0->GMAC_SA[2].GMAC_SAT = unicastMacAddr[1].w[2];
846 GMAC0->GMAC_SA[2].GMAC_SAB = 0;
853 GMAC0->GMAC_SA[3].GMAC_SAB = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
854 GMAC0->GMAC_SA[3].GMAC_SAT = unicastMacAddr[2].w[2];
859 GMAC0->GMAC_SA[3].GMAC_SAB = 0;
863 GMAC0->GMAC_HRB = hashTable[0];
864 GMAC0->GMAC_HRT = hashTable[1];
867 TRACE_DEBUG(
" HRB = %08" PRIX32
"\r\n", GMAC0->GMAC_HRB);
868 TRACE_DEBUG(
" HRT = %08" PRIX32
"\r\n", GMAC0->GMAC_HRT);
886 config = GMAC0->GMAC_NCFGR;
891 config |= GMAC_NCFGR_SPD;
895 config &= ~GMAC_NCFGR_SPD;
901 config |= GMAC_NCFGR_FD;
905 config &= ~GMAC_NCFGR_FD;
909 GMAC0->GMAC_NCFGR = config;
933 temp = GMAC_MAN_CLTTO | GMAC_MAN_OP(1) | GMAC_MAN_WTN(2);
935 temp |= GMAC_MAN_PHYA(phyAddr);
937 temp |= GMAC_MAN_REGA(
regAddr);
939 temp |= GMAC_MAN_DATA(
data);
942 GMAC0->GMAC_MAN = temp;
944 while((GMAC0->GMAC_NSR & GMAC_NSR_IDLE) == 0)
973 temp = GMAC_MAN_CLTTO | GMAC_MAN_OP(2) | GMAC_MAN_WTN(2);
975 temp |= GMAC_MAN_PHYA(phyAddr);
977 temp |= GMAC_MAN_REGA(
regAddr);
980 GMAC0->GMAC_MAN = temp;
982 while((GMAC0->GMAC_NSR & GMAC_NSR_IDLE) == 0)
987 data = GMAC0->GMAC_MAN & GMAC_MAN_DATA_Msk;
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
@ ERROR_FAILURE
Generic error code.
const MacAddr MAC_UNSPECIFIED_ADDR
#define macIsMulticastAddr(macAddr)
#define ETH_MAX_FRAME_SIZE
#define MAC_ADDR_FILTER_SIZE
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
size_t netBufferRead(void *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Read data from a multi-part buffer.
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
@ NIC_TYPE_ETHERNET
Ethernet interface.
#define osMemcpy(dest, src, length)
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define GMAC_RX_OWNERSHIP
error_t sama5d2EthInit(NetInterface *interface)
SAMA5D2 Ethernet MAC initialization.
void sama5d2EthDisableIrq(NetInterface *interface)
Disable interrupts.
error_t sama5d2EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
error_t sama5d2EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
uint16_t sama5d2EthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
void sama5d2EthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
const NicDriver sama5d2EthDriver
SAMA5D2 Ethernet MAC driver.
void sama5d2EthEnableIrq(NetInterface *interface)
Enable interrupts.
void sama5d2EthEventHandler(NetInterface *interface)
SAMA5D2 Ethernet MAC event handler.
error_t sama5d2EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
__weak_func void sama5d2EthInitGpio(NetInterface *interface)
GPIO configuration.
error_t sama5d2EthReceivePacket(NetInterface *interface)
Receive a packet.
void sama5d2EthInitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
void sama5d2EthIrqHandler(void)
SAMA5D2 Ethernet MAC interrupt service routine.
void sama5d2EthTick(NetInterface *interface)
SAMA5D2 Ethernet MAC timer handler.
SAMA5D2 Ethernet MAC driver.
#define SAMA5D2_ETH_RX_BUFFER_SIZE
#define SAMA5D2_ETH_IRQ_PRIORITY
#define SAMA5D2_ETH_DUMMY_BUFFER_COUNT
#define SAMA5D2_ETH_RAM_SECTION
#define SAMA5D2_ETH_TX_BUFFER_SIZE
#define SAMA5D2_ETH_TX_BUFFER_COUNT
#define SAMA5D2_ETH_RX_BUFFER_COUNT
#define SAMA5D2_ETH_DUMMY_BUFFER_SIZE
uint_t refCount
Reference count for the current entry.
Structure describing a buffer that spans multiple chunks.
Receive buffer descriptor.
Transmit buffer descriptor.