Update TCP/IP tack to latest form Git.

pull/4/head
Richard Barry 6 years ago
parent a6a0403fd6
commit 2e18203bb7

@ -108,11 +108,6 @@ are located. */
located. */
#define dhcpFIRST_OPTION_BYTE_OFFSET ( 0xf0 )
/* When walking the variable length options field, the following value is used
to ensure the walk has not gone past the end of the valid options. 2 bytes is
made up of the length byte, and minimum one byte value. */
#define dhcpMAX_OPTION_LENGTH_OF_INTEREST ( 2L )
/* Standard DHCP port numbers and magic cookie value. */
#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
#define dhcpCLIENT_PORT 0x4400u
@ -647,9 +642,11 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
/* Walk through the options until the dhcpOPTION_END_BYTE byte
is found, taking care not to walk off the end of the options. */
pucByte = &( pxDHCPMessage->ucFirstOptionByte );
pucLastByte = &( pucUDPPayload[ lBytes - dhcpMAX_OPTION_LENGTH_OF_INTEREST ] );
/* Maintain a pointer to the last valid byte (i.e. not the first
invalid byte). */
pucLastByte = pucUDPPayload + lBytes - 1;
while( pucByte < pucLastByte )
while( pucByte <= pucLastByte )
{
ucOptionCode = pucByte[ 0 ];
if( ucOptionCode == dhcpOPTION_END_BYTE )
@ -666,12 +663,13 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
}
/* Stop if the response is malformed. */
if( pucByte < pucLastByte - 1 )
if( pucByte < pucLastByte )
{
/* There are at least two bytes left. */
ucLength = pucByte[ 1 ];
pucByte += 2;
if( pucByte >= pucLastByte - ucLength )
if( pucByte + ucLength > pucLastByte )
{
break;
}
@ -926,7 +924,8 @@ size_t xOptionsLength = sizeof( ucDHCPRequestOptions );
FreeRTOS_debug_printf( ( "vDHCPProcess: reply %lxip\n", FreeRTOS_ntohl( xDHCPData.ulOfferedIPAddress ) ) );
iptraceSENDING_DHCP_REQUEST();
if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )
/* 'ucFirstOptionByte' is part of DHCP message struct, so subtract one byte. */
if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength - 1 ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )
{
/* The packet was not successfully queued for sending and must be
returned to the stack. */
@ -954,7 +953,8 @@ size_t xOptionsLength = sizeof( ucDHCPDiscoverOptions );
FreeRTOS_debug_printf( ( "vDHCPProcess: discover\n" ) );
iptraceSENDING_DHCP_DISCOVER();
if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )
/* 'ucFirstOptionByte' is part of DHCP message struct, so subtract one byte. */
if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength - 1 ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )
{
/* The packet was not successfully queued for sending and must be
returned to the stack. */

@ -151,6 +151,11 @@ static uint32_t prvGetHostByName( const char *pcHostName, TickType_t xIdentifier
} DNSCacheRow_t;
static DNSCacheRow_t xDNSCache[ ipconfigDNS_CACHE_ENTRIES ];
void FreeRTOS_dnsclear()
{
memset( xDNSCache, 0x0, sizeof( xDNSCache ) );
}
#endif /* ipconfigUSE_DNS_CACHE == 1 */
#if( ipconfigUSE_LLMNR == 1 )
@ -809,24 +814,16 @@ static uint8_t *prvSkipNameField( uint8_t *pucByte, size_t xSourceLen )
uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer )
{
uint8_t *pucUDPPayloadBuffer;
size_t xPlayloadBufferLength;
DNSMessage_t *pxDNSMessageHeader;
xPlayloadBufferLength = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
if ( xPlayloadBufferLength < sizeof( DNSMessage_t ) )
if( pxNetworkBuffer->xDataLength >= sizeof( DNSMessage_t ) )
{
return pdFAIL;
}
pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
pxDNSMessageHeader =
( DNSMessage_t * )( pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t ) );
if( pxNetworkBuffer->xDataLength > sizeof( UDPPacket_t ) )
{
prvParseDNSReply( pucUDPPayloadBuffer,
xPlayloadBufferLength,
( uint32_t )pxDNSMessageHeader->usIdentifier );
prvParseDNSReply( ( uint8_t * )pxDNSMessageHeader,
pxNetworkBuffer->xDataLength,
( uint32_t )pxDNSMessageHeader->usIdentifier );
}
/* The packet was not consumed. */
@ -841,12 +838,11 @@ DNSMessage_t *pxDNSMessageHeader;
UDPPacket_t *pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
uint8_t *pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
if( pxNetworkBuffer->xDataLength > sizeof( UDPPacket_t) )
{
prvTreatNBNS( pucUDPPayloadBuffer,
pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t ),
pxUDPPacket->xIPHeader.ulSourceIPAddress );
}
/* The network buffer data length has already been set to the
length of the UDP payload. */
prvTreatNBNS( pucUDPPayloadBuffer,
pxNetworkBuffer->xDataLength,
pxUDPPacket->xIPHeader.ulSourceIPAddress );
/* The packet was not consumed. */
return pdFAIL;
@ -1312,6 +1308,9 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
pxUDPHeader->usLength = FreeRTOS_htons( lNetLength + ipSIZE_OF_UDP_HEADER );
vFlip_16( pxUDPPacket->xUDPHeader.usSourcePort, pxUDPPacket->xUDPHeader.usDestinationPort );
/* Important: tell NIC driver how many bytes must be sent */
pxNetworkBuffer->xDataLength = ( size_t ) ( lNetLength + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_UDP_HEADER + ipSIZE_OF_ETH_HEADER );
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
{
/* calculate the IP header checksum */
@ -1320,13 +1319,10 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
/* calculate the UDP checksum for outgoing package */
usGenerateProtocolChecksum( ( uint8_t* ) pxUDPPacket, lNetLength, pdTRUE );
usGenerateProtocolChecksum( ( uint8_t* ) pxUDPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
}
#endif
/* Important: tell NIC driver how many bytes must be sent */
pxNetworkBuffer->xDataLength = ( size_t ) ( lNetLength + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_UDP_HEADER + ipSIZE_OF_ETH_HEADER );
/* This function will fill in the eth addresses and send the packet */
vReturnEthernetFrame( pxNetworkBuffer, pdFALSE );
}
@ -1342,13 +1338,15 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
BaseType_t xFound = pdFALSE;
uint32_t ulCurrentTimeSeconds = ( xTaskGetTickCount() / portTICK_PERIOD_MS ) / 1000;
static BaseType_t xFreeEntry = 0;
configASSERT(pcName);
/* For each entry in the DNS cache table. */
for( x = 0; x < ipconfigDNS_CACHE_ENTRIES; x++ )
{
if( xDNSCache[ x ].pcName[ 0 ] == 0 )
{
break;
continue;
}
if( 0 == strcmp( xDNSCache[ x ].pcName, pcName ) )
@ -1419,6 +1417,6 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
/* Provide access to private members for testing. */
#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
#include "aws_freertos_tcp_test_access_dns_define.h"
#include "iot_freertos_tcp_test_access_dns_define.h"
#endif

@ -1824,7 +1824,7 @@ uint8_t ucProtocol;
{
return ipINVALID_LENGTH;
}
if( uxBufferLength < FreeRTOS_ntohs( pxIPPacket->xIPHeader.usLength ) )
if( uxBufferLength < ( size_t ) ( ipSIZE_OF_ETH_HEADER + FreeRTOS_ntohs( pxIPPacket->xIPHeader.usLength ) ) )
{
return ipINVALID_LENGTH;
}
@ -2316,3 +2316,9 @@ BaseType_t FreeRTOS_IsNetworkUp( void )
}
#endif
/*-----------------------------------------------------------*/
/* Provide access to private members for verification. */
#ifdef FREERTOS_TCP_ENABLE_VERIFICATION
#include "aws_freertos_ip_verification_access_ip_define.h"
#endif

