32 #define TRACE_LEVEL NIC_TRACE_LEVEL
45 #if defined(__ICCARM__)
48 #pragma data_alignment = 8
49 #pragma location = SAMA5D3_ETH1_RAM_SECTION
52 #pragma data_alignment = 8
53 #pragma location = SAMA5D3_ETH1_RAM_SECTION
56 #pragma data_alignment = 8
57 #pragma location = SAMA5D3_ETH1_RAM_SECTION
60 #pragma data_alignment = 8
61 #pragma location = SAMA5D3_ETH1_RAM_SECTION
83 static uint_t txBufferIndex;
85 static uint_t rxBufferIndex;
122 volatile uint32_t status;
125 TRACE_INFO(
"Initializing SAMA5D3 Ethernet MAC (EMAC)...\r\n");
128 nicDriverInterface = interface;
131 PMC->PMC_PCER1 = (1 << (ID_EMAC - 32));
133 PMC->PMC_PCER1 = (1 << (ID_IRQ - 32));
142 EMAC->EMAC_NCFGR = EMAC_NCFGR_CLK_MCK_64;
144 EMAC->EMAC_NCR |= EMAC_NCR_MPE;
147 if(interface->phyDriver != NULL)
150 error = interface->phyDriver->init(interface);
152 else if(interface->switchDriver != NULL)
155 error = interface->switchDriver->init(interface);
170 EMAC->EMAC_SA[0].EMAC_SAxB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
171 EMAC->EMAC_SA[0].EMAC_SAxT = interface->macAddr.w[2];
174 EMAC->EMAC_SA[1].EMAC_SAxB = 0;
175 EMAC->EMAC_SA[2].EMAC_SAxB = 0;
176 EMAC->EMAC_SA[3].EMAC_SAxB = 0;
183 EMAC->EMAC_NCFGR |= EMAC_NCFGR_BIG | EMAC_NCFGR_MTI;
189 EMAC->EMAC_TSR = EMAC_TSR_UND | EMAC_TSR_COMP | EMAC_TSR_BEX |
190 EMAC_TSR_TGO | EMAC_TSR_RLES | EMAC_TSR_COL | EMAC_TSR_UBR;
193 EMAC->EMAC_RSR = EMAC_RSR_OVR | EMAC_RSR_REC | EMAC_RSR_BNA;
196 EMAC->EMAC_IDR = 0xFFFFFFFF;
199 EMAC->EMAC_IER = EMAC_IER_ROVR | EMAC_IER_TCOMP | EMAC_IER_TXERR |
200 EMAC_IER_RLE | EMAC_IER_TUND | EMAC_IER_RXUBR | EMAC_IER_RCOMP;
203 status = EMAC->EMAC_ISR;
207 AIC->AIC_SSR = ID_EMAC;
212 EMAC->EMAC_NCR |= EMAC_NCR_TE | EMAC_NCR_RE;
230 #if defined(USE_SAMA5D3_XPLAINED) || defined(USE_SAMA5D3_EDS)
232 PMC->PMC_PCER0 = (1 << ID_PIOC);
245 EMAC->EMAC_USRIO = EMAC_USRIO_CLKEN | EMAC_USRIO_RMII;
284 rxBufferDesc[i].
status = 0;
293 EMAC->EMAC_TBQP = (uint32_t) txBufferDesc;
295 EMAC->EMAC_RBQP = (uint32_t) rxBufferDesc;
311 if(interface->phyDriver != NULL)
314 interface->phyDriver->tick(interface);
316 else if(interface->switchDriver != NULL)
319 interface->switchDriver->tick(interface);
336 AIC->AIC_SSR = ID_EMAC;
337 AIC->AIC_IECR = AIC_IECR_INTEN;
340 if(interface->phyDriver != NULL)
343 interface->phyDriver->enableIrq(interface);
345 else if(interface->switchDriver != NULL)
348 interface->switchDriver->enableIrq(interface);
365 AIC->AIC_SSR = ID_EMAC;
366 AIC->AIC_IDCR = AIC_IDCR_INTD;
369 if(interface->phyDriver != NULL)
372 interface->phyDriver->disableIrq(interface);
374 else if(interface->switchDriver != NULL)
377 interface->switchDriver->disableIrq(interface);
393 volatile uint32_t isr;
394 volatile uint32_t tsr;
395 volatile uint32_t rsr;
405 isr = EMAC->EMAC_ISR;
406 tsr = EMAC->EMAC_TSR;
407 rsr = EMAC->EMAC_RSR;
411 if((tsr & (EMAC_TSR_UND | EMAC_TSR_COMP | EMAC_TSR_BEX |
412 EMAC_TSR_TGO | EMAC_TSR_RLES | EMAC_TSR_COL | EMAC_TSR_UBR)) != 0)
415 EMAC->EMAC_TSR = tsr;
418 if((txBufferDesc[txBufferIndex].status &
EMAC_TX_USED) != 0)
426 if((rsr & (EMAC_RSR_OVR | EMAC_RSR_REC | EMAC_RSR_BNA)) != 0)
429 nicDriverInterface->nicEvent =
TRUE;
453 rsr = EMAC->EMAC_RSR;
456 if((rsr & (EMAC_RSR_OVR | EMAC_RSR_REC | EMAC_RSR_BNA)) != 0)
459 EMAC->EMAC_RSR = rsr;
501 if((txBufferDesc[txBufferIndex].status &
EMAC_TX_USED) == 0)
530 EMAC->EMAC_NCR |= EMAC_NCR_TSTART;
533 if((txBufferDesc[txBufferIndex].status &
EMAC_TX_USED) != 0)
571 j = rxBufferIndex + i;
594 if((rxBufferDesc[j].status &
EMAC_RX_EOF) != 0 && sofIndex != UINT_MAX)
608 if(eofIndex != UINT_MAX)
612 else if(sofIndex != UINT_MAX)
625 for(i = 0; i < j; i++)
628 if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
688 uint32_t hashTable[2];
696 EMAC->EMAC_SA[0].EMAC_SAxB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
697 EMAC->EMAC_SA[0].EMAC_SAxT = interface->macAddr.w[2];
713 entry = &interface->macAddrFilter[i];
725 k = (
p[0] >> 6) ^
p[0];
726 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
727 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
728 k ^= (
p[3] >> 6) ^
p[3];
729 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
730 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
736 hashTable[k / 32] |= (1 << (k % 32));
744 unicastMacAddr[j] = entry->
addr;
752 k = (
p[0] >> 6) ^
p[0];
753 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
754 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
755 k ^= (
p[3] >> 6) ^
p[3];
756 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
757 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
763 hashTable[k / 32] |= (1 << (k % 32));
776 EMAC->EMAC_SA[1].EMAC_SAxB = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
777 EMAC->EMAC_SA[1].EMAC_SAxT = unicastMacAddr[0].w[2];
782 EMAC->EMAC_SA[1].EMAC_SAxB = 0;
789 EMAC->EMAC_SA[2].EMAC_SAxB = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
790 EMAC->EMAC_SA[2].EMAC_SAxT = unicastMacAddr[1].w[2];
795 EMAC->EMAC_SA[2].EMAC_SAxB = 0;
802 EMAC->EMAC_SA[3].EMAC_SAxB = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
803 EMAC->EMAC_SA[3].EMAC_SAxT = unicastMacAddr[2].w[2];
808 EMAC->EMAC_SA[3].EMAC_SAxB = 0;
814 EMAC->EMAC_NCFGR |= EMAC_NCFGR_UNI;
818 EMAC->EMAC_NCFGR &= ~EMAC_NCFGR_UNI;
822 EMAC->EMAC_HRB = hashTable[0];
823 EMAC->EMAC_HRT = hashTable[1];
826 TRACE_DEBUG(
" HRB = %08" PRIX32
"\r\n", EMAC->EMAC_HRB);
827 TRACE_DEBUG(
" HRT = %08" PRIX32
"\r\n", EMAC->EMAC_HRT);
845 config = EMAC->EMAC_NCFGR;
850 config |= EMAC_NCFGR_SPD;
854 config &= ~EMAC_NCFGR_SPD;
860 config |= EMAC_NCFGR_FD;
864 config &= ~EMAC_NCFGR_FD;
868 EMAC->EMAC_NCFGR = config;
892 temp = EMAC_MAN_SOF(1) | EMAC_MAN_RW(1) | EMAC_MAN_CODE(2);
894 temp |= EMAC_MAN_PHYA(phyAddr);
896 temp |= EMAC_MAN_REGA(
regAddr);
898 temp |= EMAC_MAN_DATA(
data);
901 EMAC->EMAC_MAN = temp;
903 while((EMAC->EMAC_NSR & EMAC_NSR_IDLE) == 0)
932 temp = EMAC_MAN_SOF(1) | EMAC_MAN_RW(2) | EMAC_MAN_CODE(2);
934 temp |= EMAC_MAN_PHYA(phyAddr);
936 temp |= EMAC_MAN_REGA(
regAddr);
939 EMAC->EMAC_MAN = temp;
941 while((EMAC->EMAC_NSR & EMAC_NSR_IDLE) == 0)
946 data = EMAC->EMAC_MAN & EMAC_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 EMAC_RX_OWNERSHIP
error_t sama5d3Eth1UpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
error_t sama5d3Eth1Init(NetInterface *interface)
SAMA5D3 Ethernet MAC initialization.
const NicDriver sama5d3Eth1Driver
SAMA5D3 Ethernet MAC driver (EMAC instance)
void sama5d3Eth1EnableIrq(NetInterface *interface)
Enable interrupts.
__weak_func void sama5d3Eth1InitGpio(NetInterface *interface)
GPIO configuration.
void sama5d3Eth1EventHandler(NetInterface *interface)
SAMA5D3 Ethernet MAC event handler.
void sama5d3Eth1InitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
uint16_t sama5d3Eth1ReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
void sama5d3Eth1IrqHandler(void)
SAMA5D3 Ethernet MAC interrupt service routine.
void sama5d3Eth1Tick(NetInterface *interface)
SAMA5D3 Ethernet MAC timer handler.
void sama5d3Eth1DisableIrq(NetInterface *interface)
Disable interrupts.
error_t sama5d3Eth1SendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
error_t sama5d3Eth1UpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
void sama5d3Eth1WritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
error_t sama5d3Eth1ReceivePacket(NetInterface *interface)
Receive a packet.
SAMA5D3 Ethernet MAC driver (EMAC instance)
#define SAMA5D3_ETH1_RAM_SECTION
#define SAMA5D3_ETH1_RX_BUFFER_SIZE
#define SAMA5D3_ETH1_TX_BUFFER_SIZE
#define SAMA5D3_ETH1_IRQ_PRIORITY
#define SAMA5D3_ETH1_RX_BUFFER_COUNT
#define SAMA5D3_ETH1_TX_BUFFER_COUNT
uint_t refCount
Reference count for the current entry.
Structure describing a buffer that spans multiple chunks.
Receive buffer descriptor.
Transmit buffer descriptor.