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)
234 PMC->PMC_PCER0 = (1 << ID_PIOC);
237 mask = PIO_PC9A_EMDIO | PIO_PC8A_EMDC | PIO_PC7A_EREFCK | PIO_PC6A_ERXER |
238 PIO_PC5A_ECRSDV | PIO_PC4A_ETXEN | PIO_PC3A_ERX1 | PIO_PC2A_ERX0 |
239 PIO_PC1A_ETX1 | PIO_PC0A_ETX0;
242 PIOC->PIO_PUDR =
mask;
244 PIOC->PIO_IDR =
mask;
246 PIOC->PIO_ABCDSR[0] &= ~
mask;
247 PIOC->PIO_ABCDSR[1] &= ~
mask;
249 PIOC->PIO_PDR =
mask;
252 EMAC->EMAC_USRIO = EMAC_USRIO_CLKEN | EMAC_USRIO_RMII;
291 rxBufferDesc[i].
status = 0;
300 EMAC->EMAC_TBQP = (uint32_t) txBufferDesc;
302 EMAC->EMAC_RBQP = (uint32_t) rxBufferDesc;
318 if(interface->phyDriver != NULL)
321 interface->phyDriver->tick(interface);
323 else if(interface->switchDriver != NULL)
326 interface->switchDriver->tick(interface);
343 AIC->AIC_SSR = ID_EMAC;
344 AIC->AIC_IECR = AIC_IECR_INTEN;
347 if(interface->phyDriver != NULL)
350 interface->phyDriver->enableIrq(interface);
352 else if(interface->switchDriver != NULL)
355 interface->switchDriver->enableIrq(interface);
372 AIC->AIC_SSR = ID_EMAC;
373 AIC->AIC_IDCR = AIC_IDCR_INTD;
376 if(interface->phyDriver != NULL)
379 interface->phyDriver->disableIrq(interface);
381 else if(interface->switchDriver != NULL)
384 interface->switchDriver->disableIrq(interface);
400 volatile uint32_t isr;
401 volatile uint32_t tsr;
402 volatile uint32_t rsr;
412 isr = EMAC->EMAC_ISR;
413 tsr = EMAC->EMAC_TSR;
414 rsr = EMAC->EMAC_RSR;
418 if((tsr & (EMAC_TSR_UND | EMAC_TSR_COMP | EMAC_TSR_BEX |
419 EMAC_TSR_TGO | EMAC_TSR_RLES | EMAC_TSR_COL | EMAC_TSR_UBR)) != 0)
422 EMAC->EMAC_TSR = tsr;
425 if((txBufferDesc[txBufferIndex].status &
EMAC_TX_USED) != 0)
433 if((rsr & (EMAC_RSR_OVR | EMAC_RSR_REC | EMAC_RSR_BNA)) != 0)
436 nicDriverInterface->nicEvent =
TRUE;
460 rsr = EMAC->EMAC_RSR;
463 if((rsr & (EMAC_RSR_OVR | EMAC_RSR_REC | EMAC_RSR_BNA)) != 0)
466 EMAC->EMAC_RSR = rsr;
508 if((txBufferDesc[txBufferIndex].status &
EMAC_TX_USED) == 0)
537 EMAC->EMAC_NCR |= EMAC_NCR_TSTART;
540 if((txBufferDesc[txBufferIndex].status &
EMAC_TX_USED) != 0)
578 j = rxBufferIndex + i;
601 if((rxBufferDesc[j].status &
EMAC_RX_EOF) != 0 && sofIndex != UINT_MAX)
615 if(eofIndex != UINT_MAX)
619 else if(sofIndex != UINT_MAX)
632 for(i = 0; i < j; i++)
635 if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
695 uint32_t hashTable[2];
703 EMAC->EMAC_SA[0].EMAC_SAxB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
704 EMAC->EMAC_SA[0].EMAC_SAxT = interface->macAddr.w[2];
720 entry = &interface->macAddrFilter[i];
732 k = (
p[0] >> 6) ^
p[0];
733 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
734 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
735 k ^= (
p[3] >> 6) ^
p[3];
736 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
737 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
743 hashTable[k / 32] |= (1 << (k % 32));
751 unicastMacAddr[j] = entry->
addr;
759 k = (
p[0] >> 6) ^
p[0];
760 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
761 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
762 k ^= (
p[3] >> 6) ^
p[3];
763 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
764 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
770 hashTable[k / 32] |= (1 << (k % 32));
783 EMAC->EMAC_SA[1].EMAC_SAxB = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
784 EMAC->EMAC_SA[1].EMAC_SAxT = unicastMacAddr[0].w[2];
789 EMAC->EMAC_SA[1].EMAC_SAxB = 0;
796 EMAC->EMAC_SA[2].EMAC_SAxB = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
797 EMAC->EMAC_SA[2].EMAC_SAxT = unicastMacAddr[1].w[2];
802 EMAC->EMAC_SA[2].EMAC_SAxB = 0;
809 EMAC->EMAC_SA[3].EMAC_SAxB = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
810 EMAC->EMAC_SA[3].EMAC_SAxT = unicastMacAddr[2].w[2];
815 EMAC->EMAC_SA[3].EMAC_SAxB = 0;
821 EMAC->EMAC_NCFGR |= EMAC_NCFGR_UNI;
825 EMAC->EMAC_NCFGR &= ~EMAC_NCFGR_UNI;
829 EMAC->EMAC_HRB = hashTable[0];
830 EMAC->EMAC_HRT = hashTable[1];
833 TRACE_DEBUG(
" HRB = %08" PRIX32
"\r\n", EMAC->EMAC_HRB);
834 TRACE_DEBUG(
" HRT = %08" PRIX32
"\r\n", EMAC->EMAC_HRT);
852 config = EMAC->EMAC_NCFGR;
857 config |= EMAC_NCFGR_SPD;
861 config &= ~EMAC_NCFGR_SPD;
867 config |= EMAC_NCFGR_FD;
871 config &= ~EMAC_NCFGR_FD;
875 EMAC->EMAC_NCFGR = config;
899 temp = EMAC_MAN_SOF(1) | EMAC_MAN_RW(1) | EMAC_MAN_CODE(2);
901 temp |= EMAC_MAN_PHYA(phyAddr);
903 temp |= EMAC_MAN_REGA(
regAddr);
905 temp |= EMAC_MAN_DATA(
data);
908 EMAC->EMAC_MAN = temp;
910 while((EMAC->EMAC_NSR & EMAC_NSR_IDLE) == 0)
939 temp = EMAC_MAN_SOF(1) | EMAC_MAN_RW(2) | EMAC_MAN_CODE(2);
941 temp |= EMAC_MAN_PHYA(phyAddr);
943 temp |= EMAC_MAN_REGA(
regAddr);
946 EMAC->EMAC_MAN = temp;
948 while((EMAC->EMAC_NSR & EMAC_NSR_IDLE) == 0)
953 data = EMAC->EMAC_MAN & EMAC_MAN_DATA_Msk;