@ -89,6 +89,11 @@ respectively. */
#define socketNEXT_UDP_PORT_NUMBER_INDEX 0
#define socketNEXT_TCP_PORT_NUMBER_INDEX 1
/* Some helper macro's for defining the 20/80 % limits of uxLittleSpace / uxEnoughSpace. */
#define sock20_PERCENT 20
#define sock80_PERCENT 80
#define sock100_PERCENT 100
/*-----------------------------------------------------------*/
@ -1428,6 +1433,31 @@ FreeRTOS_Socket_t *pxSocket;
break;
#endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */
case FREERTOS_SO_SET_LOW_HIGH_WATER:
{
LowHighWater_t *pxLowHighWater = ( LowHighWater_t * ) pvOptionValue;
if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
{
/* It is not allowed to access 'pxSocket->u.xTCP'. */
FreeRTOS_debug_printf( ( "FREERTOS_SO_SET_LOW_HIGH_WATER: wrong socket type\n" ) );
break; /* will return -pdFREERTOS_ERRNO_EINVAL */
}
if( ( pxLowHighWater->uxLittleSpace >= pxLowHighWater->uxEnoughSpace ) ||
( pxLowHighWater->uxEnoughSpace > pxSocket->u.xTCP.uxRxStreamSize ) )
{
/* Impossible values. */
FreeRTOS_debug_printf( ( "FREERTOS_SO_SET_LOW_HIGH_WATER: bad values\n" ) );
break; /* will return -pdFREERTOS_ERRNO_EINVAL */
}
/* Send a STOP when buffer space drops below 'uxLittleSpace' bytes. */
pxSocket->u.xTCP.uxLittleSpace = pxLowHighWater->uxLittleSpace;
/* Send a GO when buffer space grows above 'uxEnoughSpace' bytes. */
pxSocket->u.xTCP.uxEnoughSpace = pxLowHighWater->uxEnoughSpace;
xReturn = 0;
}
break;
case FREERTOS_SO_SNDBUF: /* Set the size of the send buffer, in units of MSS (TCP only) */
case FREERTOS_SO_RCVBUF: /* Set the size of the receive buffer, in units of MSS (TCP only) */
{
@ -1481,8 +1511,17 @@ FreeRTOS_Socket_t *pxSocket;
}
pxProps = ( ( WinProperties_t * ) pvOptionValue );
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDBUF, &( pxProps->lTxBufSize ), sizeof( pxProps->lTxBufSize ) );
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVBUF, &( pxProps->lRxBufSize ), sizeof( pxProps->lRxBufSize ) );
if ( FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDBUF, &( pxProps->lTxBufSize ), sizeof( pxProps->lTxBufSize ) ) != 0 )
{
break; /* will return -pdFREERTOS_ERRNO_EINVAL */
}
if ( FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVBUF, &( pxProps->lRxBufSize ), sizeof( pxProps->lRxBufSize ) ) != 0 )
{
break; /* will return -pdFREERTOS_ERRNO_EINVAL */
}
#if( ipconfigUSE_TCP_WIN == 1 )
{
pxSocket->u.xTCP.uxRxWinSize = ( uint32_t )pxProps->lRxWinSize; /* Fixed value: size of the TCP reception window */
@ -2373,7 +2412,9 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
{
xResult = -pdFREERTOS_ERRNO_ENOMEM;
}
else if( pxSocket->u.xTCP.ucTCPState == eCLOSED )
else if( pxSocket->u.xTCP.ucTCPState == eCLOSED ||
pxSocket->u.xTCP.ucTCPState == eCLOSE_WAIT ||
pxSocket->u.xTCP.ucTCPState == eCLOSING )
{
xResult = -pdFREERTOS_ERRNO_ENOTCONN;
}
@ -2412,22 +2453,25 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
'*pxLength' will contain the number of bytes that may be written. */
uint8_t *FreeRTOS_get_tx_head( Socket_t xSocket, BaseType_t *pxLength )
{
uint8_t *pucReturn;
uint8_t *pucReturn = NULL;
FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
StreamBuffer_t *pxBuffer = pxSocket->u.xTCP.txStream;
StreamBuffer_t *pxBuffer = NULL;
if( pxBuffer != NULL )
{
BaseType_t xSpace = ( BaseType_t ) uxStreamBufferGetSpace( pxBuffer );
BaseType_t xRemain = ( BaseType_t ) ( pxBuffer->LENGTH - pxBuffer->uxHead );
*pxLength = 0;
*pxLength = FreeRTOS_min_BaseType( xSpace, xRemain );
pucReturn = pxBuffer->ucArray + pxBuffer->uxHead;
}
else
/* Confirm that this is a TCP socket before dereferencing structure
member pointers. */
if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )
{
*pxLength = 0;
pucReturn = NULL;
pxBuffer = pxSocket->u.xTCP.txStream;
if( pxBuffer != NULL )
{
BaseType_t xSpace = ( BaseType_t )uxStreamBufferGetSpace( pxBuffer );
BaseType_t xRemain = ( BaseType_t )( pxBuffer->LENGTH - pxBuffer->uxHead );
*pxLength = FreeRTOS_min_BaseType( xSpace, xRemain );
pucReturn = pxBuffer->ucArray + pxBuffer->uxHead;
}
}
return pucReturn;
@ -2862,9 +2906,17 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
const struct xSTREAM_BUFFER *FreeRTOS_get_rx_buf( Socket_t xSocket )
{
FreeRTOS_Socket_t *pxSocket = (FreeRTOS_Socket_t *)xSocket;
FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * )xSocket;
struct xSTREAM_BUFFER *pxReturn = NULL;
/* Confirm that this is a TCP socket before dereferencing structure
member pointers. */
if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )
{
pxReturn = pxSocket->u.xTCP.rxStream;
}
return pxSocket->u.xTCP.rxStream;
return pxReturn;
}
#endif /* ipconfigUSE_TCP */
@ -2886,12 +2938,12 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
if( pxSocket->u.xTCP.uxLittleSpace == 0ul )
{
pxSocket->u.xTCP.uxLittleSpace = ( 1ul * pxSocket->u.xTCP.uxRxStreamSize ) / 5u; /*_RB_ Why divide by 5? Can this be changed to a #define? */
pxSocket->u.xTCP.uxLittleSpace = ( sock20_PERCENT * pxSocket->u.xTCP.uxRxStreamSize ) / sock100_PERCENT;
}
if( pxSocket->u.xTCP.uxEnoughSpace == 0ul )
{
pxSocket->u.xTCP.uxEnoughSpace = ( 4ul * pxSocket->u.xTCP.uxRxStreamSize ) / 5u; /*_RB_ Why multiply by 4? Maybe sock80_PERCENT?*/
pxSocket->u.xTCP.uxEnoughSpace = ( sock80_PERCENT * pxSocket->u.xTCP.uxRxStreamSize ) / sock100_PERCENT;
}
}
else

@ -307,6 +307,20 @@ static BaseType_t prvSendData( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescrip
*/
static BaseType_t prvTCPHandleState( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer );
/*
* Common code for sending a TCP protocol control packet (i.e. no options, no
* payload, just flags).
*/
static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
uint8_t ucTCPFlags );
/*
* A "challenge ACK" is as per https://tools.ietf.org/html/rfc5961#section-3.2,
* case #3. In summary, an RST was received with a sequence number that is
* unexpected but still within the window.
*/
static BaseType_t prvTCPSendChallengeAck( NetworkBufferDescriptor_t *pxNetworkBuffer );
/*
* Reply to a peer with the RST flag on, in case a packet can not be handled.
*/
@ -738,7 +752,7 @@ NetworkBufferDescriptor_t xTempBuffer;
}
/* Take the minimum of the RX buffer space and the RX window size. */
ulSpace = FreeRTOS_min_uint32( pxSocket->u.xTCP.ulRxCurWinSize, pxTCPWindow->xSize.ulRxWindowLength );
ulSpace = FreeRTOS_min_uint32( pxTCPWindow->xSize.ulRxWindowLength, ulFrontSpace );
if( ( pxSocket->u.xTCP.bits.bLowWater != pdFALSE_UNSIGNED ) || ( pxSocket->u.xTCP.bits.bRxStopped != pdFALSE_UNSIGNED ) )
{
@ -1092,9 +1106,6 @@ uint32_t ulInitialSequenceNumber = 0;
/* Set the values of usInitMSS / usCurMSS for this socket. */
prvSocketSetMSS( pxSocket );
/* For now this is also the advertised window size. */
pxSocket->u.xTCP.ulRxCurWinSize = pxSocket->u.xTCP.usInitMSS;
/* The initial sequence numbers at our side are known. Later
vTCPWindowInit() will be called to fill in the peer's sequence numbers, but
first wait for a SYN+ACK reply. */
@ -2521,7 +2532,6 @@ TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetB
TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
/* Find out what window size we may advertised. */
uint32_t ulFrontSpace;
int32_t lRxSpace;
#if( ipconfigUSE_TCP_WIN == 1 )
#if( ipconfigTCP_ACK_EARLIER_PACKET == 0 )
@ -2530,20 +2540,6 @@ int32_t lRxSpace;
int32_t lMinLength;
#endif
#endif
pxSocket->u.xTCP.ulRxCurWinSize = pxTCPWindow->xSize.ulRxWindowLength -
( pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulCurrentSequenceNumber );
/* Free space in rxStream. */
if( pxSocket->u.xTCP.rxStream != NULL )
{
ulFrontSpace = ( uint32_t ) uxStreamBufferFrontSpace( pxSocket->u.xTCP.rxStream );
}
else
{
ulFrontSpace = ( uint32_t ) pxSocket->u.xTCP.uxRxStreamSize;
}
pxSocket->u.xTCP.ulRxCurWinSize = FreeRTOS_min_uint32( ulFrontSpace, pxSocket->u.xTCP.ulRxCurWinSize );
/* Set the time-out field, so that we'll be called by the IP-task in case no
next message will be received. */
@ -2840,28 +2836,44 @@ TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
}
/*-----------------------------------------------------------*/
static BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t *pxNetworkBuffer )
static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
uint8_t ucTCPFlags )
{
#if( ipconfigIGNORE_UNKNOWN_PACKETS == 0 )
#if( ipconfigIGNORE_UNKNOWN_PACKETS == 0 )
{
TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
const BaseType_t xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + 0u ); /* Plus 0 options. */
TCPPacket_t *pxTCPPacket = ( TCPPacket_t * )( pxNetworkBuffer->pucEthernetBuffer );
const BaseType_t xSendLength = ( BaseType_t )
( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + 0u ); /* Plus 0 options. */
pxTCPPacket->xTCPHeader.ucTCPFlags = ipTCP_FLAG_ACK | ipTCP_FLAG_RST;
pxTCPPacket->xTCPHeader.ucTCPFlags = ucTCPFlags;
pxTCPPacket->xTCPHeader.ucTCPOffset = ( ipSIZE_OF_TCP_HEADER + 0u ) << 2;
prvTCPReturnPacket( NULL, pxNetworkBuffer, ( uint32_t ) xSendLength, pdFALSE );
prvTCPReturnPacket( NULL, pxNetworkBuffer, ( uint32_t )xSendLength, pdFALSE );
}
#endif /* !ipconfigIGNORE_UNKNOWN_PACKETS */
#endif /* !ipconfigIGNORE_UNKNOWN_PACKETS */
/* Remove compiler warnings if ipconfigIGNORE_UNKNOWN_PACKETS == 1. */
( void ) pxNetworkBuffer;
( void )pxNetworkBuffer;
( void )ucTCPFlags;
/* The packet was not consumed. */
return pdFAIL;
}
/*-----------------------------------------------------------*/
static BaseType_t prvTCPSendChallengeAck( NetworkBufferDescriptor_t *pxNetworkBuffer )
{
return prvTCPSendSpecialPacketHelper( pxNetworkBuffer, ipTCP_FLAG_ACK );
}
/*-----------------------------------------------------------*/
static BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t *pxNetworkBuffer )
{
return prvTCPSendSpecialPacketHelper( pxNetworkBuffer,
ipTCP_FLAG_ACK | ipTCP_FLAG_RST );
}
/*-----------------------------------------------------------*/
static void prvSocketSetMSS( FreeRTOS_Socket_t *pxSocket )
{
uint32_t ulMSS = ipconfigTCP_MSS;
@ -2899,8 +2911,13 @@ uint32_t ulLocalIP;
uint16_t xLocalPort;
uint32_t ulRemoteIP;
uint16_t xRemotePort;
uint32_t ulSequenceNumber;
uint32_t ulAckNumber;
BaseType_t xResult = pdPASS;
configASSERT( pxNetworkBuffer );
configASSERT( pxNetworkBuffer->pucEthernetBuffer );
/* Check for a minimum packet size. */
if( pxNetworkBuffer->xDataLength >= ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) )
{
@ -2909,6 +2926,8 @@ BaseType_t xResult = pdPASS;
xLocalPort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usDestinationPort );
ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
xRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
ulSequenceNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
ulAckNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulAckNr );
/* Find the destination socket, and if not found: return a socket listing to
the destination PORT. */
@ -2988,13 +3007,36 @@ BaseType_t xResult = pdPASS;
flag. */
if( ( ucTCPFlags & ipTCP_FLAG_RST ) != 0u )
{
/* The target socket is not in a listening state, any RST packet
will cause the socket to be closed. */
FreeRTOS_debug_printf( ( "TCP: RST received from %lxip:%u for %u\n", ulRemoteIP, xRemotePort, xLocalPort ) );
/* _HT_: should indicate that 'ECONNRESET' must be returned to the used during next API. */
vTCPStateChange( pxSocket, eCLOSED );
/* The packet cannot be handled. */
/* Implement https://tools.ietf.org/html/rfc5961#section-3.2. */
if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
{
/* Per the above RFC, "In the SYN-SENT state ... the RST is
acceptable if the ACK field acknowledges the SYN." */
if( ulAckNumber == pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber + 1 )
{
vTCPStateChange( pxSocket, eCLOSED );
}
}
else
{
/* Check whether the packet matches the next expected sequence number. */
if( ulSequenceNumber == pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber )
{
vTCPStateChange( pxSocket, eCLOSED );
}
/* Otherwise, check whether the packet is within the receive window. */
else if( ulSequenceNumber > pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber &&
ulSequenceNumber < ( pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber +
pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength ) )
{
/* Send a challenge ACK. */
prvTCPSendChallengeAck( pxNetworkBuffer );
}
}
/* Otherwise, do nothing. In any case, the packet cannot be handled. */
xResult = pdFAIL;
}
else if( ( ( ucTCPFlags & ipTCP_FLAG_CTRL ) == ipTCP_FLAG_SYN ) && ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) )
@ -3304,6 +3346,11 @@ BaseType_t xResult = pdFALSE;
/* Provide access to private members for testing. */
#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
#include "aws_freertos_tcp_test_access_tcp_define.h"
#include "iot_freertos_tcp_test_access_tcp_define.h"
#endif
/* Provide access to private members for verification. */
#ifdef FREERTOS_TCP_ENABLE_VERIFICATION
#include "aws_freertos_tcp_verification_access_tcp_define.h"
#endif

@ -292,7 +292,7 @@ void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem
pxWhere->pxPrevious = pxNewListItem;
/* Remember which list the item is in. */
pxNewListItem->pvContainer = ( void * ) pxList; /* If this line fails to build then ensure configENABLE_BACKWARD_COMPATIBILITY is set to 1 in FreeRTOSConfig.h. */
listLIST_ITEM_CONTAINER( pxNewListItem ) = ( void * ) pxList;
( pxList->uxNumberOfItems )++;
}
@ -675,17 +675,17 @@ const int32_t l500ms = 500;
#if( ipconfigUSE_TCP_WIN == 1 )
void vTCPSegmentCleanup( void )
{
/* Free and clear the TCP segments pointer. This function should only be called
* once FreeRTOS+TCP will no longer be used. No thread-safety is provided for this
* function. */
if( xTCPSegments != NULL )
{
vPortFreeLarge( xTCPSegments );
xTCPSegments = NULL;
}
}
void vTCPSegmentCleanup( void )
{
/* Free and clear the TCP segments pointer. This function should only be called
* once FreeRTOS+TCP will no longer be used. No thread-safety is provided for this
* function. */
if( xTCPSegments != NULL )
{
vPortFreeLarge( xTCPSegments );
xTCPSegments = NULL;
}
}
#endif /* ipconfgiUSE_TCP_WIN == 1 */
/*-----------------------------------------------------------*/
@ -805,20 +805,20 @@ const int32_t l500ms = 500;
{
ulSavedSequenceNumber = ulCurrentSequenceNumber;
/* Clean up all sequence received between ulSequenceNumber and ulSequenceNumber + ulLength since they are duplicated.
If the server is forced to retransmit packets several time in a row it might send a batch of concatenated packet for speed.
So we cannot rely on the packets between ulSequenceNumber and ulSequenceNumber + ulLength to be sequential and it is better to just
clean them out. */
do
{
pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
if ( pxFound != NULL )
{
/* Remove it because it will be passed to user directly. */
vTCPWindowFree( pxFound );
}
} while ( pxFound );
/* Clean up all sequence received between ulSequenceNumber and ulSequenceNumber + ulLength since they are duplicated.
If the server is forced to retransmit packets several time in a row it might send a batch of concatenated packet for speed.
So we cannot rely on the packets between ulSequenceNumber and ulSequenceNumber + ulLength to be sequential and it is better to just
clean them out. */
do
{
pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
if ( pxFound != NULL )
{
/* Remove it because it will be passed to user directly. */
vTCPWindowFree( pxFound );
}
} while ( pxFound );
/* Check for following segments that are already in the
queue and increment ulCurrentSequenceNumber. */

@ -240,9 +240,13 @@ BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer
{
BaseType_t xReturn = pdPASS;
FreeRTOS_Socket_t *pxSocket;
UDPPacket_t *pxUDPPacket;
UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
configASSERT( pxNetworkBuffer );
configASSERT( pxNetworkBuffer->pucEthernetBuffer );
pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
/* Caller must check for minimum packet size. */
pxSocket = pxUDPSocketLookup( usPort );

@ -42,9 +42,9 @@ extern "C" {
typedef struct xARP_CACHE_TABLE_ROW
{
uint32_t ulIPAddress; /* The IP address of an ARP cache entry. */
MACAddress_t xMACAddress; /* The MAC address of an ARP cache entry. */
MACAddress_t xMACAddress; /* The MAC address of an ARP cache entry. */
uint8_t ucAge; /* A value that is periodically decremented but can also be refreshed by active communication. The ARP cache entry is removed if the value reaches zero. */
uint8_t ucValid; /* pdTRUE: xMACAddress is valid, pdFALSE: waiting for ARP reply */
uint8_t ucValid; /* pdTRUE: xMACAddress is valid, pdFALSE: waiting for ARP reply */
} ARPCacheRow_t;
typedef enum

@ -84,8 +84,12 @@ uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer );
#if( ipconfigUSE_DNS_CACHE != 0 )
/* Look for the indicated host name in the DNS cache. Returns the IPv4
address if present, or 0x0 otherwise. */
uint32_t FreeRTOS_dnslookup( const char *pcHostName );
/* Remove all entries from the DNS cache. */
void FreeRTOS_dnsclear();
#endif /* ipconfigUSE_DNS_CACHE != 0 */
#if( ipconfigDNS_USE_CALLBACKS != 0 )

@ -41,6 +41,10 @@ extern "C" {
#include "FreeRTOS_TCP_IP.h"
#endif
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
#include "semphr.h"
#endif
#include "event_groups.h"
typedef struct xNetworkAddressingParameters
@ -577,7 +581,6 @@ BaseType_t xIPIsNetworkTaskReady( void );
FOnConnected_t pxHandleConnected; /* Actually type: typedef void (* FOnConnected_t) (Socket_t xSocket, BaseType_t ulConnected ); */
#endif /* ipconfigUSE_CALLBACKS */
uint32_t ulWindowSize; /* Current Window size advertised by peer */
uint32_t ulRxCurWinSize; /* Constantly changing: this is the current size available for data reception */
size_t uxRxWinSize; /* Fixed value: size of the TCP reception window */
size_t uxTxWinSize; /* Fixed value: size of the TCP transmit window */

@ -130,6 +130,7 @@ FreeRTOS_setsockopt(). */
#define FREERTOS_SO_WAKEUP_CALLBACK ( 17 )
#endif
#define FREERTOS_SO_SET_LOW_HIGH_WATER ( 18 )
#define FREERTOS_NOT_LAST_IN_FRAGMENTED_PACKET ( 0x80 ) /* For internal use only, but also part of an 8-bit bitwise value. */
#define FREERTOS_FRAGMENTED_PACKET ( 0x40 ) /* For internal use only, but also part of an 8-bit bitwise value. */
@ -155,6 +156,12 @@ typedef struct xWIN_PROPS {
int32_t lRxWinSize; /* Unit: MSS */
} WinProperties_t;
typedef struct xLOW_HIGH_WATER {
/* Structure to pass for the 'FREERTOS_SO_SET_LOW_HIGH_WATER' option */
size_t uxLittleSpace; /* Send a STOP when buffer space drops below X bytes */
size_t uxEnoughSpace; /* Send a GO when buffer space grows above X bytes */
} LowHighWater_t;
/* For compatibility with the expected Berkeley sockets naming. */
#define socklen_t uint32_t

@ -210,81 +210,84 @@ NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSi
NetworkBufferDescriptor_t *pxReturn = NULL;
size_t uxCount;
if( ( xRequestedSizeBytes != 0u ) && ( xRequestedSizeBytes < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
if( xNetworkBufferSemaphore != NULL )
{
/* ARP packets can replace application packets, so the storage must be
at least large enough to hold an ARP. */
xRequestedSizeBytes = baMINIMAL_BUFFER_SIZE;
}
/* Add 2 bytes to xRequestedSizeBytes and round up xRequestedSizeBytes
to the nearest multiple of N bytes, where N equals 'sizeof( size_t )'. */
xRequestedSizeBytes += 2u;
if( ( xRequestedSizeBytes & ( sizeof( size_t ) - 1u ) ) != 0u )
{
xRequestedSizeBytes = ( xRequestedSizeBytes | ( sizeof( size_t ) - 1u ) ) + 1u;
}
/* If there is a semaphore available, there is a network buffer available. */
if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
{
/* Protect the structure as it is accessed from tasks and interrupts. */
taskENTER_CRITICAL();
if( ( xRequestedSizeBytes != 0u ) && ( xRequestedSizeBytes < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
{
pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
uxListRemove( &( pxReturn->xBufferListItem ) );
/* ARP packets can replace application packets, so the storage must be
at least large enough to hold an ARP. */
xRequestedSizeBytes = baMINIMAL_BUFFER_SIZE;
}
taskEXIT_CRITICAL();
/* Reading UBaseType_t, no critical section needed. */
uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
if( uxMinimumFreeNetworkBuffers > uxCount )
/* Add 2 bytes to xRequestedSizeBytes and round up xRequestedSizeBytes
to the nearest multiple of N bytes, where N equals 'sizeof( size_t )'. */
xRequestedSizeBytes += 2u;
if( ( xRequestedSizeBytes & ( sizeof( size_t ) - 1u ) ) != 0u )
{
uxMinimumFreeNetworkBuffers = uxCount;
xRequestedSizeBytes = ( xRequestedSizeBytes | ( sizeof( size_t ) - 1u ) ) + 1u;
}
/* Allocate storage of exactly the requested size to the buffer. */
configASSERT( pxReturn->pucEthernetBuffer == NULL );
if( xRequestedSizeBytes > 0 )
/* If there is a semaphore available, there is a network buffer available. */
if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
{
/* Extra space is obtained so a pointer to the network buffer can
be stored at the beginning of the buffer. */
pxReturn->pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xRequestedSizeBytes + ipBUFFER_PADDING );
/* Protect the structure as it is accessed from tasks and interrupts. */
taskENTER_CRITICAL();
{
pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
uxListRemove( &( pxReturn->xBufferListItem ) );
}
taskEXIT_CRITICAL();
/* Reading UBaseType_t, no critical section needed. */
uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
if( pxReturn->pucEthernetBuffer == NULL )
if( uxMinimumFreeNetworkBuffers > uxCount )
{
/* The attempt to allocate storage for the buffer payload failed,
so the network buffer structure cannot be used and must be
released. */
vReleaseNetworkBufferAndDescriptor( pxReturn );
pxReturn = NULL;
uxMinimumFreeNetworkBuffers = uxCount;
}
else
/* Allocate storage of exactly the requested size to the buffer. */
configASSERT( pxReturn->pucEthernetBuffer == NULL );
if( xRequestedSizeBytes > 0 )
{
/* Store a pointer to the network buffer structure in the
buffer storage area, then move the buffer pointer on past the
stored pointer so the pointer value is not overwritten by the
application when the buffer is used. */
*( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer ) ) = pxReturn;
pxReturn->pucEthernetBuffer += ipBUFFER_PADDING;
/* Store the actual size of the allocated buffer, which may be
greater than the original requested size. */
pxReturn->xDataLength = xRequestedSizeBytes;
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
/* Extra space is obtained so a pointer to the network buffer can
be stored at the beginning of the buffer. */
pxReturn->pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xRequestedSizeBytes + ipBUFFER_PADDING );
if( pxReturn->pucEthernetBuffer == NULL )
{
/* The attempt to allocate storage for the buffer payload failed,
so the network buffer structure cannot be used and must be
released. */
vReleaseNetworkBufferAndDescriptor( pxReturn );
pxReturn = NULL;
}
else
{
/* make sure the buffer is not linked */
pxReturn->pxNextBuffer = NULL;
/* Store a pointer to the network buffer structure in the
buffer storage area, then move the buffer pointer on past the
stored pointer so the pointer value is not overwritten by the
application when the buffer is used. */
*( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer ) ) = pxReturn;
pxReturn->pucEthernetBuffer += ipBUFFER_PADDING;
/* Store the actual size of the allocated buffer, which may be
greater than the original requested size. */
pxReturn->xDataLength = xRequestedSizeBytes;
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
/* make sure the buffer is not linked */
pxReturn->pxNextBuffer = NULL;
}
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
}
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
}
}
else
{
/* A descriptor is being returned without an associated buffer being
allocated. */
else
{
/* A descriptor is being returned without an associated buffer being
allocated. */
}
}
}

@ -37,6 +37,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma unpack
#endif
#endif
#ifdef __RX
#ifdef __CCRX__
;
#pragma packoption
#endif
#endif

@ -36,6 +36,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma pack 1
#endif
#endif
#ifdef __RX
#ifdef __CCRX__
#pragma pack
#endif
#endif

@ -239,7 +239,7 @@ const TickType_t x5_Seconds = 5000UL;
configASSERT( xTXDescriptorSemaphore );
}
/* When returning non-zero, the stack will become active and
start DHCP (in configured) */
start DHCP (in configured) */
return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
}
/*-----------------------------------------------------------*/

