/* ===================================================================*/ LDD_TDeviceData* ETH1_Init(LDD_TUserData *UserDataPtr) { ETH1_TDeviceData *DeviceDataPrv; ETH1_TTxQueueItem *TxQueueItemPtr; ETH1_TRxQueueItem *RxQueueItemPtr; uint8_t* MemPtr; /* Allocate internal device data structure */ /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; DeviceDataPrv->DuplexMode = LDD_ETH_FULL_DUPLEX; /* Store duplex mode configuration */ DeviceDataPrv->FilterMode = LDD_ETH_ACCEPT_BC; /* Store filter mode configuration */ DeviceDataPrv->SleepMode = LDD_ETH_DISABLED; /* Store sleep mode configuration */ DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ DeviceDataPrv->Index = 0U; /* Set the component instance index */ DeviceDataPrv->EventMask = /* Initialize the event mask */ LDD_ETH_ON_FRAME_TRANSMITTED | LDD_ETH_ON_FRAME_RECEIVED | LDD_ETH_ON_FATAL_ERROR |0U; DeviceDataPrv->EnabledMode = TRUE; /* Enable the device clock configuration */ /* SIM_SCGC2: ENET=1 */ SIM_SCGC2 |= SIM_SCGC2_ENET_MASK; ENET_PDD_DisableDevice(ENET_BASE_PTR); DeviceDataPrv->Enabled = FALSE; ENET_PDD_EnableMIBCounters(ENET_BASE_PTR, FALSE); /* Disable statistic counters */ ENET_PDD_ClearMIBCounters(ENET_BASE_PTR); /* Clear statistic counters */ ENET_PDD_EnableMIBCounters(ENET_BASE_PTR, TRUE); /* Enable statistic counters */ /* Set pin assignments */ /* PORTB_PCR1: ISF=0,MUX=4 */ PORTB_PCR1 = (uint32_t)((PORTB_PCR1 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTB_PCR0: ISF=0,MUX=4 */ PORTB_PCR0 = (uint32_t)((PORTB_PCR0 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTA_PCR18: ISF=0,MUX=0 */ PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); /* PORTA_PCR16: ISF=0,MUX=4 */ PORTA_PCR16 = (uint32_t)((PORTA_PCR16 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTA_PCR17: ISF=0,MUX=4 */ PORTA_PCR17 = (uint32_t)((PORTA_PCR17 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTA_PCR15: ISF=0,MUX=4 */ PORTA_PCR15 = (uint32_t)((PORTA_PCR15 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTA_PCR14: ISF=0,MUX=4 */ PORTA_PCR14 = (uint32_t)((PORTA_PCR14 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTA_PCR13: ISF=0,MUX=4 */ PORTA_PCR13 = (uint32_t)((PORTA_PCR13 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* PORTA_PCR12: ISF=0,MUX=4 */ PORTA_PCR12 = (uint32_t)((PORTA_PCR12 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03) )) | (uint32_t)( PORT_PCR_MUX(0x04) )); /* Set interrupt priorities */ /* NVICIP76: PRI76=0x80 */ NVICIP76 = NVIC_IP_PRI76(0x80); /* NVICISER2: SETENA|=0x1000 */ NVICISER2 |= NVIC_ISER_SETENA(0x1000); /* NVICIP77: PRI77=0x80 */ NVICIP77 = NVIC_IP_PRI77(0x80); /* NVICISER2: SETENA|=0x2000 */ NVICISER2 |= NVIC_ISER_SETENA(0x2000); /* NVICIP78: PRI78=0x80 */ NVICIP78 = NVIC_IP_PRI78(0x80); /* NVICISER2: SETENA|=0x4000 */ NVICISER2 |= NVIC_ISER_SETENA(0x4000); /* Set interrupt mask */ /* ENET_EIMR: ??=0,BABR=0,BABT=0,GRA=0,TXF=1,TXB=0,RXF=1,RXB=0,MII=0,EBERR=1,LC=0,RL=0,UN=0,PLR=0,WAKEUP=0,TS_AVAIL=0,TS_TIMER=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ ENET_EIMR = (ENET_EIMR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_EBERR_MASK); /* Clear interrupt flags */ /* ENET_EIR: ??=1,BABR=1,BABT=1,GRA=1,TXF=1,TXB=1,RXF=1,RXB=1,MII=1,EBERR=1,LC=1,RL=1,UN=1,PLR=0,WAKEUP=0,TS_AVAIL=0,TS_TIMER=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ ENET_EIR = ENET_EIR_BABR_MASK | ENET_EIR_BABT_MASK | ENET_EIR_GRA_MASK | ENET_EIR_TXF_MASK | ENET_EIR_TXB_MASK | ENET_EIR_RXF_MASK | ENET_EIR_RXB_MASK | ENET_EIR_MII_MASK | ENET_EIR_EBERR_MASK | ENET_EIR_LC_MASK | ENET_EIR_RL_MASK | ENET_EIR_UN_MASK | 0x80000000U; /* Allocate the transmit frame interrupt vector */ /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ INT_ENET_Transmit__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; /* Allocate the receive frame interrupt vector */ /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ INT_ENET_Receive__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; /* Allocate the shared interrupt vector */ /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ INT_ENET_Error__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; /* Set MAC address */ /* ENET_PALR: PADDR1=0x43EF783A */ ENET_PALR = ENET_PALR_PADDR1(0x43EF783A); /* ENET_PAUR: PADDR2=0x2E19,TYPE=0 */ ENET_PAUR = (ENET_PAUR_PADDR2(0x2E19) | ENET_PAUR_TYPE(0x00)); /* Set unicast address hash table */ /* ENET_IAUR: IADDR1=0 */ ENET_IAUR = ENET_IAUR_IADDR1(0x00); /* ENET_IALR: IADDR2=0 */ ENET_IALR = ENET_IALR_IADDR2(0x00); /* Set multicast address hash table */ /* ENET_GAUR: GADDR1=0 */ ENET_GAUR = ENET_GAUR_GADDR1(0x00); /* ENET_GALR: GADDR2=0 */ ENET_GALR = ENET_GALR_GADDR2(0x00); /* Set PAUSE frame duration */ /* ENET_OPD: OPCODE=0,PAUSE_DUR=0 */ ENET_OPD = (ENET_OPD_OPCODE(0x00) | ENET_OPD_PAUSE_DUR(0x00)); /* Set transmit control register */ /* ENET_TCR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CRCFWD=0,ADDINS=0,ADDSEL=0,RFC_PAUSE=0,TFC_PAUSE=0,FDEN=1,??=0,GTS=0 */ ENET_TCR = (ENET_TCR_ADDSEL(0x00) | ENET_TCR_FDEN_MASK); /* Set transmit accelerator function configuration register */ /* ENET_TACC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,PROCHK=0,IPCHK=0,??=0,??=0,SHIFT16=0 */ ENET_TACC = 0x00U; /* Set receive control register */ /* ENET_RCR: GRS=0,NLC=0,MAX_FL=0x05EE,CFEN=0,CRCFWD=0,PAUFWD=1,PADEN=0,??=0,??=0,RMII_10T=0,RMII_MODE=1,??=0,??=0,FCE=1,BC_REJ=0,PROM=0,MII_MODE=1,DRT=0,LOOP=0 */ ENET_RCR = ENET_RCR_MAX_FL(0x05EE) | ENET_RCR_PAUFWD_MASK | ENET_RCR_RMII_MODE_MASK | ENET_RCR_FCE_MASK | ENET_RCR_MII_MODE_MASK; /* Set receive accelerator function configuration register */ /* ENET_RACC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,SHIFT16=0,LINEDIS=0,??=0,??=0,??=0,PRODIS=0,IPDIS=0,PADREM=0 */ ENET_RACC = 0x00U; /* Set transmit inter-packet gap */ /* ENET_TIPG: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,IPG=8 */ ENET_TIPG = ENET_TIPG_IPG(0x08); /* Set frame truncation length */ /* ENET_FTRL: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TRUNC_FL=0x0800 */ ENET_FTRL = ENET_FTRL_TRUNC_FL(0x0800); /* Set transmit FIFO watermark */ /* ENET_TFWR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,STRFWD=1,??=0,??=0,TFWR=0 */ ENET_TFWR = (ENET_TFWR_STRFWD_MASK | ENET_TFWR_TFWR(0x00)); /* Set transmit FIFO section empty threshold */ /* ENET_TSEM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TX_SECTION_EMPTY=0 */ ENET_TSEM = ENET_TSEM_TX_SECTION_EMPTY(0x00); /* Set transmit FIFO almost empty threshold */ /* ENET_TAEM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TX_ALMOST_EMPTY=8 */ ENET_TAEM = ENET_TAEM_TX_ALMOST_EMPTY(0x08); /* Set transmit FIFO almost full threshold */ /* ENET_TAFL: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TX_ALMOST_FULL=8 */ ENET_TAFL = ENET_TAFL_TX_ALMOST_FULL(0x08); /* Set receive FIFO section full threshold */ /* ENET_RSFL: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,RX_SECTION_FULL=0 */ ENET_RSFL = ENET_RSFL_RX_SECTION_FULL(0x00); /* Set receive FIFO section empty threshold */ /* ENET_RSEM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,RX_SECTION_EMPTY=0 */ ENET_RSEM = ENET_RSEM_RX_SECTION_EMPTY(0x00); /* Set receive FIFO almost empty threshold */ /* ENET_RAEM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,RX_ALMOST_EMPTY=8 */ ENET_RAEM = ENET_RAEM_RX_ALMOST_EMPTY(0x08); /* Set receive FIFO almost full threshold */ /* ENET_RAFL: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,RX_ALMOST_FULL=8 */ ENET_RAFL = ENET_RAFL_RX_ALMOST_FULL(0x08); /* Set MII speed control register */ /* ENET_MSCR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,HOLDTIME=7,DIS_PRE=1,MII_SPEED=3,??=0 */ ENET_MSCR = ENET_MSCR_HOLDTIME(0x07) | ENET_MSCR_DIS_PRE_MASK | ENET_MSCR_MII_SPEED(0x03); /* Set receive buffer size */ /* ENET_MRBR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,R_BUF_SIZE=0,??=0,??=0,??=0,??=0 */ ENET_MRBR = ENET_MRBR_R_BUF_SIZE(0x00); /* Initialize the transmit frame buffer queue */ LDD_QUEUE_INIT(ETH1_TTxQueueItem, DeviceDataPrv->TxQueue, ETH1_QUEUE_MEM_ALIGN); /* Initialize the queue data structure */ TxQueueItemPtr = LDD_QUEUE_GET_DATA_START(DeviceDataPrv->TxQueue); while (TxQueueItemPtr != (LDD_QUEUE_GET_DATA_END(DeviceDataPrv->TxQueue) + 1)) { /* Clear queue item */ for (MemPtr = (uint8_t*)(uint32_t)TxQueueItemPtr; MemPtr != (uint8_t*)(uint32_t)(TxQueueItemPtr + 1); MemPtr++) { *MemPtr = 0U; } TxQueueItemPtr++; /* Move to the next queue item */ } setReg32(ENET_TDSR, LDD_QUEUE_GET_DATA_START(DeviceDataPrv->TxQueue)); /* Initialize the receive frame buffer queue */ LDD_QUEUE_INIT(ETH1_TRxQueueItem, DeviceDataPrv->RxQueue, ETH1_QUEUE_MEM_ALIGN); /* Initialize the queue data structure */ RxQueueItemPtr = LDD_QUEUE_GET_DATA_START(DeviceDataPrv->RxQueue); while (RxQueueItemPtr != (LDD_QUEUE_GET_DATA_END(DeviceDataPrv->RxQueue) + 1)) { /* Clear queue item */ for (MemPtr = (uint8_t*)(uint32_t)RxQueueItemPtr; MemPtr != (uint8_t*)(uint32_t)(RxQueueItemPtr + 1); MemPtr++) { *MemPtr = 0U; } RxQueueItemPtr++; /* Move to the next queue item */ } setReg32(ENET_RDSR, LDD_QUEUE_GET_DATA_START(DeviceDataPrv->RxQueue)); /* ENET_ECR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,DBSWP=0,STOPEN=0,DBGEN=0,??=0,EN1588=0,SLEEP=0,MAGICEN=0,ETHEREN=0,RESET=0 */ ENET_ECR = 0x00U; /* Enable the device */ ENET_PDD_EnableDevice(ENET_BASE_PTR); DeviceDataPrv->Enabled = TRUE; /* Registration of the device structure */ PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_ETH1_ID,DeviceDataPrv); return (LDD_TDeviceData*)DeviceDataPrv; }
uint_32 MACNET_initialize ( ENET_CONTEXT_STRUCT_PTR enet_ptr ) { MACNET_CONTEXT_STRUCT_PTR macnet_context_ptr=NULL; ENET_MemMapPtr macnet_ptr; VENET_BD_STRUCT_PTR bd_ptr; uchar_ptr buf_ptr; MACNET_RX_PCB_PTR pcb_ptr; uint_32 i, rxsize, txsize, ssize, lsize, pcbsize,rx_pcb_size, large_packet_size, rcr; uint_32 timeout, error = ENET_OK; boolean bOK; #if ENETCFG_SUPPORT_PTP MACNET_PTP_PRIVATE_PTR macnet_ptp_ptr = NULL; #endif /* ENETCFG_SUPPORT_PTP */ KERNEL_DATA_STRUCT_PTR kernel_data; _GET_KERNEL_DATA(kernel_data); // Initialize the MACNET I/O Pins MACNET_io_init(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER); macnet_ptr = MACNET_get_base_address(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER); if (macnet_ptr == NULL) { return ENETERR_INVALID_DEVICE; } // currently limit number of TX BDs to 32, as a bitmask is used in the free function. if (enet_ptr->PARAM_PTR->NUM_TX_ENTRIES > 32) { return ENETERR_INVALID_INIT_PARAM; } /* ** This function can be called from any context, and it needs mutual ** exclusion with itself. */ MACNET_int_disable(); macnet_context_ptr = _mem_alloc_system_zero(sizeof(MACNET_CONTEXT_STRUCT)); IF_ERROR_EXIT((NULL==macnet_context_ptr), ENETERR_ALLOC_MAC_CONTEXT); _mem_set_type((pointer)macnet_context_ptr, MEM_TYPE_IO_ENET_MAC_CONTEXT_STRUCT); enet_ptr->MAC_CONTEXT_PTR = (pointer) macnet_context_ptr; macnet_context_ptr->MACNET_ADDRESS = macnet_ptr; macnet_context_ptr->PHY_PTR = MACNET_get_base_address(enet_ptr->PARAM_PTR->ENET_IF->PHY_NUMBER); /* Stop the chip */ macnet_ptr->ECR = ENET_ECR_RESET_MASK; /* wait until the initialization cycle completes */ timeout = 0; while ((macnet_ptr->ECR & ENET_ECR_RESET_MASK) && (timeout<MACNET_RESET_TIMEOUT)){ _time_delay(1); timeout++; } IF_ERROR_EXIT((macnet_ptr->ECR & ENET_ECR_RESET_MASK), ENETERR_INIT_FAILED); /* Disable all MACNET interrupts */ macnet_ptr->EIMR = 0; /* clear any pending interrpts */ macnet_ptr->EIR = ENET_EIR_ALL_PENDING; macnet_context_ptr->NumRxBDs = enet_ptr->PARAM_PTR->NUM_RX_ENTRIES; macnet_context_ptr->NumTxBDs = enet_ptr->PARAM_PTR->NUM_TX_ENTRIES; // Compute aligned buffer sizes if (enet_ptr->PARAM_PTR->TX_BUFFER_SIZE) { macnet_context_ptr->AlignedTxBufferSize = MACNET_TX_ALIGN(enet_ptr->PARAM_PTR->TX_BUFFER_SIZE); } else { macnet_context_ptr->AlignedTxBufferSize = MACNET_TX_ALIGN(enet_ptr->MaxTxFrameSize); } if (enet_ptr->PARAM_PTR->RX_BUFFER_SIZE) { macnet_context_ptr->AlignedRxBufferSize = MACNET_RX_ALIGN(enet_ptr->PARAM_PTR->RX_BUFFER_SIZE); } else { macnet_context_ptr->AlignedRxBufferSize = MACNET_RX_ALIGN(enet_ptr->MaxRxFrameSize); } // Allocate the Transmit and Receive buffer descriptors // TODO remake to using alloc_align fn #if BSPCFG_HAS_SRAM_POOL && BSPCFG_ENET_SRAM_BUF bd_ptr = (VENET_BD_STRUCT_PTR)_mem_alloc_system_zero_from(_BSP_sram_pool, (sizeof(ENET_BD_STRUCT)*(macnet_context_ptr->NumRxBDs+macnet_context_ptr->NumTxBDs))+MACNET_BD_ALIGNMENT); #else bd_ptr = (VENET_BD_STRUCT_PTR) _mem_alloc_system_zero((sizeof(ENET_BD_STRUCT)*(macnet_context_ptr->NumRxBDs+macnet_context_ptr->NumTxBDs))+MACNET_BD_ALIGNMENT); #endif IF_ERROR_EXIT((NULL == bd_ptr), ENETERR_ALLOC_BD); _mem_set_type((pointer)bd_ptr, MEM_TYPE_IO_BD_STRUCT); macnet_context_ptr->UNALIGNED_RING_PTR = (pointer) bd_ptr; macnet_context_ptr->MACNET_RX_RING_PTR = (VENET_BD_STRUCT_PTR) MACNET_BD_ALIGN((uint_32)bd_ptr); macnet_context_ptr->MACNET_TX_RING_PTR = &macnet_context_ptr->MACNET_RX_RING_PTR[macnet_context_ptr->NumRxBDs]; /* Set wrap bit in last BD */ macnet_context_ptr->MACNET_RX_RING_PTR[macnet_context_ptr->NumRxBDs - 1].CONTROL = HOST_TO_BE_SHORT_CONST(ENET_BD_ETHER_RX_WRAP); macnet_context_ptr->MACNET_TX_RING_PTR[macnet_context_ptr->NumTxBDs - 1].CONTROL = HOST_TO_BE_SHORT_CONST(ENET_BD_ETHER_TX_WRAP); macnet_context_ptr->AvailableTxBDs = macnet_context_ptr->NumTxBDs; // Allocate array to hold Transmit PCB pointers while they are queued for transmission macnet_context_ptr->TxPCBS_PTR = (PCB_PTR *) _mem_alloc_system_zero(sizeof(PCB_PTR)*macnet_context_ptr->NumTxBDs); IF_ERROR_EXIT((NULL==macnet_context_ptr->TxPCBS_PTR), ENETERR_ALLOC_PCB); _mem_set_type((pointer)macnet_context_ptr->TxPCBS_PTR, MEM_TYPE_IO_PCB_PTR); // Allocate the Receive PCBs rx_pcb_size = sizeof(MACNET_RX_PCB); pcbsize = enet_ptr->PARAM_PTR->NUM_RX_PCBS * rx_pcb_size; macnet_context_ptr->RX_PCB_BASE = (MACNET_RX_PCB_PTR) _mem_alloc_system_zero(pcbsize); IF_ERROR_EXIT((NULL==macnet_context_ptr->RX_PCB_BASE), ENETERR_ALLOC_PCB); _mem_set_type((pointer)macnet_context_ptr->RX_PCB_BASE, MEM_TYPE_IO_PCB_STRUCT); // Allocate the Transmit and Receive buffers txsize = (enet_ptr->PARAM_PTR->NUM_TX_BUFFERS * macnet_context_ptr->AlignedTxBufferSize) + MACNET_TX_BUFFER_ALIGNMENT; rxsize = (enet_ptr->PARAM_PTR->NUM_RX_BUFFERS * macnet_context_ptr->AlignedRxBufferSize) +MACNET_RX_BUFFER_ALIGNMENT; ssize = (enet_ptr->PARAM_PTR->NUM_SMALL_BUFFERS * MACNET_SMALL_PACKET_SIZE); large_packet_size = enet_ptr->PARAM_PTR->OPTIONS&ENET_OPTION_VLAN ? ENET_FRAMESIZE_VLAN : ENET_FRAMESIZE; lsize = (enet_ptr->PARAM_PTR->NUM_LARGE_BUFFERS * large_packet_size); #if BSPCFG_HAS_SRAM_POOL && BSPCFG_ENET_SRAM_BUF buf_ptr = _mem_alloc_system_from(_BSP_sram_pool, rxsize + txsize + ssize + lsize); #else buf_ptr = _mem_alloc_system(rxsize + txsize + ssize + lsize); #endif IF_ERROR_EXIT((NULL==buf_ptr), ENETERR_ALLOC_BUFFERS); _mem_set_type(buf_ptr, MEM_TYPE_IO_ENET_BUFFERS); macnet_context_ptr->UNALIGNED_BUFFERS = buf_ptr; // Align to TX buffer boundary buf_ptr = (uchar_ptr)MACNET_TX_ALIGN((uint_32)buf_ptr); // Queue packets on TX Buffer Q. macnet_context_ptr->TX_BUFFERS = NULL; for (i=0;i<enet_ptr->PARAM_PTR->NUM_TX_BUFFERS;i++) { ENET_Enqueue_Buffer((pointer *)&macnet_context_ptr->TX_BUFFERS, buf_ptr); buf_ptr += macnet_context_ptr->AlignedTxBufferSize; } // Align to RX buffer boundary buf_ptr = (uchar_ptr)MACNET_RX_ALIGN((uint_32)buf_ptr); // Queue packets on RX Buffer Q. macnet_context_ptr->RX_BUFFERS = NULL; for (i=0;i<enet_ptr->PARAM_PTR->NUM_RX_BUFFERS;i++) { ENET_Enqueue_Buffer((pointer *)&macnet_context_ptr->RX_BUFFERS, buf_ptr); buf_ptr += macnet_context_ptr->AlignedRxBufferSize; } // Queue small packets on small buffer Q. for (i=0;i<enet_ptr->PARAM_PTR->NUM_SMALL_BUFFERS;i++) { ENET_Enqueue_Buffer((pointer *)&macnet_context_ptr->SMALL_BUFFERS, buf_ptr); buf_ptr += MACNET_SMALL_PACKET_SIZE; } // Queue large packets on large buffer Q. for (i=0;i<enet_ptr->PARAM_PTR->NUM_LARGE_BUFFERS;i++) { ENET_Enqueue_Buffer((pointer *)&macnet_context_ptr->LARGE_BUFFERS, buf_ptr); buf_ptr += large_packet_size; } // Enqueue the RX PCBs onto the receive PCB queue pcb_ptr = macnet_context_ptr->RX_PCB_BASE; for (i = 0; i < enet_ptr->PARAM_PTR->NUM_RX_PCBS; i++) { QADD(macnet_context_ptr->RxPCBHead, macnet_context_ptr->RxPCBTail, (PCB_PTR) pcb_ptr); pcb_ptr++; } // Fill up the receive ring MACNET_add_buffers_to_rx_ring(macnet_context_ptr); /* Program this station's Ethernet physical address */ macnet_ptr->PALR = HOST_TO_BE_LONG(*(uint_32_ptr) &enet_ptr->ADDRESS[0]); macnet_ptr->PAUR = HOST_TO_BE_SHORT((*(uint_16_ptr)(&enet_ptr->ADDRESS[4]))) << 16; // Clear the individual hash table registers macnet_ptr->IAUR = 0; macnet_ptr->IALR = 0; // Clear the group hash table registers macnet_ptr->GAUR = 0; macnet_ptr->GALR = 0; /* Program receive buffer size */ macnet_ptr->MRBR = macnet_context_ptr->AlignedRxBufferSize; // Configure start of Rx and Tx BD rings macnet_ptr->RDSR = (uint_32)(macnet_context_ptr->MACNET_RX_RING_PTR); macnet_ptr->TDSR = (uint_32)(macnet_context_ptr->MACNET_TX_RING_PTR); // Set Receive Frame size // NOTE: Oddly, the Receive Control Register (RCR) afmacnetts the transmit side too. The RCR is used to determine if the // transmitter is babbling, which means, if the RX buffer size < Tx Buffer size, we can get babling transmitter // errors if we set RCR to the maximum Receive frame length. We really have no choice but to set RCR to one // of ENET_FRAMESIZE or ENET_FRAMESIZE_VLAN. // rcr = ENET_RCR_MII_MODE_MASK | (ENET_RCR_MAX_FL_MASK & (large_packet_size << ENET_RCR_MAX_FL_SHIFT)); if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_RMII) { rcr |= ENET_RCR_RMII_MODE_MASK; } else if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_7WIRE) { rcr &= ~ENET_RCR_MII_MODE_MASK; } macnet_ptr->RCR = rcr; if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_MAC_LOOPBACK) { macnet_ptr->RCR |= ENET_RCR_LOOP_MASK; } // Set Full/Half duplex based on mode. if (enet_ptr->PARAM_PTR->MODE & ENET_HALF_DUPLEX) { macnet_ptr->TCR = 0; // half duplex } else { macnet_ptr->TCR = 4; // full duplex } // Enable MII_SPEED register i = (MACNET_device[enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER].BUS_CLOCK / enet_ptr->PARAM_PTR->ENET_IF->PHY_MII_SPEED + 1) & ~1; if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_NO_PREAMBLE) { i |= ENET_MSCR_DIS_PRE_MASK; } macnet_context_ptr->PHY_PTR->MSCR = i; // Zero counters macnet_ptr->MIBC |= ENET_MIBC_MIB_CLEAR_MASK; // Install the ISRs bOK = MACNET_install_isrs( enet_ptr, &MACNET_device[enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER] ); IF_ERROR_EXIT(!bOK, ENETERR_INSTALL_ISR); // Unmask transmit/receive interrupts // NOTE: need to enable both RXF and RXB, but only TXB, as RXB does not get generated with RXF, // but TXB does get generated with TXF // However, on 52259, enabling RXB is resulting in an HBERR interrupt. RXB is not required, so leave it disabled. macnet_ptr->EIMR = ENET_EIR_TXB_MASK | ENET_EIR_RXF_MASK; // Enable MACNET macnet_ptr->ECR = (ENET_ECR_ETHEREN_MASK | ENET_ECR_EN1588_MASK); // Discover PHY address if PHY_DISCOVER option is set if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PHY_DISCOVER) { bOK = (*enet_ptr->PARAM_PTR->ENET_IF->PHY_IF->DISCOVER)(enet_ptr); IF_ERROR_EXIT(!bOK, ENETERR_INIT_FAILED); } else { // Set Phy address from initialization parameter enet_ptr->PHY_ADDRESS = enet_ptr->PARAM_PTR->ENET_IF->PHY_ADDRESS; } // Enable STORE & FORWARD mode if (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_STORE_AND_FORW) { macnet_ptr->TFWR |= ENET_TFWR_STRFWD_MASK; macnet_ptr->RSFL |= ENET_RSFL_RX_SECTION_FULL(0); } // Perform Phy initialization bOK = (*enet_ptr->PARAM_PTR->ENET_IF->PHY_IF->INIT)(enet_ptr); IF_ERROR_EXIT(!bOK, ENETERR_INIT_FAILED); // Signals the MACNET that empty buffers are available. // It is NECESSARY to do this AFTER enabling the MACNET. macnet_ptr->RDAR = ENET_RDAR_RDAR_MASK; #if ENETCFG_SUPPORT_PTP macnet_ptp_ptr = _mem_alloc_system_zero(sizeof(MACNET_PTP_PRIVATE)); IF_ERROR_EXIT((NULL==macnet_context_ptr), ENETERR_ALLOC_MAC_CONTEXT); macnet_ptp_ptr->MACNET_PTR = macnet_context_ptr->MACNET_ADDRESS; macnet_ptp_ptr->PTIMER_PRESENT = 1; bOK = _lwevent_create(&(macnet_ptp_ptr->LWEVENT_PTP), 0); IF_ERROR_EXIT(bOK, ENETERR_1588_LWEVENT); macnet_ptp_ptr->TXSTAMP = (MACNET_PTP_TIME){0,0}; macnet_ptp_ptr->L2PCKS_PTR = NULL; macnet_context_ptr->PTP_PRIV = macnet_ptp_ptr; MACNET_ptp_init(enet_ptr); if (macnet_ptp_ptr->PTIMER_PRESENT) { /* Set Timer count */ MACNET_ptp_start(macnet_ptp_ptr, (enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PTP_MASTER_CLK)); if(enet_ptr->PARAM_PTR->OPTIONS & ENET_OPTION_PTP_MASTER_CLK) MACNET_ptp_set_master_base_address(macnet_ptr); macnet_ptp_ptr->MACNET_PTR->ECR |= ENET_ECR_EN1588_MASK; } /* Enable timer-relative interrupts */ macnet_ptp_ptr->MACNET_PTR->EIMR |= (ENET_EIR_TS_TIMER_MASK | ENET_EIR_TS_AVAIL_MASK); #endif /* ENETCFG_SUPPORT_PTP */ // control transfers to this point on any error, with error set to error code. EXIT: if (ENET_OK!=error) { #if BSPCFG_ENET_RESTORE MACNET_uninstall_all_isrs(enet_ptr); #endif MACNET_free_context(macnet_context_ptr); } MACNET_int_enable(); return error; }