mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-21 22:11:57 -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. */
|
||||
#define dhcpFIRST_OPTION_BYTE_OFFSET ( 0xf0 )
|
||||
|
||||
/* When walking the variable length options field, the following value is used
|
||||
to ensure the walk has not gone past the end of the valid options. 2 bytes is
|
||||
made up of the length byte, and minimum one byte value. */
|
||||
#define dhcpMAX_OPTION_LENGTH_OF_INTEREST ( 2L )
|
||||
|
||||
/* Standard DHCP port numbers and magic cookie value. */
|
||||
#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
|
||||
#define dhcpCLIENT_PORT 0x4400u
|
||||
|
@ -647,9 +642,11 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
|
|||
/* Walk through the options until the dhcpOPTION_END_BYTE byte
|
||||
is found, taking care not to walk off the end of the options. */
|
||||
pucByte = &( pxDHCPMessage->ucFirstOptionByte );
|
||||
pucLastByte = &( pucUDPPayload[ lBytes - dhcpMAX_OPTION_LENGTH_OF_INTEREST ] );
|
||||
/* Maintain a pointer to the last valid byte (i.e. not the first
|
||||
invalid byte). */
|
||||
pucLastByte = pucUDPPayload + lBytes - 1;
|
||||
|
||||
while( pucByte < pucLastByte )
|
||||
while( pucByte <= pucLastByte )
|
||||
{
|
||||
ucOptionCode = pucByte[ 0 ];
|
||||
if( ucOptionCode == dhcpOPTION_END_BYTE )
|
||||
|
@ -666,12 +663,13 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
|
|||
}
|
||||
|
||||
/* Stop if the response is malformed. */
|
||||
if( pucByte < pucLastByte - 1 )
|
||||
if( pucByte < pucLastByte )
|
||||
{
|
||||
/* There are at least two bytes left. */
|
||||
ucLength = pucByte[ 1 ];
|
||||
pucByte += 2;
|
||||
|
||||
if( pucByte >= pucLastByte - ucLength )
|
||||
if( pucByte + ucLength > pucLastByte )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -926,7 +924,8 @@ size_t xOptionsLength = sizeof( ucDHCPRequestOptions );
|
|||
FreeRTOS_debug_printf( ( "vDHCPProcess: reply %lxip\n", FreeRTOS_ntohl( xDHCPData.ulOfferedIPAddress ) ) );
|
||||
iptraceSENDING_DHCP_REQUEST();
|
||||
|
||||
if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )
|
||||
/* 'ucFirstOptionByte' is part of DHCP message struct, so subtract one byte. */
|
||||
if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength - 1 ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )
|
||||
{
|
||||
/* The packet was not successfully queued for sending and must be
|
||||
returned to the stack. */
|
||||
|
@ -954,7 +953,8 @@ size_t xOptionsLength = sizeof( ucDHCPDiscoverOptions );
|
|||
FreeRTOS_debug_printf( ( "vDHCPProcess: discover\n" ) );
|
||||
iptraceSENDING_DHCP_DISCOVER();
|
||||
|
||||
if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )
|
||||
/* 'ucFirstOptionByte' is part of DHCP message struct, so subtract one byte. */
|
||||
if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength - 1 ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )
|
||||
{
|
||||
/* The packet was not successfully queued for sending and must be
|
||||
returned to the stack. */
|
||||
|
|
|
@ -151,6 +151,11 @@ static uint32_t prvGetHostByName( const char *pcHostName, TickType_t xIdentifier
|
|||
} DNSCacheRow_t;
|
||||
|
||||
static DNSCacheRow_t xDNSCache[ ipconfigDNS_CACHE_ENTRIES ];
|
||||
|
||||
void FreeRTOS_dnsclear()
|
||||
{
|
||||
memset( xDNSCache, 0x0, sizeof( xDNSCache ) );
|
||||
}
|
||||
#endif /* ipconfigUSE_DNS_CACHE == 1 */
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
|
@ -809,24 +814,16 @@ static uint8_t *prvSkipNameField( uint8_t *pucByte, size_t xSourceLen )
|
|||
|
||||
uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||
{
|
||||
uint8_t *pucUDPPayloadBuffer;
|
||||
size_t xPlayloadBufferLength;
|
||||
DNSMessage_t *pxDNSMessageHeader;
|
||||
|
||||
xPlayloadBufferLength = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
|
||||
if ( xPlayloadBufferLength < sizeof( DNSMessage_t ) )
|
||||
if( pxNetworkBuffer->xDataLength >= sizeof( DNSMessage_t ) )
|
||||
{
|
||||
return pdFAIL;
|
||||
}
|
||||
pxDNSMessageHeader =
|
||||
( DNSMessage_t * )( pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t ) );
|
||||
|
||||
pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
|
||||
pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
|
||||
|
||||
if( pxNetworkBuffer->xDataLength > sizeof( UDPPacket_t ) )
|
||||
{
|
||||
prvParseDNSReply( pucUDPPayloadBuffer,
|
||||
xPlayloadBufferLength,
|
||||
( uint32_t )pxDNSMessageHeader->usIdentifier );
|
||||
prvParseDNSReply( ( uint8_t * )pxDNSMessageHeader,
|
||||
pxNetworkBuffer->xDataLength,
|
||||
( uint32_t )pxDNSMessageHeader->usIdentifier );
|
||||
}
|
||||
|
||||
/* The packet was not consumed. */
|
||||
|
@ -841,12 +838,11 @@ DNSMessage_t *pxDNSMessageHeader;
|
|||
UDPPacket_t *pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
|
||||
uint8_t *pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
|
||||
|
||||
if( pxNetworkBuffer->xDataLength > sizeof( UDPPacket_t) )
|
||||
{
|
||||
prvTreatNBNS( pucUDPPayloadBuffer,
|
||||
pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t ),
|
||||
pxUDPPacket->xIPHeader.ulSourceIPAddress );
|
||||
}
|
||||
/* The network buffer data length has already been set to the
|
||||
length of the UDP payload. */
|
||||
prvTreatNBNS( pucUDPPayloadBuffer,
|
||||
pxNetworkBuffer->xDataLength,
|
||||
pxUDPPacket->xIPHeader.ulSourceIPAddress );
|
||||
|
||||
/* The packet was not consumed. */
|
||||
return pdFAIL;
|
||||
|
@ -1312,6 +1308,9 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
|
|||
pxUDPHeader->usLength = FreeRTOS_htons( lNetLength + ipSIZE_OF_UDP_HEADER );
|
||||
vFlip_16( pxUDPPacket->xUDPHeader.usSourcePort, pxUDPPacket->xUDPHeader.usDestinationPort );
|
||||
|
||||
/* Important: tell NIC driver how many bytes must be sent */
|
||||
pxNetworkBuffer->xDataLength = ( size_t ) ( lNetLength + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_UDP_HEADER + ipSIZE_OF_ETH_HEADER );
|
||||
|
||||
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
|
||||
{
|
||||
/* calculate the IP header checksum */
|
||||
|
@ -1320,13 +1319,10 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
|
|||
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
|
||||
|
||||
/* calculate the UDP checksum for outgoing package */
|
||||
usGenerateProtocolChecksum( ( uint8_t* ) pxUDPPacket, lNetLength, pdTRUE );
|
||||
usGenerateProtocolChecksum( ( uint8_t* ) pxUDPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Important: tell NIC driver how many bytes must be sent */
|
||||
pxNetworkBuffer->xDataLength = ( size_t ) ( lNetLength + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_UDP_HEADER + ipSIZE_OF_ETH_HEADER );
|
||||
|
||||
/* This function will fill in the eth addresses and send the packet */
|
||||
vReturnEthernetFrame( pxNetworkBuffer, pdFALSE );
|
||||
}
|
||||
|
@ -1342,13 +1338,15 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
|
|||
BaseType_t xFound = pdFALSE;
|
||||
uint32_t ulCurrentTimeSeconds = ( xTaskGetTickCount() / portTICK_PERIOD_MS ) / 1000;
|
||||
static BaseType_t xFreeEntry = 0;
|
||||
configASSERT(pcName);
|
||||
|
||||
|
||||
/* For each entry in the DNS cache table. */
|
||||
for( x = 0; x < ipconfigDNS_CACHE_ENTRIES; x++ )
|
||||
{
|
||||
if( xDNSCache[ x ].pcName[ 0 ] == 0 )
|
||||
{
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( 0 == strcmp( xDNSCache[ x ].pcName, pcName ) )
|
||||
|
@ -1419,6 +1417,6 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
|
|||
|
||||
/* Provide access to private members for testing. */
|
||||
#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
|
||||
#include "aws_freertos_tcp_test_access_dns_define.h"
|
||||
#include "iot_freertos_tcp_test_access_dns_define.h"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1824,7 +1824,7 @@ uint8_t ucProtocol;
|
|||
{
|
||||
return ipINVALID_LENGTH;
|
||||
}
|
||||
if( uxBufferLength < FreeRTOS_ntohs( pxIPPacket->xIPHeader.usLength ) )
|
||||
if( uxBufferLength < ( size_t ) ( ipSIZE_OF_ETH_HEADER + FreeRTOS_ntohs( pxIPPacket->xIPHeader.usLength ) ) )
|
||||
{
|
||||
return ipINVALID_LENGTH;
|
||||
}
|
||||
|
@ -2316,3 +2316,9 @@ BaseType_t FreeRTOS_IsNetworkUp( void )
|
|||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Provide access to private members for verification. */
|
||||
#ifdef FREERTOS_TCP_ENABLE_VERIFICATION
|
||||
#include "aws_freertos_ip_verification_access_ip_define.h"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -89,6 +89,11 @@ respectively. */
|
|||
#define socketNEXT_UDP_PORT_NUMBER_INDEX 0
|
||||
#define socketNEXT_TCP_PORT_NUMBER_INDEX 1
|
||||
|
||||
/* Some helper macro's for defining the 20/80 % limits of uxLittleSpace / uxEnoughSpace. */
|
||||
#define sock20_PERCENT 20
|
||||
#define sock80_PERCENT 80
|
||||
#define sock100_PERCENT 100
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -1428,6 +1433,31 @@ FreeRTOS_Socket_t *pxSocket;
|
|||
break;
|
||||
#endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */
|
||||
|
||||
case FREERTOS_SO_SET_LOW_HIGH_WATER:
|
||||
{
|
||||
LowHighWater_t *pxLowHighWater = ( LowHighWater_t * ) pvOptionValue;
|
||||
|
||||
if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
|
||||
{
|
||||
/* It is not allowed to access 'pxSocket->u.xTCP'. */
|
||||
FreeRTOS_debug_printf( ( "FREERTOS_SO_SET_LOW_HIGH_WATER: wrong socket type\n" ) );
|
||||
break; /* will return -pdFREERTOS_ERRNO_EINVAL */
|
||||
}
|
||||
if( ( pxLowHighWater->uxLittleSpace >= pxLowHighWater->uxEnoughSpace ) ||
|
||||
( pxLowHighWater->uxEnoughSpace > pxSocket->u.xTCP.uxRxStreamSize ) )
|
||||
{
|
||||
/* Impossible values. */
|
||||
FreeRTOS_debug_printf( ( "FREERTOS_SO_SET_LOW_HIGH_WATER: bad values\n" ) );
|
||||
break; /* will return -pdFREERTOS_ERRNO_EINVAL */
|
||||
}
|
||||
/* Send a STOP when buffer space drops below 'uxLittleSpace' bytes. */
|
||||
pxSocket->u.xTCP.uxLittleSpace = pxLowHighWater->uxLittleSpace;
|
||||
/* Send a GO when buffer space grows above 'uxEnoughSpace' bytes. */
|
||||
pxSocket->u.xTCP.uxEnoughSpace = pxLowHighWater->uxEnoughSpace;
|
||||
xReturn = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case FREERTOS_SO_SNDBUF: /* Set the size of the send buffer, in units of MSS (TCP only) */
|
||||
case FREERTOS_SO_RCVBUF: /* Set the size of the receive buffer, in units of MSS (TCP only) */
|
||||
{
|
||||
|
@ -1481,8 +1511,17 @@ FreeRTOS_Socket_t *pxSocket;
|
|||
}
|
||||
|
||||
pxProps = ( ( WinProperties_t * ) pvOptionValue );
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDBUF, &( pxProps->lTxBufSize ), sizeof( pxProps->lTxBufSize ) );
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVBUF, &( pxProps->lRxBufSize ), sizeof( pxProps->lRxBufSize ) );
|
||||
|
||||
if ( FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDBUF, &( pxProps->lTxBufSize ), sizeof( pxProps->lTxBufSize ) ) != 0 )
|
||||
{
|
||||
break; /* will return -pdFREERTOS_ERRNO_EINVAL */
|
||||
}
|
||||
|
||||
if ( FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVBUF, &( pxProps->lRxBufSize ), sizeof( pxProps->lRxBufSize ) ) != 0 )
|
||||
{
|
||||
break; /* will return -pdFREERTOS_ERRNO_EINVAL */
|
||||
}
|
||||
|
||||
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||
{
|
||||
pxSocket->u.xTCP.uxRxWinSize = ( uint32_t )pxProps->lRxWinSize; /* Fixed value: size of the TCP reception window */
|
||||
|
@ -2373,7 +2412,9 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
|
|||
{
|
||||
xResult = -pdFREERTOS_ERRNO_ENOMEM;
|
||||
}
|
||||
else if( pxSocket->u.xTCP.ucTCPState == eCLOSED )
|
||||
else if( pxSocket->u.xTCP.ucTCPState == eCLOSED ||
|
||||
pxSocket->u.xTCP.ucTCPState == eCLOSE_WAIT ||
|
||||
pxSocket->u.xTCP.ucTCPState == eCLOSING )
|
||||
{
|
||||
xResult = -pdFREERTOS_ERRNO_ENOTCONN;
|
||||
}
|
||||
|
@ -2412,22 +2453,25 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
|
|||
'*pxLength' will contain the number of bytes that may be written. */
|
||||
uint8_t *FreeRTOS_get_tx_head( Socket_t xSocket, BaseType_t *pxLength )
|
||||
{
|
||||
uint8_t *pucReturn;
|
||||
uint8_t *pucReturn = NULL;
|
||||
FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
|
||||
StreamBuffer_t *pxBuffer = pxSocket->u.xTCP.txStream;
|
||||
StreamBuffer_t *pxBuffer = NULL;
|
||||
|
||||
if( pxBuffer != NULL )
|
||||
{
|
||||
BaseType_t xSpace = ( BaseType_t ) uxStreamBufferGetSpace( pxBuffer );
|
||||
BaseType_t xRemain = ( BaseType_t ) ( pxBuffer->LENGTH - pxBuffer->uxHead );
|
||||
*pxLength = 0;
|
||||
|
||||
*pxLength = FreeRTOS_min_BaseType( xSpace, xRemain );
|
||||
pucReturn = pxBuffer->ucArray + pxBuffer->uxHead;
|
||||
}
|
||||
else
|
||||
/* Confirm that this is a TCP socket before dereferencing structure
|
||||
member pointers. */
|
||||
if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )
|
||||
{
|
||||
*pxLength = 0;
|
||||
pucReturn = NULL;
|
||||
pxBuffer = pxSocket->u.xTCP.txStream;
|
||||
if( pxBuffer != NULL )
|
||||
{
|
||||
BaseType_t xSpace = ( BaseType_t )uxStreamBufferGetSpace( pxBuffer );
|
||||
BaseType_t xRemain = ( BaseType_t )( pxBuffer->LENGTH - pxBuffer->uxHead );
|
||||
|
||||
*pxLength = FreeRTOS_min_BaseType( xSpace, xRemain );
|
||||
pucReturn = pxBuffer->ucArray + pxBuffer->uxHead;
|
||||
}
|
||||
}
|
||||
|
||||
return pucReturn;
|
||||
|
@ -2862,9 +2906,17 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
|
|||
|
||||
const struct xSTREAM_BUFFER *FreeRTOS_get_rx_buf( Socket_t xSocket )
|
||||
{
|
||||
FreeRTOS_Socket_t *pxSocket = (FreeRTOS_Socket_t *)xSocket;
|
||||
FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * )xSocket;
|
||||
struct xSTREAM_BUFFER *pxReturn = NULL;
|
||||
|
||||
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 */
|
||||
|
@ -2886,12 +2938,12 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
|
|||
|
||||
if( pxSocket->u.xTCP.uxLittleSpace == 0ul )
|
||||
{
|
||||
pxSocket->u.xTCP.uxLittleSpace = ( 1ul * pxSocket->u.xTCP.uxRxStreamSize ) / 5u; /*_RB_ Why divide by 5? Can this be changed to a #define? */
|
||||
pxSocket->u.xTCP.uxLittleSpace = ( sock20_PERCENT * pxSocket->u.xTCP.uxRxStreamSize ) / sock100_PERCENT;
|
||||
}
|
||||
|
||||
if( pxSocket->u.xTCP.uxEnoughSpace == 0ul )
|
||||
{
|
||||
pxSocket->u.xTCP.uxEnoughSpace = ( 4ul * pxSocket->u.xTCP.uxRxStreamSize ) / 5u; /*_RB_ Why multiply by 4? Maybe sock80_PERCENT?*/
|
||||
pxSocket->u.xTCP.uxEnoughSpace = ( sock80_PERCENT * pxSocket->u.xTCP.uxRxStreamSize ) / sock100_PERCENT;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -307,6 +307,20 @@ static BaseType_t prvSendData( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescrip
|
|||
*/
|
||||
static BaseType_t prvTCPHandleState( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer );
|
||||
|
||||
/*
|
||||
* Common code for sending a TCP protocol control packet (i.e. no options, no
|
||||
* payload, just flags).
|
||||
*/
|
||||
static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
|
||||
uint8_t ucTCPFlags );
|
||||
|
||||
/*
|
||||
* A "challenge ACK" is as per https://tools.ietf.org/html/rfc5961#section-3.2,
|
||||
* case #3. In summary, an RST was received with a sequence number that is
|
||||
* unexpected but still within the window.
|
||||
*/
|
||||
static BaseType_t prvTCPSendChallengeAck( NetworkBufferDescriptor_t *pxNetworkBuffer );
|
||||
|
||||
/*
|
||||
* Reply to a peer with the RST flag on, in case a packet can not be handled.
|
||||
*/
|
||||
|
@ -738,7 +752,7 @@ NetworkBufferDescriptor_t xTempBuffer;
|
|||
}
|
||||
|
||||
/* Take the minimum of the RX buffer space and the RX window size. */
|
||||
ulSpace = FreeRTOS_min_uint32( pxSocket->u.xTCP.ulRxCurWinSize, pxTCPWindow->xSize.ulRxWindowLength );
|
||||
ulSpace = FreeRTOS_min_uint32( pxTCPWindow->xSize.ulRxWindowLength, ulFrontSpace );
|
||||
|
||||
if( ( pxSocket->u.xTCP.bits.bLowWater != pdFALSE_UNSIGNED ) || ( pxSocket->u.xTCP.bits.bRxStopped != pdFALSE_UNSIGNED ) )
|
||||
{
|
||||
|
@ -1092,9 +1106,6 @@ uint32_t ulInitialSequenceNumber = 0;
|
|||
/* Set the values of usInitMSS / usCurMSS for this socket. */
|
||||
prvSocketSetMSS( pxSocket );
|
||||
|
||||
/* For now this is also the advertised window size. */
|
||||
pxSocket->u.xTCP.ulRxCurWinSize = pxSocket->u.xTCP.usInitMSS;
|
||||
|
||||
/* The initial sequence numbers at our side are known. Later
|
||||
vTCPWindowInit() will be called to fill in the peer's sequence numbers, but
|
||||
first wait for a SYN+ACK reply. */
|
||||
|
@ -2521,7 +2532,6 @@ TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetB
|
|||
TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
|
||||
TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
|
||||
/* Find out what window size we may advertised. */
|
||||
uint32_t ulFrontSpace;
|
||||
int32_t lRxSpace;
|
||||
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||
#if( ipconfigTCP_ACK_EARLIER_PACKET == 0 )
|
||||
|
@ -2530,20 +2540,6 @@ int32_t lRxSpace;
|
|||
int32_t lMinLength;
|
||||
#endif
|
||||
#endif
|
||||
pxSocket->u.xTCP.ulRxCurWinSize = pxTCPWindow->xSize.ulRxWindowLength -
|
||||
( pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulCurrentSequenceNumber );
|
||||
|
||||
/* Free space in rxStream. */
|
||||
if( pxSocket->u.xTCP.rxStream != NULL )
|
||||
{
|
||||
ulFrontSpace = ( uint32_t ) uxStreamBufferFrontSpace( pxSocket->u.xTCP.rxStream );
|
||||
}
|
||||
else
|
||||
{
|
||||
ulFrontSpace = ( uint32_t ) pxSocket->u.xTCP.uxRxStreamSize;
|
||||
}
|
||||
|
||||
pxSocket->u.xTCP.ulRxCurWinSize = FreeRTOS_min_uint32( ulFrontSpace, pxSocket->u.xTCP.ulRxCurWinSize );
|
||||
|
||||
/* Set the time-out field, so that we'll be called by the IP-task in case no
|
||||
next message will be received. */
|
||||
|
@ -2840,28 +2836,44 @@ TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||
static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
|
||||
uint8_t ucTCPFlags )
|
||||
{
|
||||
#if( ipconfigIGNORE_UNKNOWN_PACKETS == 0 )
|
||||
#if( ipconfigIGNORE_UNKNOWN_PACKETS == 0 )
|
||||
{
|
||||
TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
|
||||
const BaseType_t xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + 0u ); /* Plus 0 options. */
|
||||
TCPPacket_t *pxTCPPacket = ( TCPPacket_t * )( pxNetworkBuffer->pucEthernetBuffer );
|
||||
const BaseType_t xSendLength = ( BaseType_t )
|
||||
( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + 0u ); /* Plus 0 options. */
|
||||
|
||||
pxTCPPacket->xTCPHeader.ucTCPFlags = ipTCP_FLAG_ACK | ipTCP_FLAG_RST;
|
||||
pxTCPPacket->xTCPHeader.ucTCPFlags = ucTCPFlags;
|
||||
pxTCPPacket->xTCPHeader.ucTCPOffset = ( ipSIZE_OF_TCP_HEADER + 0u ) << 2;
|
||||
|
||||
prvTCPReturnPacket( NULL, pxNetworkBuffer, ( uint32_t ) xSendLength, pdFALSE );
|
||||
prvTCPReturnPacket( NULL, pxNetworkBuffer, ( uint32_t )xSendLength, pdFALSE );
|
||||
}
|
||||
#endif /* !ipconfigIGNORE_UNKNOWN_PACKETS */
|
||||
#endif /* !ipconfigIGNORE_UNKNOWN_PACKETS */
|
||||
|
||||
/* Remove compiler warnings if ipconfigIGNORE_UNKNOWN_PACKETS == 1. */
|
||||
( void ) pxNetworkBuffer;
|
||||
( void )pxNetworkBuffer;
|
||||
( void )ucTCPFlags;
|
||||
|
||||
/* The packet was not consumed. */
|
||||
return pdFAIL;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvTCPSendChallengeAck( NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||
{
|
||||
return prvTCPSendSpecialPacketHelper( pxNetworkBuffer, ipTCP_FLAG_ACK );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t *pxNetworkBuffer )
|
||||
{
|
||||
return prvTCPSendSpecialPacketHelper( pxNetworkBuffer,
|
||||
ipTCP_FLAG_ACK | ipTCP_FLAG_RST );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSocketSetMSS( FreeRTOS_Socket_t *pxSocket )
|
||||
{
|
||||
uint32_t ulMSS = ipconfigTCP_MSS;
|
||||
|
@ -2899,8 +2911,13 @@ uint32_t ulLocalIP;
|
|||
uint16_t xLocalPort;
|
||||
uint32_t ulRemoteIP;
|
||||
uint16_t xRemotePort;
|
||||
uint32_t ulSequenceNumber;
|
||||
uint32_t ulAckNumber;
|
||||
BaseType_t xResult = pdPASS;
|
||||
|
||||
configASSERT( pxNetworkBuffer );
|
||||
configASSERT( pxNetworkBuffer->pucEthernetBuffer );
|
||||
|
||||
/* Check for a minimum packet size. */
|
||||
if( pxNetworkBuffer->xDataLength >= ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) )
|
||||
{
|
||||
|
@ -2909,6 +2926,8 @@ BaseType_t xResult = pdPASS;
|
|||
xLocalPort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usDestinationPort );
|
||||
ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
|
||||
xRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
|
||||
ulSequenceNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
|
||||
ulAckNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulAckNr );
|
||||
|
||||
/* Find the destination socket, and if not found: return a socket listing to
|
||||
the destination PORT. */
|
||||
|
@ -2988,13 +3007,36 @@ BaseType_t xResult = pdPASS;
|
|||
flag. */
|
||||
if( ( ucTCPFlags & ipTCP_FLAG_RST ) != 0u )
|
||||
{
|
||||
/* The target socket is not in a listening state, any RST packet
|
||||
will cause the socket to be closed. */
|
||||
FreeRTOS_debug_printf( ( "TCP: RST received from %lxip:%u for %u\n", ulRemoteIP, xRemotePort, xLocalPort ) );
|
||||
/* _HT_: should indicate that 'ECONNRESET' must be returned to the used during next API. */
|
||||
vTCPStateChange( pxSocket, eCLOSED );
|
||||
|
||||
/* The packet cannot be handled. */
|
||||
/* Implement https://tools.ietf.org/html/rfc5961#section-3.2. */
|
||||
if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
|
||||
{
|
||||
/* Per the above RFC, "In the SYN-SENT state ... the RST is
|
||||
acceptable if the ACK field acknowledges the SYN." */
|
||||
if( ulAckNumber == pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber + 1 )
|
||||
{
|
||||
vTCPStateChange( pxSocket, eCLOSED );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check whether the packet matches the next expected sequence number. */
|
||||
if( ulSequenceNumber == pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber )
|
||||
{
|
||||
vTCPStateChange( pxSocket, eCLOSED );
|
||||
}
|
||||
/* Otherwise, check whether the packet is within the receive window. */
|
||||
else if( ulSequenceNumber > pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber &&
|
||||
ulSequenceNumber < ( pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber +
|
||||
pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength ) )
|
||||
{
|
||||
/* Send a challenge ACK. */
|
||||
prvTCPSendChallengeAck( pxNetworkBuffer );
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, do nothing. In any case, the packet cannot be handled. */
|
||||
xResult = pdFAIL;
|
||||
}
|
||||
else if( ( ( ucTCPFlags & ipTCP_FLAG_CTRL ) == ipTCP_FLAG_SYN ) && ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) )
|
||||
|
@ -3304,6 +3346,11 @@ BaseType_t xResult = pdFALSE;
|
|||
|
||||
/* Provide access to private members for testing. */
|
||||
#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
|
||||
#include "aws_freertos_tcp_test_access_tcp_define.h"
|
||||
#include "iot_freertos_tcp_test_access_tcp_define.h"
|
||||
#endif
|
||||
|
||||
/* Provide access to private members for verification. */
|
||||
#ifdef FREERTOS_TCP_ENABLE_VERIFICATION
|
||||
#include "aws_freertos_tcp_verification_access_tcp_define.h"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -292,7 +292,7 @@ void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem
|
|||
pxWhere->pxPrevious = pxNewListItem;
|
||||
|
||||
/* Remember which list the item is in. */
|
||||
pxNewListItem->pvContainer = ( void * ) pxList; /* If this line fails to build then ensure configENABLE_BACKWARD_COMPATIBILITY is set to 1 in FreeRTOSConfig.h. */
|
||||
listLIST_ITEM_CONTAINER( pxNewListItem ) = ( void * ) pxList;
|
||||
|
||||
( pxList->uxNumberOfItems )++;
|
||||
}
|
||||
|
@ -675,17 +675,17 @@ const int32_t l500ms = 500;
|
|||
|
||||
#if( ipconfigUSE_TCP_WIN == 1 )
|
||||
|
||||
void vTCPSegmentCleanup( void )
|
||||
{
|
||||
/* Free and clear the TCP segments pointer. This function should only be called
|
||||
* once FreeRTOS+TCP will no longer be used. No thread-safety is provided for this
|
||||
* function. */
|
||||
if( xTCPSegments != NULL )
|
||||
{
|
||||
vPortFreeLarge( xTCPSegments );
|
||||
xTCPSegments = NULL;
|
||||
}
|
||||
}
|
||||
void vTCPSegmentCleanup( void )
|
||||
{
|
||||
/* Free and clear the TCP segments pointer. This function should only be called
|
||||
* once FreeRTOS+TCP will no longer be used. No thread-safety is provided for this
|
||||
* function. */
|
||||
if( xTCPSegments != NULL )
|
||||
{
|
||||
vPortFreeLarge( xTCPSegments );
|
||||
xTCPSegments = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ipconfgiUSE_TCP_WIN == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -805,20 +805,20 @@ const int32_t l500ms = 500;
|
|||
{
|
||||
ulSavedSequenceNumber = ulCurrentSequenceNumber;
|
||||
|
||||
/* Clean up all sequence received between ulSequenceNumber and ulSequenceNumber + ulLength since they are duplicated.
|
||||
If the server is forced to retransmit packets several time in a row it might send a batch of concatenated packet for speed.
|
||||
So we cannot rely on the packets between ulSequenceNumber and ulSequenceNumber + ulLength to be sequential and it is better to just
|
||||
clean them out. */
|
||||
do
|
||||
{
|
||||
pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
|
||||
/* Clean up all sequence received between ulSequenceNumber and ulSequenceNumber + ulLength since they are duplicated.
|
||||
If the server is forced to retransmit packets several time in a row it might send a batch of concatenated packet for speed.
|
||||
So we cannot rely on the packets between ulSequenceNumber and ulSequenceNumber + ulLength to be sequential and it is better to just
|
||||
clean them out. */
|
||||
do
|
||||
{
|
||||
pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
|
||||
|
||||
if ( pxFound != NULL )
|
||||
{
|
||||
/* Remove it because it will be passed to user directly. */
|
||||
vTCPWindowFree( pxFound );
|
||||
}
|
||||
} while ( pxFound );
|
||||
if ( pxFound != NULL )
|
||||
{
|
||||
/* Remove it because it will be passed to user directly. */
|
||||
vTCPWindowFree( pxFound );
|
||||
}
|
||||
} while ( pxFound );
|
||||
|
||||
/* Check for following segments that are already in the
|
||||
queue and increment ulCurrentSequenceNumber. */
|
||||
|
|
|
@ -240,8 +240,12 @@ BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer
|
|||
{
|
||||
BaseType_t xReturn = pdPASS;
|
||||
FreeRTOS_Socket_t *pxSocket;
|
||||
UDPPacket_t *pxUDPPacket;
|
||||
|
||||
UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
|
||||
configASSERT( pxNetworkBuffer );
|
||||
configASSERT( pxNetworkBuffer->pucEthernetBuffer );
|
||||
|
||||
pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
|
||||
|
||||
/* Caller must check for minimum packet size. */
|
||||
pxSocket = pxUDPSocketLookup( usPort );
|
||||
|
|
|
@ -42,9 +42,9 @@ extern "C" {
|
|||
typedef struct xARP_CACHE_TABLE_ROW
|
||||
{
|
||||
uint32_t ulIPAddress; /* The IP address of an ARP cache entry. */
|
||||
MACAddress_t xMACAddress; /* The MAC address of an ARP cache entry. */
|
||||
MACAddress_t xMACAddress; /* The MAC address of an ARP cache entry. */
|
||||
uint8_t ucAge; /* A value that is periodically decremented but can also be refreshed by active communication. The ARP cache entry is removed if the value reaches zero. */
|
||||
uint8_t ucValid; /* pdTRUE: xMACAddress is valid, pdFALSE: waiting for ARP reply */
|
||||
uint8_t ucValid; /* pdTRUE: xMACAddress is valid, pdFALSE: waiting for ARP reply */
|
||||
} ARPCacheRow_t;
|
||||
|
||||
typedef enum
|
||||
|
|
|
@ -84,8 +84,12 @@ uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer );
|
|||
|
||||
#if( ipconfigUSE_DNS_CACHE != 0 )
|
||||
|
||||
/* Look for the indicated host name in the DNS cache. Returns the IPv4
|
||||
address if present, or 0x0 otherwise. */
|
||||
uint32_t FreeRTOS_dnslookup( const char *pcHostName );
|
||||
|
||||
/* Remove all entries from the DNS cache. */
|
||||
void FreeRTOS_dnsclear();
|
||||
#endif /* ipconfigUSE_DNS_CACHE != 0 */
|
||||
|
||||
#if( ipconfigDNS_USE_CALLBACKS != 0 )
|
||||
|
|
|
@ -41,6 +41,10 @@ extern "C" {
|
|||
#include "FreeRTOS_TCP_IP.h"
|
||||
#endif
|
||||
|
||||
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
|
||||
#include "semphr.h"
|
||||
#endif
|
||||
|
||||
#include "event_groups.h"
|
||||
|
||||
typedef struct xNetworkAddressingParameters
|
||||
|
@ -577,7 +581,6 @@ BaseType_t xIPIsNetworkTaskReady( void );
|
|||
FOnConnected_t pxHandleConnected; /* Actually type: typedef void (* FOnConnected_t) (Socket_t xSocket, BaseType_t ulConnected ); */
|
||||
#endif /* ipconfigUSE_CALLBACKS */
|
||||
uint32_t ulWindowSize; /* Current Window size advertised by peer */
|
||||
uint32_t ulRxCurWinSize; /* Constantly changing: this is the current size available for data reception */
|
||||
size_t uxRxWinSize; /* Fixed value: size of the TCP reception window */
|
||||
size_t uxTxWinSize; /* Fixed value: size of the TCP transmit window */
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ FreeRTOS_setsockopt(). */
|
|||
#define FREERTOS_SO_WAKEUP_CALLBACK ( 17 )
|
||||
#endif
|
||||
|
||||
#define FREERTOS_SO_SET_LOW_HIGH_WATER ( 18 )
|
||||
|
||||
#define FREERTOS_NOT_LAST_IN_FRAGMENTED_PACKET ( 0x80 ) /* For internal use only, but also part of an 8-bit bitwise value. */
|
||||
#define FREERTOS_FRAGMENTED_PACKET ( 0x40 ) /* For internal use only, but also part of an 8-bit bitwise value. */
|
||||
|
@ -155,6 +156,12 @@ typedef struct xWIN_PROPS {
|
|||
int32_t lRxWinSize; /* Unit: MSS */
|
||||
} WinProperties_t;
|
||||
|
||||
typedef struct xLOW_HIGH_WATER {
|
||||
/* Structure to pass for the 'FREERTOS_SO_SET_LOW_HIGH_WATER' option */
|
||||
size_t uxLittleSpace; /* Send a STOP when buffer space drops below X bytes */
|
||||
size_t uxEnoughSpace; /* Send a GO when buffer space grows above X bytes */
|
||||
} LowHighWater_t;
|
||||
|
||||
/* For compatibility with the expected Berkeley sockets naming. */
|
||||
#define socklen_t uint32_t
|
||||
|
||||
|
|
|
@ -210,82 +210,85 @@ NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSi
|
|||
NetworkBufferDescriptor_t *pxReturn = NULL;
|
||||
size_t uxCount;
|
||||
|
||||
if( ( xRequestedSizeBytes != 0u ) && ( xRequestedSizeBytes < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
|
||||
if( xNetworkBufferSemaphore != NULL )
|
||||
{
|
||||
/* ARP packets can replace application packets, so the storage must be
|
||||
at least large enough to hold an ARP. */
|
||||
xRequestedSizeBytes = baMINIMAL_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
/* Add 2 bytes to xRequestedSizeBytes and round up xRequestedSizeBytes
|
||||
to the nearest multiple of N bytes, where N equals 'sizeof( size_t )'. */
|
||||
xRequestedSizeBytes += 2u;
|
||||
if( ( xRequestedSizeBytes & ( sizeof( size_t ) - 1u ) ) != 0u )
|
||||
{
|
||||
xRequestedSizeBytes = ( xRequestedSizeBytes | ( sizeof( size_t ) - 1u ) ) + 1u;
|
||||
}
|
||||
|
||||
/* If there is a semaphore available, there is a network buffer available. */
|
||||
if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
|
||||
{
|
||||
/* Protect the structure as it is accessed from tasks and interrupts. */
|
||||
taskENTER_CRITICAL();
|
||||
if( ( xRequestedSizeBytes != 0u ) && ( xRequestedSizeBytes < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
|
||||
{
|
||||
pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
|
||||
uxListRemove( &( pxReturn->xBufferListItem ) );
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
/* Reading UBaseType_t, no critical section needed. */
|
||||
uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
|
||||
|
||||
if( uxMinimumFreeNetworkBuffers > uxCount )
|
||||
{
|
||||
uxMinimumFreeNetworkBuffers = uxCount;
|
||||
/* ARP packets can replace application packets, so the storage must be
|
||||
at least large enough to hold an ARP. */
|
||||
xRequestedSizeBytes = baMINIMAL_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
/* Allocate storage of exactly the requested size to the buffer. */
|
||||
configASSERT( pxReturn->pucEthernetBuffer == NULL );
|
||||
if( xRequestedSizeBytes > 0 )
|
||||
/* 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 )
|
||||
{
|
||||
/* 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 );
|
||||
xRequestedSizeBytes = ( xRequestedSizeBytes | ( sizeof( size_t ) - 1u ) ) + 1u;
|
||||
}
|
||||
|
||||
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,
|
||||
so the network buffer structure cannot be used and must be
|
||||
released. */
|
||||
vReleaseNetworkBufferAndDescriptor( pxReturn );
|
||||
pxReturn = NULL;
|
||||
pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
|
||||
uxListRemove( &( pxReturn->xBufferListItem ) );
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
/* Reading UBaseType_t, no critical section needed. */
|
||||
uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
|
||||
|
||||
if( 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
|
||||
{
|
||||
/* 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 */
|
||||
/* A descriptor is being returned without an associated buffer being
|
||||
allocated. */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A descriptor is being returned without an associated buffer being
|
||||
allocated. */
|
||||
}
|
||||
}
|
||||
|
||||
if( pxReturn == NULL )
|
||||
|
|
|
@ -37,6 +37,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#pragma unpack
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __RX
|
||||
#ifdef __CCRX__
|
||||
;
|
||||
#pragma packoption
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -36,6 +36,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#pragma pack 1
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __RX
|
||||
#ifdef __CCRX__
|
||||
#pragma pack
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ const TickType_t x5_Seconds = 5000UL;
|
|||
configASSERT( xTXDescriptorSemaphore );
|
||||
}
|
||||
/* When returning non-zero, the stack will become active and
|
||||
start DHCP (in configured) */
|
||||
start DHCP (in configured) */
|
||||
return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
@ -1,3 +1,28 @@
|
|||
/*
|
||||
* FreeRTOS+TCP V2.0.11
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* Handling of Ethernet PHY's
|
||||
* PHY's communicate with an EMAC either through
|
||||
|
@ -24,8 +49,6 @@
|
|||
|
||||
#include "phyHandling.h"
|
||||
|
||||
#include "eventLogging.h"
|
||||
|
||||
#define phyMIN_PHY_ADDRESS 0
|
||||
#define phyMAX_PHY_ADDRESS 31
|
||||
|
||||
|
@ -59,6 +82,7 @@
|
|||
/* Bit fields for 'phyREG_00_BMCR', the 'Basic Mode Control Register'. */
|
||||
#define phyBMCR_FULL_DUPLEX 0x0100u /* Full duplex. */
|
||||
#define phyBMCR_AN_RESTART 0x0200u /* Auto negotiation restart. */
|
||||
#define phyBMCR_ISOLATE 0x0400u /* 1 = Isolates 0 = Normal operation. */
|
||||
#define phyBMCR_AN_ENABLE 0x1000u /* Enable auto negotiation. */
|
||||
#define phyBMCR_SPEED_100 0x2000u /* Select 100Mbps. */
|
||||
#define phyBMCR_RESET 0x8000u /* Reset the PHY. */
|
||||
|
@ -114,6 +138,8 @@ BaseType_t xResult;
|
|||
case PHY_ID_KSZ8051: // same ID as 8041
|
||||
case PHY_ID_KSZ8081: // same ID as 8041
|
||||
*/
|
||||
case PHY_ID_KSZ8081MNXIA:
|
||||
|
||||
case PHY_ID_KSZ8863:
|
||||
default:
|
||||
/* Most PHY's have a 1F_PHYSPCS */
|
||||
|
@ -192,7 +218,6 @@ BaseType_t xPhyAddress;
|
|||
if( pxPhyObject->xPortCount > 0 )
|
||||
{
|
||||
FreeRTOS_printf( ( "PHY ID %lX\n", pxPhyObject->ulPhyIDs[ 0 ] ) );
|
||||
eventLogAdd( "PHY ID 0x%lX", pxPhyObject->ulPhyIDs[ 0 ] );
|
||||
}
|
||||
|
||||
return pxPhyObject->xPortCount;
|
||||
|
@ -246,6 +271,8 @@ BaseType_t xPhyIndex;
|
|||
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
|
||||
break;
|
||||
}
|
||||
/* Block for a while */
|
||||
vTaskDelay( pdMS_TO_TICKS( 50ul ) );
|
||||
}
|
||||
|
||||
/* Clear the reset bits. */
|
||||
|
@ -258,7 +285,7 @@ BaseType_t xPhyIndex;
|
|||
}
|
||||
|
||||
vTaskDelay( pdMS_TO_TICKS( 50ul ) );
|
||||
eventLogAdd( "PHY reset %d ports", (int)pxPhyObject->xPortCount );
|
||||
|
||||
return ulDoneMask;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -367,7 +394,7 @@ BaseType_t xPhyIndex;
|
|||
|
||||
ulConfig |= phyBMCR_AN_ENABLE;
|
||||
|
||||
if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_100 )
|
||||
if( ( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_100 ) || ( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_AUTO ) )
|
||||
{
|
||||
ulConfig |= phyBMCR_SPEED_100;
|
||||
}
|
||||
|
@ -376,7 +403,7 @@ BaseType_t xPhyIndex;
|
|||
ulConfig &= ~phyBMCR_SPEED_100;
|
||||
}
|
||||
|
||||
if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )
|
||||
if( ( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL ) || ( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_AUTO ) )
|
||||
{
|
||||
ulConfig |= phyBMCR_FULL_DUPLEX;
|
||||
}
|
||||
|
@ -413,11 +440,10 @@ BaseType_t xPhyIndex;
|
|||
}
|
||||
|
||||
FreeRTOS_printf( ( "+TCP: advertise: %04lX config %04lX\n", ulAdvertise, ulConfig ) );
|
||||
eventLogAdd( "adv: %04lX config %04lX", ulAdvertise, ulConfig );
|
||||
}
|
||||
|
||||
/* Keep these values for later use. */
|
||||
pxPhyObject->ulBCRValue = ulConfig;
|
||||
pxPhyObject->ulBCRValue = ulConfig & ~phyBMCR_ISOLATE;
|
||||
pxPhyObject->ulACRValue = ulAdvertise;
|
||||
|
||||
return 0;
|
||||
|
@ -476,7 +502,6 @@ TimeOut_t xTimer;
|
|||
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue | phyBMCR_AN_RESTART );
|
||||
}
|
||||
}
|
||||
eventLogAdd( "AN start" );
|
||||
xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( 3000UL );
|
||||
vTaskSetTimeOutState( &xTimer );
|
||||
ulDoneMask = 0;
|
||||
|
@ -507,11 +532,10 @@ eventLogAdd( "AN start" );
|
|||
if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )
|
||||
{
|
||||
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
|
||||
eventLogAdd( "ANtimed out");
|
||||
break;
|
||||
}
|
||||
vTaskDelay( pdMS_TO_TICKS( 50 ) );
|
||||
}
|
||||
eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
|
||||
|
||||
if( ulDoneMask != ( uint32_t)0u )
|
||||
{
|
||||
|
@ -541,7 +565,43 @@ eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
|
|||
ulPHYLinkStatus &= ~( phyBMSR_LINK_STATUS );
|
||||
}
|
||||
|
||||
if( xHas_1F_PHYSPCS( ulPhyID ) )
|
||||
if( ulPhyID == PHY_ID_KSZ8081MNXIA )
|
||||
{
|
||||
uint32_t ulControlStatus;
|
||||
|
||||
pxPhyObject->fnPhyRead( xPhyAddress, 0x1E, &ulControlStatus);
|
||||
switch( ulControlStatus & 0x07 )
|
||||
{
|
||||
case 0x01:
|
||||
case 0x05:
|
||||
// [001] = 10BASE-T half-duplex
|
||||
// [101] = 10BASE-T full-duplex
|
||||
/* 10 Mbps. */
|
||||
ulRegValue |= phyPHYSTS_SPEED_STATUS;
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x06:
|
||||
// [010] = 100BASE-TX half-duplex
|
||||
// [110] = 100BASE-TX full-duplex
|
||||
break;
|
||||
}
|
||||
switch( ulControlStatus & 0x07 )
|
||||
{
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
// [101] = 10BASE-T full-duplex
|
||||
// [110] = 100BASE-TX full-duplex
|
||||
/* Full duplex. */
|
||||
ulRegValue |= phyPHYSTS_DUPLEX_STATUS;
|
||||
break;
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
// [001] = 10BASE-T half-duplex
|
||||
// [010] = 100BASE-TX half-duplex
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( xHas_1F_PHYSPCS( ulPhyID ) )
|
||||
{
|
||||
/* 31 RW PHY Special Control Status */
|
||||
uint32_t ulControlStatus;
|
||||
|
@ -556,7 +616,6 @@ eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
|
|||
{
|
||||
ulRegValue |= phyPHYSTS_SPEED_STATUS;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -569,25 +628,6 @@ eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
|
|||
( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",
|
||||
( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,
|
||||
( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0) ? "high" : "low" ) );
|
||||
eventLogAdd( "%s duplex %u mbit %s st",
|
||||
( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",
|
||||
( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,
|
||||
( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0) ? "high" : "low" );
|
||||
{
|
||||
uint32_t regs[4];
|
||||
int i,j;
|
||||
int address = 0x10;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
pxPhyObject->fnPhyRead( xPhyAddress, address, regs + j );
|
||||
address++;
|
||||
}
|
||||
eventLogAdd("%04lX %04lX %04lX %04lX",
|
||||
regs[0], regs[1], regs[2], regs[3]);
|
||||
}
|
||||
}
|
||||
if( ( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) != ( uint32_t )0u )
|
||||
{
|
||||
pxPhyObject->xPhyProperties.ucDuplex = PHY_DUPLEX_FULL;
|
||||
|
@ -624,6 +664,15 @@ BaseType_t xNeedCheck = pdFALSE;
|
|||
but set a timer to check it later on. */
|
||||
vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );
|
||||
pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_HIGH_CHECK_TIME_MS );
|
||||
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
|
||||
{
|
||||
if( ( pxPhyObject->ulLinkStatusMask & ulBitMask ) == 0ul )
|
||||
{
|
||||
pxPhyObject->ulLinkStatusMask |= ulBitMask;
|
||||
FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );
|
||||
xNeedCheck = pdTRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( xTaskCheckForTimeOut( &( pxPhyObject->xLinkStatusTimer ), &( pxPhyObject->xLinkStatusRemaining ) ) != pdFALSE )
|
||||
{
|
||||
|
@ -644,7 +693,6 @@ BaseType_t xNeedCheck = pdFALSE;
|
|||
pxPhyObject->ulLinkStatusMask &= ~( ulBitMask );
|
||||
}
|
||||
FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );
|
||||
eventLogAdd( "PHY LS now %02lX", pxPhyObject->ulLinkStatusMask );
|
||||
xNeedCheck = pdTRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -451,7 +451,6 @@ BaseType_t xResult;
|
|||
/* For now pdFAIL will be returned. But prvEMACHandlerTask() is running
|
||||
and it will keep on checking the PHY and set 'ulLinkStatusMask' when necessary. */
|
||||
xResult = pdFAIL;
|
||||
FreeRTOS_printf( ( "Link Status still low\n" ) ) ;
|
||||
}
|
||||
/* When returning non-zero, the stack will become active and
|
||||
start DHCP (in configured) */
|
||||
|
@ -593,14 +592,6 @@ const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
|
|||
/* Open a do {} while ( 0 ) loop to be able to call break. */
|
||||
do
|
||||
{
|
||||
if( xCheckLoopback( pxDescriptor, bReleaseAfterSend ) != 0 )
|
||||
{
|
||||
/* The packet has been sent back to the IP-task.
|
||||
The IP-task will further handle it.
|
||||
Do not release the descriptor. */
|
||||
bReleaseAfterSend = pdFALSE;
|
||||
break;
|
||||
}
|
||||
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
|
||||
{
|
||||
ProtocolPacket_t *pxPacket;
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
This is a FreeeRTOS+TCP driver that works for both STM32F4xx and STM32F7xx parts.
|
||||
|
||||
The code of stm32fxx_hal_eth.c is based on both drivers as provided by ST.
|
||||
|
||||
These modules should be included:
|
||||
|
||||
NetworkInterface.c
|
||||
stm32fxx_hal_eth.c
|
||||
|
||||
It is assumed that one of these words are defined:
|
||||
|
||||
STM32F7xx
|
||||
STM32F407xx
|
||||
STM32F417xx
|
||||
STM32F427xx
|
||||
STM32F437xx
|
||||
STM32F429xx
|
||||
STM32F439xx
|
||||
|
||||
The driver has been tested on both Eval and Discovery boards with both STM32F4 and STM32F7.
|
|
@ -0,0 +1,6 @@
|
|||
/*
|
||||
* The Ethernet header files for STM32F2, STM32F4 and STM32F7 have been merged to
|
||||
* a single module that works for both parts: "stm32fxx_hal_eth"
|
||||
*/
|
||||
|
||||
#include "stm32fxx_hal_eth.h"
|
|
@ -0,0 +1,6 @@
|
|||
/*
|
||||
* The Ethernet header files for STM32F2, STM32F4 and STM32F7 have been merged to
|
||||
* a single module that works for both parts: "stm32fxx_hal_eth"
|
||||
*/
|
||||
|
||||
#include "stm32fxx_hal_eth.h"
|
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
|
||||
parameters in order to test in different machines. */
|
||||
static BaseType_t xConfigNextworkInterfaceToUse = configNETWORK_INTERFACE_TO_USE;
|
||||
static BaseType_t xConfigNetworkInterfaceToUse = configNETWORK_INTERFACE_TO_USE;
|
||||
|
||||
/* Handles to the Windows threads that handle the PCAP IO. */
|
||||
static HANDLE vWinPcapRecvThreadHandle = NULL;
|
||||
|
@ -274,9 +274,9 @@ static BaseType_t xInvalidInterfaceDetected = pdFALSE;
|
|||
printf( "\r\nThe interface that will be opened is set by " );
|
||||
printf( "\"configNETWORK_INTERFACE_TO_USE\", which\r\nshould be defined in FreeRTOSConfig.h\r\n" );
|
||||
|
||||
if( ( xConfigNextworkInterfaceToUse < 0L ) || ( xConfigNextworkInterfaceToUse >= lInterfaceNumber ) )
|
||||
if( ( xConfigNetworkInterfaceToUse < 1L ) || ( xConfigNetworkInterfaceToUse >= lInterfaceNumber ) )
|
||||
{
|
||||
printf( "\r\nERROR: configNETWORK_INTERFACE_TO_USE is set to %d, which is an invalid value.\r\n", xConfigNextworkInterfaceToUse );
|
||||
printf( "\r\nERROR: configNETWORK_INTERFACE_TO_USE is set to %d, which is an invalid value.\r\n", xConfigNetworkInterfaceToUse );
|
||||
printf( "Please set configNETWORK_INTERFACE_TO_USE to one of the interface numbers listed above,\r\n" );
|
||||
printf( "then re-compile and re-start the application. Only Ethernet (as opposed to WiFi)\r\n" );
|
||||
printf( "interfaces are supported.\r\n\r\nHALTING\r\n\r\n\r\n" );
|
||||
|
@ -291,7 +291,7 @@ static BaseType_t xInvalidInterfaceDetected = pdFALSE;
|
|||
}
|
||||
else
|
||||
{
|
||||
printf( "Attempting to open interface number %d.\n", xConfigNextworkInterfaceToUse );
|
||||
printf( "Attempting to open interface number %d.\n", xConfigNetworkInterfaceToUse );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,26 +339,24 @@ static char pucInterfaceName[ 256 ];
|
|||
|
||||
static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces )
|
||||
{
|
||||
pcap_if_t *xInterface;
|
||||
pcap_if_t *pxInterface;
|
||||
int32_t x;
|
||||
|
||||
/* Walk the list of devices until the selected device is located. */
|
||||
xInterface = pxAllNetworkInterfaces;
|
||||
if (0 == xConfigNextworkInterfaceToUse) {
|
||||
while (NULL != xInterface) {
|
||||
xInterface = xInterface->next;
|
||||
if (0 == prvOpenInterface(xInterface->name)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
pxInterface = pxAllNetworkInterfaces;
|
||||
for( x = 0L; x < ( xConfigNetworkInterfaceToUse - 1L ); x++ )
|
||||
{
|
||||
pxInterface = pxInterface->next;
|
||||
}
|
||||
else {
|
||||
for (x = 1L; x < xConfigNextworkInterfaceToUse; x++)
|
||||
{
|
||||
xInterface = xInterface->next;
|
||||
}
|
||||
/* Open the selected interface. */
|
||||
(void) prvOpenInterface(xInterface->name);
|
||||
|
||||
/* Open the selected interface. */
|
||||
if( prvOpenInterface( pxInterface->name ) == 0 )
|
||||
{
|
||||
printf( "Successfully opened interface number %d.\n", x + 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Failed to open interface number %d.\n", x + 1 );
|
||||
}
|
||||
|
||||
/* The device list is no longer required. */
|
||||
|
@ -389,7 +387,8 @@ uint32_t ulNetMask;
|
|||
{
|
||||
printf( "\nAn error occurred setting the packet filter.\n" );
|
||||
}
|
||||
|
||||
/* When pcap_compile() succeeds, it allocates memory for the memory pointed to by the bpf_program struct
|
||||
parameter.pcap_freecode() will free that memory. */
|
||||
pcap_freecode( &xFilterCode );
|
||||
}
|
||||
|
||||
|
@ -526,15 +525,15 @@ eFrameProcessingResult_t eResult;
|
|||
|
||||
iptraceNETWORK_INTERFACE_RECEIVE();
|
||||
|
||||
/* Check for minimal size. */
|
||||
if( pxHeader->len >= sizeof( EthernetHeader_t ) )
|
||||
{
|
||||
eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
|
||||
}
|
||||
else
|
||||
{
|
||||
eResult = eReleaseBuffer;
|
||||
}
|
||||
/* Check for minimal size. */
|
||||
if( pxHeader->len >= sizeof( EthernetHeader_t ) )
|
||||
{
|
||||
eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
|
||||
}
|
||||
else
|
||||
{
|
||||
eResult = eReleaseBuffer;
|
||||
}
|
||||
|
||||
if( eResult == eProcessBuffer )
|
||||
{
|
||||
|
@ -633,4 +632,3 @@ static const char *prvRemoveSpaces( char *pcBuffer, int aBuflen, const char *pcM
|
|||
|
||||
return pcBuffer;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
/*
|
||||
FreeRTOS+TCP V2.0.11
|
||||
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
http://aws.amazon.com/freertos
|
||||
http://www.FreeRTOS.org
|
||||
* FreeRTOS+TCP V2.0.11
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
|
@ -38,7 +38,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_ARP.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
#include "NetworkInterface.h"
|
||||
|
||||
|
@ -56,7 +55,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#endif
|
||||
|
||||
#define niBMSR_LINK_STATUS 0x0004UL
|
||||
#define niBMSR_AN_COMPLETE 0x0020u /* Auto-Negotiation process completed */
|
||||
|
||||
#ifndef PHY_LS_HIGH_CHECK_TIME_MS
|
||||
/* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
|
||||
|
@ -210,13 +208,6 @@ const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pd
|
|||
|
||||
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )
|
||||
{
|
||||
if( xCheckLoopback( pxBuffer, bReleaseAfterSend ) != 0 )
|
||||
{
|
||||
/* The packet has been sent back to the IP-task.
|
||||
The IP-task will further handle it.
|
||||
Do not release the descriptor. */
|
||||
return pdTRUE;
|
||||
}
|
||||
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
|
||||
{
|
||||
ProtocolPacket_t *pxPacket;
|
||||
|
@ -396,6 +387,7 @@ UBaseType_t uxCurrentBufferCount = 0;
|
|||
xEMACpsif.isr_events &= ~EMAC_IF_ERR_EVENT;
|
||||
emacps_check_errors( &xEMACpsif );
|
||||
}
|
||||
|
||||
if( xResult > 0 )
|
||||
{
|
||||
/* A packet was received. No need to check for the PHY status now,
|
||||
|
|
|
@ -35,7 +35,6 @@ extern "C" {
|
|||
#include "xil_exception.h"
|
||||
#include "xpseudo_asm.h"
|
||||
#include "xil_cache.h"
|
||||
#include "xil_printf.h"
|
||||
#include "xuartps.h"
|
||||
#include "xscugic.h"
|
||||
#include "xemacps.h" /* defines XEmacPs API */
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
/*
|
||||
FreeRTOS+TCP V2.0.11
|
||||
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
http://aws.amazon.com/freertos
|
||||
http://www.FreeRTOS.org
|
||||
* FreeRTOS+TCP V2.0.11
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
|
@ -119,7 +119,6 @@ size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount
|
|||
break;
|
||||
}
|
||||
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
|
||||
#warning ipconfigZERO_COPY_TX_DRIVER is defined
|
||||
{
|
||||
void *pvBuffer = pxDMA_tx_buffers[ tail ];
|
||||
NetworkBufferDescriptor_t *pxBuffer;
|
||||
|
@ -201,7 +200,6 @@ BaseType_t xReturn;
|
|||
XStatus emacps_send_message(xemacpsif_s *xemacpsif, NetworkBufferDescriptor_t *pxBuffer, int iReleaseAfterSend )
|
||||
{
|
||||
int head = xemacpsif->txHead;
|
||||
//int tail = xemacpsif->txTail;
|
||||
int iHasSent = 0;
|
||||
uint32_t ulBaseAddress = xemacpsif->emacps.Config.BaseAddress;
|
||||
TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
|
||||
|
@ -291,6 +289,8 @@ TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
|
|||
/* Start transmit */
|
||||
xemacpsif->txBusy = pdTRUE;
|
||||
XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) );
|
||||
/* Reading it back is important compiler is optimised. */
|
||||
XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET );
|
||||
}
|
||||
dsb();
|
||||
|
||||
|
@ -313,72 +313,51 @@ void emacps_recv_handler(void *arg)
|
|||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
|
||||
static void passEthMessages( NetworkBufferDescriptor_t *ethMsg )
|
||||
static void prvPassEthMessages( NetworkBufferDescriptor_t *pxDescriptor )
|
||||
{
|
||||
IPStackEvent_t xRxEvent;
|
||||
|
||||
xRxEvent.eEventType = eNetworkRxEvent;
|
||||
xRxEvent.pvData = ( void * ) ethMsg;
|
||||
xRxEvent.pvData = ( void * ) pxDescriptor;
|
||||
|
||||
if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 1000 ) != pdPASS )
|
||||
{
|
||||
/* The buffer could not be sent to the stack so must be released again.
|
||||
This is a deferred handler taskr, not a real interrupt, so it is ok to
|
||||
use the task level function here. */
|
||||
do
|
||||
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||
{
|
||||
NetworkBufferDescriptor_t *xNext = ethMsg->pxNextBuffer;
|
||||
vReleaseNetworkBufferAndDescriptor( ethMsg );
|
||||
ethMsg = xNext;
|
||||
} while( ethMsg != NULL );
|
||||
|
||||
do
|
||||
{
|
||||
NetworkBufferDescriptor_t *pxNext = pxDescriptor->pxNextBuffer;
|
||||
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
|
||||
pxDescriptor = pxNext;
|
||||
} while( pxDescriptor != NULL );
|
||||
}
|
||||
#else
|
||||
{
|
||||
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
|
||||
}
|
||||
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
|
||||
iptraceETHERNET_RX_EVENT_LOST();
|
||||
FreeRTOS_printf( ( "passEthMessages: Can not queue return packet!\n" ) );
|
||||
FreeRTOS_printf( ( "prvPassEthMessages: Can not queue return packet!\n" ) );
|
||||
}
|
||||
}
|
||||
|
||||
TickType_t ack_reception_delay = 10;
|
||||
|
||||
int emacps_check_rx( xemacpsif_s *xemacpsif )
|
||||
{
|
||||
NetworkBufferDescriptor_t *pxBuffer, *pxNewBuffer;
|
||||
int rx_bytes;
|
||||
volatile int msgCount = 0;
|
||||
int head = xemacpsif->rxHead;
|
||||
BaseType_t bHasDataPacket = pdFALSE;
|
||||
NetworkBufferDescriptor_t *ethMsg = NULL;
|
||||
NetworkBufferDescriptor_t *ethLast = NULL;
|
||||
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||
NetworkBufferDescriptor_t *pxFirstDescriptor = NULL;
|
||||
NetworkBufferDescriptor_t *pxLastDescriptor = NULL;
|
||||
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
|
||||
|
||||
/* There seems to be an issue (SI# 692601), see comments below. */
|
||||
resetrx_on_no_rxdata(xemacpsif);
|
||||
|
||||
{
|
||||
static int maxcount = 0;
|
||||
int count = 0;
|
||||
for( ;; )
|
||||
{
|
||||
if( ( ( xemacpsif->rxSegments[ head ].address & XEMACPS_RXBUF_NEW_MASK ) == 0 ) ||
|
||||
( pxDMA_rx_buffers[ head ] == NULL ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
if( ++head == ipconfigNIC_N_RX_DESC )
|
||||
{
|
||||
head = 0;
|
||||
}
|
||||
if( head == xemacpsif->rxHead )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (maxcount < count) {
|
||||
maxcount = count;
|
||||
FreeRTOS_printf( ( "emacps_check_rx: %d packets\n", maxcount ) );
|
||||
}
|
||||
head = xemacpsif->rxHead;
|
||||
}
|
||||
|
||||
/* This FreeRTOS+TCP driver shall be compiled with the option
|
||||
"ipconfigUSE_LINKED_RX_MESSAGES" enabled. It allows the driver to send a
|
||||
chain of RX messages within one message to the IP-task. */
|
||||
|
@ -411,10 +390,6 @@ NetworkBufferDescriptor_t *ethLast = NULL;
|
|||
rx_bytes = xemacpsif->rxSegments[ head ].flags & XEMACPS_RXBUF_LEN_MASK;
|
||||
|
||||
pxBuffer->xDataLength = rx_bytes;
|
||||
if( rx_bytes > 60 )
|
||||
{
|
||||
bHasDataPacket = 1;
|
||||
}
|
||||
if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
|
||||
{
|
||||
Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)rx_bytes );
|
||||
|
@ -423,20 +398,29 @@ if( rx_bytes > 60 )
|
|||
/* store it in the receive queue, where it'll be processed by a
|
||||
different handler. */
|
||||
iptraceNETWORK_INTERFACE_RECEIVE();
|
||||
pxBuffer->pxNextBuffer = NULL;
|
||||
|
||||
if( ethMsg == NULL )
|
||||
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||
{
|
||||
// Becomes the first message
|
||||
ethMsg = pxBuffer;
|
||||
}
|
||||
else if( ethLast != NULL )
|
||||
{
|
||||
// Add to the tail
|
||||
ethLast->pxNextBuffer = pxBuffer;
|
||||
}
|
||||
pxBuffer->pxNextBuffer = NULL;
|
||||
|
||||
if( pxFirstDescriptor == NULL )
|
||||
{
|
||||
// Becomes the first message
|
||||
pxFirstDescriptor = pxBuffer;
|
||||
}
|
||||
else if( pxLastDescriptor != NULL )
|
||||
{
|
||||
// Add to the tail
|
||||
pxLastDescriptor->pxNextBuffer = pxBuffer;
|
||||
}
|
||||
|
||||
pxLastDescriptor = pxBuffer;
|
||||
}
|
||||
#else
|
||||
{
|
||||
prvPassEthMessages( pxBuffer );
|
||||
}
|
||||
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
|
||||
|
||||
ethLast = pxBuffer;
|
||||
msgCount++;
|
||||
}
|
||||
{
|
||||
|
@ -453,7 +437,8 @@ if( rx_bytes > 60 )
|
|||
/* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */
|
||||
xemacpsif->rxSegments[ head ].flags = 0;
|
||||
xemacpsif->rxSegments[ head ].address = addr;
|
||||
if (xemacpsif->rxSegments[ head ].address) {
|
||||
if (xemacpsif->rxSegments[ head ].address)
|
||||
{
|
||||
// Just to read it
|
||||
}
|
||||
}
|
||||
|
@ -466,14 +451,14 @@ if( rx_bytes > 60 )
|
|||
xemacpsif->rxHead = head;
|
||||
}
|
||||
|
||||
if( ethMsg != NULL )
|
||||
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
|
||||
{
|
||||
if( bHasDataPacket == pdFALSE )
|
||||
if( pxFirstDescriptor != NULL )
|
||||
{
|
||||
// vTaskDelay( ack_reception_delay );
|
||||
prvPassEthMessages( pxFirstDescriptor );
|
||||
}
|
||||
passEthMessages( ethMsg );
|
||||
}
|
||||
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
|
||||
|
||||
return msgCount;
|
||||
}
|
||||
|
@ -638,7 +623,6 @@ void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif)
|
|||
tempcntr = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXCNT_OFFSET );
|
||||
if ( ( tempcntr == 0 ) && ( xemacpsif->last_rx_frms_cntr == 0 ) )
|
||||
{
|
||||
FreeRTOS_printf( ( "resetrx_on_no_rxdata: RESET~\n" ) );
|
||||
regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
regctrl &= (~XEMACPS_NWCTRL_RXEN_MASK);
|
||||
|
|
|
@ -214,8 +214,6 @@ static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
|
|||
}
|
||||
}
|
||||
|
||||
extern XEmacPs_Config mac_config;
|
||||
|
||||
void HandleTxErrors(xemacpsif_s *xemacpsif)
|
||||
{
|
||||
u32 netctrlreg;
|
||||
|
|
|
@ -234,8 +234,8 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
|||
if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
|
||||
return 10;
|
||||
|
||||
xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\n",
|
||||
__FUNCTION__);
|
||||
FreeRTOS_printf( ( "%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\n",
|
||||
__FUNCTION__ ) );
|
||||
return 10;
|
||||
|
||||
} else {
|
||||
|
@ -253,8 +253,8 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
|||
case (IEEE_CTRL_LINKSPEED_10M):
|
||||
return 10;
|
||||
default:
|
||||
xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\n",
|
||||
__FUNCTION__, phylinkspeed);
|
||||
FreeRTOS_printf( ( "%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\n",
|
||||
__FUNCTION__, phylinkspeed ) );
|
||||
return 10;
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
|||
#else
|
||||
u32 phy_addr = detect_phy(xemacpsp);
|
||||
#endif
|
||||
xil_printf("Start PHY autonegotiation \n");
|
||||
FreeRTOS_printf( ( "Start PHY autonegotiation \n" ) );
|
||||
|
||||
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
||||
#else
|
||||
|
@ -334,24 +334,24 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
|||
break;
|
||||
}
|
||||
#endif
|
||||
xil_printf("Waiting for PHY to complete autonegotiation.\n");
|
||||
FreeRTOS_printf( ( "Waiting for PHY to complete autonegotiation.\n" ) );
|
||||
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
|
||||
sleep(1);
|
||||
vTaskDelay(1);
|
||||
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
||||
#else
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
|
||||
&temp);
|
||||
if (temp & IEEE_AUTONEG_ERROR_MASK) {
|
||||
xil_printf("Auto negotiation error \n");
|
||||
FreeRTOS_printf( ( "Auto negotiation error \n" ) );
|
||||
}
|
||||
#endif
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
|
||||
&status);
|
||||
}
|
||||
|
||||
xil_printf("autonegotiation complete \n");
|
||||
FreeRTOS_printf( ( "autonegotiation complete \n" ) );
|
||||
|
||||
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
||||
#else
|
||||
|
@ -359,7 +359,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
|||
#endif
|
||||
|
||||
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
|
||||
xil_printf("Waiting for Link to be up; Polling for SGMII core Reg \n");
|
||||
FreeRTOS_printf( ( "Waiting for Link to be up; Polling for SGMII core Reg \n" ) );
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
|
||||
while(!(temp & 0x8000)) {
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
|
||||
|
@ -376,7 +376,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
|
|||
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
|
||||
return 10;
|
||||
} else {
|
||||
xil_printf("get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\n");
|
||||
FreeRTOS_printf( ( "get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\n" ) );
|
||||
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
|
||||
XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
|
||||
return 10;
|
||||
|
@ -556,26 +556,26 @@ unsigned Phy_Setup (XEmacPs *xemacpsp)
|
|||
link_speed = 1000;
|
||||
configure_IEEE_phy_speed(xemacpsp, link_speed);
|
||||
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
|
||||
sleep(1);
|
||||
vTaskDelay(1);
|
||||
#elif defined(ipconfigNIC_LINKSPEED100)
|
||||
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
|
||||
link_speed = 100;
|
||||
configure_IEEE_phy_speed(xemacpsp, link_speed);
|
||||
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
|
||||
sleep(1);
|
||||
vTaskDelay(1);
|
||||
#elif defined(ipconfigNIC_LINKSPEED10)
|
||||
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
|
||||
link_speed = 10;
|
||||
configure_IEEE_phy_speed(xemacpsp, link_speed);
|
||||
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
|
||||
sleep(1);
|
||||
vTaskDelay(1);
|
||||
#endif
|
||||
if (conv_present) {
|
||||
XEmacPs_PhyWrite(xemacpsp, convphyaddr,
|
||||
XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
|
||||
}
|
||||
|
||||
xil_printf("link speed: %d\n", link_speed);
|
||||
FreeRTOS_printf( ( "link speed: %d\n", link_speed ) );
|
||||
return link_speed;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,28 @@
|
|||
/*
|
||||
* FreeRTOS+TCP V2.0.11
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://aws.amazon.com/freertos
|
||||
* http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* Handling of Ethernet PHY's
|
||||
* PHY's communicate with an EMAC either through
|
||||
|
@ -82,6 +107,7 @@ typedef struct xEthernetPhy
|
|||
#define PHY_ID_KSZ8081 0x000010A1
|
||||
|
||||
#define PHY_ID_KSZ8863 0x00221430
|
||||
#define PHY_ID_KSZ8081MNXIA 0x00221560
|
||||
|
||||
#define PHY_ID_DP83848I 0x20005C90
|
||||
|
||||
|
|
Loading…
Reference in a new issue