@ -1,3 +1,28 @@
/*
* FreeRTOS+TCP V2.0.11
* Copyright (C) 2017 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
* 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.
*
* 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 AUTHORS OR
* COPYRIGHT HOLDERS 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.
*
* http://aws.amazon.com/freertos
* http://www.FreeRTOS.org
*/
/*
* Handling of Ethernet PHY's
* PHY's communicate with an EMAC either through
@ -24,8 +49,6 @@
#include "phyHandling.h"
#include "eventLogging.h"
#define phyMIN_PHY_ADDRESS 0
#define phyMAX_PHY_ADDRESS 31
@ -59,6 +82,7 @@
/* Bit fields for 'phyREG_00_BMCR', the 'Basic Mode Control Register'. */
#define phyBMCR_FULL_DUPLEX 0x0100u /* Full duplex. */
#define phyBMCR_AN_RESTART 0x0200u /* Auto negotiation restart. */
#define phyBMCR_ISOLATE 0x0400u /* 1 = Isolates 0 = Normal operation. */
#define phyBMCR_AN_ENABLE 0x1000u /* Enable auto negotiation. */
#define phyBMCR_SPEED_100 0x2000u /* Select 100Mbps. */
#define phyBMCR_RESET 0x8000u /* Reset the PHY. */
@ -114,6 +138,8 @@ BaseType_t xResult;
case PHY_ID_KSZ8051: // same ID as 8041
case PHY_ID_KSZ8081: // same ID as 8041
*/
case PHY_ID_KSZ8081MNXIA:
case PHY_ID_KSZ8863:
default:
/* Most PHY's have a 1F_PHYSPCS */
@ -192,7 +218,6 @@ BaseType_t xPhyAddress;
if( pxPhyObject->xPortCount > 0 )
{
FreeRTOS_printf( ( "PHY ID %lX\n", pxPhyObject->ulPhyIDs[ 0 ] ) );
eventLogAdd( "PHY ID 0x%lX", pxPhyObject->ulPhyIDs[ 0 ] );
}
return pxPhyObject->xPortCount;
@ -246,6 +271,8 @@ BaseType_t xPhyIndex;
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
break;
}
/* Block for a while */
vTaskDelay( pdMS_TO_TICKS( 50ul ) );
}
/* Clear the reset bits. */
@ -258,7 +285,7 @@ BaseType_t xPhyIndex;
}
vTaskDelay( pdMS_TO_TICKS( 50ul ) );
eventLogAdd( "PHY reset %d ports", (int)pxPhyObject->xPortCount );
return ulDoneMask;
}
/*-----------------------------------------------------------*/
@ -367,7 +394,7 @@ BaseType_t xPhyIndex;
ulConfig |= phyBMCR_AN_ENABLE;
if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_100 )
if( ( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_100 ) || ( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_AUTO ) )
{
ulConfig |= phyBMCR_SPEED_100;
}
@ -376,7 +403,7 @@ BaseType_t xPhyIndex;
ulConfig &= ~phyBMCR_SPEED_100;
}
if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )
if( ( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL ) || ( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_AUTO ) )
{
ulConfig |= phyBMCR_FULL_DUPLEX;
}
@ -413,11 +440,10 @@ BaseType_t xPhyIndex;
}
FreeRTOS_printf( ( "+TCP: advertise: %04lX config %04lX\n", ulAdvertise, ulConfig ) );
eventLogAdd( "adv: %04lX config %04lX", ulAdvertise, ulConfig );
}
/* Keep these values for later use. */
pxPhyObject->ulBCRValue = ulConfig;
pxPhyObject->ulBCRValue = ulConfig & ~phyBMCR_ISOLATE;
pxPhyObject->ulACRValue = ulAdvertise;
return 0;
@ -476,7 +502,6 @@ TimeOut_t xTimer;
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue | phyBMCR_AN_RESTART );
}
}
eventLogAdd( "AN start" );
xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( 3000UL );
vTaskSetTimeOutState( &xTimer );
ulDoneMask = 0;
@ -507,11 +532,10 @@ eventLogAdd( "AN start" );
if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )
{
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
eventLogAdd( "ANtimed out");
break;
}
vTaskDelay( pdMS_TO_TICKS( 50 ) );
}
eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
if( ulDoneMask != ( uint32_t)0u )
{
@ -541,7 +565,43 @@ eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
ulPHYLinkStatus &= ~( phyBMSR_LINK_STATUS );
}
if( xHas_1F_PHYSPCS( ulPhyID ) )
if( ulPhyID == PHY_ID_KSZ8081MNXIA )
{
uint32_t ulControlStatus;
pxPhyObject->fnPhyRead( xPhyAddress, 0x1E, &ulControlStatus);
switch( ulControlStatus & 0x07 )
{
case 0x01:
case 0x05:
// [001] = 10BASE-T half-duplex
// [101] = 10BASE-T full-duplex
/* 10 Mbps. */
ulRegValue |= phyPHYSTS_SPEED_STATUS;
break;
case 0x02:
case 0x06:
// [010] = 100BASE-TX half-duplex
// [110] = 100BASE-TX full-duplex
break;
}
switch( ulControlStatus & 0x07 )
{
case 0x05:
case 0x06:
// [101] = 10BASE-T full-duplex
// [110] = 100BASE-TX full-duplex
/* Full duplex. */
ulRegValue |= phyPHYSTS_DUPLEX_STATUS;
break;
case 0x01:
case 0x02:
// [001] = 10BASE-T half-duplex
// [010] = 100BASE-TX half-duplex
break;
}
}
else if( xHas_1F_PHYSPCS( ulPhyID ) )
{
/* 31 RW PHY Special Control Status */
uint32_t ulControlStatus;
@ -556,7 +616,6 @@ eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
{
ulRegValue |= phyPHYSTS_SPEED_STATUS;
}
}
else
{
@ -569,25 +628,6 @@ eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",
( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,
( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0) ? "high" : "low" ) );
eventLogAdd( "%s duplex %u mbit %s st",
( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",
( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,
( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0) ? "high" : "low" );
{
uint32_t regs[4];
int i,j;
int address = 0x10;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
pxPhyObject->fnPhyRead( xPhyAddress, address, regs + j );
address++;
}
eventLogAdd("%04lX %04lX %04lX %04lX",
regs[0], regs[1], regs[2], regs[3]);
}
}
if( ( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) != ( uint32_t )0u )
{
pxPhyObject->xPhyProperties.ucDuplex = PHY_DUPLEX_FULL;
@ -624,6 +664,15 @@ BaseType_t xNeedCheck = pdFALSE;
but set a timer to check it later on. */
vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );
pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_HIGH_CHECK_TIME_MS );
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
{
if( ( pxPhyObject->ulLinkStatusMask & ulBitMask ) == 0ul )
{
pxPhyObject->ulLinkStatusMask |= ulBitMask;
FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );
xNeedCheck = pdTRUE;
}
}
}
else if( xTaskCheckForTimeOut( &( pxPhyObject->xLinkStatusTimer ), &( pxPhyObject->xLinkStatusRemaining ) ) != pdFALSE )
{
@ -644,7 +693,6 @@ BaseType_t xNeedCheck = pdFALSE;
pxPhyObject->ulLinkStatusMask &= ~( ulBitMask );
}
FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );
eventLogAdd( "PHY LS now %02lX", pxPhyObject->ulLinkStatusMask );
xNeedCheck = pdTRUE;
}
}

