32 #define TRACE_LEVEL NIC_TRACE_LEVEL
45 #if defined(__ICCARM__)
48 #pragma data_alignment = 8
49 #pragma location = SAMA5D3_GETH_RAM_SECTION
52 #pragma data_alignment = 8
53 #pragma location = SAMA5D3_GETH_RAM_SECTION
56 #pragma data_alignment = 8
57 #pragma location = SAMA5D3_GETH_RAM_SECTION
60 #pragma data_alignment = 8
61 #pragma location = SAMA5D3_GETH_RAM_SECTION
83 static uint_t txBufferIndex;
85 static uint_t rxBufferIndex;
122 volatile uint32_t status;
125 TRACE_INFO(
"Initializing SAMA5D3 Ethernet MAC (GMAC)...\r\n");
128 nicDriverInterface = interface;
131 PMC->PMC_PCER1 = (1 << (ID_GMAC - 32));
133 PMC->PMC_PCER1 = (1 << (ID_IRQ - 32));
142 GMAC->GMAC_NCFGR = GMAC_NCFGR_DBW_DBW64 | GMAC_NCFGR_CLK_MCK_224;
144 GMAC->GMAC_NCR |= GMAC_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 GMAC->GMAC_SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
171 GMAC->GMAC_SA[0].GMAC_SAT = interface->macAddr.w[2];
174 GMAC->GMAC_SA[1].GMAC_SAB = 0;
175 GMAC->GMAC_SA[2].GMAC_SAB = 0;
176 GMAC->GMAC_SA[3].GMAC_SAB = 0;
183 GMAC->GMAC_NCFGR |= GMAC_NCFGR_MAXFS | GMAC_NCFGR_MTIHEN;
189 GMAC->GMAC_TSR = GMAC_TSR_HRESP | GMAC_TSR_UND | GMAC_TSR_TXCOMP | GMAC_TSR_TFC |
190 GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR;
192 GMAC->GMAC_RSR = GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA;
195 GMAC->GMAC_IDR = 0xFFFFFFFF;
197 GMAC->GMAC_IER = GMAC_IER_HRESP | GMAC_IER_ROVR | GMAC_IER_TCOMP | GMAC_IER_TFC |
198 GMAC_IER_RLEX | GMAC_IER_TUR | GMAC_IER_RXUBR | GMAC_IER_RCOMP;
201 status = GMAC->GMAC_ISR;
205 AIC->AIC_SSR = ID_GMAC;
210 GMAC->GMAC_NCR |= GMAC_NCR_TXEN | GMAC_NCR_RXEN;
228 #if defined(USE_SAMA5D3_XPLAINED) || defined(USE_SAMA5D3_EDS) || defined(USE_EVB_KSZ9477)
230 PMC->PMC_PCER0 = (1 << ID_PIOB);
243 GMAC->GMAC_UR = GMAC_UR_RGMII;
282 rxBufferDesc[i].
status = 0;
291 GMAC->GMAC_TBQB = (uint32_t) txBufferDesc;
293 GMAC->GMAC_RBQB = (uint32_t) rxBufferDesc;
309 if(interface->phyDriver != NULL)
312 interface->phyDriver->tick(interface);
314 else if(interface->switchDriver != NULL)
317 interface->switchDriver->tick(interface);
334 AIC->AIC_SSR = ID_GMAC;
335 AIC->AIC_IECR = AIC_IECR_INTEN;
338 if(interface->phyDriver != NULL)
341 interface->phyDriver->enableIrq(interface);
343 else if(interface->switchDriver != NULL)
346 interface->switchDriver->enableIrq(interface);
363 AIC->AIC_SSR = ID_GMAC;
364 AIC->AIC_IDCR = AIC_IDCR_INTD;
367 if(interface->phyDriver != NULL)
370 interface->phyDriver->disableIrq(interface);
372 else if(interface->switchDriver != NULL)
375 interface->switchDriver->disableIrq(interface);
391 volatile uint32_t isr;
392 volatile uint32_t tsr;
393 volatile uint32_t rsr;
403 isr = GMAC->GMAC_ISR;
404 tsr = GMAC->GMAC_TSR;
405 rsr = GMAC->GMAC_RSR;
409 if((tsr & (GMAC_TSR_HRESP | GMAC_TSR_UND | GMAC_TSR_TXCOMP | GMAC_TSR_TFC |
410 GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR)) != 0)
413 GMAC->GMAC_TSR = tsr;
425 if((rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA)) != 0)
428 nicDriverInterface->nicEvent =
TRUE;
452 rsr = GMAC->GMAC_RSR;
455 if((rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA)) != 0)
458 GMAC->GMAC_RSR = rsr;
500 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) == 0)
529 GMAC->GMAC_NCR |= GMAC_NCR_TSTART;
532 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) != 0)
570 j = rxBufferIndex + i;
593 if((rxBufferDesc[j].status &
GMAC_RX_EOF) != 0 && sofIndex != UINT_MAX)
607 if(eofIndex != UINT_MAX)
611 else if(sofIndex != UINT_MAX)
624 for(i = 0; i < j; i++)
627 if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
687 uint32_t hashTable[2];
695 GMAC->GMAC_SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
696 GMAC->GMAC_SA[0].GMAC_SAT = interface->macAddr.w[2];
712 entry = &interface->macAddrFilter[i];
724 k = (
p[0] >> 6) ^
p[0];
725 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
726 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
727 k ^= (
p[3] >> 6) ^
p[3];
728 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
729 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
735 hashTable[k / 32] |= (1 << (k % 32));
743 unicastMacAddr[j] = entry->
addr;
751 k = (
p[0] >> 6) ^
p[0];
752 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
753 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
754 k ^= (
p[3] >> 6) ^
p[3];
755 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
756 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
762 hashTable[k / 32] |= (1 << (k % 32));
775 GMAC->GMAC_SA[1].GMAC_SAB = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
776 GMAC->GMAC_SA[1].GMAC_SAT = unicastMacAddr[0].w[2];
781 GMAC->GMAC_SA[1].GMAC_SAB = 0;
788 GMAC->GMAC_SA[2].GMAC_SAB = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
789 GMAC->GMAC_SA[2].GMAC_SAT = unicastMacAddr[1].w[2];
794 GMAC->GMAC_SA[2].GMAC_SAB = 0;
801 GMAC->GMAC_SA[3].GMAC_SAB = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
802 GMAC->GMAC_SA[3].GMAC_SAT = unicastMacAddr[2].w[2];
807 GMAC->GMAC_SA[3].GMAC_SAB = 0;
813 GMAC->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN;
817 GMAC->GMAC_NCFGR &= ~GMAC_NCFGR_UNIHEN;
821 GMAC->GMAC_HRB = hashTable[0];
822 GMAC->GMAC_HRT = hashTable[1];
825 TRACE_DEBUG(
" HRB = %08" PRIX32
"\r\n", GMAC->GMAC_HRB);
826 TRACE_DEBUG(
" HRT = %08" PRIX32
"\r\n", GMAC->GMAC_HRT);
844 config = GMAC->GMAC_NCFGR;
849 config |= GMAC_NCFGR_GBE;
850 config &= ~GMAC_NCFGR_SPD;
855 config &= ~GMAC_NCFGR_GBE;
856 config |= GMAC_NCFGR_SPD;
861 config &= ~GMAC_NCFGR_GBE;
862 config &= ~GMAC_NCFGR_SPD;
868 config |= GMAC_NCFGR_FD;
872 config &= ~GMAC_NCFGR_FD;
876 GMAC->GMAC_NCFGR = config;
900 temp = GMAC_MAN_CLTTO | GMAC_MAN_OP(1) | GMAC_MAN_WTN(2);
902 temp |= GMAC_MAN_PHYA(phyAddr);
904 temp |= GMAC_MAN_REGA(
regAddr);
906 temp |= GMAC_MAN_DATA(
data);
909 GMAC->GMAC_MAN = temp;
911 while((GMAC->GMAC_NSR & GMAC_NSR_IDLE) == 0)
940 temp = GMAC_MAN_CLTTO | GMAC_MAN_OP(2) | GMAC_MAN_WTN(2);
942 temp |= GMAC_MAN_PHYA(phyAddr);
944 temp |= GMAC_MAN_REGA(
regAddr);
947 GMAC->GMAC_MAN = temp;
949 while((GMAC->GMAC_NSR & GMAC_NSR_IDLE) == 0)
954 data = GMAC->GMAC_MAN & GMAC_MAN_DATA_Msk;