32 #define TRACE_LEVEL NIC_TRACE_LEVEL
46 #if defined(__ICCARM__)
49 #pragma data_alignment = 8
50 #pragma location = SAMA5D3_ETH1_RAM_SECTION
53 #pragma data_alignment = 8
54 #pragma location = SAMA5D3_ETH1_RAM_SECTION
57 #pragma data_alignment = 8
58 #pragma location = SAMA5D3_ETH1_RAM_SECTION
61 #pragma data_alignment = 8
62 #pragma location = SAMA5D3_ETH1_RAM_SECTION
84 static uint_t txBufferIndex;
86 static uint_t rxBufferIndex;
123 volatile uint32_t status;
126 TRACE_INFO(
"Initializing SAMA5D3 Ethernet MAC (EMAC)...\r\n");
129 nicDriverInterface = interface;
132 PMC->PMC_PCER1 = (1 << (ID_EMAC0 - 32));
134 PMC->PMC_PCER1 = (1 << (ID_AIC - 32));
143 EMAC0->EMAC_NCFGR = EMAC_NCFGR_CLK_MCK_64;
145 EMAC0->EMAC_NCR |= EMAC_NCR_MPE;
148 if(interface->phyDriver != NULL)
151 error = interface->phyDriver->init(interface);
153 else if(interface->switchDriver != NULL)
156 error = interface->switchDriver->init(interface);
171 EMAC0->EMAC_SA[0].EMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
172 EMAC0->EMAC_SA[0].EMAC_SAT = interface->macAddr.w[2];
175 EMAC0->EMAC_SA[1].EMAC_SAB = 0;
176 EMAC0->EMAC_SA[2].EMAC_SAB = 0;
177 EMAC0->EMAC_SA[3].EMAC_SAB = 0;
184 EMAC0->EMAC_NCFGR |= EMAC_NCFGR_BIG | EMAC_NCFGR_MTI;
190 EMAC0->EMAC_TSR = EMAC_TSR_UND | EMAC_TSR_COMP | EMAC_TSR_BEX |
191 EMAC_TSR_TGO | EMAC_TSR_RLES | EMAC_TSR_COL | EMAC_TSR_UBR;
194 EMAC0->EMAC_RSR = EMAC_RSR_OVR | EMAC_RSR_REC | EMAC_RSR_BNA;
197 EMAC0->EMAC_IDR = 0xFFFFFFFF;
200 EMAC0->EMAC_IER = EMAC_IER_ROVR | EMAC_IER_TCOMP | EMAC_IER_TXERR |
201 EMAC_IER_RLE | EMAC_IER_TUND | EMAC_IER_RXUBR | EMAC_IER_RCOMP;
204 status = EMAC0->EMAC_ISR;
208 AIC->AIC_SSR = ID_EMAC0;
213 EMAC0->EMAC_NCR |= EMAC_NCR_TE | EMAC_NCR_RE;
231 #if defined(CONFIG_BOARD_SAMA5D3_XPLAINED)
235 PMC->PMC_PCER0 = (1 << ID_PIOC);
238 mask = PIO_PC9A_EMDIO | PIO_PC8A_EMDC | PIO_PC7A_EREFCK | PIO_PC6A_ERXER |
239 PIO_PC5A_ECRSDV | PIO_PC4A_ETXEN | PIO_PC3A_ERX1 | PIO_PC2A_ERX0 |
240 PIO_PC1A_ETX1 | PIO_PC0A_ETX0;
243 PIOC->PIO_PUDR =
mask;
245 PIOC->PIO_IDR =
mask;
247 PIOC->PIO_ABCDSR[0] &= ~
mask;
248 PIOC->PIO_ABCDSR[1] &= ~
mask;
250 PIOC->PIO_PDR =
mask;
253 EMAC0->EMAC_USRIO = EMAC_USRIO_CLKEN | EMAC_USRIO_RMII;
292 rxBufferDesc[i].
status = 0;
301 EMAC0->EMAC_TBQP = (uint32_t) txBufferDesc;
303 EMAC0->EMAC_RBQP = (uint32_t) rxBufferDesc;
319 if(interface->phyDriver != NULL)
322 interface->phyDriver->tick(interface);
324 else if(interface->switchDriver != NULL)
327 interface->switchDriver->tick(interface);
344 AIC->AIC_SSR = ID_EMAC0;
345 AIC->AIC_IECR = AIC_IECR_INTEN;
348 if(interface->phyDriver != NULL)
351 interface->phyDriver->enableIrq(interface);
353 else if(interface->switchDriver != NULL)
356 interface->switchDriver->enableIrq(interface);
373 AIC->AIC_SSR = ID_EMAC0;
374 AIC->AIC_IDCR = AIC_IDCR_INTD;
377 if(interface->phyDriver != NULL)
380 interface->phyDriver->disableIrq(interface);
382 else if(interface->switchDriver != NULL)
385 interface->switchDriver->disableIrq(interface);
401 volatile uint32_t isr;
402 volatile uint32_t tsr;
403 volatile uint32_t rsr;
413 isr = EMAC0->EMAC_ISR;
414 tsr = EMAC0->EMAC_TSR;
415 rsr = EMAC0->EMAC_RSR;
419 if((tsr & (EMAC_TSR_UND | EMAC_TSR_COMP | EMAC_TSR_BEX |
420 EMAC_TSR_TGO | EMAC_TSR_RLES | EMAC_TSR_COL | EMAC_TSR_UBR)) != 0)
423 EMAC0->EMAC_TSR = tsr;
426 if((txBufferDesc[txBufferIndex].status &
EMAC_TX_USED) != 0)
434 if((rsr & (EMAC_RSR_OVR | EMAC_RSR_REC | EMAC_RSR_BNA)) != 0)
437 nicDriverInterface->nicEvent =
TRUE;
461 rsr = EMAC0->EMAC_RSR;
464 if((rsr & (EMAC_RSR_OVR | EMAC_RSR_REC | EMAC_RSR_BNA)) != 0)
467 EMAC0->EMAC_RSR = rsr;
509 if((txBufferDesc[txBufferIndex].status &
EMAC_TX_USED) == 0)
541 EMAC0->EMAC_NCR |= EMAC_NCR_TSTART;
544 if((txBufferDesc[txBufferIndex].status &
EMAC_TX_USED) != 0)
582 j = rxBufferIndex + i;
605 if((rxBufferDesc[j].status &
EMAC_RX_EOF) != 0 && sofIndex != UINT_MAX)
619 if(eofIndex != UINT_MAX)
623 else if(sofIndex != UINT_MAX)
636 for(i = 0; i < j; i++)
639 if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
699 uint32_t hashTable[2];
707 EMAC0->EMAC_SA[0].EMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
708 EMAC0->EMAC_SA[0].EMAC_SAT = interface->macAddr.w[2];
724 entry = &interface->macAddrFilter[i];
736 k = (
p[0] >> 6) ^
p[0];
737 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
738 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
739 k ^= (
p[3] >> 6) ^
p[3];
740 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
741 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
747 hashTable[k / 32] |= (1 << (k % 32));
755 unicastMacAddr[j] = entry->
addr;
763 k = (
p[0] >> 6) ^
p[0];
764 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
765 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
766 k ^= (
p[3] >> 6) ^
p[3];
767 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
768 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
774 hashTable[k / 32] |= (1 << (k % 32));
787 EMAC0->EMAC_SA[1].EMAC_SAB = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
788 EMAC0->EMAC_SA[1].EMAC_SAT = unicastMacAddr[0].w[2];
793 EMAC0->EMAC_SA[1].EMAC_SAB = 0;
800 EMAC0->EMAC_SA[2].EMAC_SAB = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
801 EMAC0->EMAC_SA[2].EMAC_SAT = unicastMacAddr[1].w[2];
806 EMAC0->EMAC_SA[2].EMAC_SAB = 0;
813 EMAC0->EMAC_SA[3].EMAC_SAB = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
814 EMAC0->EMAC_SA[3].EMAC_SAT = unicastMacAddr[2].w[2];
819 EMAC0->EMAC_SA[3].EMAC_SAB = 0;
825 EMAC0->EMAC_NCFGR |= EMAC_NCFGR_UNI;
829 EMAC0->EMAC_NCFGR &= ~EMAC_NCFGR_UNI;
833 EMAC0->EMAC_HRB = hashTable[0];
834 EMAC0->EMAC_HRT = hashTable[1];
837 TRACE_DEBUG(
" HRB = 0x%08" PRIX32
"\r\n", EMAC0->EMAC_HRB);
838 TRACE_DEBUG(
" HRT = 0x%08" PRIX32
"\r\n", EMAC0->EMAC_HRT);
856 config = EMAC0->EMAC_NCFGR;
861 config |= EMAC_NCFGR_SPD;
865 config &= ~EMAC_NCFGR_SPD;
871 config |= EMAC_NCFGR_FD;
875 config &= ~EMAC_NCFGR_FD;
879 EMAC0->EMAC_NCFGR = config;
903 temp = EMAC_MAN_SOF(1) | EMAC_MAN_RW(1) | EMAC_MAN_CODE(2);
905 temp |= EMAC_MAN_PHYA(phyAddr);
907 temp |= EMAC_MAN_REGA(
regAddr);
909 temp |= EMAC_MAN_DATA(
data);
912 EMAC0->EMAC_MAN = temp;
914 while((EMAC0->EMAC_NSR & EMAC_NSR_IDLE) == 0)
943 temp = EMAC_MAN_SOF(1) | EMAC_MAN_RW(2) | EMAC_MAN_CODE(2);
945 temp |= EMAC_MAN_PHYA(phyAddr);
947 temp |= EMAC_MAN_REGA(
regAddr);
950 EMAC0->EMAC_MAN = temp;
952 while((EMAC0->EMAC_NSR & EMAC_NSR_IDLE) == 0)
957 data = EMAC0->EMAC_MAN & EMAC_MAN_DATA_Msk;