Skip to content

Commit

Permalink
Portable layer changes (#701)
Browse files Browse the repository at this point in the history
* Update NetworkInterface.c

* Update NetworkInterface.c

* Update NetworkInterface.c

* Update x_emacpsif_dma.c

* Update NetworkInterface.c

* Update NetworkInterface_eth.c

* Update NetworkInterface.c

* Uncrustify: triggered by comment.

* Update FreeRTOS_DNS_Cache.c

* Update NetworkInterface.c

* Update NetworkInterface.c

* Update NetworkInterface.c

* Update FreeRTOS_DNS_Parser.c

* Update FreeRTOS_DNS_Parser.c

* Update NetworkInterface.c

* Update uncached_memory.c

* Update x_emacpsif.h

* Update x_emacpsif_dma.c

* Update x_emacpsif_hw.c

* Update x_emacpsif_physpeed.c

* Update x_topology.h

---------

Co-authored-by: GitHub Action <[email protected]>
  • Loading branch information
kar-rahul-aws and actions-user authored Feb 10, 2023
1 parent 96a90c5 commit ab881bf
Show file tree
Hide file tree
Showing 21 changed files with 1,204 additions and 453 deletions.
2 changes: 1 addition & 1 deletion source/FreeRTOS_DNS_Parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@
prepareReplyDNSMessage( pxNetworkBuffer, usLength );
/* This function will fill in the eth addresses and send the packet */
vReturnEthernetFrame( pxNetworkBuffer, pdFALSE );

if( pxNewBuffer != NULL )
{
vReleaseNetworkBufferAndDescriptor( pxNewBuffer );
Expand Down
202 changes: 168 additions & 34 deletions source/portable/NetworkInterface/DriverSAM/NetworkInterface.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
/*
* FreeRTOS+TCP <DEVELOPMENT BRANCH>
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
* FreeRTOS+TCP V2.3.1
* Copyright (C) 2020 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
Expand Down Expand Up @@ -40,7 +38,9 @@
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
#include "FreeRTOS_DNS.h"
#include "FreeRTOS_ARP.h"
#include "FreeRTOS_Routing.h"
#include "NetworkBufferManagement.h"
#include "NetworkInterface.h"

Expand Down Expand Up @@ -172,13 +172,22 @@ static void prvEMACHandlerTask( void * pvParameters );
/*
* Initialise the ASF GMAC driver.
*/
static BaseType_t prvGMACInit( void );
static BaseType_t prvGMACInit( NetworkInterface_t * pxInterface );

/*
* Try to obtain an Rx packet from the hardware.
*/
static uint32_t prvEMACRxPoll( void );

static BaseType_t prvSAM_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface );
static BaseType_t prvSAM_NetworkInterfaceOutput( NetworkInterface_t * pxInterface,
NetworkBufferDescriptor_t * const pxBuffer,
BaseType_t bReleaseAfterSend );
static BaseType_t prvSAM_GetPhyLinkStatus( NetworkInterface_t * pxInterface );

NetworkInterface_t * pxSAM_FillInterfaceDescriptor( BaseType_t xEMACIndex,
NetworkInterface_t * pxInterface );

/*
* Handle transmission errors.
*/
Expand All @@ -200,11 +209,16 @@ static const uint8_t llmnr_mac_address[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC
/* The GMAC object as defined by the ASF drivers. */
static gmac_device_t gs_gmac_dev;

/* MAC address to use. */
extern const uint8_t ucMACAddress[ 6 ];

/* Holds the handle of the task used as a deferred interrupt processor. The
* handle is used so direct notifications can be sent to the task for all EMAC/DMA
* related interrupts. */
TaskHandle_t xEMACTaskHandle = NULL;

static NetworkInterface_t * pxMyInterface = NULL;

static QueueHandle_t xTxBufferQueue;
int tx_release_count[ 4 ];

Expand Down Expand Up @@ -421,20 +435,21 @@ static BaseType_t xPHY_Write( BaseType_t xAddress,
}
/*-----------------------------------------------------------*/

BaseType_t xNetworkInterfaceInitialise( void )
static BaseType_t prvSAM_NetworkInterfaceInitialise( NetworkInterface_t * pxInterface )
{
const TickType_t x5_Seconds = 5000UL;

if( xEMACTaskHandle == NULL )
{
prvGMACInit();
prvGMACInit( pxInterface );

cache_clean_invalidate();

/* The handler task is created at the highest possible priority to
* ensure the interrupt handler can return directly to it. */
xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &xEMACTaskHandle );
configASSERT( xEMACTaskHandle );
pxMyInterface = pxInterface;
}

if( xTxBufferQueue == NULL )
Expand All @@ -451,14 +466,54 @@ BaseType_t xNetworkInterfaceInitialise( void )

/* When returning non-zero, the stack will become active and
* start DHCP (in configured) */
return xGetPhyLinkStatus();
return prvSAM_GetPhyLinkStatus( NULL );
}
/*-----------------------------------------------------------*/

BaseType_t xGetPhyLinkStatus( void )
#if ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 )

/* Do not call the following function directly. It is there for downward compatibility.
* The function FreeRTOS_IPInit() will call it to initialice the interface and end-point
* objects. See the description in FreeRTOS_Routing.h. */
NetworkInterface_t * pxFillInterfaceDescriptor( BaseType_t xEMACIndex,
NetworkInterface_t * pxInterface )
{
pxSAM_FillInterfaceDescriptor( xEMACIndex, pxInterface );
}

#endif /* ( ipconfigCOMPATIBLE_WITH_SINGLE != 0 ) */
/*-----------------------------------------------------------*/

NetworkInterface_t * pxSAM_FillInterfaceDescriptor( BaseType_t xEMACIndex,
NetworkInterface_t * pxInterface )
{
/* This function pxSAM_FillInterfaceDescriptor() adds a network-interface.
* Make sure that the object pointed to by 'pxInterface'
* is declared static or global, and that it will remain to exist. */

memset( pxInterface, '\0', sizeof( *pxInterface ) );
pxInterface->pcName = "GMAC"; /* Just for logging, debugging. */
pxInterface->pvArgument = ( void * ) xEMACIndex; /* Has only meaning for the driver functions. */
pxInterface->pfInitialise = prvSAM_NetworkInterfaceInitialise;
pxInterface->pfOutput = prvSAM_NetworkInterfaceOutput;
pxInterface->pfGetPhyLinkStatus = prvSAM_GetPhyLinkStatus;

return pxInterface;
}
/*-----------------------------------------------------------*/

static BaseType_t prvSAM_GetPhyLinkStatus( NetworkInterface_t * pxInterface )
{
BaseType_t xReturn;

/*_RB_ Will this parameter be used by any port? */

/*_HT_ I think it will if there are two instances of an EMAC that share
* the same driver and obviously get a different 'NetworkInterface_t'. */
/* Avoid warning about unused parameter. */
( void ) pxInterface;

/* This function returns true if the Link Status in the PHY is high. */
if( xPhyObject.ulLinkStatusMask != 0 )
{
xReturn = pdPASS;
Expand Down Expand Up @@ -494,13 +549,16 @@ static void hand_tx_errors( void )

volatile IPPacket_t * pxSendPacket;

BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
BaseType_t bReleaseAfterSend )
static BaseType_t prvSAM_NetworkInterfaceOutput( NetworkInterface_t * pxInterface,
NetworkBufferDescriptor_t * const pxDescriptor,
BaseType_t bReleaseAfterSend )
{
/* Do not wait too long for a free TX DMA buffer. */
const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
uint32_t ulTransmitSize;

/* Avoid warning about unused parameter. */
( void ) pxInterface;
ulTransmitSize = pxDescriptor->xDataLength;

pxSendPacket = ( IPPacket_t * ) pxDescriptor->pucEthernetBuffer;
Expand All @@ -514,6 +572,15 @@ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescript
* statement. */
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( xPhyObject.ulLinkStatusMask == 0ul )
{
/* Do not attempt to send packets as long as the Link Status is low. */
Expand Down Expand Up @@ -571,27 +638,64 @@ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescript
}
/*-----------------------------------------------------------*/

static BaseType_t prvGMACInit( void )
static BaseType_t prvGMACInit( NetworkInterface_t * pxInterface )
{
uint32_t ncfgr;
NetworkEndPoint_t * pxEndPoint;
BaseType_t xEntry = 1;

gmac_options_t gmac_option;

pxEndPoint = FreeRTOS_FirstEndPoint( pxInterface );
configASSERT( pxEndPoint != NULL );

gmac_enable_management( GMAC, true );
/* Enable further GMAC maintenance. */
GMAC->GMAC_NCR |= GMAC_NCR_MPE;

memset( &gmac_option, '\0', sizeof( gmac_option ) );
gmac_option.uc_copy_all_frame = 0;
gmac_option.uc_no_boardcast = 0;
memcpy( gmac_option.uc_mac_addr, ipLOCAL_MAC_ADDRESS, sizeof( gmac_option.uc_mac_addr ) );
memcpy( gmac_option.uc_mac_addr, pxEndPoint->xMACAddress.ucBytes, sizeof( gmac_option.uc_mac_addr ) );

gs_gmac_dev.p_hw = GMAC;
gmac_dev_init( GMAC, &gs_gmac_dev, &gmac_option );

NVIC_SetPriority( GMAC_IRQn, configMAC_INTERRUPT_PRIORITY );
NVIC_EnableIRQ( GMAC_IRQn );

#if ( ipconfigUSE_LLMNR == 1 )
{
gmac_set_address( GMAC, xEntry++, xLLMNR_MacAdress.ucBytes );
}
#endif /* ipconfigUSE_LLMNR */

#if ( ipconfigUSE_IPv6 != 0 )
{
NetworkEndPoint_t * pxEndPoint;
#if ( ipconfigUSE_LLMNR == 1 )
{
gmac_set_address( GMAC, xEntry++, ( uint8_t * ) xLLMNR_MacAdressIPv6.ucBytes );
}
#endif /* ipconfigUSE_LLMNR */

for( pxEndPoint = FreeRTOS_FirstEndPoint( pxMyInterface );
pxEndPoint != NULL;
pxEndPoint = FreeRTOS_NextEndPoint( pxMyInterface, pxEndPoint ) )
{
if( pxEndPoint->bits.bIPv6 != pdFALSE_UNSIGNED )
{
uint8_t ucMACAddress[ 6 ] = { 0x33, 0x33, 0xff, 0, 0, 0 };

ucMACAddress[ 3 ] = pxEndPoint->ipv6_settings.xIPAddress.ucBytes[ 13 ];
ucMACAddress[ 4 ] = pxEndPoint->ipv6_settings.xIPAddress.ucBytes[ 14 ];
ucMACAddress[ 5 ] = pxEndPoint->ipv6_settings.xIPAddress.ucBytes[ 15 ];
gmac_set_address( GMAC, xEntry++, ucMACAddress );
}
}
}
#endif /* ipconfigUSE_IPv6 */

{
/* Set MDC clock divider. */
gmac_set_mdc_clock( GMAC, sysclk_get_cpu_hz() );
Expand Down Expand Up @@ -798,6 +902,8 @@ static uint32_t prvEMACRxPoll( void )
#endif /* ipconfigZERO_COPY_RX_DRIVER */

pxNextNetworkBufferDescriptor->xDataLength = ( size_t ) ulReceiveCount;
pxNextNetworkBufferDescriptor->pxInterface = pxMyInterface;
pxNextNetworkBufferDescriptor->pxEndPoint = FreeRTOS_MatchingEndpoint( pxMyInterface, pxCurDescriptor->pucEthernetBuffer );
xRxEvent.pvData = ( void * ) pxNextNetworkBufferDescriptor;

/* Send the descriptor to the IP task for processing. */
Expand All @@ -820,6 +926,54 @@ static uint32_t prvEMACRxPoll( void )
}
/*-----------------------------------------------------------*/

volatile UBaseType_t uxLastMinBufferCount = 0;
#if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
volatile UBaseType_t uxLastMinQueueSpace;
#endif
volatile UBaseType_t uxCurrentSemCount;
volatile UBaseType_t uxLowestSemCount;

void vCheckBuffersAndQueue( void )
{
static UBaseType_t uxCurrentCount;

#if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
{
uxCurrentCount = uxGetMinimumIPQueueSpace();

if( uxLastMinQueueSpace != uxCurrentCount )
{
/* The logging produced below may be helpful
* while tuning +TCP: see how many buffers are in use. */
uxLastMinQueueSpace = uxCurrentCount;
FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
}
}
#endif /* ipconfigCHECK_IP_QUEUE_SPACE */
uxCurrentCount = uxGetMinimumFreeNetworkBuffers();

if( uxLastMinBufferCount != uxCurrentCount )
{
/* The logging produced below may be helpful
* while tuning +TCP: see how many buffers are in use. */
uxLastMinBufferCount = uxCurrentCount;
FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
}

if( xTXDescriptorSemaphore != NULL )
{
uxCurrentSemCount = uxSemaphoreGetCount( xTXDescriptorSemaphore );

if( uxLowestSemCount > uxCurrentSemCount )
{
uxLowestSemCount = uxCurrentSemCount;
FreeRTOS_printf( ( "TX DMA buffers: lowest %lu\n", uxLowestSemCount ) );
}
}
}
/*-----------------------------------------------------------*/

extern uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * NETWORK_BUFFER_SIZE ];
void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
{
Expand All @@ -840,7 +994,6 @@ void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkB
static void prvEMACHandlerTask( void * pvParameters )
{
UBaseType_t uxCount;
UBaseType_t uxLowestSemCount = 0;

#if ( ipconfigZERO_COPY_TX_DRIVER != 0 )
NetworkBufferDescriptor_t * pxBuffer;
Expand All @@ -858,26 +1011,7 @@ static void prvEMACHandlerTask( void * pvParameters )
for( ; ; )
{
xResult = 0;

#if ( ipconfigHAS_PRINTF != 0 )
{
/* Call a function that monitors resources: the amount of free network
* buffers and the amount of free space on the heap. See FreeRTOS_IP.c
* for more detailed comments. */
vPrintResourceStats();

if( xTXDescriptorSemaphore != NULL )
{
UBaseType_t uxCurrentSemCount = uxSemaphoreGetCount( xTXDescriptorSemaphore );

if( uxLowestSemCount > uxCurrentSemCount )
{
uxLowestSemCount = uxCurrentSemCount;
FreeRTOS_printf( ( "TX DMA buffers: lowest %lu\n", uxLowestSemCount ) );
}
}
}
#endif /* ( ipconfigHAS_PRINTF != 0 ) */
vCheckBuffersAndQueue();

if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
{
Expand Down
Loading

0 comments on commit ab881bf

Please sign in to comment.