32 #define TRACE_LEVEL NIC_TRACE_LEVEL
36 #include "mpfs_hal/mss_plic.h"
37 #include "mpfs_hal/mss_sysreg.h"
38 #include "drivers/mss_mac/mac_registers.h"
39 #include "drivers/mss_mac/pse_mac_regs.h"
74 static uint_t txBufferIndex;
76 static uint_t rxBufferIndex;
113 volatile uint32_t temp;
116 TRACE_INFO(
"Initializing MPFSxxx Ethernet MAC (MAC1)...\r\n");
119 nicDriverInterface = interface;
122 SYSREG->SUBBLK_CLOCK_CR |= 4U;
125 SYSREG->SOFT_RESET_CR |= 4U;
126 SYSREG->SOFT_RESET_CR &= ~4U;
129 MAC1->NETWORK_CONTROL = 0;
135 MAC1->NETWORK_CONFIG = (1 << GEM_DATA_BUS_WIDTH_SHIFT) |
136 (2 << GEM_MDC_CLOCK_DIVISOR_SHIFT);
139 MAC1->NETWORK_CONTROL |= GEM_MAN_PORT_EN;
142 if(interface->phyDriver != NULL)
145 error = interface->phyDriver->init(interface);
147 else if(interface->switchDriver != NULL)
150 error = interface->switchDriver->init(interface);
165 MAC1->SPEC_ADD1_BOTTOM = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
166 MAC1->SPEC_ADD1_TOP = interface->macAddr.w[2];
169 MAC1->SPEC_ADD2_BOTTOM = 0;
170 MAC1->SPEC_ADD3_BOTTOM = 0;
171 MAC1->SPEC_ADD4_BOTTOM = 0;
174 MAC1->HASH_BOTTOM = 0;
178 MAC1->NETWORK_CONFIG |= GEM_RECEIVE_1536_BYTE_FRAMES | GEM_MULTICAST_HASH_ENABLE;
185 temp |= GEM_DMA_ADDR_BUS_WIDTH_1;
187 temp |= GEM_TX_BD_EXTENDED_MODE_EN | GEM_RX_BD_EXTENDED_MODE_EN;
189 temp |= GEM_TX_PBUF_SIZE | GEM_RX_PBUF_SIZE;
192 MAC1->DMA_CONFIG = temp;
201 MAC1->TRANSMIT_STATUS = GEM_TX_RESP_NOT_OK | GEM_STAT_TRANSMIT_UNDER_RUN |
202 GEM_STAT_TRANSMIT_COMPLETE | GEM_STAT_AMBA_ERROR | GEM_TRANSMIT_GO |
203 GEM_RETRY_LIMIT_EXCEEDED | GEM_COLLISION_OCCURRED | GEM_USED_BIT_READ;
206 MAC1->RECEIVE_STATUS = GEM_RX_RESP_NOT_OK | GEM_RECEIVE_OVERRUN |
207 GEM_FRAME_RECEIVED | GEM_BUFFER_NOT_AVAILABLE;
210 MAC1->INT_DISABLE = 0xFFFFFFFF;
211 MAC1->INT_Q1_DISABLE = 0xFFFFFFFF;
212 MAC1->INT_Q2_DISABLE = 0xFFFFFFFF;
213 MAC1->INT_Q3_DISABLE = 0xFFFFFFFF;
216 MAC1->INT_ENABLE = GEM_RESP_NOT_OK_INT |
217 GEM_RECEIVE_OVERRUN_INT | GEM_TRANSMIT_COMPLETE | GEM_AMBA_ERROR |
218 GEM_RETRY_LIMIT_EXCEEDED_OR_LATE_COLLISION | GEM_TRANSMIT_UNDER_RUN |
219 GEM_RX_USED_BIT_READ | GEM_RECEIVE_COMPLETE;
222 temp =
MAC1->INT_STATUS;
229 MAC1->NETWORK_CONTROL |= GEM_ENABLE_TRANSMIT | GEM_ENABLE_RECEIVE;
247 #if defined(USE_MPFS_ICICLE_KIT_ES)
270 txBufferDesc[i].addrLow = (uint32_t)
address;
271 txBufferDesc[i].addrHigh = (uint32_t) (
address >> 32);
277 txBufferDesc[i].reserved = 0;
278 txBufferDesc[i].nanoSeconds = 0;
279 txBufferDesc[i].seconds = 0;
295 rxBufferDesc[i].addrHigh = (uint32_t) (
address >> 32);
298 rxBufferDesc[i].status = 0;
301 rxBufferDesc[i].reserved = 0;
302 rxBufferDesc[i].nanoSeconds = 0;
303 rxBufferDesc[i].seconds = 0;
315 address = (uint64_t) dummyTxBuffer[i];
318 dummyTxBufferDesc[i].addrLow = (uint32_t)
address;
319 dummyTxBufferDesc[i].addrHigh = (uint32_t) (
address >> 32);
325 dummyTxBufferDesc[i].reserved = 0;
326 dummyTxBufferDesc[i].nanoSeconds = 0;
327 dummyTxBufferDesc[i].seconds = 0;
337 address = (uint64_t) dummyRxBuffer[i];
341 dummyRxBufferDesc[i].addrHigh = (uint32_t) (
address >> 32);
344 dummyRxBufferDesc[i].status = 0;
347 dummyRxBufferDesc[i].reserved = 0;
348 dummyRxBufferDesc[i].nanoSeconds = 0;
349 dummyRxBufferDesc[i].seconds = 0;
356 MAC1->TRANSMIT_Q_PTR = (uint32_t) ((uint64_t) txBufferDesc);
357 MAC1->UPPER_TX_Q_BASE_ADDR = (uint32_t) ((uint64_t) txBufferDesc >> 32);
359 MAC1->TRANSMIT_Q1_PTR = (uint32_t) ((uint64_t) dummyTxBufferDesc) | 1;
360 MAC1->TRANSMIT_Q2_PTR = (uint32_t) ((uint64_t) dummyTxBufferDesc) | 1;
361 MAC1->TRANSMIT_Q3_PTR = (uint32_t) ((uint64_t) dummyTxBufferDesc) | 1;
364 MAC1->RECEIVE_Q_PTR = (uint32_t) ((uint64_t) rxBufferDesc);
365 MAC1->UPPER_RX_Q_BASE_ADDR = (uint32_t) ((uint64_t) rxBufferDesc >> 32);
367 MAC1->RECEIVE_Q1_PTR = (uint32_t) ((uint64_t) dummyRxBufferDesc) | 1;
368 MAC1->RECEIVE_Q2_PTR = (uint32_t) ((uint64_t) dummyRxBufferDesc) | 1;
369 MAC1->RECEIVE_Q3_PTR = (uint32_t) ((uint64_t) dummyRxBufferDesc) | 1;
385 if(interface->phyDriver != NULL)
388 interface->phyDriver->tick(interface);
390 else if(interface->switchDriver != NULL)
393 interface->switchDriver->tick(interface);
410 PLIC_EnableIRQ(MAC1_INT_PLIC);
413 if(interface->phyDriver != NULL)
416 interface->phyDriver->enableIrq(interface);
418 else if(interface->switchDriver != NULL)
421 interface->switchDriver->enableIrq(interface);
438 PLIC_DisableIRQ(MAC1_INT_PLIC);
441 if(interface->phyDriver != NULL)
444 interface->phyDriver->disableIrq(interface);
446 else if(interface->switchDriver != NULL)
449 interface->switchDriver->disableIrq(interface);
465 volatile uint32_t isr;
466 volatile uint32_t tsr;
467 volatile uint32_t rsr;
477 isr =
MAC1->INT_Q1_STATUS;
478 isr =
MAC1->INT_Q2_STATUS;
479 isr =
MAC1->INT_Q3_STATUS;
480 isr =
MAC1->INT_STATUS;
481 tsr =
MAC1->TRANSMIT_STATUS;
482 rsr =
MAC1->RECEIVE_STATUS;
486 if((tsr & (GEM_TX_RESP_NOT_OK | GEM_STAT_TRANSMIT_UNDER_RUN |
487 GEM_STAT_TRANSMIT_COMPLETE | GEM_STAT_AMBA_ERROR | GEM_TRANSMIT_GO |
488 GEM_RETRY_LIMIT_EXCEEDED | GEM_COLLISION_OCCURRED | GEM_USED_BIT_READ)) != 0)
491 MAC1->TRANSMIT_STATUS = tsr;
494 if((txBufferDesc[txBufferIndex].status &
MAC_TX_USED) != 0)
502 if((rsr & (GEM_RX_RESP_NOT_OK | GEM_RECEIVE_OVERRUN | GEM_FRAME_RECEIVED |
503 GEM_BUFFER_NOT_AVAILABLE)) != 0)
506 nicDriverInterface->nicEvent =
TRUE;
515 return EXT_IRQ_KEEP_ENABLED;
530 rsr =
MAC1->RECEIVE_STATUS;
533 if((rsr & (GEM_RX_RESP_NOT_OK | GEM_RECEIVE_OVERRUN | GEM_FRAME_RECEIVED |
534 GEM_BUFFER_NOT_AVAILABLE)) != 0)
537 MAC1->RECEIVE_STATUS = rsr;
579 if((txBufferDesc[txBufferIndex].status &
MAC_TX_USED) == 0)
608 MAC1->NETWORK_CONTROL |= GEM_TRANSMIT_START;
611 if((txBufferDesc[txBufferIndex].status &
MAC_TX_USED) != 0)
649 j = rxBufferIndex + i;
665 if((rxBufferDesc[j].status &
MAC_RX_SOF) != 0)
672 if((rxBufferDesc[j].status &
MAC_RX_EOF) != 0 && sofIndex != UINT_MAX)
686 if(eofIndex != UINT_MAX)
690 else if(sofIndex != UINT_MAX)
703 for(i = 0; i < j; i++)
706 if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
766 uint32_t hashTable[2];
774 MAC1->SPEC_ADD1_BOTTOM = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
775 MAC1->SPEC_ADD1_TOP = interface->macAddr.w[2];
791 entry = &interface->macAddrFilter[i];
803 k = (
p[0] >> 6) ^
p[0];
804 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
805 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
806 k ^= (
p[3] >> 6) ^
p[3];
807 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
808 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
814 hashTable[k / 32] |= (1 << (k % 32));
822 unicastMacAddr[j] = entry->
addr;
830 k = (
p[0] >> 6) ^
p[0];
831 k ^= (
p[1] >> 4) ^ (
p[1] << 2);
832 k ^= (
p[2] >> 2) ^ (
p[2] << 4);
833 k ^= (
p[3] >> 6) ^
p[3];
834 k ^= (
p[4] >> 4) ^ (
p[4] << 2);
835 k ^= (
p[5] >> 2) ^ (
p[5] << 4);
841 hashTable[k / 32] |= (1 << (k % 32));
854 MAC1->SPEC_ADD2_BOTTOM = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
855 MAC1->SPEC_ADD2_TOP = unicastMacAddr[0].w[2];
860 MAC1->SPEC_ADD2_BOTTOM = 0;
867 MAC1->SPEC_ADD3_BOTTOM = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
868 MAC1->SPEC_ADD3_TOP = unicastMacAddr[1].w[2];
873 MAC1->SPEC_ADD3_BOTTOM = 0;
880 MAC1->SPEC_ADD4_BOTTOM = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
881 MAC1->SPEC_ADD4_TOP = unicastMacAddr[2].w[2];
886 MAC1->SPEC_ADD4_BOTTOM = 0;
892 MAC1->NETWORK_CONFIG |= GEM_UNICAST_HASH_ENABLE;
896 MAC1->NETWORK_CONFIG &= ~GEM_UNICAST_HASH_ENABLE;
900 MAC1->HASH_BOTTOM = hashTable[0];
901 MAC1->HASH_TOP = hashTable[1];
923 config =
MAC1->NETWORK_CONFIG;
928 config |= GEM_GIGABIT_MODE_ENABLE;
929 config &= ~GEM_SPEED;
934 config &= ~GEM_GIGABIT_MODE_ENABLE;
940 config &= ~GEM_GIGABIT_MODE_ENABLE;
941 config &= ~GEM_SPEED;
947 config |= GEM_FULL_DUPLEX;
951 config &= ~GEM_FULL_DUPLEX;
955 MAC1->NETWORK_CONFIG = config;
979 temp = GEM_WRITE1 | (GEM_PHY_OP_CL22_WRITE << GEM_OPERATION_SHIFT) |
980 (2 << GEM_WRITE10_SHIFT);
983 temp |= (phyAddr << GEM_PHY_ADDRESS_SHIFT) & GEM_PHY_ADDRESS;
985 temp |= (
regAddr << GEM_REGISTER_ADDRESS_SHIFT) & GEM_REGISTER_ADDRESS;
990 MAC1->PHY_MANAGEMENT = temp;
992 while((
MAC1->NETWORK_STATUS & GEM_MAN_DONE) == 0)
1021 temp = GEM_WRITE1 | (GEM_PHY_OP_CL22_READ << GEM_OPERATION_SHIFT) |
1022 (2 << GEM_WRITE10_SHIFT);
1025 temp |= (phyAddr << GEM_PHY_ADDRESS_SHIFT) & GEM_PHY_ADDRESS;
1027 temp |= (
regAddr << GEM_REGISTER_ADDRESS_SHIFT) & GEM_REGISTER_ADDRESS;
1030 MAC1->PHY_MANAGEMENT = temp;
1032 while((
MAC1->NETWORK_STATUS & GEM_MAN_DONE) == 0)
1037 data = (uint16_t)
MAC1->PHY_MANAGEMENT;