]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / portable / NetworkInterface / Zynq / NetworkInterface.c
index 1c11976cbcec7779ed97ef48964cc7a25bcdd9d9..4a6af81f915aea31820203ac94df75769b9ef5a5 100644 (file)
@@ -1,27 +1,27 @@
 /*\r
-FreeRTOS+TCP V2.0.11\r
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
-\r
-Permission is hereby granted, free of charge, to any person obtaining a copy of\r
-this software and associated documentation files (the "Software"), to deal in\r
-the Software without restriction, including without limitation the rights to\r
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
-the Software, and to permit persons to whom the Software is furnished to do so,\r
-subject to the following conditions:\r
-\r
-The above copyright notice and this permission notice shall be included in all\r
-copies or substantial portions of the Software.\r
-\r
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
-\r
- http://aws.amazon.com/freertos\r
- http://www.FreeRTOS.org\r
-*/\r
+ * FreeRTOS V202002.00\r
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
+ * this software and associated documentation files (the "Software"), to deal in\r
+ * the Software without restriction, including without limitation the rights to\r
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
+ * the Software, and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ *\r
http://aws.amazon.com/freertos\r
http://www.FreeRTOS.org\r
+ */\r
 \r
 /* Standard includes. */\r
 #include <stdint.h>\r
@@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "FreeRTOS_IP.h"\r
 #include "FreeRTOS_Sockets.h"\r
 #include "FreeRTOS_IP_Private.h"\r
+#include "FreeRTOS_ARP.h"\r
 #include "NetworkBufferManagement.h"\r
 #include "NetworkInterface.h"\r
 \r
@@ -50,10 +51,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 /* Provided memory configured as uncached. */\r
 #include "uncached_memory.h"\r
 \r
-#ifndef        BMSR_LINK_STATUS\r
-       #define BMSR_LINK_STATUS            0x0004UL\r
+#ifndef niEMAC_HANDLER_TASK_PRIORITY\r
+       /* Define the priority of the task prvEMACHandlerTask(). */\r
+       #define niEMAC_HANDLER_TASK_PRIORITY    configMAX_PRIORITIES - 1\r
 #endif\r
 \r
+#define niBMSR_LINK_STATUS         0x0004uL\r
+\r
 #ifndef        PHY_LS_HIGH_CHECK_TIME_MS\r
        /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not\r
        receiving packets. */\r
@@ -83,6 +87,13 @@ FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
        #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )\r
 #endif\r
 \r
+#if( ipconfigZERO_COPY_RX_DRIVER == 0 || ipconfigZERO_COPY_TX_DRIVER == 0 )\r
+       #error Please define both 'ipconfigZERO_COPY_RX_DRIVER' and 'ipconfigZERO_COPY_TX_DRIVER' as 1\r
+#endif\r
+\r
+#if( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 || ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )\r
+       #warning Please define both 'ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM' and 'ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM' as 1\r
+#endif\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
@@ -96,6 +107,10 @@ static BaseType_t prvGMACWaitLS( TickType_t xMaxTime );
  */\r
 static void prvEMACHandlerTask( void *pvParameters );\r
 \r
+#if ( ipconfigHAS_PRINTF != 0 )\r
+       static void prvMonitorResources( void );\r
+#endif\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /* EMAC data/descriptions. */\r
@@ -119,7 +134,7 @@ XEmacPs_Config mac_config =
 extern int phy_detected;\r
 \r
 /* A copy of PHY register 1: 'PHY_REG_01_BMSR' */\r
-static uint32_t ulPHYLinkStatus = 0;\r
+static uint32_t ulPHYLinkStatus = 0uL;\r
 \r
 #if( ipconfigUSE_LLMNR == 1 )\r
        static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };\r
@@ -188,7 +203,7 @@ const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pd
                possible priority to ensure the interrupt handler can return directly\r
                to it.  The task's handle is stored in xEMACTaskHandle so interrupts can\r
                notify the task when there is something to process. */\r
-               xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );\r
+               xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &xEMACTaskHandle );\r
        }\r
        else\r
        {\r
@@ -206,7 +221,24 @@ const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pd
 \r
 BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )\r
 {\r
-       if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )\r
+       #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )\r
+       {\r
+       ProtocolPacket_t *pxPacket;\r
+\r
+               /* If the peripheral must calculate the checksum, it wants\r
+               the protocol checksum to have a value of zero. */\r
+               pxPacket = ( ProtocolPacket_t * ) ( pxBuffer->pucEthernetBuffer );\r
+               if( ( pxPacket->xICMPPacket.xIPHeader.ucProtocol != ipPROTOCOL_UDP ) &&\r
+                       ( pxPacket->xICMPPacket.xIPHeader.ucProtocol != ipPROTOCOL_TCP ) )\r
+               {\r
+                       /* The EMAC will calculate the checksum of the IP-header.\r
+                       It can only calculate protocol checksums of UDP and TCP,\r
+                       so for ICMP and other protocols it must be done manually. */\r
+                       usGenerateProtocolChecksum( (uint8_t*)&( pxPacket->xUDPPacket ), pxBuffer->xDataLength, pdTRUE );\r
+               }\r
+       }\r
+       #endif /* ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM */\r
+       if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL )\r
        {\r
                iptraceNETWORK_INTERFACE_TRANSMIT();\r
                emacps_send_message( &xEMACpsif, pxBuffer, bReleaseAfterSend );\r
@@ -249,7 +281,7 @@ BaseType_t xReturn;
                }\r
                ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );\r
 \r