@ -451,7 +451,6 @@ BaseType_t xResult;
/* For now pdFAIL will be returned. But prvEMACHandlerTask() is running
and it will keep on checking the PHY and set 'ulLinkStatusMask' when necessary. */
xResult = pdFAIL;
FreeRTOS_printf( ( "Link Status still low\n" ) ) ;
}
/* When returning non-zero, the stack will become active and
start DHCP (in configured) */
@ -593,14 +592,6 @@ const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
/* Open a do {} while ( 0 ) loop to be able to call break. */
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( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
{
ProtocolPacket_t *pxPacket;

@ -0,0 +1,20 @@
This is a FreeeRTOS+TCP driver that works for both STM32F4xx and STM32F7xx parts.
The code of stm32fxx_hal_eth.c is based on both drivers as provided by ST.
These modules should be included:
NetworkInterface.c
stm32fxx_hal_eth.c
It is assumed that one of these words are defined:
STM32F7xx
STM32F407xx
STM32F417xx
STM32F427xx
STM32F437xx
STM32F429xx
STM32F439xx
The driver has been tested on both Eval and Discovery boards with both STM32F4 and STM32F7.

@ -0,0 +1,6 @@
/*
* The Ethernet header files for STM32F2, STM32F4 and STM32F7 have been merged to
* a single module that works for both parts: "stm32fxx_hal_eth"
*/
#include "stm32fxx_hal_eth.h"

@ -0,0 +1,6 @@
/*
* The Ethernet header files for STM32F2, STM32F4 and STM32F7 have been merged to
* a single module that works for both parts: "stm32fxx_hal_eth"
*/
#include "stm32fxx_hal_eth.h"

@ -115,7 +115,7 @@ static void *pvSendEvent = NULL;
/* _HT_ made the PCAP interface number configurable through the program's
parameters in order to test in different machines. */
static BaseType_t xConfigNextworkInterfaceToUse = configNETWORK_INTERFACE_TO_USE;
static BaseType_t xConfigNetworkInterfaceToUse = configNETWORK_INTERFACE_TO_USE;
/* Handles to the Windows threads that handle the PCAP IO. */
static HANDLE vWinPcapRecvThreadHandle = NULL;
@ -274,9 +274,9 @@ static BaseType_t xInvalidInterfaceDetected = pdFALSE;
printf( "\r\nThe interface that will be opened is set by " );
printf( "\"configNETWORK_INTERFACE_TO_USE\", which\r\nshould be defined in FreeRTOSConfig.h\r\n" );
if( ( xConfigNextworkInterfaceToUse < 0L ) || ( xConfigNextworkInterfaceToUse >= lInterfaceNumber ) )
if( ( xConfigNetworkInterfaceToUse < 1L ) || ( xConfigNetworkInterfaceToUse >= lInterfaceNumber ) )
{
printf( "\r\nERROR: configNETWORK_INTERFACE_TO_USE is set to %d, which is an invalid value.\r\n", xConfigNextworkInterfaceToUse );
printf( "\r\nERROR: configNETWORK_INTERFACE_TO_USE is set to %d, which is an invalid value.\r\n", xConfigNetworkInterfaceToUse );
printf( "Please set configNETWORK_INTERFACE_TO_USE to one of the interface numbers listed above,\r\n" );
printf( "then re-compile and re-start the application. Only Ethernet (as opposed to WiFi)\r\n" );
printf( "interfaces are supported.\r\n\r\nHALTING\r\n\r\n\r\n" );
@ -291,7 +291,7 @@ static BaseType_t xInvalidInterfaceDetected = pdFALSE;
}
else
{
printf( "Attempting to open interface number %d.\n", xConfigNextworkInterfaceToUse );
printf( "Attempting to open interface number %d.\n", xConfigNetworkInterfaceToUse );
}
}
@ -339,26 +339,24 @@ static char pucInterfaceName[ 256 ];
static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces )
{
pcap_if_t *xInterface;
pcap_if_t *pxInterface;
int32_t x;
/* Walk the list of devices until the selected device is located. */
xInterface = pxAllNetworkInterfaces;
if (0 == xConfigNextworkInterfaceToUse) {
while (NULL != xInterface) {
xInterface = xInterface->next;
if (0 == prvOpenInterface(xInterface->name)) {
break;
}
}
pxInterface = pxAllNetworkInterfaces;
for( x = 0L; x < ( xConfigNetworkInterfaceToUse - 1L ); x++ )
{
pxInterface = pxInterface->next;
}
else {
for (x = 1L; x < xConfigNextworkInterfaceToUse; x++)
{
xInterface = xInterface->next;
}
/* Open the selected interface. */
(void) prvOpenInterface(xInterface->name);
/* Open the selected interface. */
if( prvOpenInterface( pxInterface->name ) == 0 )
{
printf( "Successfully opened interface number %d.\n", x + 1 );
}
else
{
printf( "Failed to open interface number %d.\n", x + 1 );
}
/* The device list is no longer required. */
@ -389,7 +387,8 @@ uint32_t ulNetMask;
{
printf( "\nAn error occurred setting the packet filter.\n" );
}
/* When pcap_compile() succeeds, it allocates memory for the memory pointed to by the bpf_program struct
parameter.pcap_freecode() will free that memory. */
pcap_freecode( &xFilterCode );
}
@ -526,15 +525,15 @@ eFrameProcessingResult_t eResult;
iptraceNETWORK_INTERFACE_RECEIVE();
/* Check for minimal size. */
if( pxHeader->len >= sizeof( EthernetHeader_t ) )
{
eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
}
else
{
eResult = eReleaseBuffer;
}
/* Check for minimal size. */
if( pxHeader->len >= sizeof( EthernetHeader_t ) )
{
eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
}
else
{
eResult = eReleaseBuffer;
}
if( eResult == eProcessBuffer )
{
@ -633,4 +632,3 @@ static const char *prvRemoveSpaces( char *pcBuffer, int aBuflen, const char *pcM
return pcBuffer;
}

@ -1,26 +1,26 @@
/*
FreeRTOS+TCP V2.0.11
Copyright (C) 2017 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
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.
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 AUTHORS OR
COPYRIGHT HOLDERS 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.
http://aws.amazon.com/freertos
http://www.FreeRTOS.org
* FreeRTOS+TCP V2.0.11
* Copyright (C) 2017 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
* 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.
*
* 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 AUTHORS OR
* COPYRIGHT HOLDERS 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.
*
* http://aws.amazon.com/freertos
* http://www.FreeRTOS.org
*/
/* Standard includes. */
@ -38,7 +38,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
#include "FreeRTOS_ARP.h"
#include "NetworkBufferManagement.h"
#include "NetworkInterface.h"
@ -56,7 +55,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#endif
#define niBMSR_LINK_STATUS 0x0004UL
#define niBMSR_AN_COMPLETE 0x0020u /* Auto-Negotiation process completed */
#ifndef PHY_LS_HIGH_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
@ -210,13 +208,6 @@ const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pd
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )
{
if( xCheckLoopback( pxBuffer, bReleaseAfterSend ) != 0 )
{
/* The packet has been sent back to the IP-task.
The IP-task will further handle it.
Do not release the descriptor. */
return pdTRUE;
}
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
{
ProtocolPacket_t *pxPacket;
@ -396,6 +387,7 @@ UBaseType_t uxCurrentBufferCount = 0;
xEMACpsif.isr_events &= ~EMAC_IF_ERR_EVENT;
emacps_check_errors( &xEMACpsif );
}
if( xResult > 0 )
{
/* A packet was received. No need to check for the PHY status now,

@ -35,7 +35,6 @@ extern "C" {
#include "xil_exception.h"
#include "xpseudo_asm.h"
#include "xil_cache.h"
#include "xil_printf.h"
#include "xuartps.h"
#include "xscugic.h"
#include "xemacps.h" /* defines XEmacPs API */

@ -1,26 +1,26 @@
/*
FreeRTOS+TCP V2.0.11
Copyright (C) 2017 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
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.
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 AUTHORS OR
COPYRIGHT HOLDERS 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.
http://aws.amazon.com/freertos
http://www.FreeRTOS.org
* FreeRTOS+TCP V2.0.11
* Copyright (C) 2017 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
* 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.
*
* 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 AUTHORS OR
* COPYRIGHT HOLDERS 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.
*
* http://aws.amazon.com/freertos
* http://www.FreeRTOS.org
*/
#include "FreeRTOS.h"
@ -119,7 +119,6 @@ size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount
break;
}
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
#warning ipconfigZERO_COPY_TX_DRIVER is defined
{
void *pvBuffer = pxDMA_tx_buffers[ tail ];
NetworkBufferDescriptor_t *pxBuffer;
@ -201,7 +200,6 @@ BaseType_t xReturn;
XStatus emacps_send_message(xemacpsif_s *xemacpsif, NetworkBufferDescriptor_t *pxBuffer, int iReleaseAfterSend )
{
int head = xemacpsif->txHead;
//int tail = xemacpsif->txTail;
int iHasSent = 0;
uint32_t ulBaseAddress = xemacpsif->emacps.Config.BaseAddress;
TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
@ -291,6 +289,8 @@ TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
/* Start transmit */
xemacpsif->txBusy = pdTRUE;
XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) );
/* Reading it back is important compiler is optimised. */
XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET );
}
dsb();
@ -313,72 +313,51 @@ void emacps_recv_handler(void *arg)
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
static void passEthMessages( NetworkBufferDescriptor_t *ethMsg )
static void prvPassEthMessages( NetworkBufferDescriptor_t *pxDescriptor )
{
IPStackEvent_t xRxEvent;
xRxEvent.eEventType = eNetworkRxEvent;
xRxEvent.pvData = ( void * ) ethMsg;
xRxEvent.pvData = ( void * ) 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 taskr, not a real interrupt, so it is ok to
use the task level function here. */
do
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
NetworkBufferDescriptor_t *xNext = ethMsg->pxNextBuffer;
vReleaseNetworkBufferAndDescriptor( ethMsg );
ethMsg = xNext;
} while( ethMsg != NULL );
do
{
NetworkBufferDescriptor_t *pxNext = pxDescriptor->pxNextBuffer;
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
pxDescriptor = pxNext;
} while( pxDescriptor != NULL );
}
#else
{
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
}
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
iptraceETHERNET_RX_EVENT_LOST();
FreeRTOS_printf( ( "passEthMessages: Can not queue return packet!\n" ) );
FreeRTOS_printf( ( "prvPassEthMessages: Can not queue return packet!\n" ) );
}
}
TickType_t ack_reception_delay = 10;
int emacps_check_rx( xemacpsif_s *xemacpsif )
{
NetworkBufferDescriptor_t *pxBuffer, *pxNewBuffer;
int rx_bytes;
volatile int msgCount = 0;
int head = xemacpsif->rxHead;
BaseType_t bHasDataPacket = pdFALSE;
NetworkBufferDescriptor_t *ethMsg = NULL;
NetworkBufferDescriptor_t *ethLast = NULL;
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
NetworkBufferDescriptor_t *pxFirstDescriptor = NULL;
NetworkBufferDescriptor_t *pxLastDescriptor = NULL;
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
/* There seems to be an issue (SI# 692601), see comments below. */
resetrx_on_no_rxdata(xemacpsif);
{
static int maxcount = 0;
int count = 0;
for( ;; )
{
if( ( ( xemacpsif->rxSegments[ head ].address & XEMACPS_RXBUF_NEW_MASK ) == 0 ) ||
( pxDMA_rx_buffers[ head ] == NULL ) )
{
break;
}
count++;
if( ++head == ipconfigNIC_N_RX_DESC )
{
head = 0;
}
if( head == xemacpsif->rxHead )
{
break;
}
}
if (maxcount < count) {
maxcount = count;
FreeRTOS_printf( ( "emacps_check_rx: %d packets\n", maxcount ) );
}
head = xemacpsif->rxHead;
}
/* 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. */
@ -411,10 +390,6 @@ NetworkBufferDescriptor_t *ethLast = NULL;
rx_bytes = xemacpsif->rxSegments[ head ].flags & XEMACPS_RXBUF_LEN_MASK;
pxBuffer->xDataLength = rx_bytes;
if( rx_bytes > 60 )
{
bHasDataPacket = 1;
}
if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
{
Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)rx_bytes );
@ -423,20 +398,29 @@ if( rx_bytes > 60 )
/* store it in the receive queue, where it'll be processed by a
different handler. */
iptraceNETWORK_INTERFACE_RECEIVE();
pxBuffer->pxNextBuffer = NULL;
if( ethMsg == NULL )
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
// Becomes the first message
ethMsg = pxBuffer;
pxBuffer->pxNextBuffer = NULL;
if( pxFirstDescriptor == NULL )
{
// Becomes the first message
pxFirstDescriptor = pxBuffer;
}
else if( pxLastDescriptor != NULL )
{
// Add to the tail
pxLastDescriptor->pxNextBuffer = pxBuffer;
}
pxLastDescriptor = pxBuffer;
}
else if( ethLast != NULL )
#else
{
// Add to the tail
ethLast->pxNextBuffer = pxBuffer;
prvPassEthMessages( pxBuffer );
}
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
ethLast = pxBuffer;
msgCount++;
}
{
@ -453,7 +437,8 @@ if( rx_bytes > 60 )
/* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */
xemacpsif->rxSegments[ head ].flags = 0;
xemacpsif->rxSegments[ head ].address = addr;
if (xemacpsif->rxSegments[ head ].address) {
if (xemacpsif->rxSegments[ head ].address)
{
// Just to read it
}
}
@ -466,14 +451,14 @@ if( rx_bytes > 60 )
xemacpsif->rxHead = head;
}
if( ethMsg != NULL )
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
if( bHasDataPacket == pdFALSE )
if( pxFirstDescriptor != NULL )
{
// vTaskDelay( ack_reception_delay );
prvPassEthMessages( pxFirstDescriptor );
}
passEthMessages( ethMsg );
}
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
return msgCount;
}
@ -638,7 +623,6 @@ void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif)
tempcntr = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXCNT_OFFSET );
if ( ( tempcntr == 0 ) && ( xemacpsif->last_rx_frms_cntr == 0 ) )
{
FreeRTOS_printf( ( "resetrx_on_no_rxdata: RESET~\n" ) );
regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
XEMACPS_NWCTRL_OFFSET);
regctrl &= (~XEMACPS_NWCTRL_RXEN_MASK);

