32 #define TRACE_LEVEL NIC_TRACE_LEVEL
45 #if defined(__ICCARM__)
48 #pragma data_alignment = 8
51 #pragma data_alignment = 8
54 #pragma data_alignment = 4
57 #pragma data_alignment = 4
79 static uint_t txBufferIndex;
81 static uint_t rxBufferIndex;
118 volatile uint32_t status;
121 TRACE_INFO(
"Initializing SAME54 Ethernet MAC...\r\n");
124 nicDriverInterface = interface;
127 MCLK_REGS->MCLK_APBCMASK |= MCLK_APBCMASK_GMAC_Msk;
128 MCLK_REGS->MCLK_AHBMASK |= MCLK_AHBMASK_GMAC_Msk;
131 GMAC_REGS->GMAC_NCR = 0;
137 GMAC_REGS->GMAC_NCFGR = GMAC_NCFGR_CLK(5);
139 GMAC_REGS->GMAC_NCR |= GMAC_NCR_MPE_Msk;
142 if(interface->phyDriver != NULL)
145 error = interface->phyDriver->init(interface);
147 else if(interface->switchDriver != NULL)
150 error = interface->switchDriver->init(interface);
165 GMAC_REGS->SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
166 GMAC_REGS->SA[0].GMAC_SAT = interface->macAddr.w[2];
169 GMAC_REGS->SA[1].GMAC_SAB = 0;
170 GMAC_REGS->SA[2].GMAC_SAB = 0;
171 GMAC_REGS->SA[3].GMAC_SAB = 0;
174 GMAC_REGS->GMAC_HRB = 0;
175 GMAC_REGS->GMAC_HRT = 0;
178 GMAC_REGS->GMAC_NCFGR |= GMAC_NCFGR_MAXFS_Msk | GMAC_NCFGR_MTIHEN_Msk;
184 GMAC_REGS->GMAC_TSR = GMAC_TSR_HRESP_Msk | GMAC_TSR_UND_Msk |
185 GMAC_TSR_TXCOMP_Msk | GMAC_TSR_TFC_Msk | GMAC_TSR_TXGO_Msk |
186 GMAC_TSR_RLE_Msk | GMAC_TSR_COL_Msk | GMAC_TSR_UBR_Msk;
189 GMAC_REGS->GMAC_RSR = GMAC_RSR_HNO_Msk | GMAC_RSR_RXOVR_Msk |
190 GMAC_RSR_REC_Msk | GMAC_RSR_BNA_Msk;
193 GMAC_REGS->GMAC_IDR = 0xFFFFFFFF;
196 GMAC_REGS->GMAC_IER = GMAC_IER_HRESP_Msk | GMAC_IER_ROVR_Msk |
197 GMAC_IER_TCOMP_Msk | GMAC_IER_TFC_Msk | GMAC_IER_RLEX_Msk |
198 GMAC_IER_TUR_Msk | GMAC_IER_RXUBR_Msk | GMAC_IER_RCOMP_Msk;
201 status = GMAC_REGS->GMAC_ISR;
212 GMAC_REGS->GMAC_NCR |= GMAC_NCR_TXEN_Msk | GMAC_NCR_RXEN_Msk;
230 #if defined(USE_SAME54_XPLAINED_PRO)
234 MCLK_REGS->MCLK_APBBMASK |= MCLK_APBBMASK_PORT_Msk;
237 PORT_REGS->GROUP[0].PORT_PINCFG[12] |= PORT_PINCFG_PMUXEN_Msk;
238 temp = PORT_REGS->GROUP[0].PORT_PMUX[6] & ~PORT_PMUX_PMUXE_Msk;
239 PORT_REGS->GROUP[0].PORT_PMUX[6] = temp | PORT_PMUX_PMUXE(MUX_PA12L_GMAC_GRX1);
242 PORT_REGS->GROUP[0].PORT_PINCFG[13] |= PORT_PINCFG_PMUXEN_Msk;
243 temp = PORT_REGS->GROUP[0].PORT_PMUX[6] & ~PORT_PMUX_PMUXO_Msk;
244 PORT_REGS->GROUP[0].PORT_PMUX[6] = temp | PORT_PMUX_PMUXO(MUX_PA13L_GMAC_GRX0);
247 PORT_REGS->GROUP[0].PORT_PINCFG[14] |= PORT_PINCFG_PMUXEN_Msk;
248 temp = PORT_REGS->GROUP[0].PORT_PMUX[7] & ~PORT_PMUX_PMUXE_Msk;
249 PORT_REGS->GROUP[0].PORT_PMUX[7] = temp | PORT_PMUX_PMUXE(MUX_PA14L_GMAC_GTXCK);
252 PORT_REGS->GROUP[0].PORT_PINCFG[15] |= PORT_PINCFG_PMUXEN_Msk;
253 temp = PORT_REGS->GROUP[0].PORT_PMUX[7] & ~PORT_PMUX_PMUXO_Msk;
254 PORT_REGS->GROUP[0].PORT_PMUX[7] = temp | PORT_PMUX_PMUXO(MUX_PA15L_GMAC_GRXER);
257 PORT_REGS->GROUP[0].PORT_PINCFG[17] |= PORT_PINCFG_DRVSTR_Msk;
258 PORT_REGS->GROUP[0].PORT_PINCFG[17] |= PORT_PINCFG_PMUXEN_Msk;
259 temp = PORT_REGS->GROUP[0].PORT_PMUX[8] & ~PORT_PMUX_PMUXO_Msk;
260 PORT_REGS->GROUP[0].PORT_PMUX[8] = temp | PORT_PMUX_PMUXO(MUX_PA17L_GMAC_GTXEN);
263 PORT_REGS->GROUP[0].PORT_PINCFG[18] |= PORT_PINCFG_DRVSTR_Msk;
264 PORT_REGS->GROUP[0].PORT_PINCFG[18] |= PORT_PINCFG_PMUXEN_Msk;
265 temp = PORT_REGS->GROUP[0].PORT_PMUX[9] & ~PORT_PMUX_PMUXE_Msk;
266 PORT_REGS->GROUP[0].PORT_PMUX[9] = temp | PORT_PMUX_PMUXE(MUX_PA18L_GMAC_GTX0);
269 PORT_REGS->GROUP[0].PORT_PINCFG[19] |= PORT_PINCFG_DRVSTR_Msk;
270 PORT_REGS->GROUP[0].PORT_PINCFG[19] |= PORT_PINCFG_PMUXEN_Msk;
271 temp = PORT_REGS->GROUP[0].PORT_PMUX[9] & ~PORT_PMUX_PMUXO_Msk;
272 PORT_REGS->GROUP[0].PORT_PMUX[9] = temp | PORT_PMUX_PMUXO(MUX_PA19L_GMAC_GTX1);
275 PORT_REGS->GROUP[2].PORT_PINCFG[11] |= PORT_PINCFG_PMUXEN_Msk;
276 temp = PORT_REGS->GROUP[2].PORT_PMUX[5] & ~PORT_PMUX_PMUXO_Msk;
277 PORT_REGS->GROUP[2].PORT_PMUX[5] = temp | PORT_PMUX_PMUXO(MUX_PC11L_GMAC_GMDC);
280 PORT_REGS->GROUP[2].PORT_PINCFG[12] |= PORT_PINCFG_PMUXEN_Msk;
281 temp = PORT_REGS->GROUP[2].PORT_PMUX[6] & ~PORT_PMUX_PMUXE_Msk;
282 PORT_REGS->GROUP[2].PORT_PMUX[6] = temp | PORT_PMUX_PMUXE(MUX_PC12L_GMAC_GMDIO);
285 PORT_REGS->GROUP[2].PORT_PINCFG[20] |= PORT_PINCFG_PMUXEN_Msk;
286 temp = PORT_REGS->GROUP[2].PORT_PMUX[10] & ~PORT_PMUX_PMUXE_Msk;
287 PORT_REGS->GROUP[2].PORT_PMUX[10] = temp | PORT_PMUX_PMUXE(MUX_PC20L_GMAC_GRXDV);
290 GMAC_REGS->GMAC_UR &= ~GMAC_UR_MII_Msk;
293 PORT_REGS->GROUP[2].PORT_DIRSET = PORT_PC21;
296 PORT_REGS->GROUP[2].PORT_OUTCLR = PORT_PC21;
298 PORT_REGS->GROUP[2].PORT_OUTSET = PORT_PC21;
302 #elif defined(USE_SAME54_CURIOSITY_ULTRA)
306 MCLK_REGS->MCLK_APBBMASK |= MCLK_APBBMASK_PORT_Msk;
309 PORT_REGS->GROUP[0].PORT_PINCFG[12] |= PORT_PINCFG_PMUXEN_Msk;
310 temp = PORT_REGS->GROUP[0].PORT_PMUX[6] & ~PORT_PMUX_PMUXE_Msk;
311 PORT_REGS->GROUP[0].PORT_PMUX[6] = temp | PORT_PMUX_PMUXE(MUX_PA12L_GMAC_GRX1);
314 PORT_REGS->GROUP[0].PORT_PINCFG[13] |= PORT_PINCFG_PMUXEN_Msk;
315 temp = PORT_REGS->GROUP[0].PORT_PMUX[6] & ~PORT_PMUX_PMUXO_Msk;
316 PORT_REGS->GROUP[0].PORT_PMUX[6] = temp | PORT_PMUX_PMUXO(MUX_PA13L_GMAC_GRX0);
319 PORT_REGS->GROUP[0].PORT_PINCFG[14] |= PORT_PINCFG_PMUXEN_Msk;
320 temp = PORT_REGS->GROUP[0].PORT_PMUX[7] & ~PORT_PMUX_PMUXE_Msk;
321 PORT_REGS->GROUP[0].PORT_PMUX[7] = temp | PORT_PMUX_PMUXE(MUX_PA14L_GMAC_GTXCK);
324 PORT_REGS->GROUP[0].PORT_PINCFG[15] |= PORT_PINCFG_PMUXEN_Msk;
325 temp = PORT_REGS->GROUP[0].PORT_PMUX[7] & ~PORT_PMUX_PMUXO_Msk;
326 PORT_REGS->GROUP[0].PORT_PMUX[7] = temp | PORT_PMUX_PMUXO(MUX_PA15L_GMAC_GRXER);
329 PORT_REGS->GROUP[0].PORT_PINCFG[17] |= PORT_PINCFG_DRVSTR_Msk;
330 PORT_REGS->GROUP[0].PORT_PINCFG[17] |= PORT_PINCFG_PMUXEN_Msk;
331 temp = PORT_REGS->GROUP[0].PORT_PMUX[8] & ~PORT_PMUX_PMUXO_Msk;
332 PORT_REGS->GROUP[0].PORT_PMUX[8] = temp | PORT_PMUX_PMUXO(MUX_PA17L_GMAC_GTXEN);
335 PORT_REGS->GROUP[0].PORT_PINCFG[18] |= PORT_PINCFG_DRVSTR_Msk;
336 PORT_REGS->GROUP[0].PORT_PINCFG[18] |= PORT_PINCFG_PMUXEN_Msk;
337 temp = PORT_REGS->GROUP[0].PORT_PMUX[9] & ~PORT_PMUX_PMUXE_Msk;
338 PORT_REGS->GROUP[0].PORT_PMUX[9] = temp | PORT_PMUX_PMUXE(MUX_PA18L_GMAC_GTX0);
341 PORT_REGS->GROUP[0].PORT_PINCFG[19] |= PORT_PINCFG_DRVSTR_Msk;
342 PORT_REGS->GROUP[0].PORT_PINCFG[19] |= PORT_PINCFG_PMUXEN_Msk;
343 temp = PORT_REGS->GROUP[0].PORT_PMUX[9] & ~PORT_PMUX_PMUXO_Msk;
344 PORT_REGS->GROUP[0].PORT_PMUX[9] = temp | PORT_PMUX_PMUXO(MUX_PA19L_GMAC_GTX1);
347 PORT_REGS->GROUP[2].PORT_PINCFG[20] |= PORT_PINCFG_PMUXEN_Msk;
348 temp = PORT_REGS->GROUP[2].PORT_PMUX[10] & ~PORT_PMUX_PMUXE_Msk;
349 PORT_REGS->GROUP[2].PORT_PMUX[10] = temp | PORT_PMUX_PMUXE(MUX_PC20L_GMAC_GRXDV);
352 PORT_REGS->GROUP[2].PORT_PINCFG[22] |= PORT_PINCFG_PMUXEN_Msk;
353 temp = PORT_REGS->GROUP[2].PORT_PMUX[11] & ~PORT_PMUX_PMUXE_Msk;
354 PORT_REGS->GROUP[2].PORT_PMUX[11] = temp | PORT_PMUX_PMUXE(MUX_PC22L_GMAC_GMDC);
357 PORT_REGS->GROUP[2].PORT_PINCFG[23] |= PORT_PINCFG_PMUXEN_Msk;
358 temp = PORT_REGS->GROUP[2].PORT_PMUX[11] & ~PORT_PMUX_PMUXO_Msk;
359 PORT_REGS->GROUP[2].PORT_PMUX[11] = temp | PORT_PMUX_PMUXO(MUX_PC23L_GMAC_GMDIO);
362 GMAC_REGS->GMAC_UR &= ~GMAC_UR_MII_Msk;
365 PORT_REGS->GROUP[2].PORT_DIRSET = PORT_PC18;
368 PORT_REGS->GROUP[2].PORT_OUTCLR = PORT_PC18;
370 PORT_REGS->GROUP[2].PORT_OUTSET = PORT_PC18;
410 rxBufferDesc[i].
status = 0;
419 GMAC_REGS->GMAC_TBQB = (uint32_t) txBufferDesc;
421 GMAC_REGS->GMAC_RBQB = (uint32_t) rxBufferDesc;
437 if(interface->phyDriver != NULL)
440 interface->phyDriver->tick(interface);
442 else if(interface->switchDriver != NULL)
445 interface->switchDriver->tick(interface);
462 NVIC_EnableIRQ(GMAC_IRQn);
465 if(interface->phyDriver != NULL)
468 interface->phyDriver->enableIrq(interface);
470 else if(interface->switchDriver != NULL)
473 interface->switchDriver->enableIrq(interface);
490 NVIC_DisableIRQ(GMAC_IRQn);
493 if(interface->phyDriver != NULL)
496 interface->phyDriver->disableIrq(interface);
498 else if(interface->switchDriver != NULL)
501 interface->switchDriver->disableIrq(interface);
517 volatile uint32_t isr;
518 volatile uint32_t tsr;
519 volatile uint32_t rsr;
529 isr = GMAC_REGS->GMAC_ISR;
530 tsr = GMAC_REGS->GMAC_TSR;
531 rsr = GMAC_REGS->GMAC_RSR;
535 if((tsr & (GMAC_TSR_HRESP_Msk | GMAC_TSR_UND_Msk |
536 GMAC_TSR_TXCOMP_Msk | GMAC_TSR_TFC_Msk | GMAC_TSR_TXGO_Msk |
537 GMAC_TSR_RLE_Msk | GMAC_TSR_COL_Msk | GMAC_TSR_UBR_Msk)) != 0)
540 GMAC_REGS->GMAC_TSR = tsr;
543 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) != 0)
551 if((rsr & (GMAC_RSR_HNO_Msk | GMAC_RSR_RXOVR_Msk | GMAC_RSR_REC_Msk |
552 GMAC_RSR_BNA_Msk)) != 0)
555 nicDriverInterface->nicEvent =
TRUE;
576 rsr = GMAC_REGS->GMAC_RSR;
579 if((rsr & (GMAC_RSR_HNO_Msk | GMAC_RSR_RXOVR_Msk | GMAC_RSR_REC_Msk |
580 GMAC_RSR_BNA_Msk)) != 0)
583 GMAC_REGS->GMAC_RSR = rsr;
625 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) == 0)
657 GMAC_REGS->GMAC_NCR |= GMAC_NCR_TSTART_Msk;
660 if((txBufferDesc[txBufferIndex].status &
GMAC_TX_USED) != 0)
698 j = rxBufferIndex + i;
721 if((rxBufferDesc[j].status &
GMAC_RX_EOF) != 0 && sofIndex != UINT_MAX)
735 if(eofIndex != UINT_MAX)
739 else if(sofIndex != UINT_MAX)
752 for(i = 0; i < j; i++)
755 if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
815 uint32_t hashTable[2];
823 GMAC_REGS->SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
824 GMAC_REGS->SA[0].GMAC_SAT = interface->macAddr.w[2];
840 entry = &interface->macAddrFilter[i];
852 k = (
p[0] >> 6) ^
p[0];
853 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
854 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
855 k ^= (
p[3] >> 6) ^
p[3];
856 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
857 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
863 hashTable[k / 32] |= (1 << (k % 32));
871 unicastMacAddr[j++] = entry->
addr;
881 GMAC_REGS->SA[1].GMAC_SAB = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
882 GMAC_REGS->SA[1].GMAC_SAT = unicastMacAddr[0].w[2];
887 GMAC_REGS->SA[1].GMAC_SAB = 0;
894 GMAC_REGS->SA[2].GMAC_SAB = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
895 GMAC_REGS->SA[2].GMAC_SAT = unicastMacAddr[1].w[2];
900 GMAC_REGS->SA[2].GMAC_SAB = 0;
907 GMAC_REGS->SA[3].GMAC_SAB = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
908 GMAC_REGS->SA[3].GMAC_SAT = unicastMacAddr[2].w[2];
913 GMAC_REGS->SA[3].GMAC_SAB = 0;
917 GMAC_REGS->GMAC_HRB = hashTable[0];
918 GMAC_REGS->GMAC_HRT = hashTable[1];
921 TRACE_DEBUG(
" HRB = %08" PRIX32
"\r\n", GMAC_REGS->GMAC_HRB);
922 TRACE_DEBUG(
" HRT = %08" PRIX32
"\r\n", GMAC_REGS->GMAC_HRT);
940 config = GMAC_REGS->GMAC_NCFGR;
945 config |= GMAC_NCFGR_SPD_Msk;
949 config &= ~GMAC_NCFGR_SPD_Msk;
955 config |= GMAC_NCFGR_FD_Msk;
959 config &= ~GMAC_NCFGR_FD_Msk;
963 GMAC_REGS->GMAC_NCFGR = config;
987 temp = GMAC_MAN_CLTTO_Msk | GMAC_MAN_OP(1) | GMAC_MAN_WTN(2);
989 temp |= GMAC_MAN_PHYA(phyAddr);
991 temp |= GMAC_MAN_REGA(
regAddr);
993 temp |= GMAC_MAN_DATA(
data);
996 GMAC_REGS->GMAC_MAN = temp;
998 while((GMAC_REGS->GMAC_NSR & GMAC_NSR_IDLE_Msk) == 0)
1027 temp = GMAC_MAN_CLTTO_Msk | GMAC_MAN_OP(2) | GMAC_MAN_WTN(2);
1029 temp |= GMAC_MAN_PHYA(phyAddr);
1031 temp |= GMAC_MAN_REGA(
regAddr);
1034 GMAC_REGS->GMAC_MAN = temp;
1036 while((GMAC_REGS->GMAC_NSR & GMAC_NSR_IDLE_Msk) == 0)
1041 data = GMAC_REGS->GMAC_MAN & GMAC_MAN_DATA_Msk;