diff --git a/source/FreeRTOS_DNS_Parser.c b/source/FreeRTOS_DNS_Parser.c index dcd1c731b5..24a3c32df2 100644 --- a/source/FreeRTOS_DNS_Parser.c +++ b/source/FreeRTOS_DNS_Parser.c @@ -585,7 +585,7 @@ prepareReplyDNSMessage( pxNetworkBuffer, usLength ); /* This function will fill in the eth addresses and send the packet */ vReturnEthernetFrame( pxNetworkBuffer, pdFALSE ); - + if( pxNewBuffer != NULL ) { vReleaseNetworkBufferAndDescriptor( pxNewBuffer ); diff --git a/source/portable/NetworkInterface/DriverSAM/NetworkInterface.c b/source/portable/NetworkInterface/DriverSAM/NetworkInterface.c index 402865aaf7..c732d4efe3 100644 --- a/source/portable/NetworkInterface/DriverSAM/NetworkInterface.c +++ b/source/portable/NetworkInterface/DriverSAM/NetworkInterface.c @@ -1,8 +1,6 @@ /* - * FreeRTOS+TCP - * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT + * FreeRTOS+TCP V2.3.1 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -40,7 +38,9 @@ #include "FreeRTOS_IP.h" #include "FreeRTOS_Sockets.h" #include "FreeRTOS_IP_Private.h" +#include "FreeRTOS_DNS.h" #include "FreeRTOS_ARP.h" +#include "FreeRTOS_Routing.h" #include "NetworkBufferManagement.h" #include "NetworkInterface.h" @@ -172,13 +172,22 @@ static void prvEMACHandlerTask( void * pvParameters ); /* * Initialise the ASF GMAC driver. */ -static BaseType_t prvGMACInit( void ); +static BaseType_t prvGMACInit( NetworkInterface_t * pxInterface ); /* * Try to obtain an Rx packet from the hardware. */ static uint32_t prvEMACRxPoll( void ); +static BaseType_t prvSAM_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface ); +static BaseType_t prvSAM_NetworkInterfaceOutput( NetworkInterface_t * pxInterface, + NetworkBufferDescriptor_t * const pxBuffer, + BaseType_t bReleaseAfterSend ); +static BaseType_t prvSAM_GetPhyLinkStatus( NetworkInterface_t * pxInterface ); + +NetworkInterface_t * pxSAM_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ); + /* * Handle transmission errors. */ @@ -200,11 +209,16 @@ static const uint8_t llmnr_mac_address[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC /* The GMAC object as defined by the ASF drivers. */ static gmac_device_t gs_gmac_dev; +/* MAC address to use. */ +extern const uint8_t ucMACAddress[ 6 ]; + /* Holds the handle of the task used as a deferred interrupt processor. The * handle is used so direct notifications can be sent to the task for all EMAC/DMA * related interrupts. */ TaskHandle_t xEMACTaskHandle = NULL; +static NetworkInterface_t * pxMyInterface = NULL; + static QueueHandle_t xTxBufferQueue; int tx_release_count[ 4 ]; @@ -421,13 +435,13 @@ static BaseType_t xPHY_Write( BaseType_t xAddress, } /*-----------------------------------------------------------*/ -BaseType_t xNetworkInterfaceInitialise( void ) +static BaseType_t prvSAM_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface ) { const TickType_t x5_Seconds = 5000UL; if( xEMACTaskHandle == NULL ) { - prvGMACInit(); + prvGMACInit( pxInterface ); cache_clean_invalidate(); @@ -435,6 +449,7 @@ BaseType_t xNetworkInterfaceInitialise( void ) * ensure the interrupt handler can return directly to it. */ xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &xEMACTaskHandle ); configASSERT( xEMACTaskHandle ); + pxMyInterface = pxInterface; } if( xTxBufferQueue == NULL ) @@ -451,14 +466,54 @@ BaseType_t xNetworkInterfaceInitialise( void ) /* When returning non-zero, the stack will become active and * start DHCP (in configured) */ - return xGetPhyLinkStatus(); + return prvSAM_GetPhyLinkStatus( NULL ); } /*-----------------------------------------------------------*/ -BaseType_t xGetPhyLinkStatus( void ) +#if ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) + +/* Do not call the following function directly. It is there for downward compatibility. + * The function FreeRTOS_IPInit() will call it to initialice the interface and end-point + * objects. See the description in FreeRTOS_Routing.h. */ + NetworkInterface_t * pxFillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ) + { + pxSAM_FillInterfaceDescriptor( xEMACIndex, pxInterface ); + } + +#endif /* ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) */ +/*-----------------------------------------------------------*/ + +NetworkInterface_t * pxSAM_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ) +{ +/* This function pxSAM_FillInterfaceDescriptor() adds a network-interface. + * Make sure that the object pointed to by 'pxInterface' + * is declared static or global, and that it will remain to exist. */ + + memset( pxInterface, '\0', sizeof( *pxInterface ) ); + pxInterface->pcName = "GMAC"; /* Just for logging, debugging. */ + pxInterface->pvArgument = ( void * ) xEMACIndex; /* Has only meaning for the driver functions. */ + pxInterface->pfInitialise = prvSAM_NetworkInterfaceInitialise; + pxInterface->pfOutput = prvSAM_NetworkInterfaceOutput; + pxInterface->pfGetPhyLinkStatus = prvSAM_GetPhyLinkStatus; + + return pxInterface; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvSAM_GetPhyLinkStatus( NetworkInterface_t * pxInterface ) { BaseType_t xReturn; + /*_RB_ Will this parameter be used by any port? */ + + /*_HT_ I think it will if there are two instances of an EMAC that share + * the same driver and obviously get a different 'NetworkInterface_t'. */ + /* Avoid warning about unused parameter. */ + ( void ) pxInterface; + + /* This function returns true if the Link Status in the PHY is high. */ if( xPhyObject.ulLinkStatusMask != 0 ) { xReturn = pdPASS; @@ -494,13 +549,16 @@ static void hand_tx_errors( void ) volatile IPPacket_t * pxSendPacket; -BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, - BaseType_t bReleaseAfterSend ) +static BaseType_t prvSAM_NetworkInterfaceOutput( NetworkInterface_t * pxInterface, + NetworkBufferDescriptor_t * const pxDescriptor, + BaseType_t bReleaseAfterSend ) { /* Do not wait too long for a free TX DMA buffer. */ const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u ); uint32_t ulTransmitSize; + /* Avoid warning about unused parameter. */ + ( void ) pxInterface; ulTransmitSize = pxDescriptor->xDataLength; pxSendPacket = ( IPPacket_t * ) pxDescriptor->pucEthernetBuffer; @@ -514,6 +572,15 @@ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescript * statement. */ do { + if( xCheckLoopback( pxDescriptor, bReleaseAfterSend ) != 0 ) + { + /* The packet has been sent back to the IP-task. + * The IP-task will further handle it. + * Do not release the descriptor. */ + bReleaseAfterSend = pdFALSE; + break; + } + if( xPhyObject.ulLinkStatusMask == 0ul ) { /* Do not attempt to send packets as long as the Link Status is low. */ @@ -571,12 +638,17 @@ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescript } /*-----------------------------------------------------------*/ -static BaseType_t prvGMACInit( void ) +static BaseType_t prvGMACInit( NetworkInterface_t * pxInterface ) { uint32_t ncfgr; + NetworkEndPoint_t * pxEndPoint; + BaseType_t xEntry = 1; gmac_options_t gmac_option; + pxEndPoint = FreeRTOS_FirstEndPoint( pxInterface ); + configASSERT( pxEndPoint != NULL ); + gmac_enable_management( GMAC, true ); /* Enable further GMAC maintenance. */ GMAC->GMAC_NCR |= GMAC_NCR_MPE; @@ -584,7 +656,7 @@ static BaseType_t prvGMACInit( void ) memset( &gmac_option, '\0', sizeof( gmac_option ) ); gmac_option.uc_copy_all_frame = 0; gmac_option.uc_no_boardcast = 0; - memcpy( gmac_option.uc_mac_addr, ipLOCAL_MAC_ADDRESS, sizeof( gmac_option.uc_mac_addr ) ); + memcpy( gmac_option.uc_mac_addr, pxEndPoint->xMACAddress.ucBytes, sizeof( gmac_option.uc_mac_addr ) ); gs_gmac_dev.p_hw = GMAC; gmac_dev_init( GMAC, &gs_gmac_dev, &gmac_option ); @@ -592,6 +664,38 @@ static BaseType_t prvGMACInit( void ) NVIC_SetPriority( GMAC_IRQn, configMAC_INTERRUPT_PRIORITY ); NVIC_EnableIRQ( GMAC_IRQn ); + #if ( ipconfigUSE_LLMNR == 1 ) + { + gmac_set_address( GMAC, xEntry++, xLLMNR_MacAdress.ucBytes ); + } + #endif /* ipconfigUSE_LLMNR */ + + #if ( ipconfigUSE_IPv6 != 0 ) + { + NetworkEndPoint_t * pxEndPoint; + #if ( ipconfigUSE_LLMNR == 1 ) + { + gmac_set_address( GMAC, xEntry++, ( uint8_t * ) xLLMNR_MacAdressIPv6.ucBytes ); + } + #endif /* ipconfigUSE_LLMNR */ + + for( pxEndPoint = FreeRTOS_FirstEndPoint( pxMyInterface ); + pxEndPoint != NULL; + pxEndPoint = FreeRTOS_NextEndPoint( pxMyInterface, pxEndPoint ) ) + { + if( pxEndPoint->bits.bIPv6 != pdFALSE_UNSIGNED ) + { + uint8_t ucMACAddress[ 6 ] = { 0x33, 0x33, 0xff, 0, 0, 0 }; + + ucMACAddress[ 3 ] = pxEndPoint->ipv6_settings.xIPAddress.ucBytes[ 13 ]; + ucMACAddress[ 4 ] = pxEndPoint->ipv6_settings.xIPAddress.ucBytes[ 14 ]; + ucMACAddress[ 5 ] = pxEndPoint->ipv6_settings.xIPAddress.ucBytes[ 15 ]; + gmac_set_address( GMAC, xEntry++, ucMACAddress ); + } + } + } + #endif /* ipconfigUSE_IPv6 */ + { /* Set MDC clock divider. */ gmac_set_mdc_clock( GMAC, sysclk_get_cpu_hz() ); @@ -798,6 +902,8 @@ static uint32_t prvEMACRxPoll( void ) #endif /* ipconfigZERO_COPY_RX_DRIVER */ pxNextNetworkBufferDescriptor->xDataLength = ( size_t ) ulReceiveCount; + pxNextNetworkBufferDescriptor->pxInterface = pxMyInterface; + pxNextNetworkBufferDescriptor->pxEndPoint = FreeRTOS_MatchingEndpoint( pxMyInterface, pxCurDescriptor->pucEthernetBuffer ); xRxEvent.pvData = ( void * ) pxNextNetworkBufferDescriptor; /* Send the descriptor to the IP task for processing. */ @@ -820,6 +926,54 @@ static uint32_t prvEMACRxPoll( void ) } /*-----------------------------------------------------------*/ +volatile UBaseType_t uxLastMinBufferCount = 0; +#if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 ) + volatile UBaseType_t uxLastMinQueueSpace; +#endif +volatile UBaseType_t uxCurrentSemCount; +volatile UBaseType_t uxLowestSemCount; + +void vCheckBuffersAndQueue( void ) +{ + static UBaseType_t uxCurrentCount; + + #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 ) + { + uxCurrentCount = uxGetMinimumIPQueueSpace(); + + if( uxLastMinQueueSpace != uxCurrentCount ) + { + /* The logging produced below may be helpful + * while tuning +TCP: see how many buffers are in use. */ + uxLastMinQueueSpace = uxCurrentCount; + FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) ); + } + } + #endif /* ipconfigCHECK_IP_QUEUE_SPACE */ + uxCurrentCount = uxGetMinimumFreeNetworkBuffers(); + + if( uxLastMinBufferCount != uxCurrentCount ) + { + /* The logging produced below may be helpful + * while tuning +TCP: see how many buffers are in use. */ + uxLastMinBufferCount = uxCurrentCount; + FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n", + uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) ); + } + + if( xTXDescriptorSemaphore != NULL ) + { + uxCurrentSemCount = uxSemaphoreGetCount( xTXDescriptorSemaphore ); + + if( uxLowestSemCount > uxCurrentSemCount ) + { + uxLowestSemCount = uxCurrentSemCount; + FreeRTOS_printf( ( "TX DMA buffers: lowest %lu\n", uxLowestSemCount ) ); + } + } +} +/*-----------------------------------------------------------*/ + extern uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * NETWORK_BUFFER_SIZE ]; void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] ) { @@ -840,7 +994,6 @@ void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkB static void prvEMACHandlerTask( void * pvParameters ) { UBaseType_t uxCount; - UBaseType_t uxLowestSemCount = 0; #if ( ipconfigZERO_COPY_TX_DRIVER != 0 ) NetworkBufferDescriptor_t * pxBuffer; @@ -858,26 +1011,7 @@ static void prvEMACHandlerTask( void * pvParameters ) for( ; ; ) { xResult = 0; - - #if ( ipconfigHAS_PRINTF != 0 ) - { - /* Call a function that monitors resources: the amount of free network - * buffers and the amount of free space on the heap. See FreeRTOS_IP.c - * for more detailed comments. */ - vPrintResourceStats(); - - if( xTXDescriptorSemaphore != NULL ) - { - UBaseType_t uxCurrentSemCount = uxSemaphoreGetCount( xTXDescriptorSemaphore ); - - if( uxLowestSemCount > uxCurrentSemCount ) - { - uxLowestSemCount = uxCurrentSemCount; - FreeRTOS_printf( ( "TX DMA buffers: lowest %lu\n", uxLowestSemCount ) ); - } - } - } - #endif /* ( ipconfigHAS_PRINTF != 0 ) */ + vCheckBuffersAndQueue(); if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 ) { diff --git a/source/portable/NetworkInterface/MPS2_AN385/NetworkInterface.c b/source/portable/NetworkInterface/MPS2_AN385/NetworkInterface.c index 960a8cec41..e90d1394c9 100644 --- a/source/portable/NetworkInterface/MPS2_AN385/NetworkInterface.c +++ b/source/portable/NetworkInterface/MPS2_AN385/NetworkInterface.c @@ -82,6 +82,22 @@ static void prvSetMACAddress( void ); /*-----------------------------------------------------------*/ +/* + * A pointer to the network interface is needed later when receiving packets. + */ +static NetworkInterface_t * pxMyInterface; + +static BaseType_t xMPS2_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface ); +static BaseType_t xMPS2_NetworkInterfaceOutput( NetworkInterface_t * pxInterface, + NetworkBufferDescriptor_t * const pxNetworkBuffer, + BaseType_t bReleaseAfterSend ); +static BaseType_t xMPS2_GetPhyLinkStatus( NetworkInterface_t * pxInterface ); + +NetworkInterface_t * pxMPS2_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ); + +/*-----------------------------------------------------------*/ + static const struct smsc9220_eth_dev_cfg_t SMSC9220_ETH_DEV_CFG = { .base = SMSC9220_BASE @@ -145,6 +161,10 @@ static void prvRxTask( void * pvParameters ) { xRxEvent.pvData = ( void * ) pxNetworkBuffer; + pxNetworkBuffer->pxInterface = pxMyInterface; + pxNetworkBuffer->pxEndPoint = FreeRTOS_MatchingEndpoint( pxMyInterface, pxNetworkBuffer->pucEthernetBuffer ); + pxNetworkBuffer->pxEndPoint = pxNetworkEndPoints; /*temporary change for single end point */ + if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL ) { vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer ); @@ -218,13 +238,15 @@ void EthernetISR( void ) } /*-----------------------------------------------------------*/ -BaseType_t xNetworkInterfaceInitialise( void ) +static BaseType_t xMPS2_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface ) { const struct smsc9220_eth_dev_t * dev = &SMSC9220_ETH_DEV; const uint32_t ulEthernetIRQ = 13UL; BaseType_t xReturn = pdFAIL; enum smsc9220_error_t err; + ( void ) pxInterface; + if( xRxTaskHandle == NULL ) { /* Task has not been created before. */ @@ -296,13 +318,16 @@ BaseType_t xNetworkInterfaceInitialise( void ) } /*-----------------------------------------------------------*/ -BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, - BaseType_t xReleaseAfterSend ) +static BaseType_t xMPS2_NetworkInterfaceOutput( NetworkInterface_t * pxInterface, + NetworkBufferDescriptor_t * const pxNetworkBuffer, + BaseType_t xReleaseAfterSend ) { const struct smsc9220_eth_dev_t * dev = &SMSC9220_ETH_DEV; enum smsc9220_error_t error = SMSC9220_ERROR_NONE; BaseType_t xReturn = pdFAIL, x; + ( void ) pxInterface; + for( x = 0; x < niMAX_TX_ATTEMPTS; x++ ) { if( pxNetworkBuffer->xDataLength < SMSC9220_ETH_MAX_FRAME_SIZE ) @@ -355,12 +380,14 @@ void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkB } /*-----------------------------------------------------------*/ -BaseType_t xGetPhyLinkStatus( void ) + +static BaseType_t xMPS2_GetPhyLinkStatus( NetworkInterface_t * pxInterface ) { const struct smsc9220_eth_dev_t * dev = &SMSC9220_ETH_DEV; uint32_t ulPHYBasicStatusValue; BaseType_t xLinkStatusUp; + ( void ) pxInterface; /* Get current status */ smsc9220_phy_regread( dev, SMSC9220_PHY_REG_OFFSET_BSTATUS, &ulPHYBasicStatusValue ); @@ -368,3 +395,32 @@ BaseType_t xGetPhyLinkStatus( void ) ( 1ul << ( PHY_REG_BSTATUS_LINK_STATUS_INDEX ) ) ); return xLinkStatusUp; } + +/*-----------------------------------------------------------*/ + + +NetworkInterface_t * pxMPS2_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ) +{ + static char pcName[ 17 ]; + +/* This function pxFillInterfaceDescriptor() adds a network-interface. + * Make sure that the object pointed to by 'pxInterface' + * is declared static or global, and that it will remain to exist. */ + + pxMyInterface = pxInterface; + + snprintf( pcName, sizeof( pcName ), "eth%ld", xEMACIndex ); + + memset( pxInterface, '\0', sizeof( *pxInterface ) ); + pxInterface->pcName = pcName; /* Just for logging, debugging. */ + pxInterface->pvArgument = ( void * ) xEMACIndex; /* Has only meaning for the driver functions. */ + pxInterface->pfInitialise = xMPS2_NetworkInterfaceInitialise; + pxInterface->pfOutput = xMPS2_NetworkInterfaceOutput; + pxInterface->pfGetPhyLinkStatus = xMPS2_GetPhyLinkStatus; + + FreeRTOS_AddNetworkInterface( pxInterface ); + + return pxInterface; +} +/*-----------------------------------------------------------*/ diff --git a/source/portable/NetworkInterface/STM32Hxx/NetworkInterface.c b/source/portable/NetworkInterface/STM32Hxx/NetworkInterface.c index 68634469eb..45c9bb2bae 100644 --- a/source/portable/NetworkInterface/STM32Hxx/NetworkInterface.c +++ b/source/portable/NetworkInterface/STM32Hxx/NetworkInterface.c @@ -4,10 +4,8 @@ */ /* - * FreeRTOS+TCP - * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT + * FreeRTOS+TCP V2.3.2 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -183,17 +181,16 @@ static size_t uxGetOwnCount( ETH_HandleTypeDef * heth ); * They can be defined as static because the function addresses * addresses will be stored in struct NetworkInterface_t. */ -static BaseType_t xNetworkInterfaceInitialise( NetworkInterface_t * pxInterface ); - -static BaseType_t xNetworkInterfaceOutput( NetworkInterface_t * pxInterface, - NetworkBufferDescriptor_t * const pxBuffer, - BaseType_t xReleaseAfterSend ); +static BaseType_t xSTM32H_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface ); -static BaseType_t xGetPhyLinkStatus( NetworkInterface_t * pxInterface ); +static BaseType_t xSTM32H_NetworkInterfaceOutput( NetworkInterface_t * pxInterface, + NetworkBufferDescriptor_t * const pxBuffer, + BaseType_t xReleaseAfterSend ); -NetworkInterface_t * pxFillInterfaceDescriptor( BaseType_t xEMACIndex, - NetworkInterface_t * pxInterface ); +static BaseType_t xSTM32H_GetPhyLinkStatus( NetworkInterface_t * pxInterface ); +NetworkInterface_t * pxSTM32H_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ); /*-----------------------------------------------------------*/ static EthernetPhy_t xPhyObject; @@ -229,9 +226,9 @@ static uint8_t * pucGetRXBuffer( size_t uxSize ) } /*-----------------------------------------------------------*/ -static BaseType_t xNetworkInterfaceInitialise( NetworkInterface_t * pxInterface ) +static BaseType_t xSTM32H_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface ) { - BaseType_t xResult = pdFAIL; + BaseType_t xResult; NetworkEndPoint_t * pxEndPoint; HAL_StatusTypeDef xHalEthInitStatus; size_t uxIndex = 0; @@ -239,6 +236,7 @@ static BaseType_t xNetworkInterfaceInitialise( NetworkInterface_t * pxInterface if( xMacInitStatus == eMACInit ) { pxMyInterface = pxInterface; + pxEndPoint = FreeRTOS_FirstEndPoint( pxInterface ); configASSERT( pxEndPoint != NULL ); @@ -260,73 +258,69 @@ static BaseType_t xNetworkInterfaceInitialise( NetworkInterface_t * pxInterface xHalEthInitStatus = HAL_ETH_Init( &( xEthHandle ) ); - if( xHalEthInitStatus == HAL_OK ) + /* Only for inspection by debugger. */ + ( void ) xHalEthInitStatus; + + /* Configuration for HAL_ETH_Transmit(_IT). */ + memset( &( xTxConfig ), 0, sizeof( ETH_TxPacketConfig ) ); + xTxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CRCPAD; + + #if ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 ) + { + /*xTxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC; */ + xTxConfig.Attributes |= ETH_TX_PACKETS_FEATURES_CSUM; + xTxConfig.ChecksumCtrl = ETH_DMATXNDESCRF_CIC_IPHDR_PAYLOAD_INSERT_PHDR_CALC; + } + #else + { + xTxConfig.ChecksumCtrl = ETH_CHECKSUM_DISABLE; + } + #endif + xTxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT; + + /* This counting semaphore will count the number of free TX DMA descriptors. */ + xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TX_DESC_CNT, ( UBaseType_t ) ETH_TX_DESC_CNT ); + configASSERT( xTXDescriptorSemaphore ); + + xTransmissionMutex = xSemaphoreCreateMutex(); + configASSERT( xTransmissionMutex ); + + /* Assign Rx memory buffers to a DMA Rx descriptor */ + for( uxIndex = 0; uxIndex < ETH_RX_DESC_CNT; uxIndex++ ) { - /* Configuration for HAL_ETH_Transmit(_IT). */ - memset( &( xTxConfig ), 0, sizeof( ETH_TxPacketConfig ) ); - xTxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CRCPAD; + uint8_t * pucBuffer; - #if ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 ) + #if ( ipconfigZERO_COPY_RX_DRIVER != 0 ) { - /*xTxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC; */ - xTxConfig.Attributes |= ETH_TX_PACKETS_FEATURES_CSUM; - xTxConfig.ChecksumCtrl = ETH_DMATXNDESCRF_CIC_IPHDR_PAYLOAD_INSERT_PHDR_CALC; + pucBuffer = pucGetRXBuffer( ETH_RX_BUF_SIZE ); + configASSERT( pucBuffer != NULL ); } #else { - xTxConfig.ChecksumCtrl = ETH_CHECKSUM_DISABLE; + pucBuffer = Rx_Buff[ uxIndex ]; } #endif - xTxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT; - - /* This counting semaphore will count the number of free TX DMA descriptors. */ - xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TX_DESC_CNT, ( UBaseType_t ) ETH_TX_DESC_CNT ); - configASSERT( xTXDescriptorSemaphore ); - - xTransmissionMutex = xSemaphoreCreateMutex(); - configASSERT( xTransmissionMutex ); - - /* Assign Rx memory buffers to a DMA Rx descriptor */ - for( uxIndex = 0; uxIndex < ETH_RX_DESC_CNT; uxIndex++ ) - { - uint8_t * pucBuffer; - - #if ( ipconfigZERO_COPY_RX_DRIVER != 0 ) - { - pucBuffer = pucGetRXBuffer( ETH_RX_BUF_SIZE ); - configASSERT( pucBuffer != NULL ); - } - #else - { - pucBuffer = Rx_Buff[ uxIndex ]; - } - #endif - HAL_ETH_DescAssignMemory( &( xEthHandle ), uxIndex, pucBuffer, NULL ); - } + HAL_ETH_DescAssignMemory( &( xEthHandle ), uxIndex, pucBuffer, NULL ); + } - /* Configure the MDIO Clock */ - HAL_ETH_SetMDIOClockRange( &( xEthHandle ) ); + /* Configure the MDIO Clock */ + HAL_ETH_SetMDIOClockRange( &( xEthHandle ) ); - /* Initialize the MACB and set all PHY properties */ - prvMACBProbePhy(); + /* Initialize the MACB and set all PHY properties */ + prvMACBProbePhy(); - /* Force a negotiation with the Switch or Router and wait for LS. */ - prvEthernetUpdateConfig( pdTRUE ); + /* Force a negotiation with the Switch or Router and wait for LS. */ + prvEthernetUpdateConfig( pdTRUE ); - /* The deferred interrupt handler task is created at the highest - * possible priority to ensure the interrupt handler can return directly - * to it. The task's handle is stored in xEMACTaskHandle so interrupts can - * notify the task when there is something to process. */ - if( xTaskCreate( prvEMACHandlerTask, niEMAC_HANDLER_TASK_NAME, niEMAC_HANDLER_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &( xEMACTaskHandle ) ) == pdPASS ) - { - /* The task was created successfully. */ - xMacInitStatus = eMACPass; - } - else - { - xMacInitStatus = eMACFailed; - } + /* The deferred interrupt handler task is created at the highest + * possible priority to ensure the interrupt handler can return directly + * to it. The task's handle is stored in xEMACTaskHandle so interrupts can + * notify the task when there is something to process. */ + if( xTaskCreate( prvEMACHandlerTask, niEMAC_HANDLER_TASK_NAME, niEMAC_HANDLER_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &( xEMACTaskHandle ) ) == pdPASS ) + { + /* The task was created successfully. */ + xMacInitStatus = eMACPass; } else { @@ -334,7 +328,12 @@ static BaseType_t xNetworkInterfaceInitialise( NetworkInterface_t * pxInterface } } /* ( xMacInitStatus == eMACInit ) */ - if( xMacInitStatus == eMACPass ) + if( xMacInitStatus != eMACPass ) + { + /* EMAC initialisation failed, return pdFAIL. */ + xResult = pdFAIL; + } + else { if( xPhyObject.ulLinkStatusMask != 0uL ) { @@ -348,18 +347,14 @@ static BaseType_t xNetworkInterfaceInitialise( NetworkInterface_t * pxInterface xResult = pdFAIL; } } - else - { - xResult = pdFAIL; - } return xResult; } /*-----------------------------------------------------------*/ -static BaseType_t xGetPhyLinkStatus( NetworkInterface_t * pxInterface ) +static BaseType_t xSTM32H_GetPhyLinkStatus( NetworkInterface_t * pxInterface ) { - BaseType_t xReturn = pdFAIL; + BaseType_t xReturn; if( xPhyObject.ulLinkStatusMask != 0U ) { @@ -374,12 +369,26 @@ static BaseType_t xGetPhyLinkStatus( NetworkInterface_t * pxInterface ) } /*-----------------------------------------------------------*/ -NetworkInterface_t * pxFillInterfaceDescriptor( BaseType_t xEMACIndex, - NetworkInterface_t * pxInterface ) +#if ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) + +/* Do not call the following function directly. It is there for downward compatibility. + * The function FreeRTOS_IPInit() will call it to initialice the interface and end-point + * objects. See the description in FreeRTOS_Routing.h. */ + NetworkInterface_t * pxFillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ) + { + pxSTM32Hxx_FillInterfaceDescriptor( xEMACIndex, pxInterface ); + } + +#endif /* ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) */ +/*-----------------------------------------------------------*/ + +NetworkInterface_t * pxSTM32H_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ) { static char pcName[ 17 ]; -/* This function pxFillInterfaceDescriptor() adds a network-interface. +/* This function pxSTM32Hxx_FillInterfaceDescriptor() adds a network-interface. * Make sure that the object pointed to by 'pxInterface' * is declared static or global, and that it will remain to exist. */ @@ -388,9 +397,9 @@ NetworkInterface_t * pxFillInterfaceDescriptor( BaseType_t xEMACIndex, memset( pxInterface, '\0', sizeof( *pxInterface ) ); pxInterface->pcName = pcName; /* Just for logging, debugging. */ pxInterface->pvArgument = ( void * ) xEMACIndex; /* Has only meaning for the driver functions. */ - pxInterface->pfInitialise = xNetworkInterfaceInitialise; - pxInterface->pfOutput = xNetworkInterfaceOutput; - pxInterface->pfGetPhyLinkStatus = xGetPhyLinkStatus; + pxInterface->pfInitialise = xSTM32H_NetworkInterfaceInitialise; + pxInterface->pfOutput = xSTM32H_NetworkInterfaceOutput; + pxInterface->pfGetPhyLinkStatus = xSTM32H_GetPhyLinkStatus; FreeRTOS_AddNetworkInterface( pxInterface ); @@ -398,19 +407,19 @@ NetworkInterface_t * pxFillInterfaceDescriptor( BaseType_t xEMACIndex, } /*-----------------------------------------------------------*/ -static BaseType_t xNetworkInterfaceOutput( NetworkInterface_t * pxInterface, - NetworkBufferDescriptor_t * const pxDescriptor, - BaseType_t xReleaseAfterSend ) +static BaseType_t xSTM32H_NetworkInterfaceOutput( NetworkInterface_t * pxInterface, + NetworkBufferDescriptor_t * const pxBuffer, + BaseType_t xReleaseAfterSend ) { BaseType_t xResult = pdFAIL; TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 100U ); uint8_t * pucTXBuffer; - if( xGetPhyLinkStatus() == pdPASS ) + if( xGetPhyLinkStatus( pxInterface ) == = pdPASS ) { #if ( ipconfigZERO_COPY_TX_DRIVER != 0 ) /* Zero-copy method, pass the buffer. */ - pucTXBuffer = pxDescriptor->pucEthernetBuffer; + pucTXBuffer = pxBuffer->pucEthernetBuffer; /* As the buffer is passed to the driver, it must exist. * The library takes care of this. */ @@ -418,17 +427,17 @@ static BaseType_t xNetworkInterfaceOutput( NetworkInterface_t * pxInterface, #else pucTXBuffer = Tx_Buff[ xEthHandle.TxDescList.CurTxDesc ]; /* The copy method, left here for educational purposes. */ - configASSERT( pxDescriptor->xDataLength <= sizeof( Tx_Buff[ 0 ] ) ); + configASSERT( pxBuffer->xDataLength <= sizeof( Tx_Buff[ 0 ] ) ); #endif ETH_BufferTypeDef xTransmitBuffer = { .buffer = pucTXBuffer, - .len = pxDescriptor->xDataLength, + .len = pxBuffer->xDataLength, .next = NULL /* FreeRTOS+TCP does not use linked buffers. */ }; /* This is the total length, which is equal to the buffer. */ - xTxConfig.Length = pxDescriptor->xDataLength; + xTxConfig.Length = pxBuffer->xDataLength; xTxConfig.TxBuffer = &( xTransmitBuffer ); /* This counting semaphore counts the number of free TX DMA descriptors. */ @@ -454,7 +463,7 @@ static BaseType_t xNetworkInterfaceOutput( NetworkInterface_t * pxInterface, } #else { - memcpy( pucTXBuffer, pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength ); + memcpy( pucTXBuffer, pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength ); /* A memory barrier to make sure that the outgoing packets has been written * to the physical memory. */ @@ -478,7 +487,7 @@ static BaseType_t xNetworkInterfaceOutput( NetworkInterface_t * pxInterface, if( xReleaseAfterSend != pdFALSE ) { - vReleaseNetworkBufferAndDescriptor( pxDescriptor ); + vReleaseNetworkBufferAndDescriptor( pxBuffer ); } return xResult; @@ -864,6 +873,8 @@ void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkB } /*-----------------------------------------------------------*/ +#define __NOP() __ASM volatile ( "nop" ) + static void vClearOptionBit( volatile uint32_t * pulValue, uint32_t ulValue ) { @@ -980,13 +991,13 @@ static void prvEMACHandlerTask( void * pvParameters ) xResult += prvNetworkInterfaceInput(); } - if( xPhyCheckLinkStatus( &xPhyObject, xResult ) != pdFALSE ) + if( xPhyCheckLinkStatus( &xPhyObject, xResult ) != 0 ) { /* * The function xPhyCheckLinkStatus() returns pdTRUE if the * Link Status has changes since it was called the last time. */ - if( xGetPhyLinkStatus() == pdFALSE ) + if( xGetPhyLinkStatus( pxMyInterface ) == pdFALSE ) { /* Stop the DMA transfer. */ HAL_ETH_Stop_IT( &( xEthHandle ) ); @@ -1003,4 +1014,5 @@ static void prvEMACHandlerTask( void * pvParameters ) } } } + /*-----------------------------------------------------------*/ diff --git a/source/portable/NetworkInterface/Zynq/NetworkInterface.c b/source/portable/NetworkInterface/Zynq/NetworkInterface.c index 49bb833e18..0b7aa474f9 100644 --- a/source/portable/NetworkInterface/Zynq/NetworkInterface.c +++ b/source/portable/NetworkInterface/Zynq/NetworkInterface.c @@ -43,6 +43,9 @@ #include "FreeRTOS_ARP.h" #include "NetworkBufferManagement.h" #include "NetworkInterface.h" +#include "FreeRTOS_DHCP.h" +#include "FreeRTOS_DNS.h" +#include "FreeRTOS_Routing.h" /* Xilinx library files. */ #include @@ -90,6 +93,16 @@ #define configEMAC_TASK_STACK_SIZE ( 8 * configMINIMAL_STACK_SIZE ) #endif +#if ( ipconfigNIC_LINKSPEED100 != 1 ) + +/* When the PHY is forces to work with a speed of 100 Mbps + * many outgoing packets seem to get dropped. + */ + #warning ipconfigNIC_LINKSPEED100 is btoken. Are you sure? +#endif + +static NetworkInterface_t * pxMyInterfaces[ XPAR_XEMACPS_NUM_INSTANCES ]; + #if ( ipconfigZERO_COPY_RX_DRIVER == 0 || ipconfigZERO_COPY_TX_DRIVER == 0 ) #error Please define both 'ipconfigZERO_COPY_RX_DRIVER' and 'ipconfigZERO_COPY_TX_DRIVER' as 1 #endif @@ -97,85 +110,205 @@ #if ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 || ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 ) #warning Please define both 'ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM' and 'ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM' as 1 #endif + +#ifndef nicUSE_UNCACHED_MEMORY + #define nicUSE_UNCACHED_MEMORY 1 +#endif + /*-----------------------------------------------------------*/ /* * Look for the link to be up every few milliseconds until either xMaxTime time * has passed or a link is found. */ -static BaseType_t prvGMACWaitLS( TickType_t xMaxTime ); +static BaseType_t prvGMACWaitLS( BaseType_t xEMACIndex, + TickType_t xMaxTime ); /* * A deferred interrupt handler for all MAC/DMA interrupt sources. */ static void prvEMACHandlerTask( void * pvParameters ); +/* FreeRTOS+TCP/multi : + * Each network device has 3 access functions: + * - initialise the device + * - output a network packet + * - return the PHY link-status (LS) + * They can be defined as static because their addresses will be + * stored in struct NetworkInterface_t. */ + +static BaseType_t xZynqNetworkInterfaceInitialise( NetworkInterface_t * pxInterface ); + +static BaseType_t xZynqNetworkInterfaceOutput( NetworkInterface_t * pxInterface, + NetworkBufferDescriptor_t * const pxBuffer, + BaseType_t bReleaseAfterSend ); + +static BaseType_t xZynqGetPhyLinkStatus( NetworkInterface_t * pxInterface ); + +NetworkInterface_t * pxZynq_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ); + /*-----------------------------------------------------------*/ /* EMAC data/descriptions. */ -static xemacpsif_s xEMACpsif; -struct xtopology_t xXTopology = +static xemacpsif_s xEMACpsifs[ XPAR_XEMACPS_NUM_INSTANCES ]; + +struct xtopology_t xXTopologies[ XPAR_XEMACPS_NUM_INSTANCES ] = { - .emac_baseaddr = XPAR_PS7_ETHERNET_0_BASEADDR, - .emac_type = xemac_type_emacps, - .intc_baseaddr = 0x0, - .intc_emac_intr = 0x0, - .scugic_baseaddr = XPAR_PS7_SCUGIC_0_BASEADDR, - .scugic_emac_intr = 0x36, + [ 0 ] = + { + .emac_baseaddr = XPAR_PS7_ETHERNET_0_BASEADDR, + .emac_type = xemac_type_emacps, + .intc_baseaddr = 0x0, + .intc_emac_intr = 0x0, + .scugic_baseaddr = XPAR_PS7_SCUGIC_0_BASEADDR, + .scugic_emac_intr = 0x36, + }, + #if ( XPAR_XEMACPS_NUM_INSTANCES > 1 ) + [ 1 ] = + { + .emac_baseaddr = XPAR_PS7_ETHERNET_1_BASEADDR, + .emac_type = xemac_type_emacps, + .intc_baseaddr = 0x0, + .intc_emac_intr = 0x0, + .scugic_baseaddr = XPAR_PS7_SCUGIC_0_BASEADDR, + .scugic_emac_intr = 0x4D, /* See "7.2.3 Shared Peripheral Interrupts (SPI)" */ + }, + #endif }; -XEmacPs_Config mac_config = +XEmacPs_Config mac_configs[ XPAR_XEMACPS_NUM_INSTANCES ] = { - .DeviceId = XPAR_PS7_ETHERNET_0_DEVICE_ID, /**< Unique ID of device */ - .BaseAddress = XPAR_PS7_ETHERNET_0_BASEADDR /**< Physical base address of IPIF registers */ + [ 0 ] = + { + .DeviceId = XPAR_PS7_ETHERNET_0_DEVICE_ID, /**< Unique ID of device, used for 'xEMACIndex' */ + .BaseAddress = XPAR_PS7_ETHERNET_0_BASEADDR /**< Physical base address of IPIF registers */ + }, + #if ( XPAR_XEMACPS_NUM_INSTANCES > 1 ) + [ 1 ] = + { + .DeviceId = XPAR_PS7_ETHERNET_1_DEVICE_ID, /**< Unique ID of device */ + .BaseAddress = XPAR_PS7_ETHERNET_1_BASEADDR /**< Physical base address of IPIF registers */ + }, + #endif }; -extern int phy_detected; +extern int phy_detected[ XPAR_XEMACPS_NUM_INSTANCES ]; /* A copy of PHY register 1: 'PHY_REG_01_BMSR' */ -static uint32_t ulPHYLinkStatus = 0uL; +static uint32_t ulPHYLinkStates[ XPAR_XEMACPS_NUM_INSTANCES ]; -#if ( ipconfigUSE_LLMNR == 1 ) - static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC }; -#endif /* Holds the handle of the task used as a deferred interrupt processor. The * handle is used so direct notifications can be sent to the task for all EMAC/DMA * related interrupts. */ -TaskHandle_t xEMACTaskHandle = NULL; +TaskHandle_t xEMACTaskHandles[ XPAR_XEMACPS_NUM_INSTANCES ]; + +/*-----------------------------------------------------------*/ +/** + * @brief Initialise the interface number 'xIndex' + * @param xIndex: the index of the interface, between 0 + * zero and (XPAR_XEMACPS_NUM_INSTANCES-1) + * @note Although the function is declared public, it should + * not be called directly by an application. + */ +void vInitialiseOnIndex( BaseType_t xIndex ) +{ + if( ( xIndex >= 0 ) && ( xIndex < XPAR_XEMACPS_NUM_INSTANCES ) ) + { + NetworkInterface_t * pxInterface = pxMyInterfaces[ xIndex ]; + + if( pxInterface != NULL ) + { + xZynqNetworkInterfaceInitialise( pxInterface ); + } + } +} /*-----------------------------------------------------------*/ -BaseType_t xNetworkInterfaceInitialise( void ) +static BaseType_t xZynqNetworkInterfaceInitialise( NetworkInterface_t * pxInterface ) { uint32_t ulLinkSpeed, ulDMAReg; BaseType_t xStatus, xLinkStatus; XEmacPs * pxEMAC_PS; const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pdMS_TO_TICKS( 1000UL ); + NetworkEndPoint_t * pxEndPoint; + BaseType_t xEMACIndex = ( BaseType_t ) pxInterface->pvArgument; + + configASSERT( xEMACIndex >= 0 ); + configASSERT( xEMACIndex < XPAR_XEMACPS_NUM_INSTANCES ); /* Guard against the init function being called more than once. */ - if( xEMACTaskHandle == NULL ) + if( xEMACTaskHandles[ xEMACIndex ] == NULL ) { - pxEMAC_PS = &( xEMACpsif.emacps ); - memset( &xEMACpsif, '\0', sizeof( xEMACpsif ) ); + const char * pcTaskName; + + pxMyInterfaces[ xEMACIndex ] = pxInterface; + + pxEMAC_PS = &( xEMACpsifs[ xEMACIndex ].emacps ); + memset( &xEMACpsifs[ xEMACIndex ], '\0', sizeof( xEMACpsifs[ xEMACIndex ] ) ); - xStatus = XEmacPs_CfgInitialize( pxEMAC_PS, &mac_config, mac_config.BaseAddress ); + xStatus = XEmacPs_CfgInitialize( pxEMAC_PS, &( mac_configs[ xEMACIndex ] ), mac_configs[ xEMACIndex ].BaseAddress ); if( xStatus != XST_SUCCESS ) { FreeRTOS_printf( ( "xEMACInit: EmacPs Configuration Failed....\n" ) ); } - /* Initialize the mac and set the MAC address. */ - XEmacPs_SetMacAddress( pxEMAC_PS, ( void * ) ipLOCAL_MAC_ADDRESS, 1 ); + pxEndPoint = FreeRTOS_FirstEndPoint( pxInterface ); + configASSERT( pxEndPoint != NULL ); + + /* Initialize the mac and set the MAC address at position 1. */ + XEmacPs_SetMacAddress( pxEMAC_PS, ( void * ) pxEndPoint->xMACAddress.ucBytes, 1 ); #if ( ipconfigUSE_LLMNR == 1 ) { /* Also add LLMNR multicast MAC address. */ - XEmacPs_SetMacAddress( pxEMAC_PS, ( void * ) xLLMNR_MACAddress, 2 ); + #if ( ipconfigUSE_IPv6 == 0 ) + { + XEmacPs_SetHash( pxEMAC_PS, ( void * ) xLLMNR_MacAdress.ucBytes ); + } + #else + { + NetworkEndPoint_t * pxEndPoint; + NetworkInterface_t * pxInterface = pxMyInterfaces[ xEMACIndex ]; + + for( pxEndPoint = FreeRTOS_FirstEndPoint( pxInterface ); + pxEndPoint != NULL; + pxEndPoint = FreeRTOS_NextEndPoint( pxInterface, pxEndPoint ) ) + { + if( pxEndPoint->bits.bIPv6 != pdFALSE_UNSIGNED ) + { + unsigned char ucMACAddress[ 6 ] = { 0x33, 0x33, 0xff, 0, 0, 0 }; + ucMACAddress[ 3 ] = pxEndPoint->ipv6_settings.xIPAddress.ucBytes[ 13 ]; + ucMACAddress[ 4 ] = pxEndPoint->ipv6_settings.xIPAddress.ucBytes[ 14 ]; + ucMACAddress[ 5 ] = pxEndPoint->ipv6_settings.xIPAddress.ucBytes[ 15 ]; + XEmacPs_SetHash( pxEMAC_PS, ( void * ) ucMACAddress ); + } + } + + XEmacPs_SetHash( pxEMAC_PS, ( void * ) xLLMNR_MacAdressIPv6.ucBytes ); + } + #endif /* if ( ipconfigUSE_IPv6 == 0 ) */ } #endif /* ipconfigUSE_LLMNR == 1 */ +#if ( ( ipconfigUSE_MDNS == 1 ) && ( ipconfigUSE_IPv6 != 0 ) ) + XEmacPs_SetHash( pxEMAC_PS, ( void * ) xMDNS_MacAdress.ucBytes ); + XEmacPs_SetHash( pxEMAC_PS, ( void * ) xMDNS_MACAdressIPv6.ucBytes ); +#endif + + pxEndPoint = FreeRTOS_NextEndPoint( pxInterface, pxEndPoint ); + + if( pxEndPoint != NULL ) + { + /* If there is a second end-point, store the MAC + * address at position 4.*/ + XEmacPs_SetMacAddress( pxEMAC_PS, ( void * ) pxEndPoint->xMACAddress.ucBytes, 4 ); + } + + /* MDIO goes via ETH0 only */ XEmacPs_SetMdioDivisor( pxEMAC_PS, MDC_DIV_224 ); ulLinkSpeed = Phy_Setup( pxEMAC_PS ); XEmacPs_SetOperatingSpeed( pxEMAC_PS, ulLinkSpeed ); @@ -185,40 +318,66 @@ BaseType_t xNetworkInterfaceInitialise( void ) ulDMAReg = XEmacPs_ReadReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET ); + { + uint32_t ulValue = XEmacPs_ReadReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_NWCFG_OFFSET ); + /* Allow the use of hashed MAC addresses. */ + ulValue |= XEMACPS_NWCFG_MCASTHASHEN_MASK; + #warning As 'MCASTHASHEN' doesn't seem to work, use the promiscuous mode so that IPv6 multicast packets are received. + /* Allow promiscuous mode. */ + ulValue |= XEMACPS_NWCFG_COPYALLEN_MASK; + XEmacPs_WriteReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_NWCFG_OFFSET, ulValue ); + } + /* DISC_WHEN_NO_AHB: when set, the GEM DMA will automatically discard receive * packets from the receiver packet buffer memory when no AHB resource is available. */ XEmacPs_WriteReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET, ulDMAReg | XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK ); - setup_isr( &xEMACpsif ); - init_dma( &xEMACpsif ); - start_emacps( &xEMACpsif ); + setup_isr( &( xEMACpsifs[ xEMACIndex ] ) ); + init_dma( &( xEMACpsifs[ xEMACIndex ] ) ); + start_emacps( &( xEMACpsifs[ xEMACIndex ] ) ); - prvGMACWaitLS( xWaitLinkDelay ); + prvGMACWaitLS( xEMACIndex, xWaitLinkDelay ); /* The deferred interrupt handler task is created at the highest * possible priority to ensure the interrupt handler can return directly - * to it. The task's handle is stored in xEMACTaskHandle so interrupts can + * to it. The task's handle is stored in xEMACTaskHandles[] so interrupts can * notify the task when there is something to process. */ - xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &xEMACTaskHandle ); + if( xEMACIndex == 0 ) + { + pcTaskName = "GEM0"; + } + else + { + pcTaskName = "GEM1"; + } + + xTaskCreate( prvEMACHandlerTask, pcTaskName, configEMAC_TASK_STACK_SIZE, ( void * ) xEMACIndex, niEMAC_HANDLER_TASK_PRIORITY, &( xEMACTaskHandles[ xEMACIndex ] ) ); } else { /* Initialisation was already performed, just wait for the link. */ - prvGMACWaitLS( xWaitRelinkDelay ); + prvGMACWaitLS( xEMACIndex, xWaitRelinkDelay ); } /* Only return pdTRUE when the Link Status of the PHY is high, otherwise the * DHCP process and all other communication will fail. */ - xLinkStatus = xGetPhyLinkStatus(); + xLinkStatus = xZynqGetPhyLinkStatus( pxInterface ); - return( xLinkStatus != pdFALSE ); +/* return ( xLinkStatus != pdFALSE ); */ + return pdTRUE; /* Workaround because network buffers are not freed when xZynqNetworkInterfaceInitialise() did not complete */ } /*-----------------------------------------------------------*/ -BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, - BaseType_t bReleaseAfterSend ) +static BaseType_t xZynqNetworkInterfaceOutput( NetworkInterface_t * pxInterface, + NetworkBufferDescriptor_t * const pxBuffer, + BaseType_t bReleaseAfterSend ) { + BaseType_t xEMACIndex = ( BaseType_t ) pxInterface->pvArgument; + + configASSERT( xEMACIndex >= 0 ); + configASSERT( xEMACIndex < XPAR_XEMACPS_NUM_INSTANCES ); + #if ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 ) { ProtocolPacket_t * pxPacket; @@ -227,22 +386,37 @@ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, * the protocol checksum to have a value of zero. */ pxPacket = ( ProtocolPacket_t * ) ( pxBuffer->pucEthernetBuffer ); + #if ( ipconfigUSE_IPv6 != 0 ) + ICMPPacket_IPv6_t * pxICMPPacket = ( ICMPPacket_IPv6_t * ) pxBuffer->pucEthernetBuffer; + + if( ( pxPacket->xICMPPacket.xEthernetHeader.usFrameType == ipIPv6_FRAME_TYPE ) && + ( pxICMPPacket->xIPHeader.ucNextHeader == ipPROTOCOL_ICMP_IPv6 ) ) + { + /* The EMAC will calculate the checksum of the IP-header. + * It can only calculate protocol checksums of UDP and TCP, + * so for ICMP and other protocols it must be done manually. */ + usGenerateProtocolChecksum( pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength, pdTRUE ); + } + #endif + if( ( pxPacket->xICMPPacket.xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE ) && - ( pxPacket->xICMPPacket.xIPHeader.ucProtocol != ipPROTOCOL_UDP ) && - ( pxPacket->xICMPPacket.xIPHeader.ucProtocol != ipPROTOCOL_TCP ) ) + ( pxPacket->xICMPPacket.xIPHeader.ucProtocol == ipPROTOCOL_ICMP ) ) { /* The EMAC will calculate the checksum of the IP-header. * It can only calculate protocol checksums of UDP and TCP, * so for ICMP and other protocols it must be done manually. */ - usGenerateProtocolChecksum( ( uint8_t * ) &( pxPacket->xUDPPacket ), pxBuffer->xDataLength, pdTRUE ); + usGenerateProtocolChecksum( pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength, pdTRUE ); } } #endif /* ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM */ - if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0UL ) + if( ( ulPHYLinkStates[ xEMACIndex ] & niBMSR_LINK_STATUS ) != 0UL ) { iptraceNETWORK_INTERFACE_TRANSMIT(); - emacps_send_message( &xEMACpsif, pxBuffer, bReleaseAfterSend ); + + /* emacps_send_message() will take ownership of pxBuffer, and + * make sure it will get release when bReleaseAfterSend is pdTRUE. */ + emacps_send_message( &( xEMACpsifs[ xEMACIndex ] ), pxBuffer, bReleaseAfterSend ); } else if( bReleaseAfterSend != pdFALSE ) { @@ -254,16 +428,19 @@ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, } /*-----------------------------------------------------------*/ -static inline unsigned long ulReadMDIO( unsigned ulRegister ) +static inline unsigned long ulReadMDIO( BaseType_t xEMACIndex, + unsigned ulRegister ) { uint16_t usValue; - XEmacPs_PhyRead( &( xEMACpsif.emacps ), phy_detected, ulRegister, &usValue ); + /* Always ETH0 because both PHYs are connected to ETH0 MDIO */ + XEmacPs_PhyRead( &( xEMACpsifs[ 0 ].emacps ), phy_detected[ xEMACIndex ], ulRegister, &usValue ); return usValue; } /*-----------------------------------------------------------*/ -static BaseType_t prvGMACWaitLS( TickType_t xMaxTime ) +static BaseType_t prvGMACWaitLS( BaseType_t xEMACIndex, + TickType_t xMaxTime ) { TickType_t xStartTime, xEndTime; const TickType_t xShortDelay = pdMS_TO_TICKS( 20UL ); @@ -281,9 +458,9 @@ static BaseType_t prvGMACWaitLS( TickType_t xMaxTime ) break; } - ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR ); + ulPHYLinkStates[ xEMACIndex ] = ulReadMDIO( xEMACIndex, PHY_REG_01_BMSR ); - if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL ) + if( ( ulPHYLinkStates[ xEMACIndex ] & niBMSR_LINK_STATUS ) != 0U ) { xReturn = pdTRUE; break; @@ -296,26 +473,52 @@ static BaseType_t prvGMACWaitLS( TickType_t xMaxTime ) } /*-----------------------------------------------------------*/ -void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] ) -{ - static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__( ( aligned( 32 ) ) ); - uint8_t * ucRAMBuffer = ucNetworkPackets; - uint32_t ul; - - for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ ) +#if ( nicUSE_UNCACHED_MEMORY == 0 ) + void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] ) + { + static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__( ( aligned( 32 ) ) ); + uint8_t * ucRAMBuffer = ucNetworkPackets; + uint32_t ul; + + for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ ) + { + pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING; + *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) ); + ucRAMBuffer += niBUFFER_1_PACKET_SIZE; + } + } +#else /* if ( nicUSE_UNCACHED_MEMORY == 0 ) */ + void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] ) { - pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING; - *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) ); - ucRAMBuffer += niBUFFER_1_PACKET_SIZE; + static uint8_t * pucNetworkPackets = NULL; + + if( pucNetworkPackets == NULL ) + { + pucNetworkPackets = pucGetUncachedMemory( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ); + + if( pucNetworkPackets != NULL ) + { + uint8_t * ucRAMBuffer = pucNetworkPackets; + uint32_t ul; + + for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ ) + { + pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING; + *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) ); + ucRAMBuffer += niBUFFER_1_PACKET_SIZE; + } + } + } } -} +#endif /* ( nicUSE_UNCACHED_MEMORY == 0 ) */ /*-----------------------------------------------------------*/ -BaseType_t xGetPhyLinkStatus( void ) +static BaseType_t xZynqGetPhyLinkStatus( NetworkInterface_t * pxInterface ) { BaseType_t xReturn; + BaseType_t xEMACIndex = ( BaseType_t ) pxInterface->pvArgument; - if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) == 0uL ) + if( ( ulPHYLinkStates[ xEMACIndex ] & niBMSR_LINK_STATUS ) == 0U ) { xReturn = pdFALSE; } @@ -328,6 +531,49 @@ BaseType_t xGetPhyLinkStatus( void ) } /*-----------------------------------------------------------*/ + +#if ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) + + +/* Do not call the following function directly. It is there for downward compatibility. + * The function FreeRTOS_IPInit() will call it to initialice the interface and end-point + * objects. See the description in FreeRTOS_Routing.h. */ + NetworkInterface_t * pxFillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ) + { + pxZynq_FillInterfaceDescriptor( xEMACIndex, pxInterface ); + } + +#endif /* ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) */ +/*-----------------------------------------------------------*/ + +NetworkInterface_t * pxZynq_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ) +{ + static char pcNames[ XPAR_XEMACPS_NUM_INSTANCES ][ 8 ]; + + configASSERT( xEMACIndex >= 0 ); + configASSERT( xEMACIndex < XPAR_XEMACPS_NUM_INSTANCES ); + +/* This function pxZynq_FillInterfaceDescriptor() adds a network-interface. + * Make sure that the object pointed to by 'pxInterface' + * is declared static or global, and that it will remain to exist. */ + + snprintf( pcNames[ xEMACIndex ], sizeof( pcNames[ xEMACIndex ] ), "eth%ld", xEMACIndex ); + + memset( pxInterface, '\0', sizeof( *pxInterface ) ); + pxInterface->pcName = pcNames[ xEMACIndex ]; /* Just for logging, debugging. */ + pxInterface->pvArgument = ( void * ) xEMACIndex; /* Has only meaning for the driver functions. */ + pxInterface->pfInitialise = xZynqNetworkInterfaceInitialise; + pxInterface->pfOutput = xZynqNetworkInterfaceOutput; + pxInterface->pfGetPhyLinkStatus = xZynqGetPhyLinkStatus; + + FreeRTOS_AddNetworkInterface( pxInterface ); + + return pxInterface; +} +/*-----------------------------------------------------------*/ + static void prvEMACHandlerTask( void * pvParameters ) { TimeOut_t xPhyTime; @@ -335,6 +581,13 @@ static void prvEMACHandlerTask( void * pvParameters ) BaseType_t xResult = 0; uint32_t xStatus; const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL ); + BaseType_t xEMACIndex = ( BaseType_t ) pvParameters; + xemacpsif_s * pxEMAC_PS; + + configASSERT( xEMACIndex >= 0 ); + configASSERT( xEMACIndex < XPAR_XEMACPS_NUM_INSTANCES ); + + pxEMAC_PS = &( xEMACpsifs[ xEMACIndex ] ); /* Remove compiler warnings about unused parameters. */ ( void ) pvParameters; @@ -345,6 +598,7 @@ static void prvEMACHandlerTask( void * pvParameters ) vTaskSetTimeOutState( &xPhyTime ); xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS ); + FreeRTOS_printf( ( "prvEMACHandlerTask[ %ld ] started running\n", xEMACIndex ) ); for( ; ; ) { @@ -357,28 +611,28 @@ static void prvEMACHandlerTask( void * pvParameters ) } #endif /* ( ipconfigHAS_PRINTF != 0 ) */ - if( ( xEMACpsif.isr_events & EMAC_IF_ALL_EVENT ) == 0 ) + if( ( pxEMAC_PS->isr_events & EMAC_IF_ALL_EVENT ) == 0 ) { /* No events to process now, wait for the next. */ ulTaskNotifyTake( pdFALSE, ulMaxBlockTime ); } - if( ( xEMACpsif.isr_events & EMAC_IF_RX_EVENT ) != 0 ) + if( ( pxEMAC_PS->isr_events & EMAC_IF_RX_EVENT ) != 0 ) { - xEMACpsif.isr_events &= ~EMAC_IF_RX_EVENT; - xResult = emacps_check_rx( &xEMACpsif ); + pxEMAC_PS->isr_events &= ~EMAC_IF_RX_EVENT; + xResult = emacps_check_rx( pxEMAC_PS, pxMyInterfaces[ xEMACIndex ] ); } - if( ( xEMACpsif.isr_events & EMAC_IF_TX_EVENT ) != 0 ) + if( ( pxEMAC_PS->isr_events & EMAC_IF_TX_EVENT ) != 0 ) { - xEMACpsif.isr_events &= ~EMAC_IF_TX_EVENT; - emacps_check_tx( &xEMACpsif ); + pxEMAC_PS->isr_events &= ~EMAC_IF_TX_EVENT; + emacps_check_tx( pxEMAC_PS ); } - if( ( xEMACpsif.isr_events & EMAC_IF_ERR_EVENT ) != 0 ) + if( ( pxEMAC_PS->isr_events & EMAC_IF_ERR_EVENT ) != 0 ) { - xEMACpsif.isr_events &= ~EMAC_IF_ERR_EVENT; - emacps_check_errors( &xEMACpsif ); + pxEMAC_PS->isr_events &= ~EMAC_IF_ERR_EVENT; + emacps_check_errors( pxEMAC_PS ); } if( xResult > 0 ) @@ -388,28 +642,21 @@ static void prvEMACHandlerTask( void * pvParameters ) vTaskSetTimeOutState( &xPhyTime ); xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS ); xResult = 0; - - if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) == 0uL ) - { - /* Indicate that the Link Status is high, so that - * xNetworkInterfaceOutput() can send packets. */ - ulPHYLinkStatus |= niBMSR_LINK_STATUS; - FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS assume 1\n" ) ); - } + ulPHYLinkStates[ xEMACIndex ] |= niBMSR_LINK_STATUS; } else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE ) { - xStatus = ulReadMDIO( PHY_REG_01_BMSR ); + xStatus = ulReadMDIO( xEMACIndex, PHY_REG_01_BMSR ); - if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != ( xStatus & niBMSR_LINK_STATUS ) ) + if( ( ulPHYLinkStates[ xEMACIndex ] & niBMSR_LINK_STATUS ) != ( xStatus & niBMSR_LINK_STATUS ) ) { - ulPHYLinkStatus = xStatus; - FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL ) ); + ulPHYLinkStates[ xEMACIndex ] = xStatus; + FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStates[ xEMACIndex ] & niBMSR_LINK_STATUS ) != 0 ) ); } vTaskSetTimeOutState( &xPhyTime ); - if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL ) + if( ( ulPHYLinkStates[ xEMACIndex ] & niBMSR_LINK_STATUS ) != 0 ) { xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS ); } diff --git a/source/portable/NetworkInterface/Zynq/uncached_memory.c b/source/portable/NetworkInterface/Zynq/uncached_memory.c index 0c472d6638..ec77842876 100644 --- a/source/portable/NetworkInterface/Zynq/uncached_memory.c +++ b/source/portable/NetworkInterface/Zynq/uncached_memory.c @@ -1,8 +1,6 @@ /* - * FreeRTOS+TCP - * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT + * FreeRTOS+FAT V2.3.3 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -21,8 +19,9 @@ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * */ /* @@ -59,7 +58,6 @@ #include "FreeRTOS_Sockets.h" #include "FreeRTOS_IP_Private.h" -#include "Zynq/x_emacpsif.h" #include "Zynq/x_topology.h" #include "xstatus.h" @@ -70,18 +68,30 @@ #include "uncached_memory.h" -/* Reserve 1 MB of memory. */ -#define uncMEMORY_SIZE 0x100000uL +#if ( ipconfigULTRASCALE == 1 ) + /* Reserve 2 MB of memory. */ + #define uncMINIMAL_MEMORY_SIZE 0x200000U + #ifndef uncMEMORY_SIZE + #define uncMEMORY_SIZE uncMINIMAL_MEMORY_SIZE + #endif + #define DDR_MEMORY_END ( XPAR_PSU_DDR_0_S_AXI_HIGHADDR ) + #define uncMEMORY_ATTRIBUTE NORM_NONCACHE | INNER_SHAREABLE +#else + /* Reserve 1 MB of memory. */ + #define uncMINIMAL_MEMORY_SIZE 0x100000U + #ifndef uncMEMORY_SIZE + #define uncMEMORY_SIZE uncMINIMAL_MEMORY_SIZE + #endif + #define DDR_MEMORY_END ( XPAR_PS7_DDR_0_S_AXI_HIGHADDR + 1 ) + #define uncMEMORY_ATTRIBUTE 0x1C02 +#endif /* ( ipconfigULTRASCALE == 1 ) */ /* Make sure that each pointer has an alignment of 4 KB. */ #define uncALIGNMENT_SIZE 0x1000uL -#define DDR_MEMORY_END ( XPAR_PS7_DDR_0_S_AXI_HIGHADDR + 1 ) - -#define uncMEMORY_ATTRIBUTE 0x1C02 - static void vInitialiseUncachedMemory( void ); +static uint8_t pucUncachedMemory[ uncMEMORY_SIZE ] __attribute__( ( aligned( uncMEMORY_SIZE ) ) ); static uint8_t * pucHeadOfMemory; static uint32_t ulMemorySize; static uint8_t * pucStartOfMemory = NULL; @@ -141,12 +151,9 @@ uint8_t * pucGetUncachedMemory( uint32_t ulSize ) static void vInitialiseUncachedMemory() { /* At the end of program's space... */ - pucStartOfMemory = ( uint8_t * ) &( _end ); - - /* Align the start address to 1 MB boundary. */ - pucStartOfMemory = ( uint8_t * ) ( ( ( uint32_t ) pucStartOfMemory + uncMEMORY_SIZE ) & ( ~( uncMEMORY_SIZE - 1 ) ) ); + pucStartOfMemory = pucUncachedMemory; - if( ( ( u32 ) pucStartOfMemory ) + uncMEMORY_SIZE > DDR_MEMORY_END ) + if( ( ( uintptr_t ) pucStartOfMemory ) + uncMEMORY_SIZE > DDR_MEMORY_END ) { FreeRTOS_printf( ( "vInitialiseUncachedMemory: Can not allocate uncached memory\n" ) ); } @@ -155,7 +162,15 @@ static void vInitialiseUncachedMemory() /* Some objects want to be stored in uncached memory. Hence the 1 MB * address range that starts after "_end" is made uncached by setting * appropriate attributes in the translation table. */ - Xil_SetTlbAttributes( ( uint32_t ) pucStartOfMemory, uncMEMORY_ATTRIBUTE ); + uint32_t ulBytesLeft = uncMEMORY_SIZE; + uint8_t *puc = pucStartOfMemory; + while( ulBytesLeft > 0U ) + { + uint32_t ulCurrentSize = ( ulBytesLeft > uncMINIMAL_MEMORY_SIZE ) ? uncMINIMAL_MEMORY_SIZE : ulBytesLeft; + Xil_SetTlbAttributes( ( uintptr_t ) puc, uncMEMORY_ATTRIBUTE ); + ulBytesLeft -= ulCurrentSize; + puc += ulCurrentSize; + } /* For experiments in the SDIO driver, make the remaining uncached memory * public */ diff --git a/source/portable/NetworkInterface/Zynq/x_emacpsif.h b/source/portable/NetworkInterface/Zynq/x_emacpsif.h index 029e4a3ae0..54170dbd3f 100644 --- a/source/portable/NetworkInterface/Zynq/x_emacpsif.h +++ b/source/portable/NetworkInterface/Zynq/x_emacpsif.h @@ -38,14 +38,16 @@ #include "xscugic.h" #include "xemacps.h" /* defines XEmacPs API */ -/*#include "netif/xpqueue.h" */ -/*#include "xlwipconfig.h" */ + #define XPAR_PS7_ETHERNET_1_DEVICE_ID 1 + #define XPAR_PS7_ETHERNET_1_BASEADDR 0xE000C000 + + extern XEmacPs_Config mac_configs[ XPAR_XEMACPS_NUM_INSTANCES ]; + void xemacpsif_setmac( uint32_t index, uint8_t * addr ); uint8_t * xemacpsif_getmac( uint32_t index ); -/*int xemacpsif_init(struct netif *netif); */ -/*int xemacpsif_input(struct netif *netif); */ + #ifdef NOTNOW_BHILL unsigned get_IEEE_phy_speed( XLlTemac * xlltemacp ); #endif @@ -111,7 +113,8 @@ struct xNETWORK_BUFFER; - int emacps_check_rx( xemacpsif_s * xemacpsif ); + int emacps_check_rx( xemacpsif_s * xemacpsif, + NetworkInterface_t * pxInterface ); void emacps_check_tx( xemacpsif_s * xemacpsif ); int emacps_check_errors( xemacpsif_s * xemacps ); void emacps_set_rx_buffers( xemacpsif_s * xemacpsif, @@ -125,8 +128,8 @@ extern XStatus init_dma( xemacpsif_s * xemacpsif ); extern void start_emacps( xemacpsif_s * xemacpsif ); - void EmacEnableIntr( void ); - void EmacDisableIntr( void ); + void EmacEnableIntr( int xEMACIndex ); + void EmacDisableIntr( int xEMACIndex ); XStatus init_axi_dma( xemacpsif_s * xemacpsif ); void process_sent_bds( xemacpsif_s * xemacpsif ); @@ -142,8 +145,14 @@ void clean_dma_txdescs( xemacpsif_s * xemacpsif ); void resetrx_on_no_rxdata( xemacpsif_s * xemacpsif ); +/** + * @brief Initialise the interface number 'xIndex'. Do not call directly. + */ + void vInitialiseOnIndex( BaseType_t xIndex ); + #ifdef __cplusplus } #endif #endif /* __NETIF_XAXIEMACIF_H__ */ + diff --git a/source/portable/NetworkInterface/Zynq/x_emacpsif_dma.c b/source/portable/NetworkInterface/Zynq/x_emacpsif_dma.c index fd496c5566..6567384629 100644 --- a/source/portable/NetworkInterface/Zynq/x_emacpsif_dma.c +++ b/source/portable/NetworkInterface/Zynq/x_emacpsif_dma.c @@ -1,8 +1,38 @@ +/****************************************************************************** +* +* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + /* - * FreeRTOS+TCP - * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT + * FreeRTOS+TCP V2.3.3 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -34,6 +64,7 @@ #include "FreeRTOS_IP.h" #include "FreeRTOS_Sockets.h" #include "FreeRTOS_IP_Private.h" +#include "FreeRTOS_Routing.h" #include "NetworkBufferManagement.h" #include "Zynq/x_emacpsif.h" @@ -61,28 +92,32 @@ #define dmaRX_TX_BUFFER_SIZE 1536 /* Defined in NetworkInterface.c */ -extern TaskHandle_t xEMACTaskHandle; +extern TaskHandle_t xEMACTaskHandles[ XPAR_XEMACPS_NUM_INSTANCES ]; /* * pxDMA_tx_buffers: these are character arrays, each one is big enough to hold 1 MTU. * The actual TX buffers are located in uncached RAM. */ -static unsigned char * pxDMA_tx_buffers[ ipconfigNIC_N_TX_DESC ] = { NULL }; +static unsigned char * pxDMA_tx_buffers[ XPAR_XEMACPS_NUM_INSTANCES ][ ipconfigNIC_N_TX_DESC ]; /* * pxDMA_rx_buffers: these are pointers to 'NetworkBufferDescriptor_t'. * Once a message has been received by the EMAC, the descriptor can be passed * immediately to the IP-task. */ -static NetworkBufferDescriptor_t * pxDMA_rx_buffers[ ipconfigNIC_N_RX_DESC ] = { NULL }; +static NetworkBufferDescriptor_t * pxDMA_rx_buffers[ XPAR_XEMACPS_NUM_INSTANCES ][ ipconfigNIC_N_RX_DESC ]; /* * The FreeRTOS+TCP port is using a fixed 'topology', which is declared in * ./portable/NetworkInterface/Zynq/NetworkInterface.c */ -extern struct xtopology_t xXTopology; +extern struct xtopology_t xXTopologies[ XPAR_XEMACPS_NUM_INSTANCES ]; + +static SemaphoreHandle_t xTXDescriptorSemaphores[ XPAR_XEMACPS_NUM_INSTANCES ]; + +BaseType_t xMayAcceptPacket( uint8_t * pucEthernetBuffer ); -static SemaphoreHandle_t xTXDescriptorSemaphore = NULL; +static void prvPassEthMessages( NetworkBufferDescriptor_t * pxDescriptor ); /* * The FreeRTOS+TCP port does not make use of "src/xemacps_bdring.c". @@ -94,10 +129,11 @@ static SemaphoreHandle_t xTXDescriptorSemaphore = NULL; int is_tx_space_available( xemacpsif_s * xemacpsif ) { size_t uxCount; + BaseType_t xEMACIndex = xemacpsif->emacps.Config.DeviceId; - if( xTXDescriptorSemaphore != NULL ) + if( xTXDescriptorSemaphores[ xEMACIndex ] != NULL ) { - uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount( xTXDescriptorSemaphore ); + uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount( xTXDescriptorSemaphores[ xEMACIndex ] ); } else { @@ -111,7 +147,8 @@ void emacps_check_tx( xemacpsif_s * xemacpsif ) { int tail = xemacpsif->txTail; int head = xemacpsif->txHead; - size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount( xTXDescriptorSemaphore ); + BaseType_t xEMACIndex = xemacpsif->emacps.Config.DeviceId; + size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount( xTXDescriptorSemaphores[ xEMACIndex ] ); /* uxCount is the number of TX descriptors that are in use by the DMA. */ /* When done, "TXBUF_USED" will be set. */ @@ -124,12 +161,12 @@ void emacps_check_tx( xemacpsif_s * xemacpsif ) } { - void * pvBuffer = pxDMA_tx_buffers[ tail ]; + void * pvBuffer = pxDMA_tx_buffers[ xEMACIndex ][ tail ]; NetworkBufferDescriptor_t * pxBuffer; if( pvBuffer != NULL ) { - pxDMA_tx_buffers[ tail ] = NULL; + pxDMA_tx_buffers[ xEMACIndex ][ tail ] = NULL; pxBuffer = pxPacketBuffer_to_NetworkBuffer( pvBuffer ); if( pxBuffer != NULL ) @@ -155,7 +192,7 @@ void emacps_check_tx( xemacpsif_s * xemacpsif ) uxCount--; /* Tell the counting semaphore that one more TX descriptor is available. */ - xSemaphoreGive( xTXDescriptorSemaphore ); + xSemaphoreGive( xTXDescriptorSemaphores[ xEMACIndex ] ); if( ++tail == ipconfigNIC_N_TX_DESC ) { @@ -170,8 +207,10 @@ void emacps_send_handler( void * arg ) { xemacpsif_s * xemacpsif; BaseType_t xHigherPriorityTaskWoken = pdFALSE; + BaseType_t xEMACIndex; - xemacpsif = ( xemacpsif_s * ) ( arg ); + xemacpsif = ( xemacpsif_s * ) arg; + xEMACIndex = xemacpsif->emacps.Config.DeviceId; /* This function is called from an ISR. The Xilinx ISR-handler has already * cleared the TXCOMPL and TXSR_USEDREAD status bits in the XEMACPS_TXSR register. @@ -184,9 +223,9 @@ void emacps_send_handler( void * arg ) xemacpsif->isr_events |= EMAC_IF_TX_EVENT; xemacpsif->txBusy = pdFALSE; - if( xEMACTaskHandle != NULL ) + if( xEMACTaskHandles[ xEMACIndex ] != NULL ) { - vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken ); + vTaskNotifyGiveFromISR( xEMACTaskHandles[ xEMACIndex ], &xHigherPriorityTaskWoken ); } portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); @@ -212,10 +251,11 @@ XStatus emacps_send_message( xemacpsif_s * xemacpsif, NetworkBufferDescriptor_t * pxBuffer, int iReleaseAfterSend ) { - int head = xemacpsif->txHead; + int txHead = xemacpsif->txHead; int iHasSent = 0; uint32_t ulBaseAddress = xemacpsif->emacps.Config.BaseAddress; - TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u ); + BaseType_t xEMACIndex = xemacpsif->emacps.Config.DeviceId; + TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000U ); /* This driver wants to own all network buffers which are to be transmitted. */ configASSERT( iReleaseAfterSend != pdFALSE ); @@ -230,23 +270,23 @@ XStatus emacps_send_message( xemacpsif_s * xemacpsif, break; } - if( xTXDescriptorSemaphore == NULL ) + if( xTXDescriptorSemaphores[ xEMACIndex ] == NULL ) { break; } - if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS ) + if( xSemaphoreTake( xTXDescriptorSemaphores[ xEMACIndex ], xBlockTimeTicks ) != pdPASS ) { FreeRTOS_printf( ( "emacps_send_message: Time-out waiting for TX buffer\n" ) ); break; } /* Pass the pointer (and its ownership) directly to DMA. */ - pxDMA_tx_buffers[ head ] = pxBuffer->pucEthernetBuffer; + pxDMA_tx_buffers[ xEMACIndex ][ txHead ] = pxBuffer->pucEthernetBuffer; if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 ) { - Xil_DCacheFlushRange( ( unsigned ) pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength ); + Xil_DCacheFlushRange( ( INTPTR ) pxBuffer->pucEthernetBuffer, ( u32 ) pxBuffer->xDataLength ); } /* Buffer has been transferred, do not release it. */ @@ -257,26 +297,53 @@ XStatus emacps_send_message( xemacpsif_s * xemacpsif, ulFlags |= XEMACPS_TXBUF_LAST_MASK; ulFlags |= ( pxBuffer->xDataLength & XEMACPS_TXBUF_LEN_MASK ); - if( head == ( ipconfigNIC_N_TX_DESC - 1 ) ) + if( txHead == ( ipconfigNIC_N_TX_DESC - 1 ) ) { ulFlags |= XEMACPS_TXBUF_WRAP_MASK; } /* Copy the address of the buffer and set the flags. */ - xemacpsif->txSegments[ head ].address = ( uint32_t ) pxDMA_tx_buffers[ head ]; - xemacpsif->txSegments[ head ].flags = ulFlags; + xemacpsif->txSegments[ txHead ].address = ( uint32_t ) pxDMA_tx_buffers[ xEMACIndex ][ txHead ]; + + if( xemacpsif->txSegments[ txHead ].address ) + { + } + + xemacpsif->txSegments[ txHead ].flags = ulFlags; + + if( xemacpsif->txSegments[ txHead ].flags ) + { + } iHasSent = pdTRUE; - if( ++head == ipconfigNIC_N_TX_DESC ) + txHead++; + + if( txHead == ipconfigNIC_N_TX_DESC ) { - head = 0; + txHead = 0; } /* Update the TX-head index. These variable are declared volatile so they will be - * accessed as little as possible. */ - xemacpsif->txHead = head; - } while( pdFALSE ); + * accessed as little as possible. */ + xemacpsif->txHead = txHead; + + /* Data Synchronization Barrier */ + dsb(); + + if( iHasSent == pdTRUE ) + { + /* Make STARTTX high */ + uint32_t ulValue = XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET ); + /* Start transmit */ + xemacpsif->txBusy = pdTRUE; + XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) ); + /* Read back the register to make sure the data is flushed. */ + ( void ) XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET ); + } + + dsb(); + } while( ipFALSE_BOOL ); if( iReleaseAfterSend != pdFALSE ) { @@ -284,22 +351,6 @@ XStatus emacps_send_message( xemacpsif_s * xemacpsif, pxBuffer = NULL; } - /* Data Synchronization Barrier */ - dsb(); - - if( iHasSent != pdFALSE ) - { - /* Make STARTTX high */ - uint32_t ulValue = XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET ); - /* Start transmit */ - xemacpsif->txBusy = pdTRUE; - XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) ); - /* Read back the register to make sure the data is flushed. */ - ( void ) XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET ); - } - - dsb(); - return 0; } @@ -307,22 +358,25 @@ void emacps_recv_handler( void * arg ) { xemacpsif_s * xemacpsif; BaseType_t xHigherPriorityTaskWoken = pdFALSE; + BaseType_t xEMACIndex; - xemacpsif = ( xemacpsif_s * ) ( arg ); + xemacpsif = ( xemacpsif_s * ) arg; xemacpsif->isr_events |= EMAC_IF_RX_EVENT; + xEMACIndex = xemacpsif->emacps.Config.DeviceId; /* The driver has already cleared the FRAMERX, BUFFNA and error bits * in the XEMACPS_RXSR register, * But it forgets to do a read-back. Do so now. */ ( void ) XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET ); - if( xEMACTaskHandle != NULL ) + if( xEMACTaskHandles[ xEMACIndex ] != NULL ) { - vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken ); + vTaskNotifyGiveFromISR( xEMACTaskHandles[ xEMACIndex ], &xHigherPriorityTaskWoken ); } portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); } +/*-----------------------------------------------------------*/ static void prvPassEthMessages( NetworkBufferDescriptor_t * pxDescriptor ) { @@ -333,8 +387,8 @@ static void prvPassEthMessages( NetworkBufferDescriptor_t * pxDescriptor ) if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 1000 ) != pdPASS ) { - /* The buffer could not be sent to the stack so must be released again. - * This is a deferred handler task, not a real interrupt, so it is ok to + /* The buffer could not be sent to the IP-task so it must be released again. + * This is a deferred handler taskr, not a real interrupt, so it is ok to * use the task level function here. */ #if ( ipconfigUSE_LINKED_RX_MESSAGES != 0 ) { @@ -354,13 +408,91 @@ static void prvPassEthMessages( NetworkBufferDescriptor_t * pxDescriptor ) FreeRTOS_printf( ( "prvPassEthMessages: Can not queue return packet!\n" ) ); } } +/*-----------------------------------------------------------*/ -int emacps_check_rx( xemacpsif_s * xemacpsif ) +BaseType_t xMayAcceptPacket( uint8_t * pucEthernetBuffer ) +{ + const ProtocolPacket_t * pxProtPacket = ( const ProtocolPacket_t * ) pucEthernetBuffer; + + switch( pxProtPacket->xTCPPacket.xEthernetHeader.usFrameType ) + { + case ipARP_FRAME_TYPE: + /* Check it later. */ + return pdTRUE; + + case ipIPv6_FRAME_TYPE: + /* Check it later. */ + return pdTRUE; + + case ipIPv4_FRAME_TYPE: + /* Check it here. */ + break; + + default: + /* Refuse the packet. */ + return pdFALSE; + } + + #if ( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 ) + { + const IPHeader_t * pxIPHeader = &( pxProtPacket->xTCPPacket.xIPHeader ); + + /* Ensure that the incoming packet is not fragmented (only outgoing packets + * can be fragmented) as these are the only handled IP frames currently. */ + if( ( pxIPHeader->usFragmentOffset & FreeRTOS_ntohs( ipFRAGMENT_OFFSET_BIT_MASK ) ) != 0U ) + { + return pdFALSE; + } + + /* HT: Might want to make the following configurable because + * most IP messages have a standard length of 20 bytes */ + + /* 0x45 means: IPv4 with an IP header of 5 x 4 = 20 bytes + * 0x47 means: IPv4 with an IP header of 7 x 4 = 28 bytes */ + if( ( pxIPHeader->ucVersionHeaderLength < 0x45 ) || ( pxIPHeader->ucVersionHeaderLength > 0x4F ) ) + { + return pdFALSE; + } + + if( pxIPHeader->ucProtocol == ipPROTOCOL_UDP ) + { + uint16_t usSourcePort = FreeRTOS_ntohs( pxProtPacket->xUDPPacket.xUDPHeader.usSourcePort ); + uint16_t usDestinationPort = FreeRTOS_ntohs( pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort ); + + if( ( xPortHasUDPSocket( pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort ) == pdFALSE ) + #if ipconfigUSE_LLMNR == 1 + && ( usDestinationPort != ipLLMNR_PORT ) && + ( usSourcePort != ipLLMNR_PORT ) + #endif + #if ipconfigUSE_NBNS == 1 + && ( usDestinationPort != ipNBNS_PORT ) && + ( usSourcePort != ipNBNS_PORT ) + #endif + #if ipconfigUSE_DNS == 1 + && ( usSourcePort != ipDNS_PORT ) + #endif + ) + { + /* Drop this packet, not for this device. */ + /* FreeRTOS_printf( ( "Drop: UDP port %d -> %d\n", usSourcePort, usDestinationPort ) ); */ + return pdFALSE; + } + } + } + #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */ + return pdTRUE; +} +/*-----------------------------------------------------------*/ + +int emacps_check_rx( xemacpsif_s * xemacpsif, + NetworkInterface_t * pxInterface ) { NetworkBufferDescriptor_t * pxBuffer, * pxNewBuffer; int rx_bytes; volatile int msgCount = 0; - int head = xemacpsif->rxHead; + int rxHead = xemacpsif->rxHead; + BaseType_t xEMACIndex = xemacpsif->emacps.Config.DeviceId; + BaseType_t xAccepted; #if ( ipconfigUSE_LINKED_RX_MESSAGES != 0 ) NetworkBufferDescriptor_t * pxFirstDescriptor = NULL; @@ -372,35 +504,50 @@ int emacps_check_rx( xemacpsif_s * xemacpsif ) /* This FreeRTOS+TCP driver shall be compiled with the option * "ipconfigUSE_LINKED_RX_MESSAGES" enabled. It allows the driver to send a - * chain of RX messages within one message to the IP-task. */ + * chain of RX messages within one message to the IP-task. */ for( ; ; ) { - if( ( ( xemacpsif->rxSegments[ head ].address & XEMACPS_RXBUF_NEW_MASK ) == 0 ) || - ( pxDMA_rx_buffers[ head ] == NULL ) ) + if( ( ( xemacpsif->rxSegments[ rxHead ].address & XEMACPS_RXBUF_NEW_MASK ) == 0 ) || + ( pxDMA_rx_buffers[ xEMACIndex ][ rxHead ] == NULL ) ) { break; } - pxNewBuffer = pxGetNetworkBufferWithDescriptor( dmaRX_TX_BUFFER_SIZE, ( TickType_t ) 0 ); + pxBuffer = ( NetworkBufferDescriptor_t * ) pxDMA_rx_buffers[ xEMACIndex ][ rxHead ]; + xAccepted = xMayAcceptPacket( pxBuffer->pucEthernetBuffer ); - if( pxNewBuffer == NULL ) + if( xAccepted == pdFALSE ) { - /* A packet has been received, but there is no replacement for this Network Buffer. - * The packet will be dropped, and it Network Buffer will stay in place. */ - FreeRTOS_printf( ( "emacps_check_rx: unable to allocate a Network Buffer\n" ) ); - pxNewBuffer = ( NetworkBufferDescriptor_t * ) pxDMA_rx_buffers[ head ]; + pxNewBuffer = NULL; } else { - pxBuffer = ( NetworkBufferDescriptor_t * ) pxDMA_rx_buffers[ head ]; + pxNewBuffer = pxGetNetworkBufferWithDescriptor( dmaRX_TX_BUFFER_SIZE, ( TickType_t ) 0 ); + + if( pxNewBuffer == NULL ) + { + /* A packet has been received, but there is no replacement for this Network Buffer. + * The packet will be dropped, and it Network Buffer will stay in place. */ + FreeRTOS_printf( ( "emacps_check_rx: unable to allocate a Network Buffer\n" ) ); + } + } + if( pxNewBuffer == NULL ) + { + pxNewBuffer = ( NetworkBufferDescriptor_t * ) pxDMA_rx_buffers[ xEMACIndex ][ rxHead ]; + } + else + { + pxBuffer->pxInterface = pxInterface; + pxBuffer->pxEndPoint = FreeRTOS_MatchingEndpoint( pxInterface, pxBuffer->pucEthernetBuffer ); + pxBuffer->pxEndPoint = pxInterface->pxEndPoint; /* Just avoiding to use or refer to the same buffer again */ - pxDMA_rx_buffers[ head ] = pxNewBuffer; + pxDMA_rx_buffers[ xEMACIndex ][ rxHead ] = pxNewBuffer; /* * Adjust the buffer size to the actual number of bytes received. */ - rx_bytes = xemacpsif->rxSegments[ head ].flags & XEMACPS_RXBUF_LEN_MASK; + rx_bytes = xemacpsif->rxSegments[ rxHead ].flags & XEMACPS_RXBUF_LEN_MASK; pxBuffer->xDataLength = rx_bytes; @@ -447,25 +594,27 @@ int emacps_check_rx( xemacpsif_s * xemacpsif ) { uint32_t addr = ( ( uint32_t ) pxNewBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK; - if( head == ( ipconfigNIC_N_RX_DESC - 1 ) ) + if( rxHead == ( ipconfigNIC_N_RX_DESC - 1 ) ) { addr |= XEMACPS_RXBUF_WRAP_MASK; } /* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */ - xemacpsif->rxSegments[ head ].flags = 0; - xemacpsif->rxSegments[ head ].address = addr; + xemacpsif->rxSegments[ rxHead ].flags = 0; + xemacpsif->rxSegments[ rxHead ].address = addr; /* Make sure that the value has reached the peripheral by reading it back. */ - ( void ) xemacpsif->rxSegments[ head ].address; + ( void ) xemacpsif->rxSegments[ rxHead ].address; } } - if( ++head == ipconfigNIC_N_RX_DESC ) + rxHead++; + + if( rxHead == ipconfigNIC_N_RX_DESC ) { - head = 0; + rxHead = 0; } - xemacpsif->rxHead = head; + xemacpsif->rxHead = rxHead; } #if ( ipconfigUSE_LINKED_RX_MESSAGES != 0 ) @@ -484,6 +633,7 @@ void clean_dma_txdescs( xemacpsif_s * xemacpsif ) { int index; unsigned char * ucTxBuffer; + BaseType_t xEMACIndex = xemacpsif->emacps.Config.DeviceId; /* Clear all TX descriptors and assign uncached memory to each descriptor. * "tx_space" points to the first available TX buffer. */ @@ -493,7 +643,7 @@ void clean_dma_txdescs( xemacpsif_s * xemacpsif ) { xemacpsif->txSegments[ index ].address = ( uint32_t ) ucTxBuffer; xemacpsif->txSegments[ index ].flags = XEMACPS_TXBUF_USED_MASK; - pxDMA_tx_buffers[ index ] = ( unsigned char * ) NULL; + pxDMA_tx_buffers[ xEMACIndex ][ index ] = ( unsigned char * ) NULL; ucTxBuffer += xemacpsif->uTxUnitSize; } @@ -504,11 +654,12 @@ void clean_dma_txdescs( xemacpsif_s * xemacpsif ) XStatus init_dma( xemacpsif_s * xemacpsif ) { NetworkBufferDescriptor_t * pxBuffer; + BaseType_t xEMACIndex = xemacpsif->emacps.Config.DeviceId; int iIndex; UBaseType_t xRxSize; UBaseType_t xTxSize; - struct xtopology_t * xtopologyp = &xXTopology; + struct xtopology_t * xtopologyp = &( xXTopologies[ xEMACIndex ] ); xRxSize = ipconfigNIC_N_RX_DESC * sizeof( xemacpsif->rxSegments[ 0 ] ); @@ -529,10 +680,10 @@ XStatus init_dma( xemacpsif_s * xemacpsif ) xemacpsif->emacps.RxBdRing.BaseBdAddr = ( uint32_t ) xemacpsif->rxSegments; xemacpsif->emacps.TxBdRing.BaseBdAddr = ( uint32_t ) xemacpsif->txSegments; - if( xTXDescriptorSemaphore == NULL ) + if( xTXDescriptorSemaphores[ xEMACIndex ] == NULL ) { - xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ipconfigNIC_N_TX_DESC, ( UBaseType_t ) ipconfigNIC_N_TX_DESC ); - configASSERT( xTXDescriptorSemaphore ); + xTXDescriptorSemaphores[ xEMACIndex ] = xSemaphoreCreateCounting( ( UBaseType_t ) ipconfigNIC_N_TX_DESC, ( UBaseType_t ) ipconfigNIC_N_TX_DESC ); + configASSERT( xTXDescriptorSemaphores[ xEMACIndex ] ); } /* @@ -540,7 +691,7 @@ XStatus init_dma( xemacpsif_s * xemacpsif ) */ for( iIndex = 0; iIndex < ipconfigNIC_N_RX_DESC; iIndex++ ) { - pxBuffer = pxDMA_rx_buffers[ iIndex ]; + pxBuffer = pxDMA_rx_buffers[ xEMACIndex ][ iIndex ]; if( pxBuffer == NULL ) { @@ -553,10 +704,10 @@ XStatus init_dma( xemacpsif_s * xemacpsif ) } } - xemacpsif->rxSegments[ iIndex ].flags = 0; + xemacpsif->rxSegments[ iIndex ].flags = 0U; xemacpsif->rxSegments[ iIndex ].address = ( ( uint32_t ) pxBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK; - pxDMA_rx_buffers[ iIndex ] = pxBuffer; + pxDMA_rx_buffers[ xEMACIndex ][ iIndex ] = pxBuffer; /* Make sure this memory is not in cache for now. */ if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 ) @@ -598,7 +749,7 @@ XStatus init_dma( xemacpsif_s * xemacpsif ) value |= XEMACPS_NWCFG_RXCHKSUMEN_MASK; #else #warning Are you sure the EMAC should not calculate incoming checksums? - value &= ~XEMACPS_NWCFG_RXCHKSUMEN_MASK; + value &= ~( ( uint32_t ) XEMACPS_NWCFG_RXCHKSUMEN_MASK ); #endif XEmacPs_WriteReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCFG_OFFSET, value ); } @@ -615,7 +766,7 @@ XStatus init_dma( xemacpsif_s * xemacpsif ) /* * Enable the interrupt for emacps. */ - EmacEnableIntr(); + EmacEnableIntr( xEMACIndex ); return 0; } @@ -636,8 +787,8 @@ XStatus init_dma( xemacpsif_s * xemacpsif ) void resetrx_on_no_rxdata( xemacpsif_s * xemacpsif ) { - unsigned long regctrl; - unsigned long tempcntr; + uint32_t regctrl; + uint32_t tempcntr; tempcntr = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXCNT_OFFSET ); @@ -656,12 +807,12 @@ void resetrx_on_no_rxdata( xemacpsif_s * xemacpsif ) xemacpsif->last_rx_frms_cntr = tempcntr; } -void EmacDisableIntr( void ) +void EmacDisableIntr( int xEMACIndex ) { - XScuGic_DisableIntr( INTC_DIST_BASE_ADDR, xXTopology.scugic_emac_intr ); + XScuGic_DisableIntr( INTC_DIST_BASE_ADDR, xXTopologies[ xEMACIndex ].scugic_emac_intr ); } -void EmacEnableIntr( void ) +void EmacEnableIntr( int xEMACIndex ) { - XScuGic_EnableIntr( INTC_DIST_BASE_ADDR, xXTopology.scugic_emac_intr ); + XScuGic_EnableIntr( INTC_DIST_BASE_ADDR, xXTopologies[ xEMACIndex ].scugic_emac_intr ); } diff --git a/source/portable/NetworkInterface/Zynq/x_emacpsif_hw.c b/source/portable/NetworkInterface/Zynq/x_emacpsif_hw.c index 49e7043535..5eb9530f67 100644 --- a/source/portable/NetworkInterface/Zynq/x_emacpsif_hw.c +++ b/source/portable/NetworkInterface/Zynq/x_emacpsif_hw.c @@ -31,12 +31,13 @@ #include "FreeRTOS_IP.h" #include "FreeRTOS_Sockets.h" #include "FreeRTOS_IP_Private.h" +#include "FreeRTOS_Routing.h" #include "NetworkBufferManagement.h" #include "NetworkInterface.h" #include "Zynq/x_emacpsif.h" -extern TaskHandle_t xEMACTaskHandle; +extern TaskHandle_t xEMACTaskHandles[ XPAR_XEMACPS_NUM_INSTANCES ]; /*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c *** to run it on a PEEP board @@ -66,7 +67,6 @@ void start_emacps( xemacpsif_s * xemacps ) XEmacPs_Start( &xemacps->emacps ); } -extern struct xtopology_t xXTopology; volatile int error_msg_count = 0; volatile const char * last_err_msg = ""; @@ -88,8 +88,10 @@ void emacps_error_handler( void * arg, BaseType_t xHigherPriorityTaskWoken = pdFALSE; xemacpsif_s * xemacpsif; BaseType_t xNextHead = xErrorHead; + BaseType_t xEMACIndex; xemacpsif = ( xemacpsif_s * ) ( arg ); + xEMACIndex = xemacpsif->emacps.Config.DeviceId; if( ( Direction != XEMACPS_SEND ) || ( ErrorWord != XEMACPS_TXSR_USEDREAD_MASK ) ) { @@ -110,9 +112,9 @@ void emacps_error_handler( void * arg, xemacpsif->isr_events |= EMAC_IF_ERR_EVENT; } - if( xEMACTaskHandle != NULL ) + if( xEMACTaskHandles[ xEMACIndex ] != NULL ) { - vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken ); + vTaskNotifyGiveFromISR( xEMACTaskHandles[ xEMACIndex ], &xHigherPriorityTaskWoken ); } } @@ -150,18 +152,13 @@ static void emacps_handle_error( void * arg, u32 ErrorWord ) { xemacpsif_s * xemacpsif; - struct xtopology_t * xtopologyp; XEmacPs * xemacps; + BaseType_t xEMACIndex; xemacpsif = ( xemacpsif_s * ) ( arg ); - xtopologyp = &xXTopology; - xemacps = &xemacpsif->emacps; - - /* Do not appear to be used. */ - ( void ) xemacps; - ( void ) xtopologyp; + xEMACIndex = xemacps->Config.DeviceId; last_err_msg = NULL; @@ -174,7 +171,7 @@ static void emacps_handle_error( void * arg, if( ( ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK ) != 0 ) { last_err_msg = "Receive DMA error"; - xNetworkInterfaceInitialise(); + vInitialiseOnIndex( xEMACIndex ); } if( ( ErrorWord & XEMACPS_RXSR_RXOVR_MASK ) != 0 ) @@ -196,7 +193,7 @@ static void emacps_handle_error( void * arg, if( ( ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK ) != 0 ) { last_err_msg = "Transmit DMA error"; - xNetworkInterfaceInitialise(); + vInitialiseOnIndex( xEMACIndex ); } if( ( ErrorWord & XEMACPS_TXSR_URUN_MASK ) != 0 ) diff --git a/source/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c b/source/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c index a023e6c867..75d01fa3b3 100644 --- a/source/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c +++ b/source/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c @@ -63,44 +63,35 @@ #include "FreeRTOS_IP.h" #include "FreeRTOS_Sockets.h" #include "FreeRTOS_IP_Private.h" +#include "FreeRTOS_Routing.h" #include "NetworkBufferManagement.h" #include "Zynq/x_emacpsif.h" #include "xparameters_ps.h" #include "xparameters.h" +#define ETH0_PHY_ADDRESS ( 1 ) /* Hardwired in WFI PCB */ +#define ETH1_PHY_ADDRESS ( 2 ) /* Hardwired in WFI PCB */ +int phy_detected[ 2 ] = { ETH0_PHY_ADDRESS, ETH1_PHY_ADDRESS }; -int phy_detected = 0; - -/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c - *** to run it on a PEEP board - ***/ /* Advertisement control register. */ -#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ -#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ -#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ -#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ #define ADVERTISE_100_AND_10 \ ( ADVERTISE_10FULL | ADVERTISE_100FULL | \ ADVERTISE_10HALF | ADVERTISE_100HALF ) -#define ADVERTISE_100 ( ADVERTISE_100FULL | ADVERTISE_100HALF ) -#define ADVERTISE_10 ( ADVERTISE_10FULL | ADVERTISE_10HALF ) - -#define ADVERTISE_1000 0x0300 +#define ADVERTISE_100 ( ADVERTISE_100FULL | ADVERTISE_100HALF ) +#define ADVERTISE_10 ( ADVERTISE_10FULL | ADVERTISE_10HALF ) +#define ADVERTISE_1000 0x0300 -/*#define PHY_REG_00_BMCR 0x00 // Basic mode control register */ -/*#define PHY_REG_01_BMSR 0x01 // Basic mode status register */ -/*#define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1 */ -/*#define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2 */ -/*#define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg */ #define IEEE_CONTROL_REG_OFFSET 0 #define IEEE_STATUS_REG_OFFSET 1 -#define IEEE_PHYSID1_OFFSET 2 -#define IEEE_PHYSID2_OFFSET 3 #define IEEE_AUTONEGO_ADVERTISE_REG 4 #define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5 #define IEEE_1000_ADVERTISE_REG_OFFSET 9 @@ -137,6 +128,9 @@ int phy_detected = 0; #define IEEE_PAUSE_MASK 0x0400 #define IEEE_AUTONEG_ERROR_MASK 0x8000 +#define PHY_DETECT_REG 1 +#define PHY_DETECT_MASK 0x1808 + #define XEMACPS_GMII2RGMII_SPEED1000_FD 0x140 #define XEMACPS_GMII2RGMII_SPEED100_FD 0x2100 #define XEMACPS_GMII2RGMII_SPEED10_FD 0x100 @@ -168,18 +162,18 @@ int phy_detected = 0; static int detect_phy( XEmacPs * xemacpsp ) { u16 id_lower, id_upper; - u32 phy_addr, id; + u32 phy_addr; for( phy_addr = 0; phy_addr < PHY_ADDRESS_COUNT; phy_addr++ ) { - XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_PHYSID1_OFFSET, &id_lower ); + XEmacPs_PhyRead( xemacpsp, phy_addr, PHY_DETECT_REG, &id_lower ); - if( ( id_lower != ( u16 ) 0xFFFFu ) && ( id_lower != ( u16 ) 0x0u ) ) + if( ( id_lower != 0xFFFF ) && + ( ( id_lower & PHY_DETECT_MASK ) == PHY_DETECT_MASK ) ) { - XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_PHYSID2_OFFSET, &id_upper ); - id = ( ( ( uint32_t ) id_upper ) << 16 ) | ( id_lower & 0xFFF0 ); - FreeRTOS_printf( ( "XEmacPs detect_phy: %04lX at address %d.\n", id, phy_addr ) ); - phy_detected = phy_addr; + /* Found a valid PHY address */ + FreeRTOS_printf( ( "XEmacPs detect_phy: PHY detected at address %d.\n", phy_addr ) ); + phy_detected[ xemacpsp->Config.DeviceId ] = phy_addr; return phy_addr; } } @@ -297,6 +291,7 @@ static int detect_phy( XEmacPs * xemacpsp ) #if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1 u32 phy_addr = XPAR_PCSPMA_SGMII_PHYADDR; #else + /* PHY addresses hardcoded ETH0=1 and ETH1=2. */ u32 phy_addr = detect_phy( xemacpsp ); #endif FreeRTOS_printf( ( "Start PHY autonegotiation \n" ) ); @@ -435,66 +430,73 @@ static int detect_phy( XEmacPs * xemacpsp ) } #endif /* if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1 */ } -#endif /* ifdef PEEP */ +#endif /* Zynq */ unsigned configure_IEEE_phy_speed( XEmacPs * xemacpsp, unsigned speed ) { u16 control; - u32 phy_addr = detect_phy( xemacpsp ); + u32 phy_addr; + int i; - XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2 ); - XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control ); - control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK; - XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control ); + for( i = 0; i < 2; i++ ) + { + phy_addr = phy_detected[ i ]; /* Both PHYs are connected to ETH0 */ - XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0 ); + XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2 ); + XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control ); + control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK; + XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control ); - XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control ); - control |= IEEE_ASYMMETRIC_PAUSE_MASK; - control |= IEEE_PAUSE_MASK; - XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control ); + XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0 ); - XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control ); - control &= ~IEEE_CTRL_LINKSPEED_1000M; - control &= ~IEEE_CTRL_LINKSPEED_100M; - control &= ~IEEE_CTRL_LINKSPEED_10M; + XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control ); + control |= IEEE_ASYMMETRIC_PAUSE_MASK; + control |= IEEE_PAUSE_MASK; + XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control ); - if( speed == 1000 ) - { - control |= IEEE_CTRL_LINKSPEED_1000M; - } + XEmacPs_PhyRead( xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control ); + control &= ~IEEE_CTRL_LINKSPEED_1000M; + control &= ~IEEE_CTRL_LINKSPEED_100M; + control &= ~IEEE_CTRL_LINKSPEED_10M; - else if( speed == 100 ) - { - control |= IEEE_CTRL_LINKSPEED_100M; - /* Dont advertise PHY speed of 1000 Mbps */ - XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, 0 ); - /* Dont advertise PHY speed of 10 Mbps */ - XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, - ADVERTISE_100 ); - } + if( speed == 1000 ) + { + control |= IEEE_CTRL_LINKSPEED_1000M; + } - else if( speed == 10 ) - { - control |= IEEE_CTRL_LINKSPEED_10M; - /* Dont advertise PHY speed of 1000 Mbps */ - XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, - 0 ); - /* Dont advertise PHY speed of 100 Mbps */ - XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, - ADVERTISE_10 ); - } + else if( speed == 100 ) + { + control |= IEEE_CTRL_LINKSPEED_100M; + /* Dont advertise PHY speed of 1000 Mbps */ + XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, 0 ); + /* Dont advertise PHY speed of 10 Mbps */ + XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, + ADVERTISE_100 ); + } - XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, - control | IEEE_CTRL_RESET_MASK ); - { - volatile int wait; + else if( speed == 10 ) + { + control |= IEEE_CTRL_LINKSPEED_10M; + /* Dont advertise PHY speed of 1000 Mbps */ + XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, + 0 ); + /* Dont advertise PHY speed of 100 Mbps */ + XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, + ADVERTISE_10 ); + } - for( wait = 0; wait < 100000; wait++ ) + XEmacPs_PhyWrite( xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, + control | IEEE_CTRL_RESET_MASK ); { + volatile int wait; + + for( wait = 0; wait < 100000; wait++ ) + { + } } } + return 0; } diff --git a/source/portable/NetworkInterface/Zynq/x_topology.h b/source/portable/NetworkInterface/Zynq/x_topology.h index d6fe110b6b..67b773154d 100644 --- a/source/portable/NetworkInterface/Zynq/x_topology.h +++ b/source/portable/NetworkInterface/Zynq/x_topology.h @@ -38,10 +38,7 @@ unsigned scugic_emac_intr; /* valid only for GEM */ }; - extern int x_topology_n_emacs; - extern struct xtopology_t x_topology[]; - - int x_topology_find_index( unsigned base ); + extern struct xtopology_t xXTopologies[ XPAR_XEMACPS_NUM_INSTANCES ]; #ifdef __cplusplus } diff --git a/source/portable/NetworkInterface/esp32/NetworkInterface.c b/source/portable/NetworkInterface/esp32/NetworkInterface.c index cd79234319..67af7e4bee 100644 --- a/source/portable/NetworkInterface/esp32/NetworkInterface.c +++ b/source/portable/NetworkInterface/esp32/NetworkInterface.c @@ -45,7 +45,62 @@ enum if_state_t static const char * TAG = "NetInterface"; volatile static uint32_t xInterfaceState = INTERFACE_DOWN; -BaseType_t xNetworkInterfaceInitialise( void ) +static NetworkInterface_t * pxMyInterface; + +static BaseType_t xESP32_Eth_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface ); + +static BaseType_t xESP32_Eth_NetworkInterfaceOutput( NetworkInterface_t * pxInterface, + NetworkBufferDescriptor_t * const pxDescriptor, + BaseType_t xReleaseAfterSend ); + +static BaseType_t xESP32_Eth_GetPhyLinkStatus( NetworkInterface_t * pxInterface ); + +NetworkInterface_t * pxESP32_Eth_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ); + +/*-----------------------------------------------------------*/ + +#if ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) + +/* Do not call the following function directly. It is there for downward compatibility. + * The function FreeRTOS_IPInit() will call it to initialice the interface and end-point + * objects. See the description in FreeRTOS_Routing.h. */ + NetworkInterface_t * pxFillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ) + { + pxESP32_Eth_FillInterfaceDescriptor( xEMACIndex, pxInterface ); + } + +#endif /* ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) */ +/*-----------------------------------------------------------*/ + + +NetworkInterface_t * pxESP32_Eth_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ) +{ + static char pcName[ 8 ]; + +/* This function pxESP32_Eth_FillInterfaceDescriptor() adds a network-interface. + * Make sure that the object pointed to by 'pxInterface' + * is declared static or global, and that it will remain to exist. */ + + snprintf( pcName, sizeof( pcName ), "eth%ld", xEMACIndex ); + + memset( pxInterface, '\0', sizeof( *pxInterface ) ); + pxInterface->pcName = pcName; /* Just for logging, debugging. */ + pxInterface->pvArgument = ( void * ) xEMACIndex; /* Has only meaning for the driver functions. */ + pxInterface->pfInitialise = xESP32_Eth_NetworkInterfaceInitialise; + pxInterface->pfOutput = xESP32_Eth_NetworkInterfaceOutput; + pxInterface->pfGetPhyLinkStatus = xESP32_Eth_GetPhyLinkStatus; + + FreeRTOS_AddNetworkInterface( pxInterface ); + pxMyInterface = pxInterface; + + return pxInterface; +} +/*-----------------------------------------------------------*/ + +static BaseType_t xESP32_Eth_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface ) { static BaseType_t xMACAdrInitialized = pdFALSE; uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ]; @@ -65,8 +120,21 @@ BaseType_t xNetworkInterfaceInitialise( void ) return pdFALSE; } -BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, - BaseType_t xReleaseAfterSend ) +static BaseType_t xESP32_Eth_GetPhyLinkStatus( NetworkInterface_t * pxInterface ) +{ + BaseType_t xResult = pdFALSE; + + if( xInterfaceState == INTERFACE_UP ) + { + xResult = pdTRUE; + } + + return xResult; +} + +static BaseType_t xESP32_Eth_NetworkInterfaceOutput( NetworkInterface_t * pxInterface, + NetworkBufferDescriptor_t * const pxDescriptor, + BaseType_t xReleaseAfterSend ) { if( ( pxNetworkBuffer == NULL ) || ( pxNetworkBuffer->pucEthernetBuffer == NULL ) || ( pxNetworkBuffer->xDataLength == 0 ) ) { @@ -152,6 +220,8 @@ esp_err_t wlanif_input( void * netif, { /* Set the packet size, in case a larger buffer was returned. */ pxNetworkBuffer->xDataLength = len; + pxNetworkBuffer->pxInterface = pxMyInterface; + pxNetworkBuffer->pxEndPoint = FreeRTOS_MatchingEndpoint( pxMyInterface, pcBuffer ); /* Copy the packet data. */ memcpy( pxNetworkBuffer->pucEthernetBuffer, buffer, len ); diff --git a/source/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c b/source/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c index 131b571fe7..9128947aa7 100644 --- a/source/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c +++ b/source/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c @@ -36,6 +36,7 @@ #include "event_groups.h" #include "FreeRTOS_IP.h" #include "FreeRTOS_IP_Private.h" +#include "FreeRTOS_Routing.h" #include "NetworkInterface.h" #include "NetworkBufferManagement.h" @@ -102,7 +103,7 @@ static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit; /* local prototypes */ - static bool StartInitMac( void ); + static bool StartInitMac( NetworkInterface_t * pxInterface ); static void StartInitCleanup( void ); static void SetMacCtrl( TCPIP_MAC_MODULE_CTRL * pMacCtrl ); @@ -124,6 +125,17 @@ static void MacRxPackets( void ); static void MacProcessRxPacket( TCPIP_MAC_PACKET * pRxPkt ); + static NetworkInterface_t * pxMyInterface; + static BaseType_t xPIC32_Eth_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface ); + + static BaseType_t xPIC32_Eth_NetworkInterfaceOutput( NetworkInterface_t * pxInterface, + NetworkBufferDescriptor_t * const pxDescriptor, + BaseType_t xReleaseAfterSend ); + + static BaseType_t xPIC32_Eth_GetPhyLinkStatus( NetworkInterface_t * pxInterface ); + + NetworkInterface_t * pxPIC32_Eth_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ); /* memory allocation mapping to FreeRTOS */ static void * _malloc( size_t nBytes ) @@ -207,9 +219,47 @@ }; #endif /* (PIC32_MAC_DEBUG_COMMANDS != 0) */ + #if ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) + +/* Do not call the following function directly. It is there for downward compatibility. + * The function FreeRTOS_IPInit() will call it to initialice the interface and end-point + * objects. See the description in FreeRTOS_Routing.h. */ + NetworkInterface_t * pxFillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ) + { + pxPIC32_Eth_FillInterfaceDescriptor( xEMACIndex, pxInterface ); + } + + #endif /* ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) */ +/*-----------------------------------------------------------*/ + + NetworkInterface_t * pxPIC32_Eth_FillInterfaceDescriptor( BaseType_t xEMACIndex, + NetworkInterface_t * pxInterface ) + { + static char pcName[ 8 ]; + +/* This function pxPIC32_Eth_FillInterfaceDescriptor() adds a network-interface. + * Make sure that the object pointed to by 'pxInterface' + * is declared static or global, and that it will remain to exist. */ + + snprintf( pcName, sizeof( pcName ), "eth%ld", xEMACIndex ); + + memset( pxInterface, '\0', sizeof( *pxInterface ) ); + pxInterface->pcName = pcName; /* Just for logging, debugging. */ + pxInterface->pvArgument = ( void * ) xEMACIndex; /* Has only meaning for the driver functions. */ + pxInterface->pfInitialise = xPIC32_Eth_NetworkInterfaceInitialise; + pxInterface->pfOutput = xPIC32_Eth_NetworkInterfaceOutput; + pxInterface->pfGetPhyLinkStatus = xPIC32_Eth_GetPhyLinkStatus; + + FreeRTOS_AddNetworkInterface( pxInterface ); + pxMyInterface = pxInterface; + + return pxInterface; + } + /*-----------------------------------------------------------*/ /* FreeRTOS implementation functions */ - BaseType_t xNetworkInterfaceInitialise( void ) + static BaseType_t xPIC32_Eth_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface ) { BaseType_t xResult; @@ -229,7 +279,7 @@ if( xMacInitStatus == eMACPass ) { - xResult = xGetPhyLinkStatus(); + xResult = xPIC32_Eth_GetPhyLinkStatus( pxMyInterface ); } else { @@ -241,12 +291,14 @@ return xResult; } - /*-----------------------------------------------------------*/ - BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, - BaseType_t xReleaseAfterSend ) +/*-----------------------------------------------------------*/ + static BaseType_t xPIC32_Eth_NetworkInterfaceOutput( NetworkInterface_t * pxInterface, + NetworkBufferDescriptor_t * const pxDescriptor, + BaseType_t xReleaseAfterSend ) { + BaseType_t xEMACIndex = ( BaseType_t ) pxInterface->pvArgument; TCPIP_MAC_RES macRes; TCPIP_MAC_PACKET * pTxPkt; @@ -317,11 +369,12 @@ /* */ - static bool StartInitMac( void ) + static bool StartInitMac( NetworkInterface_t * pxInterface ) { TCPIP_MAC_MODULE_CTRL macCtrl; SYS_MODULE_INIT moduleInit; EventBits_t evBits; + NetworkEndPoint_t * pxEndPoint; /* perform some initialization of all variables so that we can cleanup what failed */ @@ -360,8 +413,15 @@ * FreeRTOSConfig.h and therefore it will be initialized to the * factory programmed MAC address. */ SetMacCtrl( &macCtrl ); - /* Set the mac address in the FreeRTOS+TCP stack. */ - FreeRTOS_UpdateMACAddress( macCtrl.ifPhyAddress.v ); + + /* Set the mac address in the end-points. */ + for( pxEndPoint = FreeRTOS_FirstEndPoint( pxInterface ); + pxEndPoint != NULL; + pxEndPoint = FreeRTOS_NextEndPoint( pxInterface, pxEndPoint ) ) + { + /* This driver, for now, will have the same MAC-address for all its end-points. */ + memcpy( pxEndPoint->xMACAddress.ucBytes, macCtrl.ifPhyAddress.v, ipMAC_ADDRESS_LENGTH_BYTES ); + } TCPIP_MAC_INIT macInit = { @@ -677,9 +737,9 @@ /*-----------------------------------------------------------*/ - BaseType_t xGetPhyLinkStatus( void ) + static BaseType_t xPIC32_Eth_GetPhyLinkStatus( NetworkInterface_t * pxInterface ) { - return macLinkStatus == true ? pdPASS : pdFAIL; + return ( macLinkStatus == true ) ? pdPASS : pdFAIL; } @@ -748,6 +808,8 @@ } PIC32_MacAssociate( pRxPkt, pxBufferDescriptor, pktLength ); + pxBufferDescriptor->pxInterface = pxMyInterface; + pxBufferDescriptor->pxEndPoint = FreeRTOS_MatchingEndpoint( pxMyInterface, pxBufferDescriptor->pucEthernetBuffer ); xRxEvent.eEventType = eNetworkRxEvent; xRxEvent.pvData = ( void * ) pxBufferDescriptor; diff --git a/test/unit-test/ConfigFiles/FreeRTOSIPConfig.h b/test/unit-test/ConfigFiles/FreeRTOSIPConfig.h index 8369700c9e..4dc2e966a9 100644 --- a/test/unit-test/ConfigFiles/FreeRTOSIPConfig.h +++ b/test/unit-test/ConfigFiles/FreeRTOSIPConfig.h @@ -37,7 +37,7 @@ #define ipconfigMULTI_INTERFACE 1 #define ipconfigCOMPATIBLE_WITH_SINGLE 0 -#define ipconfigUSE_IPv4 ( 1 ) +#define ipconfigUSE_IPv4 ( 1 ) /* Set to 1 to print out debug messages. If ipconfigHAS_DEBUG_PRINTF is set to * 1 then FreeRTOS_debug_printf should be defined to the function used to print diff --git a/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c b/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c index 3f10eedf2d..9dde9c9db1 100644 --- a/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c +++ b/test/unit-test/FreeRTOS_ARP/FreeRTOS_ARP_utest.c @@ -2188,4 +2188,4 @@ void test_FreeRTOS_PrintARPCache( void ) /* Nothing to actually unit-test here. */ FreeRTOS_PrintARPCache(); -} +} \ No newline at end of file diff --git a/test/unit-test/FreeRTOS_DHCP/FreeRTOS_DHCP_utest.c b/test/unit-test/FreeRTOS_DHCP/FreeRTOS_DHCP_utest.c index 235571f77f..bbbda0a790 100644 --- a/test/unit-test/FreeRTOS_DHCP/FreeRTOS_DHCP_utest.c +++ b/test/unit-test/FreeRTOS_DHCP/FreeRTOS_DHCP_utest.c @@ -67,9 +67,9 @@ static NetworkBufferDescriptor_t * GetNetworkBuffer( size_t SizeOfEthBuf, static void ReleaseNetworkBuffer( void ) { /* Free the ethernet buffer. */ - free( ((uint8_t *) pxGlobalNetworkBuffer[ --GlobalBufferCounter ]->pucEthernetBuffer) - ipBUFFER_PADDING ); + free( ( ( uint8_t * ) pxGlobalNetworkBuffer[ --GlobalBufferCounter ]->pucEthernetBuffer ) - ipBUFFER_PADDING ); /* Free the network buffer. */ - free( ((uint8_t *) pxGlobalNetworkBuffer[ GlobalBufferCounter ]) - ipBUFFER_PADDING ); + free( ( ( uint8_t * ) pxGlobalNetworkBuffer[ GlobalBufferCounter ] ) - ipBUFFER_PADDING ); } static void ReleaseUDPBuffer( const void * temp, @@ -488,7 +488,7 @@ void test_vDHCPProcess_ResetAndIncorrectStateWithRNGSuccessSocketCreationFail( v xSocketValid_ExpectAnyArgsAndReturn( pdTRUE ); xSocketValid_ExpectAnyArgsAndReturn( pdFALSE ); - + /* See if the timer is reloaded. */ vDHCP_RATimerReload_Expect( &xEndPoint, dhcpINITIAL_TIMER_PERIOD ); /* Try all kinds of states. */ @@ -545,7 +545,6 @@ void test_vDHCPProcess_ResetAndIncorrectStateWithRNGSuccessSocketBindFail( void vSocketBind_ExpectAnyArgsAndReturn( pdTRUE ); catch_assert( vDHCPProcess( pdTRUE, pxEndPoint ) ); - } } diff --git a/test/unit-test/FreeRTOS_DNS/FreeRTOS_DNS_utest.c b/test/unit-test/FreeRTOS_DNS/FreeRTOS_DNS_utest.c index f48a596a84..f7af5daf80 100644 --- a/test/unit-test/FreeRTOS_DNS/FreeRTOS_DNS_utest.c +++ b/test/unit-test/FreeRTOS_DNS/FreeRTOS_DNS_utest.c @@ -123,7 +123,7 @@ void test_FreeRTOS_gethostbyname_fail_allocate_network_buffer( void ) Prepare_CacheLookup_ExpectAnyArgsAndReturn( 0 ); xApplicationGetRandomNumber_IgnoreAndReturn( pdTRUE ); - DNS_CreateSocket_ExpectAnyArgsAndReturn( &xDNSSocket); + DNS_CreateSocket_ExpectAnyArgsAndReturn( &xDNSSocket ); FreeRTOS_FirstEndPoint_IgnoreAndReturn( &xEndPoint ); FreeRTOS_NextEndPoint_IgnoreAndReturn( NULL ); @@ -310,7 +310,6 @@ void test_FreeRTOS_gethostbyname_fail_read_dns_reply_null( void ) /* prvFillSockAddress */ for( i = 0; i < ipconfigDNS_REQUEST_ATTEMPTS; i++ ) { - /* in prvGetHostByName */ /* in prvGetPayloadBuffer */ pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( &xNetworkBuffer ); @@ -318,7 +317,7 @@ void test_FreeRTOS_gethostbyname_fail_read_dns_reply_null( void ) /* back prvGetHostByNameOp */ DNS_SendRequest_ExpectAnyArgsAndReturn( pdPASS ); - DNS_ReadReply_ExpectAnyArgsAndReturn(0); + DNS_ReadReply_ExpectAnyArgsAndReturn( 0 ); DNS_ReadReply_ReturnThruPtr_pxReceiveBuffer( &xReceiveBuffer ); } @@ -375,11 +374,10 @@ void test_FreeRTOS_gethostbyname_fail_send_dns_reply_zero( void ) /* prvFillSockAddress */ for( i = 0; i < ipconfigDNS_REQUEST_ATTEMPTS; i++ ) { - pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( &xNetworkBuffer ); /* back prvGetHostByNameOp */ DNS_SendRequest_ExpectAnyArgsAndReturn( pdPASS ); - DNS_ReadReply_ExpectAnyArgsAndReturn(0); + DNS_ReadReply_ExpectAnyArgsAndReturn( 0 ); DNS_ReadReply_ReturnThruPtr_pxReceiveBuffer( &xReceiveBuffer ); FreeRTOS_ReleaseUDPPayloadBuffer_ExpectAnyArgs(); @@ -442,7 +440,7 @@ void test_FreeRTOS_gethostbyname_succes( void ) /* prvFillSockAddress */ /* back prvGetHostByNameOp */ DNS_SendRequest_ExpectAnyArgsAndReturn( pdPASS ); - DNS_ReadReply_ExpectAnyArgsAndReturn(4); + DNS_ReadReply_ExpectAnyArgsAndReturn( 4 ); DNS_ReadReply_ReturnThruPtr_pxReceiveBuffer( &xReceiveBuffer ); /* prvDNSReply */ DNS_ParseDNSReply_ExpectAnyArgsAndReturn( 12345 ); @@ -671,7 +669,7 @@ void test_FreeRTOS_gethostbyname_a_no_callback_retry_once( void ) xDNSSocket.usLocalPort = 0; xEndPoint.bits.bIPv6 = pdFALSE; xEndPoint.ipv4_settings.ucDNSIndex = 0; - xEndPoint.ipv4_settings.ulDNSServerAddresses[0] = 0xC0C0C0C0; + xEndPoint.ipv4_settings.ulDNSServerAddresses[ 0 ] = 0xC0C0C0C0; DNS_BindSocket_IgnoreAndReturn( 0 ); FreeRTOS_inet_addr_ExpectAndReturn( GOOD_ADDRESS, 0 ); @@ -696,7 +694,7 @@ void test_FreeRTOS_gethostbyname_a_no_callback_retry_once( void ) DNS_SendRequest_ExpectAnyArgsAndReturn( pdPASS ); /* back in prvGetHostByNameOp */ - DNS_ReadReply_ExpectAnyArgsAndReturn(4); + DNS_ReadReply_ExpectAnyArgsAndReturn( 4 ); DNS_ReadReply_ReturnThruPtr_pxReceiveBuffer( &xReceiveBuffer ); /* prvDNSReply */ DNS_ParseDNSReply_ExpectAnyArgsAndReturn( 12345 ); diff --git a/test/unit-test/FreeRTOS_DNS_Networking/FreeRTOS_DNS_Networking_utest.c b/test/unit-test/FreeRTOS_DNS_Networking/FreeRTOS_DNS_Networking_utest.c index ee01f38283..d8e9291269 100644 --- a/test/unit-test/FreeRTOS_DNS_Networking/FreeRTOS_DNS_Networking_utest.c +++ b/test/unit-test/FreeRTOS_DNS_Networking/FreeRTOS_DNS_Networking_utest.c @@ -141,6 +141,7 @@ void test_SendRequest_success( void ) uint32_t ret; struct freertos_sockaddr xAddress; struct xDNSBuffer pxDNSBuf; + pxDNSBuf.uxPayloadLength = 1024; FreeRTOS_sendto_ExpectAnyArgsAndReturn( pxDNSBuf.uxPayloadLength ); diff --git a/test/unit-test/FreeRTOS_DNS_Parser/FreeRTOS_DNS_Parser_utest.c b/test/unit-test/FreeRTOS_DNS_Parser/FreeRTOS_DNS_Parser_utest.c index 8006028dbf..66d753d044 100644 --- a/test/unit-test/FreeRTOS_DNS_Parser/FreeRTOS_DNS_Parser_utest.c +++ b/test/unit-test/FreeRTOS_DNS_Parser/FreeRTOS_DNS_Parser_utest.c @@ -1507,13 +1507,13 @@ void test_DNS_ParseDNSReply_ansswer_lmmnr_reply_null_new_netbuffer( void ) hook_return = pdTRUE; pxUDPPayloadBuffer_to_NetworkBuffer_ExpectAnyArgsAndReturn( NULL ); - catch_assert(DNS_ParseDNSReply( pucUDPPayloadBuffer, - uxBufferLength, - &pxAddressInfo, - xExpected, - usPort )); + catch_assert( DNS_ParseDNSReply( pucUDPPayloadBuffer, + uxBufferLength, + &pxAddressInfo, + xExpected, + usPort ) ); - //TEST_ASSERT_EQUAL( pdFALSE, ret ); + /*TEST_ASSERT_EQUAL( pdFALSE, ret ); */ /*ASSERT_DNS_QUERY_HOOK_CALLED(); */ } diff --git a/test/unit-test/FreeRTOS_IP_Timers/FreeRTOS_IP_Timers_utest.c b/test/unit-test/FreeRTOS_IP_Timers/FreeRTOS_IP_Timers_utest.c index 7cbcab7a8c..93a46f1c53 100644 --- a/test/unit-test/FreeRTOS_IP_Timers/FreeRTOS_IP_Timers_utest.c +++ b/test/unit-test/FreeRTOS_IP_Timers/FreeRTOS_IP_Timers_utest.c @@ -321,6 +321,7 @@ void test_vCheckNetworkTimers_DHCPTimerActiveAndExpired( void ) void test_vCheckNetworkTimers_DNSTimerActiveAndExpired( void ) { NetworkEndPoint_t xEndPoint; + xARPTimer.bActive = pdFALSE; xDHCPTimer.bActive = pdFALSE; xDNSTimer.bActive = pdTRUE; diff --git a/test/unit-test/FreeRTOS_Sockets/FreeRTOS_Sockets_UDP_API_utest.c b/test/unit-test/FreeRTOS_Sockets/FreeRTOS_Sockets_UDP_API_utest.c index 1e30c44238..f932f7c565 100644 --- a/test/unit-test/FreeRTOS_Sockets/FreeRTOS_Sockets_UDP_API_utest.c +++ b/test/unit-test/FreeRTOS_Sockets/FreeRTOS_Sockets_UDP_API_utest.c @@ -1025,7 +1025,7 @@ void test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy2( void ) } /* - * @brief Sending from IP task without using zero copy. Checks if xIsCallingFromIPTask + * @brief Sending from IP task without using zero copy. Checks if xIsCallingFromIPTask * gets called if xFlags's FREERTOS_MSG_DONTWAIT bit is unset. */ void test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy2_xFlagZero( void )