@ -214,8 +214,6 @@ static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
}
}
extern XEmacPs_Config mac_config;
void HandleTxErrors(xemacpsif_s *xemacpsif)
{
u32 netctrlreg;

@ -234,8 +234,8 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
return 10;
xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\n",
__FUNCTION__);
FreeRTOS_printf( ( "%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\n",
__FUNCTION__ ) );
return 10;
} else {
@ -253,8 +253,8 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
case (IEEE_CTRL_LINKSPEED_10M):
return 10;
default:
xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\n",
__FUNCTION__, phylinkspeed);
FreeRTOS_printf( ( "%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\n",
__FUNCTION__, phylinkspeed ) );
return 10;
}
@ -278,7 +278,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
#else
u32 phy_addr = detect_phy(xemacpsp);
#endif
xil_printf("Start PHY autonegotiation \n");
FreeRTOS_printf( ( "Start PHY autonegotiation \n" ) );
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
@ -334,24 +334,24 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
break;
}
#endif
xil_printf("Waiting for PHY to complete autonegotiation.\n");
FreeRTOS_printf( ( "Waiting for PHY to complete autonegotiation.\n" ) );
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
sleep(1);
vTaskDelay(1);
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
&temp);
if (temp & IEEE_AUTONEG_ERROR_MASK) {
xil_printf("Auto negotiation error \n");
FreeRTOS_printf( ( "Auto negotiation error \n" ) );
}
#endif
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
&status);
}
xil_printf("autonegotiation complete \n");
FreeRTOS_printf( ( "autonegotiation complete \n" ) );
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
@ -359,7 +359,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
#endif
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
xil_printf("Waiting for Link to be up; Polling for SGMII core Reg \n");
FreeRTOS_printf( ( "Waiting for Link to be up; Polling for SGMII core Reg \n" ) );
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
while(!(temp & 0x8000)) {
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
@ -376,7 +376,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
return 10;
} else {
xil_printf("get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\n");
FreeRTOS_printf( ( "get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\n" ) );
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
return 10;
@ -556,26 +556,26 @@ unsigned Phy_Setup (XEmacPs *xemacpsp)
link_speed = 1000;
configure_IEEE_phy_speed(xemacpsp, link_speed);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
sleep(1);
vTaskDelay(1);
#elif defined(ipconfigNIC_LINKSPEED100)
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
link_speed = 100;
configure_IEEE_phy_speed(xemacpsp, link_speed);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
sleep(1);
vTaskDelay(1);
#elif defined(ipconfigNIC_LINKSPEED10)
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
link_speed = 10;
configure_IEEE_phy_speed(xemacpsp, link_speed);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
sleep(1);
vTaskDelay(1);
#endif
if (conv_present) {
XEmacPs_PhyWrite(xemacpsp, convphyaddr,
XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
}
xil_printf("link speed: %d\n", link_speed);
FreeRTOS_printf( ( "link speed: %d\n", link_speed ) );
return link_speed;
}

@ -1,3 +1,28 @@
/*
* FreeRTOS+TCP V2.0.11
* Copyright (C) 2017 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
* 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.
*
* 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 AUTHORS OR
* COPYRIGHT HOLDERS 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.
*
* http://aws.amazon.com/freertos
* http://www.FreeRTOS.org
*/
/*
* Handling of Ethernet PHY's
* PHY's communicate with an EMAC either through
@ -82,6 +107,7 @@ typedef struct xEthernetPhy
#define PHY_ID_KSZ8081 0x000010A1
#define PHY_ID_KSZ8863 0x00221430
#define PHY_ID_KSZ8081MNXIA 0x00221560
#define PHY_ID_DP83848I 0x20005C90

Loading…
Cancel
Save