mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 21:41:59 -04:00
Update TCP/IP tack to latest form Git.
This commit is contained in:
parent
a6a0403fd6
commit
2e18203bb7
|
@ -108,11 +108,6 @@ are located. */
|
||||||
located. */
|
located. */
|
||||||
#define dhcpFIRST_OPTION_BYTE_OFFSET ( 0xf0 )
|
#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. */
|
/* Standard DHCP port numbers and magic cookie value. */
|
||||||
#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
|
#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
|
||||||
#define dhcpCLIENT_PORT 0x4400u
|
#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
|
/* Walk through the options until the dhcpOPTION_END_BYTE byte
|
||||||
is found, taking care not to walk off the end of the options. */
|
is found, taking care not to walk off the end of the options. */
|
||||||
pucByte = &( pxDHCPMessage->ucFirstOptionByte );
|
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 ];
|
ucOptionCode = pucByte[ 0 ];
|
||||||
if( ucOptionCode == dhcpOPTION_END_BYTE )
|
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. */
|
/* Stop if the response is malformed. */
|
||||||
if( pucByte < pucLastByte - 1 )
|
if( pucByte < pucLastByte )
|
||||||
{
|
{
|
||||||
|
/* There are at least two bytes left. */
|
||||||
ucLength = pucByte[ 1 ];
|
ucLength = pucByte[ 1 ];
|
||||||
pucByte += 2;
|
pucByte += 2;
|
||||||
|
|
||||||
if( pucByte >= pucLastByte - ucLength )
|
if( pucByte + ucLength > pucLastByte )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -926,7 +924,8 @@ size_t xOptionsLength = sizeof( ucDHCPRequestOptions );
|
||||||
FreeRTOS_debug_printf( ( "vDHCPProcess: reply %lxip\n", FreeRTOS_ntohl( xDHCPData.ulOfferedIPAddress ) ) );
|
FreeRTOS_debug_printf( ( "vDHCPProcess: reply %lxip\n", FreeRTOS_ntohl( xDHCPData.ulOfferedIPAddress ) ) );
|
||||||
iptraceSENDING_DHCP_REQUEST();
|
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
|
/* The packet was not successfully queued for sending and must be
|
||||||
returned to the stack. */
|
returned to the stack. */
|
||||||
|
@ -954,7 +953,8 @@ size_t xOptionsLength = sizeof( ucDHCPDiscoverOptions );
|
||||||
FreeRTOS_debug_printf( ( "vDHCPProcess: discover\n" ) );
|
FreeRTOS_debug_printf( ( "vDHCPProcess: discover\n" ) );
|
||||||
iptraceSENDING_DHCP_DISCOVER();
|
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
|
/* The packet was not successfully queued for sending and must be
|
||||||
returned to the stack. */
|
returned to the stack. */
|
||||||
|
|
|
@ -151,6 +151,11 @@ static uint32_t prvGetHostByName( const char *pcHostName, TickType_t xIdentifier
|
||||||
} DNSCacheRow_t;
|
} DNSCacheRow_t;
|
||||||
|
|
||||||
static DNSCacheRow_t xDNSCache[ ipconfigDNS_CACHE_ENTRIES ];
|
static DNSCacheRow_t xDNSCache[ ipconfigDNS_CACHE_ENTRIES ];
|
||||||
|
|
||||||
|
void FreeRTOS_dnsclear()
|
||||||
|
{
|
||||||
|
memset( xDNSCache, 0x0, sizeof( xDNSCache ) );
|
||||||
|
}
|
||||||
#endif /* ipconfigUSE_DNS_CACHE == 1 */
|
#endif /* ipconfigUSE_DNS_CACHE == 1 */
|
||||||
|
|
||||||
#if( ipconfigUSE_LLMNR == 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 )
|
uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||||
{
|
{
|
||||||
uint8_t *pucUDPPayloadBuffer;
|
|
||||||
size_t xPlayloadBufferLength;
|
|
||||||
DNSMessage_t *pxDNSMessageHeader;
|
DNSMessage_t *pxDNSMessageHeader;
|
||||||
|
|
||||||
xPlayloadBufferLength = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
|
if( pxNetworkBuffer->xDataLength >= sizeof( DNSMessage_t ) )
|
||||||
if ( xPlayloadBufferLength < sizeof( DNSMessage_t ) )
|
|
||||||
{
|
{
|
||||||
return pdFAIL;
|
pxDNSMessageHeader =
|
||||||
}
|
( DNSMessage_t * )( pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t ) );
|
||||||
|
|
||||||
pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
|
prvParseDNSReply( ( uint8_t * )pxDNSMessageHeader,
|
||||||
pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
|
pxNetworkBuffer->xDataLength,
|
||||||
|
( uint32_t )pxDNSMessageHeader->usIdentifier );
|
||||||
if( pxNetworkBuffer->xDataLength > sizeof( UDPPacket_t ) )
|
|
||||||
{
|
|
||||||
prvParseDNSReply( pucUDPPayloadBuffer,
|
|
||||||
xPlayloadBufferLength,
|
|
||||||
( uint32_t )pxDNSMessageHeader->usIdentifier );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The packet was not consumed. */
|
/* The packet was not consumed. */
|
||||||
|
@ -841,12 +838,11 @@ DNSMessage_t *pxDNSMessageHeader;
|
||||||
UDPPacket_t *pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
|
UDPPacket_t *pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
|
||||||
uint8_t *pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
|
uint8_t *pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
|
||||||
|
|
||||||
if( pxNetworkBuffer->xDataLength > sizeof( UDPPacket_t) )
|
/* The network buffer data length has already been set to the
|
||||||
{
|
length of the UDP payload. */
|
||||||
prvTreatNBNS( pucUDPPayloadBuffer,
|
prvTreatNBNS( pucUDPPayloadBuffer,
|
||||||
pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t ),
|
pxNetworkBuffer->xDataLength,
|
||||||
pxUDPPacket->xIPHeader.ulSourceIPAddress );
|
pxUDPPacket->xIPHeader.ulSourceIPAddress );
|
||||||
}
|
|
||||||
|
|
||||||
/* The packet was not consumed. */
|
/* The packet was not consumed. */
|
||||||
return pdFAIL;
|
return pdFAIL;
|
||||||
|
@ -1312,6 +1308,9 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
|
||||||
pxUDPHeader->usLength = FreeRTOS_htons( lNetLength + ipSIZE_OF_UDP_HEADER );
|
pxUDPHeader->usLength = FreeRTOS_htons( lNetLength + ipSIZE_OF_UDP_HEADER );
|
||||||
vFlip_16( pxUDPPacket->xUDPHeader.usSourcePort, pxUDPPacket->xUDPHeader.usDestinationPort );
|
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 )
|
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
|
||||||
{
|
{
|
||||||
/* calculate the IP header checksum */
|
/* calculate the IP header checksum */
|
||||||
|
@ -1320,13 +1319,10 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
|
||||||
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
|
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
|
||||||
|
|
||||||
/* calculate the UDP checksum for outgoing package */
|
/* calculate the UDP checksum for outgoing package */
|
||||||
usGenerateProtocolChecksum( ( uint8_t* ) pxUDPPacket, lNetLength, pdTRUE );
|
usGenerateProtocolChecksum( ( uint8_t* ) pxUDPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
|
||||||
}
|
}
|
||||||
#endif
|
#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 */
|
/* This function will fill in the eth addresses and send the packet */
|
||||||
vReturnEthernetFrame( pxNetworkBuffer, pdFALSE );
|
vReturnEthernetFrame( pxNetworkBuffer, pdFALSE );
|
||||||
}
|
}
|
||||||
|
@ -1342,13 +1338,15 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
|
||||||
BaseType_t xFound = pdFALSE;
|
BaseType_t xFound = pdFALSE;
|
||||||
uint32_t ulCurrentTimeSeconds = ( xTaskGetTickCount() / portTICK_PERIOD_MS ) / 1000;
|
uint32_t ulCurrentTimeSeconds = ( xTaskGetTickCount() / portTICK_PERIOD_MS ) / 1000;
|
||||||
static BaseType_t xFreeEntry = 0;
|
static BaseType_t xFreeEntry = 0;
|
||||||
|
configASSERT(pcName);
|
||||||
|
|
||||||
|
|
||||||
/* For each entry in the DNS cache table. */
|
/* For each entry in the DNS cache table. */
|
||||||
for( x = 0; x < ipconfigDNS_CACHE_ENTRIES; x++ )
|
for( x = 0; x < ipconfigDNS_CACHE_ENTRIES; x++ )
|
||||||
{
|
{
|
||||||
if( xDNSCache[ x ].pcName[ 0 ] == 0 )
|
if( xDNSCache[ x ].pcName[ 0 ] == 0 )
|
||||||
{
|
{
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( 0 == strcmp( xDNSCache[ x ].pcName, pcName ) )
|
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. */
|
/* Provide access to private members for testing. */
|
||||||
#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
|
#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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1824,7 +1824,7 @@ uint8_t ucProtocol;
|
||||||
{
|
{
|
||||||
return ipINVALID_LENGTH;
|
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;
|
return ipINVALID_LENGTH;
|
||||||
}
|
}
|
||||||
|
@ -2316,3 +2316,9 @@ BaseType_t FreeRTOS_IsNetworkUp( void )
|
||||||
}
|
}
|
||||||
#endif
|
#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_UDP_PORT_NUMBER_INDEX 0
|
||||||
#define socketNEXT_TCP_PORT_NUMBER_INDEX 1
|
#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;
|
break;
|
||||||
#endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */
|
#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_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) */
|
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 );
|
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 )
|
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||||
{
|
{
|
||||||
pxSocket->u.xTCP.uxRxWinSize = ( uint32_t )pxProps->lRxWinSize; /* Fixed value: size of the TCP reception window */
|
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;
|
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;
|
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. */
|
'*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 *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;
|
FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
|
||||||
StreamBuffer_t *pxBuffer = pxSocket->u.xTCP.txStream;
|
StreamBuffer_t *pxBuffer = NULL;
|
||||||
|
|
||||||
if( pxBuffer != NULL )
|
*pxLength = 0;
|
||||||
{
|
|
||||||
BaseType_t xSpace = ( BaseType_t ) uxStreamBufferGetSpace( pxBuffer );
|
|
||||||
BaseType_t xRemain = ( BaseType_t ) ( pxBuffer->LENGTH - pxBuffer->uxHead );
|
|
||||||
|
|
||||||
*pxLength = FreeRTOS_min_BaseType( xSpace, xRemain );
|
/* Confirm that this is a TCP socket before dereferencing structure
|
||||||
pucReturn = pxBuffer->ucArray + pxBuffer->uxHead;
|
member pointers. */
|
||||||
}
|
if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )
|
||||||
else
|
|
||||||
{
|
{
|
||||||
*pxLength = 0;
|
pxBuffer = pxSocket->u.xTCP.txStream;
|
||||||
pucReturn = NULL;
|
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;
|
return pucReturn;
|
||||||
|
@ -2862,9 +2906,17 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
|
||||||
|
|
||||||
const struct xSTREAM_BUFFER *FreeRTOS_get_rx_buf( Socket_t xSocket )
|
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;
|
||||||
|
|
||||||
return pxSocket->u.xTCP.rxStream;
|
/* 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 pxReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* ipconfigUSE_TCP */
|
#endif /* ipconfigUSE_TCP */
|
||||||
|
@ -2886,12 +2938,12 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
|
||||||
|
|
||||||
if( pxSocket->u.xTCP.uxLittleSpace == 0ul )
|
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 )
|
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
|
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 );
|
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.
|
* 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. */
|
/* 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 ) )
|
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. */
|
/* Set the values of usInitMSS / usCurMSS for this socket. */
|
||||||
prvSocketSetMSS( pxSocket );
|
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
|
/* The initial sequence numbers at our side are known. Later
|
||||||
vTCPWindowInit() will be called to fill in the peer's sequence numbers, but
|
vTCPWindowInit() will be called to fill in the peer's sequence numbers, but
|
||||||
first wait for a SYN+ACK reply. */
|
first wait for a SYN+ACK reply. */
|
||||||
|
@ -2521,7 +2532,6 @@ TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetB
|
||||||
TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
|
TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
|
||||||
TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
|
TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
|
||||||
/* Find out what window size we may advertised. */
|
/* Find out what window size we may advertised. */
|
||||||
uint32_t ulFrontSpace;
|
|
||||||
int32_t lRxSpace;
|
int32_t lRxSpace;
|
||||||
#if( ipconfigUSE_TCP_WIN == 1 )
|
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||||
#if( ipconfigTCP_ACK_EARLIER_PACKET == 0 )
|
#if( ipconfigTCP_ACK_EARLIER_PACKET == 0 )
|
||||||
|
@ -2530,20 +2540,6 @@ int32_t lRxSpace;
|
||||||
int32_t lMinLength;
|
int32_t lMinLength;
|
||||||
#endif
|
#endif
|
||||||
#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
|
/* Set the time-out field, so that we'll be called by the IP-task in case no
|
||||||
next message will be received. */
|
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 );
|
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. */
|
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;
|
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. */
|
/* Remove compiler warnings if ipconfigIGNORE_UNKNOWN_PACKETS == 1. */
|
||||||
( void ) pxNetworkBuffer;
|
( void )pxNetworkBuffer;
|
||||||
|
( void )ucTCPFlags;
|
||||||
|
|
||||||
/* The packet was not consumed. */
|
/* The packet was not consumed. */
|
||||||
return pdFAIL;
|
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 )
|
static void prvSocketSetMSS( FreeRTOS_Socket_t *pxSocket )
|
||||||
{
|
{
|
||||||
uint32_t ulMSS = ipconfigTCP_MSS;
|
uint32_t ulMSS = ipconfigTCP_MSS;
|
||||||
|
@ -2899,8 +2911,13 @@ uint32_t ulLocalIP;
|
||||||
uint16_t xLocalPort;
|
uint16_t xLocalPort;
|
||||||
uint32_t ulRemoteIP;
|
uint32_t ulRemoteIP;
|
||||||
uint16_t xRemotePort;
|
uint16_t xRemotePort;
|
||||||
|
uint32_t ulSequenceNumber;
|
||||||
|
uint32_t ulAckNumber;
|
||||||
BaseType_t xResult = pdPASS;
|
BaseType_t xResult = pdPASS;
|
||||||
|
|
||||||
|
configASSERT( pxNetworkBuffer );
|
||||||
|
configASSERT( pxNetworkBuffer->pucEthernetBuffer );
|
||||||
|
|
||||||
/* Check for a minimum packet size. */
|
/* Check for a minimum packet size. */
|
||||||
if( pxNetworkBuffer->xDataLength >= ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) )
|
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 );
|
xLocalPort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usDestinationPort );
|
||||||
ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
|
ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
|
||||||
xRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
|
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
|
/* Find the destination socket, and if not found: return a socket listing to
|
||||||
the destination PORT. */
|
the destination PORT. */
|
||||||
|
@ -2988,13 +3007,36 @@ BaseType_t xResult = pdPASS;
|
||||||
flag. */
|
flag. */
|
||||||
if( ( ucTCPFlags & ipTCP_FLAG_RST ) != 0u )
|
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 ) );
|
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;
|
xResult = pdFAIL;
|
||||||
}
|
}
|
||||||
else if( ( ( ucTCPFlags & ipTCP_FLAG_CTRL ) == ipTCP_FLAG_SYN ) && ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) )
|
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. */
|
/* Provide access to private members for testing. */
|
||||||
#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
|
#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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -292,7 +292,7 @@ void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem
|
||||||
pxWhere->pxPrevious = pxNewListItem;
|
pxWhere->pxPrevious = pxNewListItem;
|
||||||
|
|
||||||
/* Remember which list the item is in. */
|
/* 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 )++;
|
( pxList->uxNumberOfItems )++;
|
||||||
}
|
}
|
||||||
|
@ -675,17 +675,17 @@ const int32_t l500ms = 500;
|
||||||
|
|
||||||
#if( ipconfigUSE_TCP_WIN == 1 )
|
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||||
|
|
||||||
void vTCPSegmentCleanup( void )
|
void vTCPSegmentCleanup( void )
|
||||||
{
|
{
|
||||||
/* Free and clear the TCP segments pointer. This function should only be called
|
/* 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
|
* once FreeRTOS+TCP will no longer be used. No thread-safety is provided for this
|
||||||
* function. */
|
* function. */
|
||||||
if( xTCPSegments != NULL )
|
if( xTCPSegments != NULL )
|
||||||
{
|
{
|
||||||
vPortFreeLarge( xTCPSegments );
|
vPortFreeLarge( xTCPSegments );
|
||||||
xTCPSegments = NULL;
|
xTCPSegments = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* ipconfgiUSE_TCP_WIN == 1 */
|
#endif /* ipconfgiUSE_TCP_WIN == 1 */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -805,20 +805,20 @@ const int32_t l500ms = 500;
|
||||||
{
|
{
|
||||||
ulSavedSequenceNumber = ulCurrentSequenceNumber;
|
ulSavedSequenceNumber = ulCurrentSequenceNumber;
|
||||||
|
|
||||||
/* Clean up all sequence received between ulSequenceNumber and ulSequenceNumber + ulLength since they are duplicated.
|
/* 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.
|
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
|
So we cannot rely on the packets between ulSequenceNumber and ulSequenceNumber + ulLength to be sequential and it is better to just
|
||||||
clean them out. */
|
clean them out. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
|
pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
|
||||||
|
|
||||||
if ( pxFound != NULL )
|
if ( pxFound != NULL )
|
||||||
{
|
{
|
||||||
/* Remove it because it will be passed to user directly. */
|
/* Remove it because it will be passed to user directly. */
|
||||||
vTCPWindowFree( pxFound );
|
vTCPWindowFree( pxFound );
|
||||||
}
|
}
|
||||||
} while ( pxFound );
|
} while ( pxFound );
|
||||||
|
|
||||||
/* Check for following segments that are already in the
|
/* Check for following segments that are already in the
|
||||||
queue and increment ulCurrentSequenceNumber. */
|
queue and increment ulCurrentSequenceNumber. */
|
||||||
|
|
|
@ -240,8 +240,12 @@ BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer
|
||||||
{
|
{
|
||||||
BaseType_t xReturn = pdPASS;
|
BaseType_t xReturn = pdPASS;
|
||||||
FreeRTOS_Socket_t *pxSocket;
|
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. */
|
/* Caller must check for minimum packet size. */
|
||||||
pxSocket = pxUDPSocketLookup( usPort );
|
pxSocket = pxUDPSocketLookup( usPort );
|
||||||
|
|
|
@ -42,9 +42,9 @@ extern "C" {
|
||||||
typedef struct xARP_CACHE_TABLE_ROW
|
typedef struct xARP_CACHE_TABLE_ROW
|
||||||
{
|
{
|
||||||
uint32_t ulIPAddress; /* The IP address of an ARP cache entry. */
|
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 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;
|
} ARPCacheRow_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
|
@ -84,8 +84,12 @@ uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer );
|
||||||
|
|
||||||
#if( ipconfigUSE_DNS_CACHE != 0 )
|
#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 );
|
uint32_t FreeRTOS_dnslookup( const char *pcHostName );
|
||||||
|
|
||||||
|
/* Remove all entries from the DNS cache. */
|
||||||
|
void FreeRTOS_dnsclear();
|
||||||
#endif /* ipconfigUSE_DNS_CACHE != 0 */
|
#endif /* ipconfigUSE_DNS_CACHE != 0 */
|
||||||
|
|
||||||
#if( ipconfigDNS_USE_CALLBACKS != 0 )
|
#if( ipconfigDNS_USE_CALLBACKS != 0 )
|
||||||
|
|
|
@ -41,6 +41,10 @@ extern "C" {
|
||||||
#include "FreeRTOS_TCP_IP.h"
|
#include "FreeRTOS_TCP_IP.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
|
||||||
|
#include "semphr.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "event_groups.h"
|
#include "event_groups.h"
|
||||||
|
|
||||||
typedef struct xNetworkAddressingParameters
|
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 ); */
|
FOnConnected_t pxHandleConnected; /* Actually type: typedef void (* FOnConnected_t) (Socket_t xSocket, BaseType_t ulConnected ); */
|
||||||
#endif /* ipconfigUSE_CALLBACKS */
|
#endif /* ipconfigUSE_CALLBACKS */
|
||||||
uint32_t ulWindowSize; /* Current Window size advertised by peer */
|
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 uxRxWinSize; /* Fixed value: size of the TCP reception window */
|
||||||
size_t uxTxWinSize; /* Fixed value: size of the TCP transmit window */
|
size_t uxTxWinSize; /* Fixed value: size of the TCP transmit window */
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,7 @@ FreeRTOS_setsockopt(). */
|
||||||
#define FREERTOS_SO_WAKEUP_CALLBACK ( 17 )
|
#define FREERTOS_SO_WAKEUP_CALLBACK ( 17 )
|
||||||
#endif
|
#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_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. */
|
#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 */
|
int32_t lRxWinSize; /* Unit: MSS */
|
||||||
} WinProperties_t;
|
} 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. */
|
/* For compatibility with the expected Berkeley sockets naming. */
|
||||||
#define socklen_t uint32_t
|
#define socklen_t uint32_t
|
||||||
|
|
||||||
|
|
|
@ -210,82 +210,85 @@ NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSi
|
||||||
NetworkBufferDescriptor_t *pxReturn = NULL;
|
NetworkBufferDescriptor_t *pxReturn = NULL;
|
||||||
size_t uxCount;
|
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
|
if( ( xRequestedSizeBytes != 0u ) && ( xRequestedSizeBytes < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
|
||||||
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();
|
|
||||||
{
|
{
|
||||||
pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
|
/* ARP packets can replace application packets, so the storage must be
|
||||||
uxListRemove( &( pxReturn->xBufferListItem ) );
|
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 )
|
|
||||||
{
|
|
||||||
uxMinimumFreeNetworkBuffers = uxCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate storage of exactly the requested size to the buffer. */
|
/* Add 2 bytes to xRequestedSizeBytes and round up xRequestedSizeBytes
|
||||||
configASSERT( pxReturn->pucEthernetBuffer == NULL );
|
to the nearest multiple of N bytes, where N equals 'sizeof( size_t )'. */
|
||||||
if( xRequestedSizeBytes > 0 )
|
xRequestedSizeBytes += 2u;
|
||||||
|
if( ( xRequestedSizeBytes & ( sizeof( size_t ) - 1u ) ) != 0u )
|
||||||
{
|
{
|
||||||
/* Extra space is obtained so a pointer to the network buffer can
|
xRequestedSizeBytes = ( xRequestedSizeBytes | ( sizeof( size_t ) - 1u ) ) + 1u;
|
||||||
be stored at the beginning of the buffer. */
|
}
|
||||||
pxReturn->pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xRequestedSizeBytes + ipBUFFER_PADDING );
|
|
||||||
|
|
||||||
if( pxReturn->pucEthernetBuffer == NULL )
|
/* 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();
|
||||||
{
|
{
|
||||||
/* The attempt to allocate storage for the buffer payload failed,
|
pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
|
||||||
so the network buffer structure cannot be used and must be
|
uxListRemove( &( pxReturn->xBufferListItem ) );
|
||||||
released. */
|
}
|
||||||
vReleaseNetworkBufferAndDescriptor( pxReturn );
|
taskEXIT_CRITICAL();
|
||||||
pxReturn = NULL;
|
|
||||||
|
/* Reading UBaseType_t, no critical section needed. */
|
||||||
|
uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
|
||||||
|
|
||||||
|
if( uxMinimumFreeNetworkBuffers > uxCount )
|
||||||
|
{
|
||||||
|
uxMinimumFreeNetworkBuffers = uxCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate storage of exactly the requested size to the buffer. */
|
||||||
|
configASSERT( pxReturn->pucEthernetBuffer == NULL );
|
||||||
|
if( xRequestedSizeBytes > 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
|
||||||
|
{
|
||||||
|
/* 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 */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Store a pointer to the network buffer structure in the
|
/* A descriptor is being returned without an associated buffer being
|
||||||
buffer storage area, then move the buffer pointer on past the
|
allocated. */
|
||||||
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 */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* A descriptor is being returned without an associated buffer being
|
|
||||||
allocated. */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pxReturn == NULL )
|
if( pxReturn == NULL )
|
||||||
|
|
|
@ -37,6 +37,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#pragma unpack
|
#pragma unpack
|
||||||
#endif
|
#endif
|
||||||
#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
|
#pragma pack 1
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __RX
|
||||||
|
#ifdef __CCRX__
|
||||||
|
#pragma pack
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -239,7 +239,7 @@ const TickType_t x5_Seconds = 5000UL;
|
||||||
configASSERT( xTXDescriptorSemaphore );
|
configASSERT( xTXDescriptorSemaphore );
|
||||||
}
|
}
|
||||||
/* When returning non-zero, the stack will become active and
|
/* When returning non-zero, the stack will become active and
|
||||||
start DHCP (in configured) */
|
start DHCP (in configured) */
|
||||||
return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
|
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
|
* Handling of Ethernet PHY's
|
||||||
* PHY's communicate with an EMAC either through
|
* PHY's communicate with an EMAC either through
|
||||||
|
@ -24,8 +49,6 @@
|
||||||
|
|
||||||
#include "phyHandling.h"
|
#include "phyHandling.h"
|
||||||
|
|
||||||
#include "eventLogging.h"
|
|
||||||
|
|
||||||
#define phyMIN_PHY_ADDRESS 0
|
#define phyMIN_PHY_ADDRESS 0
|
||||||
#define phyMAX_PHY_ADDRESS 31
|
#define phyMAX_PHY_ADDRESS 31
|
||||||
|
|
||||||
|
@ -59,6 +82,7 @@
|
||||||
/* Bit fields for 'phyREG_00_BMCR', the 'Basic Mode Control Register'. */
|
/* Bit fields for 'phyREG_00_BMCR', the 'Basic Mode Control Register'. */
|
||||||
#define phyBMCR_FULL_DUPLEX 0x0100u /* Full duplex. */
|
#define phyBMCR_FULL_DUPLEX 0x0100u /* Full duplex. */
|
||||||
#define phyBMCR_AN_RESTART 0x0200u /* Auto negotiation restart. */
|
#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_AN_ENABLE 0x1000u /* Enable auto negotiation. */
|
||||||
#define phyBMCR_SPEED_100 0x2000u /* Select 100Mbps. */
|
#define phyBMCR_SPEED_100 0x2000u /* Select 100Mbps. */
|
||||||
#define phyBMCR_RESET 0x8000u /* Reset the PHY. */
|
#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_KSZ8051: // same ID as 8041
|
||||||
case PHY_ID_KSZ8081: // same ID as 8041
|
case PHY_ID_KSZ8081: // same ID as 8041
|
||||||
*/
|
*/
|
||||||
|
case PHY_ID_KSZ8081MNXIA:
|
||||||
|
|
||||||
case PHY_ID_KSZ8863:
|
case PHY_ID_KSZ8863:
|
||||||
default:
|
default:
|
||||||
/* Most PHY's have a 1F_PHYSPCS */
|
/* Most PHY's have a 1F_PHYSPCS */
|
||||||
|
@ -192,7 +218,6 @@ BaseType_t xPhyAddress;
|
||||||
if( pxPhyObject->xPortCount > 0 )
|
if( pxPhyObject->xPortCount > 0 )
|
||||||
{
|
{
|
||||||
FreeRTOS_printf( ( "PHY ID %lX\n", pxPhyObject->ulPhyIDs[ 0 ] ) );
|
FreeRTOS_printf( ( "PHY ID %lX\n", pxPhyObject->ulPhyIDs[ 0 ] ) );
|
||||||
eventLogAdd( "PHY ID 0x%lX", pxPhyObject->ulPhyIDs[ 0 ] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pxPhyObject->xPortCount;
|
return pxPhyObject->xPortCount;
|
||||||
|
@ -246,6 +271,8 @@ BaseType_t xPhyIndex;
|
||||||
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
|
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* Block for a while */
|
||||||
|
vTaskDelay( pdMS_TO_TICKS( 50ul ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the reset bits. */
|
/* Clear the reset bits. */
|
||||||
|
@ -258,7 +285,7 @@ BaseType_t xPhyIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
vTaskDelay( pdMS_TO_TICKS( 50ul ) );
|
vTaskDelay( pdMS_TO_TICKS( 50ul ) );
|
||||||
eventLogAdd( "PHY reset %d ports", (int)pxPhyObject->xPortCount );
|
|
||||||
return ulDoneMask;
|
return ulDoneMask;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -367,7 +394,7 @@ BaseType_t xPhyIndex;
|
||||||
|
|
||||||
ulConfig |= phyBMCR_AN_ENABLE;
|
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;
|
ulConfig |= phyBMCR_SPEED_100;
|
||||||
}
|
}
|
||||||
|
@ -376,7 +403,7 @@ BaseType_t xPhyIndex;
|
||||||
ulConfig &= ~phyBMCR_SPEED_100;
|
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;
|
ulConfig |= phyBMCR_FULL_DUPLEX;
|
||||||
}
|
}
|
||||||
|
@ -413,11 +440,10 @@ BaseType_t xPhyIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeRTOS_printf( ( "+TCP: advertise: %04lX config %04lX\n", ulAdvertise, ulConfig ) );
|
FreeRTOS_printf( ( "+TCP: advertise: %04lX config %04lX\n", ulAdvertise, ulConfig ) );
|
||||||
eventLogAdd( "adv: %04lX config %04lX", ulAdvertise, ulConfig );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep these values for later use. */
|
/* Keep these values for later use. */
|
||||||
pxPhyObject->ulBCRValue = ulConfig;
|
pxPhyObject->ulBCRValue = ulConfig & ~phyBMCR_ISOLATE;
|
||||||
pxPhyObject->ulACRValue = ulAdvertise;
|
pxPhyObject->ulACRValue = ulAdvertise;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -476,7 +502,6 @@ TimeOut_t xTimer;
|
||||||
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue | phyBMCR_AN_RESTART );
|
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue | phyBMCR_AN_RESTART );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eventLogAdd( "AN start" );
|
|
||||||
xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( 3000UL );
|
xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( 3000UL );
|
||||||
vTaskSetTimeOutState( &xTimer );
|
vTaskSetTimeOutState( &xTimer );
|
||||||
ulDoneMask = 0;
|
ulDoneMask = 0;
|
||||||
|
@ -507,11 +532,10 @@ eventLogAdd( "AN start" );
|
||||||
if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )
|
if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )
|
||||||
{
|
{
|
||||||
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
|
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
|
||||||
eventLogAdd( "ANtimed out");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
vTaskDelay( pdMS_TO_TICKS( 50 ) );
|
||||||
}
|
}
|
||||||
eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
|
|
||||||
|
|
||||||
if( ulDoneMask != ( uint32_t)0u )
|
if( ulDoneMask != ( uint32_t)0u )
|
||||||
{
|
{
|
||||||
|
@ -541,7 +565,43 @@ eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
|
||||||
ulPHYLinkStatus &= ~( phyBMSR_LINK_STATUS );
|
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 */
|
/* 31 RW PHY Special Control Status */
|
||||||
uint32_t ulControlStatus;
|
uint32_t ulControlStatus;
|
||||||
|
@ -556,7 +616,6 @@ eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
|
||||||
{
|
{
|
||||||
ulRegValue |= phyPHYSTS_SPEED_STATUS;
|
ulRegValue |= phyPHYSTS_SPEED_STATUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -569,25 +628,6 @@ eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
|
||||||
( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",
|
( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",
|
||||||
( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,
|
( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,
|
||||||
( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0) ? "high" : "low" ) );
|
( ( 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 )
|
if( ( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) != ( uint32_t )0u )
|
||||||
{
|
{
|
||||||
pxPhyObject->xPhyProperties.ucDuplex = PHY_DUPLEX_FULL;
|
pxPhyObject->xPhyProperties.ucDuplex = PHY_DUPLEX_FULL;
|
||||||
|
@ -624,6 +664,15 @@ BaseType_t xNeedCheck = pdFALSE;
|
||||||
but set a timer to check it later on. */
|
but set a timer to check it later on. */
|
||||||
vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );
|
vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );
|
||||||
pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_HIGH_CHECK_TIME_MS );
|
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 )
|
else if( xTaskCheckForTimeOut( &( pxPhyObject->xLinkStatusTimer ), &( pxPhyObject->xLinkStatusRemaining ) ) != pdFALSE )
|
||||||
{
|
{
|
||||||
|
@ -644,7 +693,6 @@ BaseType_t xNeedCheck = pdFALSE;
|
||||||
pxPhyObject->ulLinkStatusMask &= ~( ulBitMask );
|
pxPhyObject->ulLinkStatusMask &= ~( ulBitMask );
|
||||||
}
|
}
|
||||||
FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );
|
FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );
|
||||||
eventLogAdd( "PHY LS now %02lX", pxPhyObject->ulLinkStatusMask );
|
|
||||||
xNeedCheck = pdTRUE;
|
xNeedCheck = pdTRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -451,7 +451,6 @@ BaseType_t xResult;
|
||||||
/* For now pdFAIL will be returned. But prvEMACHandlerTask() is running
|
/* For now pdFAIL will be returned. But prvEMACHandlerTask() is running
|
||||||
and it will keep on checking the PHY and set 'ulLinkStatusMask' when necessary. */
|
and it will keep on checking the PHY and set 'ulLinkStatusMask' when necessary. */
|
||||||
xResult = pdFAIL;
|
xResult = pdFAIL;
|
||||||
FreeRTOS_printf( ( "Link Status still low\n" ) ) ;
|
|
||||||
}
|
}
|
||||||
/* When returning non-zero, the stack will become active and
|
/* When returning non-zero, the stack will become active and
|
||||||
start DHCP (in configured) */
|
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. */
|
/* Open a do {} while ( 0 ) loop to be able to call break. */
|
||||||
do
|
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 )
|
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
|
||||||
{
|
{
|
||||||
ProtocolPacket_t *pxPacket;
|
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"
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -115,7 +115,7 @@ static void *pvSendEvent = NULL;
|
||||||
|
|
||||||
/* _HT_ made the PCAP interface number configurable through the program's
|
/* _HT_ made the PCAP interface number configurable through the program's
|
||||||
parameters in order to test in different machines. */
|
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. */
|
/* Handles to the Windows threads that handle the PCAP IO. */
|
||||||
static HANDLE vWinPcapRecvThreadHandle = NULL;
|
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( "\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" );
|
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( "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( "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" );
|
printf( "interfaces are supported.\r\n\r\nHALTING\r\n\r\n\r\n" );
|
||||||
|
@ -291,7 +291,7 @@ static BaseType_t xInvalidInterfaceDetected = pdFALSE;
|
||||||
}
|
}
|
||||||
else
|
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 )
|
static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces )
|
||||||
{
|
{
|
||||||
pcap_if_t *xInterface;
|
pcap_if_t *pxInterface;
|
||||||
int32_t x;
|
int32_t x;
|
||||||
|
|
||||||
/* Walk the list of devices until the selected device is located. */
|
/* Walk the list of devices until the selected device is located. */
|
||||||
xInterface = pxAllNetworkInterfaces;
|
pxInterface = pxAllNetworkInterfaces;
|
||||||
if (0 == xConfigNextworkInterfaceToUse) {
|
for( x = 0L; x < ( xConfigNetworkInterfaceToUse - 1L ); x++ )
|
||||||
while (NULL != xInterface) {
|
{
|
||||||
xInterface = xInterface->next;
|
pxInterface = pxInterface->next;
|
||||||
if (0 == prvOpenInterface(xInterface->name)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
for (x = 1L; x < xConfigNextworkInterfaceToUse; x++)
|
/* Open the selected interface. */
|
||||||
{
|
if( prvOpenInterface( pxInterface->name ) == 0 )
|
||||||
xInterface = xInterface->next;
|
{
|
||||||
}
|
printf( "Successfully opened interface number %d.\n", x + 1 );
|
||||||
/* Open the selected interface. */
|
}
|
||||||
(void) prvOpenInterface(xInterface->name);
|
else
|
||||||
|
{
|
||||||
|
printf( "Failed to open interface number %d.\n", x + 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The device list is no longer required. */
|
/* The device list is no longer required. */
|
||||||
|
@ -389,7 +387,8 @@ uint32_t ulNetMask;
|
||||||
{
|
{
|
||||||
printf( "\nAn error occurred setting the packet filter.\n" );
|
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 );
|
pcap_freecode( &xFilterCode );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,15 +525,15 @@ eFrameProcessingResult_t eResult;
|
||||||
|
|
||||||
iptraceNETWORK_INTERFACE_RECEIVE();
|
iptraceNETWORK_INTERFACE_RECEIVE();
|
||||||
|
|
||||||
/* Check for minimal size. */
|
/* Check for minimal size. */
|
||||||
if( pxHeader->len >= sizeof( EthernetHeader_t ) )
|
if( pxHeader->len >= sizeof( EthernetHeader_t ) )
|
||||||
{
|
{
|
||||||
eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
|
eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eResult = eReleaseBuffer;
|
eResult = eReleaseBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( eResult == eProcessBuffer )
|
if( eResult == eProcessBuffer )
|
||||||
{
|
{
|
||||||
|
@ -633,4 +632,3 @@ static const char *prvRemoveSpaces( char *pcBuffer, int aBuflen, const char *pcM
|
||||||
|
|
||||||
return pcBuffer;
|
return pcBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS+TCP V2.0.11
|
* FreeRTOS+TCP V2.0.11
|
||||||
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* 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
|
* 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
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
the Software without restriction, including without limitation the rights to
|
* the Software without restriction, including without limitation the rights to
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
* 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,
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
subject to the following conditions:
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
The above copyright notice and this permission notice shall be included in all
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
* 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
|
* 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
|
* 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.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
http://aws.amazon.com/freertos
|
* http://aws.amazon.com/freertos
|
||||||
http://www.FreeRTOS.org
|
* http://www.FreeRTOS.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Standard includes. */
|
/* 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_IP.h"
|
||||||
#include "FreeRTOS_Sockets.h"
|
#include "FreeRTOS_Sockets.h"
|
||||||
#include "FreeRTOS_IP_Private.h"
|
#include "FreeRTOS_IP_Private.h"
|
||||||
#include "FreeRTOS_ARP.h"
|
|
||||||
#include "NetworkBufferManagement.h"
|
#include "NetworkBufferManagement.h"
|
||||||
#include "NetworkInterface.h"
|
#include "NetworkInterface.h"
|
||||||
|
|
||||||
|
@ -56,7 +55,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define niBMSR_LINK_STATUS 0x0004UL
|
#define niBMSR_LINK_STATUS 0x0004UL
|
||||||
#define niBMSR_AN_COMPLETE 0x0020u /* Auto-Negotiation process completed */
|
|
||||||
|
|
||||||
#ifndef PHY_LS_HIGH_CHECK_TIME_MS
|
#ifndef PHY_LS_HIGH_CHECK_TIME_MS
|
||||||
/* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
|
/* 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 )
|
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 )
|
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
|
||||||
{
|
{
|
||||||
ProtocolPacket_t *pxPacket;
|
ProtocolPacket_t *pxPacket;
|
||||||
|
@ -396,6 +387,7 @@ UBaseType_t uxCurrentBufferCount = 0;
|
||||||
xEMACpsif.isr_events &= ~EMAC_IF_ERR_EVENT;
|
xEMACpsif.isr_events &= ~EMAC_IF_ERR_EVENT;
|
||||||
emacps_check_errors( &xEMACpsif );
|
emacps_check_errors( &xEMACpsif );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( xResult > 0 )
|
if( xResult > 0 )
|
||||||
{
|
{
|
||||||
/* A packet was received. No need to check for the PHY status now,
|
/* A packet was received. No need to check for the PHY status now,
|
||||||
|
|
|
@ -35,7 +35,6 @@ extern "C" {
|
||||||
#include "xil_exception.h"
|
#include "xil_exception.h"
|
||||||
#include "xpseudo_asm.h"
|
#include "xpseudo_asm.h"
|
||||||
#include "xil_cache.h"
|
#include "xil_cache.h"
|
||||||
#include "xil_printf.h"
|
|
||||||
#include "xuartps.h"
|
#include "xuartps.h"
|
||||||
#include "xscugic.h"
|
#include "xscugic.h"
|
||||||
#include "xemacps.h" /* defines XEmacPs API */
|
#include "xemacps.h" /* defines XEmacPs API */
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
/*
|
/*
|
||||||
FreeRTOS+TCP V2.0.11
|
* FreeRTOS+TCP V2.0.11
|
||||||
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* 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
|
* 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
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
the Software without restriction, including without limitation the rights to
|
* the Software without restriction, including without limitation the rights to
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
* 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,
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
subject to the following conditions:
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
The above copyright notice and this permission notice shall be included in all
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
* 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
|
* 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
|
* 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.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
http://aws.amazon.com/freertos
|
* http://aws.amazon.com/freertos
|
||||||
http://www.FreeRTOS.org
|
* http://www.FreeRTOS.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
@ -119,7 +119,6 @@ size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
|
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
|
||||||
#warning ipconfigZERO_COPY_TX_DRIVER is defined
|
|
||||||
{
|
{
|
||||||
void *pvBuffer = pxDMA_tx_buffers[ tail ];
|
void *pvBuffer = pxDMA_tx_buffers[ tail ];
|
||||||
NetworkBufferDescriptor_t *pxBuffer;
|
NetworkBufferDescriptor_t *pxBuffer;
|
||||||
|
@ -201,7 +200,6 @@ BaseType_t xReturn;
|
||||||
XStatus emacps_send_message(xemacpsif_s *xemacpsif, NetworkBufferDescriptor_t *pxBuffer, int iReleaseAfterSend )
|
XStatus emacps_send_message(xemacpsif_s *xemacpsif, NetworkBufferDescriptor_t *pxBuffer, int iReleaseAfterSend )
|
||||||
{
|
{
|
||||||
int head = xemacpsif->txHead;
|
int head = xemacpsif->txHead;
|
||||||
//int tail = xemacpsif->txTail;
|
|
||||||
int iHasSent = 0;
|
int iHasSent = 0;
|
||||||
uint32_t ulBaseAddress = xemacpsif->emacps.Config.BaseAddress;
|
uint32_t ulBaseAddress = xemacpsif->emacps.Config.BaseAddress;
|
||||||
TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
|
TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
|
||||||
|
@ -291,6 +289,8 @@ TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
|
||||||
/* Start transmit */
|
/* Start transmit */
|
||||||
xemacpsif->txBusy = pdTRUE;
|
xemacpsif->txBusy = pdTRUE;
|
||||||
XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) );
|
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();
|
dsb();
|
||||||
|
|
||||||
|
@ -313,72 +313,51 @@ void emacps_recv_handler(void *arg)
|
||||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void passEthMessages( NetworkBufferDescriptor_t *ethMsg )
|
static void prvPassEthMessages( NetworkBufferDescriptor_t *pxDescriptor )
|
||||||
{
|
{
|
||||||
IPStackEvent_t xRxEvent;
|
IPStackEvent_t xRxEvent;
|
||||||
|
|
||||||
xRxEvent.eEventType = eNetworkRxEvent;
|
xRxEvent.eEventType = eNetworkRxEvent;
|
||||||
xRxEvent.pvData = ( void * ) ethMsg;
|
xRxEvent.pvData = ( void * ) pxDescriptor;
|
||||||
|
|
||||||
if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 1000 ) != pdPASS )
|
if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 1000 ) != pdPASS )
|
||||||
{
|
{
|
||||||
/* The buffer could not be sent to the stack so must be released again.
|
/* 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
|
This is a deferred handler taskr, not a real interrupt, so it is ok to
|
||||||
use the task level function here. */
|
use the task level function here. */
|
||||||
do
|
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||||
{
|
{
|
||||||
NetworkBufferDescriptor_t *xNext = ethMsg->pxNextBuffer;
|
do
|
||||||
vReleaseNetworkBufferAndDescriptor( ethMsg );
|
{
|
||||||
ethMsg = xNext;
|
NetworkBufferDescriptor_t *pxNext = pxDescriptor->pxNextBuffer;
|
||||||
} while( ethMsg != NULL );
|
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
|
||||||
|
pxDescriptor = pxNext;
|
||||||
|
} while( pxDescriptor != NULL );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
|
||||||
|
}
|
||||||
|
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
|
||||||
iptraceETHERNET_RX_EVENT_LOST();
|
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 )
|
int emacps_check_rx( xemacpsif_s *xemacpsif )
|
||||||
{
|
{
|
||||||
NetworkBufferDescriptor_t *pxBuffer, *pxNewBuffer;
|
NetworkBufferDescriptor_t *pxBuffer, *pxNewBuffer;
|
||||||
int rx_bytes;
|
int rx_bytes;
|
||||||
volatile int msgCount = 0;
|
volatile int msgCount = 0;
|
||||||
int head = xemacpsif->rxHead;
|
int head = xemacpsif->rxHead;
|
||||||
BaseType_t bHasDataPacket = pdFALSE;
|
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||||
NetworkBufferDescriptor_t *ethMsg = NULL;
|
NetworkBufferDescriptor_t *pxFirstDescriptor = NULL;
|
||||||
NetworkBufferDescriptor_t *ethLast = NULL;
|
NetworkBufferDescriptor_t *pxLastDescriptor = NULL;
|
||||||
|
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
|
||||||
|
|
||||||
/* There seems to be an issue (SI# 692601), see comments below. */
|
/* There seems to be an issue (SI# 692601), see comments below. */
|
||||||
resetrx_on_no_rxdata(xemacpsif);
|
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
|
/* This FreeRTOS+TCP driver shall be compiled with the option
|
||||||
"ipconfigUSE_LINKED_RX_MESSAGES" enabled. It allows the driver to send a
|
"ipconfigUSE_LINKED_RX_MESSAGES" enabled. It allows the driver to send a
|
||||||
chain of RX messages within one message to the IP-task. */
|
chain of RX messages within one message to the IP-task. */
|
||||||
|
@ -411,10 +390,6 @@ NetworkBufferDescriptor_t *ethLast = NULL;
|
||||||
rx_bytes = xemacpsif->rxSegments[ head ].flags & XEMACPS_RXBUF_LEN_MASK;
|
rx_bytes = xemacpsif->rxSegments[ head ].flags & XEMACPS_RXBUF_LEN_MASK;
|
||||||
|
|
||||||
pxBuffer->xDataLength = rx_bytes;
|
pxBuffer->xDataLength = rx_bytes;
|
||||||
if( rx_bytes > 60 )
|
|
||||||
{
|
|
||||||
bHasDataPacket = 1;
|
|
||||||
}
|
|
||||||
if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
|
if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
|
||||||
{
|
{
|
||||||
Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)rx_bytes );
|
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
|
/* store it in the receive queue, where it'll be processed by a
|
||||||
different handler. */
|
different handler. */
|
||||||
iptraceNETWORK_INTERFACE_RECEIVE();
|
iptraceNETWORK_INTERFACE_RECEIVE();
|
||||||
pxBuffer->pxNextBuffer = NULL;
|
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||||
|
|
||||||
if( ethMsg == NULL )
|
|
||||||
{
|
{
|
||||||
// Becomes the first message
|
pxBuffer->pxNextBuffer = NULL;
|
||||||
ethMsg = pxBuffer;
|
|
||||||
}
|
if( pxFirstDescriptor == NULL )
|
||||||
else if( ethLast != NULL )
|
{
|
||||||
{
|
// Becomes the first message
|
||||||
// Add to the tail
|
pxFirstDescriptor = pxBuffer;
|
||||||
ethLast->pxNextBuffer = pxBuffer;
|
}
|
||||||
}
|
else if( pxLastDescriptor != NULL )
|
||||||
|
{
|
||||||
|
// Add to the tail
|
||||||
|
pxLastDescriptor->pxNextBuffer = pxBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
pxLastDescriptor = pxBuffer;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
prvPassEthMessages( pxBuffer );
|
||||||
|
}
|
||||||
|
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
|
||||||
|
|
||||||
ethLast = pxBuffer;
|
|
||||||
msgCount++;
|
msgCount++;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -453,7 +437,8 @@ if( rx_bytes > 60 )
|
||||||
/* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */
|
/* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */
|
||||||
xemacpsif->rxSegments[ head ].flags = 0;
|
xemacpsif->rxSegments[ head ].flags = 0;
|
||||||
xemacpsif->rxSegments[ head ].address = addr;
|
xemacpsif->rxSegments[ head ].address = addr;
|
||||||
if (xemacpsif->rxSegments[ head ].address) {
|
if (xemacpsif->rxSegments[ head ].address)
|
||||||
|
{
|
||||||
// Just to read it
|
// Just to read it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,14 +451,14 @@ if( rx_bytes > 60 )
|
||||||
xemacpsif->rxHead = head;
|
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;
|
return msgCount;
|
||||||
}
|
}
|
||||||
|
@ -638,7 +623,6 @@ void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif)
|
||||||
tempcntr = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXCNT_OFFSET );
|
tempcntr = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXCNT_OFFSET );
|
||||||
if ( ( tempcntr == 0 ) && ( xemacpsif->last_rx_frms_cntr == 0 ) )
|
if ( ( tempcntr == 0 ) && ( xemacpsif->last_rx_frms_cntr == 0 ) )
|
||||||
{
|
{
|
||||||
FreeRTOS_printf( ( "resetrx_on_no_rxdata: RESET~\n" ) );
|
|
||||||
regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||||
XEMACPS_NWCTRL_OFFSET);
|
XEMACPS_NWCTRL_OFFSET);
|
||||||
regctrl &= (~XEMACPS_NWCTRL_RXEN_MASK);
|
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)
|
void HandleTxErrors(xemacpsif_s *xemacpsif)
|
||||||
{
|
{
|
||||||
u32 netctrlreg;
|
u32 netctrlreg;
|
||||||
|
|
|
@ -234,8 +234,8 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
||||||
if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
|
if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
|
||||||
return 10;
|
return 10;
|
||||||
|
|
||||||
xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\n",
|
FreeRTOS_printf( ( "%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\n",
|
||||||
__FUNCTION__);
|
__FUNCTION__ ) );
|
||||||
return 10;
|
return 10;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -253,8 +253,8 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
||||||
case (IEEE_CTRL_LINKSPEED_10M):
|
case (IEEE_CTRL_LINKSPEED_10M):
|
||||||
return 10;
|
return 10;
|
||||||
default:
|
default:
|
||||||
xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\n",
|
FreeRTOS_printf( ( "%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\n",
|
||||||
__FUNCTION__, phylinkspeed);
|
__FUNCTION__, phylinkspeed ) );
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
||||||
#else
|
#else
|
||||||
u32 phy_addr = detect_phy(xemacpsp);
|
u32 phy_addr = detect_phy(xemacpsp);
|
||||||
#endif
|
#endif
|
||||||
xil_printf("Start PHY autonegotiation \n");
|
FreeRTOS_printf( ( "Start PHY autonegotiation \n" ) );
|
||||||
|
|
||||||
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
||||||
#else
|
#else
|
||||||
|
@ -334,24 +334,24 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||||
while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
|
while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
|
||||||
sleep(1);
|
vTaskDelay(1);
|
||||||
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
||||||
#else
|
#else
|
||||||
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
|
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
|
||||||
&temp);
|
&temp);
|
||||||
if (temp & IEEE_AUTONEG_ERROR_MASK) {
|
if (temp & IEEE_AUTONEG_ERROR_MASK) {
|
||||||
xil_printf("Auto negotiation error \n");
|
FreeRTOS_printf( ( "Auto negotiation error \n" ) );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
|
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
|
||||||
&status);
|
&status);
|
||||||
}
|
}
|
||||||
|
|
||||||
xil_printf("autonegotiation complete \n");
|
FreeRTOS_printf( ( "autonegotiation complete \n" ) );
|
||||||
|
|
||||||
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
||||||
#else
|
#else
|
||||||
|
@ -359,7 +359,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
#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);
|
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
|
||||||
while(!(temp & 0x8000)) {
|
while(!(temp & 0x8000)) {
|
||||||
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
|
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);
|
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
|
||||||
return 10;
|
return 10;
|
||||||
} else {
|
} 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_PhyRead(xemacpsp, phy_addr, 0, &temp);
|
||||||
XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
|
XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
|
||||||
return 10;
|
return 10;
|
||||||
|
@ -556,26 +556,26 @@ unsigned Phy_Setup (XEmacPs *xemacpsp)
|
||||||
link_speed = 1000;
|
link_speed = 1000;
|
||||||
configure_IEEE_phy_speed(xemacpsp, link_speed);
|
configure_IEEE_phy_speed(xemacpsp, link_speed);
|
||||||
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
|
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
|
||||||
sleep(1);
|
vTaskDelay(1);
|
||||||
#elif defined(ipconfigNIC_LINKSPEED100)
|
#elif defined(ipconfigNIC_LINKSPEED100)
|
||||||
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
|
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
|
||||||
link_speed = 100;
|
link_speed = 100;
|
||||||
configure_IEEE_phy_speed(xemacpsp, link_speed);
|
configure_IEEE_phy_speed(xemacpsp, link_speed);
|
||||||
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
|
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
|
||||||
sleep(1);
|
vTaskDelay(1);
|
||||||
#elif defined(ipconfigNIC_LINKSPEED10)
|
#elif defined(ipconfigNIC_LINKSPEED10)
|
||||||
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
|
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
|
||||||
link_speed = 10;
|
link_speed = 10;
|
||||||
configure_IEEE_phy_speed(xemacpsp, link_speed);
|
configure_IEEE_phy_speed(xemacpsp, link_speed);
|
||||||
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
|
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
|
||||||
sleep(1);
|
vTaskDelay(1);
|
||||||
#endif
|
#endif
|
||||||
if (conv_present) {
|
if (conv_present) {
|
||||||
XEmacPs_PhyWrite(xemacpsp, convphyaddr,
|
XEmacPs_PhyWrite(xemacpsp, convphyaddr,
|
||||||
XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
|
XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
xil_printf("link speed: %d\n", link_speed);
|
FreeRTOS_printf( ( "link speed: %d\n", link_speed ) );
|
||||||
return 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
|
* Handling of Ethernet PHY's
|
||||||
* PHY's communicate with an EMAC either through
|
* PHY's communicate with an EMAC either through
|
||||||
|
@ -82,6 +107,7 @@ typedef struct xEthernetPhy
|
||||||
#define PHY_ID_KSZ8081 0x000010A1
|
#define PHY_ID_KSZ8081 0x000010A1
|
||||||
|
|
||||||
#define PHY_ID_KSZ8863 0x00221430
|
#define PHY_ID_KSZ8863 0x00221430
|
||||||
|
#define PHY_ID_KSZ8081MNXIA 0x00221560
|
||||||
|
|
||||||
#define PHY_ID_DP83848I 0x20005C90
|
#define PHY_ID_DP83848I 0x20005C90
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue