]> 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 92084617d52554bb4eca6c1398f56165261cee93..4a6af81f915aea31820203ac94df75769b9ef5a5 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
- * FreeRTOS+TCP V2.0.3\r
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\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
@@ -23,7 +23,6 @@
  * http://www.FreeRTOS.org\r
  */\r
 \r
-\r
 /* Standard includes. */\r
 #include <stdint.h>\r
 #include <stdio.h>\r
@@ -39,6 +38,7 @@
 #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
 /* 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
@@ -84,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
@@ -97,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
@@ -120,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
@@ -189,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
@@ -207,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
@@ -250,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
@@ -282,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
@@ -295,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
@@ -317,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
@@ -373,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