/*\r
- * FreeRTOS+TCP 191100 experimental\r
- * Copyright (C) 2018 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+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
+\r
+#include "Zynq/x_emacpsif.h"\r
+#include "Zynq/x_topology.h"\r
+#include "xstatus.h"\r
+\r
+#include "xparameters.h"\r
+#include "xparameters_ps.h"\r
+#include "xil_exception.h"\r
+#include "xil_mmu.h"\r
\r
#include "FreeRTOS.h"\r
#include "task.h"\r
#include "FreeRTOS_IP_Private.h"\r
#include "NetworkBufferManagement.h"\r
\r
-#include "Zynq/x_emacpsif.h"\r
-#include "Zynq/x_topology.h"\r
-#include "xstatus.h"\r
-\r
-#include "xparameters.h"\r
-#include "xparameters_ps.h"\r
-#include "xil_exception.h"\r
-#include "xil_mmu.h"\r
-\r
#include "uncached_memory.h"\r
\r
/* Two defines used to set or clear the EMAC interrupt */\r
#endif\r
#define TX_OFFSET ipconfigPACKET_FILLER_SIZE\r
\r
+#define RX_BUFFER_ALIGNMENT 14\r
+\r
/* Defined in NetworkInterface.c */\r
extern TaskHandle_t xEMACTaskHandle;\r
\r
break;\r
}\r
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
+#warning ipconfigZERO_COPY_TX_DRIVER is defined\r
{\r
void *pvBuffer = pxDMA_tx_buffers[ tail ];\r
NetworkBufferDescriptor_t *pxBuffer;\r
/* Start transmit */\r
xemacpsif->txBusy = pdTRUE;\r
XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) );\r
- /* Reading it back is important compiler is optimised. */\r
- XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET );\r
}\r
dsb();\r
\r
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );\r
}\r
\r
-static void prvPassEthMessages( NetworkBufferDescriptor_t *pxDescriptor )\r
+static NetworkBufferDescriptor_t *ethMsg = NULL;\r
+static NetworkBufferDescriptor_t *ethLast = NULL;\r
+\r
+static void passEthMessages( void )\r
{\r
IPStackEvent_t xRxEvent;\r
\r
xRxEvent.eEventType = eNetworkRxEvent;\r
- xRxEvent.pvData = ( void * ) pxDescriptor;\r
+ xRxEvent.pvData = ( void * ) ethMsg;\r
\r
if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 1000 ) != pdPASS )\r
{\r
/* The buffer could not be sent to the stack so must be released again.\r
This is a deferred handler taskr, not a real interrupt, so it is ok to\r
use the task level function here. */\r
- #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )\r
- {\r
- do\r
- {\r
- NetworkBufferDescriptor_t *pxNext = pxDescriptor->pxNextBuffer;\r
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );\r
- pxDescriptor = pxNext;\r
- } while( pxDescriptor != NULL );\r
- }\r
- #else\r
+ do\r
{\r
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );\r
- }\r
- #endif /* ipconfigUSE_LINKED_RX_MESSAGES */\r
+ NetworkBufferDescriptor_t *xNext = ethMsg->pxNextBuffer;\r
+ vReleaseNetworkBufferAndDescriptor( ethMsg );\r
+ ethMsg = xNext;\r
+ } while( ethMsg != NULL );\r
+\r
iptraceETHERNET_RX_EVENT_LOST();\r
- FreeRTOS_printf( ( "prvPassEthMessages: Can not queue return packet!\n" ) );\r
+ FreeRTOS_printf( ( "passEthMessages: Can not queue return packet!\n" ) );\r
}\r
+\r
+ ethMsg = ethLast = NULL;\r
}\r
\r
int emacps_check_rx( xemacpsif_s *xemacpsif )\r
int rx_bytes;\r
volatile int msgCount = 0;\r
int head = xemacpsif->rxHead;\r
-#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )\r
- NetworkBufferDescriptor_t *pxFirstDescriptor = NULL;\r
- NetworkBufferDescriptor_t *pxLastDescriptor = NULL;\r
-#endif /* ipconfigUSE_LINKED_RX_MESSAGES */\r
\r
/* There seems to be an issue (SI# 692601), see comments below. */\r
resetrx_on_no_rxdata(xemacpsif);\r
break;\r
}\r
\r
- pxNewBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, ( TickType_t ) 0 );\r
+ pxNewBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );\r
if( pxNewBuffer == NULL )\r
{\r
/* A packet has been received, but there is no replacement for this Network Buffer.\r
rx_bytes = xemacpsif->rxSegments[ head ].flags & XEMACPS_RXBUF_LEN_MASK;\r
\r
pxBuffer->xDataLength = rx_bytes;\r
+\r
if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )\r
{\r
Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)rx_bytes );\r
/* store it in the receive queue, where it'll be processed by a\r
different handler. */\r
iptraceNETWORK_INTERFACE_RECEIVE();\r
- #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )\r
- {\r
- pxBuffer->pxNextBuffer = NULL;\r
+ pxBuffer->pxNextBuffer = NULL;\r
\r
- if( pxFirstDescriptor == NULL )\r
- {\r
- // Becomes the first message\r
- pxFirstDescriptor = pxBuffer;\r
- }\r
- else if( pxLastDescriptor != NULL )\r
- {\r
- // Add to the tail\r
- pxLastDescriptor->pxNextBuffer = pxBuffer;\r
- }\r
-\r
- pxLastDescriptor = pxBuffer;\r
+ if( ethMsg == NULL )\r
+ {\r
+ // Becomes the first message\r
+ ethMsg = pxBuffer;\r
}\r
- #else\r
+ else if( ethLast != NULL )\r
{\r
- prvPassEthMessages( pxBuffer );\r
+ // Add to the tail\r
+ ethLast->pxNextBuffer = pxBuffer;\r
}\r
- #endif /* ipconfigUSE_LINKED_RX_MESSAGES */\r
\r
+ ethLast = pxBuffer;\r
msgCount++;\r
}\r
{\r
if( ucIsCachedMemory( pxNewBuffer->pucEthernetBuffer ) != 0 )\r
{\r
- Xil_DCacheInvalidateRange( ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE );\r
+ Xil_DCacheInvalidateRange( ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);\r
}\r
{\r
uint32_t addr = ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;\r
addr |= XEMACPS_RXBUF_WRAP_MASK;\r
}\r
/* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */\r
- xemacpsif->rxSegments[ head ].flags = 0;\r
xemacpsif->rxSegments[ head ].address = addr;\r
- if (xemacpsif->rxSegments[ head ].address)\r
- {\r
- // Just to read it\r
- }\r
+ xemacpsif->rxSegments[ head ].flags = 0;\r
}\r
}\r
\r
xemacpsif->rxHead = head;\r
}\r
\r
- #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )\r
+ if( ethMsg != NULL )\r
{\r
- if( pxFirstDescriptor != NULL )\r
- {\r
- prvPassEthMessages( pxFirstDescriptor );\r
- }\r
+ passEthMessages( );\r
}\r
- #endif /* ipconfigUSE_LINKED_RX_MESSAGES */\r
\r
return msgCount;\r
}\r
xemacpsif->txSegments[ index ].address = ( uint32_t )ucTxBuffer;\r
xemacpsif->txSegments[ index ].flags = XEMACPS_TXBUF_USED_MASK;\r
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
- pxDMA_tx_buffers[ index ] = ( unsigned char * )NULL;\r
+ pxDMA_tx_buffers[ index ] = ( void* )NULL;\r
#else\r
- pxDMA_tx_buffers[ index ] = ( unsigned char * )( ucTxBuffer + TX_OFFSET );\r
+ pxDMA_tx_buffers[ index ] = ( void* )( ucTxBuffer + TX_OFFSET );\r
#endif\r
ucTxBuffer += xemacpsif->uTxUnitSize;\r
}\r
pxBuffer = pxDMA_rx_buffers[ iIndex ];\r
if( pxBuffer == NULL )\r
{\r
- pxBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, ( TickType_t ) 0 );\r
+ pxBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );\r
if( pxBuffer == NULL )\r
{\r
FreeRTOS_printf( ("Unable to allocate a network buffer in recv_handler\n" ) );\r
if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )\r
{\r
Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE,\r
- (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE );\r
+ (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);\r
}\r
}\r
\r