32 #define TRACE_LEVEL NIC_TRACE_LEVEL
45 #if defined(__ICCARM__)
48 #pragma data_alignment = 8
49 #pragma location = SAMV71_ETH_RAM_SECTION
52 #pragma data_alignment = 8
53 #pragma location = SAMV71_ETH_RAM_SECTION
56 #pragma data_alignment = 4
57 #pragma location = SAMV71_ETH_RAM_SECTION
60 #pragma data_alignment = 4
61 #pragma location = SAMV71_ETH_RAM_SECTION
65 #pragma data_alignment = 8
66 #pragma location = SAMV71_ETH_RAM_SECTION
69 #pragma data_alignment = 8
70 #pragma location = SAMV71_ETH_RAM_SECTION
73 #pragma data_alignment = 4
74 #pragma location = SAMV71_ETH_RAM_SECTION
77 #pragma data_alignment = 4
78 #pragma location = SAMV71_ETH_RAM_SECTION
113 static uint_t txBufferIndex;
115 static uint_t rxBufferIndex;
152 volatile uint32_t status;
155 TRACE_INFO(
"Initializing SAMV71 Ethernet MAC...\r\n");
158 nicDriverInterface = interface;
161 PMC_REGS->PMC_PCER1 = (1 << (ID_GMAC - 32));
164 GMAC_REGS->GMAC_NCR = 0;
170 GMAC_REGS->GMAC_NCFGR = GMAC_NCFGR_CLK_MCK_96;
172 GMAC_REGS->GMAC_NCR |= GMAC_NCR_MPE_Msk;
175 if(interface->phyDriver != NULL)
178 error = interface->phyDriver->init(interface);
180 else if(interface->switchDriver != NULL)
183 error = interface->switchDriver->init(interface);
198 GMAC_REGS->GMAC_SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
199 GMAC_REGS->GMAC_SA[0].GMAC_SAT = interface->macAddr.w[2];
202 GMAC_REGS->GMAC_SA[1].GMAC_SAB = 0;
203 GMAC_REGS->GMAC_SA[2].GMAC_SAB = 0;
204 GMAC_REGS->GMAC_SA[3].GMAC_SAB = 0;
207 GMAC_REGS->GMAC_HRB = 0;
208 GMAC_REGS->GMAC_HRT = 0;
211 GMAC_REGS->GMAC_NCFGR |= GMAC_NCFGR_MAXFS_Msk | GMAC_NCFGR_MTIHEN_Msk;
215 GMAC_DCFGR_TXPBMS_Msk | GMAC_DCFGR_RXBMS_FULL | GMAC_DCFGR_FBLDO_INCR4;
227 GMAC_REGS->GMAC_TSR = GMAC_TSR_HRESP_Msk | GMAC_TSR_TXCOMP_Msk |
228 GMAC_TSR_TFC_Msk | GMAC_TSR_TXGO_Msk | GMAC_TSR_RLE_Msk |
229 GMAC_TSR_COL_Msk | GMAC_TSR_UBR_Msk;
232 GMAC_REGS->GMAC_RSR = GMAC_RSR_HNO_Msk | GMAC_RSR_RXOVR_Msk |
233 GMAC_RSR_REC_Msk | GMAC_RSR_BNA_Msk;
236 GMAC_REGS->GMAC_IDR = 0xFFFFFFFF;
237 GMAC_REGS->GMAC_IDRPQ[0] = 0xFFFFFFFF;
238 GMAC_REGS->GMAC_IDRPQ[1] = 0xFFFFFFFF;
239 GMAC_REGS->GMAC_IDRPQ[2] = 0xFFFFFFFF;
240 GMAC_REGS->GMAC_IDRPQ[3] = 0xFFFFFFFF;
241 GMAC_REGS->GMAC_IDRPQ[4] = 0xFFFFFFFF;
244 GMAC_REGS->GMAC_IER = GMAC_IER_HRESP_Msk | GMAC_IER_ROVR_Msk |
245 GMAC_IER_TCOMP_Msk | GMAC_IER_TFC_Msk | GMAC_IER_RLEX_Msk |
246 GMAC_IER_TUR_Msk | GMAC_IER_RXUBR_Msk | GMAC_IER_RCOMP_Msk;
249 status = GMAC_REGS->GMAC_ISR;
250 status = GMAC_REGS->GMAC_ISRPQ[0];
251 status = GMAC_REGS->GMAC_ISRPQ[1];
252 status = GMAC_REGS->GMAC_ISRPQ[2];
253 status = GMAC_REGS->GMAC_ISRPQ[3];
254 status = GMAC_REGS->GMAC_ISRPQ[4];
265 GMAC_REGS->GMAC_NCR |= GMAC_NCR_TXEN_Msk | GMAC_NCR_RXEN_Msk;
283 #if defined(USE_SAMV71_XPLAINED_ULTRA)
285 PMC_REGS->PMC_PCER0 = (1 << ID_PIOC) | (1 << ID_PIOD);
298 GMAC_REGS->GMAC_UR &= ~GMAC_UR_RMII_Msk;
301 PIOC_REGS->PIO_PER = PIO_PC10;
302 PIOC_REGS->PIO_OER = PIO_PC10;
305 PIOC_REGS->PIO_CODR = PIO_PC10;
307 PIOC_REGS->PIO_SODR = PIO_PC10;
347 rxBufferDesc[i].
status = 0;
359 address = (uint32_t) dummyTxBuffer[i];
373 address = (uint32_t) dummyRxBuffer[i];
377 dummyRxBufferDesc[i].
status = 0;
384 GMAC_REGS->GMAC_TBQB = (uint32_t) txBufferDesc;
385 GMAC_REGS->GMAC_TBQBAPQ[0] = (uint32_t) dummyTxBufferDesc;
386 GMAC_REGS->GMAC_TBQBAPQ[1] = (uint32_t) dummyTxBufferDesc;
387 GMAC_REGS->GMAC_TBQBAPQ[2] = (uint32_t) dummyTxBufferDesc;
388 GMAC_REGS->GMAC_TBQBAPQ[3] = (uint32_t) dummyTxBufferDesc;
389 GMAC_REGS->GMAC_TBQBAPQ[4] = (uint32_t) dummyTxBufferDesc;
392 GMAC_REGS->GMAC_RBQB = (uint32_t) rxBufferDesc;
393 GMAC_REGS->GMAC_RBQBAPQ[0] = (uint32_t) dummyRxBufferDesc;
394 GMAC_REGS->GMAC_RBQBAPQ[1] = (uint32_t) dummyRxBufferDesc;
395 GMAC_REGS->GMAC_RBQBAPQ[2] = (uint32_t) dummyRxBufferDesc;
396 GMAC_REGS->GMAC_RBQBAPQ[3] = (uint32_t) dummyRxBufferDesc;
397 GMAC_REGS->GMAC_RBQBAPQ[4] = (uint32_t) dummyRxBufferDesc;
413 if(interface->phyDriver != NULL)
416 interface->phyDriver->tick(interface);
418 else if(interface->switchDriver != NULL)
421 interface->switchDriver->tick(interface);
438 NVIC_EnableIRQ(GMAC_IRQn);
441 if(interface->phyDriver != NULL)
444 interface->phyDriver->enableIrq(interface);
446 else if(interface->switchDriver != NULL)
449 interface->switchDriver->enableIrq(interface);
466 NVIC_DisableIRQ(GMAC_IRQn);
469 if(interface->phyDriver != NULL)
472 interface->phyDriver->disableIrq(interface);
474 else if(interface->switchDriver != NULL)
477 interface->switchDriver->disableIrq(interface);
493 volatile uint32_t isr;
494 volatile uint32_t tsr;
495 volatile uint32_t rsr;
505 isr = GMAC_REGS->GMAC_ISRPQ[0];
506 isr = GMAC_REGS->GMAC_ISRPQ[1];
507 isr = GMAC_REGS->GMAC_ISRPQ[2];
508 isr = GMAC_REGS->GMAC_ISRPQ[3];
509 isr = GMAC_REGS->GMAC_ISRPQ[4];
510 isr = GMAC_REGS->GMAC_ISR;
511 tsr = GMAC_REGS->GMAC_TSR;
512 rsr = GMAC_REGS->GMAC_RSR;
516 if((tsr & (GMAC_TSR_HRESP_Msk | GMAC_TSR_TXCOMP_Msk |
517 GMAC_TSR_TFC_Msk | GMAC_TSR_TXGO_Msk | GMAC_TSR_RLE_Msk |
518 GMAC_TSR_COL_Msk | GMAC_TSR_UBR_Msk)) != 0)
521 GMAC_REGS->GMAC_TSR = tsr;
524 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) != 0)
532 if((rsr & (GMAC_RSR_HNO_Msk | GMAC_RSR_RXOVR_Msk | GMAC_RSR_REC_Msk |
533 GMAC_RSR_BNA_Msk)) != 0)
536 nicDriverInterface->nicEvent =
TRUE;
557 rsr = GMAC_REGS->GMAC_RSR;
560 if((rsr & (GMAC_RSR_HNO_Msk | GMAC_RSR_RXOVR_Msk | GMAC_RSR_REC_Msk |
561 GMAC_RSR_BNA_Msk)) != 0)
564 GMAC_REGS->GMAC_RSR = rsr;
607 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) == 0)
640 GMAC_REGS->GMAC_NCR |= GMAC_NCR_TSTART_Msk;
643 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) != 0)
681 j = rxBufferIndex + i;
704 if((rxBufferDesc[j].status &
GMAC_RX_EOF) != 0 && sofIndex != UINT_MAX)
718 if(eofIndex != UINT_MAX)
722 else if(sofIndex != UINT_MAX)
735 for(i = 0; i < j; i++)
738 if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
798 uint32_t hashTable[2];
806 GMAC_REGS->GMAC_SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
807 GMAC_REGS->GMAC_SA[0].GMAC_SAT = interface->macAddr.w[2];
823 entry = &interface->macAddrFilter[i];
835 k = (
p[0] >> 6) ^
p[0];
836 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
837 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
838 k ^= (
p[3] >> 6) ^
p[3];
839 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
840 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
846 hashTable[k / 32] |= (1 << (k % 32));
854 unicastMacAddr[j] = entry->
addr;
862 k = (
p[0] >> 6) ^
p[0];
863 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
864 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
865 k ^= (
p[3] >> 6) ^
p[3];
866 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
867 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
873 hashTable[k / 32] |= (1 << (k % 32));
886 GMAC_REGS->GMAC_SA[1].GMAC_SAB = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
887 GMAC_REGS->GMAC_SA[1].GMAC_SAT = unicastMacAddr[0].w[2];
892 GMAC_REGS->GMAC_SA[1].GMAC_SAB = 0;
899 GMAC_REGS->GMAC_SA[2].GMAC_SAB = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
900 GMAC_REGS->GMAC_SA[2].GMAC_SAT = unicastMacAddr[1].w[2];
905 GMAC_REGS->GMAC_SA[2].GMAC_SAB = 0;
912 GMAC_REGS->GMAC_SA[3].GMAC_SAB = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
913 GMAC_REGS->GMAC_SA[3].GMAC_SAT = unicastMacAddr[2].w[2];
918 GMAC_REGS->GMAC_SA[3].GMAC_SAB = 0;
924 GMAC_REGS->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN_Msk;
928 GMAC_REGS->GMAC_NCFGR &= ~GMAC_NCFGR_UNIHEN_Msk;
932 GMAC_REGS->GMAC_HRB = hashTable[0];
933 GMAC_REGS->GMAC_HRT = hashTable[1];
936 TRACE_DEBUG(
" HRB = %08" PRIX32
"\r\n", GMAC_REGS->GMAC_HRB);
937 TRACE_DEBUG(
" HRT = %08" PRIX32
"\r\n", GMAC_REGS->GMAC_HRT);
955 config = GMAC_REGS->GMAC_NCFGR;
960 config |= GMAC_NCFGR_SPD_Msk;
964 config &= ~GMAC_NCFGR_SPD_Msk;
970 config |= GMAC_NCFGR_FD_Msk;
974 config &= ~GMAC_NCFGR_FD_Msk;
978 GMAC_REGS->GMAC_NCFGR = config;
1002 temp = GMAC_MAN_CLTTO_Msk | GMAC_MAN_OP(1) | GMAC_MAN_WTN(2);
1004 temp |= GMAC_MAN_PHYA(phyAddr);
1006 temp |= GMAC_MAN_REGA(
regAddr);
1008 temp |= GMAC_MAN_DATA(
data);
1011 GMAC_REGS->GMAC_MAN = temp;
1013 while((GMAC_REGS->GMAC_NSR & GMAC_NSR_IDLE_Msk) == 0)
1042 temp = GMAC_MAN_CLTTO_Msk | GMAC_MAN_OP(2) | GMAC_MAN_WTN(2);
1044 temp |= GMAC_MAN_PHYA(phyAddr);
1046 temp |= GMAC_MAN_REGA(
regAddr);
1049 GMAC_REGS->GMAC_MAN = temp;
1051 while((GMAC_REGS->GMAC_NSR & GMAC_NSR_IDLE_Msk) == 0)
1056 data = GMAC_REGS->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
void samv71EthEventHandler(NetInterface *interface)
SAMV71 Ethernet MAC event handler.
error_t samv71EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
error_t samv71EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
void GMAC_Handler(void)
SAMV71 Ethernet MAC interrupt service routine.
void samv71EthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
void samv71EthDisableIrq(NetInterface *interface)
Disable interrupts.
void samv71EthInitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
void samv71EthEnableIrq(NetInterface *interface)
Enable interrupts.
__weak_func void samv71EthInitGpio(NetInterface *interface)
GPIO configuration.
error_t samv71EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
uint16_t samv71EthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
error_t samv71EthReceivePacket(NetInterface *interface)
Receive a packet.
const NicDriver samv71EthDriver
SAMV71 Ethernet MAC driver.
error_t samv71EthInit(NetInterface *interface)
SAMV71 Ethernet MAC initialization.
void samv71EthTick(NetInterface *interface)
SAMV71 Ethernet MAC timer handler.
SAMV71 Ethernet MAC driver.
#define SAMV71_ETH_RX_BUFFER_COUNT
#define SAMV71_ETH_TX_BUFFER_COUNT
#define SAMV71_ETH_IRQ_SUB_PRIORITY
#define SAMV71_ETH_IRQ_PRIORITY_GROUPING
#define SAMV71_ETH_IRQ_GROUP_PRIORITY
#define SAMV71_ETH_TX_BUFFER_SIZE
#define SAMV71_ETH_DUMMY_BUFFER_SIZE
#define SAMV71_ETH_RAM_SECTION
#define SAMV71_ETH_RX_BUFFER_SIZE
#define SAMV71_ETH_DUMMY_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.