-               if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )\r
+               if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL )\r
                {\r
                        xReturn = pdTRUE;\r
                        break;\r
@@ -281,7 +313,7 @@ BaseType_t xGetPhyLinkStatus( void )
 {\r
 BaseType_t xReturn;\r
 \r
-       if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )\r
+       if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) == 0uL )\r
        {\r
                xReturn = pdFALSE;\r
        }\r
@@ -294,12 +326,58 @@ BaseType_t xReturn;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+#if ( ipconfigHAS_PRINTF != 0 )\r
+       static void prvMonitorResources()\r
+       {\r
+       static UBaseType_t uxLastMinBufferCount = 0u;\r
+       static size_t uxMinLastSize = 0uL;\r
+       UBaseType_t uxCurrentBufferCount;\r
+       size_t uxMinSize;\r
+\r
+               uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();\r
+\r
+               if( uxLastMinBufferCount != uxCurrentBufferCount )\r
+               {\r
+                       /* The logging produced below may be helpful\r
+                        * while tuning +TCP: see how many buffers are in use. */\r
+                       uxLastMinBufferCount = uxCurrentBufferCount;\r
+                       FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",\r
+                                                          uxGetNumberOfFreeNetworkBuffers(),\r
+                                                          uxCurrentBufferCount ) );\r
+               }\r
+\r
+               uxMinSize = xPortGetMinimumEverFreeHeapSize();\r
+\r
+               if( uxMinLastSize != uxMinSize )\r
+               {\r
+                       uxMinLastSize = uxMinSize;\r
+                       FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", xPortGetFreeHeapSize(), uxMinSize ) );\r
+               }\r
+\r
+               #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )\r
+                       {\r
+                               static UBaseType_t uxLastMinQueueSpace = 0;\r
+                               UBaseType_t uxCurrentCount = 0u;\r
+\r
+                               uxCurrentCount = uxGetMinimumIPQueueSpace();\r
+\r
+                               if( uxLastMinQueueSpace != uxCurrentCount )\r
+                               {\r
+                                       /* The logging produced below may be helpful\r
+                                        * while tuning +TCP: see how many buffers are in use. */\r
+                                       uxLastMinQueueSpace = uxCurrentCount;\r
+                                       FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );\r
+                               }\r
+                       }\r
+               #endif /* ipconfigCHECK_IP_QUEUE_SPACE */\r
+       }\r
+#endif /* ( ipconfigHAS_PRINTF != 0 ) */\r
+/*-----------------------------------------------------------*/\r
+\r
 static void prvEMACHandlerTask( void *pvParameters )\r
 {\r
 TimeOut_t xPhyTime;\r
 TickType_t xPhyRemTime;\r
-UBaseType_t uxLastMinBufferCount = 0;\r
-UBaseType_t uxCurrentCount;\r
 BaseType_t xResult = 0;\r
 uint32_t xStatus;\r
 const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );\r
@@ -316,30 +394,11 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
 \r
        for( ;; )\r
        {\r
-               uxCurrentCount = uxGetMinimumFreeNetworkBuffers();\r
-               if( uxLastMinBufferCount != uxCurrentCount )\r
-               {\r
-                       /* The logging produced below may be helpful\r
-                       while tuning +TCP: see how many buffers are in use. */\r
-                       uxLastMinBufferCount = uxCurrentCount;\r
-                       FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",\r
-                               uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );\r
-               }\r
-\r
-               #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )\r
-               {\r
-               static UBaseType_t uxLastMinQueueSpace = 0;\r
-\r
-                       uxCurrentCount = uxGetMinimumIPQueueSpace();\r
-                       if( uxLastMinQueueSpace != uxCurrentCount )\r
+               #if ( ipconfigHAS_PRINTF != 0 )\r
                        {\r
-                               /* The logging produced below may be helpful\r
-                               while tuning +TCP: see how many buffers are in use. */\r
-                               uxLastMinQueueSpace = uxCurrentCount;\r
-                               FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );\r
+                               prvMonitorResources();\r
                        }\r
-               }\r
-               #endif /* ipconfigCHECK_IP_QUEUE_SPACE */\r
+               #endif /* ipconfigHAS_PRINTF != 0 ) */\r
 \r
                if( ( xEMACpsif.isr_events & EMAC_IF_ALL_EVENT ) == 0 )\r
                {\r
@@ -372,19 +431,26 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
                        vTaskSetTimeOutState( &xPhyTime );\r
                        xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );\r
                        xResult = 0;\r
+                       if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) == 0uL )\r
+                       {\r
+                               /* Indicate that the Link Status is high, so that\r
+                               xNetworkInterfaceOutput() can send packets. */\r
+                               ulPHYLinkStatus |= niBMSR_LINK_STATUS;\r
+                               FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS assume 1\n" ) );\r
+                       }\r
                }\r
                else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )\r
                {\r
                        xStatus = ulReadMDIO( PHY_REG_01_BMSR );\r
 \r
-                       if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )\r
+                       if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != ( xStatus & niBMSR_LINK_STATUS ) )\r
                        {\r
                                ulPHYLinkStatus = xStatus;\r
-                               FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );\r
+                               FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL ) );\r
                        }\r
 \r
                        vTaskSetTimeOutState( &xPhyTime );\r
-                       if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )\r
+                       if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL )\r
                        {\r
                                xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );\r
                        }\r