summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2020-02-07 21:49:55 +0000
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2020-02-07 21:49:55 +0000
commit24e71d4ee11bb34889ce22426fd9642a886cf43d (patch)
tree78f618c5044384f380791db602279737f01d6545
parent9bc63c45b54da904224124255fb3556898df6dc5 (diff)
downloadfreertos-24e71d4ee11bb34889ce22426fd9642a886cf43d.tar.gz
git-svn-id: http://svn.code.sf.net/p/freertos/code/trunk@2822 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
-rw-r--r--FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/ReadMe.txt3
-rw-r--r--FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_end.h32
-rw-r--r--FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_start.h32
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/NetworkInterface.c1274
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/component/gmac.h1492
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.c908
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.h562
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.c1888
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.h2692
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/instance/gmac.h2698
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c534
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/NetworkInterface.c2136
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/NetworkInterface.c662
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.c896
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.h328
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c1244
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/ether_callback.c354
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c236
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/FaultInjection.c350
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c1268
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c796
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h288
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c1252
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c486
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.h78
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c1170
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_topology.h92
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/board_family/NetworkInterface.c124
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c2544
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/mw300_rd/NetworkInterface.c434
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c1240
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c1778
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_wifi.c384
-rw-r--r--FreeRTOS/History.txt2
-rw-r--r--FreeRTOS/Source/include/task.h6
-rw-r--r--Upgrading to FreeRTOS V10.3.0.url5
36 files changed, 15170 insertions, 15098 deletions
diff --git a/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/ReadMe.txt b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/ReadMe.txt
new file mode 100644
index 000000000..17aca5764
--- /dev/null
+++ b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/ReadMe.txt
@@ -0,0 +1,3 @@
+Update pack_struct_start.h and pack_struct_end.h for your architecure.
+These files define the specifiers needed by your compiler to properly pack struct data
+need by FreeRTOS+TCP. \ No newline at end of file
diff --git a/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_end.h b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_end.h
new file mode 100644
index 000000000..cdbad17c4
--- /dev/null
+++ b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_end.h
@@ -0,0 +1,32 @@
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2018 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
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+; /* FIX ME. Update for the compiler specifier needed at end of a struct declartion to pack the struct. */ \ No newline at end of file
diff --git a/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_start.h b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_start.h
new file mode 100644
index 000000000..7fe533a06
--- /dev/null
+++ b/FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_start.h
@@ -0,0 +1,32 @@
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2018 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
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+/* FIX ME. Update for the compiler specifier needed at the start of a struct declartion to pack the struct. */ \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/NetworkInterface.c
index 3528269bd..83c96a07c 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/NetworkInterface.c
@@ -1,637 +1,637 @@
-/*
-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. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-/* Some files from the Atmel Software Framework */
-/*_RB_ The SAM4E portable layer has three different header files called gmac.h! */
-#include "instance/gmac.h"
-#include <sysclk.h>
-#include <ethernet_phy.h>
-
-#ifndef BMSR_LINK_STATUS
- #define BMSR_LINK_STATUS 0x0004 //!< Link status
-#endif
-
-#ifndef PHY_LS_HIGH_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
- receiving packets. */
- #define PHY_LS_HIGH_CHECK_TIME_MS 15000
-#endif
-
-#ifndef PHY_LS_LOW_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still low every second. */
- #define PHY_LS_LOW_CHECK_TIME_MS 1000
-#endif
-
-/* Interrupt events to process. Currently only the Rx event is processed
-although code for other events is included to allow for possible future
-expansion. */
-#define EMAC_IF_RX_EVENT 1UL
-#define EMAC_IF_TX_EVENT 2UL
-#define EMAC_IF_ERR_EVENT 4UL
-#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
-
-#define ETHERNET_CONF_PHY_ADDR BOARD_GMAC_PHY_ADDR
-
-#define HZ_PER_MHZ ( 1000000UL )
-
-#ifndef EMAC_MAX_BLOCK_TIME_MS
- #define EMAC_MAX_BLOCK_TIME_MS 100ul
-#endif
-
-#if !defined( GMAC_USES_TX_CALLBACK ) || ( GMAC_USES_TX_CALLBACK != 1 )
- #error Please define GMAC_USES_TX_CALLBACK as 1
-#endif
-
-/* Default the size of the stack used by the EMAC deferred handler task to 4x
-the size of the stack used by the idle task - but allow this to be overridden in
-FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
-#ifndef configEMAC_TASK_STACK_SIZE
- #define configEMAC_TASK_STACK_SIZE ( 4 * configMINIMAL_STACK_SIZE )
-#endif
-
-/*-----------------------------------------------------------*/
-
-/*
- * Wait a fixed time for the link status to indicate the network is up.
- */
-static BaseType_t xGMACWaitLS( TickType_t xMaxTime );
-
-#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 1 ) && ( ipconfigHAS_TX_CRC_OFFLOADING == 0 )
- void vGMACGenerateChecksum( uint8_t *apBuffer );
-#endif
-
-/*
- * Called from the ASF GMAC driver.
- */
-static void prvRxCallback( uint32_t ulStatus );
-static void prvTxCallback( uint32_t ulStatus, uint8_t *puc_buffer );
-
-/*
- * A deferred interrupt handler task that processes GMAC interrupts.
- */
-static void prvEMACHandlerTask( void *pvParameters );
-
-/*
- * Initialise the ASF GMAC driver.
- */
-static BaseType_t prvGMACInit( void );
-
-/*
- * Try to obtain an Rx packet from the hardware.
- */
-static uint32_t prvEMACRxPoll( void );
-
-/*-----------------------------------------------------------*/
-
-/* Bit map of outstanding ETH interrupt events for processing. Currently only
-the Rx interrupt is handled, although code is included for other events to
-enable future expansion. */
-static volatile uint32_t ulISREvents;
-
-/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
-static uint32_t ulPHYLinkStatus = 0;
-static volatile BaseType_t xGMACSwitchRequired;
-
-/* ethernet_phy_addr: the address of the PHY in use.
-Atmel was a bit ambiguous about it so the address will be stored
-in this variable, see ethernet_phy.c */
-extern int ethernet_phy_addr;
-
-/* LLMNR multicast address. */
-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 QueueHandle_t xTxBufferQueue;
-int tx_release_count[ 4 ];
-
-/* xTXDescriptorSemaphore is a counting semaphore with
-a maximum count of GMAC_TX_BUFFERS, which is the number of
-DMA TX descriptors. */
-static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
-
-/*-----------------------------------------------------------*/
-
-/*
- * GMAC interrupt handler.
- */
-void GMAC_Handler(void)
-{
- xGMACSwitchRequired = pdFALSE;
-
- /* gmac_handler() may call prvRxCallback() which may change
- the value of xGMACSwitchRequired. */
- gmac_handler( &gs_gmac_dev );
-
- if( xGMACSwitchRequired != pdFALSE )
- {
- portEND_SWITCHING_ISR( xGMACSwitchRequired );
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvRxCallback( uint32_t ulStatus )
-{
- if( ( ( ulStatus & GMAC_RSR_REC ) != 0 ) && ( xEMACTaskHandle != NULL ) )
- {
- /* let the prvEMACHandlerTask know that there was an RX event. */
- ulISREvents |= EMAC_IF_RX_EVENT;
- /* Only an RX interrupt can wakeup prvEMACHandlerTask. */
- vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvTxCallback( uint32_t ulStatus, uint8_t *puc_buffer )
-{
- if( ( xTxBufferQueue != NULL ) && ( xEMACTaskHandle != NULL ) )
- {
- /* let the prvEMACHandlerTask know that there was an RX event. */
- ulISREvents |= EMAC_IF_TX_EVENT;
-
- vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
- xQueueSendFromISR( xTxBufferQueue, &puc_buffer, ( BaseType_t * ) &xGMACSwitchRequired );
- tx_release_count[ 2 ]++;
- }
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-const TickType_t x5_Seconds = 5000UL;
-
- if( xEMACTaskHandle == NULL )
- {
- prvGMACInit();
-
- /* Wait at most 5 seconds for a Link Status in the PHY. */
- xGMACWaitLS( pdMS_TO_TICKS( x5_Seconds ) );
-
- /* 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, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
- configASSERT( xEMACTaskHandle );
- }
-
- if( xTxBufferQueue == NULL )
- {
- xTxBufferQueue = xQueueCreate( GMAC_TX_BUFFERS, sizeof( void * ) );
- configASSERT( xTxBufferQueue );
- }
-
- if( xTXDescriptorSemaphore == NULL )
- {
- xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) GMAC_TX_BUFFERS, ( UBaseType_t ) GMAC_TX_BUFFERS );
- configASSERT( xTXDescriptorSemaphore );
- }
- /* When returning non-zero, the stack will become active and
- start DHCP (in configured) */
- return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xGetPhyLinkStatus( void )
-{
-BaseType_t xResult;
-
- /* This function returns true if the Link Status in the PHY is high. */
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- xResult = pdTRUE;
- }
- else
- {
- xResult = pdFALSE;
- }
-
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( 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 );
-
- do {
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
- {
- /* Do not attempt to send packets as long as the Link Status is low. */
- break;
- }
- if( xTXDescriptorSemaphore == NULL )
- {
- /* Semaphore has not been created yet? */
- break;
- }
- if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
- {
- /* Time-out waiting for a free TX descriptor. */
- tx_release_count[ 3 ]++;
- break;
- }
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* Confirm that the pxDescriptor may be kept by the driver. */
- configASSERT( bReleaseAfterSend != pdFALSE );
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
-
- gmac_dev_write( &gs_gmac_dev, (void *)pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength, prvTxCallback );
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* Confirm that the pxDescriptor may be kept by the driver. */
- bReleaseAfterSend = pdFALSE;
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
- /* Not interested in a call-back after TX. */
- iptraceNETWORK_INTERFACE_TRANSMIT();
- } while( 0 );
-
- if( bReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvGMACInit( void )
-{
-uint32_t ncfgr;
-
- gmac_options_t gmac_option;
-
- 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, ucMACAddress, 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 );
-
- /* Contact the Ethernet PHY and store it's address in 'ethernet_phy_addr' */
- ethernet_phy_init( GMAC, ETHERNET_CONF_PHY_ADDR, sysclk_get_cpu_hz() );
-
- ethernet_phy_auto_negotiate( GMAC, ethernet_phy_addr );
- ethernet_phy_set_link( GMAC, ethernet_phy_addr, 1 );
-
- /* The GMAC driver will call a hook prvRxCallback(), which
- in turn will wake-up the task by calling vTaskNotifyGiveFromISR() */
- gmac_dev_set_rx_callback( &gs_gmac_dev, prvRxCallback );
- gmac_set_address( GMAC, 1, (uint8_t*)llmnr_mac_address );
-
- ncfgr = GMAC_NCFGR_SPD | GMAC_NCFGR_FD;
-
- GMAC->GMAC_NCFGR = ( GMAC->GMAC_NCFGR & ~( GMAC_NCFGR_SPD | GMAC_NCFGR_FD ) ) | ncfgr;
-
- return 1;
-}
-/*-----------------------------------------------------------*/
-
-static inline unsigned long ulReadMDIO( unsigned /*short*/ usAddress )
-{
-uint32_t ulValue, ulReturn;
-int rc;
-
- gmac_enable_management( GMAC, 1 );
- rc = gmac_phy_read( GMAC, ethernet_phy_addr, usAddress, &ulValue );
- gmac_enable_management( GMAC, 0 );
- if( rc == GMAC_OK )
- {
- ulReturn = ulValue;
- }
- else
- {
- ulReturn = 0UL;
- }
-
- return ulReturn;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t xGMACWaitLS( TickType_t xMaxTime )
-{
-TickType_t xStartTime = xTaskGetTickCount();
-TickType_t xEndTime;
-BaseType_t xReturn;
-const TickType_t xShortTime = pdMS_TO_TICKS( 100UL );
-
- for( ;; )
- {
- xEndTime = xTaskGetTickCount();
-
- if( ( xEndTime - xStartTime ) > xMaxTime )
- {
- /* Wated more than xMaxTime, return. */
- xReturn = pdFALSE;
- break;
- }
-
- /* Check the link status again. */
- ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- /* Link is up - return. */
- xReturn = pdTRUE;
- break;
- }
-
- /* Link is down - wait in the Blocked state for a short while (to allow
- other tasks to execute) before checking again. */
- vTaskDelay( xShortTime );
- }
-
- FreeRTOS_printf( ( "xGMACWaitLS: %ld (PHY %d) freq %lu Mz\n",
- xReturn,
- ethernet_phy_addr,
- sysclk_get_cpu_hz() / HZ_PER_MHZ ) );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-//#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 1 ) && ( ipconfigHAS_TX_CRC_OFFLOADING == 0 )
-
- void vGMACGenerateChecksum( uint8_t *apBuffer )
- {
- ProtocolPacket_t *xProtPacket = (ProtocolPacket_t *)apBuffer;
-
- if ( xProtPacket->xTCPPacket.xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE )
- {
- IPHeader_t *pxIPHeader = &(xProtPacket->xTCPPacket.xIPHeader);
-
- /* Calculate the IP header checksum. */
- pxIPHeader->usHeaderChecksum = 0x00;
- pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
- pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
-
- /* Calculate the TCP checksum for an outgoing packet. */
- usGenerateProtocolChecksum( ( uint8_t * ) apBuffer, pdTRUE );
- }
- }
-
-//#endif
-/*-----------------------------------------------------------*/
-
-static uint32_t prvEMACRxPoll( void )
-{
-unsigned char *pucUseBuffer;
-uint32_t ulReceiveCount, ulResult, ulReturnValue = 0;
-static NetworkBufferDescriptor_t *pxNextNetworkBufferDescriptor = NULL;
-const UBaseType_t xMinDescriptorsToLeave = 2UL;
-const TickType_t xBlockTime = pdMS_TO_TICKS( 100UL );
-static IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-
- for( ;; )
- {
- /* If pxNextNetworkBufferDescriptor was not left pointing at a valid
- descriptor then allocate one now. */
- if( ( pxNextNetworkBufferDescriptor == NULL ) && ( uxGetNumberOfFreeNetworkBuffers() > xMinDescriptorsToLeave ) )
- {
- pxNextNetworkBufferDescriptor = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, xBlockTime );
- }
-
- if( pxNextNetworkBufferDescriptor != NULL )
- {
- /* Point pucUseBuffer to the buffer pointed to by the descriptor. */
- pucUseBuffer = ( unsigned char* ) ( pxNextNetworkBufferDescriptor->pucEthernetBuffer - ipconfigPACKET_FILLER_SIZE );
- }
- else
- {
- /* As long as pxNextNetworkBufferDescriptor is NULL, the incoming
- messages will be flushed and ignored. */
- pucUseBuffer = NULL;
- }
-
- /* Read the next packet from the hardware into pucUseBuffer. */
- ulResult = gmac_dev_read( &gs_gmac_dev, pucUseBuffer, ipTOTAL_ETHERNET_FRAME_SIZE, &ulReceiveCount );
-
- if( ( ulResult != GMAC_OK ) || ( ulReceiveCount == 0 ) )
- {
- /* No data from the hardware. */
- break;
- }
-
- if( pxNextNetworkBufferDescriptor == NULL )
- {
- /* Data was read from the hardware, but no descriptor was available
- for it, so it will be dropped. */
- iptraceETHERNET_RX_EVENT_LOST();
- continue;
- }
-
- iptraceNETWORK_INTERFACE_RECEIVE();
- pxNextNetworkBufferDescriptor->xDataLength = ( size_t ) ulReceiveCount;
- xRxEvent.pvData = ( void * ) pxNextNetworkBufferDescriptor;
-
- /* Send the descriptor to the IP task for processing. */
- if( xSendEventStructToIPTask( &xRxEvent, xBlockTime ) != pdTRUE )
- {
- /* The buffer could not be sent to the stack so must be released
- again. */
- vReleaseNetworkBufferAndDescriptor( pxNextNetworkBufferDescriptor );
- iptraceETHERNET_RX_EVENT_LOST();
- FreeRTOS_printf( ( "prvEMACRxPoll: Can not queue return packet!\n" ) );
- }
-
- /* Now the buffer has either been passed to the IP-task,
- or it has been released in the code above. */
- pxNextNetworkBufferDescriptor = NULL;
- ulReturnValue++;
- }
-
- return ulReturnValue;
-}
-/*-----------------------------------------------------------*/
-
-static void prvEMACHandlerTask( void *pvParameters )
-{
-TimeOut_t xPhyTime;
-TickType_t xPhyRemTime;
-UBaseType_t uxLastMinBufferCount = 0, uxCount;
-UBaseType_t uxCurrentCount;
-#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- UBaseType_t uxLastMinQueueSpace;
-#endif
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- NetworkBufferDescriptor_t *pxBuffer;
-#endif
-uint8_t *pucBuffer;
-BaseType_t xResult = 0;
-uint32_t xStatus;
-const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
-
- configASSERT( xEMACTaskHandle );
-
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
-
- for( ;; )
- {
- 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( 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 */
-
- if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
- {
- /* No events to process now, wait for the next. */
- ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
- }
-
- if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
- {
- ulISREvents &= ~EMAC_IF_RX_EVENT;
-
- /* Wait for the EMAC interrupt to indicate that another packet has been
- received. */
- xResult = prvEMACRxPoll();
- }
-
- if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
- {
- /* Future extension: code to release TX buffers if zero-copy is used. */
- ulISREvents &= ~EMAC_IF_TX_EVENT;
- while( xQueueReceive( xTxBufferQueue, &pucBuffer, 0 ) != pdFALSE )
- {
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- pxBuffer = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
- if( pxBuffer != NULL )
- {
- vReleaseNetworkBufferAndDescriptor( pxBuffer );
- tx_release_count[ 0 ]++;
- }
- else
- {
- tx_release_count[ 1 ]++;
- }
- }
- #else
- {
- tx_release_count[ 0 ]++;
- }
- #endif
- uxCount = uxQueueMessagesWaiting( ( QueueHandle_t ) xTXDescriptorSemaphore );
- if( uxCount < GMAC_TX_BUFFERS )
- {
- /* Tell the counting semaphore that one more TX descriptor is available. */
- xSemaphoreGive( xTXDescriptorSemaphore );
- }
- }
- }
-
- if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
- {
- /* Future extension: logging about errors that occurred. */
- ulISREvents &= ~EMAC_IF_ERR_EVENT;
- }
-
- if( xResult > 0 )
- {
- /* A packet was received. No need to check for the PHY status now,
- but set a timer to check it later on. */
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- xResult = 0;
- }
- else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
- {
- /* Check the link status again. */
- xStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
- {
- ulPHYLinkStatus = xStatus;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
- }
-
- vTaskSetTimeOutState( &xPhyTime );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- }
- else
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
- }
- }
- }
-}
-/*-----------------------------------------------------------*/
+/*
+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. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+/* Some files from the Atmel Software Framework */
+/*_RB_ The SAM4E portable layer has three different header files called gmac.h! */
+#include "instance/gmac.h"
+#include <sysclk.h>
+#include <ethernet_phy.h>
+
+#ifndef BMSR_LINK_STATUS
+ #define BMSR_LINK_STATUS 0x0004 //!< Link status
+#endif
+
+#ifndef PHY_LS_HIGH_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
+ receiving packets. */
+ #define PHY_LS_HIGH_CHECK_TIME_MS 15000
+#endif
+
+#ifndef PHY_LS_LOW_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still low every second. */
+ #define PHY_LS_LOW_CHECK_TIME_MS 1000
+#endif
+
+/* Interrupt events to process. Currently only the Rx event is processed
+although code for other events is included to allow for possible future
+expansion. */
+#define EMAC_IF_RX_EVENT 1UL
+#define EMAC_IF_TX_EVENT 2UL
+#define EMAC_IF_ERR_EVENT 4UL
+#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
+
+#define ETHERNET_CONF_PHY_ADDR BOARD_GMAC_PHY_ADDR
+
+#define HZ_PER_MHZ ( 1000000UL )
+
+#ifndef EMAC_MAX_BLOCK_TIME_MS
+ #define EMAC_MAX_BLOCK_TIME_MS 100ul
+#endif
+
+#if !defined( GMAC_USES_TX_CALLBACK ) || ( GMAC_USES_TX_CALLBACK != 1 )
+ #error Please define GMAC_USES_TX_CALLBACK as 1
+#endif
+
+/* Default the size of the stack used by the EMAC deferred handler task to 4x
+the size of the stack used by the idle task - but allow this to be overridden in
+FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
+#ifndef configEMAC_TASK_STACK_SIZE
+ #define configEMAC_TASK_STACK_SIZE ( 4 * configMINIMAL_STACK_SIZE )
+#endif
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Wait a fixed time for the link status to indicate the network is up.
+ */
+static BaseType_t xGMACWaitLS( TickType_t xMaxTime );
+
+#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 1 ) && ( ipconfigHAS_TX_CRC_OFFLOADING == 0 )
+ void vGMACGenerateChecksum( uint8_t *apBuffer );
+#endif
+
+/*
+ * Called from the ASF GMAC driver.
+ */
+static void prvRxCallback( uint32_t ulStatus );
+static void prvTxCallback( uint32_t ulStatus, uint8_t *puc_buffer );
+
+/*
+ * A deferred interrupt handler task that processes GMAC interrupts.
+ */
+static void prvEMACHandlerTask( void *pvParameters );
+
+/*
+ * Initialise the ASF GMAC driver.
+ */
+static BaseType_t prvGMACInit( void );
+
+/*
+ * Try to obtain an Rx packet from the hardware.
+ */
+static uint32_t prvEMACRxPoll( void );
+
+/*-----------------------------------------------------------*/
+
+/* Bit map of outstanding ETH interrupt events for processing. Currently only
+the Rx interrupt is handled, although code is included for other events to
+enable future expansion. */
+static volatile uint32_t ulISREvents;
+
+/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
+static uint32_t ulPHYLinkStatus = 0;
+static volatile BaseType_t xGMACSwitchRequired;
+
+/* ethernet_phy_addr: the address of the PHY in use.
+Atmel was a bit ambiguous about it so the address will be stored
+in this variable, see ethernet_phy.c */
+extern int ethernet_phy_addr;
+
+/* LLMNR multicast address. */
+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 QueueHandle_t xTxBufferQueue;
+int tx_release_count[ 4 ];
+
+/* xTXDescriptorSemaphore is a counting semaphore with
+a maximum count of GMAC_TX_BUFFERS, which is the number of
+DMA TX descriptors. */
+static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
+
+/*-----------------------------------------------------------*/
+
+/*
+ * GMAC interrupt handler.
+ */
+void GMAC_Handler(void)
+{
+ xGMACSwitchRequired = pdFALSE;
+
+ /* gmac_handler() may call prvRxCallback() which may change
+ the value of xGMACSwitchRequired. */
+ gmac_handler( &gs_gmac_dev );
+
+ if( xGMACSwitchRequired != pdFALSE )
+ {
+ portEND_SWITCHING_ISR( xGMACSwitchRequired );
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvRxCallback( uint32_t ulStatus )
+{
+ if( ( ( ulStatus & GMAC_RSR_REC ) != 0 ) && ( xEMACTaskHandle != NULL ) )
+ {
+ /* let the prvEMACHandlerTask know that there was an RX event. */
+ ulISREvents |= EMAC_IF_RX_EVENT;
+ /* Only an RX interrupt can wakeup prvEMACHandlerTask. */
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvTxCallback( uint32_t ulStatus, uint8_t *puc_buffer )
+{
+ if( ( xTxBufferQueue != NULL ) && ( xEMACTaskHandle != NULL ) )
+ {
+ /* let the prvEMACHandlerTask know that there was an RX event. */
+ ulISREvents |= EMAC_IF_TX_EVENT;
+
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
+ xQueueSendFromISR( xTxBufferQueue, &puc_buffer, ( BaseType_t * ) &xGMACSwitchRequired );
+ tx_release_count[ 2 ]++;
+ }
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+const TickType_t x5_Seconds = 5000UL;
+
+ if( xEMACTaskHandle == NULL )
+ {
+ prvGMACInit();
+
+ /* Wait at most 5 seconds for a Link Status in the PHY. */
+ xGMACWaitLS( pdMS_TO_TICKS( x5_Seconds ) );
+
+ /* 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, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
+ configASSERT( xEMACTaskHandle );
+ }
+
+ if( xTxBufferQueue == NULL )
+ {
+ xTxBufferQueue = xQueueCreate( GMAC_TX_BUFFERS, sizeof( void * ) );
+ configASSERT( xTxBufferQueue );
+ }
+
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) GMAC_TX_BUFFERS, ( UBaseType_t ) GMAC_TX_BUFFERS );
+ configASSERT( xTXDescriptorSemaphore );
+ }
+ /* When returning non-zero, the stack will become active and
+ start DHCP (in configured) */
+ return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xGetPhyLinkStatus( void )
+{
+BaseType_t xResult;
+
+ /* This function returns true if the Link Status in the PHY is high. */
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xResult = pdTRUE;
+ }
+ else
+ {
+ xResult = pdFALSE;
+ }
+
+ return xResult;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceOutput( 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 );
+
+ do {
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
+ {
+ /* Do not attempt to send packets as long as the Link Status is low. */
+ break;
+ }
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ /* Semaphore has not been created yet? */
+ break;
+ }
+ if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
+ {
+ /* Time-out waiting for a free TX descriptor. */
+ tx_release_count[ 3 ]++;
+ break;
+ }
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* Confirm that the pxDescriptor may be kept by the driver. */
+ configASSERT( bReleaseAfterSend != pdFALSE );
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+ gmac_dev_write( &gs_gmac_dev, (void *)pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength, prvTxCallback );
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* Confirm that the pxDescriptor may be kept by the driver. */
+ bReleaseAfterSend = pdFALSE;
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+ /* Not interested in a call-back after TX. */
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+ } while( 0 );
+
+ if( bReleaseAfterSend != pdFALSE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+ return pdTRUE;
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvGMACInit( void )
+{
+uint32_t ncfgr;
+
+ gmac_options_t gmac_option;
+
+ 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, ucMACAddress, 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 );
+
+ /* Contact the Ethernet PHY and store it's address in 'ethernet_phy_addr' */
+ ethernet_phy_init( GMAC, ETHERNET_CONF_PHY_ADDR, sysclk_get_cpu_hz() );
+
+ ethernet_phy_auto_negotiate( GMAC, ethernet_phy_addr );
+ ethernet_phy_set_link( GMAC, ethernet_phy_addr, 1 );
+
+ /* The GMAC driver will call a hook prvRxCallback(), which
+ in turn will wake-up the task by calling vTaskNotifyGiveFromISR() */
+ gmac_dev_set_rx_callback( &gs_gmac_dev, prvRxCallback );
+ gmac_set_address( GMAC, 1, (uint8_t*)llmnr_mac_address );
+
+ ncfgr = GMAC_NCFGR_SPD | GMAC_NCFGR_FD;
+
+ GMAC->GMAC_NCFGR = ( GMAC->GMAC_NCFGR & ~( GMAC_NCFGR_SPD | GMAC_NCFGR_FD ) ) | ncfgr;
+
+ return 1;
+}
+/*-----------------------------------------------------------*/
+
+static inline unsigned long ulReadMDIO( unsigned /*short*/ usAddress )
+{
+uint32_t ulValue, ulReturn;
+int rc;
+
+ gmac_enable_management( GMAC, 1 );
+ rc = gmac_phy_read( GMAC, ethernet_phy_addr, usAddress, &ulValue );
+ gmac_enable_management( GMAC, 0 );
+ if( rc == GMAC_OK )
+ {
+ ulReturn = ulValue;
+ }
+ else
+ {
+ ulReturn = 0UL;
+ }
+
+ return ulReturn;
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t xGMACWaitLS( TickType_t xMaxTime )
+{
+TickType_t xStartTime = xTaskGetTickCount();
+TickType_t xEndTime;
+BaseType_t xReturn;
+const TickType_t xShortTime = pdMS_TO_TICKS( 100UL );
+
+ for( ;; )
+ {
+ xEndTime = xTaskGetTickCount();
+
+ if( ( xEndTime - xStartTime ) > xMaxTime )
+ {
+ /* Wated more than xMaxTime, return. */
+ xReturn = pdFALSE;
+ break;
+ }
+
+ /* Check the link status again. */
+ ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ /* Link is up - return. */
+ xReturn = pdTRUE;
+ break;
+ }
+
+ /* Link is down - wait in the Blocked state for a short while (to allow
+ other tasks to execute) before checking again. */
+ vTaskDelay( xShortTime );
+ }
+
+ FreeRTOS_printf( ( "xGMACWaitLS: %ld (PHY %d) freq %lu Mz\n",
+ xReturn,
+ ethernet_phy_addr,
+ sysclk_get_cpu_hz() / HZ_PER_MHZ ) );
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+//#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 1 ) && ( ipconfigHAS_TX_CRC_OFFLOADING == 0 )
+
+ void vGMACGenerateChecksum( uint8_t *apBuffer )
+ {
+ ProtocolPacket_t *xProtPacket = (ProtocolPacket_t *)apBuffer;
+
+ if ( xProtPacket->xTCPPacket.xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE )
+ {
+ IPHeader_t *pxIPHeader = &(xProtPacket->xTCPPacket.xIPHeader);
+
+ /* Calculate the IP header checksum. */
+ pxIPHeader->usHeaderChecksum = 0x00;
+ pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
+ pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
+
+ /* Calculate the TCP checksum for an outgoing packet. */
+ usGenerateProtocolChecksum( ( uint8_t * ) apBuffer, pdTRUE );
+ }
+ }
+
+//#endif
+/*-----------------------------------------------------------*/
+
+static uint32_t prvEMACRxPoll( void )
+{
+unsigned char *pucUseBuffer;
+uint32_t ulReceiveCount, ulResult, ulReturnValue = 0;
+static NetworkBufferDescriptor_t *pxNextNetworkBufferDescriptor = NULL;
+const UBaseType_t xMinDescriptorsToLeave = 2UL;
+const TickType_t xBlockTime = pdMS_TO_TICKS( 100UL );
+static IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+
+ for( ;; )
+ {
+ /* If pxNextNetworkBufferDescriptor was not left pointing at a valid
+ descriptor then allocate one now. */
+ if( ( pxNextNetworkBufferDescriptor == NULL ) && ( uxGetNumberOfFreeNetworkBuffers() > xMinDescriptorsToLeave ) )
+ {
+ pxNextNetworkBufferDescriptor = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, xBlockTime );
+ }
+
+ if( pxNextNetworkBufferDescriptor != NULL )
+ {
+ /* Point pucUseBuffer to the buffer pointed to by the descriptor. */
+ pucUseBuffer = ( unsigned char* ) ( pxNextNetworkBufferDescriptor->pucEthernetBuffer - ipconfigPACKET_FILLER_SIZE );
+ }
+ else
+ {
+ /* As long as pxNextNetworkBufferDescriptor is NULL, the incoming
+ messages will be flushed and ignored. */
+ pucUseBuffer = NULL;
+ }
+
+ /* Read the next packet from the hardware into pucUseBuffer. */
+ ulResult = gmac_dev_read( &gs_gmac_dev, pucUseBuffer, ipTOTAL_ETHERNET_FRAME_SIZE, &ulReceiveCount );
+
+ if( ( ulResult != GMAC_OK ) || ( ulReceiveCount == 0 ) )
+ {
+ /* No data from the hardware. */
+ break;
+ }
+
+ if( pxNextNetworkBufferDescriptor == NULL )
+ {
+ /* Data was read from the hardware, but no descriptor was available
+ for it, so it will be dropped. */
+ iptraceETHERNET_RX_EVENT_LOST();
+ continue;
+ }
+
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ pxNextNetworkBufferDescriptor->xDataLength = ( size_t ) ulReceiveCount;
+ xRxEvent.pvData = ( void * ) pxNextNetworkBufferDescriptor;
+
+ /* Send the descriptor to the IP task for processing. */
+ if( xSendEventStructToIPTask( &xRxEvent, xBlockTime ) != pdTRUE )
+ {
+ /* The buffer could not be sent to the stack so must be released
+ again. */
+ vReleaseNetworkBufferAndDescriptor( pxNextNetworkBufferDescriptor );
+ iptraceETHERNET_RX_EVENT_LOST();
+ FreeRTOS_printf( ( "prvEMACRxPoll: Can not queue return packet!\n" ) );
+ }
+
+ /* Now the buffer has either been passed to the IP-task,
+ or it has been released in the code above. */
+ pxNextNetworkBufferDescriptor = NULL;
+ ulReturnValue++;
+ }
+
+ return ulReturnValue;
+}
+/*-----------------------------------------------------------*/
+
+static void prvEMACHandlerTask( void *pvParameters )
+{
+TimeOut_t xPhyTime;
+TickType_t xPhyRemTime;
+UBaseType_t uxLastMinBufferCount = 0, uxCount;
+UBaseType_t uxCurrentCount;
+#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ UBaseType_t uxLastMinQueueSpace;
+#endif
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ NetworkBufferDescriptor_t *pxBuffer;
+#endif
+uint8_t *pucBuffer;
+BaseType_t xResult = 0;
+uint32_t xStatus;
+const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+
+ configASSERT( xEMACTaskHandle );
+
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+
+ for( ;; )
+ {
+ 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( 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 */
+
+ if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
+ {
+ /* No events to process now, wait for the next. */
+ ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
+ }
+
+ if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
+ {
+ ulISREvents &= ~EMAC_IF_RX_EVENT;
+
+ /* Wait for the EMAC interrupt to indicate that another packet has been
+ received. */
+ xResult = prvEMACRxPoll();
+ }
+
+ if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
+ {
+ /* Future extension: code to release TX buffers if zero-copy is used. */
+ ulISREvents &= ~EMAC_IF_TX_EVENT;
+ while( xQueueReceive( xTxBufferQueue, &pucBuffer, 0 ) != pdFALSE )
+ {
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ pxBuffer = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
+ if( pxBuffer != NULL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxBuffer );
+ tx_release_count[ 0 ]++;
+ }
+ else
+ {
+ tx_release_count[ 1 ]++;
+ }
+ }
+ #else
+ {
+ tx_release_count[ 0 ]++;
+ }
+ #endif
+ uxCount = uxQueueMessagesWaiting( ( QueueHandle_t ) xTXDescriptorSemaphore );
+ if( uxCount < GMAC_TX_BUFFERS )
+ {
+ /* Tell the counting semaphore that one more TX descriptor is available. */
+ xSemaphoreGive( xTXDescriptorSemaphore );
+ }
+ }
+ }
+
+ if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
+ {
+ /* Future extension: logging about errors that occurred. */
+ ulISREvents &= ~EMAC_IF_ERR_EVENT;
+ }
+
+ if( xResult > 0 )
+ {
+ /* A packet was received. No need to check for the PHY status now,
+ but set a timer to check it later on. */
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ xResult = 0;
+ }
+ else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
+ {
+ /* Check the link status again. */
+ xStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
+ {
+ ulPHYLinkStatus = xStatus;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
+ }
+
+ vTaskSetTimeOutState( &xPhyTime );
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ }
+ else
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/component/gmac.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/component/gmac.h
index ae40ac960..6eb069f55 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/component/gmac.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/component/gmac.h
@@ -1,746 +1,746 @@
-/**
- * \file
- *
- * Copyright (c) 2012 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#ifndef _SAM4E_GMAC_COMPONENT_
-#define _SAM4E_GMAC_COMPONENT_
-
-/* ============================================================================= */
-/** SOFTWARE API DEFINITION FOR Gigabit Ethernet MAC */
-/* ============================================================================= */
-/** \addtogroup SAM4E_GMAC Gigabit Ethernet MAC */
-/*@{*/
-
-#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
-/** \brief GmacSa hardware registers */
-typedef struct {
- RwReg GMAC_SAB; /**< \brief (GmacSa Offset: 0x0) Specific Address 1 Bottom [31:0] Register */
- RwReg GMAC_SAT; /**< \brief (GmacSa Offset: 0x4) Specific Address 1 Top [47:32] Register */
-} GmacSa;
-/** \brief Gmac hardware registers */
-#define GMACSA_NUMBER 4
-typedef struct {
- RwReg GMAC_NCR; /**< \brief (Gmac Offset: 0x000) Network Control Register */
- RwReg GMAC_NCFGR; /**< \brief (Gmac Offset: 0x004) Network Configuration Register */
- RoReg GMAC_NSR; /**< \brief (Gmac Offset: 0x008) Network Status Register */
- RwReg GMAC_UR; /**< \brief (Gmac Offset: 0x00C) User Register */
- RwReg GMAC_DCFGR; /**< \brief (Gmac Offset: 0x010) DMA Configuration Register */
- RwReg GMAC_TSR; /**< \brief (Gmac Offset: 0x014) Transmit Status Register */
- RwReg GMAC_RBQB; /**< \brief (Gmac Offset: 0x018) Receive Buffer Queue Base Address */
- RwReg GMAC_TBQB; /**< \brief (Gmac Offset: 0x01C) Transmit Buffer Queue Base Address */
- RwReg GMAC_RSR; /**< \brief (Gmac Offset: 0x020) Receive Status Register */
- RoReg GMAC_ISR; /**< \brief (Gmac Offset: 0x024) Interrupt Status Register */
- WoReg GMAC_IER; /**< \brief (Gmac Offset: 0x028) Interrupt Enable Register */
- WoReg GMAC_IDR; /**< \brief (Gmac Offset: 0x02C) Interrupt Disable Register */
- RoReg GMAC_IMR; /**< \brief (Gmac Offset: 0x030) Interrupt Mask Register */
- RwReg GMAC_MAN; /**< \brief (Gmac Offset: 0x034) PHY Maintenance Register */
- RoReg GMAC_RPQ; /**< \brief (Gmac Offset: 0x038) Received Pause Quantum Register */
- RwReg GMAC_TPQ; /**< \brief (Gmac Offset: 0x03C) Transmit Pause Quantum Register */
- RwReg GMAC_TPSF; /**< \brief (Gmac Offset: 0x040) TX Partial Store and Forward Register */
- RwReg GMAC_RPSF; /**< \brief (Gmac Offset: 0x044) RX Partial Store and Forward Register */
- RoReg Reserved1[14];
- RwReg GMAC_HRB; /**< \brief (Gmac Offset: 0x080) Hash Register Bottom [31:0] */
- RwReg GMAC_HRT; /**< \brief (Gmac Offset: 0x084) Hash Register Top [63:32] */
- GmacSa GMAC_SA[GMACSA_NUMBER]; /**< \brief (Gmac Offset: 0x088) 1 .. 4 */
- RwReg GMAC_TIDM[4]; /**< \brief (Gmac Offset: 0x0A8) Type ID Match 1 Register */
- RwReg GMAC_WOL; /**< \brief (Gmac Offset: 0x0B8) Wake on LAN Register */
- RwReg GMAC_IPGS; /**< \brief (Gmac Offset: 0x0BC) IPG Stretch Register */
- RwReg GMAC_SVLAN; /**< \brief (Gmac Offset: 0x0C0) Stacked VLAN Register */
- RwReg GMAC_TPFCP; /**< \brief (Gmac Offset: 0x0C4) Transmit PFC Pause Register */
- RwReg GMAC_SAMB1; /**< \brief (Gmac Offset: 0x0C8) Specific Address 1 Mask Bottom [31:0] Register */
- RwReg GMAC_SAMT1; /**< \brief (Gmac Offset: 0x0CC) Specific Address 1 Mask Top [47:32] Register */
- RoReg Reserved2[12];
- RoReg GMAC_OTLO; /**< \brief (Gmac Offset: 0x100) Octets Transmitted [31:0] Register */
- RoReg GMAC_OTHI; /**< \brief (Gmac Offset: 0x104) Octets Transmitted [47:32] Register */
- RoReg GMAC_FT; /**< \brief (Gmac Offset: 0x108) Frames Transmitted Register */
- RoReg GMAC_BCFT; /**< \brief (Gmac Offset: 0x10C) Broadcast Frames Transmitted Register */
- RoReg GMAC_MFT; /**< \brief (Gmac Offset: 0x110) Multicast Frames Transmitted Register */
- RoReg GMAC_PFT; /**< \brief (Gmac Offset: 0x114) Pause Frames Transmitted Register */
- RoReg GMAC_BFT64; /**< \brief (Gmac Offset: 0x118) 64 Byte Frames Transmitted Register */
- RoReg GMAC_TBFT127; /**< \brief (Gmac Offset: 0x11C) 65 to 127 Byte Frames Transmitted Register */
- RoReg GMAC_TBFT255; /**< \brief (Gmac Offset: 0x120) 128 to 255 Byte Frames Transmitted Register */
- RoReg GMAC_TBFT511; /**< \brief (Gmac Offset: 0x124) 256 to 511 Byte Frames Transmitted Register */
- RoReg GMAC_TBFT1023; /**< \brief (Gmac Offset: 0x128) 512 to 1023 Byte Frames Transmitted Register */
- RoReg GMAC_TBFT1518; /**< \brief (Gmac Offset: 0x12C) 1024 to 1518 Byte Frames Transmitted Register */
- RoReg GMAC_GTBFT1518; /**< \brief (Gmac Offset: 0x130) Greater Than 1518 Byte Frames Transmitted Register */
- RoReg GMAC_TUR; /**< \brief (Gmac Offset: 0x134) Transmit Under Runs Register */
- RoReg GMAC_SCF; /**< \brief (Gmac Offset: 0x138) Single Collision Frames Register */
- RoReg GMAC_MCF; /**< \brief (Gmac Offset: 0x13C) Multiple Collision Frames Register */
- RoReg GMAC_EC; /**< \brief (Gmac Offset: 0x140) Excessive Collisions Register */
- RoReg GMAC_LC; /**< \brief (Gmac Offset: 0x144) Late Collisions Register */
- RoReg GMAC_DTF; /**< \brief (Gmac Offset: 0x148) Deferred Transmission Frames Register */
- RoReg GMAC_CSE; /**< \brief (Gmac Offset: 0x14C) Carrier Sense Errors Register */
- RoReg GMAC_ORLO; /**< \brief (Gmac Offset: 0x150) Octets Received [31:0] Received */
- RoReg GMAC_ORHI; /**< \brief (Gmac Offset: 0x154) Octets Received [47:32] Received */
- RoReg GMAC_FR; /**< \brief (Gmac Offset: 0x158) Frames Received Register */
- RoReg GMAC_BCFR; /**< \brief (Gmac Offset: 0x15C) Broadcast Frames Received Register */
- RoReg GMAC_MFR; /**< \brief (Gmac Offset: 0x160) Multicast Frames Received Register */
- RoReg GMAC_PFR; /**< \brief (Gmac Offset: 0x164) Pause Frames Received Register */
- RoReg GMAC_BFR64; /**< \brief (Gmac Offset: 0x168) 64 Byte Frames Received Register */
- RoReg GMAC_TBFR127; /**< \brief (Gmac Offset: 0x16C) 65 to 127 Byte Frames Received Register */
- RoReg GMAC_TBFR255; /**< \brief (Gmac Offset: 0x170) 128 to 255 Byte Frames Received Register */
- RoReg GMAC_TBFR511; /**< \brief (Gmac Offset: 0x174) 256 to 511Byte Frames Received Register */
- RoReg GMAC_TBFR1023; /**< \brief (Gmac Offset: 0x178) 512 to 1023 Byte Frames Received Register */
- RoReg GMAC_TBFR1518; /**< \brief (Gmac Offset: 0x17C) 1024 to 1518 Byte Frames Received Register */
- RoReg GMAC_TMXBFR; /**< \brief (Gmac Offset: 0x180) 1519 to Maximum Byte Frames Received Register */
- RoReg GMAC_UFR; /**< \brief (Gmac Offset: 0x184) Undersize Frames Received Register */
- RoReg GMAC_OFR; /**< \brief (Gmac Offset: 0x188) Oversize Frames Received Register */
- RoReg GMAC_JR; /**< \brief (Gmac Offset: 0x18C) Jabbers Received Register */
- RoReg GMAC_FCSE; /**< \brief (Gmac Offset: 0x190) Frame Check Sequence Errors Register */
- RoReg GMAC_LFFE; /**< \brief (Gmac Offset: 0x194) Length Field Frame Errors Register */
- RoReg GMAC_RSE; /**< \brief (Gmac Offset: 0x198) Receive Symbol Errors Register */
- RoReg GMAC_AE; /**< \brief (Gmac Offset: 0x19C) Alignment Errors Register */
- RoReg GMAC_RRE; /**< \brief (Gmac Offset: 0x1A0) Receive Resource Errors Register */
- RoReg GMAC_ROE; /**< \brief (Gmac Offset: 0x1A4) Receive Overrun Register */
- RoReg GMAC_IHCE; /**< \brief (Gmac Offset: 0x1A8) IP Header Checksum Errors Register */
- RoReg GMAC_TCE; /**< \brief (Gmac Offset: 0x1AC) TCP Checksum Errors Register */
- RoReg GMAC_UCE; /**< \brief (Gmac Offset: 0x1B0) UDP Checksum Errors Register */
- RoReg Reserved3[5];
- RwReg GMAC_TSSS; /**< \brief (Gmac Offset: 0x1C8) 1588 Timer Sync Strobe Seconds Register */
- RwReg GMAC_TSSN; /**< \brief (Gmac Offset: 0x1CC) 1588 Timer Sync Strobe Nanoseconds Register */
- RwReg GMAC_TS; /**< \brief (Gmac Offset: 0x1D0) 1588 Timer Seconds Register */
- RwReg GMAC_TN; /**< \brief (Gmac Offset: 0x1D4) 1588 Timer Nanoseconds Register */
- WoReg GMAC_TA; /**< \brief (Gmac Offset: 0x1D8) 1588 Timer Adjust Register */
- RwReg GMAC_TI; /**< \brief (Gmac Offset: 0x1DC) 1588 Timer Increment Register */
- RoReg GMAC_EFTS; /**< \brief (Gmac Offset: 0x1E0) PTP Event Frame Transmitted Seconds */
- RoReg GMAC_EFTN; /**< \brief (Gmac Offset: 0x1E4) PTP Event Frame Transmitted Nanoseconds */
- RoReg GMAC_EFRS; /**< \brief (Gmac Offset: 0x1E8) PTP Event Frame Received Seconds */
- RoReg GMAC_EFRN; /**< \brief (Gmac Offset: 0x1EC) PTP Event Frame Received Nanoseconds */
- RoReg GMAC_PEFTS; /**< \brief (Gmac Offset: 0x1F0) PTP Peer Event Frame Transmitted Seconds */
- RoReg GMAC_PEFTN; /**< \brief (Gmac Offset: 0x1F4) PTP Peer Event Frame Transmitted Nanoseconds */
- RoReg GMAC_PEFRS; /**< \brief (Gmac Offset: 0x1F8) PTP Peer Event Frame Received Seconds */
- RoReg GMAC_PEFRN; /**< \brief (Gmac Offset: 0x1FC) PTP Peer Event Frame Received Nanoseconds */
- RoReg Reserved4[128];
- RoReg GMAC_ISRPQ[7]; /**< \brief (Gmac Offset: 0x400) Interrupt Status Register Priority Queue */
- RoReg Reserved5[9];
- RwReg GMAC_TBQBAPQ[7]; /**< \brief (Gmac Offset: 0x440) Transmit Buffer Queue Base Address Priority Queue */
- RoReg Reserved6[9];
- RwReg GMAC_RBQBAPQ[7]; /**< \brief (Gmac Offset: 0x480) Receive Buffer Queue Base Address Priority Queue */
- RoReg Reserved7[1];
- RwReg GMAC_RBSRPQ[7]; /**< \brief (Gmac Offset: 0x4A0) Receive Buffer Size Register Priority Queue */
- RoReg Reserved8[17];
- RwReg GMAC_ST1RPQ[16]; /**< \brief (Gmac Offset: 0x500) Screening Type1 Register Priority Queue */
- RwReg GMAC_ST2RPQ[16]; /**< \brief (Gmac Offset: 0x540) Screening Type2 Register Priority Queue */
- RoReg Reserved9[32];
- WoReg GMAC_IERPQ[7]; /**< \brief (Gmac Offset: 0x600) Interrupt Enable Register Priority Queue */
- RoReg Reserved10[1];
- WoReg GMAC_IDRPQ[7]; /**< \brief (Gmac Offset: 0x620) Interrupt Disable Register Priority Queue */
- RoReg Reserved11[1];
- RwReg GMAC_IMRPQ[7]; /**< \brief (Gmac Offset: 0x640) Interrupt Mask Register Priority Queue */
-} Gmac;
-#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
-/* -------- GMAC_NCR : (GMAC Offset: 0x000) Network Control Register -------- */
-#define GMAC_NCR_LB (0x1u << 0) /**< \brief (GMAC_NCR) Loop Back */
-#define GMAC_NCR_LBL (0x1u << 1) /**< \brief (GMAC_NCR) Loop Back Local */
-#define GMAC_NCR_RXEN (0x1u << 2) /**< \brief (GMAC_NCR) Receive Enable */
-#define GMAC_NCR_TXEN (0x1u << 3) /**< \brief (GMAC_NCR) Transmit Enable */
-#define GMAC_NCR_MPE (0x1u << 4) /**< \brief (GMAC_NCR) Management Port Enable */
-#define GMAC_NCR_CLRSTAT (0x1u << 5) /**< \brief (GMAC_NCR) Clear Statistics Registers */
-#define GMAC_NCR_INCSTAT (0x1u << 6) /**< \brief (GMAC_NCR) Increment Statistics Registers */
-#define GMAC_NCR_WESTAT (0x1u << 7) /**< \brief (GMAC_NCR) Write Enable for Statistics Registers */
-#define GMAC_NCR_BP (0x1u << 8) /**< \brief (GMAC_NCR) Back pressure */
-#define GMAC_NCR_TSTART (0x1u << 9) /**< \brief (GMAC_NCR) Start Transmission */
-#define GMAC_NCR_THALT (0x1u << 10) /**< \brief (GMAC_NCR) Transmit Halt */
-#define GMAC_NCR_TXPF (0x1u << 11) /**< \brief (GMAC_NCR) Transmit Pause Frame */
-#define GMAC_NCR_TXZQPF (0x1u << 12) /**< \brief (GMAC_NCR) Transmit Zero Quantum Pause Frame */
-#define GMAC_NCR_RDS (0x1u << 14) /**< \brief (GMAC_NCR) Read Snapshot */
-#define GMAC_NCR_SRTSM (0x1u << 15) /**< \brief (GMAC_NCR) Store Receive Time Stamp to Memory */
-#define GMAC_NCR_ENPBPR (0x1u << 16) /**< \brief (GMAC_NCR) Enable PFC Priority-based Pause Reception */
-#define GMAC_NCR_TXPBPF (0x1u << 17) /**< \brief (GMAC_NCR) Transmit PFC Priority-based Pause Frame */
-#define GMAC_NCR_FNP (0x1u << 18) /**< \brief (GMAC_NCR) Flush Next Packet */
-/* -------- GMAC_NCFGR : (GMAC Offset: 0x004) Network Configuration Register -------- */
-#define GMAC_NCFGR_SPD (0x1u << 0) /**< \brief (GMAC_NCFGR) Speed */
-#define GMAC_NCFGR_FD (0x1u << 1) /**< \brief (GMAC_NCFGR) Full Duplex */
-#define GMAC_NCFGR_DNVLAN (0x1u << 2) /**< \brief (GMAC_NCFGR) Discard Non-VLAN FRAMES */
-#define GMAC_NCFGR_JFRAME (0x1u << 3) /**< \brief (GMAC_NCFGR) Jumbo Frame Size */
-#define GMAC_NCFGR_CAF (0x1u << 4) /**< \brief (GMAC_NCFGR) Copy All Frames */
-#define GMAC_NCFGR_NBC (0x1u << 5) /**< \brief (GMAC_NCFGR) No Broadcast */
-#define GMAC_NCFGR_MTIHEN (0x1u << 6) /**< \brief (GMAC_NCFGR) Multicast Hash Enable */
-#define GMAC_NCFGR_UNIHEN (0x1u << 7) /**< \brief (GMAC_NCFGR) Unicast Hash Enable */
-#define GMAC_NCFGR_MAXFS (0x1u << 8) /**< \brief (GMAC_NCFGR) 1536 Maximum Frame Size */
-#define GMAC_NCFGR_GBE (0x1u << 10) /**< \brief (GMAC_NCFGR) Gigabit Mode Enable */
-#define GMAC_NCFGR_PIS (0x1u << 11) /**< \brief (GMAC_NCFGR) Physical Interface Select */
-#define GMAC_NCFGR_RTY (0x1u << 12) /**< \brief (GMAC_NCFGR) Retry Test */
-#define GMAC_NCFGR_PEN (0x1u << 13) /**< \brief (GMAC_NCFGR) Pause Enable */
-#define GMAC_NCFGR_RXBUFO_Pos 14
-#define GMAC_NCFGR_RXBUFO_Msk (0x3u << GMAC_NCFGR_RXBUFO_Pos) /**< \brief (GMAC_NCFGR) Receive Buffer Offset */
-#define GMAC_NCFGR_RXBUFO(value) ((GMAC_NCFGR_RXBUFO_Msk & ((value) << GMAC_NCFGR_RXBUFO_Pos)))
-#define GMAC_NCFGR_LFERD (0x1u << 16) /**< \brief (GMAC_NCFGR) Length Field Error Frame Discard */
-#define GMAC_NCFGR_RFCS (0x1u << 17) /**< \brief (GMAC_NCFGR) Remove FCS */
-#define GMAC_NCFGR_CLK_Pos 18
-#define GMAC_NCFGR_CLK_Msk (0x7u << GMAC_NCFGR_CLK_Pos) /**< \brief (GMAC_NCFGR) MDC CLock Division */
-#define GMAC_NCFGR_CLK_MCK_8 (0x0u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 8 (MCK up to 20 MHz) */
-#define GMAC_NCFGR_CLK_MCK_16 (0x1u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 16 (MCK up to 40 MHz) */
-#define GMAC_NCFGR_CLK_MCK_32 (0x2u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 32 (MCK up to 80 MHz) */
-#define GMAC_NCFGR_CLK_MCK_48 (0x3u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 48 (MCK up to 120MHz) */
-#define GMAC_NCFGR_CLK_MCK_64 (0x4u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 64 (MCK up to 160 MHz) */
-#define GMAC_NCFGR_CLK_MCK_96 (0x5u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 96 (MCK up to 240 MHz) */
-#define GMAC_NCFGR_CLK_MCK_128 (0x6u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 128 (MCK up to 320 MHz) */
-#define GMAC_NCFGR_CLK_MCK_224 (0x7u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 224 (MCK up to 540 MHz) */
-#define GMAC_NCFGR_DBW_Pos 21
-#define GMAC_NCFGR_DBW_Msk (0x3u << GMAC_NCFGR_DBW_Pos) /**< \brief (GMAC_NCFGR) Data Bus Width */
-#define GMAC_NCFGR_DBW_DBW32 (0x0u << 21) /**< \brief (GMAC_NCFGR) 32-bit data bus width */
-#define GMAC_NCFGR_DBW_DBW64 (0x1u << 21) /**< \brief (GMAC_NCFGR) 64-bit data bus width */
-#define GMAC_NCFGR_DCPF (0x1u << 23) /**< \brief (GMAC_NCFGR) Disable Copy of Pause Frames */
-#define GMAC_NCFGR_RXCOEN (0x1u << 24) /**< \brief (GMAC_NCFGR) Receive Checksum Offload Enable */
-#define GMAC_NCFGR_EFRHD (0x1u << 25) /**< \brief (GMAC_NCFGR) Enable Frames Received in Half Duplex */
-#define GMAC_NCFGR_IRXFCS (0x1u << 26) /**< \brief (GMAC_NCFGR) Ignore RX FCS */
-#define GMAC_NCFGR_IPGSEN (0x1u << 28) /**< \brief (GMAC_NCFGR) IP Stretch Enable */
-#define GMAC_NCFGR_RXBP (0x1u << 29) /**< \brief (GMAC_NCFGR) Receive Bad Preamble */
-#define GMAC_NCFGR_IRXER (0x1u << 30) /**< \brief (GMAC_NCFGR) Ignore IPG rx_er */
-/* -------- GMAC_NSR : (GMAC Offset: 0x008) Network Status Register -------- */
-#define GMAC_NSR_MDIO (0x1u << 1) /**< \brief (GMAC_NSR) MDIO Input Status */
-#define GMAC_NSR_IDLE (0x1u << 2) /**< \brief (GMAC_NSR) PHY Management Logic Idle */
-/* -------- GMAC_UR : (GMAC Offset: 0x00C) User Register -------- */
-#define GMAC_UR_RGMII (0x1u << 0) /**< \brief (GMAC_UR) RGMII Mode */
-#define GMAC_UR_HDFC (0x1u << 6) /**< \brief (GMAC_UR) Half Duplex Flow Control */
-#define GMAC_UR_BPDG (0x1u << 7) /**< \brief (GMAC_UR) BPDG Bypass Deglitchers */
-/* -------- GMAC_DCFGR : (GMAC Offset: 0x010) DMA Configuration Register -------- */
-#define GMAC_DCFGR_FBLDO_Pos 0
-#define GMAC_DCFGR_FBLDO_Msk (0x1fu << GMAC_DCFGR_FBLDO_Pos) /**< \brief (GMAC_DCFGR) Fixed Burst Length for DMA Data Operations: */
-#define GMAC_DCFGR_FBLDO_SINGLE (0x1u << 0) /**< \brief (GMAC_DCFGR) 00001: Always use SINGLE AHB bursts */
-#define GMAC_DCFGR_FBLDO_INCR4 (0x4u << 0) /**< \brief (GMAC_DCFGR) 001xx: Attempt to use INCR4 AHB bursts (Default) */
-#define GMAC_DCFGR_FBLDO_INCR8 (0x8u << 0) /**< \brief (GMAC_DCFGR) 01xxx: Attempt to use INCR8 AHB bursts */
-#define GMAC_DCFGR_FBLDO_INCR16 (0x10u << 0) /**< \brief (GMAC_DCFGR) 1xxxx: Attempt to use INCR16 AHB bursts */
-#define GMAC_DCFGR_ESMA (0x1u << 6) /**< \brief (GMAC_DCFGR) Endian Swap Mode Enable for Management Descriptor Accesses */
-#define GMAC_DCFGR_ESPA (0x1u << 7) /**< \brief (GMAC_DCFGR) Endian Swap Mode Enable for Packet Data Accesses */
-#define GMAC_DCFGR_RXBMS_Pos 8
-#define GMAC_DCFGR_RXBMS_Msk (0x3u << GMAC_DCFGR_RXBMS_Pos) /**< \brief (GMAC_DCFGR) Receiver Packet Buffer Memory Size Select */
-#define GMAC_DCFGR_RXBMS_EIGHTH (0x0u << 8) /**< \brief (GMAC_DCFGR) 1 Kbyte Memory Size */
-#define GMAC_DCFGR_RXBMS_QUARTER (0x1u << 8) /**< \brief (GMAC_DCFGR) 2 Kbytes Memory Size */
-#define GMAC_DCFGR_RXBMS_HALF (0x2u << 8) /**< \brief (GMAC_DCFGR) 4 Kbytes Memory Size */
-#define GMAC_DCFGR_RXBMS_FULL (0x3u << 8) /**< \brief (GMAC_DCFGR) 8 Kbytes Memory Size */
-#define GMAC_DCFGR_TXPBMS (0x1u << 10) /**< \brief (GMAC_DCFGR) Transmitter Packet Buffer Memory Size Select */
-#define GMAC_DCFGR_TXCOEN (0x1u << 11) /**< \brief (GMAC_DCFGR) Transmitter Checksum Generation Offload Enable */
-#define GMAC_DCFGR_DRBS_Pos 16
-#define GMAC_DCFGR_DRBS_Msk (0xffu << GMAC_DCFGR_DRBS_Pos) /**< \brief (GMAC_DCFGR) DMA Receive Buffer Size */
-#define GMAC_DCFGR_DRBS(value) ((GMAC_DCFGR_DRBS_Msk & ((value) << GMAC_DCFGR_DRBS_Pos)))
-#define GMAC_DCFGR_DDRP (0x1u << 24) /**< \brief (GMAC_DCFGR) DMA Discard Receive Packets */
-/* -------- GMAC_TSR : (GMAC Offset: 0x014) Transmit Status Register -------- */
-#define GMAC_TSR_UBR (0x1u << 0) /**< \brief (GMAC_TSR) Used Bit Read */
-#define GMAC_TSR_COL (0x1u << 1) /**< \brief (GMAC_TSR) Collision Occurred */
-#define GMAC_TSR_RLE (0x1u << 2) /**< \brief (GMAC_TSR) Retry Limit Exceeded */
-#define GMAC_TSR_TXGO (0x1u << 3) /**< \brief (GMAC_TSR) Transmit Go */
-#define GMAC_TSR_TFC (0x1u << 4) /**< \brief (GMAC_TSR) Transmit Frame Corruption due to AHB error */
-#define GMAC_TSR_TXCOMP (0x1u << 5) /**< \brief (GMAC_TSR) Transmit Complete */
-#define GMAC_TSR_UND (0x1u << 6) /**< \brief (GMAC_TSR) Transmit Under Run */
-#define GMAC_TSR_LCO (0x1u << 7) /**< \brief (GMAC_TSR) Late Collision Occurred */
-#define GMAC_TSR_HRESP (0x1u << 8) /**< \brief (GMAC_TSR) HRESP Not OK */
-/* -------- GMAC_RBQB : (GMAC Offset: 0x018) Receive Buffer Queue Base Address -------- */
-#define GMAC_RBQB_ADDR_Pos 2
-#define GMAC_RBQB_ADDR_Msk (0x3fffffffu << GMAC_RBQB_ADDR_Pos) /**< \brief (GMAC_RBQB) Receive buffer queue base address */
-#define GMAC_RBQB_ADDR(value) ((GMAC_RBQB_ADDR_Msk & ((value) << GMAC_RBQB_ADDR_Pos)))
-/* -------- GMAC_TBQB : (GMAC Offset: 0x01C) Transmit Buffer Queue Base Address -------- */
-#define GMAC_TBQB_ADDR_Pos 2
-#define GMAC_TBQB_ADDR_Msk (0x3fffffffu << GMAC_TBQB_ADDR_Pos) /**< \brief (GMAC_TBQB) Transmit Buffer Queue Base Address */
-#define GMAC_TBQB_ADDR(value) ((GMAC_TBQB_ADDR_Msk & ((value) << GMAC_TBQB_ADDR_Pos)))
-/* -------- GMAC_RSR : (GMAC Offset: 0x020) Receive Status Register -------- */
-#define GMAC_RSR_BNA (0x1u << 0) /**< \brief (GMAC_RSR) Buffer Not Available */
-#define GMAC_RSR_REC (0x1u << 1) /**< \brief (GMAC_RSR) Frame Received */
-#define GMAC_RSR_RXOVR (0x1u << 2) /**< \brief (GMAC_RSR) Receive Overrun */
-#define GMAC_RSR_HNO (0x1u << 3) /**< \brief (GMAC_RSR) HRESP Not OK */
-/* -------- GMAC_ISR : (GMAC Offset: 0x024) Interrupt Status Register -------- */
-#define GMAC_ISR_MFS (0x1u << 0) /**< \brief (GMAC_ISR) Management Frame Sent */
-#define GMAC_ISR_RCOMP (0x1u << 1) /**< \brief (GMAC_ISR) Receive Complete */
-#define GMAC_ISR_RXUBR (0x1u << 2) /**< \brief (GMAC_ISR) RX Used Bit Read */
-#define GMAC_ISR_TXUBR (0x1u << 3) /**< \brief (GMAC_ISR) TX Used Bit Read */
-#define GMAC_ISR_TUR (0x1u << 4) /**< \brief (GMAC_ISR) Transmit Under Run */
-#define GMAC_ISR_RLEX (0x1u << 5) /**< \brief (GMAC_ISR) Retry Limit Exceeded or Late Collision */
-#define GMAC_ISR_TFC (0x1u << 6) /**< \brief (GMAC_ISR) Transmit Frame Corruption due to AHB error */
-#define GMAC_ISR_TCOMP (0x1u << 7) /**< \brief (GMAC_ISR) Transmit Complete */
-#define GMAC_ISR_ROVR (0x1u << 10) /**< \brief (GMAC_ISR) Receive Overrun */
-#define GMAC_ISR_HRESP (0x1u << 11) /**< \brief (GMAC_ISR) HRESP Not OK */
-#define GMAC_ISR_PFNZ (0x1u << 12) /**< \brief (GMAC_ISR) Pause Frame with Non-zero Pause Quantum Received */
-#define GMAC_ISR_PTZ (0x1u << 13) /**< \brief (GMAC_ISR) Pause Time Zero */
-#define GMAC_ISR_PFTR (0x1u << 14) /**< \brief (GMAC_ISR) Pause Frame Transmitted */
-#define GMAC_ISR_EXINT (0x1u << 15) /**< \brief (GMAC_ISR) External Interrupt */
-#define GMAC_ISR_DRQFR (0x1u << 18) /**< \brief (GMAC_ISR) PTP Delay Request Frame Received */
-#define GMAC_ISR_SFR (0x1u << 19) /**< \brief (GMAC_ISR) PTP Sync Frame Received */
-#define GMAC_ISR_DRQFT (0x1u << 20) /**< \brief (GMAC_ISR) PTP Delay Request Frame Transmitted */
-#define GMAC_ISR_SFT (0x1u << 21) /**< \brief (GMAC_ISR) PTP Sync Frame Transmitted */
-#define GMAC_ISR_PDRQFR (0x1u << 22) /**< \brief (GMAC_ISR) PDelay Request Frame Received */
-#define GMAC_ISR_PDRSFR (0x1u << 23) /**< \brief (GMAC_ISR) PDelay Response Frame Received */
-#define GMAC_ISR_PDRQFT (0x1u << 24) /**< \brief (GMAC_ISR) PDelay Request Frame Transmitted */
-#define GMAC_ISR_PDRSFT (0x1u << 25) /**< \brief (GMAC_ISR) PDelay Response Frame Transmitted */
-#define GMAC_ISR_SRI (0x1u << 26) /**< \brief (GMAC_ISR) TSU Seconds Register Increment */
-#define GMAC_ISR_WOL (0x1u << 28) /**< \brief (GMAC_ISR) Wake On LAN */
-/* -------- GMAC_IER : (GMAC Offset: 0x028) Interrupt Enable Register -------- */
-#define GMAC_IER_MFS (0x1u << 0) /**< \brief (GMAC_IER) Management Frame Sent */
-#define GMAC_IER_RCOMP (0x1u << 1) /**< \brief (GMAC_IER) Receive Complete */
-#define GMAC_IER_RXUBR (0x1u << 2) /**< \brief (GMAC_IER) RX Used Bit Read */
-#define GMAC_IER_TXUBR (0x1u << 3) /**< \brief (GMAC_IER) TX Used Bit Read */
-#define GMAC_IER_TUR (0x1u << 4) /**< \brief (GMAC_IER) Transmit Under Run */
-#define GMAC_IER_RLEX (0x1u << 5) /**< \brief (GMAC_IER) Retry Limit Exceeded or Late Collision */
-#define GMAC_IER_TFC (0x1u << 6) /**< \brief (GMAC_IER) Transmit Frame Corruption due to AHB error */
-#define GMAC_IER_TCOMP (0x1u << 7) /**< \brief (GMAC_IER) Transmit Complete */
-#define GMAC_IER_ROVR (0x1u << 10) /**< \brief (GMAC_IER) Receive Overrun */
-#define GMAC_IER_HRESP (0x1u << 11) /**< \brief (GMAC_IER) HRESP Not OK */
-#define GMAC_IER_PFNZ (0x1u << 12) /**< \brief (GMAC_IER) Pause Frame with Non-zero Pause Quantum Received */
-#define GMAC_IER_PTZ (0x1u << 13) /**< \brief (GMAC_IER) Pause Time Zero */
-#define GMAC_IER_PFTR (0x1u << 14) /**< \brief (GMAC_IER) Pause Frame Transmitted */
-#define GMAC_IER_EXINT (0x1u << 15) /**< \brief (GMAC_IER) External Interrupt */
-#define GMAC_IER_DRQFR (0x1u << 18) /**< \brief (GMAC_IER) PTP Delay Request Frame Received */
-#define GMAC_IER_SFR (0x1u << 19) /**< \brief (GMAC_IER) PTP Sync Frame Received */
-#define GMAC_IER_DRQFT (0x1u << 20) /**< \brief (GMAC_IER) PTP Delay Request Frame Transmitted */
-#define GMAC_IER_SFT (0x1u << 21) /**< \brief (GMAC_IER) PTP Sync Frame Transmitted */
-#define GMAC_IER_PDRQFR (0x1u << 22) /**< \brief (GMAC_IER) PDelay Request Frame Received */
-#define GMAC_IER_PDRSFR (0x1u << 23) /**< \brief (GMAC_IER) PDelay Response Frame Received */
-#define GMAC_IER_PDRQFT (0x1u << 24) /**< \brief (GMAC_IER) PDelay Request Frame Transmitted */
-#define GMAC_IER_PDRSFT (0x1u << 25) /**< \brief (GMAC_IER) PDelay Response Frame Transmitted */
-#define GMAC_IER_SRI (0x1u << 26) /**< \brief (GMAC_IER) TSU Seconds Register Increment */
-#define GMAC_IER_WOL (0x1u << 28) /**< \brief (GMAC_IER) Wake On LAN */
-/* -------- GMAC_IDR : (GMAC Offset: 0x02C) Interrupt Disable Register -------- */
-#define GMAC_IDR_MFS (0x1u << 0) /**< \brief (GMAC_IDR) Management Frame Sent */
-#define GMAC_IDR_RCOMP (0x1u << 1) /**< \brief (GMAC_IDR) Receive Complete */
-#define GMAC_IDR_RXUBR (0x1u << 2) /**< \brief (GMAC_IDR) RX Used Bit Read */
-#define GMAC_IDR_TXUBR (0x1u << 3) /**< \brief (GMAC_IDR) TX Used Bit Read */
-#define GMAC_IDR_TUR (0x1u << 4) /**< \brief (GMAC_IDR) Transmit Under Run */
-#define GMAC_IDR_RLEX (0x1u << 5) /**< \brief (GMAC_IDR) Retry Limit Exceeded or Late Collision */
-#define GMAC_IDR_TFC (0x1u << 6) /**< \brief (GMAC_IDR) Transmit Frame Corruption due to AHB error */
-#define GMAC_IDR_TCOMP (0x1u << 7) /**< \brief (GMAC_IDR) Transmit Complete */
-#define GMAC_IDR_ROVR (0x1u << 10) /**< \brief (GMAC_IDR) Receive Overrun */
-#define GMAC_IDR_HRESP (0x1u << 11) /**< \brief (GMAC_IDR) HRESP Not OK */
-#define GMAC_IDR_PFNZ (0x1u << 12) /**< \brief (GMAC_IDR) Pause Frame with Non-zero Pause Quantum Received */
-#define GMAC_IDR_PTZ (0x1u << 13) /**< \brief (GMAC_IDR) Pause Time Zero */
-#define GMAC_IDR_PFTR (0x1u << 14) /**< \brief (GMAC_IDR) Pause Frame Transmitted */
-#define GMAC_IDR_EXINT (0x1u << 15) /**< \brief (GMAC_IDR) External Interrupt */
-#define GMAC_IDR_DRQFR (0x1u << 18) /**< \brief (GMAC_IDR) PTP Delay Request Frame Received */
-#define GMAC_IDR_SFR (0x1u << 19) /**< \brief (GMAC_IDR) PTP Sync Frame Received */
-#define GMAC_IDR_DRQFT (0x1u << 20) /**< \brief (GMAC_IDR) PTP Delay Request Frame Transmitted */
-#define GMAC_IDR_SFT (0x1u << 21) /**< \brief (GMAC_IDR) PTP Sync Frame Transmitted */
-#define GMAC_IDR_PDRQFR (0x1u << 22) /**< \brief (GMAC_IDR) PDelay Request Frame Received */
-#define GMAC_IDR_PDRSFR (0x1u << 23) /**< \brief (GMAC_IDR) PDelay Response Frame Received */
-#define GMAC_IDR_PDRQFT (0x1u << 24) /**< \brief (GMAC_IDR) PDelay Request Frame Transmitted */
-#define GMAC_IDR_PDRSFT (0x1u << 25) /**< \brief (GMAC_IDR) PDelay Response Frame Transmitted */
-#define GMAC_IDR_SRI (0x1u << 26) /**< \brief (GMAC_IDR) TSU Seconds Register Increment */
-#define GMAC_IDR_WOL (0x1u << 28) /**< \brief (GMAC_IDR) Wake On LAN */
-/* -------- GMAC_IMR : (GMAC Offset: 0x030) Interrupt Mask Register -------- */
-#define GMAC_IMR_MFS (0x1u << 0) /**< \brief (GMAC_IMR) Management Frame Sent */
-#define GMAC_IMR_RCOMP (0x1u << 1) /**< \brief (GMAC_IMR) Receive Complete */
-#define GMAC_IMR_RXUBR (0x1u << 2) /**< \brief (GMAC_IMR) RX Used Bit Read */
-#define GMAC_IMR_TXUBR (0x1u << 3) /**< \brief (GMAC_IMR) TX Used Bit Read */
-#define GMAC_IMR_TUR (0x1u << 4) /**< \brief (GMAC_IMR) Transmit Under Run */
-#define GMAC_IMR_RLEX (0x1u << 5) /**< \brief (GMAC_IMR) Retry Limit Exceeded or Late Collision */
-#define GMAC_IMR_TFC (0x1u << 6) /**< \brief (GMAC_IMR) Transmit Frame Corruption due to AHB error */
-#define GMAC_IMR_TCOMP (0x1u << 7) /**< \brief (GMAC_IMR) Transmit Complete */
-#define GMAC_IMR_ROVR (0x1u << 10) /**< \brief (GMAC_IMR) Receive Overrun */
-#define GMAC_IMR_HRESP (0x1u << 11) /**< \brief (GMAC_IMR) HRESP Not OK */
-#define GMAC_IMR_PFNZ (0x1u << 12) /**< \brief (GMAC_IMR) Pause Frame with Non-zero Pause Quantum Received */
-#define GMAC_IMR_PTZ (0x1u << 13) /**< \brief (GMAC_IMR) Pause Time Zero */
-#define GMAC_IMR_PFTR (0x1u << 14) /**< \brief (GMAC_IMR) Pause Frame Transmitted */
-#define GMAC_IMR_EXINT (0x1u << 15) /**< \brief (GMAC_IMR) External Interrupt */
-#define GMAC_IMR_DRQFR (0x1u << 18) /**< \brief (GMAC_IMR) PTP Delay Request Frame Received */
-#define GMAC_IMR_SFR (0x1u << 19) /**< \brief (GMAC_IMR) PTP Sync Frame Received */
-#define GMAC_IMR_DRQFT (0x1u << 20) /**< \brief (GMAC_IMR) PTP Delay Request Frame Transmitted */
-#define GMAC_IMR_SFT (0x1u << 21) /**< \brief (GMAC_IMR) PTP Sync Frame Transmitted */
-#define GMAC_IMR_PDRQFR (0x1u << 22) /**< \brief (GMAC_IMR) PDelay Request Frame Received */
-#define GMAC_IMR_PDRSFR (0x1u << 23) /**< \brief (GMAC_IMR) PDelay Response Frame Received */
-#define GMAC_IMR_PDRQFT (0x1u << 24) /**< \brief (GMAC_IMR) PDelay Request Frame Transmitted */
-#define GMAC_IMR_PDRSFT (0x1u << 25) /**< \brief (GMAC_IMR) PDelay Response Frame Transmitted */
-/* -------- GMAC_MAN : (GMAC Offset: 0x034) PHY Maintenance Register -------- */
-#define GMAC_MAN_DATA_Pos 0
-#define GMAC_MAN_DATA_Msk (0xffffu << GMAC_MAN_DATA_Pos) /**< \brief (GMAC_MAN) PHY Data */
-#define GMAC_MAN_DATA(value) ((GMAC_MAN_DATA_Msk & ((value) << GMAC_MAN_DATA_Pos)))
-#define GMAC_MAN_WTN_Pos 16
-#define GMAC_MAN_WTN_Msk (0x3u << GMAC_MAN_WTN_Pos) /**< \brief (GMAC_MAN) Write Ten */
-#define GMAC_MAN_WTN(value) ((GMAC_MAN_WTN_Msk & ((value) << GMAC_MAN_WTN_Pos)))
-#define GMAC_MAN_REGA_Pos 18
-#define GMAC_MAN_REGA_Msk (0x1fu << GMAC_MAN_REGA_Pos) /**< \brief (GMAC_MAN) Register Address */
-#define GMAC_MAN_REGA(value) ((GMAC_MAN_REGA_Msk & ((value) << GMAC_MAN_REGA_Pos)))
-#define GMAC_MAN_PHYA_Pos 23
-#define GMAC_MAN_PHYA_Msk (0x1fu << GMAC_MAN_PHYA_Pos) /**< \brief (GMAC_MAN) PHY Address */
-#define GMAC_MAN_PHYA(value) ((GMAC_MAN_PHYA_Msk & ((value) << GMAC_MAN_PHYA_Pos)))
-#define GMAC_MAN_OP_Pos 28
-#define GMAC_MAN_OP_Msk (0x3u << GMAC_MAN_OP_Pos) /**< \brief (GMAC_MAN) Operation */
-#define GMAC_MAN_OP(value) ((GMAC_MAN_OP_Msk & ((value) << GMAC_MAN_OP_Pos)))
-#define GMAC_MAN_CLTTO (0x1u << 30) /**< \brief (GMAC_MAN) Clause 22 Operation */
-#define GMAC_MAN_WZO (0x1u << 31) /**< \brief (GMAC_MAN) Write ZERO */
-/* -------- GMAC_RPQ : (GMAC Offset: 0x038) Received Pause Quantum Register -------- */
-#define GMAC_RPQ_RPQ_Pos 0
-#define GMAC_RPQ_RPQ_Msk (0xffffu << GMAC_RPQ_RPQ_Pos) /**< \brief (GMAC_RPQ) Received Pause Quantum */
-/* -------- GMAC_TPQ : (GMAC Offset: 0x03C) Transmit Pause Quantum Register -------- */
-#define GMAC_TPQ_TPQ_Pos 0
-#define GMAC_TPQ_TPQ_Msk (0xffffu << GMAC_TPQ_TPQ_Pos) /**< \brief (GMAC_TPQ) Transmit Pause Quantum */
-#define GMAC_TPQ_TPQ(value) ((GMAC_TPQ_TPQ_Msk & ((value) << GMAC_TPQ_TPQ_Pos)))
-/* -------- GMAC_TPSF : (GMAC Offset: 0x040) TX Partial Store and Forward Register -------- */
-#define GMAC_TPSF_TPB1ADR_Pos 0
-#define GMAC_TPSF_TPB1ADR_Msk (0xfffu << GMAC_TPSF_TPB1ADR_Pos) /**< \brief (GMAC_TPSF) tx_pbuf_addr-1:0 */
-#define GMAC_TPSF_TPB1ADR(value) ((GMAC_TPSF_TPB1ADR_Msk & ((value) << GMAC_TPSF_TPB1ADR_Pos)))
-#define GMAC_TPSF_ENTXP (0x1u << 31) /**< \brief (GMAC_TPSF) Enable TX Partial Store and Forward Operation */
-/* -------- GMAC_RPSF : (GMAC Offset: 0x044) RX Partial Store and Forward Register -------- */
-#define GMAC_RPSF_RPB1ADR_Pos 0
-#define GMAC_RPSF_RPB1ADR_Msk (0xfffu << GMAC_RPSF_RPB1ADR_Pos) /**< \brief (GMAC_RPSF) rx_pbuf_addr-1:0 */
-#define GMAC_RPSF_RPB1ADR(value) ((GMAC_RPSF_RPB1ADR_Msk & ((value) << GMAC_RPSF_RPB1ADR_Pos)))
-#define GMAC_RPSF_ENRXP (0x1u << 31) /**< \brief (GMAC_RPSF) Enable RX Partial Store and Forward Operation */
-/* -------- GMAC_HRB : (GMAC Offset: 0x080) Hash Register Bottom [31:0] -------- */
-#define GMAC_HRB_ADDR_Pos 0
-#define GMAC_HRB_ADDR_Msk (0xffffffffu << GMAC_HRB_ADDR_Pos) /**< \brief (GMAC_HRB) Hash Address */
-#define GMAC_HRB_ADDR(value) ((GMAC_HRB_ADDR_Msk & ((value) << GMAC_HRB_ADDR_Pos)))
-/* -------- GMAC_HRT : (GMAC Offset: 0x084) Hash Register Top [63:32] -------- */
-#define GMAC_HRT_ADDR_Pos 0
-#define GMAC_HRT_ADDR_Msk (0xffffffffu << GMAC_HRT_ADDR_Pos) /**< \brief (GMAC_HRT) Hash Address */
-#define GMAC_HRT_ADDR(value) ((GMAC_HRT_ADDR_Msk & ((value) << GMAC_HRT_ADDR_Pos)))
-/* -------- GMAC_SAB1 : (GMAC Offset: 0x088) Specific Address 1 Bottom [31:0] Register -------- */
-#define GMAC_SAB1_ADDR_Pos 0
-#define GMAC_SAB1_ADDR_Msk (0xffffffffu << GMAC_SAB1_ADDR_Pos) /**< \brief (GMAC_SAB1) Specific Address 1 */
-#define GMAC_SAB1_ADDR(value) ((GMAC_SAB1_ADDR_Msk & ((value) << GMAC_SAB1_ADDR_Pos)))
-/* -------- GMAC_SAT1 : (GMAC Offset: 0x08C) Specific Address 1 Top [47:32] Register -------- */
-#define GMAC_SAT1_ADDR_Pos 0
-#define GMAC_SAT1_ADDR_Msk (0xffffu << GMAC_SAT1_ADDR_Pos) /**< \brief (GMAC_SAT1) Specific Address 1 */
-#define GMAC_SAT1_ADDR(value) ((GMAC_SAT1_ADDR_Msk & ((value) << GMAC_SAT1_ADDR_Pos)))
-/* -------- GMAC_SAB2 : (GMAC Offset: 0x090) Specific Address 2 Bottom [31:0] Register -------- */
-#define GMAC_SAB2_ADDR_Pos 0
-#define GMAC_SAB2_ADDR_Msk (0xffffffffu << GMAC_SAB2_ADDR_Pos) /**< \brief (GMAC_SAB2) Specific Address 2 */
-#define GMAC_SAB2_ADDR(value) ((GMAC_SAB2_ADDR_Msk & ((value) << GMAC_SAB2_ADDR_Pos)))
-/* -------- GMAC_SAT2 : (GMAC Offset: 0x094) Specific Address 2 Top [47:32] Register -------- */
-#define GMAC_SAT2_ADDR_Pos 0
-#define GMAC_SAT2_ADDR_Msk (0xffffu << GMAC_SAT2_ADDR_Pos) /**< \brief (GMAC_SAT2) Specific Address 2 */
-#define GMAC_SAT2_ADDR(value) ((GMAC_SAT2_ADDR_Msk & ((value) << GMAC_SAT2_ADDR_Pos)))
-/* -------- GMAC_SAB3 : (GMAC Offset: 0x098) Specific Address 3 Bottom [31:0] Register -------- */
-#define GMAC_SAB3_ADDR_Pos 0
-#define GMAC_SAB3_ADDR_Msk (0xffffffffu << GMAC_SAB3_ADDR_Pos) /**< \brief (GMAC_SAB3) Specific Address 3 */
-#define GMAC_SAB3_ADDR(value) ((GMAC_SAB3_ADDR_Msk & ((value) << GMAC_SAB3_ADDR_Pos)))
-/* -------- GMAC_SAT3 : (GMAC Offset: 0x09C) Specific Address 3 Top [47:32] Register -------- */
-#define GMAC_SAT3_ADDR_Pos 0
-#define GMAC_SAT3_ADDR_Msk (0xffffu << GMAC_SAT3_ADDR_Pos) /**< \brief (GMAC_SAT3) Specific Address 3 */
-#define GMAC_SAT3_ADDR(value) ((GMAC_SAT3_ADDR_Msk & ((value) << GMAC_SAT3_ADDR_Pos)))
-/* -------- GMAC_SAB4 : (GMAC Offset: 0x0A0) Specific Address 4 Bottom [31:0] Register -------- */
-#define GMAC_SAB4_ADDR_Pos 0
-#define GMAC_SAB4_ADDR_Msk (0xffffffffu << GMAC_SAB4_ADDR_Pos) /**< \brief (GMAC_SAB4) Specific Address 4 */
-#define GMAC_SAB4_ADDR(value) ((GMAC_SAB4_ADDR_Msk & ((value) << GMAC_SAB4_ADDR_Pos)))
-/* -------- GMAC_SAT4 : (GMAC Offset: 0x0A4) Specific Address 4 Top [47:32] Register -------- */
-#define GMAC_SAT4_ADDR_Pos 0
-#define GMAC_SAT4_ADDR_Msk (0xffffu << GMAC_SAT4_ADDR_Pos) /**< \brief (GMAC_SAT4) Specific Address 4 */
-#define GMAC_SAT4_ADDR(value) ((GMAC_SAT4_ADDR_Msk & ((value) << GMAC_SAT4_ADDR_Pos)))
-/* -------- GMAC_TIDM[4] : (GMAC Offset: 0x0A8) Type ID Match 1 Register -------- */
-#define GMAC_TIDM_TID_Pos 0
-#define GMAC_TIDM_TID_Msk (0xffffu << GMAC_TIDM_TID_Pos) /**< \brief (GMAC_TIDM[4]) Type ID Match 1 */
-#define GMAC_TIDM_TID(value) ((GMAC_TIDM_TID_Msk & ((value) << GMAC_TIDM_TID_Pos)))
-/* -------- GMAC_WOL : (GMAC Offset: 0x0B8) Wake on LAN Register -------- */
-#define GMAC_WOL_IP_Pos 0
-#define GMAC_WOL_IP_Msk (0xffffu << GMAC_WOL_IP_Pos) /**< \brief (GMAC_WOL) ARP Request IP Address */
-#define GMAC_WOL_IP(value) ((GMAC_WOL_IP_Msk & ((value) << GMAC_WOL_IP_Pos)))
-#define GMAC_WOL_MAG (0x1u << 16) /**< \brief (GMAC_WOL) Magic Packet Event Enable */
-#define GMAC_WOL_ARP (0x1u << 17) /**< \brief (GMAC_WOL) ARP Request IP Address */
-#define GMAC_WOL_SA1 (0x1u << 18) /**< \brief (GMAC_WOL) Specific Address Register 1 Event Enable */
-#define GMAC_WOL_MTI (0x1u << 19) /**< \brief (GMAC_WOL) Multicast Hash Event Enable */
-/* -------- GMAC_IPGS : (GMAC Offset: 0x0BC) IPG Stretch Register -------- */
-#define GMAC_IPGS_FL_Pos 0
-#define GMAC_IPGS_FL_Msk (0xffffu << GMAC_IPGS_FL_Pos) /**< \brief (GMAC_IPGS) Frame Length */
-#define GMAC_IPGS_FL(value) ((GMAC_IPGS_FL_Msk & ((value) << GMAC_IPGS_FL_Pos)))
-/* -------- GMAC_SVLAN : (GMAC Offset: 0x0C0) Stacked VLAN Register -------- */
-#define GMAC_SVLAN_VLAN_TYPE_Pos 0
-#define GMAC_SVLAN_VLAN_TYPE_Msk (0xffffu << GMAC_SVLAN_VLAN_TYPE_Pos) /**< \brief (GMAC_SVLAN) User Defined VLAN_TYPE Field */
-#define GMAC_SVLAN_VLAN_TYPE(value) ((GMAC_SVLAN_VLAN_TYPE_Msk & ((value) << GMAC_SVLAN_VLAN_TYPE_Pos)))
-#define GMAC_SVLAN_ESVLAN (0x1u << 31) /**< \brief (GMAC_SVLAN) Enable Stacked VLAN Processing Mode */
-/* -------- GMAC_TPFCP : (GMAC Offset: 0x0C4) Transmit PFC Pause Register -------- */
-#define GMAC_TPFCP_PEV_Pos 0
-#define GMAC_TPFCP_PEV_Msk (0xffu << GMAC_TPFCP_PEV_Pos) /**< \brief (GMAC_TPFCP) Priority Enable Vector */
-#define GMAC_TPFCP_PEV(value) ((GMAC_TPFCP_PEV_Msk & ((value) << GMAC_TPFCP_PEV_Pos)))
-#define GMAC_TPFCP_PQ_Pos 8
-#define GMAC_TPFCP_PQ_Msk (0xffu << GMAC_TPFCP_PQ_Pos) /**< \brief (GMAC_TPFCP) Pause Quantum */
-#define GMAC_TPFCP_PQ(value) ((GMAC_TPFCP_PQ_Msk & ((value) << GMAC_TPFCP_PQ_Pos)))
-/* -------- GMAC_SAMB1 : (GMAC Offset: 0x0C8) Specific Address 1 Mask Bottom [31:0] Register -------- */
-#define GMAC_SAMB1_ADDR_Pos 0
-#define GMAC_SAMB1_ADDR_Msk (0xffffffffu << GMAC_SAMB1_ADDR_Pos) /**< \brief (GMAC_SAMB1) Specific Address 1 Mask */
-#define GMAC_SAMB1_ADDR(value) ((GMAC_SAMB1_ADDR_Msk & ((value) << GMAC_SAMB1_ADDR_Pos)))
-/* -------- GMAC_SAMT1 : (GMAC Offset: 0x0CC) Specific Address 1 Mask Top [47:32] Register -------- */
-#define GMAC_SAMT1_ADDR_Pos 0
-#define GMAC_SAMT1_ADDR_Msk (0xffffu << GMAC_SAMT1_ADDR_Pos) /**< \brief (GMAC_SAMT1) Specific Address 1 Mask */
-#define GMAC_SAMT1_ADDR(value) ((GMAC_SAMT1_ADDR_Msk & ((value) << GMAC_SAMT1_ADDR_Pos)))
-/* -------- GMAC_OTLO : (GMAC Offset: 0x100) Octets Transmitted [31:0] Register -------- */
-#define GMAC_OTLO_TXO_Pos 0
-#define GMAC_OTLO_TXO_Msk (0xffffffffu << GMAC_OTLO_TXO_Pos) /**< \brief (GMAC_OTLO) Transmitted Octets */
-/* -------- GMAC_OTHI : (GMAC Offset: 0x104) Octets Transmitted [47:32] Register -------- */
-#define GMAC_OTHI_TXO_Pos 0
-#define GMAC_OTHI_TXO_Msk (0xffffu << GMAC_OTHI_TXO_Pos) /**< \brief (GMAC_OTHI) Transmitted Octets */
-/* -------- GMAC_FT : (GMAC Offset: 0x108) Frames Transmitted Register -------- */
-#define GMAC_FT_FTX_Pos 0
-#define GMAC_FT_FTX_Msk (0xffffffffu << GMAC_FT_FTX_Pos) /**< \brief (GMAC_FT) Frames Transmitted without Error */
-/* -------- GMAC_BCFT : (GMAC Offset: 0x10C) Broadcast Frames Transmitted Register -------- */
-#define GMAC_BCFT_BFTX_Pos 0
-#define GMAC_BCFT_BFTX_Msk (0xffffffffu << GMAC_BCFT_BFTX_Pos) /**< \brief (GMAC_BCFT) Broadcast Frames Transmitted without Error */
-/* -------- GMAC_MFT : (GMAC Offset: 0x110) Multicast Frames Transmitted Register -------- */
-#define GMAC_MFT_MFTX_Pos 0
-#define GMAC_MFT_MFTX_Msk (0xffffffffu << GMAC_MFT_MFTX_Pos) /**< \brief (GMAC_MFT) Multicast Frames Transmitted without Error */
-/* -------- GMAC_PFT : (GMAC Offset: 0x114) Pause Frames Transmitted Register -------- */
-#define GMAC_PFT_PFTX_Pos 0
-#define GMAC_PFT_PFTX_Msk (0xffffu << GMAC_PFT_PFTX_Pos) /**< \brief (GMAC_PFT) Pause Frames Transmitted Register */
-/* -------- GMAC_BFT64 : (GMAC Offset: 0x118) 64 Byte Frames Transmitted Register -------- */
-#define GMAC_BFT64_NFTX_Pos 0
-#define GMAC_BFT64_NFTX_Msk (0xffffffffu << GMAC_BFT64_NFTX_Pos) /**< \brief (GMAC_BFT64) 64 Byte Frames Transmitted without Error */
-/* -------- GMAC_TBFT127 : (GMAC Offset: 0x11C) 65 to 127 Byte Frames Transmitted Register -------- */
-#define GMAC_TBFT127_NFTX_Pos 0
-#define GMAC_TBFT127_NFTX_Msk (0xffffffffu << GMAC_TBFT127_NFTX_Pos) /**< \brief (GMAC_TBFT127) 65 to 127 Byte Frames Transmitted without Error */
-/* -------- GMAC_TBFT255 : (GMAC Offset: 0x120) 128 to 255 Byte Frames Transmitted Register -------- */
-#define GMAC_TBFT255_NFTX_Pos 0
-#define GMAC_TBFT255_NFTX_Msk (0xffffffffu << GMAC_TBFT255_NFTX_Pos) /**< \brief (GMAC_TBFT255) 128 to 255 Byte Frames Transmitted without Error */
-/* -------- GMAC_TBFT511 : (GMAC Offset: 0x124) 256 to 511 Byte Frames Transmitted Register -------- */
-#define GMAC_TBFT511_NFTX_Pos 0
-#define GMAC_TBFT511_NFTX_Msk (0xffffffffu << GMAC_TBFT511_NFTX_Pos) /**< \brief (GMAC_TBFT511) 256 to 511 Byte Frames Transmitted without Error */
-/* -------- GMAC_TBFT1023 : (GMAC Offset: 0x128) 512 to 1023 Byte Frames Transmitted Register -------- */
-#define GMAC_TBFT1023_NFTX_Pos 0
-#define GMAC_TBFT1023_NFTX_Msk (0xffffffffu << GMAC_TBFT1023_NFTX_Pos) /**< \brief (GMAC_TBFT1023) 512 to 1023 Byte Frames Transmitted without Error */
-/* -------- GMAC_TBFT1518 : (GMAC Offset: 0x12C) 1024 to 1518 Byte Frames Transmitted Register -------- */
-#define GMAC_TBFT1518_NFTX_Pos 0
-#define GMAC_TBFT1518_NFTX_Msk (0xffffffffu << GMAC_TBFT1518_NFTX_Pos) /**< \brief (GMAC_TBFT1518) 1024 to 1518 Byte Frames Transmitted without Error */
-/* -------- GMAC_GTBFT1518 : (GMAC Offset: 0x130) Greater Than 1518 Byte Frames Transmitted Register -------- */
-#define GMAC_GTBFT1518_NFTX_Pos 0
-#define GMAC_GTBFT1518_NFTX_Msk (0xffffffffu << GMAC_GTBFT1518_NFTX_Pos) /**< \brief (GMAC_GTBFT1518) Greater than 1518 Byte Frames Transmitted without Error */
-/* -------- GMAC_TUR : (GMAC Offset: 0x134) Transmit Under Runs Register -------- */
-#define GMAC_TUR_TXUNR_Pos 0
-#define GMAC_TUR_TXUNR_Msk (0x3ffu << GMAC_TUR_TXUNR_Pos) /**< \brief (GMAC_TUR) Transmit Under Runs */
-/* -------- GMAC_SCF : (GMAC Offset: 0x138) Single Collision Frames Register -------- */
-#define GMAC_SCF_SCOL_Pos 0
-#define GMAC_SCF_SCOL_Msk (0x3ffffu << GMAC_SCF_SCOL_Pos) /**< \brief (GMAC_SCF) Single Collision */
-/* -------- GMAC_MCF : (GMAC Offset: 0x13C) Multiple Collision Frames Register -------- */
-#define GMAC_MCF_MCOL_Pos 0
-#define GMAC_MCF_MCOL_Msk (0x3ffffu << GMAC_MCF_MCOL_Pos) /**< \brief (GMAC_MCF) Multiple Collision */
-/* -------- GMAC_EC : (GMAC Offset: 0x140) Excessive Collisions Register -------- */
-#define GMAC_EC_XCOL_Pos 0
-#define GMAC_EC_XCOL_Msk (0x3ffu << GMAC_EC_XCOL_Pos) /**< \brief (GMAC_EC) Excessive Collisions */
-/* -------- GMAC_LC : (GMAC Offset: 0x144) Late Collisions Register -------- */
-#define GMAC_LC_LCOL_Pos 0
-#define GMAC_LC_LCOL_Msk (0x3ffu << GMAC_LC_LCOL_Pos) /**< \brief (GMAC_LC) Late Collisions */
-/* -------- GMAC_DTF : (GMAC Offset: 0x148) Deferred Transmission Frames Register -------- */
-#define GMAC_DTF_DEFT_Pos 0
-#define GMAC_DTF_DEFT_Msk (0x3ffffu << GMAC_DTF_DEFT_Pos) /**< \brief (GMAC_DTF) Deferred Transmission */
-/* -------- GMAC_CSE : (GMAC Offset: 0x14C) Carrier Sense Errors Register -------- */
-#define GMAC_CSE_CSR_Pos 0
-#define GMAC_CSE_CSR_Msk (0x3ffu << GMAC_CSE_CSR_Pos) /**< \brief (GMAC_CSE) Carrier Sense Error */
-/* -------- GMAC_ORLO : (GMAC Offset: 0x150) Octets Received [31:0] Received -------- */
-#define GMAC_ORLO_RXO_Pos 0
-#define GMAC_ORLO_RXO_Msk (0xffffffffu << GMAC_ORLO_RXO_Pos) /**< \brief (GMAC_ORLO) Received Octets */
-/* -------- GMAC_ORHI : (GMAC Offset: 0x154) Octets Received [47:32] Received -------- */
-#define GMAC_ORHI_RXO_Pos 0
-#define GMAC_ORHI_RXO_Msk (0xffffu << GMAC_ORHI_RXO_Pos) /**< \brief (GMAC_ORHI) Received Octets */
-/* -------- GMAC_FR : (GMAC Offset: 0x158) Frames Received Register -------- */
-#define GMAC_FR_FRX_Pos 0
-#define GMAC_FR_FRX_Msk (0xffffffffu << GMAC_FR_FRX_Pos) /**< \brief (GMAC_FR) Frames Received without Error */
-/* -------- GMAC_BCFR : (GMAC Offset: 0x15C) Broadcast Frames Received Register -------- */
-#define GMAC_BCFR_BFRX_Pos 0
-#define GMAC_BCFR_BFRX_Msk (0xffffffffu << GMAC_BCFR_BFRX_Pos) /**< \brief (GMAC_BCFR) Broadcast Frames Received without Error */
-/* -------- GMAC_MFR : (GMAC Offset: 0x160) Multicast Frames Received Register -------- */
-#define GMAC_MFR_MFRX_Pos 0
-#define GMAC_MFR_MFRX_Msk (0xffffffffu << GMAC_MFR_MFRX_Pos) /**< \brief (GMAC_MFR) Multicast Frames Received without Error */
-/* -------- GMAC_PFR : (GMAC Offset: 0x164) Pause Frames Received Register -------- */
-#define GMAC_PFR_PFRX_Pos 0
-#define GMAC_PFR_PFRX_Msk (0xffffu << GMAC_PFR_PFRX_Pos) /**< \brief (GMAC_PFR) Pause Frames Received Register */
-/* -------- GMAC_BFR64 : (GMAC Offset: 0x168) 64 Byte Frames Received Register -------- */
-#define GMAC_BFR64_NFRX_Pos 0
-#define GMAC_BFR64_NFRX_Msk (0xffffffffu << GMAC_BFR64_NFRX_Pos) /**< \brief (GMAC_BFR64) 64 Byte Frames Received without Error */
-/* -------- GMAC_TBFR127 : (GMAC Offset: 0x16C) 65 to 127 Byte Frames Received Register -------- */
-#define GMAC_TBFR127_NFRX_Pos 0
-#define GMAC_TBFR127_NFRX_Msk (0xffffffffu << GMAC_TBFR127_NFRX_Pos) /**< \brief (GMAC_TBFR127) 65 to 127 Byte Frames Received without Error */
-/* -------- GMAC_TBFR255 : (GMAC Offset: 0x170) 128 to 255 Byte Frames Received Register -------- */
-#define GMAC_TBFR255_NFRX_Pos 0
-#define GMAC_TBFR255_NFRX_Msk (0xffffffffu << GMAC_TBFR255_NFRX_Pos) /**< \brief (GMAC_TBFR255) 128 to 255 Byte Frames Received without Error */
-/* -------- GMAC_TBFR511 : (GMAC Offset: 0x174) 256 to 511Byte Frames Received Register -------- */
-#define GMAC_TBFR511_NFRX_Pos 0
-#define GMAC_TBFR511_NFRX_Msk (0xffffffffu << GMAC_TBFR511_NFRX_Pos) /**< \brief (GMAC_TBFR511) 256 to 511 Byte Frames Received without Error */
-/* -------- GMAC_TBFR1023 : (GMAC Offset: 0x178) 512 to 1023 Byte Frames Received Register -------- */
-#define GMAC_TBFR1023_NFRX_Pos 0
-#define GMAC_TBFR1023_NFRX_Msk (0xffffffffu << GMAC_TBFR1023_NFRX_Pos) /**< \brief (GMAC_TBFR1023) 512 to 1023 Byte Frames Received without Error */
-/* -------- GMAC_TBFR1518 : (GMAC Offset: 0x17C) 1024 to 1518 Byte Frames Received Register -------- */
-#define GMAC_TBFR1518_NFRX_Pos 0
-#define GMAC_TBFR1518_NFRX_Msk (0xffffffffu << GMAC_TBFR1518_NFRX_Pos) /**< \brief (GMAC_TBFR1518) 1024 to 1518 Byte Frames Received without Error */
-/* -------- GMAC_TMXBFR : (GMAC Offset: 0x180) 1519 to Maximum Byte Frames Received Register -------- */
-#define GMAC_TMXBFR_NFRX_Pos 0
-#define GMAC_TMXBFR_NFRX_Msk (0xffffffffu << GMAC_TMXBFR_NFRX_Pos) /**< \brief (GMAC_TMXBFR) 1519 to Maximum Byte Frames Received without Error */
-/* -------- GMAC_UFR : (GMAC Offset: 0x184) Undersize Frames Received Register -------- */
-#define GMAC_UFR_UFRX_Pos 0
-#define GMAC_UFR_UFRX_Msk (0x3ffu << GMAC_UFR_UFRX_Pos) /**< \brief (GMAC_UFR) Undersize Frames Received */
-/* -------- GMAC_OFR : (GMAC Offset: 0x188) Oversize Frames Received Register -------- */
-#define GMAC_OFR_OFRX_Pos 0
-#define GMAC_OFR_OFRX_Msk (0x3ffu << GMAC_OFR_OFRX_Pos) /**< \brief (GMAC_OFR) Oversized Frames Received */
-/* -------- GMAC_JR : (GMAC Offset: 0x18C) Jabbers Received Register -------- */
-#define GMAC_JR_JRX_Pos 0
-#define GMAC_JR_JRX_Msk (0x3ffu << GMAC_JR_JRX_Pos) /**< \brief (GMAC_JR) Jabbers Received */
-/* -------- GMAC_FCSE : (GMAC Offset: 0x190) Frame Check Sequence Errors Register -------- */
-#define GMAC_FCSE_FCKR_Pos 0
-#define GMAC_FCSE_FCKR_Msk (0x3ffu << GMAC_FCSE_FCKR_Pos) /**< \brief (GMAC_FCSE) Frame Check Sequence Errors */
-/* -------- GMAC_LFFE : (GMAC Offset: 0x194) Length Field Frame Errors Register -------- */
-#define GMAC_LFFE_LFER_Pos 0
-#define GMAC_LFFE_LFER_Msk (0x3ffu << GMAC_LFFE_LFER_Pos) /**< \brief (GMAC_LFFE) Length Field Frame Errors */
-/* -------- GMAC_RSE : (GMAC Offset: 0x198) Receive Symbol Errors Register -------- */
-#define GMAC_RSE_RXSE_Pos 0
-#define GMAC_RSE_RXSE_Msk (0x3ffu << GMAC_RSE_RXSE_Pos) /**< \brief (GMAC_RSE) Receive Symbol Errors */
-/* -------- GMAC_AE : (GMAC Offset: 0x19C) Alignment Errors Register -------- */
-#define GMAC_AE_AER_Pos 0
-#define GMAC_AE_AER_Msk (0x3ffu << GMAC_AE_AER_Pos) /**< \brief (GMAC_AE) Alignment Errors */
-/* -------- GMAC_RRE : (GMAC Offset: 0x1A0) Receive Resource Errors Register -------- */
-#define GMAC_RRE_RXRER_Pos 0
-#define GMAC_RRE_RXRER_Msk (0x3ffffu << GMAC_RRE_RXRER_Pos) /**< \brief (GMAC_RRE) Receive Resource Errors */
-/* -------- GMAC_ROE : (GMAC Offset: 0x1A4) Receive Overrun Register -------- */
-#define GMAC_ROE_RXOVR_Pos 0
-#define GMAC_ROE_RXOVR_Msk (0x3ffu << GMAC_ROE_RXOVR_Pos) /**< \brief (GMAC_ROE) Receive Overruns */
-/* -------- GMAC_IHCE : (GMAC Offset: 0x1A8) IP Header Checksum Errors Register -------- */
-#define GMAC_IHCE_HCKER_Pos 0
-#define GMAC_IHCE_HCKER_Msk (0xffu << GMAC_IHCE_HCKER_Pos) /**< \brief (GMAC_IHCE) IP Header Checksum Errors */
-/* -------- GMAC_TCE : (GMAC Offset: 0x1AC) TCP Checksum Errors Register -------- */
-#define GMAC_TCE_TCKER_Pos 0
-#define GMAC_TCE_TCKER_Msk (0xffu << GMAC_TCE_TCKER_Pos) /**< \brief (GMAC_TCE) TCP Checksum Errors */
-/* -------- GMAC_UCE : (GMAC Offset: 0x1B0) UDP Checksum Errors Register -------- */
-#define GMAC_UCE_UCKER_Pos 0
-#define GMAC_UCE_UCKER_Msk (0xffu << GMAC_UCE_UCKER_Pos) /**< \brief (GMAC_UCE) UDP Checksum Errors */
-/* -------- GMAC_TSSS : (GMAC Offset: 0x1C8) 1588 Timer Sync Strobe Seconds Register -------- */
-#define GMAC_TSSS_VTS_Pos 0
-#define GMAC_TSSS_VTS_Msk (0xffffffffu << GMAC_TSSS_VTS_Pos) /**< \brief (GMAC_TSSS) Value of Timer Seconds Register Capture */
-#define GMAC_TSSS_VTS(value) ((GMAC_TSSS_VTS_Msk & ((value) << GMAC_TSSS_VTS_Pos)))
-/* -------- GMAC_TSSN : (GMAC Offset: 0x1CC) 1588 Timer Sync Strobe Nanoseconds Register -------- */
-#define GMAC_TSSN_VTN_Pos 0
-#define GMAC_TSSN_VTN_Msk (0x3fffffffu << GMAC_TSSN_VTN_Pos) /**< \brief (GMAC_TSSN) Value Timer Nanoseconds Register Capture */
-#define GMAC_TSSN_VTN(value) ((GMAC_TSSN_VTN_Msk & ((value) << GMAC_TSSN_VTN_Pos)))
-/* -------- GMAC_TS : (GMAC Offset: 0x1D0) 1588 Timer Seconds Register -------- */
-#define GMAC_TS_TCS_Pos 0
-#define GMAC_TS_TCS_Msk (0xffffffffu << GMAC_TS_TCS_Pos) /**< \brief (GMAC_TS) Timer Count in Seconds */
-#define GMAC_TS_TCS(value) ((GMAC_TS_TCS_Msk & ((value) << GMAC_TS_TCS_Pos)))
-/* -------- GMAC_TN : (GMAC Offset: 0x1D4) 1588 Timer Nanoseconds Register -------- */
-#define GMAC_TN_TNS_Pos 0
-#define GMAC_TN_TNS_Msk (0x3fffffffu << GMAC_TN_TNS_Pos) /**< \brief (GMAC_TN) Timer Count in Nanoseconds */
-#define GMAC_TN_TNS(value) ((GMAC_TN_TNS_Msk & ((value) << GMAC_TN_TNS_Pos)))
-/* -------- GMAC_TA : (GMAC Offset: 0x1D8) 1588 Timer Adjust Register -------- */
-#define GMAC_TA_ITDT_Pos 0
-#define GMAC_TA_ITDT_Msk (0x3fffffffu << GMAC_TA_ITDT_Pos) /**< \brief (GMAC_TA) Increment/Decrement */
-#define GMAC_TA_ITDT(value) ((GMAC_TA_ITDT_Msk & ((value) << GMAC_TA_ITDT_Pos)))
-#define GMAC_TA_ADJ (0x1u << 31) /**< \brief (GMAC_TA) Adjust 1588 Timer */
-/* -------- GMAC_TI : (GMAC Offset: 0x1DC) 1588 Timer Increment Register -------- */
-#define GMAC_TI_CNS_Pos 0
-#define GMAC_TI_CNS_Msk (0xffu << GMAC_TI_CNS_Pos) /**< \brief (GMAC_TI) Count Nanoseconds */
-#define GMAC_TI_CNS(value) ((GMAC_TI_CNS_Msk & ((value) << GMAC_TI_CNS_Pos)))
-#define GMAC_TI_ACNS_Pos 8
-#define GMAC_TI_ACNS_Msk (0xffu << GMAC_TI_ACNS_Pos) /**< \brief (GMAC_TI) Alternative Count Nanoseconds */
-#define GMAC_TI_ACNS(value) ((GMAC_TI_ACNS_Msk & ((value) << GMAC_TI_ACNS_Pos)))
-#define GMAC_TI_NIT_Pos 16
-#define GMAC_TI_NIT_Msk (0xffu << GMAC_TI_NIT_Pos) /**< \brief (GMAC_TI) Number of Increments */
-#define GMAC_TI_NIT(value) ((GMAC_TI_NIT_Msk & ((value) << GMAC_TI_NIT_Pos)))
-/* -------- GMAC_EFTS : (GMAC Offset: 0x1E0) PTP Event Frame Transmitted Seconds -------- */
-#define GMAC_EFTS_RUD_Pos 0
-#define GMAC_EFTS_RUD_Msk (0xffffffffu << GMAC_EFTS_RUD_Pos) /**< \brief (GMAC_EFTS) Register Update */
-/* -------- GMAC_EFTN : (GMAC Offset: 0x1E4) PTP Event Frame Transmitted Nanoseconds -------- */
-#define GMAC_EFTN_RUD_Pos 0
-#define GMAC_EFTN_RUD_Msk (0x3fffffffu << GMAC_EFTN_RUD_Pos) /**< \brief (GMAC_EFTN) Register Update */
-/* -------- GMAC_EFRS : (GMAC Offset: 0x1E8) PTP Event Frame Received Seconds -------- */
-#define GMAC_EFRS_RUD_Pos 0
-#define GMAC_EFRS_RUD_Msk (0xffffffffu << GMAC_EFRS_RUD_Pos) /**< \brief (GMAC_EFRS) Register Update */
-/* -------- GMAC_EFRN : (GMAC Offset: 0x1EC) PTP Event Frame Received Nanoseconds -------- */
-#define GMAC_EFRN_RUD_Pos 0
-#define GMAC_EFRN_RUD_Msk (0x3fffffffu << GMAC_EFRN_RUD_Pos) /**< \brief (GMAC_EFRN) Register Update */
-/* -------- GMAC_PEFTS : (GMAC Offset: 0x1F0) PTP Peer Event Frame Transmitted Seconds -------- */
-#define GMAC_PEFTS_RUD_Pos 0
-#define GMAC_PEFTS_RUD_Msk (0xffffffffu << GMAC_PEFTS_RUD_Pos) /**< \brief (GMAC_PEFTS) Register Update */
-/* -------- GMAC_PEFTN : (GMAC Offset: 0x1F4) PTP Peer Event Frame Transmitted Nanoseconds -------- */
-#define GMAC_PEFTN_RUD_Pos 0
-#define GMAC_PEFTN_RUD_Msk (0x3fffffffu << GMAC_PEFTN_RUD_Pos) /**< \brief (GMAC_PEFTN) Register Update */
-/* -------- GMAC_PEFRS : (GMAC Offset: 0x1F8) PTP Peer Event Frame Received Seconds -------- */
-#define GMAC_PEFRS_RUD_Pos 0
-#define GMAC_PEFRS_RUD_Msk (0xffffffffu << GMAC_PEFRS_RUD_Pos) /**< \brief (GMAC_PEFRS) Register Update */
-/* -------- GMAC_PEFRN : (GMAC Offset: 0x1FC) PTP Peer Event Frame Received Nanoseconds -------- */
-#define GMAC_PEFRN_RUD_Pos 0
-#define GMAC_PEFRN_RUD_Msk (0x3fffffffu << GMAC_PEFRN_RUD_Pos) /**< \brief (GMAC_PEFRN) Register Update */
-/* -------- GMAC_ISRPQ[7] : (GMAC Offset: 0x400) Interrupt Status Register Priority Queue -------- */
-#define GMAC_ISRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_ISRPQ[7]) Receive Complete */
-#define GMAC_ISRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_ISRPQ[7]) RX Used Bit Read */
-#define GMAC_ISRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_ISRPQ[7]) Retry Limit Exceeded or Late Collision */
-#define GMAC_ISRPQ_TFC (0x1u << 6) /**< \brief (GMAC_ISRPQ[7]) Transmit Frame Corruption due to AHB error */
-#define GMAC_ISRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_ISRPQ[7]) Transmit Complete */
-#define GMAC_ISRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_ISRPQ[7]) Receive Overrun */
-#define GMAC_ISRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_ISRPQ[7]) HRESP Not OK */
-/* -------- GMAC_TBQBAPQ[7] : (GMAC Offset: 0x440) Transmit Buffer Queue Base Address Priority Queue -------- */
-#define GMAC_TBQBAPQ_TXBQBA_Pos 2
-#define GMAC_TBQBAPQ_TXBQBA_Msk (0x3fu << GMAC_TBQBAPQ_TXBQBA_Pos) /**< \brief (GMAC_TBQBAPQ[7]) Transmit Buffer Queue Base Address */
-#define GMAC_TBQBAPQ_TXBQBA(value) ((GMAC_TBQBAPQ_TXBQBA_Msk & ((value) << GMAC_TBQBAPQ_TXBQBA_Pos)))
-/* -------- GMAC_RBQBAPQ[7] : (GMAC Offset: 0x480) Receive Buffer Queue Base Address Priority Queue -------- */
-#define GMAC_RBQBAPQ_RXBQBA_Pos 2
-#define GMAC_RBQBAPQ_RXBQBA_Msk (0x3fu << GMAC_RBQBAPQ_RXBQBA_Pos) /**< \brief (GMAC_RBQBAPQ[7]) Receive Buffer Queue Base Address */
-#define GMAC_RBQBAPQ_RXBQBA(value) ((GMAC_RBQBAPQ_RXBQBA_Msk & ((value) << GMAC_RBQBAPQ_RXBQBA_Pos)))
-/* -------- GMAC_RBSRPQ[7] : (GMAC Offset: 0x4A0) Receive Buffer Size Register Priority Queue -------- */
-#define GMAC_RBSRPQ_RBS_Pos 0
-#define GMAC_RBSRPQ_RBS_Msk (0xffffu << GMAC_RBSRPQ_RBS_Pos) /**< \brief (GMAC_RBSRPQ[7]) Receive Buffer Size */
-#define GMAC_RBSRPQ_RBS(value) ((GMAC_RBSRPQ_RBS_Msk & ((value) << GMAC_RBSRPQ_RBS_Pos)))
-/* -------- GMAC_ST1RPQ[16] : (GMAC Offset: 0x500) Screening Type1 Register Priority Queue -------- */
-#define GMAC_ST1RPQ_QNB_Pos 0
-#define GMAC_ST1RPQ_QNB_Msk (0xfu << GMAC_ST1RPQ_QNB_Pos) /**< \brief (GMAC_ST1RPQ[16]) Que Number (0->7) */
-#define GMAC_ST1RPQ_QNB(value) ((GMAC_ST1RPQ_QNB_Msk & ((value) << GMAC_ST1RPQ_QNB_Pos)))
-#define GMAC_ST1RPQ_DSTCM_Pos 4
-#define GMAC_ST1RPQ_DSTCM_Msk (0xffu << GMAC_ST1RPQ_DSTCM_Pos) /**< \brief (GMAC_ST1RPQ[16]) Differentiated Services or Traffic Class Match */
-#define GMAC_ST1RPQ_DSTCM(value) ((GMAC_ST1RPQ_DSTCM_Msk & ((value) << GMAC_ST1RPQ_DSTCM_Pos)))
-#define GMAC_ST1RPQ_UDPM_Pos 12
-#define GMAC_ST1RPQ_UDPM_Msk (0xffffu << GMAC_ST1RPQ_UDPM_Pos) /**< \brief (GMAC_ST1RPQ[16]) UDP Port Match */
-#define GMAC_ST1RPQ_UDPM(value) ((GMAC_ST1RPQ_UDPM_Msk & ((value) << GMAC_ST1RPQ_UDPM_Pos)))
-#define GMAC_ST1RPQ_DSTCE (0x1u << 28) /**< \brief (GMAC_ST1RPQ[16]) Differentiated Services or Traffic Class Match Enable */
-#define GMAC_ST1RPQ_UDPE (0x1u << 29) /**< \brief (GMAC_ST1RPQ[16]) UDP Port Match Enable */
-/* -------- GMAC_ST2RPQ[16] : (GMAC Offset: 0x540) Screening Type2 Register Priority Queue -------- */
-#define GMAC_ST2RPQ_QNB_Pos 0
-#define GMAC_ST2RPQ_QNB_Msk (0xfu << GMAC_ST2RPQ_QNB_Pos) /**< \brief (GMAC_ST2RPQ[16]) Que Number (0->7) */
-#define GMAC_ST2RPQ_QNB(value) ((GMAC_ST2RPQ_QNB_Msk & ((value) << GMAC_ST2RPQ_QNB_Pos)))
-#define GMAC_ST2RPQ_VLANP_Pos 4
-#define GMAC_ST2RPQ_VLANP_Msk (0xfu << GMAC_ST2RPQ_VLANP_Pos) /**< \brief (GMAC_ST2RPQ[16]) VLAN Priority */
-#define GMAC_ST2RPQ_VLANP(value) ((GMAC_ST2RPQ_VLANP_Msk & ((value) << GMAC_ST2RPQ_VLANP_Pos)))
-#define GMAC_ST2RPQ_VLANE (0x1u << 8) /**< \brief (GMAC_ST2RPQ[16]) VLAN Enable */
-/* -------- GMAC_IERPQ[7] : (GMAC Offset: 0x600) Interrupt Enable Register Priority Queue -------- */
-#define GMAC_IERPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IERPQ[7]) Receive Complete */
-#define GMAC_IERPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IERPQ[7]) RX Used Bit Read */
-#define GMAC_IERPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IERPQ[7]) Retry Limit Exceeded or Late Collision */
-#define GMAC_IERPQ_TFC (0x1u << 6) /**< \brief (GMAC_IERPQ[7]) Transmit Frame Corruption due to AHB error */
-#define GMAC_IERPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IERPQ[7]) Transmit Complete */
-#define GMAC_IERPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IERPQ[7]) Receive Overrun */
-#define GMAC_IERPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IERPQ[7]) HRESP Not OK */
-/* -------- GMAC_IDRPQ[7] : (GMAC Offset: 0x620) Interrupt Disable Register Priority Queue -------- */
-#define GMAC_IDRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IDRPQ[7]) Receive Complete */
-#define GMAC_IDRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IDRPQ[7]) RX Used Bit Read */
-#define GMAC_IDRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IDRPQ[7]) Retry Limit Exceeded or Late Collision */
-#define GMAC_IDRPQ_TFC (0x1u << 6) /**< \brief (GMAC_IDRPQ[7]) Transmit Frame Corruption due to AHB error */
-#define GMAC_IDRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IDRPQ[7]) Transmit Complete */
-#define GMAC_IDRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IDRPQ[7]) Receive Overrun */
-#define GMAC_IDRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IDRPQ[7]) HRESP Not OK */
-/* -------- GMAC_IMRPQ[7] : (GMAC Offset: 0x640) Interrupt Mask Register Priority Queue -------- */
-#define GMAC_IMRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IMRPQ[7]) Receive Complete */
-#define GMAC_IMRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IMRPQ[7]) RX Used Bit Read */
-#define GMAC_IMRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IMRPQ[7]) Retry Limit Exceeded or Late Collision */
-#define GMAC_IMRPQ_AHB (0x1u << 6) /**< \brief (GMAC_IMRPQ[7]) AHB Error */
-#define GMAC_IMRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IMRPQ[7]) Transmit Complete */
-#define GMAC_IMRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IMRPQ[7]) Receive Overrun */
-#define GMAC_IMRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IMRPQ[7]) HRESP Not OK */
-
-/*@}*/
-
-
-#endif /* _SAM4E_GMAC_COMPONENT_ */
+/**
+ * \file
+ *
+ * Copyright (c) 2012 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#ifndef _SAM4E_GMAC_COMPONENT_
+#define _SAM4E_GMAC_COMPONENT_
+
+/* ============================================================================= */
+/** SOFTWARE API DEFINITION FOR Gigabit Ethernet MAC */
+/* ============================================================================= */
+/** \addtogroup SAM4E_GMAC Gigabit Ethernet MAC */
+/*@{*/
+
+#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
+/** \brief GmacSa hardware registers */
+typedef struct {
+ RwReg GMAC_SAB; /**< \brief (GmacSa Offset: 0x0) Specific Address 1 Bottom [31:0] Register */
+ RwReg GMAC_SAT; /**< \brief (GmacSa Offset: 0x4) Specific Address 1 Top [47:32] Register */
+} GmacSa;
+/** \brief Gmac hardware registers */
+#define GMACSA_NUMBER 4
+typedef struct {
+ RwReg GMAC_NCR; /**< \brief (Gmac Offset: 0x000) Network Control Register */
+ RwReg GMAC_NCFGR; /**< \brief (Gmac Offset: 0x004) Network Configuration Register */
+ RoReg GMAC_NSR; /**< \brief (Gmac Offset: 0x008) Network Status Register */
+ RwReg GMAC_UR; /**< \brief (Gmac Offset: 0x00C) User Register */
+ RwReg GMAC_DCFGR; /**< \brief (Gmac Offset: 0x010) DMA Configuration Register */
+ RwReg GMAC_TSR; /**< \brief (Gmac Offset: 0x014) Transmit Status Register */
+ RwReg GMAC_RBQB; /**< \brief (Gmac Offset: 0x018) Receive Buffer Queue Base Address */
+ RwReg GMAC_TBQB; /**< \brief (Gmac Offset: 0x01C) Transmit Buffer Queue Base Address */
+ RwReg GMAC_RSR; /**< \brief (Gmac Offset: 0x020) Receive Status Register */
+ RoReg GMAC_ISR; /**< \brief (Gmac Offset: 0x024) Interrupt Status Register */
+ WoReg GMAC_IER; /**< \brief (Gmac Offset: 0x028) Interrupt Enable Register */
+ WoReg GMAC_IDR; /**< \brief (Gmac Offset: 0x02C) Interrupt Disable Register */
+ RoReg GMAC_IMR; /**< \brief (Gmac Offset: 0x030) Interrupt Mask Register */
+ RwReg GMAC_MAN; /**< \brief (Gmac Offset: 0x034) PHY Maintenance Register */
+ RoReg GMAC_RPQ; /**< \brief (Gmac Offset: 0x038) Received Pause Quantum Register */
+ RwReg GMAC_TPQ; /**< \brief (Gmac Offset: 0x03C) Transmit Pause Quantum Register */
+ RwReg GMAC_TPSF; /**< \brief (Gmac Offset: 0x040) TX Partial Store and Forward Register */
+ RwReg GMAC_RPSF; /**< \brief (Gmac Offset: 0x044) RX Partial Store and Forward Register */
+ RoReg Reserved1[14];
+ RwReg GMAC_HRB; /**< \brief (Gmac Offset: 0x080) Hash Register Bottom [31:0] */
+ RwReg GMAC_HRT; /**< \brief (Gmac Offset: 0x084) Hash Register Top [63:32] */
+ GmacSa GMAC_SA[GMACSA_NUMBER]; /**< \brief (Gmac Offset: 0x088) 1 .. 4 */
+ RwReg GMAC_TIDM[4]; /**< \brief (Gmac Offset: 0x0A8) Type ID Match 1 Register */
+ RwReg GMAC_WOL; /**< \brief (Gmac Offset: 0x0B8) Wake on LAN Register */
+ RwReg GMAC_IPGS; /**< \brief (Gmac Offset: 0x0BC) IPG Stretch Register */
+ RwReg GMAC_SVLAN; /**< \brief (Gmac Offset: 0x0C0) Stacked VLAN Register */
+ RwReg GMAC_TPFCP; /**< \brief (Gmac Offset: 0x0C4) Transmit PFC Pause Register */
+ RwReg GMAC_SAMB1; /**< \brief (Gmac Offset: 0x0C8) Specific Address 1 Mask Bottom [31:0] Register */
+ RwReg GMAC_SAMT1; /**< \brief (Gmac Offset: 0x0CC) Specific Address 1 Mask Top [47:32] Register */
+ RoReg Reserved2[12];
+ RoReg GMAC_OTLO; /**< \brief (Gmac Offset: 0x100) Octets Transmitted [31:0] Register */
+ RoReg GMAC_OTHI; /**< \brief (Gmac Offset: 0x104) Octets Transmitted [47:32] Register */
+ RoReg GMAC_FT; /**< \brief (Gmac Offset: 0x108) Frames Transmitted Register */
+ RoReg GMAC_BCFT; /**< \brief (Gmac Offset: 0x10C) Broadcast Frames Transmitted Register */
+ RoReg GMAC_MFT; /**< \brief (Gmac Offset: 0x110) Multicast Frames Transmitted Register */
+ RoReg GMAC_PFT; /**< \brief (Gmac Offset: 0x114) Pause Frames Transmitted Register */
+ RoReg GMAC_BFT64; /**< \brief (Gmac Offset: 0x118) 64 Byte Frames Transmitted Register */
+ RoReg GMAC_TBFT127; /**< \brief (Gmac Offset: 0x11C) 65 to 127 Byte Frames Transmitted Register */
+ RoReg GMAC_TBFT255; /**< \brief (Gmac Offset: 0x120) 128 to 255 Byte Frames Transmitted Register */
+ RoReg GMAC_TBFT511; /**< \brief (Gmac Offset: 0x124) 256 to 511 Byte Frames Transmitted Register */
+ RoReg GMAC_TBFT1023; /**< \brief (Gmac Offset: 0x128) 512 to 1023 Byte Frames Transmitted Register */
+ RoReg GMAC_TBFT1518; /**< \brief (Gmac Offset: 0x12C) 1024 to 1518 Byte Frames Transmitted Register */
+ RoReg GMAC_GTBFT1518; /**< \brief (Gmac Offset: 0x130) Greater Than 1518 Byte Frames Transmitted Register */
+ RoReg GMAC_TUR; /**< \brief (Gmac Offset: 0x134) Transmit Under Runs Register */
+ RoReg GMAC_SCF; /**< \brief (Gmac Offset: 0x138) Single Collision Frames Register */
+ RoReg GMAC_MCF; /**< \brief (Gmac Offset: 0x13C) Multiple Collision Frames Register */
+ RoReg GMAC_EC; /**< \brief (Gmac Offset: 0x140) Excessive Collisions Register */
+ RoReg GMAC_LC; /**< \brief (Gmac Offset: 0x144) Late Collisions Register */
+ RoReg GMAC_DTF; /**< \brief (Gmac Offset: 0x148) Deferred Transmission Frames Register */
+ RoReg GMAC_CSE; /**< \brief (Gmac Offset: 0x14C) Carrier Sense Errors Register */
+ RoReg GMAC_ORLO; /**< \brief (Gmac Offset: 0x150) Octets Received [31:0] Received */
+ RoReg GMAC_ORHI; /**< \brief (Gmac Offset: 0x154) Octets Received [47:32] Received */
+ RoReg GMAC_FR; /**< \brief (Gmac Offset: 0x158) Frames Received Register */
+ RoReg GMAC_BCFR; /**< \brief (Gmac Offset: 0x15C) Broadcast Frames Received Register */
+ RoReg GMAC_MFR; /**< \brief (Gmac Offset: 0x160) Multicast Frames Received Register */
+ RoReg GMAC_PFR; /**< \brief (Gmac Offset: 0x164) Pause Frames Received Register */
+ RoReg GMAC_BFR64; /**< \brief (Gmac Offset: 0x168) 64 Byte Frames Received Register */
+ RoReg GMAC_TBFR127; /**< \brief (Gmac Offset: 0x16C) 65 to 127 Byte Frames Received Register */
+ RoReg GMAC_TBFR255; /**< \brief (Gmac Offset: 0x170) 128 to 255 Byte Frames Received Register */
+ RoReg GMAC_TBFR511; /**< \brief (Gmac Offset: 0x174) 256 to 511Byte Frames Received Register */
+ RoReg GMAC_TBFR1023; /**< \brief (Gmac Offset: 0x178) 512 to 1023 Byte Frames Received Register */
+ RoReg GMAC_TBFR1518; /**< \brief (Gmac Offset: 0x17C) 1024 to 1518 Byte Frames Received Register */
+ RoReg GMAC_TMXBFR; /**< \brief (Gmac Offset: 0x180) 1519 to Maximum Byte Frames Received Register */
+ RoReg GMAC_UFR; /**< \brief (Gmac Offset: 0x184) Undersize Frames Received Register */
+ RoReg GMAC_OFR; /**< \brief (Gmac Offset: 0x188) Oversize Frames Received Register */
+ RoReg GMAC_JR; /**< \brief (Gmac Offset: 0x18C) Jabbers Received Register */
+ RoReg GMAC_FCSE; /**< \brief (Gmac Offset: 0x190) Frame Check Sequence Errors Register */
+ RoReg GMAC_LFFE; /**< \brief (Gmac Offset: 0x194) Length Field Frame Errors Register */
+ RoReg GMAC_RSE; /**< \brief (Gmac Offset: 0x198) Receive Symbol Errors Register */
+ RoReg GMAC_AE; /**< \brief (Gmac Offset: 0x19C) Alignment Errors Register */
+ RoReg GMAC_RRE; /**< \brief (Gmac Offset: 0x1A0) Receive Resource Errors Register */
+ RoReg GMAC_ROE; /**< \brief (Gmac Offset: 0x1A4) Receive Overrun Register */
+ RoReg GMAC_IHCE; /**< \brief (Gmac Offset: 0x1A8) IP Header Checksum Errors Register */
+ RoReg GMAC_TCE; /**< \brief (Gmac Offset: 0x1AC) TCP Checksum Errors Register */
+ RoReg GMAC_UCE; /**< \brief (Gmac Offset: 0x1B0) UDP Checksum Errors Register */
+ RoReg Reserved3[5];
+ RwReg GMAC_TSSS; /**< \brief (Gmac Offset: 0x1C8) 1588 Timer Sync Strobe Seconds Register */
+ RwReg GMAC_TSSN; /**< \brief (Gmac Offset: 0x1CC) 1588 Timer Sync Strobe Nanoseconds Register */
+ RwReg GMAC_TS; /**< \brief (Gmac Offset: 0x1D0) 1588 Timer Seconds Register */
+ RwReg GMAC_TN; /**< \brief (Gmac Offset: 0x1D4) 1588 Timer Nanoseconds Register */
+ WoReg GMAC_TA; /**< \brief (Gmac Offset: 0x1D8) 1588 Timer Adjust Register */
+ RwReg GMAC_TI; /**< \brief (Gmac Offset: 0x1DC) 1588 Timer Increment Register */
+ RoReg GMAC_EFTS; /**< \brief (Gmac Offset: 0x1E0) PTP Event Frame Transmitted Seconds */
+ RoReg GMAC_EFTN; /**< \brief (Gmac Offset: 0x1E4) PTP Event Frame Transmitted Nanoseconds */
+ RoReg GMAC_EFRS; /**< \brief (Gmac Offset: 0x1E8) PTP Event Frame Received Seconds */
+ RoReg GMAC_EFRN; /**< \brief (Gmac Offset: 0x1EC) PTP Event Frame Received Nanoseconds */
+ RoReg GMAC_PEFTS; /**< \brief (Gmac Offset: 0x1F0) PTP Peer Event Frame Transmitted Seconds */
+ RoReg GMAC_PEFTN; /**< \brief (Gmac Offset: 0x1F4) PTP Peer Event Frame Transmitted Nanoseconds */
+ RoReg GMAC_PEFRS; /**< \brief (Gmac Offset: 0x1F8) PTP Peer Event Frame Received Seconds */
+ RoReg GMAC_PEFRN; /**< \brief (Gmac Offset: 0x1FC) PTP Peer Event Frame Received Nanoseconds */
+ RoReg Reserved4[128];
+ RoReg GMAC_ISRPQ[7]; /**< \brief (Gmac Offset: 0x400) Interrupt Status Register Priority Queue */
+ RoReg Reserved5[9];
+ RwReg GMAC_TBQBAPQ[7]; /**< \brief (Gmac Offset: 0x440) Transmit Buffer Queue Base Address Priority Queue */
+ RoReg Reserved6[9];
+ RwReg GMAC_RBQBAPQ[7]; /**< \brief (Gmac Offset: 0x480) Receive Buffer Queue Base Address Priority Queue */
+ RoReg Reserved7[1];
+ RwReg GMAC_RBSRPQ[7]; /**< \brief (Gmac Offset: 0x4A0) Receive Buffer Size Register Priority Queue */
+ RoReg Reserved8[17];
+ RwReg GMAC_ST1RPQ[16]; /**< \brief (Gmac Offset: 0x500) Screening Type1 Register Priority Queue */
+ RwReg GMAC_ST2RPQ[16]; /**< \brief (Gmac Offset: 0x540) Screening Type2 Register Priority Queue */
+ RoReg Reserved9[32];
+ WoReg GMAC_IERPQ[7]; /**< \brief (Gmac Offset: 0x600) Interrupt Enable Register Priority Queue */
+ RoReg Reserved10[1];
+ WoReg GMAC_IDRPQ[7]; /**< \brief (Gmac Offset: 0x620) Interrupt Disable Register Priority Queue */
+ RoReg Reserved11[1];
+ RwReg GMAC_IMRPQ[7]; /**< \brief (Gmac Offset: 0x640) Interrupt Mask Register Priority Queue */
+} Gmac;
+#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
+/* -------- GMAC_NCR : (GMAC Offset: 0x000) Network Control Register -------- */
+#define GMAC_NCR_LB (0x1u << 0) /**< \brief (GMAC_NCR) Loop Back */
+#define GMAC_NCR_LBL (0x1u << 1) /**< \brief (GMAC_NCR) Loop Back Local */
+#define GMAC_NCR_RXEN (0x1u << 2) /**< \brief (GMAC_NCR) Receive Enable */
+#define GMAC_NCR_TXEN (0x1u << 3) /**< \brief (GMAC_NCR) Transmit Enable */
+#define GMAC_NCR_MPE (0x1u << 4) /**< \brief (GMAC_NCR) Management Port Enable */
+#define GMAC_NCR_CLRSTAT (0x1u << 5) /**< \brief (GMAC_NCR) Clear Statistics Registers */
+#define GMAC_NCR_INCSTAT (0x1u << 6) /**< \brief (GMAC_NCR) Increment Statistics Registers */
+#define GMAC_NCR_WESTAT (0x1u << 7) /**< \brief (GMAC_NCR) Write Enable for Statistics Registers */
+#define GMAC_NCR_BP (0x1u << 8) /**< \brief (GMAC_NCR) Back pressure */
+#define GMAC_NCR_TSTART (0x1u << 9) /**< \brief (GMAC_NCR) Start Transmission */
+#define GMAC_NCR_THALT (0x1u << 10) /**< \brief (GMAC_NCR) Transmit Halt */
+#define GMAC_NCR_TXPF (0x1u << 11) /**< \brief (GMAC_NCR) Transmit Pause Frame */
+#define GMAC_NCR_TXZQPF (0x1u << 12) /**< \brief (GMAC_NCR) Transmit Zero Quantum Pause Frame */
+#define GMAC_NCR_RDS (0x1u << 14) /**< \brief (GMAC_NCR) Read Snapshot */
+#define GMAC_NCR_SRTSM (0x1u << 15) /**< \brief (GMAC_NCR) Store Receive Time Stamp to Memory */
+#define GMAC_NCR_ENPBPR (0x1u << 16) /**< \brief (GMAC_NCR) Enable PFC Priority-based Pause Reception */
+#define GMAC_NCR_TXPBPF (0x1u << 17) /**< \brief (GMAC_NCR) Transmit PFC Priority-based Pause Frame */
+#define GMAC_NCR_FNP (0x1u << 18) /**< \brief (GMAC_NCR) Flush Next Packet */
+/* -------- GMAC_NCFGR : (GMAC Offset: 0x004) Network Configuration Register -------- */
+#define GMAC_NCFGR_SPD (0x1u << 0) /**< \brief (GMAC_NCFGR) Speed */
+#define GMAC_NCFGR_FD (0x1u << 1) /**< \brief (GMAC_NCFGR) Full Duplex */
+#define GMAC_NCFGR_DNVLAN (0x1u << 2) /**< \brief (GMAC_NCFGR) Discard Non-VLAN FRAMES */
+#define GMAC_NCFGR_JFRAME (0x1u << 3) /**< \brief (GMAC_NCFGR) Jumbo Frame Size */
+#define GMAC_NCFGR_CAF (0x1u << 4) /**< \brief (GMAC_NCFGR) Copy All Frames */
+#define GMAC_NCFGR_NBC (0x1u << 5) /**< \brief (GMAC_NCFGR) No Broadcast */
+#define GMAC_NCFGR_MTIHEN (0x1u << 6) /**< \brief (GMAC_NCFGR) Multicast Hash Enable */
+#define GMAC_NCFGR_UNIHEN (0x1u << 7) /**< \brief (GMAC_NCFGR) Unicast Hash Enable */
+#define GMAC_NCFGR_MAXFS (0x1u << 8) /**< \brief (GMAC_NCFGR) 1536 Maximum Frame Size */
+#define GMAC_NCFGR_GBE (0x1u << 10) /**< \brief (GMAC_NCFGR) Gigabit Mode Enable */
+#define GMAC_NCFGR_PIS (0x1u << 11) /**< \brief (GMAC_NCFGR) Physical Interface Select */
+#define GMAC_NCFGR_RTY (0x1u << 12) /**< \brief (GMAC_NCFGR) Retry Test */
+#define GMAC_NCFGR_PEN (0x1u << 13) /**< \brief (GMAC_NCFGR) Pause Enable */
+#define GMAC_NCFGR_RXBUFO_Pos 14
+#define GMAC_NCFGR_RXBUFO_Msk (0x3u << GMAC_NCFGR_RXBUFO_Pos) /**< \brief (GMAC_NCFGR) Receive Buffer Offset */
+#define GMAC_NCFGR_RXBUFO(value) ((GMAC_NCFGR_RXBUFO_Msk & ((value) << GMAC_NCFGR_RXBUFO_Pos)))
+#define GMAC_NCFGR_LFERD (0x1u << 16) /**< \brief (GMAC_NCFGR) Length Field Error Frame Discard */
+#define GMAC_NCFGR_RFCS (0x1u << 17) /**< \brief (GMAC_NCFGR) Remove FCS */
+#define GMAC_NCFGR_CLK_Pos 18
+#define GMAC_NCFGR_CLK_Msk (0x7u << GMAC_NCFGR_CLK_Pos) /**< \brief (GMAC_NCFGR) MDC CLock Division */
+#define GMAC_NCFGR_CLK_MCK_8 (0x0u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 8 (MCK up to 20 MHz) */
+#define GMAC_NCFGR_CLK_MCK_16 (0x1u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 16 (MCK up to 40 MHz) */
+#define GMAC_NCFGR_CLK_MCK_32 (0x2u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 32 (MCK up to 80 MHz) */
+#define GMAC_NCFGR_CLK_MCK_48 (0x3u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 48 (MCK up to 120MHz) */
+#define GMAC_NCFGR_CLK_MCK_64 (0x4u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 64 (MCK up to 160 MHz) */
+#define GMAC_NCFGR_CLK_MCK_96 (0x5u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 96 (MCK up to 240 MHz) */
+#define GMAC_NCFGR_CLK_MCK_128 (0x6u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 128 (MCK up to 320 MHz) */
+#define GMAC_NCFGR_CLK_MCK_224 (0x7u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 224 (MCK up to 540 MHz) */
+#define GMAC_NCFGR_DBW_Pos 21
+#define GMAC_NCFGR_DBW_Msk (0x3u << GMAC_NCFGR_DBW_Pos) /**< \brief (GMAC_NCFGR) Data Bus Width */
+#define GMAC_NCFGR_DBW_DBW32 (0x0u << 21) /**< \brief (GMAC_NCFGR) 32-bit data bus width */
+#define GMAC_NCFGR_DBW_DBW64 (0x1u << 21) /**< \brief (GMAC_NCFGR) 64-bit data bus width */
+#define GMAC_NCFGR_DCPF (0x1u << 23) /**< \brief (GMAC_NCFGR) Disable Copy of Pause Frames */
+#define GMAC_NCFGR_RXCOEN (0x1u << 24) /**< \brief (GMAC_NCFGR) Receive Checksum Offload Enable */
+#define GMAC_NCFGR_EFRHD (0x1u << 25) /**< \brief (GMAC_NCFGR) Enable Frames Received in Half Duplex */
+#define GMAC_NCFGR_IRXFCS (0x1u << 26) /**< \brief (GMAC_NCFGR) Ignore RX FCS */
+#define GMAC_NCFGR_IPGSEN (0x1u << 28) /**< \brief (GMAC_NCFGR) IP Stretch Enable */
+#define GMAC_NCFGR_RXBP (0x1u << 29) /**< \brief (GMAC_NCFGR) Receive Bad Preamble */
+#define GMAC_NCFGR_IRXER (0x1u << 30) /**< \brief (GMAC_NCFGR) Ignore IPG rx_er */
+/* -------- GMAC_NSR : (GMAC Offset: 0x008) Network Status Register -------- */
+#define GMAC_NSR_MDIO (0x1u << 1) /**< \brief (GMAC_NSR) MDIO Input Status */
+#define GMAC_NSR_IDLE (0x1u << 2) /**< \brief (GMAC_NSR) PHY Management Logic Idle */
+/* -------- GMAC_UR : (GMAC Offset: 0x00C) User Register -------- */
+#define GMAC_UR_RGMII (0x1u << 0) /**< \brief (GMAC_UR) RGMII Mode */
+#define GMAC_UR_HDFC (0x1u << 6) /**< \brief (GMAC_UR) Half Duplex Flow Control */
+#define GMAC_UR_BPDG (0x1u << 7) /**< \brief (GMAC_UR) BPDG Bypass Deglitchers */
+/* -------- GMAC_DCFGR : (GMAC Offset: 0x010) DMA Configuration Register -------- */
+#define GMAC_DCFGR_FBLDO_Pos 0
+#define GMAC_DCFGR_FBLDO_Msk (0x1fu << GMAC_DCFGR_FBLDO_Pos) /**< \brief (GMAC_DCFGR) Fixed Burst Length for DMA Data Operations: */
+#define GMAC_DCFGR_FBLDO_SINGLE (0x1u << 0) /**< \brief (GMAC_DCFGR) 00001: Always use SINGLE AHB bursts */
+#define GMAC_DCFGR_FBLDO_INCR4 (0x4u << 0) /**< \brief (GMAC_DCFGR) 001xx: Attempt to use INCR4 AHB bursts (Default) */
+#define GMAC_DCFGR_FBLDO_INCR8 (0x8u << 0) /**< \brief (GMAC_DCFGR) 01xxx: Attempt to use INCR8 AHB bursts */
+#define GMAC_DCFGR_FBLDO_INCR16 (0x10u << 0) /**< \brief (GMAC_DCFGR) 1xxxx: Attempt to use INCR16 AHB bursts */
+#define GMAC_DCFGR_ESMA (0x1u << 6) /**< \brief (GMAC_DCFGR) Endian Swap Mode Enable for Management Descriptor Accesses */
+#define GMAC_DCFGR_ESPA (0x1u << 7) /**< \brief (GMAC_DCFGR) Endian Swap Mode Enable for Packet Data Accesses */
+#define GMAC_DCFGR_RXBMS_Pos 8
+#define GMAC_DCFGR_RXBMS_Msk (0x3u << GMAC_DCFGR_RXBMS_Pos) /**< \brief (GMAC_DCFGR) Receiver Packet Buffer Memory Size Select */
+#define GMAC_DCFGR_RXBMS_EIGHTH (0x0u << 8) /**< \brief (GMAC_DCFGR) 1 Kbyte Memory Size */
+#define GMAC_DCFGR_RXBMS_QUARTER (0x1u << 8) /**< \brief (GMAC_DCFGR) 2 Kbytes Memory Size */
+#define GMAC_DCFGR_RXBMS_HALF (0x2u << 8) /**< \brief (GMAC_DCFGR) 4 Kbytes Memory Size */
+#define GMAC_DCFGR_RXBMS_FULL (0x3u << 8) /**< \brief (GMAC_DCFGR) 8 Kbytes Memory Size */
+#define GMAC_DCFGR_TXPBMS (0x1u << 10) /**< \brief (GMAC_DCFGR) Transmitter Packet Buffer Memory Size Select */
+#define GMAC_DCFGR_TXCOEN (0x1u << 11) /**< \brief (GMAC_DCFGR) Transmitter Checksum Generation Offload Enable */
+#define GMAC_DCFGR_DRBS_Pos 16
+#define GMAC_DCFGR_DRBS_Msk (0xffu << GMAC_DCFGR_DRBS_Pos) /**< \brief (GMAC_DCFGR) DMA Receive Buffer Size */
+#define GMAC_DCFGR_DRBS(value) ((GMAC_DCFGR_DRBS_Msk & ((value) << GMAC_DCFGR_DRBS_Pos)))
+#define GMAC_DCFGR_DDRP (0x1u << 24) /**< \brief (GMAC_DCFGR) DMA Discard Receive Packets */
+/* -------- GMAC_TSR : (GMAC Offset: 0x014) Transmit Status Register -------- */
+#define GMAC_TSR_UBR (0x1u << 0) /**< \brief (GMAC_TSR) Used Bit Read */
+#define GMAC_TSR_COL (0x1u << 1) /**< \brief (GMAC_TSR) Collision Occurred */
+#define GMAC_TSR_RLE (0x1u << 2) /**< \brief (GMAC_TSR) Retry Limit Exceeded */
+#define GMAC_TSR_TXGO (0x1u << 3) /**< \brief (GMAC_TSR) Transmit Go */
+#define GMAC_TSR_TFC (0x1u << 4) /**< \brief (GMAC_TSR) Transmit Frame Corruption due to AHB error */
+#define GMAC_TSR_TXCOMP (0x1u << 5) /**< \brief (GMAC_TSR) Transmit Complete */
+#define GMAC_TSR_UND (0x1u << 6) /**< \brief (GMAC_TSR) Transmit Under Run */
+#define GMAC_TSR_LCO (0x1u << 7) /**< \brief (GMAC_TSR) Late Collision Occurred */
+#define GMAC_TSR_HRESP (0x1u << 8) /**< \brief (GMAC_TSR) HRESP Not OK */
+/* -------- GMAC_RBQB : (GMAC Offset: 0x018) Receive Buffer Queue Base Address -------- */
+#define GMAC_RBQB_ADDR_Pos 2
+#define GMAC_RBQB_ADDR_Msk (0x3fffffffu << GMAC_RBQB_ADDR_Pos) /**< \brief (GMAC_RBQB) Receive buffer queue base address */
+#define GMAC_RBQB_ADDR(value) ((GMAC_RBQB_ADDR_Msk & ((value) << GMAC_RBQB_ADDR_Pos)))
+/* -------- GMAC_TBQB : (GMAC Offset: 0x01C) Transmit Buffer Queue Base Address -------- */
+#define GMAC_TBQB_ADDR_Pos 2
+#define GMAC_TBQB_ADDR_Msk (0x3fffffffu << GMAC_TBQB_ADDR_Pos) /**< \brief (GMAC_TBQB) Transmit Buffer Queue Base Address */
+#define GMAC_TBQB_ADDR(value) ((GMAC_TBQB_ADDR_Msk & ((value) << GMAC_TBQB_ADDR_Pos)))
+/* -------- GMAC_RSR : (GMAC Offset: 0x020) Receive Status Register -------- */
+#define GMAC_RSR_BNA (0x1u << 0) /**< \brief (GMAC_RSR) Buffer Not Available */
+#define GMAC_RSR_REC (0x1u << 1) /**< \brief (GMAC_RSR) Frame Received */
+#define GMAC_RSR_RXOVR (0x1u << 2) /**< \brief (GMAC_RSR) Receive Overrun */
+#define GMAC_RSR_HNO (0x1u << 3) /**< \brief (GMAC_RSR) HRESP Not OK */
+/* -------- GMAC_ISR : (GMAC Offset: 0x024) Interrupt Status Register -------- */
+#define GMAC_ISR_MFS (0x1u << 0) /**< \brief (GMAC_ISR) Management Frame Sent */
+#define GMAC_ISR_RCOMP (0x1u << 1) /**< \brief (GMAC_ISR) Receive Complete */
+#define GMAC_ISR_RXUBR (0x1u << 2) /**< \brief (GMAC_ISR) RX Used Bit Read */
+#define GMAC_ISR_TXUBR (0x1u << 3) /**< \brief (GMAC_ISR) TX Used Bit Read */
+#define GMAC_ISR_TUR (0x1u << 4) /**< \brief (GMAC_ISR) Transmit Under Run */
+#define GMAC_ISR_RLEX (0x1u << 5) /**< \brief (GMAC_ISR) Retry Limit Exceeded or Late Collision */
+#define GMAC_ISR_TFC (0x1u << 6) /**< \brief (GMAC_ISR) Transmit Frame Corruption due to AHB error */
+#define GMAC_ISR_TCOMP (0x1u << 7) /**< \brief (GMAC_ISR) Transmit Complete */
+#define GMAC_ISR_ROVR (0x1u << 10) /**< \brief (GMAC_ISR) Receive Overrun */
+#define GMAC_ISR_HRESP (0x1u << 11) /**< \brief (GMAC_ISR) HRESP Not OK */
+#define GMAC_ISR_PFNZ (0x1u << 12) /**< \brief (GMAC_ISR) Pause Frame with Non-zero Pause Quantum Received */
+#define GMAC_ISR_PTZ (0x1u << 13) /**< \brief (GMAC_ISR) Pause Time Zero */
+#define GMAC_ISR_PFTR (0x1u << 14) /**< \brief (GMAC_ISR) Pause Frame Transmitted */
+#define GMAC_ISR_EXINT (0x1u << 15) /**< \brief (GMAC_ISR) External Interrupt */
+#define GMAC_ISR_DRQFR (0x1u << 18) /**< \brief (GMAC_ISR) PTP Delay Request Frame Received */
+#define GMAC_ISR_SFR (0x1u << 19) /**< \brief (GMAC_ISR) PTP Sync Frame Received */
+#define GMAC_ISR_DRQFT (0x1u << 20) /**< \brief (GMAC_ISR) PTP Delay Request Frame Transmitted */
+#define GMAC_ISR_SFT (0x1u << 21) /**< \brief (GMAC_ISR) PTP Sync Frame Transmitted */
+#define GMAC_ISR_PDRQFR (0x1u << 22) /**< \brief (GMAC_ISR) PDelay Request Frame Received */
+#define GMAC_ISR_PDRSFR (0x1u << 23) /**< \brief (GMAC_ISR) PDelay Response Frame Received */
+#define GMAC_ISR_PDRQFT (0x1u << 24) /**< \brief (GMAC_ISR) PDelay Request Frame Transmitted */
+#define GMAC_ISR_PDRSFT (0x1u << 25) /**< \brief (GMAC_ISR) PDelay Response Frame Transmitted */
+#define GMAC_ISR_SRI (0x1u << 26) /**< \brief (GMAC_ISR) TSU Seconds Register Increment */
+#define GMAC_ISR_WOL (0x1u << 28) /**< \brief (GMAC_ISR) Wake On LAN */
+/* -------- GMAC_IER : (GMAC Offset: 0x028) Interrupt Enable Register -------- */
+#define GMAC_IER_MFS (0x1u << 0) /**< \brief (GMAC_IER) Management Frame Sent */
+#define GMAC_IER_RCOMP (0x1u << 1) /**< \brief (GMAC_IER) Receive Complete */
+#define GMAC_IER_RXUBR (0x1u << 2) /**< \brief (GMAC_IER) RX Used Bit Read */
+#define GMAC_IER_TXUBR (0x1u << 3) /**< \brief (GMAC_IER) TX Used Bit Read */
+#define GMAC_IER_TUR (0x1u << 4) /**< \brief (GMAC_IER) Transmit Under Run */
+#define GMAC_IER_RLEX (0x1u << 5) /**< \brief (GMAC_IER) Retry Limit Exceeded or Late Collision */
+#define GMAC_IER_TFC (0x1u << 6) /**< \brief (GMAC_IER) Transmit Frame Corruption due to AHB error */
+#define GMAC_IER_TCOMP (0x1u << 7) /**< \brief (GMAC_IER) Transmit Complete */
+#define GMAC_IER_ROVR (0x1u << 10) /**< \brief (GMAC_IER) Receive Overrun */
+#define GMAC_IER_HRESP (0x1u << 11) /**< \brief (GMAC_IER) HRESP Not OK */
+#define GMAC_IER_PFNZ (0x1u << 12) /**< \brief (GMAC_IER) Pause Frame with Non-zero Pause Quantum Received */
+#define GMAC_IER_PTZ (0x1u << 13) /**< \brief (GMAC_IER) Pause Time Zero */
+#define GMAC_IER_PFTR (0x1u << 14) /**< \brief (GMAC_IER) Pause Frame Transmitted */
+#define GMAC_IER_EXINT (0x1u << 15) /**< \brief (GMAC_IER) External Interrupt */
+#define GMAC_IER_DRQFR (0x1u << 18) /**< \brief (GMAC_IER) PTP Delay Request Frame Received */
+#define GMAC_IER_SFR (0x1u << 19) /**< \brief (GMAC_IER) PTP Sync Frame Received */
+#define GMAC_IER_DRQFT (0x1u << 20) /**< \brief (GMAC_IER) PTP Delay Request Frame Transmitted */
+#define GMAC_IER_SFT (0x1u << 21) /**< \brief (GMAC_IER) PTP Sync Frame Transmitted */
+#define GMAC_IER_PDRQFR (0x1u << 22) /**< \brief (GMAC_IER) PDelay Request Frame Received */
+#define GMAC_IER_PDRSFR (0x1u << 23) /**< \brief (GMAC_IER) PDelay Response Frame Received */
+#define GMAC_IER_PDRQFT (0x1u << 24) /**< \brief (GMAC_IER) PDelay Request Frame Transmitted */
+#define GMAC_IER_PDRSFT (0x1u << 25) /**< \brief (GMAC_IER) PDelay Response Frame Transmitted */
+#define GMAC_IER_SRI (0x1u << 26) /**< \brief (GMAC_IER) TSU Seconds Register Increment */
+#define GMAC_IER_WOL (0x1u << 28) /**< \brief (GMAC_IER) Wake On LAN */
+/* -------- GMAC_IDR : (GMAC Offset: 0x02C) Interrupt Disable Register -------- */
+#define GMAC_IDR_MFS (0x1u << 0) /**< \brief (GMAC_IDR) Management Frame Sent */
+#define GMAC_IDR_RCOMP (0x1u << 1) /**< \brief (GMAC_IDR) Receive Complete */
+#define GMAC_IDR_RXUBR (0x1u << 2) /**< \brief (GMAC_IDR) RX Used Bit Read */
+#define GMAC_IDR_TXUBR (0x1u << 3) /**< \brief (GMAC_IDR) TX Used Bit Read */
+#define GMAC_IDR_TUR (0x1u << 4) /**< \brief (GMAC_IDR) Transmit Under Run */
+#define GMAC_IDR_RLEX (0x1u << 5) /**< \brief (GMAC_IDR) Retry Limit Exceeded or Late Collision */
+#define GMAC_IDR_TFC (0x1u << 6) /**< \brief (GMAC_IDR) Transmit Frame Corruption due to AHB error */
+#define GMAC_IDR_TCOMP (0x1u << 7) /**< \brief (GMAC_IDR) Transmit Complete */
+#define GMAC_IDR_ROVR (0x1u << 10) /**< \brief (GMAC_IDR) Receive Overrun */
+#define GMAC_IDR_HRESP (0x1u << 11) /**< \brief (GMAC_IDR) HRESP Not OK */
+#define GMAC_IDR_PFNZ (0x1u << 12) /**< \brief (GMAC_IDR) Pause Frame with Non-zero Pause Quantum Received */
+#define GMAC_IDR_PTZ (0x1u << 13) /**< \brief (GMAC_IDR) Pause Time Zero */
+#define GMAC_IDR_PFTR (0x1u << 14) /**< \brief (GMAC_IDR) Pause Frame Transmitted */
+#define GMAC_IDR_EXINT (0x1u << 15) /**< \brief (GMAC_IDR) External Interrupt */
+#define GMAC_IDR_DRQFR (0x1u << 18) /**< \brief (GMAC_IDR) PTP Delay Request Frame Received */
+#define GMAC_IDR_SFR (0x1u << 19) /**< \brief (GMAC_IDR) PTP Sync Frame Received */
+#define GMAC_IDR_DRQFT (0x1u << 20) /**< \brief (GMAC_IDR) PTP Delay Request Frame Transmitted */
+#define GMAC_IDR_SFT (0x1u << 21) /**< \brief (GMAC_IDR) PTP Sync Frame Transmitted */
+#define GMAC_IDR_PDRQFR (0x1u << 22) /**< \brief (GMAC_IDR) PDelay Request Frame Received */
+#define GMAC_IDR_PDRSFR (0x1u << 23) /**< \brief (GMAC_IDR) PDelay Response Frame Received */
+#define GMAC_IDR_PDRQFT (0x1u << 24) /**< \brief (GMAC_IDR) PDelay Request Frame Transmitted */
+#define GMAC_IDR_PDRSFT (0x1u << 25) /**< \brief (GMAC_IDR) PDelay Response Frame Transmitted */
+#define GMAC_IDR_SRI (0x1u << 26) /**< \brief (GMAC_IDR) TSU Seconds Register Increment */
+#define GMAC_IDR_WOL (0x1u << 28) /**< \brief (GMAC_IDR) Wake On LAN */
+/* -------- GMAC_IMR : (GMAC Offset: 0x030) Interrupt Mask Register -------- */
+#define GMAC_IMR_MFS (0x1u << 0) /**< \brief (GMAC_IMR) Management Frame Sent */
+#define GMAC_IMR_RCOMP (0x1u << 1) /**< \brief (GMAC_IMR) Receive Complete */
+#define GMAC_IMR_RXUBR (0x1u << 2) /**< \brief (GMAC_IMR) RX Used Bit Read */
+#define GMAC_IMR_TXUBR (0x1u << 3) /**< \brief (GMAC_IMR) TX Used Bit Read */
+#define GMAC_IMR_TUR (0x1u << 4) /**< \brief (GMAC_IMR) Transmit Under Run */
+#define GMAC_IMR_RLEX (0x1u << 5) /**< \brief (GMAC_IMR) Retry Limit Exceeded or Late Collision */
+#define GMAC_IMR_TFC (0x1u << 6) /**< \brief (GMAC_IMR) Transmit Frame Corruption due to AHB error */
+#define GMAC_IMR_TCOMP (0x1u << 7) /**< \brief (GMAC_IMR) Transmit Complete */
+#define GMAC_IMR_ROVR (0x1u << 10) /**< \brief (GMAC_IMR) Receive Overrun */
+#define GMAC_IMR_HRESP (0x1u << 11) /**< \brief (GMAC_IMR) HRESP Not OK */
+#define GMAC_IMR_PFNZ (0x1u << 12) /**< \brief (GMAC_IMR) Pause Frame with Non-zero Pause Quantum Received */
+#define GMAC_IMR_PTZ (0x1u << 13) /**< \brief (GMAC_IMR) Pause Time Zero */
+#define GMAC_IMR_PFTR (0x1u << 14) /**< \brief (GMAC_IMR) Pause Frame Transmitted */
+#define GMAC_IMR_EXINT (0x1u << 15) /**< \brief (GMAC_IMR) External Interrupt */
+#define GMAC_IMR_DRQFR (0x1u << 18) /**< \brief (GMAC_IMR) PTP Delay Request Frame Received */
+#define GMAC_IMR_SFR (0x1u << 19) /**< \brief (GMAC_IMR) PTP Sync Frame Received */
+#define GMAC_IMR_DRQFT (0x1u << 20) /**< \brief (GMAC_IMR) PTP Delay Request Frame Transmitted */
+#define GMAC_IMR_SFT (0x1u << 21) /**< \brief (GMAC_IMR) PTP Sync Frame Transmitted */
+#define GMAC_IMR_PDRQFR (0x1u << 22) /**< \brief (GMAC_IMR) PDelay Request Frame Received */
+#define GMAC_IMR_PDRSFR (0x1u << 23) /**< \brief (GMAC_IMR) PDelay Response Frame Received */
+#define GMAC_IMR_PDRQFT (0x1u << 24) /**< \brief (GMAC_IMR) PDelay Request Frame Transmitted */
+#define GMAC_IMR_PDRSFT (0x1u << 25) /**< \brief (GMAC_IMR) PDelay Response Frame Transmitted */
+/* -------- GMAC_MAN : (GMAC Offset: 0x034) PHY Maintenance Register -------- */
+#define GMAC_MAN_DATA_Pos 0
+#define GMAC_MAN_DATA_Msk (0xffffu << GMAC_MAN_DATA_Pos) /**< \brief (GMAC_MAN) PHY Data */
+#define GMAC_MAN_DATA(value) ((GMAC_MAN_DATA_Msk & ((value) << GMAC_MAN_DATA_Pos)))
+#define GMAC_MAN_WTN_Pos 16
+#define GMAC_MAN_WTN_Msk (0x3u << GMAC_MAN_WTN_Pos) /**< \brief (GMAC_MAN) Write Ten */
+#define GMAC_MAN_WTN(value) ((GMAC_MAN_WTN_Msk & ((value) << GMAC_MAN_WTN_Pos)))
+#define GMAC_MAN_REGA_Pos 18
+#define GMAC_MAN_REGA_Msk (0x1fu << GMAC_MAN_REGA_Pos) /**< \brief (GMAC_MAN) Register Address */
+#define GMAC_MAN_REGA(value) ((GMAC_MAN_REGA_Msk & ((value) << GMAC_MAN_REGA_Pos)))
+#define GMAC_MAN_PHYA_Pos 23
+#define GMAC_MAN_PHYA_Msk (0x1fu << GMAC_MAN_PHYA_Pos) /**< \brief (GMAC_MAN) PHY Address */
+#define GMAC_MAN_PHYA(value) ((GMAC_MAN_PHYA_Msk & ((value) << GMAC_MAN_PHYA_Pos)))
+#define GMAC_MAN_OP_Pos 28
+#define GMAC_MAN_OP_Msk (0x3u << GMAC_MAN_OP_Pos) /**< \brief (GMAC_MAN) Operation */
+#define GMAC_MAN_OP(value) ((GMAC_MAN_OP_Msk & ((value) << GMAC_MAN_OP_Pos)))
+#define GMAC_MAN_CLTTO (0x1u << 30) /**< \brief (GMAC_MAN) Clause 22 Operation */
+#define GMAC_MAN_WZO (0x1u << 31) /**< \brief (GMAC_MAN) Write ZERO */
+/* -------- GMAC_RPQ : (GMAC Offset: 0x038) Received Pause Quantum Register -------- */
+#define GMAC_RPQ_RPQ_Pos 0
+#define GMAC_RPQ_RPQ_Msk (0xffffu << GMAC_RPQ_RPQ_Pos) /**< \brief (GMAC_RPQ) Received Pause Quantum */
+/* -------- GMAC_TPQ : (GMAC Offset: 0x03C) Transmit Pause Quantum Register -------- */
+#define GMAC_TPQ_TPQ_Pos 0
+#define GMAC_TPQ_TPQ_Msk (0xffffu << GMAC_TPQ_TPQ_Pos) /**< \brief (GMAC_TPQ) Transmit Pause Quantum */
+#define GMAC_TPQ_TPQ(value) ((GMAC_TPQ_TPQ_Msk & ((value) << GMAC_TPQ_TPQ_Pos)))
+/* -------- GMAC_TPSF : (GMAC Offset: 0x040) TX Partial Store and Forward Register -------- */
+#define GMAC_TPSF_TPB1ADR_Pos 0
+#define GMAC_TPSF_TPB1ADR_Msk (0xfffu << GMAC_TPSF_TPB1ADR_Pos) /**< \brief (GMAC_TPSF) tx_pbuf_addr-1:0 */
+#define GMAC_TPSF_TPB1ADR(value) ((GMAC_TPSF_TPB1ADR_Msk & ((value) << GMAC_TPSF_TPB1ADR_Pos)))
+#define GMAC_TPSF_ENTXP (0x1u << 31) /**< \brief (GMAC_TPSF) Enable TX Partial Store and Forward Operation */
+/* -------- GMAC_RPSF : (GMAC Offset: 0x044) RX Partial Store and Forward Register -------- */
+#define GMAC_RPSF_RPB1ADR_Pos 0
+#define GMAC_RPSF_RPB1ADR_Msk (0xfffu << GMAC_RPSF_RPB1ADR_Pos) /**< \brief (GMAC_RPSF) rx_pbuf_addr-1:0 */
+#define GMAC_RPSF_RPB1ADR(value) ((GMAC_RPSF_RPB1ADR_Msk & ((value) << GMAC_RPSF_RPB1ADR_Pos)))
+#define GMAC_RPSF_ENRXP (0x1u << 31) /**< \brief (GMAC_RPSF) Enable RX Partial Store and Forward Operation */
+/* -------- GMAC_HRB : (GMAC Offset: 0x080) Hash Register Bottom [31:0] -------- */
+#define GMAC_HRB_ADDR_Pos 0
+#define GMAC_HRB_ADDR_Msk (0xffffffffu << GMAC_HRB_ADDR_Pos) /**< \brief (GMAC_HRB) Hash Address */
+#define GMAC_HRB_ADDR(value) ((GMAC_HRB_ADDR_Msk & ((value) << GMAC_HRB_ADDR_Pos)))
+/* -------- GMAC_HRT : (GMAC Offset: 0x084) Hash Register Top [63:32] -------- */
+#define GMAC_HRT_ADDR_Pos 0
+#define GMAC_HRT_ADDR_Msk (0xffffffffu << GMAC_HRT_ADDR_Pos) /**< \brief (GMAC_HRT) Hash Address */
+#define GMAC_HRT_ADDR(value) ((GMAC_HRT_ADDR_Msk & ((value) << GMAC_HRT_ADDR_Pos)))
+/* -------- GMAC_SAB1 : (GMAC Offset: 0x088) Specific Address 1 Bottom [31:0] Register -------- */
+#define GMAC_SAB1_ADDR_Pos 0
+#define GMAC_SAB1_ADDR_Msk (0xffffffffu << GMAC_SAB1_ADDR_Pos) /**< \brief (GMAC_SAB1) Specific Address 1 */
+#define GMAC_SAB1_ADDR(value) ((GMAC_SAB1_ADDR_Msk & ((value) << GMAC_SAB1_ADDR_Pos)))
+/* -------- GMAC_SAT1 : (GMAC Offset: 0x08C) Specific Address 1 Top [47:32] Register -------- */
+#define GMAC_SAT1_ADDR_Pos 0
+#define GMAC_SAT1_ADDR_Msk (0xffffu << GMAC_SAT1_ADDR_Pos) /**< \brief (GMAC_SAT1) Specific Address 1 */
+#define GMAC_SAT1_ADDR(value) ((GMAC_SAT1_ADDR_Msk & ((value) << GMAC_SAT1_ADDR_Pos)))
+/* -------- GMAC_SAB2 : (GMAC Offset: 0x090) Specific Address 2 Bottom [31:0] Register -------- */
+#define GMAC_SAB2_ADDR_Pos 0
+#define GMAC_SAB2_ADDR_Msk (0xffffffffu << GMAC_SAB2_ADDR_Pos) /**< \brief (GMAC_SAB2) Specific Address 2 */
+#define GMAC_SAB2_ADDR(value) ((GMAC_SAB2_ADDR_Msk & ((value) << GMAC_SAB2_ADDR_Pos)))
+/* -------- GMAC_SAT2 : (GMAC Offset: 0x094) Specific Address 2 Top [47:32] Register -------- */
+#define GMAC_SAT2_ADDR_Pos 0
+#define GMAC_SAT2_ADDR_Msk (0xffffu << GMAC_SAT2_ADDR_Pos) /**< \brief (GMAC_SAT2) Specific Address 2 */
+#define GMAC_SAT2_ADDR(value) ((GMAC_SAT2_ADDR_Msk & ((value) << GMAC_SAT2_ADDR_Pos)))
+/* -------- GMAC_SAB3 : (GMAC Offset: 0x098) Specific Address 3 Bottom [31:0] Register -------- */
+#define GMAC_SAB3_ADDR_Pos 0
+#define GMAC_SAB3_ADDR_Msk (0xffffffffu << GMAC_SAB3_ADDR_Pos) /**< \brief (GMAC_SAB3) Specific Address 3 */
+#define GMAC_SAB3_ADDR(value) ((GMAC_SAB3_ADDR_Msk & ((value) << GMAC_SAB3_ADDR_Pos)))
+/* -------- GMAC_SAT3 : (GMAC Offset: 0x09C) Specific Address 3 Top [47:32] Register -------- */
+#define GMAC_SAT3_ADDR_Pos 0
+#define GMAC_SAT3_ADDR_Msk (0xffffu << GMAC_SAT3_ADDR_Pos) /**< \brief (GMAC_SAT3) Specific Address 3 */
+#define GMAC_SAT3_ADDR(value) ((GMAC_SAT3_ADDR_Msk & ((value) << GMAC_SAT3_ADDR_Pos)))
+/* -------- GMAC_SAB4 : (GMAC Offset: 0x0A0) Specific Address 4 Bottom [31:0] Register -------- */
+#define GMAC_SAB4_ADDR_Pos 0
+#define GMAC_SAB4_ADDR_Msk (0xffffffffu << GMAC_SAB4_ADDR_Pos) /**< \brief (GMAC_SAB4) Specific Address 4 */
+#define GMAC_SAB4_ADDR(value) ((GMAC_SAB4_ADDR_Msk & ((value) << GMAC_SAB4_ADDR_Pos)))
+/* -------- GMAC_SAT4 : (GMAC Offset: 0x0A4) Specific Address 4 Top [47:32] Register -------- */
+#define GMAC_SAT4_ADDR_Pos 0
+#define GMAC_SAT4_ADDR_Msk (0xffffu << GMAC_SAT4_ADDR_Pos) /**< \brief (GMAC_SAT4) Specific Address 4 */
+#define GMAC_SAT4_ADDR(value) ((GMAC_SAT4_ADDR_Msk & ((value) << GMAC_SAT4_ADDR_Pos)))
+/* -------- GMAC_TIDM[4] : (GMAC Offset: 0x0A8) Type ID Match 1 Register -------- */
+#define GMAC_TIDM_TID_Pos 0
+#define GMAC_TIDM_TID_Msk (0xffffu << GMAC_TIDM_TID_Pos) /**< \brief (GMAC_TIDM[4]) Type ID Match 1 */
+#define GMAC_TIDM_TID(value) ((GMAC_TIDM_TID_Msk & ((value) << GMAC_TIDM_TID_Pos)))
+/* -------- GMAC_WOL : (GMAC Offset: 0x0B8) Wake on LAN Register -------- */
+#define GMAC_WOL_IP_Pos 0
+#define GMAC_WOL_IP_Msk (0xffffu << GMAC_WOL_IP_Pos) /**< \brief (GMAC_WOL) ARP Request IP Address */
+#define GMAC_WOL_IP(value) ((GMAC_WOL_IP_Msk & ((value) << GMAC_WOL_IP_Pos)))
+#define GMAC_WOL_MAG (0x1u << 16) /**< \brief (GMAC_WOL) Magic Packet Event Enable */
+#define GMAC_WOL_ARP (0x1u << 17) /**< \brief (GMAC_WOL) ARP Request IP Address */
+#define GMAC_WOL_SA1 (0x1u << 18) /**< \brief (GMAC_WOL) Specific Address Register 1 Event Enable */
+#define GMAC_WOL_MTI (0x1u << 19) /**< \brief (GMAC_WOL) Multicast Hash Event Enable */
+/* -------- GMAC_IPGS : (GMAC Offset: 0x0BC) IPG Stretch Register -------- */
+#define GMAC_IPGS_FL_Pos 0
+#define GMAC_IPGS_FL_Msk (0xffffu << GMAC_IPGS_FL_Pos) /**< \brief (GMAC_IPGS) Frame Length */
+#define GMAC_IPGS_FL(value) ((GMAC_IPGS_FL_Msk & ((value) << GMAC_IPGS_FL_Pos)))
+/* -------- GMAC_SVLAN : (GMAC Offset: 0x0C0) Stacked VLAN Register -------- */
+#define GMAC_SVLAN_VLAN_TYPE_Pos 0
+#define GMAC_SVLAN_VLAN_TYPE_Msk (0xffffu << GMAC_SVLAN_VLAN_TYPE_Pos) /**< \brief (GMAC_SVLAN) User Defined VLAN_TYPE Field */
+#define GMAC_SVLAN_VLAN_TYPE(value) ((GMAC_SVLAN_VLAN_TYPE_Msk & ((value) << GMAC_SVLAN_VLAN_TYPE_Pos)))
+#define GMAC_SVLAN_ESVLAN (0x1u << 31) /**< \brief (GMAC_SVLAN) Enable Stacked VLAN Processing Mode */
+/* -------- GMAC_TPFCP : (GMAC Offset: 0x0C4) Transmit PFC Pause Register -------- */
+#define GMAC_TPFCP_PEV_Pos 0
+#define GMAC_TPFCP_PEV_Msk (0xffu << GMAC_TPFCP_PEV_Pos) /**< \brief (GMAC_TPFCP) Priority Enable Vector */
+#define GMAC_TPFCP_PEV(value) ((GMAC_TPFCP_PEV_Msk & ((value) << GMAC_TPFCP_PEV_Pos)))
+#define GMAC_TPFCP_PQ_Pos 8
+#define GMAC_TPFCP_PQ_Msk (0xffu << GMAC_TPFCP_PQ_Pos) /**< \brief (GMAC_TPFCP) Pause Quantum */
+#define GMAC_TPFCP_PQ(value) ((GMAC_TPFCP_PQ_Msk & ((value) << GMAC_TPFCP_PQ_Pos)))
+/* -------- GMAC_SAMB1 : (GMAC Offset: 0x0C8) Specific Address 1 Mask Bottom [31:0] Register -------- */
+#define GMAC_SAMB1_ADDR_Pos 0
+#define GMAC_SAMB1_ADDR_Msk (0xffffffffu << GMAC_SAMB1_ADDR_Pos) /**< \brief (GMAC_SAMB1) Specific Address 1 Mask */
+#define GMAC_SAMB1_ADDR(value) ((GMAC_SAMB1_ADDR_Msk & ((value) << GMAC_SAMB1_ADDR_Pos)))
+/* -------- GMAC_SAMT1 : (GMAC Offset: 0x0CC) Specific Address 1 Mask Top [47:32] Register -------- */
+#define GMAC_SAMT1_ADDR_Pos 0
+#define GMAC_SAMT1_ADDR_Msk (0xffffu << GMAC_SAMT1_ADDR_Pos) /**< \brief (GMAC_SAMT1) Specific Address 1 Mask */
+#define GMAC_SAMT1_ADDR(value) ((GMAC_SAMT1_ADDR_Msk & ((value) << GMAC_SAMT1_ADDR_Pos)))
+/* -------- GMAC_OTLO : (GMAC Offset: 0x100) Octets Transmitted [31:0] Register -------- */
+#define GMAC_OTLO_TXO_Pos 0
+#define GMAC_OTLO_TXO_Msk (0xffffffffu << GMAC_OTLO_TXO_Pos) /**< \brief (GMAC_OTLO) Transmitted Octets */
+/* -------- GMAC_OTHI : (GMAC Offset: 0x104) Octets Transmitted [47:32] Register -------- */
+#define GMAC_OTHI_TXO_Pos 0
+#define GMAC_OTHI_TXO_Msk (0xffffu << GMAC_OTHI_TXO_Pos) /**< \brief (GMAC_OTHI) Transmitted Octets */
+/* -------- GMAC_FT : (GMAC Offset: 0x108) Frames Transmitted Register -------- */
+#define GMAC_FT_FTX_Pos 0
+#define GMAC_FT_FTX_Msk (0xffffffffu << GMAC_FT_FTX_Pos) /**< \brief (GMAC_FT) Frames Transmitted without Error */
+/* -------- GMAC_BCFT : (GMAC Offset: 0x10C) Broadcast Frames Transmitted Register -------- */
+#define GMAC_BCFT_BFTX_Pos 0
+#define GMAC_BCFT_BFTX_Msk (0xffffffffu << GMAC_BCFT_BFTX_Pos) /**< \brief (GMAC_BCFT) Broadcast Frames Transmitted without Error */
+/* -------- GMAC_MFT : (GMAC Offset: 0x110) Multicast Frames Transmitted Register -------- */
+#define GMAC_MFT_MFTX_Pos 0
+#define GMAC_MFT_MFTX_Msk (0xffffffffu << GMAC_MFT_MFTX_Pos) /**< \brief (GMAC_MFT) Multicast Frames Transmitted without Error */
+/* -------- GMAC_PFT : (GMAC Offset: 0x114) Pause Frames Transmitted Register -------- */
+#define GMAC_PFT_PFTX_Pos 0
+#define GMAC_PFT_PFTX_Msk (0xffffu << GMAC_PFT_PFTX_Pos) /**< \brief (GMAC_PFT) Pause Frames Transmitted Register */
+/* -------- GMAC_BFT64 : (GMAC Offset: 0x118) 64 Byte Frames Transmitted Register -------- */
+#define GMAC_BFT64_NFTX_Pos 0
+#define GMAC_BFT64_NFTX_Msk (0xffffffffu << GMAC_BFT64_NFTX_Pos) /**< \brief (GMAC_BFT64) 64 Byte Frames Transmitted without Error */
+/* -------- GMAC_TBFT127 : (GMAC Offset: 0x11C) 65 to 127 Byte Frames Transmitted Register -------- */
+#define GMAC_TBFT127_NFTX_Pos 0
+#define GMAC_TBFT127_NFTX_Msk (0xffffffffu << GMAC_TBFT127_NFTX_Pos) /**< \brief (GMAC_TBFT127) 65 to 127 Byte Frames Transmitted without Error */
+/* -------- GMAC_TBFT255 : (GMAC Offset: 0x120) 128 to 255 Byte Frames Transmitted Register -------- */
+#define GMAC_TBFT255_NFTX_Pos 0
+#define GMAC_TBFT255_NFTX_Msk (0xffffffffu << GMAC_TBFT255_NFTX_Pos) /**< \brief (GMAC_TBFT255) 128 to 255 Byte Frames Transmitted without Error */
+/* -------- GMAC_TBFT511 : (GMAC Offset: 0x124) 256 to 511 Byte Frames Transmitted Register -------- */
+#define GMAC_TBFT511_NFTX_Pos 0
+#define GMAC_TBFT511_NFTX_Msk (0xffffffffu << GMAC_TBFT511_NFTX_Pos) /**< \brief (GMAC_TBFT511) 256 to 511 Byte Frames Transmitted without Error */
+/* -------- GMAC_TBFT1023 : (GMAC Offset: 0x128) 512 to 1023 Byte Frames Transmitted Register -------- */
+#define GMAC_TBFT1023_NFTX_Pos 0
+#define GMAC_TBFT1023_NFTX_Msk (0xffffffffu << GMAC_TBFT1023_NFTX_Pos) /**< \brief (GMAC_TBFT1023) 512 to 1023 Byte Frames Transmitted without Error */
+/* -------- GMAC_TBFT1518 : (GMAC Offset: 0x12C) 1024 to 1518 Byte Frames Transmitted Register -------- */
+#define GMAC_TBFT1518_NFTX_Pos 0
+#define GMAC_TBFT1518_NFTX_Msk (0xffffffffu << GMAC_TBFT1518_NFTX_Pos) /**< \brief (GMAC_TBFT1518) 1024 to 1518 Byte Frames Transmitted without Error */
+/* -------- GMAC_GTBFT1518 : (GMAC Offset: 0x130) Greater Than 1518 Byte Frames Transmitted Register -------- */
+#define GMAC_GTBFT1518_NFTX_Pos 0
+#define GMAC_GTBFT1518_NFTX_Msk (0xffffffffu << GMAC_GTBFT1518_NFTX_Pos) /**< \brief (GMAC_GTBFT1518) Greater than 1518 Byte Frames Transmitted without Error */
+/* -------- GMAC_TUR : (GMAC Offset: 0x134) Transmit Under Runs Register -------- */
+#define GMAC_TUR_TXUNR_Pos 0
+#define GMAC_TUR_TXUNR_Msk (0x3ffu << GMAC_TUR_TXUNR_Pos) /**< \brief (GMAC_TUR) Transmit Under Runs */
+/* -------- GMAC_SCF : (GMAC Offset: 0x138) Single Collision Frames Register -------- */
+#define GMAC_SCF_SCOL_Pos 0
+#define GMAC_SCF_SCOL_Msk (0x3ffffu << GMAC_SCF_SCOL_Pos) /**< \brief (GMAC_SCF) Single Collision */
+/* -------- GMAC_MCF : (GMAC Offset: 0x13C) Multiple Collision Frames Register -------- */
+#define GMAC_MCF_MCOL_Pos 0
+#define GMAC_MCF_MCOL_Msk (0x3ffffu << GMAC_MCF_MCOL_Pos) /**< \brief (GMAC_MCF) Multiple Collision */
+/* -------- GMAC_EC : (GMAC Offset: 0x140) Excessive Collisions Register -------- */
+#define GMAC_EC_XCOL_Pos 0
+#define GMAC_EC_XCOL_Msk (0x3ffu << GMAC_EC_XCOL_Pos) /**< \brief (GMAC_EC) Excessive Collisions */
+/* -------- GMAC_LC : (GMAC Offset: 0x144) Late Collisions Register -------- */
+#define GMAC_LC_LCOL_Pos 0
+#define GMAC_LC_LCOL_Msk (0x3ffu << GMAC_LC_LCOL_Pos) /**< \brief (GMAC_LC) Late Collisions */
+/* -------- GMAC_DTF : (GMAC Offset: 0x148) Deferred Transmission Frames Register -------- */
+#define GMAC_DTF_DEFT_Pos 0
+#define GMAC_DTF_DEFT_Msk (0x3ffffu << GMAC_DTF_DEFT_Pos) /**< \brief (GMAC_DTF) Deferred Transmission */
+/* -------- GMAC_CSE : (GMAC Offset: 0x14C) Carrier Sense Errors Register -------- */
+#define GMAC_CSE_CSR_Pos 0
+#define GMAC_CSE_CSR_Msk (0x3ffu << GMAC_CSE_CSR_Pos) /**< \brief (GMAC_CSE) Carrier Sense Error */
+/* -------- GMAC_ORLO : (GMAC Offset: 0x150) Octets Received [31:0] Received -------- */
+#define GMAC_ORLO_RXO_Pos 0
+#define GMAC_ORLO_RXO_Msk (0xffffffffu << GMAC_ORLO_RXO_Pos) /**< \brief (GMAC_ORLO) Received Octets */
+/* -------- GMAC_ORHI : (GMAC Offset: 0x154) Octets Received [47:32] Received -------- */
+#define GMAC_ORHI_RXO_Pos 0
+#define GMAC_ORHI_RXO_Msk (0xffffu << GMAC_ORHI_RXO_Pos) /**< \brief (GMAC_ORHI) Received Octets */
+/* -------- GMAC_FR : (GMAC Offset: 0x158) Frames Received Register -------- */
+#define GMAC_FR_FRX_Pos 0
+#define GMAC_FR_FRX_Msk (0xffffffffu << GMAC_FR_FRX_Pos) /**< \brief (GMAC_FR) Frames Received without Error */
+/* -------- GMAC_BCFR : (GMAC Offset: 0x15C) Broadcast Frames Received Register -------- */
+#define GMAC_BCFR_BFRX_Pos 0
+#define GMAC_BCFR_BFRX_Msk (0xffffffffu << GMAC_BCFR_BFRX_Pos) /**< \brief (GMAC_BCFR) Broadcast Frames Received without Error */
+/* -------- GMAC_MFR : (GMAC Offset: 0x160) Multicast Frames Received Register -------- */
+#define GMAC_MFR_MFRX_Pos 0
+#define GMAC_MFR_MFRX_Msk (0xffffffffu << GMAC_MFR_MFRX_Pos) /**< \brief (GMAC_MFR) Multicast Frames Received without Error */
+/* -------- GMAC_PFR : (GMAC Offset: 0x164) Pause Frames Received Register -------- */
+#define GMAC_PFR_PFRX_Pos 0
+#define GMAC_PFR_PFRX_Msk (0xffffu << GMAC_PFR_PFRX_Pos) /**< \brief (GMAC_PFR) Pause Frames Received Register */
+/* -------- GMAC_BFR64 : (GMAC Offset: 0x168) 64 Byte Frames Received Register -------- */
+#define GMAC_BFR64_NFRX_Pos 0
+#define GMAC_BFR64_NFRX_Msk (0xffffffffu << GMAC_BFR64_NFRX_Pos) /**< \brief (GMAC_BFR64) 64 Byte Frames Received without Error */
+/* -------- GMAC_TBFR127 : (GMAC Offset: 0x16C) 65 to 127 Byte Frames Received Register -------- */
+#define GMAC_TBFR127_NFRX_Pos 0
+#define GMAC_TBFR127_NFRX_Msk (0xffffffffu << GMAC_TBFR127_NFRX_Pos) /**< \brief (GMAC_TBFR127) 65 to 127 Byte Frames Received without Error */
+/* -------- GMAC_TBFR255 : (GMAC Offset: 0x170) 128 to 255 Byte Frames Received Register -------- */
+#define GMAC_TBFR255_NFRX_Pos 0
+#define GMAC_TBFR255_NFRX_Msk (0xffffffffu << GMAC_TBFR255_NFRX_Pos) /**< \brief (GMAC_TBFR255) 128 to 255 Byte Frames Received without Error */
+/* -------- GMAC_TBFR511 : (GMAC Offset: 0x174) 256 to 511Byte Frames Received Register -------- */
+#define GMAC_TBFR511_NFRX_Pos 0
+#define GMAC_TBFR511_NFRX_Msk (0xffffffffu << GMAC_TBFR511_NFRX_Pos) /**< \brief (GMAC_TBFR511) 256 to 511 Byte Frames Received without Error */
+/* -------- GMAC_TBFR1023 : (GMAC Offset: 0x178) 512 to 1023 Byte Frames Received Register -------- */
+#define GMAC_TBFR1023_NFRX_Pos 0
+#define GMAC_TBFR1023_NFRX_Msk (0xffffffffu << GMAC_TBFR1023_NFRX_Pos) /**< \brief (GMAC_TBFR1023) 512 to 1023 Byte Frames Received without Error */
+/* -------- GMAC_TBFR1518 : (GMAC Offset: 0x17C) 1024 to 1518 Byte Frames Received Register -------- */
+#define GMAC_TBFR1518_NFRX_Pos 0
+#define GMAC_TBFR1518_NFRX_Msk (0xffffffffu << GMAC_TBFR1518_NFRX_Pos) /**< \brief (GMAC_TBFR1518) 1024 to 1518 Byte Frames Received without Error */
+/* -------- GMAC_TMXBFR : (GMAC Offset: 0x180) 1519 to Maximum Byte Frames Received Register -------- */
+#define GMAC_TMXBFR_NFRX_Pos 0
+#define GMAC_TMXBFR_NFRX_Msk (0xffffffffu << GMAC_TMXBFR_NFRX_Pos) /**< \brief (GMAC_TMXBFR) 1519 to Maximum Byte Frames Received without Error */
+/* -------- GMAC_UFR : (GMAC Offset: 0x184) Undersize Frames Received Register -------- */
+#define GMAC_UFR_UFRX_Pos 0
+#define GMAC_UFR_UFRX_Msk (0x3ffu << GMAC_UFR_UFRX_Pos) /**< \brief (GMAC_UFR) Undersize Frames Received */
+/* -------- GMAC_OFR : (GMAC Offset: 0x188) Oversize Frames Received Register -------- */
+#define GMAC_OFR_OFRX_Pos 0
+#define GMAC_OFR_OFRX_Msk (0x3ffu << GMAC_OFR_OFRX_Pos) /**< \brief (GMAC_OFR) Oversized Frames Received */
+/* -------- GMAC_JR : (GMAC Offset: 0x18C) Jabbers Received Register -------- */
+#define GMAC_JR_JRX_Pos 0
+#define GMAC_JR_JRX_Msk (0x3ffu << GMAC_JR_JRX_Pos) /**< \brief (GMAC_JR) Jabbers Received */
+/* -------- GMAC_FCSE : (GMAC Offset: 0x190) Frame Check Sequence Errors Register -------- */
+#define GMAC_FCSE_FCKR_Pos 0
+#define GMAC_FCSE_FCKR_Msk (0x3ffu << GMAC_FCSE_FCKR_Pos) /**< \brief (GMAC_FCSE) Frame Check Sequence Errors */
+/* -------- GMAC_LFFE : (GMAC Offset: 0x194) Length Field Frame Errors Register -------- */
+#define GMAC_LFFE_LFER_Pos 0
+#define GMAC_LFFE_LFER_Msk (0x3ffu << GMAC_LFFE_LFER_Pos) /**< \brief (GMAC_LFFE) Length Field Frame Errors */
+/* -------- GMAC_RSE : (GMAC Offset: 0x198) Receive Symbol Errors Register -------- */
+#define GMAC_RSE_RXSE_Pos 0
+#define GMAC_RSE_RXSE_Msk (0x3ffu << GMAC_RSE_RXSE_Pos) /**< \brief (GMAC_RSE) Receive Symbol Errors */
+/* -------- GMAC_AE : (GMAC Offset: 0x19C) Alignment Errors Register -------- */
+#define GMAC_AE_AER_Pos 0
+#define GMAC_AE_AER_Msk (0x3ffu << GMAC_AE_AER_Pos) /**< \brief (GMAC_AE) Alignment Errors */
+/* -------- GMAC_RRE : (GMAC Offset: 0x1A0) Receive Resource Errors Register -------- */
+#define GMAC_RRE_RXRER_Pos 0
+#define GMAC_RRE_RXRER_Msk (0x3ffffu << GMAC_RRE_RXRER_Pos) /**< \brief (GMAC_RRE) Receive Resource Errors */
+/* -------- GMAC_ROE : (GMAC Offset: 0x1A4) Receive Overrun Register -------- */
+#define GMAC_ROE_RXOVR_Pos 0
+#define GMAC_ROE_RXOVR_Msk (0x3ffu << GMAC_ROE_RXOVR_Pos) /**< \brief (GMAC_ROE) Receive Overruns */
+/* -------- GMAC_IHCE : (GMAC Offset: 0x1A8) IP Header Checksum Errors Register -------- */
+#define GMAC_IHCE_HCKER_Pos 0
+#define GMAC_IHCE_HCKER_Msk (0xffu << GMAC_IHCE_HCKER_Pos) /**< \brief (GMAC_IHCE) IP Header Checksum Errors */
+/* -------- GMAC_TCE : (GMAC Offset: 0x1AC) TCP Checksum Errors Register -------- */
+#define GMAC_TCE_TCKER_Pos 0
+#define GMAC_TCE_TCKER_Msk (0xffu << GMAC_TCE_TCKER_Pos) /**< \brief (GMAC_TCE) TCP Checksum Errors */
+/* -------- GMAC_UCE : (GMAC Offset: 0x1B0) UDP Checksum Errors Register -------- */
+#define GMAC_UCE_UCKER_Pos 0
+#define GMAC_UCE_UCKER_Msk (0xffu << GMAC_UCE_UCKER_Pos) /**< \brief (GMAC_UCE) UDP Checksum Errors */
+/* -------- GMAC_TSSS : (GMAC Offset: 0x1C8) 1588 Timer Sync Strobe Seconds Register -------- */
+#define GMAC_TSSS_VTS_Pos 0
+#define GMAC_TSSS_VTS_Msk (0xffffffffu << GMAC_TSSS_VTS_Pos) /**< \brief (GMAC_TSSS) Value of Timer Seconds Register Capture */
+#define GMAC_TSSS_VTS(value) ((GMAC_TSSS_VTS_Msk & ((value) << GMAC_TSSS_VTS_Pos)))
+/* -------- GMAC_TSSN : (GMAC Offset: 0x1CC) 1588 Timer Sync Strobe Nanoseconds Register -------- */
+#define GMAC_TSSN_VTN_Pos 0
+#define GMAC_TSSN_VTN_Msk (0x3fffffffu << GMAC_TSSN_VTN_Pos) /**< \brief (GMAC_TSSN) Value Timer Nanoseconds Register Capture */
+#define GMAC_TSSN_VTN(value) ((GMAC_TSSN_VTN_Msk & ((value) << GMAC_TSSN_VTN_Pos)))
+/* -------- GMAC_TS : (GMAC Offset: 0x1D0) 1588 Timer Seconds Register -------- */
+#define GMAC_TS_TCS_Pos 0
+#define GMAC_TS_TCS_Msk (0xffffffffu << GMAC_TS_TCS_Pos) /**< \brief (GMAC_TS) Timer Count in Seconds */
+#define GMAC_TS_TCS(value) ((GMAC_TS_TCS_Msk & ((value) << GMAC_TS_TCS_Pos)))
+/* -------- GMAC_TN : (GMAC Offset: 0x1D4) 1588 Timer Nanoseconds Register -------- */
+#define GMAC_TN_TNS_Pos 0
+#define GMAC_TN_TNS_Msk (0x3fffffffu << GMAC_TN_TNS_Pos) /**< \brief (GMAC_TN) Timer Count in Nanoseconds */
+#define GMAC_TN_TNS(value) ((GMAC_TN_TNS_Msk & ((value) << GMAC_TN_TNS_Pos)))
+/* -------- GMAC_TA : (GMAC Offset: 0x1D8) 1588 Timer Adjust Register -------- */
+#define GMAC_TA_ITDT_Pos 0
+#define GMAC_TA_ITDT_Msk (0x3fffffffu << GMAC_TA_ITDT_Pos) /**< \brief (GMAC_TA) Increment/Decrement */
+#define GMAC_TA_ITDT(value) ((GMAC_TA_ITDT_Msk & ((value) << GMAC_TA_ITDT_Pos)))
+#define GMAC_TA_ADJ (0x1u << 31) /**< \brief (GMAC_TA) Adjust 1588 Timer */
+/* -------- GMAC_TI : (GMAC Offset: 0x1DC) 1588 Timer Increment Register -------- */
+#define GMAC_TI_CNS_Pos 0
+#define GMAC_TI_CNS_Msk (0xffu << GMAC_TI_CNS_Pos) /**< \brief (GMAC_TI) Count Nanoseconds */
+#define GMAC_TI_CNS(value) ((GMAC_TI_CNS_Msk & ((value) << GMAC_TI_CNS_Pos)))
+#define GMAC_TI_ACNS_Pos 8
+#define GMAC_TI_ACNS_Msk (0xffu << GMAC_TI_ACNS_Pos) /**< \brief (GMAC_TI) Alternative Count Nanoseconds */
+#define GMAC_TI_ACNS(value) ((GMAC_TI_ACNS_Msk & ((value) << GMAC_TI_ACNS_Pos)))
+#define GMAC_TI_NIT_Pos 16
+#define GMAC_TI_NIT_Msk (0xffu << GMAC_TI_NIT_Pos) /**< \brief (GMAC_TI) Number of Increments */
+#define GMAC_TI_NIT(value) ((GMAC_TI_NIT_Msk & ((value) << GMAC_TI_NIT_Pos)))
+/* -------- GMAC_EFTS : (GMAC Offset: 0x1E0) PTP Event Frame Transmitted Seconds -------- */
+#define GMAC_EFTS_RUD_Pos 0
+#define GMAC_EFTS_RUD_Msk (0xffffffffu << GMAC_EFTS_RUD_Pos) /**< \brief (GMAC_EFTS) Register Update */
+/* -------- GMAC_EFTN : (GMAC Offset: 0x1E4) PTP Event Frame Transmitted Nanoseconds -------- */
+#define GMAC_EFTN_RUD_Pos 0
+#define GMAC_EFTN_RUD_Msk (0x3fffffffu << GMAC_EFTN_RUD_Pos) /**< \brief (GMAC_EFTN) Register Update */
+/* -------- GMAC_EFRS : (GMAC Offset: 0x1E8) PTP Event Frame Received Seconds -------- */
+#define GMAC_EFRS_RUD_Pos 0
+#define GMAC_EFRS_RUD_Msk (0xffffffffu << GMAC_EFRS_RUD_Pos) /**< \brief (GMAC_EFRS) Register Update */
+/* -------- GMAC_EFRN : (GMAC Offset: 0x1EC) PTP Event Frame Received Nanoseconds -------- */
+#define GMAC_EFRN_RUD_Pos 0
+#define GMAC_EFRN_RUD_Msk (0x3fffffffu << GMAC_EFRN_RUD_Pos) /**< \brief (GMAC_EFRN) Register Update */
+/* -------- GMAC_PEFTS : (GMAC Offset: 0x1F0) PTP Peer Event Frame Transmitted Seconds -------- */
+#define GMAC_PEFTS_RUD_Pos 0
+#define GMAC_PEFTS_RUD_Msk (0xffffffffu << GMAC_PEFTS_RUD_Pos) /**< \brief (GMAC_PEFTS) Register Update */
+/* -------- GMAC_PEFTN : (GMAC Offset: 0x1F4) PTP Peer Event Frame Transmitted Nanoseconds -------- */
+#define GMAC_PEFTN_RUD_Pos 0
+#define GMAC_PEFTN_RUD_Msk (0x3fffffffu << GMAC_PEFTN_RUD_Pos) /**< \brief (GMAC_PEFTN) Register Update */
+/* -------- GMAC_PEFRS : (GMAC Offset: 0x1F8) PTP Peer Event Frame Received Seconds -------- */
+#define GMAC_PEFRS_RUD_Pos 0
+#define GMAC_PEFRS_RUD_Msk (0xffffffffu << GMAC_PEFRS_RUD_Pos) /**< \brief (GMAC_PEFRS) Register Update */
+/* -------- GMAC_PEFRN : (GMAC Offset: 0x1FC) PTP Peer Event Frame Received Nanoseconds -------- */
+#define GMAC_PEFRN_RUD_Pos 0
+#define GMAC_PEFRN_RUD_Msk (0x3fffffffu << GMAC_PEFRN_RUD_Pos) /**< \brief (GMAC_PEFRN) Register Update */
+/* -------- GMAC_ISRPQ[7] : (GMAC Offset: 0x400) Interrupt Status Register Priority Queue -------- */
+#define GMAC_ISRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_ISRPQ[7]) Receive Complete */
+#define GMAC_ISRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_ISRPQ[7]) RX Used Bit Read */
+#define GMAC_ISRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_ISRPQ[7]) Retry Limit Exceeded or Late Collision */
+#define GMAC_ISRPQ_TFC (0x1u << 6) /**< \brief (GMAC_ISRPQ[7]) Transmit Frame Corruption due to AHB error */
+#define GMAC_ISRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_ISRPQ[7]) Transmit Complete */
+#define GMAC_ISRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_ISRPQ[7]) Receive Overrun */
+#define GMAC_ISRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_ISRPQ[7]) HRESP Not OK */
+/* -------- GMAC_TBQBAPQ[7] : (GMAC Offset: 0x440) Transmit Buffer Queue Base Address Priority Queue -------- */
+#define GMAC_TBQBAPQ_TXBQBA_Pos 2
+#define GMAC_TBQBAPQ_TXBQBA_Msk (0x3fu << GMAC_TBQBAPQ_TXBQBA_Pos) /**< \brief (GMAC_TBQBAPQ[7]) Transmit Buffer Queue Base Address */
+#define GMAC_TBQBAPQ_TXBQBA(value) ((GMAC_TBQBAPQ_TXBQBA_Msk & ((value) << GMAC_TBQBAPQ_TXBQBA_Pos)))
+/* -------- GMAC_RBQBAPQ[7] : (GMAC Offset: 0x480) Receive Buffer Queue Base Address Priority Queue -------- */
+#define GMAC_RBQBAPQ_RXBQBA_Pos 2
+#define GMAC_RBQBAPQ_RXBQBA_Msk (0x3fu << GMAC_RBQBAPQ_RXBQBA_Pos) /**< \brief (GMAC_RBQBAPQ[7]) Receive Buffer Queue Base Address */
+#define GMAC_RBQBAPQ_RXBQBA(value) ((GMAC_RBQBAPQ_RXBQBA_Msk & ((value) << GMAC_RBQBAPQ_RXBQBA_Pos)))
+/* -------- GMAC_RBSRPQ[7] : (GMAC Offset: 0x4A0) Receive Buffer Size Register Priority Queue -------- */
+#define GMAC_RBSRPQ_RBS_Pos 0
+#define GMAC_RBSRPQ_RBS_Msk (0xffffu << GMAC_RBSRPQ_RBS_Pos) /**< \brief (GMAC_RBSRPQ[7]) Receive Buffer Size */
+#define GMAC_RBSRPQ_RBS(value) ((GMAC_RBSRPQ_RBS_Msk & ((value) << GMAC_RBSRPQ_RBS_Pos)))
+/* -------- GMAC_ST1RPQ[16] : (GMAC Offset: 0x500) Screening Type1 Register Priority Queue -------- */
+#define GMAC_ST1RPQ_QNB_Pos 0
+#define GMAC_ST1RPQ_QNB_Msk (0xfu << GMAC_ST1RPQ_QNB_Pos) /**< \brief (GMAC_ST1RPQ[16]) Que Number (0->7) */
+#define GMAC_ST1RPQ_QNB(value) ((GMAC_ST1RPQ_QNB_Msk & ((value) << GMAC_ST1RPQ_QNB_Pos)))
+#define GMAC_ST1RPQ_DSTCM_Pos 4
+#define GMAC_ST1RPQ_DSTCM_Msk (0xffu << GMAC_ST1RPQ_DSTCM_Pos) /**< \brief (GMAC_ST1RPQ[16]) Differentiated Services or Traffic Class Match */
+#define GMAC_ST1RPQ_DSTCM(value) ((GMAC_ST1RPQ_DSTCM_Msk & ((value) << GMAC_ST1RPQ_DSTCM_Pos)))
+#define GMAC_ST1RPQ_UDPM_Pos 12
+#define GMAC_ST1RPQ_UDPM_Msk (0xffffu << GMAC_ST1RPQ_UDPM_Pos) /**< \brief (GMAC_ST1RPQ[16]) UDP Port Match */
+#define GMAC_ST1RPQ_UDPM(value) ((GMAC_ST1RPQ_UDPM_Msk & ((value) << GMAC_ST1RPQ_UDPM_Pos)))
+#define GMAC_ST1RPQ_DSTCE (0x1u << 28) /**< \brief (GMAC_ST1RPQ[16]) Differentiated Services or Traffic Class Match Enable */
+#define GMAC_ST1RPQ_UDPE (0x1u << 29) /**< \brief (GMAC_ST1RPQ[16]) UDP Port Match Enable */
+/* -------- GMAC_ST2RPQ[16] : (GMAC Offset: 0x540) Screening Type2 Register Priority Queue -------- */
+#define GMAC_ST2RPQ_QNB_Pos 0
+#define GMAC_ST2RPQ_QNB_Msk (0xfu << GMAC_ST2RPQ_QNB_Pos) /**< \brief (GMAC_ST2RPQ[16]) Que Number (0->7) */
+#define GMAC_ST2RPQ_QNB(value) ((GMAC_ST2RPQ_QNB_Msk & ((value) << GMAC_ST2RPQ_QNB_Pos)))
+#define GMAC_ST2RPQ_VLANP_Pos 4
+#define GMAC_ST2RPQ_VLANP_Msk (0xfu << GMAC_ST2RPQ_VLANP_Pos) /**< \brief (GMAC_ST2RPQ[16]) VLAN Priority */
+#define GMAC_ST2RPQ_VLANP(value) ((GMAC_ST2RPQ_VLANP_Msk & ((value) << GMAC_ST2RPQ_VLANP_Pos)))
+#define GMAC_ST2RPQ_VLANE (0x1u << 8) /**< \brief (GMAC_ST2RPQ[16]) VLAN Enable */
+/* -------- GMAC_IERPQ[7] : (GMAC Offset: 0x600) Interrupt Enable Register Priority Queue -------- */
+#define GMAC_IERPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IERPQ[7]) Receive Complete */
+#define GMAC_IERPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IERPQ[7]) RX Used Bit Read */
+#define GMAC_IERPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IERPQ[7]) Retry Limit Exceeded or Late Collision */
+#define GMAC_IERPQ_TFC (0x1u << 6) /**< \brief (GMAC_IERPQ[7]) Transmit Frame Corruption due to AHB error */
+#define GMAC_IERPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IERPQ[7]) Transmit Complete */
+#define GMAC_IERPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IERPQ[7]) Receive Overrun */
+#define GMAC_IERPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IERPQ[7]) HRESP Not OK */
+/* -------- GMAC_IDRPQ[7] : (GMAC Offset: 0x620) Interrupt Disable Register Priority Queue -------- */
+#define GMAC_IDRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IDRPQ[7]) Receive Complete */
+#define GMAC_IDRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IDRPQ[7]) RX Used Bit Read */
+#define GMAC_IDRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IDRPQ[7]) Retry Limit Exceeded or Late Collision */
+#define GMAC_IDRPQ_TFC (0x1u << 6) /**< \brief (GMAC_IDRPQ[7]) Transmit Frame Corruption due to AHB error */
+#define GMAC_IDRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IDRPQ[7]) Transmit Complete */
+#define GMAC_IDRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IDRPQ[7]) Receive Overrun */
+#define GMAC_IDRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IDRPQ[7]) HRESP Not OK */
+/* -------- GMAC_IMRPQ[7] : (GMAC Offset: 0x640) Interrupt Mask Register Priority Queue -------- */
+#define GMAC_IMRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IMRPQ[7]) Receive Complete */
+#define GMAC_IMRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IMRPQ[7]) RX Used Bit Read */
+#define GMAC_IMRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IMRPQ[7]) Retry Limit Exceeded or Late Collision */
+#define GMAC_IMRPQ_AHB (0x1u << 6) /**< \brief (GMAC_IMRPQ[7]) AHB Error */
+#define GMAC_IMRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IMRPQ[7]) Transmit Complete */
+#define GMAC_IMRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IMRPQ[7]) Receive Overrun */
+#define GMAC_IMRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IMRPQ[7]) HRESP Not OK */
+
+/*@}*/
+
+
+#endif /* _SAM4E_GMAC_COMPONENT_ */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.c
index fc72c6ad9..fe9e2960f 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.c
@@ -1,454 +1,454 @@
- /**
- * \file
- *
- * \brief API driver for KSZ8051MNL PHY component.
- *
- * Copyright (c) 2013 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "FreeRTOSIPConfig.h"
-
-#include "ethernet_phy.h"
-#include "instance/gmac.h"
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-extern "C" {
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-/**
- * \defgroup ksz8051mnl_ethernet_phy_group PHY component (KSZ8051MNL)
- *
- * Driver for the ksz8051mnl component. This driver provides access to the main
- * features of the PHY.
- *
- * \section dependencies Dependencies
- * This driver depends on the following modules:
- * - \ref gmac_group Ethernet Media Access Controller (GMAC) module.
- *
- * @{
- */
-
-SPhyProps phyProps;
-
-/* Max PHY number */
-#define ETH_PHY_MAX_ADDR 31
-
-/* Ethernet PHY operation max retry count */
-#define ETH_PHY_RETRY_MAX 1000000
-
-/* Ethernet PHY operation timeout */
-#define ETH_PHY_TIMEOUT 10
-
-/**
- * \brief Find a valid PHY Address ( from addrStart to 31 ).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param uc_start_addr Start address of the PHY to be searched.
- *
- * \return 0xFF when no valid PHY address is found.
- */
-int ethernet_phy_addr = 0;
-static uint8_t ethernet_phy_find_valid(Gmac *p_gmac, uint8_t uc_phy_addr,
- uint8_t uc_start_addr)
-{
- uint32_t ul_value = 0;
- uint8_t uc_cnt;
- uint8_t uc_phy_address = uc_phy_addr;
-
- gmac_enable_management(p_gmac, true);
-/*
-#define GMII_OUI_MSB 0x0022
-#define GMII_OUI_LSB 0x05
-
-PHYID1 = 0x0022
-PHYID2 = 0x1550
-0001_0101_0101_0000 = 0x1550 <= mask should be 0xFFF0
-*/
- /* Check the current PHY address */
- gmac_phy_read(p_gmac, uc_phy_addr, GMII_PHYID1, &ul_value);
-
- /* Find another one */
- if (ul_value != GMII_OUI_MSB) {
- ethernet_phy_addr = 0xFF;
- for (uc_cnt = uc_start_addr; uc_cnt <= ETH_PHY_MAX_ADDR; uc_cnt++) {
- uc_phy_address = (uc_phy_address + 1) & 0x1F;
- ul_value = 0;
- gmac_phy_read(p_gmac, uc_phy_address, GMII_PHYID1, &ul_value);
- if (ul_value == GMII_OUI_MSB) {
- ethernet_phy_addr = uc_phy_address;
- break;
- }
- }
- }
-
- gmac_enable_management(p_gmac, false);
-
- if (ethernet_phy_addr != 0xFF) {
- gmac_phy_read(p_gmac, uc_phy_address, GMII_BMSR, &ul_value);
- }
- return ethernet_phy_addr;
-}
-
-
-/**
- * \brief Perform a HW initialization to the PHY and set up clocks.
- *
- * This should be called only once to initialize the PHY pre-settings.
- * The PHY address is the reset status of CRS, RXD[3:0] (the emacPins' pullups).
- * The COL pin is used to select MII mode on reset (pulled up for Reduced MII).
- * The RXDV pin is used to select test mode on reset (pulled up for test mode).
- * The above pins should be predefined for corresponding settings in resetPins.
- * The GMAC peripheral pins are configured after the reset is done.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param ul_mck GMAC MCK.
- *
- * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_init(Gmac *p_gmac, uint8_t uc_phy_addr, uint32_t mck)
-{
- uint8_t uc_rc = GMAC_TIMEOUT;
- uint8_t uc_phy;
-
- ethernet_phy_reset(GMAC,uc_phy_addr);
-
- /* Configure GMAC runtime clock */
- uc_rc = gmac_set_mdc_clock(p_gmac, mck);
- if (uc_rc != GMAC_OK) {
- return 0;
- }
-
- /* Check PHY Address */
- uc_phy = ethernet_phy_find_valid(p_gmac, uc_phy_addr, 0);
- if (uc_phy == 0xFF) {
- return 0;
- }
- if (uc_phy != uc_phy_addr) {
- ethernet_phy_reset(p_gmac, uc_phy_addr);
- }
- phy_props.phy_chn = uc_phy;
- return uc_phy;
-}
-
-
-/**
- * \brief Get the Link & speed settings, and automatically set up the GMAC with the
- * settings.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param uc_apply_setting_flag Set to 0 to not apply the PHY configurations, else to apply.
- *
- * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_set_link(Gmac *p_gmac, uint8_t uc_phy_addr,
- uint8_t uc_apply_setting_flag)
-{
- uint32_t ul_stat1;
- uint32_t ul_stat2;
- uint8_t uc_phy_address, uc_speed = true, uc_fd = true;
- uint8_t uc_rc = GMAC_TIMEOUT;
-
- gmac_enable_management(p_gmac, true);
-
- uc_phy_address = uc_phy_addr;
-
- uc_rc = gmac_phy_read(p_gmac, uc_phy_address, GMII_BMSR, &ul_stat1);
- if (uc_rc != GMAC_OK) {
- /* Disable PHY management and start the GMAC transfer */
- gmac_enable_management(p_gmac, false);
-
- return uc_rc;
- }
- if ((ul_stat1 & GMII_LINK_STATUS) == 0) {
- /* Disable PHY management and start the GMAC transfer */
- gmac_enable_management(p_gmac, false);
-
- return GMAC_INVALID;
- }
-
- if (uc_apply_setting_flag == 0) {
- /* Disable PHY management and start the GMAC transfer */
- gmac_enable_management(p_gmac, false);
-
- return uc_rc;
- }
-
- /* Read advertisement */
- uc_rc = gmac_phy_read(p_gmac, uc_phy_address, GMII_ANAR, &ul_stat2);
-phy_props.phy_stat1 = ul_stat1;
-phy_props.phy_stat2 = ul_stat2;
- if (uc_rc != GMAC_OK) {
- /* Disable PHY management and start the GMAC transfer */
- gmac_enable_management(p_gmac, false);
-
- return uc_rc;
- }
-
- if ((ul_stat1 & GMII_100BASE_TX_FD) && (ul_stat2 & GMII_100TX_FDX)) {
- /* Set GMAC for 100BaseTX and Full Duplex */
- uc_speed = true;
- uc_fd = true;
- } else
- if ((ul_stat1 & GMII_100BASE_T4_HD) && (ul_stat2 & GMII_100TX_HDX)) {
- /* Set MII for 100BaseTX and Half Duplex */
- uc_speed = true;
- uc_fd = false;
- } else
- if ((ul_stat1 & GMII_10BASE_T_FD) && (ul_stat2 & GMII_10_FDX)) {
- /* Set MII for 10BaseT and Full Duplex */
- uc_speed = false;
- uc_fd = true;
- } else
- if ((ul_stat1 & GMII_10BASE_T_HD) && (ul_stat2 & GMII_10_HDX)) {
- /* Set MII for 10BaseT and Half Duplex */
- uc_speed = false;
- uc_fd = false;
- }
-
- gmac_set_speed(p_gmac, uc_speed);
- gmac_enable_full_duplex(p_gmac, uc_fd);
-
- /* Start the GMAC transfers */
- gmac_enable_management(p_gmac, false);
- return uc_rc;
-}
-
-PhyProps_t phy_props;
-
-/**
- * \brief Issue an auto negotiation of the PHY.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- *
- * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_auto_negotiate(Gmac *p_gmac, uint8_t uc_phy_addr)
-{
- uint32_t ul_retry_max = ETH_PHY_RETRY_MAX;
- uint32_t ul_value;
- uint32_t ul_phy_anar;
- uint32_t ul_retry_count = 0;
- uint8_t uc_speed = 0;
- uint8_t uc_fd=0;
- uint8_t uc_rc = GMAC_TIMEOUT;
-
- gmac_enable_management(p_gmac, true);
-
- /* Set up control register */
- uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMCR, &ul_value);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -1;
- return uc_rc;
- }
-
- ul_value &= ~(uint32_t)GMII_AUTONEG; /* Remove auto-negotiation enable */
- ul_value &= ~(uint32_t)(GMII_LOOPBACK | GMII_POWER_DOWN);
- ul_value |= (uint32_t)GMII_ISOLATE; /* Electrically isolate PHY */
- uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -2;
- return uc_rc;
- }
-
- /*
- * Set the Auto_negotiation Advertisement Register.
- * MII advertising for Next page.
- * 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3.
- */
- ul_phy_anar = GMII_100TX_FDX | GMII_100TX_HDX | GMII_10_FDX | GMII_10_HDX |
- GMII_AN_IEEE_802_3;
- uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_ANAR, ul_phy_anar);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -3;
- return uc_rc;
- }
-
- /* Read & modify control register */
- uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMCR, &ul_value);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -4;
- return uc_rc;
- }
-
- ul_value |= GMII_SPEED_SELECT | GMII_AUTONEG | GMII_DUPLEX_MODE;
- uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -5;
- return uc_rc;
- }
-
- /* Restart auto negotiation */
- ul_value |= (uint32_t)GMII_RESTART_AUTONEG;
- ul_value &= ~(uint32_t)GMII_ISOLATE;
- uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -6;
- return uc_rc;
- }
-
- /* Check if auto negotiation is completed */
- while (1) {
- uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMSR, &ul_value);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -7;
- return uc_rc;
- }
- /* Done successfully */
- if (ul_value & GMII_AUTONEG_COMP) {
- break;
- }
-
- /* Timeout check */
- if (ul_retry_max) {
- if (++ul_retry_count >= ul_retry_max) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -8;
- return GMAC_TIMEOUT;
- }
- }
- }
-
- /* Get the auto negotiate link partner base page */
- uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_PCR1, &phy_props.phy_params);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -9;
- return uc_rc;
- }
-
-
- /* Set up the GMAC link speed */
- if ((ul_phy_anar & phy_props.phy_params) & GMII_100TX_FDX) {
- /* Set MII for 100BaseTX and Full Duplex */
- uc_speed = true;
- uc_fd = true;
- } else if ((ul_phy_anar & phy_props.phy_params) & GMII_10_FDX) {
- /* Set MII for 10BaseT and Full Duplex */
- uc_speed = false;
- uc_fd = true;
- } else if ((ul_phy_anar & phy_props.phy_params) & GMII_100TX_HDX) {
- /* Set MII for 100BaseTX and half Duplex */
- uc_speed = true;
- uc_fd = false;
- } else if ((ul_phy_anar & phy_props.phy_params) & GMII_10_HDX) {
- /* Set MII for 10BaseT and half Duplex */
- uc_speed = false;
- uc_fd = false;
- }
-
- gmac_set_speed(p_gmac, uc_speed);
- gmac_enable_full_duplex(p_gmac, uc_fd);
-
- /* Select Media Independent Interface type */
- gmac_select_mii_mode(p_gmac, ETH_PHY_MODE);
-
- gmac_enable_transmit(GMAC, true);
- gmac_enable_receive(GMAC, true);
-
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = 1;
- return uc_rc;
-}
-
-/**
- * \brief Issue a SW reset to reset all registers of the PHY.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- *
- * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_reset(Gmac *p_gmac, uint8_t uc_phy_addr)
-{
- uint32_t ul_bmcr = GMII_RESET;
- uint8_t uc_phy_address = uc_phy_addr;
- uint32_t ul_timeout = ETH_PHY_TIMEOUT;
- uint8_t uc_rc = GMAC_TIMEOUT;
-
- gmac_enable_management(p_gmac, true);
-
- ul_bmcr = GMII_RESET;
- gmac_phy_write(p_gmac, uc_phy_address, GMII_BMCR, ul_bmcr);
-
- do {
- gmac_phy_read(p_gmac, uc_phy_address, GMII_BMCR, &ul_bmcr);
- ul_timeout--;
- } while ((ul_bmcr & GMII_RESET) && ul_timeout);
-
- gmac_enable_management(p_gmac, false);
-
- if (!ul_timeout) {
- uc_rc = GMAC_OK;
- }
-
- return (uc_rc);
-}
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-}
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-/**
- * \}
- */
+ /**
+ * \file
+ *
+ * \brief API driver for KSZ8051MNL PHY component.
+ *
+ * Copyright (c) 2013 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "FreeRTOSIPConfig.h"
+
+#include "ethernet_phy.h"
+#include "instance/gmac.h"
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/**
+ * \defgroup ksz8051mnl_ethernet_phy_group PHY component (KSZ8051MNL)
+ *
+ * Driver for the ksz8051mnl component. This driver provides access to the main
+ * features of the PHY.
+ *
+ * \section dependencies Dependencies
+ * This driver depends on the following modules:
+ * - \ref gmac_group Ethernet Media Access Controller (GMAC) module.
+ *
+ * @{
+ */
+
+SPhyProps phyProps;
+
+/* Max PHY number */
+#define ETH_PHY_MAX_ADDR 31
+
+/* Ethernet PHY operation max retry count */
+#define ETH_PHY_RETRY_MAX 1000000
+
+/* Ethernet PHY operation timeout */
+#define ETH_PHY_TIMEOUT 10
+
+/**
+ * \brief Find a valid PHY Address ( from addrStart to 31 ).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param uc_start_addr Start address of the PHY to be searched.
+ *
+ * \return 0xFF when no valid PHY address is found.
+ */
+int ethernet_phy_addr = 0;
+static uint8_t ethernet_phy_find_valid(Gmac *p_gmac, uint8_t uc_phy_addr,
+ uint8_t uc_start_addr)
+{
+ uint32_t ul_value = 0;
+ uint8_t uc_cnt;
+ uint8_t uc_phy_address = uc_phy_addr;
+
+ gmac_enable_management(p_gmac, true);
+/*
+#define GMII_OUI_MSB 0x0022
+#define GMII_OUI_LSB 0x05
+
+PHYID1 = 0x0022
+PHYID2 = 0x1550
+0001_0101_0101_0000 = 0x1550 <= mask should be 0xFFF0
+*/
+ /* Check the current PHY address */
+ gmac_phy_read(p_gmac, uc_phy_addr, GMII_PHYID1, &ul_value);
+
+ /* Find another one */
+ if (ul_value != GMII_OUI_MSB) {
+ ethernet_phy_addr = 0xFF;
+ for (uc_cnt = uc_start_addr; uc_cnt <= ETH_PHY_MAX_ADDR; uc_cnt++) {
+ uc_phy_address = (uc_phy_address + 1) & 0x1F;
+ ul_value = 0;
+ gmac_phy_read(p_gmac, uc_phy_address, GMII_PHYID1, &ul_value);
+ if (ul_value == GMII_OUI_MSB) {
+ ethernet_phy_addr = uc_phy_address;
+ break;
+ }
+ }
+ }
+
+ gmac_enable_management(p_gmac, false);
+
+ if (ethernet_phy_addr != 0xFF) {
+ gmac_phy_read(p_gmac, uc_phy_address, GMII_BMSR, &ul_value);
+ }
+ return ethernet_phy_addr;
+}
+
+
+/**
+ * \brief Perform a HW initialization to the PHY and set up clocks.
+ *
+ * This should be called only once to initialize the PHY pre-settings.
+ * The PHY address is the reset status of CRS, RXD[3:0] (the emacPins' pullups).
+ * The COL pin is used to select MII mode on reset (pulled up for Reduced MII).
+ * The RXDV pin is used to select test mode on reset (pulled up for test mode).
+ * The above pins should be predefined for corresponding settings in resetPins.
+ * The GMAC peripheral pins are configured after the reset is done.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param ul_mck GMAC MCK.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_init(Gmac *p_gmac, uint8_t uc_phy_addr, uint32_t mck)
+{
+ uint8_t uc_rc = GMAC_TIMEOUT;
+ uint8_t uc_phy;
+
+ ethernet_phy_reset(GMAC,uc_phy_addr);
+
+ /* Configure GMAC runtime clock */
+ uc_rc = gmac_set_mdc_clock(p_gmac, mck);
+ if (uc_rc != GMAC_OK) {
+ return 0;
+ }
+
+ /* Check PHY Address */
+ uc_phy = ethernet_phy_find_valid(p_gmac, uc_phy_addr, 0);
+ if (uc_phy == 0xFF) {
+ return 0;
+ }
+ if (uc_phy != uc_phy_addr) {
+ ethernet_phy_reset(p_gmac, uc_phy_addr);
+ }
+ phy_props.phy_chn = uc_phy;
+ return uc_phy;
+}
+
+
+/**
+ * \brief Get the Link & speed settings, and automatically set up the GMAC with the
+ * settings.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param uc_apply_setting_flag Set to 0 to not apply the PHY configurations, else to apply.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_set_link(Gmac *p_gmac, uint8_t uc_phy_addr,
+ uint8_t uc_apply_setting_flag)
+{
+ uint32_t ul_stat1;
+ uint32_t ul_stat2;
+ uint8_t uc_phy_address, uc_speed = true, uc_fd = true;
+ uint8_t uc_rc = GMAC_TIMEOUT;
+
+ gmac_enable_management(p_gmac, true);
+
+ uc_phy_address = uc_phy_addr;
+
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_address, GMII_BMSR, &ul_stat1);
+ if (uc_rc != GMAC_OK) {
+ /* Disable PHY management and start the GMAC transfer */
+ gmac_enable_management(p_gmac, false);
+
+ return uc_rc;
+ }
+ if ((ul_stat1 & GMII_LINK_STATUS) == 0) {
+ /* Disable PHY management and start the GMAC transfer */
+ gmac_enable_management(p_gmac, false);
+
+ return GMAC_INVALID;
+ }
+
+ if (uc_apply_setting_flag == 0) {
+ /* Disable PHY management and start the GMAC transfer */
+ gmac_enable_management(p_gmac, false);
+
+ return uc_rc;
+ }
+
+ /* Read advertisement */
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_address, GMII_ANAR, &ul_stat2);
+phy_props.phy_stat1 = ul_stat1;
+phy_props.phy_stat2 = ul_stat2;
+ if (uc_rc != GMAC_OK) {
+ /* Disable PHY management and start the GMAC transfer */
+ gmac_enable_management(p_gmac, false);
+
+ return uc_rc;
+ }
+
+ if ((ul_stat1 & GMII_100BASE_TX_FD) && (ul_stat2 & GMII_100TX_FDX)) {
+ /* Set GMAC for 100BaseTX and Full Duplex */
+ uc_speed = true;
+ uc_fd = true;
+ } else
+ if ((ul_stat1 & GMII_100BASE_T4_HD) && (ul_stat2 & GMII_100TX_HDX)) {
+ /* Set MII for 100BaseTX and Half Duplex */
+ uc_speed = true;
+ uc_fd = false;
+ } else
+ if ((ul_stat1 & GMII_10BASE_T_FD) && (ul_stat2 & GMII_10_FDX)) {
+ /* Set MII for 10BaseT and Full Duplex */
+ uc_speed = false;
+ uc_fd = true;
+ } else
+ if ((ul_stat1 & GMII_10BASE_T_HD) && (ul_stat2 & GMII_10_HDX)) {
+ /* Set MII for 10BaseT and Half Duplex */
+ uc_speed = false;
+ uc_fd = false;
+ }
+
+ gmac_set_speed(p_gmac, uc_speed);
+ gmac_enable_full_duplex(p_gmac, uc_fd);
+
+ /* Start the GMAC transfers */
+ gmac_enable_management(p_gmac, false);
+ return uc_rc;
+}
+
+PhyProps_t phy_props;
+
+/**
+ * \brief Issue an auto negotiation of the PHY.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_auto_negotiate(Gmac *p_gmac, uint8_t uc_phy_addr)
+{
+ uint32_t ul_retry_max = ETH_PHY_RETRY_MAX;
+ uint32_t ul_value;
+ uint32_t ul_phy_anar;
+ uint32_t ul_retry_count = 0;
+ uint8_t uc_speed = 0;
+ uint8_t uc_fd=0;
+ uint8_t uc_rc = GMAC_TIMEOUT;
+
+ gmac_enable_management(p_gmac, true);
+
+ /* Set up control register */
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMCR, &ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -1;
+ return uc_rc;
+ }
+
+ ul_value &= ~(uint32_t)GMII_AUTONEG; /* Remove auto-negotiation enable */
+ ul_value &= ~(uint32_t)(GMII_LOOPBACK | GMII_POWER_DOWN);
+ ul_value |= (uint32_t)GMII_ISOLATE; /* Electrically isolate PHY */
+ uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -2;
+ return uc_rc;
+ }
+
+ /*
+ * Set the Auto_negotiation Advertisement Register.
+ * MII advertising for Next page.
+ * 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3.
+ */
+ ul_phy_anar = GMII_100TX_FDX | GMII_100TX_HDX | GMII_10_FDX | GMII_10_HDX |
+ GMII_AN_IEEE_802_3;
+ uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_ANAR, ul_phy_anar);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -3;
+ return uc_rc;
+ }
+
+ /* Read & modify control register */
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMCR, &ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -4;
+ return uc_rc;
+ }
+
+ ul_value |= GMII_SPEED_SELECT | GMII_AUTONEG | GMII_DUPLEX_MODE;
+ uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -5;
+ return uc_rc;
+ }
+
+ /* Restart auto negotiation */
+ ul_value |= (uint32_t)GMII_RESTART_AUTONEG;
+ ul_value &= ~(uint32_t)GMII_ISOLATE;
+ uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -6;
+ return uc_rc;
+ }
+
+ /* Check if auto negotiation is completed */
+ while (1) {
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMSR, &ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -7;
+ return uc_rc;
+ }
+ /* Done successfully */
+ if (ul_value & GMII_AUTONEG_COMP) {
+ break;
+ }
+
+ /* Timeout check */
+ if (ul_retry_max) {
+ if (++ul_retry_count >= ul_retry_max) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -8;
+ return GMAC_TIMEOUT;
+ }
+ }
+ }
+
+ /* Get the auto negotiate link partner base page */
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_PCR1, &phy_props.phy_params);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -9;
+ return uc_rc;
+ }
+
+
+ /* Set up the GMAC link speed */
+ if ((ul_phy_anar & phy_props.phy_params) & GMII_100TX_FDX) {
+ /* Set MII for 100BaseTX and Full Duplex */
+ uc_speed = true;
+ uc_fd = true;
+ } else if ((ul_phy_anar & phy_props.phy_params) & GMII_10_FDX) {
+ /* Set MII for 10BaseT and Full Duplex */
+ uc_speed = false;
+ uc_fd = true;
+ } else if ((ul_phy_anar & phy_props.phy_params) & GMII_100TX_HDX) {
+ /* Set MII for 100BaseTX and half Duplex */
+ uc_speed = true;
+ uc_fd = false;
+ } else if ((ul_phy_anar & phy_props.phy_params) & GMII_10_HDX) {
+ /* Set MII for 10BaseT and half Duplex */
+ uc_speed = false;
+ uc_fd = false;
+ }
+
+ gmac_set_speed(p_gmac, uc_speed);
+ gmac_enable_full_duplex(p_gmac, uc_fd);
+
+ /* Select Media Independent Interface type */
+ gmac_select_mii_mode(p_gmac, ETH_PHY_MODE);
+
+ gmac_enable_transmit(GMAC, true);
+ gmac_enable_receive(GMAC, true);
+
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = 1;
+ return uc_rc;
+}
+
+/**
+ * \brief Issue a SW reset to reset all registers of the PHY.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ *
+ * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_reset(Gmac *p_gmac, uint8_t uc_phy_addr)
+{
+ uint32_t ul_bmcr = GMII_RESET;
+ uint8_t uc_phy_address = uc_phy_addr;
+ uint32_t ul_timeout = ETH_PHY_TIMEOUT;
+ uint8_t uc_rc = GMAC_TIMEOUT;
+
+ gmac_enable_management(p_gmac, true);
+
+ ul_bmcr = GMII_RESET;
+ gmac_phy_write(p_gmac, uc_phy_address, GMII_BMCR, ul_bmcr);
+
+ do {
+ gmac_phy_read(p_gmac, uc_phy_address, GMII_BMCR, &ul_bmcr);
+ ul_timeout--;
+ } while ((ul_bmcr & GMII_RESET) && ul_timeout);
+
+ gmac_enable_management(p_gmac, false);
+
+ if (!ul_timeout) {
+ uc_rc = GMAC_OK;
+ }
+
+ return (uc_rc);
+}
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+}
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/**
+ * \}
+ */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.h
index 6729df0fe..8ea5fa0c7 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.h
@@ -1,281 +1,281 @@
-/**
- * \file
- *
- * \brief KSZ8051MNL (Ethernet PHY) driver for SAM.
- *
- * Copyright (c) 2013 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#ifndef ETHERNET_PHY_H_INCLUDED
-#define ETHERNET_PHY_H_INCLUDED
-
-#include "compiler.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// IEEE defined Registers
-#define GMII_BMCR 0x00 // Basic Control
-#define GMII_BMSR 0x01 // Basic Status
-#define GMII_PHYID1 0x02 // PHY Idendifier 1
-#define GMII_PHYID2 0x03 // PHY Idendifier 2
-#define GMII_ANAR 0x04 // Auto_Negotiation Advertisement
-#define GMII_ANLPAR 0x05 // Auto_negotiation Link Partner Ability
-#define GMII_ANER 0x06 // Auto-negotiation Expansion
-#define GMII_ANNPR 0x07 // Auto-negotiation Next Page
-#define GMII_ANLPNPAR 0x08 // Link Partner Next Page Ability
-//#define GMII_1000BTCR 9 // 1000Base-T Control // Reserved
-//#define GMII_1000BTSR 10 // 1000Base-T Status // Reserved
-#define GMII_AFECR1 0x11 // AFE Control 1
-//#define GMII_ERDWR 12 // Extend Register - Data Write Register
-//#define GMII_ERDRR 13 // Extend Register - Data Read Register
-//14 reserved
-#define GMII_RXERCR 0x15 // RXER Counter
-
- #define PHY_REG_01_BMSR 0x01 // Basic mode status register
- #define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1
- #define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2
- #define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg
- #define PHY_REG_05_LPA 0x05 // Link partner ability reg
- #define PHY_REG_06_ANER 0x06 // 6 RW Auto-Negotiation Expansion Register
- #define PHY_REG_07_ANNPTR 0x07 // 7 RW Auto-Negotiation Next Page TX
- #define PHY_REG_08_RESERVED0 0x08 // 0x08..0x0Fh 8-15 RW RESERVED
-
- #define PHY_REG_10_PHYSTS 0x10 // 16 RO PHY Status Register
- #define PHY_REG_11_MICR 0x11 // 17 RW MII Interrupt Control Register
- #define PHY_REG_12_MISR 0x12 // 18 RO MII Interrupt Status Register
- #define PHY_REG_13_RESERVED1 0x13 // 19 RW RESERVED
- #define PHY_REG_14_FCSCR 0x14 // 20 RO False Carrier Sense Counter Register
- #define PHY_REG_15_RECR 0x15 // 21 RO Receive Error Counter Register
- #define PHY_REG_16_PCSR 0x16 // 22 RW PCS Sub-Layer Configuration and Status Register
- #define PHY_REG_17_RBR 0x17 // 23 RW RMII and Bypass Register
- #define PHY_REG_18_LEDCR 0x18 // 24 RW LED Direct Control Register
- #define PHY_REG_19_PHYCR 0x19 // 25 RW PHY Control Register
- #define PHY_REG_1A_10BTSCR 0x1A // 26 RW 10Base-T Status/Control Register
- #define PHY_REG_1B_CDCTRL1 0x1B // 27 RW CD Test Control Register and BIST Extensions Register
- #define PHY_REG_1B_INT_CTRL 0x1B // 27 RW KSZ8041NL interrupt control
- #define PHY_REG_1C_RESERVED2 0x1C // 28 RW RESERVED
- #define PHY_REG_1D_EDCR 0x1D // 29 RW Energy Detect Control Register
- #define PHY_REG_1E_RESERVED3 0x1E //
- #define PHY_REG_1F_RESERVED4 0x1F // 30-31 RW RESERVED
-
- #define PHY_REG_1E_PHYCR_1 0x1E //
- #define PHY_REG_1F_PHYCR_2 0x1F //
-
- #define PHY_SPEED_10 1
- #define PHY_SPEED_100 2
- #define PHY_SPEED_AUTO (PHY_SPEED_10|PHY_SPEED_100)
-
- #define PHY_MDIX_DIRECT 1
- #define PHY_MDIX_CROSSED 2
- #define PHY_MDIX_AUTO (PHY_MDIX_CROSSED|PHY_MDIX_DIRECT)
-
- #define PHY_DUPLEX_HALF 1
- #define PHY_DUPLEX_FULL 2
- #define PHY_DUPLEX_AUTO (PHY_DUPLEX_FULL|PHY_DUPLEX_HALF)
-
- typedef struct _SPhyProps {
- unsigned char speed;
- unsigned char mdix;
- unsigned char duplex;
- unsigned char spare;
- } SPhyProps;
-
- const char *phyPrintable (const SPhyProps *apProps);
-
- extern SPhyProps phyProps;
-
-#define GMII_OMSOR 0x16 // Operation Mode Strap Override
-#define GMII_OMSSR 0x17 // Operation Mode Strap Status
-#define GMII_ECR 0x18 // Expanded Control
-//#define GMII_DPPSR 19 // Digital PMA/PCS Status
-//20 reserved
-//#define GMII_RXERCR 21 // RXER Counter Register
-//22-26 reserved
-#define GMII_ICSR 0x1B // Interrupt Control/Status
-//#define GMII_DDC1R 28 // Digital Debug Control 1 Register
-#define GMII_LCSR 0x1D // LinkMD Control/Status
-
-//29-30 reserved
-#define GMII_PCR1 0x1E // PHY Control 1
-#define GMII_PCR2 0x1F // PHY Control 2
-
-/*
-//Extend Registers
-#define GMII_CCR 256 // Common Control Register
-#define GMII_SSR 257 // Strap Status Register
-#define GMII_OMSOR 258 // Operation Mode Strap Override Register
-#define GMII_OMSSR 259 // Operation Mode Strap Status Register
-#define GMII_RCCPSR 260 // RGMII Clock and Control Pad Skew Register
-#define GMII_RRDPSR 261 // RGMII RX Data Pad Skew Register
-#define GMII_ATR 263 // Analog Test Register
-*/
-
-
-// Bit definitions: GMII_BMCR 0x00 Basic Control
-#define GMII_RESET (1 << 15) // 1= Software Reset; 0=Normal Operation
-#define GMII_LOOPBACK (1 << 14) // 1=loopback Enabled; 0=Normal Operation
-#define GMII_SPEED_SELECT (1 << 13) // 1=100Mbps; 0=10Mbps
-#define GMII_AUTONEG (1 << 12) // Auto-negotiation Enable
-#define GMII_POWER_DOWN (1 << 11) // 1=Power down 0=Normal operation
-#define GMII_ISOLATE (1 << 10) // 1 = Isolates 0 = Normal operation
-#define GMII_RESTART_AUTONEG (1 << 9) // 1 = Restart auto-negotiation 0 = Normal operation
-#define GMII_DUPLEX_MODE (1 << 8) // 1 = Full duplex operation 0 = Normal operation
-#define GMII_COLLISION_TEST (1 << 7) // 1 = Enable COL test; 0 = Disable COL test
-//#define GMII_SPEED_SELECT_MSB (1 << 6) // Reserved
-// Reserved 6 to 0 // Read as 0, ignore on write
-
-// Bit definitions: GMII_BMSR 0x01 Basic Status
-#define GMII_100BASE_T4 (1 << 15) // 100BASE-T4 Capable
-#define GMII_100BASE_TX_FD (1 << 14) // 100BASE-TX Full Duplex Capable
-#define GMII_100BASE_T4_HD (1 << 13) // 100BASE-TX Half Duplex Capable
-#define GMII_10BASE_T_FD (1 << 12) // 10BASE-T Full Duplex Capable
-#define GMII_10BASE_T_HD (1 << 11) // 10BASE-T Half Duplex Capable
-// Reserved 10 to79 // Read as 0, ignore on write
-//#define GMII_EXTEND_STATUS (1 << 8) // 1 = Extend Status Information In Reg 15
-// Reserved 7
-#define GMII_MF_PREAMB_SUPPR (1 << 6) // MII Frame Preamble Suppression
-#define GMII_AUTONEG_COMP (1 << 5) // Auto-negotiation Complete
-#define GMII_REMOTE_FAULT (1 << 4) // Remote Fault
-#define GMII_AUTONEG_ABILITY (1 << 3) // Auto Configuration Ability
-#define GMII_LINK_STATUS (1 << 2) // Link Status
-#define GMII_JABBER_DETECT (1 << 1) // Jabber Detect
-#define GMII_EXTEND_CAPAB (1 << 0) // Extended Capability
-
-
-// Bit definitions: GMII_PHYID1 0x02 PHY Idendifier 1
-// Bit definitions: GMII_PHYID2 0x03 PHY Idendifier 2
-#define GMII_LSB_MASK 0x3F
-#define GMII_OUI_MSB 0x0022
-#define GMII_OUI_LSB 0x05
-
-
-// Bit definitions: GMII_ANAR 0x04 Auto_Negotiation Advertisement
-// Bit definitions: GMII_ANLPAR 0x05 Auto_negotiation Link Partner Ability
-#define GMII_NP (1 << 15) // Next page Indication
-// Reserved 7
-#define GMII_RF (1 << 13) // Remote Fault
-// Reserved 12 // Write as 0, ignore on read
-#define GMII_PAUSE_MASK (3 << 11) // 0,0 = No Pause 1,0 = Asymmetric Pause(link partner)
- // 0,1 = Symmetric Pause 1,1 = Symmetric&Asymmetric Pause(local device)
-#define GMII_100T4 (1 << 9) // 100BASE-T4 Support
-#define GMII_100TX_FDX (1 << 8) // 100BASE-TX Full Duplex Support
-#define GMII_100TX_HDX (1 << 7) // 100BASE-TX Support
-#define GMII_10_FDX (1 << 6) // 10BASE-T Full Duplex Support
-#define GMII_10_HDX (1 << 5) // 10BASE-T Support
-// Selector 4 to 0 // Protocol Selection Bits
-#define GMII_AN_IEEE_802_3 0x0001 // [00001] = IEEE 802.3
-
-
-// Bit definitions: GMII_ANER 0x06 Auto-negotiation Expansion
-// Reserved 15 to 5 // Read as 0, ignore on write
-#define GMII_PDF (1 << 4) // Local Device Parallel Detection Fault
-#define GMII_LP_NP_ABLE (1 << 3) // Link Partner Next Page Able
-#define GMII_NP_ABLE (1 << 2) // Local Device Next Page Able
-#define GMII_PAGE_RX (1 << 1) // New Page Received
-#define GMII_LP_AN_ABLE (1 << 0) // Link Partner Auto-negotiation Able
-
-/**
- * \brief Perform a HW initialization to the PHY and set up clocks.
- *
- * This should be called only once to initialize the PHY pre-settings.
- * The PHY address is the reset status of CRS, RXD[3:0] (the GmacPins' pullups).
- * The COL pin is used to select MII mode on reset (pulled up for Reduced MII).
- * The RXDV pin is used to select test mode on reset (pulled up for test mode).
- * The above pins should be predefined for corresponding settings in resetPins.
- * The GMAC peripheral pins are configured after the reset is done.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param ul_mck GMAC MCK.
- *
- * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_init(Gmac *p_gmac, uint8_t uc_phy_addr, uint32_t ul_mck);
-
-
-/**
- * \brief Get the Link & speed settings, and automatically set up the GMAC with the
- * settings.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param uc_apply_setting_flag Set to 0 to not apply the PHY configurations, else to apply.
- *
- * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_set_link(Gmac *p_gmac, uint8_t uc_phy_addr,
- uint8_t uc_apply_setting_flag);
-
-
-/**
- * \brief Issue an auto negotiation of the PHY.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- *
- * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_auto_negotiate(Gmac *p_gmac, uint8_t uc_phy_addr);
-
-/**
- * \brief Issue a SW reset to reset all registers of the PHY.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- *
- * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_reset(Gmac *p_gmac, uint8_t uc_phy_addr);
-
-typedef struct xPHY_PROPS {
- signed char phy_result;
- uint32_t phy_params;
- uint32_t phy_stat1;
- uint32_t phy_stat2;
- unsigned char phy_chn;
-} PhyProps_t;
-extern PhyProps_t phy_props;
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* #ifndef ETHERNET_PHY_H_INCLUDED */
-
+/**
+ * \file
+ *
+ * \brief KSZ8051MNL (Ethernet PHY) driver for SAM.
+ *
+ * Copyright (c) 2013 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#ifndef ETHERNET_PHY_H_INCLUDED
+#define ETHERNET_PHY_H_INCLUDED
+
+#include "compiler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// IEEE defined Registers
+#define GMII_BMCR 0x00 // Basic Control
+#define GMII_BMSR 0x01 // Basic Status
+#define GMII_PHYID1 0x02 // PHY Idendifier 1
+#define GMII_PHYID2 0x03 // PHY Idendifier 2
+#define GMII_ANAR 0x04 // Auto_Negotiation Advertisement
+#define GMII_ANLPAR 0x05 // Auto_negotiation Link Partner Ability
+#define GMII_ANER 0x06 // Auto-negotiation Expansion
+#define GMII_ANNPR 0x07 // Auto-negotiation Next Page
+#define GMII_ANLPNPAR 0x08 // Link Partner Next Page Ability
+//#define GMII_1000BTCR 9 // 1000Base-T Control // Reserved
+//#define GMII_1000BTSR 10 // 1000Base-T Status // Reserved
+#define GMII_AFECR1 0x11 // AFE Control 1
+//#define GMII_ERDWR 12 // Extend Register - Data Write Register
+//#define GMII_ERDRR 13 // Extend Register - Data Read Register
+//14 reserved
+#define GMII_RXERCR 0x15 // RXER Counter
+
+ #define PHY_REG_01_BMSR 0x01 // Basic mode status register
+ #define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1
+ #define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2
+ #define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg
+ #define PHY_REG_05_LPA 0x05 // Link partner ability reg
+ #define PHY_REG_06_ANER 0x06 // 6 RW Auto-Negotiation Expansion Register
+ #define PHY_REG_07_ANNPTR 0x07 // 7 RW Auto-Negotiation Next Page TX
+ #define PHY_REG_08_RESERVED0 0x08 // 0x08..0x0Fh 8-15 RW RESERVED
+
+ #define PHY_REG_10_PHYSTS 0x10 // 16 RO PHY Status Register
+ #define PHY_REG_11_MICR 0x11 // 17 RW MII Interrupt Control Register
+ #define PHY_REG_12_MISR 0x12 // 18 RO MII Interrupt Status Register
+ #define PHY_REG_13_RESERVED1 0x13 // 19 RW RESERVED
+ #define PHY_REG_14_FCSCR 0x14 // 20 RO False Carrier Sense Counter Register
+ #define PHY_REG_15_RECR 0x15 // 21 RO Receive Error Counter Register
+ #define PHY_REG_16_PCSR 0x16 // 22 RW PCS Sub-Layer Configuration and Status Register
+ #define PHY_REG_17_RBR 0x17 // 23 RW RMII and Bypass Register
+ #define PHY_REG_18_LEDCR 0x18 // 24 RW LED Direct Control Register
+ #define PHY_REG_19_PHYCR 0x19 // 25 RW PHY Control Register
+ #define PHY_REG_1A_10BTSCR 0x1A // 26 RW 10Base-T Status/Control Register
+ #define PHY_REG_1B_CDCTRL1 0x1B // 27 RW CD Test Control Register and BIST Extensions Register
+ #define PHY_REG_1B_INT_CTRL 0x1B // 27 RW KSZ8041NL interrupt control
+ #define PHY_REG_1C_RESERVED2 0x1C // 28 RW RESERVED
+ #define PHY_REG_1D_EDCR 0x1D // 29 RW Energy Detect Control Register
+ #define PHY_REG_1E_RESERVED3 0x1E //
+ #define PHY_REG_1F_RESERVED4 0x1F // 30-31 RW RESERVED
+
+ #define PHY_REG_1E_PHYCR_1 0x1E //
+ #define PHY_REG_1F_PHYCR_2 0x1F //
+
+ #define PHY_SPEED_10 1
+ #define PHY_SPEED_100 2
+ #define PHY_SPEED_AUTO (PHY_SPEED_10|PHY_SPEED_100)
+
+ #define PHY_MDIX_DIRECT 1
+ #define PHY_MDIX_CROSSED 2
+ #define PHY_MDIX_AUTO (PHY_MDIX_CROSSED|PHY_MDIX_DIRECT)
+
+ #define PHY_DUPLEX_HALF 1
+ #define PHY_DUPLEX_FULL 2
+ #define PHY_DUPLEX_AUTO (PHY_DUPLEX_FULL|PHY_DUPLEX_HALF)
+
+ typedef struct _SPhyProps {
+ unsigned char speed;
+ unsigned char mdix;
+ unsigned char duplex;
+ unsigned char spare;
+ } SPhyProps;
+
+ const char *phyPrintable (const SPhyProps *apProps);
+
+ extern SPhyProps phyProps;
+
+#define GMII_OMSOR 0x16 // Operation Mode Strap Override
+#define GMII_OMSSR 0x17 // Operation Mode Strap Status
+#define GMII_ECR 0x18 // Expanded Control
+//#define GMII_DPPSR 19 // Digital PMA/PCS Status
+//20 reserved
+//#define GMII_RXERCR 21 // RXER Counter Register
+//22-26 reserved
+#define GMII_ICSR 0x1B // Interrupt Control/Status
+//#define GMII_DDC1R 28 // Digital Debug Control 1 Register
+#define GMII_LCSR 0x1D // LinkMD Control/Status
+
+//29-30 reserved
+#define GMII_PCR1 0x1E // PHY Control 1
+#define GMII_PCR2 0x1F // PHY Control 2
+
+/*
+//Extend Registers
+#define GMII_CCR 256 // Common Control Register
+#define GMII_SSR 257 // Strap Status Register
+#define GMII_OMSOR 258 // Operation Mode Strap Override Register
+#define GMII_OMSSR 259 // Operation Mode Strap Status Register
+#define GMII_RCCPSR 260 // RGMII Clock and Control Pad Skew Register
+#define GMII_RRDPSR 261 // RGMII RX Data Pad Skew Register
+#define GMII_ATR 263 // Analog Test Register
+*/
+
+
+// Bit definitions: GMII_BMCR 0x00 Basic Control
+#define GMII_RESET (1 << 15) // 1= Software Reset; 0=Normal Operation
+#define GMII_LOOPBACK (1 << 14) // 1=loopback Enabled; 0=Normal Operation
+#define GMII_SPEED_SELECT (1 << 13) // 1=100Mbps; 0=10Mbps
+#define GMII_AUTONEG (1 << 12) // Auto-negotiation Enable
+#define GMII_POWER_DOWN (1 << 11) // 1=Power down 0=Normal operation
+#define GMII_ISOLATE (1 << 10) // 1 = Isolates 0 = Normal operation
+#define GMII_RESTART_AUTONEG (1 << 9) // 1 = Restart auto-negotiation 0 = Normal operation
+#define GMII_DUPLEX_MODE (1 << 8) // 1 = Full duplex operation 0 = Normal operation
+#define GMII_COLLISION_TEST (1 << 7) // 1 = Enable COL test; 0 = Disable COL test
+//#define GMII_SPEED_SELECT_MSB (1 << 6) // Reserved
+// Reserved 6 to 0 // Read as 0, ignore on write
+
+// Bit definitions: GMII_BMSR 0x01 Basic Status
+#define GMII_100BASE_T4 (1 << 15) // 100BASE-T4 Capable
+#define GMII_100BASE_TX_FD (1 << 14) // 100BASE-TX Full Duplex Capable
+#define GMII_100BASE_T4_HD (1 << 13) // 100BASE-TX Half Duplex Capable
+#define GMII_10BASE_T_FD (1 << 12) // 10BASE-T Full Duplex Capable
+#define GMII_10BASE_T_HD (1 << 11) // 10BASE-T Half Duplex Capable
+// Reserved 10 to79 // Read as 0, ignore on write
+//#define GMII_EXTEND_STATUS (1 << 8) // 1 = Extend Status Information In Reg 15
+// Reserved 7
+#define GMII_MF_PREAMB_SUPPR (1 << 6) // MII Frame Preamble Suppression
+#define GMII_AUTONEG_COMP (1 << 5) // Auto-negotiation Complete
+#define GMII_REMOTE_FAULT (1 << 4) // Remote Fault
+#define GMII_AUTONEG_ABILITY (1 << 3) // Auto Configuration Ability
+#define GMII_LINK_STATUS (1 << 2) // Link Status
+#define GMII_JABBER_DETECT (1 << 1) // Jabber Detect
+#define GMII_EXTEND_CAPAB (1 << 0) // Extended Capability
+
+
+// Bit definitions: GMII_PHYID1 0x02 PHY Idendifier 1
+// Bit definitions: GMII_PHYID2 0x03 PHY Idendifier 2
+#define GMII_LSB_MASK 0x3F
+#define GMII_OUI_MSB 0x0022
+#define GMII_OUI_LSB 0x05
+
+
+// Bit definitions: GMII_ANAR 0x04 Auto_Negotiation Advertisement
+// Bit definitions: GMII_ANLPAR 0x05 Auto_negotiation Link Partner Ability
+#define GMII_NP (1 << 15) // Next page Indication
+// Reserved 7
+#define GMII_RF (1 << 13) // Remote Fault
+// Reserved 12 // Write as 0, ignore on read
+#define GMII_PAUSE_MASK (3 << 11) // 0,0 = No Pause 1,0 = Asymmetric Pause(link partner)
+ // 0,1 = Symmetric Pause 1,1 = Symmetric&Asymmetric Pause(local device)
+#define GMII_100T4 (1 << 9) // 100BASE-T4 Support
+#define GMII_100TX_FDX (1 << 8) // 100BASE-TX Full Duplex Support
+#define GMII_100TX_HDX (1 << 7) // 100BASE-TX Support
+#define GMII_10_FDX (1 << 6) // 10BASE-T Full Duplex Support
+#define GMII_10_HDX (1 << 5) // 10BASE-T Support
+// Selector 4 to 0 // Protocol Selection Bits
+#define GMII_AN_IEEE_802_3 0x0001 // [00001] = IEEE 802.3
+
+
+// Bit definitions: GMII_ANER 0x06 Auto-negotiation Expansion
+// Reserved 15 to 5 // Read as 0, ignore on write
+#define GMII_PDF (1 << 4) // Local Device Parallel Detection Fault
+#define GMII_LP_NP_ABLE (1 << 3) // Link Partner Next Page Able
+#define GMII_NP_ABLE (1 << 2) // Local Device Next Page Able
+#define GMII_PAGE_RX (1 << 1) // New Page Received
+#define GMII_LP_AN_ABLE (1 << 0) // Link Partner Auto-negotiation Able
+
+/**
+ * \brief Perform a HW initialization to the PHY and set up clocks.
+ *
+ * This should be called only once to initialize the PHY pre-settings.
+ * The PHY address is the reset status of CRS, RXD[3:0] (the GmacPins' pullups).
+ * The COL pin is used to select MII mode on reset (pulled up for Reduced MII).
+ * The RXDV pin is used to select test mode on reset (pulled up for test mode).
+ * The above pins should be predefined for corresponding settings in resetPins.
+ * The GMAC peripheral pins are configured after the reset is done.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param ul_mck GMAC MCK.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_init(Gmac *p_gmac, uint8_t uc_phy_addr, uint32_t ul_mck);
+
+
+/**
+ * \brief Get the Link & speed settings, and automatically set up the GMAC with the
+ * settings.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param uc_apply_setting_flag Set to 0 to not apply the PHY configurations, else to apply.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_set_link(Gmac *p_gmac, uint8_t uc_phy_addr,
+ uint8_t uc_apply_setting_flag);
+
+
+/**
+ * \brief Issue an auto negotiation of the PHY.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_auto_negotiate(Gmac *p_gmac, uint8_t uc_phy_addr);
+
+/**
+ * \brief Issue a SW reset to reset all registers of the PHY.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ *
+ * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_reset(Gmac *p_gmac, uint8_t uc_phy_addr);
+
+typedef struct xPHY_PROPS {
+ signed char phy_result;
+ uint32_t phy_params;
+ uint32_t phy_stat1;
+ uint32_t phy_stat2;
+ unsigned char phy_chn;
+} PhyProps_t;
+extern PhyProps_t phy_props;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* #ifndef ETHERNET_PHY_H_INCLUDED */
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.c
index e4a3ba988..948f9a661 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.c
@@ -1,944 +1,944 @@
- /**
- * \file
- *
- * \brief GMAC (Ethernet MAC) driver for SAM.
- *
- * Copyright (c) 2013 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-
-#include "FreeRTOSIPConfig.h"
-
-#include "compiler.h"
-#include "instance/gmac.h"
-#include "ethernet_phy.h"
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-extern "C" {
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (int)( sizeof(x) / sizeof(x)[0] )
-#endif
-/**
- * \defgroup gmac_group Ethernet Media Access Controller
- *
- * See \ref gmac_quickstart.
- *
- * Driver for the GMAC (Ethernet Media Access Controller).
- * This file contains basic functions for the GMAC, with support for all modes, settings
- * and clock speeds.
- *
- * \section dependencies Dependencies
- * This driver does not depend on other modules.
- *
- * @{
- */
-
-/** TX descriptor lists */
-COMPILER_ALIGNED(8)
-static gmac_tx_descriptor_t gs_tx_desc[ GMAC_TX_BUFFERS ];
-#if( GMAC_USES_TX_CALLBACK != 0 )
-/** TX callback lists */
-static gmac_dev_tx_cb_t gs_tx_callback[ GMAC_TX_BUFFERS ];
-#endif
-/** RX descriptors lists */
-COMPILER_ALIGNED(8)
-static gmac_rx_descriptor_t gs_rx_desc[ GMAC_RX_BUFFERS ];
-
-#if( ipconfigZERO_COPY_TX_DRIVER == 0 )
- /** Send Buffer. Section 3.6 of AMBA 2.0 spec states that burst should not cross the
- * 1K Boundaries. Receive buffer manager write operations are burst of 2 words => 3 lsb bits
- * of the address shall be set to 0.
- */
- COMPILER_ALIGNED(8)
- static uint8_t gs_uc_tx_buffer[ GMAC_TX_BUFFERS * GMAC_TX_UNITSIZE ];
-#endif /* ipconfigZERO_COPY_TX_DRIVER */
-
-/** Receive Buffer */
-COMPILER_ALIGNED(8)
-static uint8_t gs_uc_rx_buffer[ GMAC_RX_BUFFERS * GMAC_RX_UNITSIZE ];
-
-/**
- * GMAC device memory management struct.
- */
-typedef struct gmac_dev_mem {
- /* Pointer to allocated buffer for RX. The address should be 8-byte aligned
- and the size should be GMAC_RX_UNITSIZE * wRxSize. */
- uint8_t *p_rx_buffer;
- /* Pointer to allocated RX descriptor list. */
- gmac_rx_descriptor_t *p_rx_dscr;
- /* RX size, in number of registered units (RX descriptors). */
- /* Increased size from 16- to 32-bits, because it's more efficient */
- uint32_t us_rx_size;
- /* Pointer to allocated buffer for TX. The address should be 8-byte aligned
- and the size should be GMAC_TX_UNITSIZE * wTxSize. */
- uint8_t *p_tx_buffer;
- /* Pointer to allocated TX descriptor list. */
- gmac_tx_descriptor_t *p_tx_dscr;
- /* TX size, in number of registered units (TX descriptors). */
- uint32_t us_tx_size;
-} gmac_dev_mem_t;
-
-/** Return count in buffer */
-#define CIRC_CNT( head, tail, size ) ( ( ( head ) - ( tail ) ) % ( size ) )
-
-/*
- * Return space available, from 0 to size-1.
- * Always leave one free char as a completely full buffer that has (head == tail),
- * which is the same as empty.
- */
-#define CIRC_SPACE( head, tail, size ) CIRC_CNT( ( tail ), ( ( head ) + 1 ), ( size ) )
-
-/** Circular buffer is empty ? */
-#define CIRC_EMPTY( head, tail ) ( head == tail )
-/** Clear circular buffer */
-#define CIRC_CLEAR( head, tail ) do { ( head ) = 0; ( tail ) = 0; } while( 0 )
-
-/** Increment head or tail */
-static __inline void circ_inc32( int32_t *lHeadOrTail, uint32_t ulSize )
-{
- ( *lHeadOrTail ) ++;
- if( ( *lHeadOrTail ) >= ( int32_t )ulSize )
- {
- ( *lHeadOrTail ) = 0;
- }
-}
-
-/**
- * \brief Wait PHY operation to be completed.
- *
- * \param p_gmac HW controller address.
- * \param ul_retry The retry times, 0 to wait forever until completeness.
- *
- * Return GMAC_OK if the operation is completed successfully.
- */
-static uint8_t gmac_wait_phy(Gmac* p_gmac, const uint32_t ul_retry)
-{
- volatile uint32_t ul_retry_count = 0;
- const uint32_t xPHYPollDelay = pdMS_TO_TICKS( 1ul );
-
- while (!gmac_is_phy_idle(p_gmac)) {
- if (ul_retry == 0) {
- continue;
- }
-
- ul_retry_count++;
-
- if (ul_retry_count >= ul_retry) {
- return GMAC_TIMEOUT;
- }
-
- /* Block the task to allow other tasks to execute while the PHY
- is not connected. */
- vTaskDelay( xPHYPollDelay );
- }
- return GMAC_OK;
-}
-
-/**
- * \brief Disable transfer, reset registers and descriptor lists.
- *
- * \param p_dev Pointer to GMAC driver instance.
- *
- */
-static void gmac_reset_tx_mem(gmac_device_t* p_dev)
-{
- Gmac *p_hw = p_dev->p_hw;
- uint8_t *p_tx_buff = p_dev->p_tx_buffer;
- gmac_tx_descriptor_t *p_td = p_dev->p_tx_dscr;
-
- uint32_t ul_index;
- uint32_t ul_address;
-
- /* Disable TX */
- gmac_enable_transmit(p_hw, 0);
-
- /* Set up the TX descriptors */
- CIRC_CLEAR(p_dev->l_tx_head, p_dev->l_tx_tail);
- for( ul_index = 0; ul_index < p_dev->ul_tx_list_size; ul_index++ )
- {
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- ul_address = (uint32_t) 0u;
- }
- #else
- {
- ul_address = (uint32_t) (&(p_tx_buff[ul_index * GMAC_TX_UNITSIZE]));
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
- p_td[ul_index].addr = ul_address;
- p_td[ul_index].status.val = GMAC_TXD_USED;
- }
- p_td[p_dev->ul_tx_list_size - 1].status.val =
- GMAC_TXD_USED | GMAC_TXD_WRAP;
-
- /* Set transmit buffer queue */
- gmac_set_tx_queue(p_hw, (uint32_t) p_td);
-}
-
-/**
- * \brief Disable receiver, reset registers and descriptor list.
- *
- * \param p_drv Pointer to GMAC Driver instance.
- */
-static void gmac_reset_rx_mem(gmac_device_t* p_dev)
-{
- Gmac *p_hw = p_dev->p_hw;
- uint8_t *p_rx_buff = p_dev->p_rx_buffer;
- gmac_rx_descriptor_t *pRd = p_dev->p_rx_dscr;
-
- uint32_t ul_index;
- uint32_t ul_address;
-
- /* Disable RX */
- gmac_enable_receive(p_hw, 0);
-
- /* Set up the RX descriptors */
- p_dev->ul_rx_idx = 0;
- for( ul_index = 0; ul_index < p_dev->ul_rx_list_size; ul_index++ )
- {
- ul_address = (uint32_t) (&(p_rx_buff[ul_index * GMAC_RX_UNITSIZE]));
- pRd[ul_index].addr.val = ul_address & GMAC_RXD_ADDR_MASK;
- pRd[ul_index].status.val = 0;
- }
- pRd[p_dev->ul_rx_list_size - 1].addr.val |= GMAC_RXD_WRAP;
-
- /* Set receive buffer queue */
- gmac_set_rx_queue(p_hw, (uint32_t) pRd);
-}
-
-
-/**
- * \brief Initialize the allocated buffer lists for GMAC driver to transfer data.
- * Must be invoked after gmac_dev_init() but before RX/TX starts.
- *
- * \note If input address is not 8-byte aligned, the address is automatically
- * adjusted and the list size is reduced by one.
- *
- * \param p_gmac Pointer to GMAC instance.
- * \param p_gmac_dev Pointer to GMAC device instance.
- * \param p_dev_mm Pointer to the GMAC memory management control block.
- * \param p_tx_cb Pointer to allocated TX callback list.
- *
- * \return GMAC_OK or GMAC_PARAM.
- */
-static uint8_t gmac_init_mem(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
- gmac_dev_mem_t* p_dev_mm
-#if( GMAC_USES_TX_CALLBACK != 0 )
- , gmac_dev_tx_cb_t* p_tx_cb
-#endif
- )
-{
- if (p_dev_mm->us_rx_size <= 1 || p_dev_mm->us_tx_size <= 1
-#if( GMAC_USES_TX_CALLBACK != 0 )
- || p_tx_cb == NULL
-#endif
- ) {
- return GMAC_PARAM;
- }
-
- /* Assign RX buffers */
- if (((uint32_t) p_dev_mm->p_rx_buffer & 0x7)
- || ((uint32_t) p_dev_mm->p_rx_dscr & 0x7)) {
- p_dev_mm->us_rx_size--;
- }
- p_gmac_dev->p_rx_buffer =
- (uint8_t *) ((uint32_t) p_dev_mm->p_rx_buffer & 0xFFFFFFF8);
- p_gmac_dev->p_rx_dscr =
- (gmac_rx_descriptor_t *) ((uint32_t) p_dev_mm->p_rx_dscr
- & 0xFFFFFFF8);
- p_gmac_dev->ul_rx_list_size = p_dev_mm->us_rx_size;
-
- /* Assign TX buffers */
- if (((uint32_t) p_dev_mm->p_tx_buffer & 0x7)
- || ((uint32_t) p_dev_mm->p_tx_dscr & 0x7)) {
- p_dev_mm->us_tx_size--;
- }
- p_gmac_dev->p_tx_buffer =
- (uint8_t *) ((uint32_t) p_dev_mm->p_tx_buffer & 0xFFFFFFF8);
- p_gmac_dev->p_tx_dscr =
- (gmac_tx_descriptor_t *) ((uint32_t) p_dev_mm->p_tx_dscr
- & 0xFFFFFFF8);
- p_gmac_dev->ul_tx_list_size = p_dev_mm->us_tx_size;
-#if( GMAC_USES_TX_CALLBACK != 0 )
- p_gmac_dev->func_tx_cb_list = p_tx_cb;
-#endif
- /* Reset TX & RX */
- gmac_reset_rx_mem(p_gmac_dev);
- gmac_reset_tx_mem(p_gmac_dev);
-
- /* Enable Rx and Tx, plus the statistics register */
- gmac_enable_transmit(p_gmac, true);
- gmac_enable_receive(p_gmac, true);
- gmac_enable_statistics_write(p_gmac, true);
-
- /* Set up the interrupts for transmission and errors */
- gmac_enable_interrupt(p_gmac,
- GMAC_IER_RXUBR | /* Enable receive used bit read interrupt. */
- GMAC_IER_TUR | /* Enable transmit underrun interrupt. */
- GMAC_IER_RLEX | /* Enable retry limit exceeded interrupt. */
- GMAC_IER_TFC | /* Enable transmit buffers exhausted in mid-frame interrupt. */
- GMAC_IER_TCOMP | /* Enable transmit complete interrupt. */
- GMAC_IER_ROVR | /* Enable receive overrun interrupt. */
- GMAC_IER_HRESP | /* Enable Hresp not OK interrupt. */
- GMAC_IER_PFNZ | /* Enable pause frame received interrupt. */
- GMAC_IER_PTZ); /* Enable pause time zero interrupt. */
-
- return GMAC_OK;
-}
-
-/**
- * \brief Read the PHY register.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_address PHY address.
- * \param uc_address Register address.
- * \param p_value Pointer to a 32-bit location to store read data.
- *
- * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
- uint32_t* p_value)
-{
- gmac_maintain_phy(p_gmac, uc_phy_address, uc_address, 1, 0);
-
- if (gmac_wait_phy(p_gmac, MAC_PHY_RETRY_MAX) == GMAC_TIMEOUT) {
- return GMAC_TIMEOUT;
- }
- *p_value = gmac_get_phy_data(p_gmac);
- return GMAC_OK;
-}
-
-/**
- * \brief Write the PHY register.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_address PHY Address.
- * \param uc_address Register Address.
- * \param ul_value Data to write, actually 16-bit data.
- *
- * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
- uint8_t uc_address, uint32_t ul_value)
-{
- gmac_maintain_phy(p_gmac, uc_phy_address, uc_address, 0, ul_value);
-
- if (gmac_wait_phy(p_gmac, MAC_PHY_RETRY_MAX) == GMAC_TIMEOUT) {
- return GMAC_TIMEOUT;
- }
- return GMAC_OK;
-}
-
-/**
- * \brief Initialize the GMAC driver.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param p_gmac_dev Pointer to the GMAC device instance.
- * \param p_opt GMAC configure options.
- */
-void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
- gmac_options_t* p_opt)
-{
- gmac_dev_mem_t gmac_dev_mm;
-
- /* Disable TX & RX and more */
- gmac_network_control(p_gmac, 0);
- gmac_disable_interrupt(p_gmac, ~0u);
-
-
- gmac_clear_statistics(p_gmac);
-
- /* Clear all status bits in the receive status register. */
- gmac_clear_rx_status(p_gmac, GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA);
-
- /* Clear all status bits in the transmit status register */
- gmac_clear_tx_status(p_gmac, GMAC_TSR_UBR | GMAC_TSR_COL | GMAC_TSR_RLE
- | GMAC_TSR_TFC | GMAC_TSR_TXCOMP | GMAC_TSR_UND);
-
- /* Clear interrupts */
- gmac_get_interrupt_status(p_gmac);
-#if !defined(ETHERNET_CONF_DATA_OFFSET)
- /* Receive Buffer Offset
- * Indicates the number of bytes by which the received data
- * is offset from the start of the receive buffer
- * which can be handy for alignment reasons */
- /* Note: FreeRTOS+TCP wants to have this offset set to 2 bytes */
- #error ETHERNET_CONF_DATA_OFFSET not defined, assuming 0
-#endif
- /* Enable the copy of data into the buffers
- ignore broadcasts, and not copy FCS. */
-
- gmac_set_configure(p_gmac,
- ( gmac_get_configure(p_gmac) & ~GMAC_NCFGR_RXBUFO_Msk ) |
- GMAC_NCFGR_RFCS | /* Remove FCS, frame check sequence (last 4 bytes) */
- GMAC_NCFGR_PEN | /* Pause Enable */
- GMAC_NCFGR_RXBUFO( ETHERNET_CONF_DATA_OFFSET ) |
- GMAC_RXD_RXCOEN );
-
- /*
- * GMAC_DCFGR_TXCOEN: (GMAC_DCFGR) Transmitter Checksum Generation Offload Enable.
- * Note: tha SAM4E does have RX checksum offloading
- * but TX checksum offloading has NOT been implemented.
- */
-
- gmac_set_dma(p_gmac,
- gmac_get_dma(p_gmac) | GMAC_DCFGR_TXCOEN );
-
- gmac_enable_copy_all(p_gmac, p_opt->uc_copy_all_frame);
- gmac_disable_broadcast(p_gmac, p_opt->uc_no_boardcast);
-
- /* Fill in GMAC device memory management */
- gmac_dev_mm.p_rx_buffer = gs_uc_rx_buffer;
- gmac_dev_mm.p_rx_dscr = gs_rx_desc;
- gmac_dev_mm.us_rx_size = GMAC_RX_BUFFERS;
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- gmac_dev_mm.p_tx_buffer = NULL;
- }
- #else
- {
- gmac_dev_mm.p_tx_buffer = gs_uc_tx_buffer;
- }
- #endif
- gmac_dev_mm.p_tx_dscr = gs_tx_desc;
- gmac_dev_mm.us_tx_size = GMAC_TX_BUFFERS;
-
- gmac_init_mem(p_gmac, p_gmac_dev, &gmac_dev_mm
-#if( GMAC_USES_TX_CALLBACK != 0 )
- , gs_tx_callback
-#endif
- );
-
- gmac_set_address(p_gmac, 0, p_opt->uc_mac_addr);
-}
-
-/**
- * \brief Frames can be read from the GMAC in multiple sections.
- *
- * Returns > 0 if a complete frame is available
- * It also it cleans up incomplete older frames
- */
-
-static uint32_t gmac_dev_poll(gmac_device_t* p_gmac_dev)
-{
- uint32_t ulReturn = 0;
- int32_t ulIndex = p_gmac_dev->ul_rx_idx;
- gmac_rx_descriptor_t *pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
-
- /* Discard any incomplete frames */
- while ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) &&
- (pxHead->status.val & GMAC_RXD_SOF) == 0) {
- pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
- circ_inc32 (&ulIndex, p_gmac_dev->ul_rx_list_size);
- pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
- p_gmac_dev->ul_rx_idx = ulIndex;
- #if( GMAC_STATS != 0 )
- {
- gmacStats.incompCount++;
- }
- #endif
- }
-
- while ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) != 0) {
- if ((pxHead->status.val & GMAC_RXD_EOF) != 0) {
- /* Here a complete frame has been seen with SOF and EOF */
- ulReturn = pxHead->status.bm.len;
- break;
- }
- circ_inc32 (&ulIndex, p_gmac_dev->ul_rx_list_size);
- pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
- if ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) == 0) {
- /* CPU is not the owner (yet) */
- break;
- }
- if ((pxHead->status.val & GMAC_RXD_SOF) != 0) {
- /* Strange, we found a new Start Of Frame
- * discard previous segments */
- int32_t ulPrev = p_gmac_dev->ul_rx_idx;
- pxHead = &p_gmac_dev->p_rx_dscr[ulPrev];
- do {
- pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
- circ_inc32 (&ulPrev, p_gmac_dev->ul_rx_list_size);
- pxHead = &p_gmac_dev->p_rx_dscr[ulPrev];
- #if( GMAC_STATS != 0 )
- {
- gmacStats.truncCount++;
- }
- #endif
- } while (ulPrev != ulIndex);
- p_gmac_dev->ul_rx_idx = ulIndex;
- }
- }
- return ulReturn;
-}
-
-/**
- * \brief Frames can be read from the GMAC in multiple sections.
- * Read ul_frame_size bytes from the GMAC receive buffers to pcTo.
- * p_rcv_size is the size of the entire frame. Generally gmac_read
- * will be repeatedly called until the sum of all the ul_frame_size equals
- * the value of p_rcv_size.
- *
- * \param p_gmac_dev Pointer to the GMAC device instance.
- * \param p_frame Address of the frame buffer.
- * \param ul_frame_size Length of the frame.
- * \param p_rcv_size Received frame size.
- *
- * \return GMAC_OK if receiving frame successfully, otherwise failed.
- */
-uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
- uint32_t ul_frame_size, uint32_t* p_rcv_size)
-{
- int32_t nextIdx; /* A copy of the Rx-index 'ul_rx_idx' */
- int32_t bytesLeft = gmac_dev_poll (p_gmac_dev);
- gmac_rx_descriptor_t *pxHead;
-
- if (bytesLeft == 0 )
- {
- return GMAC_RX_NULL;
- }
-
- /* gmac_dev_poll has confirmed that there is a complete frame at
- * the current position 'ul_rx_idx'
- */
- nextIdx = p_gmac_dev->ul_rx_idx;
-
- /* Read +2 bytes because buffers are aligned at -2 bytes */
- bytesLeft = min( bytesLeft + 2, ( int32_t )ul_frame_size );
-
- /* The frame will be copied in 1 or 2 memcpy's */
- if( ( p_frame != NULL ) && ( bytesLeft != 0 ) )
- {
- const uint8_t *source;
- int32_t left;
- int32_t toCopy;
-
- source = p_gmac_dev->p_rx_buffer + nextIdx * GMAC_RX_UNITSIZE;
- left = bytesLeft;
- toCopy = ( p_gmac_dev->ul_rx_list_size - nextIdx ) * GMAC_RX_UNITSIZE;
- if(toCopy > left )
- {
- toCopy = left;
- }
- memcpy (p_frame, source, toCopy);
- left -= toCopy;
-
- if( left != 0ul )
- {
- memcpy (p_frame + toCopy, (void*)p_gmac_dev->p_rx_buffer, left);
- }
- }
-
- do
- {
- pxHead = &p_gmac_dev->p_rx_dscr[nextIdx];
- pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
- circ_inc32 (&nextIdx, p_gmac_dev->ul_rx_list_size);
- } while ((pxHead->status.val & GMAC_RXD_EOF) == 0);
-
- p_gmac_dev->ul_rx_idx = nextIdx;
-
- *p_rcv_size = bytesLeft;
-
- return GMAC_OK;
-}
-
-
-extern void vGMACGenerateChecksum( uint8_t *apBuffer );
-
-/**
- * \brief Send ulLength bytes from pcFrom. This copies the buffer to one of the
- * GMAC Tx buffers, and then indicates to the GMAC that the buffer is ready.
- * If lEndOfFrame is true then the data being copied is the end of the frame
- * and the frame can be transmitted.
- *
- * \param p_gmac_dev Pointer to the GMAC device instance.
- * \param p_buffer Pointer to the data buffer.
- * \param ul_size Length of the frame.
- * \param func_tx_cb Transmit callback function.
- *
- * \return Length sent.
- */
-uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
- uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb)
-{
-
- volatile gmac_tx_descriptor_t *p_tx_td;
-#if( GMAC_USES_TX_CALLBACK != 0 )
- volatile gmac_dev_tx_cb_t *p_func_tx_cb;
-#endif
-
- Gmac *p_hw = p_gmac_dev->p_hw;
-
-#if( GMAC_USES_TX_CALLBACK == 0 )
- ( void )func_tx_cb;
-#endif
-
- /* Check parameter */
- if (ul_size > GMAC_TX_UNITSIZE) {
- return GMAC_PARAM;
- }
-
- /* Pointers to the current transmit descriptor */
- p_tx_td = &p_gmac_dev->p_tx_dscr[p_gmac_dev->l_tx_head];
-
- /* If no free TxTd, buffer can't be sent, schedule the wakeup callback */
-// if (CIRC_SPACE(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
-// p_gmac_dev->ul_tx_list_size) == 0)
- {
- if ((p_tx_td->status.val & GMAC_TXD_USED) == 0)
- return GMAC_TX_BUSY;
- }
-#if( GMAC_USES_TX_CALLBACK != 0 )
- /* Pointers to the current Tx callback */
- p_func_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_head];
-#endif
-
- /* Set up/copy data to transmission buffer */
- if (p_buffer && ul_size) {
- /* Driver manages the ring buffer */
- /* Calculating the checksum here is faster than calculating it from the GMAC buffer
- * because withing p_buffer, it is well aligned */
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* Zero-copy... */
- p_tx_td->addr = ( uint32_t ) p_buffer;
- }
- #else
- {
- /* Or Memcopy... */
- memcpy((void *)p_tx_td->addr, p_buffer, ul_size);
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
- vGMACGenerateChecksum( ( uint8_t * ) p_tx_td->addr );
- }
-
-#if( GMAC_USES_TX_CALLBACK != 0 )
- /* Tx callback */
- *p_func_tx_cb = func_tx_cb;
-#endif
-
- /* Update transmit descriptor status */
-
- /* The buffer size defined is the length of ethernet frame,
- so it's always the last buffer of the frame. */
- if( p_gmac_dev->l_tx_head == ( int32_t )( p_gmac_dev->ul_tx_list_size - 1 ) )
- {
- /* No need to 'and' with GMAC_TXD_LEN_MASK because ul_size has been checked */
- p_tx_td->status.val =
- ul_size | GMAC_TXD_LAST | GMAC_TXD_WRAP;
- } else {
- p_tx_td->status.val =
- ul_size | GMAC_TXD_LAST;
- }
-
- circ_inc32( &p_gmac_dev->l_tx_head, p_gmac_dev->ul_tx_list_size );
-
- /* Now start to transmit if it is still not done */
- gmac_start_transmission(p_hw);
-
- return GMAC_OK;
-}
-
-/**
- * \brief Get current load of transmit.
- *
- * \param p_gmac_dev Pointer to the GMAC device instance.
- *
- * \return Current load of transmit.
- */
-#if( GMAC_USES_TX_CALLBACK != 0 )
-/* Without defining GMAC_USES_TX_CALLBACK, l_tx_tail won't be updated */
-uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev)
-{
- uint16_t us_head = p_gmac_dev->l_tx_head;
- uint16_t us_tail = p_gmac_dev->l_tx_tail;
- return CIRC_CNT(us_head, us_tail, p_gmac_dev->ul_tx_list_size);
-}
-#endif
-
-/**
- * \brief Register/Clear RX callback. Callback will be invoked after the next received
- * frame.
- *
- * When gmac_dev_read() returns GMAC_RX_NULL, the application task calls
- * gmac_dev_set_rx_callback() to register func_rx_cb() callback and enters suspend state.
- * The callback is in charge to resume the task once a new frame has been
- * received. The next time gmac_dev_read() is called, it will be successful.
- *
- * This function is usually invoked from the RX callback itself with NULL
- * callback, to unregister. Once the callback has resumed the application task,
- * there is no need to invoke the callback again.
- *
- * \param p_gmac_dev Pointer to the GMAC device instance.
- * \param func_tx_cb Receive callback function.
- */
-void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
- gmac_dev_rx_cb_t func_rx_cb)
-{
- Gmac *p_hw = p_gmac_dev->p_hw;
-
- if (func_rx_cb == NULL) {
- gmac_disable_interrupt(p_hw, GMAC_IDR_RCOMP);
- p_gmac_dev->func_rx_cb = NULL;
- } else {
- p_gmac_dev->func_rx_cb = func_rx_cb;
- gmac_enable_interrupt(p_hw, GMAC_IER_RCOMP);
- }
-}
-
-/**
- * \brief Register/Clear TX wakeup callback.
- *
- * When gmac_dev_write() returns GMAC_TX_BUSY (all transmit descriptor busy), the application
- * task calls gmac_dev_set_tx_wakeup_callback() to register func_wakeup() callback and
- * enters suspend state. The callback is in charge to resume the task once
- * several transmit descriptors have been released. The next time gmac_dev_write() will be called,
- * it shall be successful.
- *
- * This function is usually invoked with NULL callback from the TX wakeup
- * callback itself, to unregister. Once the callback has resumed the
- * application task, there is no need to invoke the callback again.
- *
- * \param p_gmac_dev Pointer to GMAC device instance.
- * \param func_wakeup Pointer to wakeup callback function.
- * \param uc_threshold Number of free transmit descriptor before wakeup callback invoked.
- *
- * \return GMAC_OK, GMAC_PARAM on parameter error.
- */
-#if( GMAC_USES_WAKEUP_CALLBACK )
-uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
- gmac_dev_wakeup_cb_t func_wakeup_cb, uint8_t uc_threshold)
-{
- if (func_wakeup_cb == NULL) {
- p_gmac_dev->func_wakeup_cb = NULL;
- } else {
- if (uc_threshold <= p_gmac_dev->ul_tx_list_size) {
- p_gmac_dev->func_wakeup_cb = func_wakeup_cb;
- p_gmac_dev->uc_wakeup_threshold = uc_threshold;
- } else {
- return GMAC_PARAM;
- }
- }
-
- return GMAC_OK;
-}
-#endif /* GMAC_USES_WAKEUP_CALLBACK */
-
-/**
- * \brief Reset TX & RX queue & statistics.
- *
- * \param p_gmac_dev Pointer to GMAC device instance.
- */
-void gmac_dev_reset(gmac_device_t* p_gmac_dev)
-{
- Gmac *p_hw = p_gmac_dev->p_hw;
-
- gmac_reset_rx_mem(p_gmac_dev);
- gmac_reset_tx_mem(p_gmac_dev);
- gmac_network_control(p_hw, GMAC_NCR_TXEN | GMAC_NCR_RXEN
- | GMAC_NCR_WESTAT | GMAC_NCR_CLRSTAT);
-}
-
-void gmac_dev_halt(Gmac* p_gmac);
-
-void gmac_dev_halt(Gmac* p_gmac)
-{
- gmac_network_control(p_gmac, GMAC_NCR_WESTAT | GMAC_NCR_CLRSTAT);
- gmac_disable_interrupt(p_gmac, ~0u);
-}
-
-
-/**
- * \brief GMAC Interrupt handler.
- *
- * \param p_gmac_dev Pointer to GMAC device instance.
- */
-
-#if( GMAC_STATS != 0 )
- extern int logPrintf( const char *pcFormat, ... );
-
- void gmac_show_irq_counts ()
- {
- int index;
- for (index = 0; index < ARRAY_SIZE(intPairs); index++) {
- if (gmacStats.intStatus[intPairs[index].index]) {
- logPrintf("%s : %6u\n", intPairs[index].name, gmacStats.intStatus[intPairs[index].index]);
- }
- }
- }
-#endif
-
-void gmac_handler(gmac_device_t* p_gmac_dev)
-{
- Gmac *p_hw = p_gmac_dev->p_hw;
-
-#if( GMAC_USES_TX_CALLBACK != 0 )
- gmac_tx_descriptor_t *p_tx_td;
- gmac_dev_tx_cb_t *p_tx_cb = NULL;
- uint32_t ul_tx_status_flag;
-#endif
-#if( GMAC_STATS != 0 )
- int index;
-#endif
-
- /* volatile */ uint32_t ul_isr;
- /* volatile */ uint32_t ul_rsr;
- /* volatile */ uint32_t ul_tsr;
-
- ul_isr = gmac_get_interrupt_status(p_hw);
- ul_rsr = gmac_get_rx_status(p_hw);
- ul_tsr = gmac_get_tx_status(p_hw);
-
-/* Why clear bits that are ignored anyway ? */
-/* ul_isr &= ~(gmac_get_interrupt_mask(p_hw) | 0xF8030300); */
- #if( GMAC_STATS != 0 )
- {
- for (index = 0; index < ARRAY_SIZE(intPairs); index++) {
- if (ul_isr & intPairs[index].mask)
- gmacStats.intStatus[intPairs[index].index]++;
- }
- }
- #endif /* GMAC_STATS != 0 */
-
- /* RX packet */
- if ((ul_isr & GMAC_ISR_RCOMP) || (ul_rsr & (GMAC_RSR_REC|GMAC_RSR_RXOVR|GMAC_RSR_BNA))) {
- /* Clear status */
- gmac_clear_rx_status(p_hw, ul_rsr);
-
- if (ul_isr & GMAC_ISR_RCOMP)
- ul_rsr |= GMAC_RSR_REC;
- /* Invoke callbacks which can be useful to wake op a task */
- if (p_gmac_dev->func_rx_cb) {
- p_gmac_dev->func_rx_cb(ul_rsr);
- }
- }
-
- /* TX packet */
- if ((ul_isr & GMAC_ISR_TCOMP) || (ul_tsr & (GMAC_TSR_TXCOMP|GMAC_TSR_COL|GMAC_TSR_RLE|GMAC_TSR_UND))) {
-
-#if( GMAC_USES_TX_CALLBACK != 0 )
- ul_tx_status_flag = GMAC_TSR_TXCOMP;
-#endif
- /* A frame transmitted */
-
- /* Check RLE */
- if (ul_tsr & GMAC_TSR_RLE) {
- /* Status RLE & Number of discarded buffers */
-#if( GMAC_USES_TX_CALLBACK != 0 )
- ul_tx_status_flag = GMAC_TSR_RLE | CIRC_CNT(p_gmac_dev->l_tx_head,
- p_gmac_dev->l_tx_tail, p_gmac_dev->ul_tx_list_size);
- p_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_tail];
-#endif
- gmac_reset_tx_mem(p_gmac_dev);
- gmac_enable_transmit(p_hw, 1);
- }
- /* Clear status */
- gmac_clear_tx_status(p_hw, ul_tsr);
-
-#if( GMAC_USES_TX_CALLBACK != 0 )
- if (!CIRC_EMPTY(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail)) {
- /* Check the buffers */
- do {
- p_tx_td = &p_gmac_dev->p_tx_dscr[p_gmac_dev->l_tx_tail];
- p_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_tail];
- /* Any error? Exit if buffer has not been sent yet */
- if ((p_tx_td->status.val & GMAC_TXD_USED) == 0) {
- break;
- }
-
- /* Notify upper layer that a packet has been sent */
- if (*p_tx_cb) {
- (*p_tx_cb) (ul_tx_status_flag, (void*)p_tx_td->addr);
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- p_tx_td->addr = 0ul;
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
- }
-
- circ_inc32(&p_gmac_dev->l_tx_tail, p_gmac_dev->ul_tx_list_size);
- } while (CIRC_CNT(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
- p_gmac_dev->ul_tx_list_size));
- }
-
- if (ul_tsr & GMAC_TSR_RLE) {
- /* Notify upper layer RLE */
- if (*p_tx_cb) {
- (*p_tx_cb) (ul_tx_status_flag, NULL);
- }
- }
-#endif /* GMAC_USES_TX_CALLBACK */
-
-#if( GMAC_USES_WAKEUP_CALLBACK )
- /* If a wakeup has been scheduled, notify upper layer that it can
- send other packets, and the sending will be successful. */
- if ((CIRC_SPACE(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
- p_gmac_dev->ul_tx_list_size) >= p_gmac_dev->uc_wakeup_threshold)
- && p_gmac_dev->func_wakeup_cb) {
- p_gmac_dev->func_wakeup_cb();
- }
-#endif
- }
-}
-
-//@}
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-}
-#endif
-/**INDENT-ON**/
-/// @endcond
+ /**
+ * \file
+ *
+ * \brief GMAC (Ethernet MAC) driver for SAM.
+ *
+ * Copyright (c) 2013 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include "FreeRTOSIPConfig.h"
+
+#include "compiler.h"
+#include "instance/gmac.h"
+#include "ethernet_phy.h"
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (int)( sizeof(x) / sizeof(x)[0] )
+#endif
+/**
+ * \defgroup gmac_group Ethernet Media Access Controller
+ *
+ * See \ref gmac_quickstart.
+ *
+ * Driver for the GMAC (Ethernet Media Access Controller).
+ * This file contains basic functions for the GMAC, with support for all modes, settings
+ * and clock speeds.
+ *
+ * \section dependencies Dependencies
+ * This driver does not depend on other modules.
+ *
+ * @{
+ */
+
+/** TX descriptor lists */
+COMPILER_ALIGNED(8)
+static gmac_tx_descriptor_t gs_tx_desc[ GMAC_TX_BUFFERS ];
+#if( GMAC_USES_TX_CALLBACK != 0 )
+/** TX callback lists */
+static gmac_dev_tx_cb_t gs_tx_callback[ GMAC_TX_BUFFERS ];
+#endif
+/** RX descriptors lists */
+COMPILER_ALIGNED(8)
+static gmac_rx_descriptor_t gs_rx_desc[ GMAC_RX_BUFFERS ];
+
+#if( ipconfigZERO_COPY_TX_DRIVER == 0 )
+ /** Send Buffer. Section 3.6 of AMBA 2.0 spec states that burst should not cross the
+ * 1K Boundaries. Receive buffer manager write operations are burst of 2 words => 3 lsb bits
+ * of the address shall be set to 0.
+ */
+ COMPILER_ALIGNED(8)
+ static uint8_t gs_uc_tx_buffer[ GMAC_TX_BUFFERS * GMAC_TX_UNITSIZE ];
+#endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+/** Receive Buffer */
+COMPILER_ALIGNED(8)
+static uint8_t gs_uc_rx_buffer[ GMAC_RX_BUFFERS * GMAC_RX_UNITSIZE ];
+
+/**
+ * GMAC device memory management struct.
+ */
+typedef struct gmac_dev_mem {
+ /* Pointer to allocated buffer for RX. The address should be 8-byte aligned
+ and the size should be GMAC_RX_UNITSIZE * wRxSize. */
+ uint8_t *p_rx_buffer;
+ /* Pointer to allocated RX descriptor list. */
+ gmac_rx_descriptor_t *p_rx_dscr;
+ /* RX size, in number of registered units (RX descriptors). */
+ /* Increased size from 16- to 32-bits, because it's more efficient */
+ uint32_t us_rx_size;
+ /* Pointer to allocated buffer for TX. The address should be 8-byte aligned
+ and the size should be GMAC_TX_UNITSIZE * wTxSize. */
+ uint8_t *p_tx_buffer;
+ /* Pointer to allocated TX descriptor list. */
+ gmac_tx_descriptor_t *p_tx_dscr;
+ /* TX size, in number of registered units (TX descriptors). */
+ uint32_t us_tx_size;
+} gmac_dev_mem_t;
+
+/** Return count in buffer */
+#define CIRC_CNT( head, tail, size ) ( ( ( head ) - ( tail ) ) % ( size ) )
+
+/*
+ * Return space available, from 0 to size-1.
+ * Always leave one free char as a completely full buffer that has (head == tail),
+ * which is the same as empty.
+ */
+#define CIRC_SPACE( head, tail, size ) CIRC_CNT( ( tail ), ( ( head ) + 1 ), ( size ) )
+
+/** Circular buffer is empty ? */
+#define CIRC_EMPTY( head, tail ) ( head == tail )
+/** Clear circular buffer */
+#define CIRC_CLEAR( head, tail ) do { ( head ) = 0; ( tail ) = 0; } while( 0 )
+
+/** Increment head or tail */
+static __inline void circ_inc32( int32_t *lHeadOrTail, uint32_t ulSize )
+{
+ ( *lHeadOrTail ) ++;
+ if( ( *lHeadOrTail ) >= ( int32_t )ulSize )
+ {
+ ( *lHeadOrTail ) = 0;
+ }
+}
+
+/**
+ * \brief Wait PHY operation to be completed.
+ *
+ * \param p_gmac HW controller address.
+ * \param ul_retry The retry times, 0 to wait forever until completeness.
+ *
+ * Return GMAC_OK if the operation is completed successfully.
+ */
+static uint8_t gmac_wait_phy(Gmac* p_gmac, const uint32_t ul_retry)
+{
+ volatile uint32_t ul_retry_count = 0;
+ const uint32_t xPHYPollDelay = pdMS_TO_TICKS( 1ul );
+
+ while (!gmac_is_phy_idle(p_gmac)) {
+ if (ul_retry == 0) {
+ continue;
+ }
+
+ ul_retry_count++;
+
+ if (ul_retry_count >= ul_retry) {
+ return GMAC_TIMEOUT;
+ }
+
+ /* Block the task to allow other tasks to execute while the PHY
+ is not connected. */
+ vTaskDelay( xPHYPollDelay );
+ }
+ return GMAC_OK;
+}
+
+/**
+ * \brief Disable transfer, reset registers and descriptor lists.
+ *
+ * \param p_dev Pointer to GMAC driver instance.
+ *
+ */
+static void gmac_reset_tx_mem(gmac_device_t* p_dev)
+{
+ Gmac *p_hw = p_dev->p_hw;
+ uint8_t *p_tx_buff = p_dev->p_tx_buffer;
+ gmac_tx_descriptor_t *p_td = p_dev->p_tx_dscr;
+
+ uint32_t ul_index;
+ uint32_t ul_address;
+
+ /* Disable TX */
+ gmac_enable_transmit(p_hw, 0);
+
+ /* Set up the TX descriptors */
+ CIRC_CLEAR(p_dev->l_tx_head, p_dev->l_tx_tail);
+ for( ul_index = 0; ul_index < p_dev->ul_tx_list_size; ul_index++ )
+ {
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ ul_address = (uint32_t) 0u;
+ }
+ #else
+ {
+ ul_address = (uint32_t) (&(p_tx_buff[ul_index * GMAC_TX_UNITSIZE]));
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+ p_td[ul_index].addr = ul_address;
+ p_td[ul_index].status.val = GMAC_TXD_USED;
+ }
+ p_td[p_dev->ul_tx_list_size - 1].status.val =
+ GMAC_TXD_USED | GMAC_TXD_WRAP;
+
+ /* Set transmit buffer queue */
+ gmac_set_tx_queue(p_hw, (uint32_t) p_td);
+}
+
+/**
+ * \brief Disable receiver, reset registers and descriptor list.
+ *
+ * \param p_drv Pointer to GMAC Driver instance.
+ */
+static void gmac_reset_rx_mem(gmac_device_t* p_dev)
+{
+ Gmac *p_hw = p_dev->p_hw;
+ uint8_t *p_rx_buff = p_dev->p_rx_buffer;
+ gmac_rx_descriptor_t *pRd = p_dev->p_rx_dscr;
+
+ uint32_t ul_index;
+ uint32_t ul_address;
+
+ /* Disable RX */
+ gmac_enable_receive(p_hw, 0);
+
+ /* Set up the RX descriptors */
+ p_dev->ul_rx_idx = 0;
+ for( ul_index = 0; ul_index < p_dev->ul_rx_list_size; ul_index++ )
+ {
+ ul_address = (uint32_t) (&(p_rx_buff[ul_index * GMAC_RX_UNITSIZE]));
+ pRd[ul_index].addr.val = ul_address & GMAC_RXD_ADDR_MASK;
+ pRd[ul_index].status.val = 0;
+ }
+ pRd[p_dev->ul_rx_list_size - 1].addr.val |= GMAC_RXD_WRAP;
+
+ /* Set receive buffer queue */
+ gmac_set_rx_queue(p_hw, (uint32_t) pRd);
+}
+
+
+/**
+ * \brief Initialize the allocated buffer lists for GMAC driver to transfer data.
+ * Must be invoked after gmac_dev_init() but before RX/TX starts.
+ *
+ * \note If input address is not 8-byte aligned, the address is automatically
+ * adjusted and the list size is reduced by one.
+ *
+ * \param p_gmac Pointer to GMAC instance.
+ * \param p_gmac_dev Pointer to GMAC device instance.
+ * \param p_dev_mm Pointer to the GMAC memory management control block.
+ * \param p_tx_cb Pointer to allocated TX callback list.
+ *
+ * \return GMAC_OK or GMAC_PARAM.
+ */
+static uint8_t gmac_init_mem(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
+ gmac_dev_mem_t* p_dev_mm
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ , gmac_dev_tx_cb_t* p_tx_cb
+#endif
+ )
+{
+ if (p_dev_mm->us_rx_size <= 1 || p_dev_mm->us_tx_size <= 1
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ || p_tx_cb == NULL
+#endif
+ ) {
+ return GMAC_PARAM;
+ }
+
+ /* Assign RX buffers */
+ if (((uint32_t) p_dev_mm->p_rx_buffer & 0x7)
+ || ((uint32_t) p_dev_mm->p_rx_dscr & 0x7)) {
+ p_dev_mm->us_rx_size--;
+ }
+ p_gmac_dev->p_rx_buffer =
+ (uint8_t *) ((uint32_t) p_dev_mm->p_rx_buffer & 0xFFFFFFF8);
+ p_gmac_dev->p_rx_dscr =
+ (gmac_rx_descriptor_t *) ((uint32_t) p_dev_mm->p_rx_dscr
+ & 0xFFFFFFF8);
+ p_gmac_dev->ul_rx_list_size = p_dev_mm->us_rx_size;
+
+ /* Assign TX buffers */
+ if (((uint32_t) p_dev_mm->p_tx_buffer & 0x7)
+ || ((uint32_t) p_dev_mm->p_tx_dscr & 0x7)) {
+ p_dev_mm->us_tx_size--;
+ }
+ p_gmac_dev->p_tx_buffer =
+ (uint8_t *) ((uint32_t) p_dev_mm->p_tx_buffer & 0xFFFFFFF8);
+ p_gmac_dev->p_tx_dscr =
+ (gmac_tx_descriptor_t *) ((uint32_t) p_dev_mm->p_tx_dscr
+ & 0xFFFFFFF8);
+ p_gmac_dev->ul_tx_list_size = p_dev_mm->us_tx_size;
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ p_gmac_dev->func_tx_cb_list = p_tx_cb;
+#endif
+ /* Reset TX & RX */
+ gmac_reset_rx_mem(p_gmac_dev);
+ gmac_reset_tx_mem(p_gmac_dev);
+
+ /* Enable Rx and Tx, plus the statistics register */
+ gmac_enable_transmit(p_gmac, true);
+ gmac_enable_receive(p_gmac, true);
+ gmac_enable_statistics_write(p_gmac, true);
+
+ /* Set up the interrupts for transmission and errors */
+ gmac_enable_interrupt(p_gmac,
+ GMAC_IER_RXUBR | /* Enable receive used bit read interrupt. */
+ GMAC_IER_TUR | /* Enable transmit underrun interrupt. */
+ GMAC_IER_RLEX | /* Enable retry limit exceeded interrupt. */
+ GMAC_IER_TFC | /* Enable transmit buffers exhausted in mid-frame interrupt. */
+ GMAC_IER_TCOMP | /* Enable transmit complete interrupt. */
+ GMAC_IER_ROVR | /* Enable receive overrun interrupt. */
+ GMAC_IER_HRESP | /* Enable Hresp not OK interrupt. */
+ GMAC_IER_PFNZ | /* Enable pause frame received interrupt. */
+ GMAC_IER_PTZ); /* Enable pause time zero interrupt. */
+
+ return GMAC_OK;
+}
+
+/**
+ * \brief Read the PHY register.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_address PHY address.
+ * \param uc_address Register address.
+ * \param p_value Pointer to a 32-bit location to store read data.
+ *
+ * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
+ uint32_t* p_value)
+{
+ gmac_maintain_phy(p_gmac, uc_phy_address, uc_address, 1, 0);
+
+ if (gmac_wait_phy(p_gmac, MAC_PHY_RETRY_MAX) == GMAC_TIMEOUT) {
+ return GMAC_TIMEOUT;
+ }
+ *p_value = gmac_get_phy_data(p_gmac);
+ return GMAC_OK;
+}
+
+/**
+ * \brief Write the PHY register.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_address PHY Address.
+ * \param uc_address Register Address.
+ * \param ul_value Data to write, actually 16-bit data.
+ *
+ * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
+ uint8_t uc_address, uint32_t ul_value)
+{
+ gmac_maintain_phy(p_gmac, uc_phy_address, uc_address, 0, ul_value);
+
+ if (gmac_wait_phy(p_gmac, MAC_PHY_RETRY_MAX) == GMAC_TIMEOUT) {
+ return GMAC_TIMEOUT;
+ }
+ return GMAC_OK;
+}
+
+/**
+ * \brief Initialize the GMAC driver.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param p_gmac_dev Pointer to the GMAC device instance.
+ * \param p_opt GMAC configure options.
+ */
+void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
+ gmac_options_t* p_opt)
+{
+ gmac_dev_mem_t gmac_dev_mm;
+
+ /* Disable TX & RX and more */
+ gmac_network_control(p_gmac, 0);
+ gmac_disable_interrupt(p_gmac, ~0u);
+
+
+ gmac_clear_statistics(p_gmac);
+
+ /* Clear all status bits in the receive status register. */
+ gmac_clear_rx_status(p_gmac, GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA);
+
+ /* Clear all status bits in the transmit status register */
+ gmac_clear_tx_status(p_gmac, GMAC_TSR_UBR | GMAC_TSR_COL | GMAC_TSR_RLE
+ | GMAC_TSR_TFC | GMAC_TSR_TXCOMP | GMAC_TSR_UND);
+
+ /* Clear interrupts */
+ gmac_get_interrupt_status(p_gmac);
+#if !defined(ETHERNET_CONF_DATA_OFFSET)
+ /* Receive Buffer Offset
+ * Indicates the number of bytes by which the received data
+ * is offset from the start of the receive buffer
+ * which can be handy for alignment reasons */
+ /* Note: FreeRTOS+TCP wants to have this offset set to 2 bytes */
+ #error ETHERNET_CONF_DATA_OFFSET not defined, assuming 0
+#endif
+ /* Enable the copy of data into the buffers
+ ignore broadcasts, and not copy FCS. */
+
+ gmac_set_configure(p_gmac,
+ ( gmac_get_configure(p_gmac) & ~GMAC_NCFGR_RXBUFO_Msk ) |
+ GMAC_NCFGR_RFCS | /* Remove FCS, frame check sequence (last 4 bytes) */
+ GMAC_NCFGR_PEN | /* Pause Enable */
+ GMAC_NCFGR_RXBUFO( ETHERNET_CONF_DATA_OFFSET ) |
+ GMAC_RXD_RXCOEN );
+
+ /*
+ * GMAC_DCFGR_TXCOEN: (GMAC_DCFGR) Transmitter Checksum Generation Offload Enable.
+ * Note: tha SAM4E does have RX checksum offloading
+ * but TX checksum offloading has NOT been implemented.
+ */
+
+ gmac_set_dma(p_gmac,
+ gmac_get_dma(p_gmac) | GMAC_DCFGR_TXCOEN );
+
+ gmac_enable_copy_all(p_gmac, p_opt->uc_copy_all_frame);
+ gmac_disable_broadcast(p_gmac, p_opt->uc_no_boardcast);
+
+ /* Fill in GMAC device memory management */
+ gmac_dev_mm.p_rx_buffer = gs_uc_rx_buffer;
+ gmac_dev_mm.p_rx_dscr = gs_rx_desc;
+ gmac_dev_mm.us_rx_size = GMAC_RX_BUFFERS;
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ gmac_dev_mm.p_tx_buffer = NULL;
+ }
+ #else
+ {
+ gmac_dev_mm.p_tx_buffer = gs_uc_tx_buffer;
+ }
+ #endif
+ gmac_dev_mm.p_tx_dscr = gs_tx_desc;
+ gmac_dev_mm.us_tx_size = GMAC_TX_BUFFERS;
+
+ gmac_init_mem(p_gmac, p_gmac_dev, &gmac_dev_mm
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ , gs_tx_callback
+#endif
+ );
+
+ gmac_set_address(p_gmac, 0, p_opt->uc_mac_addr);
+}
+
+/**
+ * \brief Frames can be read from the GMAC in multiple sections.
+ *
+ * Returns > 0 if a complete frame is available
+ * It also it cleans up incomplete older frames
+ */
+
+static uint32_t gmac_dev_poll(gmac_device_t* p_gmac_dev)
+{
+ uint32_t ulReturn = 0;
+ int32_t ulIndex = p_gmac_dev->ul_rx_idx;
+ gmac_rx_descriptor_t *pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
+
+ /* Discard any incomplete frames */
+ while ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) &&
+ (pxHead->status.val & GMAC_RXD_SOF) == 0) {
+ pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
+ circ_inc32 (&ulIndex, p_gmac_dev->ul_rx_list_size);
+ pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
+ p_gmac_dev->ul_rx_idx = ulIndex;
+ #if( GMAC_STATS != 0 )
+ {
+ gmacStats.incompCount++;
+ }
+ #endif
+ }
+
+ while ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) != 0) {
+ if ((pxHead->status.val & GMAC_RXD_EOF) != 0) {
+ /* Here a complete frame has been seen with SOF and EOF */
+ ulReturn = pxHead->status.bm.len;
+ break;
+ }
+ circ_inc32 (&ulIndex, p_gmac_dev->ul_rx_list_size);
+ pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
+ if ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) == 0) {
+ /* CPU is not the owner (yet) */
+ break;
+ }
+ if ((pxHead->status.val & GMAC_RXD_SOF) != 0) {
+ /* Strange, we found a new Start Of Frame
+ * discard previous segments */
+ int32_t ulPrev = p_gmac_dev->ul_rx_idx;
+ pxHead = &p_gmac_dev->p_rx_dscr[ulPrev];
+ do {
+ pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
+ circ_inc32 (&ulPrev, p_gmac_dev->ul_rx_list_size);
+ pxHead = &p_gmac_dev->p_rx_dscr[ulPrev];
+ #if( GMAC_STATS != 0 )
+ {
+ gmacStats.truncCount++;
+ }
+ #endif
+ } while (ulPrev != ulIndex);
+ p_gmac_dev->ul_rx_idx = ulIndex;
+ }
+ }
+ return ulReturn;
+}
+
+/**
+ * \brief Frames can be read from the GMAC in multiple sections.
+ * Read ul_frame_size bytes from the GMAC receive buffers to pcTo.
+ * p_rcv_size is the size of the entire frame. Generally gmac_read
+ * will be repeatedly called until the sum of all the ul_frame_size equals
+ * the value of p_rcv_size.
+ *
+ * \param p_gmac_dev Pointer to the GMAC device instance.
+ * \param p_frame Address of the frame buffer.
+ * \param ul_frame_size Length of the frame.
+ * \param p_rcv_size Received frame size.
+ *
+ * \return GMAC_OK if receiving frame successfully, otherwise failed.
+ */
+uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
+ uint32_t ul_frame_size, uint32_t* p_rcv_size)
+{
+ int32_t nextIdx; /* A copy of the Rx-index 'ul_rx_idx' */
+ int32_t bytesLeft = gmac_dev_poll (p_gmac_dev);
+ gmac_rx_descriptor_t *pxHead;
+
+ if (bytesLeft == 0 )
+ {
+ return GMAC_RX_NULL;
+ }
+
+ /* gmac_dev_poll has confirmed that there is a complete frame at
+ * the current position 'ul_rx_idx'
+ */
+ nextIdx = p_gmac_dev->ul_rx_idx;
+
+ /* Read +2 bytes because buffers are aligned at -2 bytes */
+ bytesLeft = min( bytesLeft + 2, ( int32_t )ul_frame_size );
+
+ /* The frame will be copied in 1 or 2 memcpy's */
+ if( ( p_frame != NULL ) && ( bytesLeft != 0 ) )
+ {
+ const uint8_t *source;
+ int32_t left;
+ int32_t toCopy;
+
+ source = p_gmac_dev->p_rx_buffer + nextIdx * GMAC_RX_UNITSIZE;
+ left = bytesLeft;
+ toCopy = ( p_gmac_dev->ul_rx_list_size - nextIdx ) * GMAC_RX_UNITSIZE;
+ if(toCopy > left )
+ {
+ toCopy = left;
+ }
+ memcpy (p_frame, source, toCopy);
+ left -= toCopy;
+
+ if( left != 0ul )
+ {
+ memcpy (p_frame + toCopy, (void*)p_gmac_dev->p_rx_buffer, left);
+ }
+ }
+
+ do
+ {
+ pxHead = &p_gmac_dev->p_rx_dscr[nextIdx];
+ pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
+ circ_inc32 (&nextIdx, p_gmac_dev->ul_rx_list_size);
+ } while ((pxHead->status.val & GMAC_RXD_EOF) == 0);
+
+ p_gmac_dev->ul_rx_idx = nextIdx;
+
+ *p_rcv_size = bytesLeft;
+
+ return GMAC_OK;
+}
+
+
+extern void vGMACGenerateChecksum( uint8_t *apBuffer );
+
+/**
+ * \brief Send ulLength bytes from pcFrom. This copies the buffer to one of the
+ * GMAC Tx buffers, and then indicates to the GMAC that the buffer is ready.
+ * If lEndOfFrame is true then the data being copied is the end of the frame
+ * and the frame can be transmitted.
+ *
+ * \param p_gmac_dev Pointer to the GMAC device instance.
+ * \param p_buffer Pointer to the data buffer.
+ * \param ul_size Length of the frame.
+ * \param func_tx_cb Transmit callback function.
+ *
+ * \return Length sent.
+ */
+uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
+ uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb)
+{
+
+ volatile gmac_tx_descriptor_t *p_tx_td;
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ volatile gmac_dev_tx_cb_t *p_func_tx_cb;
+#endif
+
+ Gmac *p_hw = p_gmac_dev->p_hw;
+
+#if( GMAC_USES_TX_CALLBACK == 0 )
+ ( void )func_tx_cb;
+#endif
+
+ /* Check parameter */
+ if (ul_size > GMAC_TX_UNITSIZE) {
+ return GMAC_PARAM;
+ }
+
+ /* Pointers to the current transmit descriptor */
+ p_tx_td = &p_gmac_dev->p_tx_dscr[p_gmac_dev->l_tx_head];
+
+ /* If no free TxTd, buffer can't be sent, schedule the wakeup callback */
+// if (CIRC_SPACE(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
+// p_gmac_dev->ul_tx_list_size) == 0)
+ {
+ if ((p_tx_td->status.val & GMAC_TXD_USED) == 0)
+ return GMAC_TX_BUSY;
+ }
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ /* Pointers to the current Tx callback */
+ p_func_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_head];
+#endif
+
+ /* Set up/copy data to transmission buffer */
+ if (p_buffer && ul_size) {
+ /* Driver manages the ring buffer */
+ /* Calculating the checksum here is faster than calculating it from the GMAC buffer
+ * because withing p_buffer, it is well aligned */
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* Zero-copy... */
+ p_tx_td->addr = ( uint32_t ) p_buffer;
+ }
+ #else
+ {
+ /* Or Memcopy... */
+ memcpy((void *)p_tx_td->addr, p_buffer, ul_size);
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+ vGMACGenerateChecksum( ( uint8_t * ) p_tx_td->addr );
+ }
+
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ /* Tx callback */
+ *p_func_tx_cb = func_tx_cb;
+#endif
+
+ /* Update transmit descriptor status */
+
+ /* The buffer size defined is the length of ethernet frame,
+ so it's always the last buffer of the frame. */
+ if( p_gmac_dev->l_tx_head == ( int32_t )( p_gmac_dev->ul_tx_list_size - 1 ) )
+ {
+ /* No need to 'and' with GMAC_TXD_LEN_MASK because ul_size has been checked */
+ p_tx_td->status.val =
+ ul_size | GMAC_TXD_LAST | GMAC_TXD_WRAP;
+ } else {
+ p_tx_td->status.val =
+ ul_size | GMAC_TXD_LAST;
+ }
+
+ circ_inc32( &p_gmac_dev->l_tx_head, p_gmac_dev->ul_tx_list_size );
+
+ /* Now start to transmit if it is still not done */
+ gmac_start_transmission(p_hw);
+
+ return GMAC_OK;
+}
+
+/**
+ * \brief Get current load of transmit.
+ *
+ * \param p_gmac_dev Pointer to the GMAC device instance.
+ *
+ * \return Current load of transmit.
+ */
+#if( GMAC_USES_TX_CALLBACK != 0 )
+/* Without defining GMAC_USES_TX_CALLBACK, l_tx_tail won't be updated */
+uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev)
+{
+ uint16_t us_head = p_gmac_dev->l_tx_head;
+ uint16_t us_tail = p_gmac_dev->l_tx_tail;
+ return CIRC_CNT(us_head, us_tail, p_gmac_dev->ul_tx_list_size);
+}
+#endif
+
+/**
+ * \brief Register/Clear RX callback. Callback will be invoked after the next received
+ * frame.
+ *
+ * When gmac_dev_read() returns GMAC_RX_NULL, the application task calls
+ * gmac_dev_set_rx_callback() to register func_rx_cb() callback and enters suspend state.
+ * The callback is in charge to resume the task once a new frame has been
+ * received. The next time gmac_dev_read() is called, it will be successful.
+ *
+ * This function is usually invoked from the RX callback itself with NULL
+ * callback, to unregister. Once the callback has resumed the application task,
+ * there is no need to invoke the callback again.
+ *
+ * \param p_gmac_dev Pointer to the GMAC device instance.
+ * \param func_tx_cb Receive callback function.
+ */
+void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
+ gmac_dev_rx_cb_t func_rx_cb)
+{
+ Gmac *p_hw = p_gmac_dev->p_hw;
+
+ if (func_rx_cb == NULL) {
+ gmac_disable_interrupt(p_hw, GMAC_IDR_RCOMP);
+ p_gmac_dev->func_rx_cb = NULL;
+ } else {
+ p_gmac_dev->func_rx_cb = func_rx_cb;
+ gmac_enable_interrupt(p_hw, GMAC_IER_RCOMP);
+ }
+}
+
+/**
+ * \brief Register/Clear TX wakeup callback.
+ *
+ * When gmac_dev_write() returns GMAC_TX_BUSY (all transmit descriptor busy), the application
+ * task calls gmac_dev_set_tx_wakeup_callback() to register func_wakeup() callback and
+ * enters suspend state. The callback is in charge to resume the task once
+ * several transmit descriptors have been released. The next time gmac_dev_write() will be called,
+ * it shall be successful.
+ *
+ * This function is usually invoked with NULL callback from the TX wakeup
+ * callback itself, to unregister. Once the callback has resumed the
+ * application task, there is no need to invoke the callback again.
+ *
+ * \param p_gmac_dev Pointer to GMAC device instance.
+ * \param func_wakeup Pointer to wakeup callback function.
+ * \param uc_threshold Number of free transmit descriptor before wakeup callback invoked.
+ *
+ * \return GMAC_OK, GMAC_PARAM on parameter error.
+ */
+#if( GMAC_USES_WAKEUP_CALLBACK )
+uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
+ gmac_dev_wakeup_cb_t func_wakeup_cb, uint8_t uc_threshold)
+{
+ if (func_wakeup_cb == NULL) {
+ p_gmac_dev->func_wakeup_cb = NULL;
+ } else {
+ if (uc_threshold <= p_gmac_dev->ul_tx_list_size) {
+ p_gmac_dev->func_wakeup_cb = func_wakeup_cb;
+ p_gmac_dev->uc_wakeup_threshold = uc_threshold;
+ } else {
+ return GMAC_PARAM;
+ }
+ }
+
+ return GMAC_OK;
+}
+#endif /* GMAC_USES_WAKEUP_CALLBACK */
+
+/**
+ * \brief Reset TX & RX queue & statistics.
+ *
+ * \param p_gmac_dev Pointer to GMAC device instance.
+ */
+void gmac_dev_reset(gmac_device_t* p_gmac_dev)
+{
+ Gmac *p_hw = p_gmac_dev->p_hw;
+
+ gmac_reset_rx_mem(p_gmac_dev);
+ gmac_reset_tx_mem(p_gmac_dev);
+ gmac_network_control(p_hw, GMAC_NCR_TXEN | GMAC_NCR_RXEN
+ | GMAC_NCR_WESTAT | GMAC_NCR_CLRSTAT);
+}
+
+void gmac_dev_halt(Gmac* p_gmac);
+
+void gmac_dev_halt(Gmac* p_gmac)
+{
+ gmac_network_control(p_gmac, GMAC_NCR_WESTAT | GMAC_NCR_CLRSTAT);
+ gmac_disable_interrupt(p_gmac, ~0u);
+}
+
+
+/**
+ * \brief GMAC Interrupt handler.
+ *
+ * \param p_gmac_dev Pointer to GMAC device instance.
+ */
+
+#if( GMAC_STATS != 0 )
+ extern int logPrintf( const char *pcFormat, ... );
+
+ void gmac_show_irq_counts ()
+ {
+ int index;
+ for (index = 0; index < ARRAY_SIZE(intPairs); index++) {
+ if (gmacStats.intStatus[intPairs[index].index]) {
+ logPrintf("%s : %6u\n", intPairs[index].name, gmacStats.intStatus[intPairs[index].index]);
+ }
+ }
+ }
+#endif
+
+void gmac_handler(gmac_device_t* p_gmac_dev)
+{
+ Gmac *p_hw = p_gmac_dev->p_hw;
+
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ gmac_tx_descriptor_t *p_tx_td;
+ gmac_dev_tx_cb_t *p_tx_cb = NULL;
+ uint32_t ul_tx_status_flag;
+#endif
+#if( GMAC_STATS != 0 )
+ int index;
+#endif
+
+ /* volatile */ uint32_t ul_isr;
+ /* volatile */ uint32_t ul_rsr;
+ /* volatile */ uint32_t ul_tsr;
+
+ ul_isr = gmac_get_interrupt_status(p_hw);
+ ul_rsr = gmac_get_rx_status(p_hw);
+ ul_tsr = gmac_get_tx_status(p_hw);
+
+/* Why clear bits that are ignored anyway ? */
+/* ul_isr &= ~(gmac_get_interrupt_mask(p_hw) | 0xF8030300); */
+ #if( GMAC_STATS != 0 )
+ {
+ for (index = 0; index < ARRAY_SIZE(intPairs); index++) {
+ if (ul_isr & intPairs[index].mask)
+ gmacStats.intStatus[intPairs[index].index]++;
+ }
+ }
+ #endif /* GMAC_STATS != 0 */
+
+ /* RX packet */
+ if ((ul_isr & GMAC_ISR_RCOMP) || (ul_rsr & (GMAC_RSR_REC|GMAC_RSR_RXOVR|GMAC_RSR_BNA))) {
+ /* Clear status */
+ gmac_clear_rx_status(p_hw, ul_rsr);
+
+ if (ul_isr & GMAC_ISR_RCOMP)
+ ul_rsr |= GMAC_RSR_REC;
+ /* Invoke callbacks which can be useful to wake op a task */
+ if (p_gmac_dev->func_rx_cb) {
+ p_gmac_dev->func_rx_cb(ul_rsr);
+ }
+ }
+
+ /* TX packet */
+ if ((ul_isr & GMAC_ISR_TCOMP) || (ul_tsr & (GMAC_TSR_TXCOMP|GMAC_TSR_COL|GMAC_TSR_RLE|GMAC_TSR_UND))) {
+
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ ul_tx_status_flag = GMAC_TSR_TXCOMP;
+#endif
+ /* A frame transmitted */
+
+ /* Check RLE */
+ if (ul_tsr & GMAC_TSR_RLE) {
+ /* Status RLE & Number of discarded buffers */
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ ul_tx_status_flag = GMAC_TSR_RLE | CIRC_CNT(p_gmac_dev->l_tx_head,
+ p_gmac_dev->l_tx_tail, p_gmac_dev->ul_tx_list_size);
+ p_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_tail];
+#endif
+ gmac_reset_tx_mem(p_gmac_dev);
+ gmac_enable_transmit(p_hw, 1);
+ }
+ /* Clear status */
+ gmac_clear_tx_status(p_hw, ul_tsr);
+
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ if (!CIRC_EMPTY(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail)) {
+ /* Check the buffers */
+ do {
+ p_tx_td = &p_gmac_dev->p_tx_dscr[p_gmac_dev->l_tx_tail];
+ p_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_tail];
+ /* Any error? Exit if buffer has not been sent yet */
+ if ((p_tx_td->status.val & GMAC_TXD_USED) == 0) {
+ break;
+ }
+
+ /* Notify upper layer that a packet has been sent */
+ if (*p_tx_cb) {
+ (*p_tx_cb) (ul_tx_status_flag, (void*)p_tx_td->addr);
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ p_tx_td->addr = 0ul;
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+ }
+
+ circ_inc32(&p_gmac_dev->l_tx_tail, p_gmac_dev->ul_tx_list_size);
+ } while (CIRC_CNT(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
+ p_gmac_dev->ul_tx_list_size));
+ }
+
+ if (ul_tsr & GMAC_TSR_RLE) {
+ /* Notify upper layer RLE */
+ if (*p_tx_cb) {
+ (*p_tx_cb) (ul_tx_status_flag, NULL);
+ }
+ }
+#endif /* GMAC_USES_TX_CALLBACK */
+
+#if( GMAC_USES_WAKEUP_CALLBACK )
+ /* If a wakeup has been scheduled, notify upper layer that it can
+ send other packets, and the sending will be successful. */
+ if ((CIRC_SPACE(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
+ p_gmac_dev->ul_tx_list_size) >= p_gmac_dev->uc_wakeup_threshold)
+ && p_gmac_dev->func_wakeup_cb) {
+ p_gmac_dev->func_wakeup_cb();
+ }
+#endif
+ }
+}
+
+//@}
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+}
+#endif
+/**INDENT-ON**/
+/// @endcond
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.h
index d741a2a0a..fca3ece33 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.h
@@ -1,1346 +1,1346 @@
- /**
- * \file
- *
- * \brief GMAC (Ethernet MAC) driver for SAM.
- *
- * Copyright (c) 2013 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#ifndef GMAC_H_INCLUDED
-#define GMAC_H_INCLUDED
-
-#include "compiler.h"
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-extern "C" {
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-/** The buffer addresses written into the descriptors must be aligned, so the
- last few bits are zero. These bits have special meaning for the GMAC
- peripheral and cannot be used as part of the address. */
-#define GMAC_RXD_ADDR_MASK 0xFFFFFFFC
-#define GMAC_RXD_WRAP (1ul << 1) /**< Wrap bit */
-#define GMAC_RXD_OWNERSHIP (1ul << 0) /**< Ownership bit */
-
-#define GMAC_RXD_BROADCAST (1ul << 31) /**< Broadcast detected */
-#define GMAC_RXD_MULTIHASH (1ul << 30) /**< Multicast hash match */
-#define GMAC_RXD_UNIHASH (1ul << 29) /**< Unicast hash match */
-#define GMAC_RXD_ADDR_FOUND (1ul << 27) /**< Specific address match found */
-#define GMAC_RXD_ADDR (3ul << 25) /**< Address match */
-#define GMAC_RXD_RXCOEN (1ul << 24) /**< RXCOEN related function */
-#define GMAC_RXD_TYPE (3ul << 22) /**< Type ID match */
-#define GMAC_RXD_VLAN (1ul << 21) /**< VLAN tag detected */
-#define GMAC_RXD_PRIORITY (1ul << 20) /**< Priority tag detected */
-#define GMAC_RXD_PRIORITY_MASK (3ul << 17) /**< VLAN priority */
-#define GMAC_RXD_CFI (1ul << 16) /**< Concatenation Format Indicator only if bit 21 is set */
-#define GMAC_RXD_EOF (1ul << 15) /**< End of frame */
-#define GMAC_RXD_SOF (1ul << 14) /**< Start of frame */
-#define GMAC_RXD_FCS (1ul << 13) /**< Frame check sequence */
-#define GMAC_RXD_OFFSET_MASK /**< Receive buffer offset */
-#define GMAC_RXD_LEN_MASK (0xFFF) /**< Length of frame including FCS (if selected) */
-#define GMAC_RXD_LENJUMBO_MASK (0x3FFF) /**< Jumbo frame length */
-
-#define GMAC_TXD_USED (1ul << 31) /**< Frame is transmitted */
-#define GMAC_TXD_WRAP (1ul << 30) /**< Last descriptor */
-#define GMAC_TXD_ERROR (1ul << 29) /**< Retry limit exceeded, error */
-#define GMAC_TXD_UNDERRUN (1ul << 28) /**< Transmit underrun */
-#define GMAC_TXD_EXHAUSTED (1ul << 27) /**< Buffer exhausted */
-#define GMAC_TXD_LATE (1ul << 26) /**< Late collision,transmit error */
-#define GMAC_TXD_CHECKSUM_ERROR (7ul << 20) /**< Checksum error */
-#define GMAC_TXD_NOCRC (1ul << 16) /**< No CRC */
-#define GMAC_TXD_LAST (1ul << 15) /**< Last buffer in frame */
-#define GMAC_TXD_LEN_MASK (0x1FFF) /**< Length of buffer */
-
-/** The MAC can support frame lengths up to 1536 bytes */
-#define GMAC_FRAME_LENTGH_MAX 1536
-
-#define GMAC_RX_UNITSIZE 128 /**< Fixed size for RX buffer */
-#define GMAC_TX_UNITSIZE 1518 /**< Size for ETH frame length */
-
-/** GMAC clock speed */
-#define GMAC_MCK_SPEED_240MHZ (240*1000*1000)
-#define GMAC_MCK_SPEED_160MHZ (160*1000*1000)
-#define GMAC_MCK_SPEED_120MHZ (120*1000*1000)
-#define GMAC_MCK_SPEED_80MHZ (80*1000*1000)
-#define GMAC_MCK_SPEED_40MHZ (40*1000*1000)
-#define GMAC_MCK_SPEED_20MHZ (20*1000*1000)
-
-/** GMAC maintain code default value*/
-#define GMAC_MAN_CODE_VALUE (10)
-
-/** GMAC maintain start of frame default value*/
-#define GMAC_MAN_SOF_VALUE (1)
-
-/** GMAC maintain read/write*/
-#define GMAC_MAN_RW_TYPE (2)
-
-/** GMAC maintain read only*/
-#define GMAC_MAN_READ_ONLY (1)
-
-/** GMAC address length */
-#define GMAC_ADDR_LENGTH (6)
-
-
-#define GMAC_DUPLEX_HALF 0
-#define GMAC_DUPLEX_FULL 1
-
-#define GMAC_SPEED_10M 0
-#define GMAC_SPEED_100M 1
-
-/**
- * \brief Return codes for GMAC APIs.
- */
-typedef enum {
- GMAC_OK = 0, /** 0 Operation OK */
- GMAC_TIMEOUT = 1, /** 1 GMAC operation timeout */
- GMAC_TX_BUSY, /** 2 TX in progress */
- GMAC_RX_NULL, /** 3 No data received */
- GMAC_SIZE_TOO_SMALL, /** 4 Buffer size not enough */
- GMAC_PARAM, /** 5 Parameter error, TX packet invalid or RX size too small */
- GMAC_INVALID = 0xFF, /* Invalid */
-} gmac_status_t;
-
-/**
- * \brief Media Independent Interface (MII) type.
- */
-typedef enum {
- GMAC_PHY_MII = 0, /** MII mode */
- GMAC_PHY_RMII = 1, /** Reduced MII mode */
- GMAC_PHY_INVALID = 0xFF, /* Invalid mode*/
-} gmac_mii_mode_t;
-
-/** Receive buffer descriptor struct */
-COMPILER_PACK_SET(8)
-typedef struct gmac_rx_descriptor {
- union gmac_rx_addr {
- uint32_t val;
- struct gmac_rx_addr_bm {
- uint32_t b_ownership:1, /**< User clear, GMAC sets this to 1 once it has successfully written a frame to memory */
- b_wrap:1, /**< Marks last descriptor in receive buffer */
- addr_dw:30; /**< Address in number of DW */
- } bm;
- } addr; /**< Address, Wrap & Ownership */
- union gmac_rx_status {
- uint32_t val;
- struct gmac_rx_status_bm {
- uint32_t len:13, /** 0..12 Length of frame including FCS */
- b_fcs:1, /** 13 Receive buffer offset, bits 13:12 of frame length for jumbo frame */
- b_sof:1, /** 14 Start of frame */
- b_eof:1, /** 15 End of frame */
- b_cfi:1, /** 16 Concatenation Format Indicator */
- vlan_priority:3, /** 17..19 VLAN priority (if VLAN detected) */
- b_priority_detected:1, /** 20 Priority tag detected */
- b_vlan_detected:1, /** 21 VLAN tag detected */
- b_type_id_match:2, /** 22..23 Type ID match */
- b_checksumoffload:1, /** 24 Checksum offload specific function */
- b_addrmatch:2, /** 25..26 Address register match */
- b_ext_addr_match:1, /** 27 External address match found */
- reserved:1, /** 28 */
- b_uni_hash_match:1, /** 29 Unicast hash match */
- b_multi_hash_match:1, /** 30 Multicast hash match */
- b_boardcast_detect:1; /** 31 Global broadcast address detected */
- } bm;
- } status;
-} gmac_rx_descriptor_t;
-
-/** Transmit buffer descriptor struct */
-COMPILER_PACK_SET(8)
-typedef struct gmac_tx_descriptor {
- uint32_t addr;
- union gmac_tx_status {
- uint32_t val;
- struct gmac_tx_status_bm {
- uint32_t len:14, /** 0..13 Length of buffer */
- reserved:1, /** 14 */
- b_last_buffer:1, /** 15 Last buffer (in the current frame) */
- b_no_crc:1, /** 16 No CRC */
- reserved1:3, /** 17..19 */
- b_checksumoffload:3, /** 20..22 Transmit checksum generation offload errors */
- reserved2:3, /** 23..25 */
- b_lco:1, /** 26 Late collision, transmit error detected */
- b_exhausted:1, /** 27 Buffer exhausted in mid frame */
- b_underrun:1, /** 28 Transmit underrun */
- b_error:1, /** 29 Retry limit exceeded, error detected */
- b_wrap:1, /** 30 Marks last descriptor in TD list */
- b_used:1; /** 31 User clear, GMAC sets this to 1 once a frame has been successfully transmitted */
- } bm;
- } status;
-} gmac_tx_descriptor_t;
-
-COMPILER_PACK_RESET()
-
-/**
- * \brief Input parameters when initializing the gmac module mode.
- */
-typedef struct gmac_options {
- /* Enable/Disable CopyAllFrame */
- uint8_t uc_copy_all_frame;
- /* Enable/Disable NoBroadCast */
- uint8_t uc_no_boardcast;
- /* MAC address */
- uint8_t uc_mac_addr[GMAC_ADDR_LENGTH];
-} gmac_options_t;
-
-/** RX callback */
-typedef void (*gmac_dev_tx_cb_t) (uint32_t ul_status);
-/** Wakeup callback */
-typedef void (*gmac_dev_wakeup_cb_t) (void);
-
-/**
- * GMAC driver structure.
- */
-typedef struct gmac_device {
-
- /** Pointer to HW register base */
- Gmac *p_hw;
- /**
- * Pointer to allocated TX buffer.
- * Section 3.6 of AMBA 2.0 spec states that burst should not cross
- * 1K Boundaries.
- * Receive buffer manager writes are burst of 2 words => 3 lsb bits
- * of the address shall be set to 0.
- */
- uint8_t *p_tx_buffer;
- /** Pointer to allocated RX buffer */
- uint8_t *p_rx_buffer;
- /** Pointer to Rx TDs (must be 8-byte aligned) */
- gmac_rx_descriptor_t *p_rx_dscr;
- /** Pointer to Tx TDs (must be 8-byte aligned) */
- gmac_tx_descriptor_t *p_tx_dscr;
- /** Optional callback to be invoked once a frame has been received */
- gmac_dev_tx_cb_t func_rx_cb;
-#if( GMAC_USES_WAKEUP_CALLBACK )
- /** Optional callback to be invoked once several TDs have been released */
- gmac_dev_wakeup_cb_t func_wakeup_cb;
-#endif
-#if( GMAC_USES_TX_CALLBACK != 0 )
- /** Optional callback list to be invoked once TD has been processed */
- gmac_dev_tx_cb_t *func_tx_cb_list;
-#endif
- /** RX TD list size */
- uint32_t ul_rx_list_size;
- /** RX index for current processing TD */
- uint32_t ul_rx_idx;
- /** TX TD list size */
- uint32_t ul_tx_list_size;
- /** Circular buffer head pointer by upper layer (buffer to be sent) */
- int32_t l_tx_head;
- /** Circular buffer tail pointer incremented by handlers (buffer sent) */
- int32_t l_tx_tail;
-
- /** Number of free TD before wakeup callback is invoked */
- uint32_t uc_wakeup_threshold;
-} gmac_device_t;
-
-/**
- * \brief Write network control value.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_ncr Network control value.
- */
-static inline void gmac_network_control(Gmac* p_gmac, uint32_t ul_ncr)
-{
- p_gmac->GMAC_NCR = ul_ncr;
-}
-
-/**
- * \brief Get network control value.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-
-static inline uint32_t gmac_get_network_control(Gmac* p_gmac)
-{
- return p_gmac->GMAC_NCR;
-}
-
-/**
- * \brief Enable/Disable GMAC receive.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable GMAC receiver, else to enable it.
- */
-static inline void gmac_enable_receive(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_RXEN;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_RXEN;
- }
-}
-
-/**
- * \brief Enable/Disable GMAC transmit.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable GMAC transmit, else to enable it.
- */
-static inline void gmac_enable_transmit(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_TXEN;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_TXEN;
- }
-}
-
-/**
- * \brief Enable/Disable GMAC management.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable GMAC management, else to enable it.
- */
-static inline void gmac_enable_management(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_MPE;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_MPE;
- }
-}
-
-/**
- * \brief Clear all statistics registers.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_clear_statistics(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_CLRSTAT;
-}
-
-/**
- * \brief Increase all statistics registers.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_increase_statistics(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_INCSTAT;
-}
-
-/**
- * \brief Enable/Disable statistics registers writing.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the statistics registers writing, else to enable it.
- */
-static inline void gmac_enable_statistics_write(Gmac* p_gmac,
- uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_WESTAT;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_WESTAT;
- }
-}
-
-/**
- * \brief In half-duplex mode, forces collisions on all received frames.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the back pressure, else to enable it.
- */
-static inline void gmac_enable_back_pressure(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_BP;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_BP;
- }
-}
-
-/**
- * \brief Start transmission.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_start_transmission(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TSTART;
-}
-
-/**
- * \brief Halt transmission.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_halt_transmission(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_THALT;
-}
-
-/**
- * \brief Transmit pause frame.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_tx_pause_frame(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TXPF;
-}
-
-/**
- * \brief Transmit zero quantum pause frame.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_tx_pause_zero_quantum_frame(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TXZQPF;
-}
-
-/**
- * \brief Read snapshot.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_read_snapshot(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_RDS;
-}
-
-/**
- * \brief Store receivetime stamp to memory.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to normal operation, else to enable the store.
- */
-static inline void gmac_store_rx_time_stamp(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_SRTSM;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_SRTSM;
- }
-}
-
-/**
- * \brief Enable PFC priority-based pause reception.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 1 to set the reception, 0 to disable.
- */
-static inline void gmac_enable_pfc_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_ENPBPR;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_ENPBPR;
- }
-}
-
-/**
- * \brief Transmit PFC priority-based pause reception.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_transmit_pfc_pause_frame(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TXPBPF;
-}
-
-/**
- * \brief Flush next packet.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_flush_next_packet(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_FNP;
-}
-
-/**
- * \brief Set up network configuration register.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_cfg Network configuration value.
- */
-static inline void gmac_set_configure(Gmac* p_gmac, uint32_t ul_cfg)
-{
- p_gmac->GMAC_NCFGR = ul_cfg;
-}
-
-/**
- * \brief Get network configuration.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Network configuration.
- */
-static inline uint32_t gmac_get_configure(Gmac* p_gmac)
-{
- return p_gmac->GMAC_NCFGR;
-}
-
-
-/* Get and set DMA Configuration Register */
-static inline void gmac_set_dma(Gmac* p_gmac, uint32_t ul_cfg)
-{
- p_gmac->GMAC_DCFGR = ul_cfg;
-}
-
-static inline uint32_t gmac_get_dma(Gmac* p_gmac)
-{
- return p_gmac->GMAC_DCFGR;
-}
-
-/**
- * \brief Set speed.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_speed 1 to indicate 100Mbps, 0 to 10Mbps.
- */
-static inline void gmac_set_speed(Gmac* p_gmac, uint8_t uc_speed)
-{
- if (uc_speed) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_SPD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_SPD;
- }
-}
-
-/**
- * \brief Enable/Disable Full-Duplex mode.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the Full-Duplex mode, else to enable it.
- */
-static inline void gmac_enable_full_duplex(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_FD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_FD;
- }
-}
-
-/**
- * \brief Enable/Disable Copy(Receive) All Valid Frames.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable copying all valid frames, else to enable it.
- */
-static inline void gmac_enable_copy_all(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_CAF;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_CAF;
- }
-}
-
-/**
- * \brief Enable/Disable jumbo frames (up to 10240 bytes).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the jumbo frames, else to enable it.
- */
-static inline void gmac_enable_jumbo_frames(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_JFRAME;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_JFRAME;
- }
-}
-
-/**
- * \brief Disable/Enable broadcast receiving.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 1 to disable the broadcast, else to enable it.
- */
-static inline void gmac_disable_broadcast(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_NBC;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_NBC;
- }
-}
-
-/**
- * \brief Enable/Disable multicast hash.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the multicast hash, else to enable it.
- */
-static inline void gmac_enable_multicast_hash(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_UNIHEN;
- }
-}
-
-/**
- * \brief Enable/Disable big frames (over 1518, up to 1536).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable big frames else to enable it.
- */
-static inline void gmac_enable_big_frame(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_MAXFS;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_MAXFS;
- }
-}
-
-/**
- * \brief Set MDC clock divider.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_mck GMAC MCK.
- *
- * \return GMAC_OK if successfully.
- */
-static inline uint8_t gmac_set_mdc_clock(Gmac* p_gmac, uint32_t ul_mck)
-{
- uint32_t ul_clk;
-
- if (ul_mck > GMAC_MCK_SPEED_240MHZ) {
- return GMAC_INVALID;
- } else if (ul_mck > GMAC_MCK_SPEED_160MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_96;
- } else if (ul_mck > GMAC_MCK_SPEED_120MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_64;
- } else if (ul_mck > GMAC_MCK_SPEED_80MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_48;
- } else if (ul_mck > GMAC_MCK_SPEED_40MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_32;
- } else if (ul_mck > GMAC_MCK_SPEED_20MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_16;
- } else {
- ul_clk = GMAC_NCFGR_CLK_MCK_8;
- }
- ;
- p_gmac->GMAC_NCFGR = (p_gmac->GMAC_NCFGR & ~GMAC_NCFGR_CLK_Msk) | ul_clk;
- return GMAC_OK;
-}
-
-/**
- * \brief Enable/Disable retry test.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the GMAC receiver, else to enable it.
- */
-static inline void gmac_enable_retry_test(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RTY;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RTY;
- }
-}
-
-/**
- * \brief Enable/Disable pause (when a valid pause frame is received).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable pause frame, else to enable it.
- */
-static inline void gmac_enable_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_PEN;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_PEN;
- }
-}
-
-/**
- * \brief Set receive buffer offset to 0 ~ 3.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_set_rx_buffer_offset(Gmac* p_gmac, uint8_t uc_offset)
-{
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RXBUFO_Msk;
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RXBUFO(uc_offset);
-}
-
-/**
- * \brief Enable/Disable receive length field checking.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable receive length field checking, else to enable it.
- */
-static inline void gmac_enable_rx_length_check(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_LFERD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_LFERD;
- }
-}
-
-/**
- * \brief Enable/Disable discarding FCS field of received frames.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable discarding FCS field of received frames, else to enable it.
- */
-static inline void gmac_enable_discard_fcs(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RFCS;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RFCS;
- }
-}
-
-
-/**
- * \brief Enable/Disable frames to be received in half-duplex mode
- * while transmitting.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the received in half-duplex mode, else to enable it.
- */
-static inline void gmac_enable_efrhd(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_EFRHD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_EFRHD;
- }
-}
-
-/**
- * \brief Enable/Disable ignore RX FCS.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable ignore RX FCS, else to enable it.
- */
-static inline void gmac_enable_ignore_rx_fcs(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_IRXFCS;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_IRXFCS;
- }
-}
-
-/**
- * \brief Get Network Status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Network status.
- */
-static inline uint32_t gmac_get_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_NSR;
-}
-
-/**
- * \brief Get MDIO IN pin status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return MDIO IN pin status.
- */
-static inline uint8_t gmac_get_MDIO(Gmac* p_gmac)
-{
- return ((p_gmac->GMAC_NSR & GMAC_NSR_MDIO) > 0);
-}
-
-/**
- * \brief Check if PHY is idle.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return 1 if PHY is idle.
- */
-static inline uint8_t gmac_is_phy_idle(Gmac* p_gmac)
-{
- return ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) > 0);
-}
-
-/**
- * \brief Return transmit status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Transmit status.
- */
-static inline uint32_t gmac_get_tx_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_TSR;
-}
-
-/**
- * \brief Clear transmit status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_status Transmit status.
- */
-static inline void gmac_clear_tx_status(Gmac* p_gmac, uint32_t ul_status)
-{
- p_gmac->GMAC_TSR = ul_status;
-}
-
-/**
- * \brief Return receive status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline uint32_t gmac_get_rx_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_RSR;
-}
-
-/**
- * \brief Clear receive status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_status Receive status.
- */
-static inline void gmac_clear_rx_status(Gmac* p_gmac, uint32_t ul_status)
-{
- p_gmac->GMAC_RSR = ul_status;
-}
-
-/**
- * \brief Set Rx Queue.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_addr Rx queue address.
- */
-static inline void gmac_set_rx_queue(Gmac* p_gmac, uint32_t ul_addr)
-{
- p_gmac->GMAC_RBQB = GMAC_RBQB_ADDR_Msk & ul_addr;
-}
-
-/**
- * \brief Get Rx Queue Address.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Rx queue address.
- */
-static inline uint32_t gmac_get_rx_queue(Gmac* p_gmac)
-{
- return p_gmac->GMAC_RBQB;
-}
-
-/**
- * \brief Set Tx Queue.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_addr Tx queue address.
- */
-static inline void gmac_set_tx_queue(Gmac* p_gmac, uint32_t ul_addr)
-{
- p_gmac->GMAC_TBQB = GMAC_TBQB_ADDR_Msk & ul_addr;
-}
-
-/**
- * \brief Get Tx Queue.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Rx queue address.
- */
-static inline uint32_t gmac_get_tx_queue(Gmac* p_gmac)
-{
- return p_gmac->GMAC_TBQB;
-}
-
-/**
- * \brief Enable interrupt(s).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_source Interrupt source(s) to be enabled.
- */
-static inline void gmac_enable_interrupt(Gmac* p_gmac, uint32_t ul_source)
-{
- p_gmac->GMAC_IER = ul_source;
-}
-
-/**
- * \brief Disable interrupt(s).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_source Interrupt source(s) to be disabled.
- */
-static inline void gmac_disable_interrupt(Gmac* p_gmac, uint32_t ul_source)
-{
- p_gmac->GMAC_IDR = ul_source;
-}
-
-/**
- * \brief Return interrupt status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Interrupt status.
- */
-static inline uint32_t gmac_get_interrupt_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_ISR;
-}
-
-/**
- * \brief Return interrupt mask.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Interrupt mask.
- */
-static inline uint32_t gmac_get_interrupt_mask(Gmac* p_gmac)
-{
- return p_gmac->GMAC_IMR;
-}
-
-/**
- * \brief Execute PHY maintenance command.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param uc_reg_addr Register address.
- * \param uc_rw 1 to Read, 0 to write.
- * \param us_data Data to be performed, write only.
- */
-static inline void gmac_maintain_phy(Gmac* p_gmac,
- uint8_t uc_phy_addr, uint8_t uc_reg_addr, uint8_t uc_rw,
- uint16_t us_data)
-{
- /* Wait until bus idle */
- while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
- /* Write maintain register */
- p_gmac->GMAC_MAN = GMAC_MAN_WTN(GMAC_MAN_CODE_VALUE)
- | GMAC_MAN_CLTTO
- | GMAC_MAN_PHYA(uc_phy_addr)
- | GMAC_MAN_REGA(uc_reg_addr)
- | GMAC_MAN_OP((uc_rw ? GMAC_MAN_RW_TYPE : GMAC_MAN_READ_ONLY))
- | GMAC_MAN_DATA(us_data);
-}
-
-/**
- * \brief Get PHY maintenance data returned.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Get PHY data.
- */
-static inline uint16_t gmac_get_phy_data(Gmac* p_gmac)
-{
- /* Wait until bus idle */
- while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
- /* Return data */
- return (uint16_t) (p_gmac->GMAC_MAN & GMAC_MAN_DATA_Msk);
-}
-
-/**
- * \brief Set Hash.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_hash_top Hash top.
- * \param ul_hash_bottom Hash bottom.
- */
-static inline void gmac_set_hash(Gmac* p_gmac, uint32_t ul_hash_top,
- uint32_t ul_hash_bottom)
-{
- p_gmac->GMAC_HRB = ul_hash_bottom;
- p_gmac->GMAC_HRT = ul_hash_top;
-}
-
-/**
- * \brief Set 64 bits Hash.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ull_hash 64 bits hash value.
- */
-static inline void gmac_set_hash64(Gmac* p_gmac, uint64_t ull_hash)
-{
- p_gmac->GMAC_HRB = (uint32_t) ull_hash;
- p_gmac->GMAC_HRT = (uint32_t) (ull_hash >> 32);
-}
-
-/**
- * \brief Set MAC Address.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_index GMAC specific address register index.
- * \param p_mac_addr GMAC address.
- */
-static inline void gmac_set_address(Gmac* p_gmac, uint8_t uc_index,
- uint8_t* p_mac_addr)
-{
- p_gmac->GMAC_SA[uc_index].GMAC_SAB = (p_mac_addr[3] << 24)
- | (p_mac_addr[2] << 16)
- | (p_mac_addr[1] << 8)
- | (p_mac_addr[0]);
- p_gmac->GMAC_SA[uc_index].GMAC_SAT = (p_mac_addr[5] << 8)
- | (p_mac_addr[4]);
-}
-
-/**
- * \brief Set MAC Address via 2 dword.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_index GMAC specific address register index.
- * \param ul_mac_top GMAC top address.
- * \param ul_mac_bottom GMAC bottom address.
- */
-static inline void gmac_set_address32(Gmac* p_gmac, uint8_t uc_index,
- uint32_t ul_mac_top, uint32_t ul_mac_bottom)
-{
- p_gmac->GMAC_SA[uc_index].GMAC_SAB = ul_mac_bottom;
- p_gmac->GMAC_SA[uc_index].GMAC_SAT = ul_mac_top;
-}
-
-/**
- * \brief Set MAC Address via int64.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_index GMAC specific address register index.
- * \param ull_mac 64-bit GMAC address.
- */
-static inline void gmac_set_address64(Gmac* p_gmac, uint8_t uc_index,
- uint64_t ull_mac)
-{
- p_gmac->GMAC_SA[uc_index].GMAC_SAB = (uint32_t) ull_mac;
- p_gmac->GMAC_SA[uc_index].GMAC_SAT = (uint32_t) (ull_mac >> 32);
-}
-
-/**
- * \brief Select media independent interface mode.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param mode Media independent interface mode.
- */
-static inline void gmac_select_mii_mode(Gmac* p_gmac, gmac_mii_mode_t mode)
-{
- switch (mode) {
- case GMAC_PHY_MII:
- case GMAC_PHY_RMII:
- p_gmac->GMAC_UR |= GMAC_UR_RMIIMII;
- break;
-
- default:
- p_gmac->GMAC_UR &= ~GMAC_UR_RMIIMII;
- break;
- }
-}
-
-uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
- uint32_t* p_value);
-uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
- uint8_t uc_address, uint32_t ul_value);
-void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
- gmac_options_t* p_opt);
-uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
- uint32_t ul_frame_size, uint32_t* p_rcv_size);
-uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
- uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb);
-uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev);
-void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
- gmac_dev_tx_cb_t func_rx_cb);
-uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
- gmac_dev_wakeup_cb_t func_wakeup, uint8_t uc_threshold);
-void gmac_dev_reset(gmac_device_t* p_gmac_dev);
-void gmac_handler(gmac_device_t* p_gmac_dev);
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-}
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-/**
- * \page gmac_quickstart Quickstart guide for GMAC driver.
- *
- * This is the quickstart guide for the \ref gmac_group "Ethernet MAC",
- * with step-by-step instructions on how to configure and use the driver in a
- * selection of use cases.
- *
- * The use cases contain several code fragments. The code fragments in the
- * steps for setup can be copied into a custom initialization function, while
- * the steps for usage can be copied into, e.g., the main application function.
- *
- * \section gmac_basic_use_case Basic use case
- * In the basic use case, the GMAC driver are configured for:
- * - PHY component KSZ8051MNL is used
- * - GMAC uses MII mode
- * - The number of receive buffer is 16
- * - The number of transfer buffer is 8
- * - MAC address is set to 00-04-25-1c-a0-02
- * - IP address is set to 192.168.0.2
- * - IP address is set to 192.168.0.2
- * - Gateway is set to 192.168.0.1
- * - Network mask is 255.255.255.0
- * - PHY operation max retry count is 1000000
- * - GMAC is configured to not support copy all frame and support broadcast
- * - The data will be read from the ethernet
- *
- * \section gmac_basic_use_case_setup Setup steps
- *
- * \subsection gmac_basic_use_case_setup_prereq Prerequisites
- * -# \ref sysclk_group "System Clock Management (sysclock)"
- * -# \ref pmc_group "Power Management Controller (pmc)"
- * -# \ref ksz8051mnl_ethernet_phy_group "PHY component (KSZ8051MNL)"
- *
- * \subsection gmac_basic_use_case_setup_code Example code
- * Content of conf_eth.h
- * \code
- * #define GMAC_RX_BUFFERS 16
- * #define GMAC_TX_BUFFERS 8
- * #define MAC_PHY_RETRY_MAX 1000000
- * #define ETHERNET_CONF_ETHADDR0 0x00
- * #define ETHERNET_CONF_ETHADDR0 0x00
- * #define ETHERNET_CONF_ETHADDR1 0x04
- * #define ETHERNET_CONF_ETHADDR2 0x25
- * #define ETHERNET_CONF_ETHADDR3 0x1C
- * #define ETHERNET_CONF_ETHADDR4 0xA0
- * #define ETHERNET_CONF_ETHADDR5 0x02
- * #define ETHERNET_CONF_IPADDR0 192
- * #define ETHERNET_CONF_IPADDR1 168
- * #define ETHERNET_CONF_IPADDR2 0
- * #define ETHERNET_CONF_IPADDR3 2
- * #define ETHERNET_CONF_GATEWAY_ADDR0 192
- * #define ETHERNET_CONF_GATEWAY_ADDR1 168
- * #define ETHERNET_CONF_GATEWAY_ADDR2 0
- * #define ETHERNET_CONF_GATEWAY_ADDR3 1
- * #define ETHERNET_CONF_NET_MASK0 255
- * #define ETHERNET_CONF_NET_MASK1 255
- * #define ETHERNET_CONF_NET_MASK2 255
- * #define ETHERNET_CONF_NET_MASK3 0
- * #define ETH_PHY_MODE ETH_PHY_MODE
- * \endcode
- *
- * A specific gmac device and the receive data buffer must be defined; another ul_frm_size should be defined
- * to trace the actual size of the data received.
- * \code
- * static gmac_device_t gs_gmac_dev;
- * static volatile uint8_t gs_uc_eth_buffer[GMAC_FRAME_LENTGH_MAX];
- *
- * uint32_t ul_frm_size;
- * \endcode
- *
- * Add to application C-file:
- * \code
- * void gmac_init(void)
- * {
- * sysclk_init();
- *
- * board_init();
- *
- * pmc_enable_periph_clk(ID_GMAC);
- *
- * gmac_option.uc_copy_all_frame = 0;
- * gmac_option.uc_no_boardcast = 0;
- * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
- * gs_gmac_dev.p_hw = GMAC;
- *
- * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
- *
- * NVIC_EnableIRQ(GMAC_IRQn);
- *
- * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
- *
- * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
- *
- * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
- * \endcode
- *
- * \subsection gmac_basic_use_case_setup_flow Workflow
- * - Ensure that conf_eth.h is present and contains the
- * following configuration symbol. This configuration file is used
- * by the driver and should not be included by the application.
- * -# Define the receiving buffer size used in the internal GMAC driver.
- * The buffer size used for RX is GMAC_RX_BUFFERS * 128.
- * If it was supposed receiving a large number of frame, the
- * GMAC_RX_BUFFERS should be set higher. E.g., the application wants to accept
- * a ping echo test of 2048, the GMAC_RX_BUFFERS should be set at least
- * (2048/128)=16, and as there are additional frames coming, a preferred
- * number is 24 depending on a normal Ethernet throughput.
- * - \code
- * #define GMAC_RX_BUFFERS 16
- * \endcode
- * -# Define the transmitting buffer size used in the internal GMAC driver.
- * The buffer size used for TX is GMAC_TX_BUFFERS * 1518.
- * - \code
- * #define GMAC_TX_BUFFERS 8
- * \endcode
- * -# Define maximum retry time for a PHY read/write operation.
- * - \code
- * #define MAC_PHY_RETRY_MAX 1000000
- * \endcode
- * -# Define the MAC address. 00:04:25:1C:A0:02 is the address reserved
- * for ATMEL, application should always change this address to its' own.
- * - \code
- * #define ETHERNET_CONF_ETHADDR0 0x00
- * #define ETHERNET_CONF_ETHADDR1 0x04
- * #define ETHERNET_CONF_ETHADDR2 0x25
- * #define ETHERNET_CONF_ETHADDR3 0x1C
- * #define ETHERNET_CONF_ETHADDR4 0xA0
- * #define ETHERNET_CONF_ETHADDR5 0x02
- * \endcode
- * -# Define the IP address configration used in the application. When DHCP
- * is enabled, this configuration is not effected.
- * - \code
- * #define ETHERNET_CONF_IPADDR0 192
- * #define ETHERNET_CONF_IPADDR1 168
- * #define ETHERNET_CONF_IPADDR2 0
- * #define ETHERNET_CONF_IPADDR3 2
- * #define ETHERNET_CONF_GATEWAY_ADDR0 192
- * #define ETHERNET_CONF_GATEWAY_ADDR1 168
- * #define ETHERNET_CONF_GATEWAY_ADDR2 0
- * #define ETHERNET_CONF_GATEWAY_ADDR3 1
- * #define ETHERNET_CONF_NET_MASK0 255
- * #define ETHERNET_CONF_NET_MASK1 255
- * #define ETHERNET_CONF_NET_MASK2 255
- * #define ETHERNET_CONF_NET_MASK3 0
- * \endcode
- * -# Configure the PHY maintainance interface.
- * - \code
- * #define ETH_PHY_MODE GMAC_PHY_MII
- * \endcode
- * -# Enable the system clock:
- * - \code sysclk_init(); \endcode
- * -# Enable PIO configurations for GMAC:
- * - \code board_init(); \endcode
- * -# Enable PMC clock for GMAC:
- * - \code pmc_enable_periph_clk(ID_GMAC); \endcode
- * -# Set the GMAC options; it's set to copy all frame and support broadcast:
- * - \code
- * gmac_option.uc_copy_all_frame = 0;
- * gmac_option.uc_no_boardcast = 0;
- * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
- * gs_gmac_dev.p_hw = GMAC;
- * \endcode
- * -# Initialize GMAC device with the filled option:
- * - \code
- * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
- * \endcode
- * -# Enable the interrupt service for GMAC:
- * - \code
- * NVIC_EnableIRQ(GMAC_IRQn);
- * \endcode
- * -# Initialize the PHY component:
- * - \code
- * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
- * \endcode
- * -# The link will be established based on auto negotiation.
- * - \code
- * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
- * \endcode
- * -# Establish the ethernet link; the network can be worked from now on:
- * - \code
- * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
- * \endcode
- *
- * \section gmac_basic_use_case_usage Usage steps
- * \subsection gmac_basic_use_case_usage_code Example code
- * Add to, e.g., main loop in application C-file:
- * \code
- * gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size));
- * \endcode
- *
- * \subsection gmac_basic_use_case_usage_flow Workflow
- * -# Start reading the data from the ethernet:
- * - \code gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size)); \endcode
- */
-
-# define GMAC_STATS 0
-
-#if( GMAC_STATS != 0 )
-
- /* Here below some code to study the types and
- frequencies of GMAC interrupts. */
- #define GMAC_IDX_RXUBR 0
- #define GMAC_IDX_TUR 1
- #define GMAC_IDX_RLEX 2
- #define GMAC_IDX_TFC 3
- #define GMAC_IDX_RCOMP 4
- #define GMAC_IDX_TCOMP 5
- #define GMAC_IDX_ROVR 6
- #define GMAC_IDX_HRESP 7
- #define GMAC_IDX_PFNZ 8
- #define GMAC_IDX_PTZ 9
-
- struct SGmacStats {
- unsigned recvCount;
- unsigned rovrCount;
- unsigned bnaCount;
- unsigned sendCount;
- unsigned sovrCount;
- unsigned incompCount;
- unsigned truncCount;
-
- unsigned intStatus[10];
- };
- extern struct SGmacStats gmacStats;
-
- struct SIntPair {
- const char *name;
- unsigned mask;
- int index;
- };
-
- #define MK_PAIR( NAME ) #NAME, GMAC_IER_##NAME, GMAC_IDX_##NAME
- static const struct SIntPair intPairs[] = {
- { MK_PAIR( RXUBR ) }, /* Enable receive used bit read interrupt. */
- { MK_PAIR( TUR ) }, /* Enable transmit underrun interrupt. */
- { MK_PAIR( RLEX ) }, /* Enable retry limit exceeded interrupt. */
- { MK_PAIR( TFC ) }, /* Enable transmit buffers exhausted in mid-frame interrupt. */
- { MK_PAIR( RCOMP ) }, /* Receive complete */
- { MK_PAIR( TCOMP ) }, /* Enable transmit complete interrupt. */
- { MK_PAIR( ROVR ) }, /* Enable receive overrun interrupt. */
- { MK_PAIR( HRESP ) }, /* Enable Hresp not OK interrupt. */
- { MK_PAIR( PFNZ ) }, /* Enable pause frame received interrupt. */
- { MK_PAIR( PTZ ) } /* Enable pause time zero interrupt. */
- };
-
- void gmac_show_irq_counts ();
-
-#endif
-
-#endif /* GMAC_H_INCLUDED */
+ /**
+ * \file
+ *
+ * \brief GMAC (Ethernet MAC) driver for SAM.
+ *
+ * Copyright (c) 2013 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#ifndef GMAC_H_INCLUDED
+#define GMAC_H_INCLUDED
+
+#include "compiler.h"
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/** The buffer addresses written into the descriptors must be aligned, so the
+ last few bits are zero. These bits have special meaning for the GMAC
+ peripheral and cannot be used as part of the address. */
+#define GMAC_RXD_ADDR_MASK 0xFFFFFFFC
+#define GMAC_RXD_WRAP (1ul << 1) /**< Wrap bit */
+#define GMAC_RXD_OWNERSHIP (1ul << 0) /**< Ownership bit */
+
+#define GMAC_RXD_BROADCAST (1ul << 31) /**< Broadcast detected */
+#define GMAC_RXD_MULTIHASH (1ul << 30) /**< Multicast hash match */
+#define GMAC_RXD_UNIHASH (1ul << 29) /**< Unicast hash match */
+#define GMAC_RXD_ADDR_FOUND (1ul << 27) /**< Specific address match found */
+#define GMAC_RXD_ADDR (3ul << 25) /**< Address match */
+#define GMAC_RXD_RXCOEN (1ul << 24) /**< RXCOEN related function */
+#define GMAC_RXD_TYPE (3ul << 22) /**< Type ID match */
+#define GMAC_RXD_VLAN (1ul << 21) /**< VLAN tag detected */
+#define GMAC_RXD_PRIORITY (1ul << 20) /**< Priority tag detected */
+#define GMAC_RXD_PRIORITY_MASK (3ul << 17) /**< VLAN priority */
+#define GMAC_RXD_CFI (1ul << 16) /**< Concatenation Format Indicator only if bit 21 is set */
+#define GMAC_RXD_EOF (1ul << 15) /**< End of frame */
+#define GMAC_RXD_SOF (1ul << 14) /**< Start of frame */
+#define GMAC_RXD_FCS (1ul << 13) /**< Frame check sequence */
+#define GMAC_RXD_OFFSET_MASK /**< Receive buffer offset */
+#define GMAC_RXD_LEN_MASK (0xFFF) /**< Length of frame including FCS (if selected) */
+#define GMAC_RXD_LENJUMBO_MASK (0x3FFF) /**< Jumbo frame length */
+
+#define GMAC_TXD_USED (1ul << 31) /**< Frame is transmitted */
+#define GMAC_TXD_WRAP (1ul << 30) /**< Last descriptor */
+#define GMAC_TXD_ERROR (1ul << 29) /**< Retry limit exceeded, error */
+#define GMAC_TXD_UNDERRUN (1ul << 28) /**< Transmit underrun */
+#define GMAC_TXD_EXHAUSTED (1ul << 27) /**< Buffer exhausted */
+#define GMAC_TXD_LATE (1ul << 26) /**< Late collision,transmit error */
+#define GMAC_TXD_CHECKSUM_ERROR (7ul << 20) /**< Checksum error */
+#define GMAC_TXD_NOCRC (1ul << 16) /**< No CRC */
+#define GMAC_TXD_LAST (1ul << 15) /**< Last buffer in frame */
+#define GMAC_TXD_LEN_MASK (0x1FFF) /**< Length of buffer */
+
+/** The MAC can support frame lengths up to 1536 bytes */
+#define GMAC_FRAME_LENTGH_MAX 1536
+
+#define GMAC_RX_UNITSIZE 128 /**< Fixed size for RX buffer */
+#define GMAC_TX_UNITSIZE 1518 /**< Size for ETH frame length */
+
+/** GMAC clock speed */
+#define GMAC_MCK_SPEED_240MHZ (240*1000*1000)
+#define GMAC_MCK_SPEED_160MHZ (160*1000*1000)
+#define GMAC_MCK_SPEED_120MHZ (120*1000*1000)
+#define GMAC_MCK_SPEED_80MHZ (80*1000*1000)
+#define GMAC_MCK_SPEED_40MHZ (40*1000*1000)
+#define GMAC_MCK_SPEED_20MHZ (20*1000*1000)
+
+/** GMAC maintain code default value*/
+#define GMAC_MAN_CODE_VALUE (10)
+
+/** GMAC maintain start of frame default value*/
+#define GMAC_MAN_SOF_VALUE (1)
+
+/** GMAC maintain read/write*/
+#define GMAC_MAN_RW_TYPE (2)
+
+/** GMAC maintain read only*/
+#define GMAC_MAN_READ_ONLY (1)
+
+/** GMAC address length */
+#define GMAC_ADDR_LENGTH (6)
+
+
+#define GMAC_DUPLEX_HALF 0
+#define GMAC_DUPLEX_FULL 1
+
+#define GMAC_SPEED_10M 0
+#define GMAC_SPEED_100M 1
+
+/**
+ * \brief Return codes for GMAC APIs.
+ */
+typedef enum {
+ GMAC_OK = 0, /** 0 Operation OK */
+ GMAC_TIMEOUT = 1, /** 1 GMAC operation timeout */
+ GMAC_TX_BUSY, /** 2 TX in progress */
+ GMAC_RX_NULL, /** 3 No data received */
+ GMAC_SIZE_TOO_SMALL, /** 4 Buffer size not enough */
+ GMAC_PARAM, /** 5 Parameter error, TX packet invalid or RX size too small */
+ GMAC_INVALID = 0xFF, /* Invalid */
+} gmac_status_t;
+
+/**
+ * \brief Media Independent Interface (MII) type.
+ */
+typedef enum {
+ GMAC_PHY_MII = 0, /** MII mode */
+ GMAC_PHY_RMII = 1, /** Reduced MII mode */
+ GMAC_PHY_INVALID = 0xFF, /* Invalid mode*/
+} gmac_mii_mode_t;
+
+/** Receive buffer descriptor struct */
+COMPILER_PACK_SET(8)
+typedef struct gmac_rx_descriptor {
+ union gmac_rx_addr {
+ uint32_t val;
+ struct gmac_rx_addr_bm {
+ uint32_t b_ownership:1, /**< User clear, GMAC sets this to 1 once it has successfully written a frame to memory */
+ b_wrap:1, /**< Marks last descriptor in receive buffer */
+ addr_dw:30; /**< Address in number of DW */
+ } bm;
+ } addr; /**< Address, Wrap & Ownership */
+ union gmac_rx_status {
+ uint32_t val;
+ struct gmac_rx_status_bm {
+ uint32_t len:13, /** 0..12 Length of frame including FCS */
+ b_fcs:1, /** 13 Receive buffer offset, bits 13:12 of frame length for jumbo frame */
+ b_sof:1, /** 14 Start of frame */
+ b_eof:1, /** 15 End of frame */
+ b_cfi:1, /** 16 Concatenation Format Indicator */
+ vlan_priority:3, /** 17..19 VLAN priority (if VLAN detected) */
+ b_priority_detected:1, /** 20 Priority tag detected */
+ b_vlan_detected:1, /** 21 VLAN tag detected */
+ b_type_id_match:2, /** 22..23 Type ID match */
+ b_checksumoffload:1, /** 24 Checksum offload specific function */
+ b_addrmatch:2, /** 25..26 Address register match */
+ b_ext_addr_match:1, /** 27 External address match found */
+ reserved:1, /** 28 */
+ b_uni_hash_match:1, /** 29 Unicast hash match */
+ b_multi_hash_match:1, /** 30 Multicast hash match */
+ b_boardcast_detect:1; /** 31 Global broadcast address detected */
+ } bm;
+ } status;
+} gmac_rx_descriptor_t;
+
+/** Transmit buffer descriptor struct */
+COMPILER_PACK_SET(8)
+typedef struct gmac_tx_descriptor {
+ uint32_t addr;
+ union gmac_tx_status {
+ uint32_t val;
+ struct gmac_tx_status_bm {
+ uint32_t len:14, /** 0..13 Length of buffer */
+ reserved:1, /** 14 */
+ b_last_buffer:1, /** 15 Last buffer (in the current frame) */
+ b_no_crc:1, /** 16 No CRC */
+ reserved1:3, /** 17..19 */
+ b_checksumoffload:3, /** 20..22 Transmit checksum generation offload errors */
+ reserved2:3, /** 23..25 */
+ b_lco:1, /** 26 Late collision, transmit error detected */
+ b_exhausted:1, /** 27 Buffer exhausted in mid frame */
+ b_underrun:1, /** 28 Transmit underrun */
+ b_error:1, /** 29 Retry limit exceeded, error detected */
+ b_wrap:1, /** 30 Marks last descriptor in TD list */
+ b_used:1; /** 31 User clear, GMAC sets this to 1 once a frame has been successfully transmitted */
+ } bm;
+ } status;
+} gmac_tx_descriptor_t;
+
+COMPILER_PACK_RESET()
+
+/**
+ * \brief Input parameters when initializing the gmac module mode.
+ */
+typedef struct gmac_options {
+ /* Enable/Disable CopyAllFrame */
+ uint8_t uc_copy_all_frame;
+ /* Enable/Disable NoBroadCast */
+ uint8_t uc_no_boardcast;
+ /* MAC address */
+ uint8_t uc_mac_addr[GMAC_ADDR_LENGTH];
+} gmac_options_t;
+
+/** RX callback */
+typedef void (*gmac_dev_tx_cb_t) (uint32_t ul_status);
+/** Wakeup callback */
+typedef void (*gmac_dev_wakeup_cb_t) (void);
+
+/**
+ * GMAC driver structure.
+ */
+typedef struct gmac_device {
+
+ /** Pointer to HW register base */
+ Gmac *p_hw;
+ /**
+ * Pointer to allocated TX buffer.
+ * Section 3.6 of AMBA 2.0 spec states that burst should not cross
+ * 1K Boundaries.
+ * Receive buffer manager writes are burst of 2 words => 3 lsb bits
+ * of the address shall be set to 0.
+ */
+ uint8_t *p_tx_buffer;
+ /** Pointer to allocated RX buffer */
+ uint8_t *p_rx_buffer;
+ /** Pointer to Rx TDs (must be 8-byte aligned) */
+ gmac_rx_descriptor_t *p_rx_dscr;
+ /** Pointer to Tx TDs (must be 8-byte aligned) */
+ gmac_tx_descriptor_t *p_tx_dscr;
+ /** Optional callback to be invoked once a frame has been received */
+ gmac_dev_tx_cb_t func_rx_cb;
+#if( GMAC_USES_WAKEUP_CALLBACK )
+ /** Optional callback to be invoked once several TDs have been released */
+ gmac_dev_wakeup_cb_t func_wakeup_cb;
+#endif
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ /** Optional callback list to be invoked once TD has been processed */
+ gmac_dev_tx_cb_t *func_tx_cb_list;
+#endif
+ /** RX TD list size */
+ uint32_t ul_rx_list_size;
+ /** RX index for current processing TD */
+ uint32_t ul_rx_idx;
+ /** TX TD list size */
+ uint32_t ul_tx_list_size;
+ /** Circular buffer head pointer by upper layer (buffer to be sent) */
+ int32_t l_tx_head;
+ /** Circular buffer tail pointer incremented by handlers (buffer sent) */
+ int32_t l_tx_tail;
+
+ /** Number of free TD before wakeup callback is invoked */
+ uint32_t uc_wakeup_threshold;
+} gmac_device_t;
+
+/**
+ * \brief Write network control value.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_ncr Network control value.
+ */
+static inline void gmac_network_control(Gmac* p_gmac, uint32_t ul_ncr)
+{
+ p_gmac->GMAC_NCR = ul_ncr;
+}
+
+/**
+ * \brief Get network control value.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+
+static inline uint32_t gmac_get_network_control(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_NCR;
+}
+
+/**
+ * \brief Enable/Disable GMAC receive.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable GMAC receiver, else to enable it.
+ */
+static inline void gmac_enable_receive(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_RXEN;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_RXEN;
+ }
+}
+
+/**
+ * \brief Enable/Disable GMAC transmit.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable GMAC transmit, else to enable it.
+ */
+static inline void gmac_enable_transmit(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXEN;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_TXEN;
+ }
+}
+
+/**
+ * \brief Enable/Disable GMAC management.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable GMAC management, else to enable it.
+ */
+static inline void gmac_enable_management(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_MPE;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_MPE;
+ }
+}
+
+/**
+ * \brief Clear all statistics registers.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_clear_statistics(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_CLRSTAT;
+}
+
+/**
+ * \brief Increase all statistics registers.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_increase_statistics(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_INCSTAT;
+}
+
+/**
+ * \brief Enable/Disable statistics registers writing.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the statistics registers writing, else to enable it.
+ */
+static inline void gmac_enable_statistics_write(Gmac* p_gmac,
+ uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_WESTAT;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_WESTAT;
+ }
+}
+
+/**
+ * \brief In half-duplex mode, forces collisions on all received frames.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the back pressure, else to enable it.
+ */
+static inline void gmac_enable_back_pressure(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_BP;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_BP;
+ }
+}
+
+/**
+ * \brief Start transmission.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_start_transmission(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TSTART;
+}
+
+/**
+ * \brief Halt transmission.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_halt_transmission(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_THALT;
+}
+
+/**
+ * \brief Transmit pause frame.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_tx_pause_frame(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXPF;
+}
+
+/**
+ * \brief Transmit zero quantum pause frame.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_tx_pause_zero_quantum_frame(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXZQPF;
+}
+
+/**
+ * \brief Read snapshot.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_read_snapshot(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_RDS;
+}
+
+/**
+ * \brief Store receivetime stamp to memory.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to normal operation, else to enable the store.
+ */
+static inline void gmac_store_rx_time_stamp(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_SRTSM;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_SRTSM;
+ }
+}
+
+/**
+ * \brief Enable PFC priority-based pause reception.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 1 to set the reception, 0 to disable.
+ */
+static inline void gmac_enable_pfc_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_ENPBPR;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_ENPBPR;
+ }
+}
+
+/**
+ * \brief Transmit PFC priority-based pause reception.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_transmit_pfc_pause_frame(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXPBPF;
+}
+
+/**
+ * \brief Flush next packet.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_flush_next_packet(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_FNP;
+}
+
+/**
+ * \brief Set up network configuration register.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_cfg Network configuration value.
+ */
+static inline void gmac_set_configure(Gmac* p_gmac, uint32_t ul_cfg)
+{
+ p_gmac->GMAC_NCFGR = ul_cfg;
+}
+
+/**
+ * \brief Get network configuration.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Network configuration.
+ */
+static inline uint32_t gmac_get_configure(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_NCFGR;
+}
+
+
+/* Get and set DMA Configuration Register */
+static inline void gmac_set_dma(Gmac* p_gmac, uint32_t ul_cfg)
+{
+ p_gmac->GMAC_DCFGR = ul_cfg;
+}
+
+static inline uint32_t gmac_get_dma(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_DCFGR;
+}
+
+/**
+ * \brief Set speed.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_speed 1 to indicate 100Mbps, 0 to 10Mbps.
+ */
+static inline void gmac_set_speed(Gmac* p_gmac, uint8_t uc_speed)
+{
+ if (uc_speed) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_SPD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_SPD;
+ }
+}
+
+/**
+ * \brief Enable/Disable Full-Duplex mode.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the Full-Duplex mode, else to enable it.
+ */
+static inline void gmac_enable_full_duplex(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_FD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_FD;
+ }
+}
+
+/**
+ * \brief Enable/Disable Copy(Receive) All Valid Frames.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable copying all valid frames, else to enable it.
+ */
+static inline void gmac_enable_copy_all(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_CAF;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_CAF;
+ }
+}
+
+/**
+ * \brief Enable/Disable jumbo frames (up to 10240 bytes).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the jumbo frames, else to enable it.
+ */
+static inline void gmac_enable_jumbo_frames(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_JFRAME;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_JFRAME;
+ }
+}
+
+/**
+ * \brief Disable/Enable broadcast receiving.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 1 to disable the broadcast, else to enable it.
+ */
+static inline void gmac_disable_broadcast(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_NBC;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_NBC;
+ }
+}
+
+/**
+ * \brief Enable/Disable multicast hash.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the multicast hash, else to enable it.
+ */
+static inline void gmac_enable_multicast_hash(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_UNIHEN;
+ }
+}
+
+/**
+ * \brief Enable/Disable big frames (over 1518, up to 1536).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable big frames else to enable it.
+ */
+static inline void gmac_enable_big_frame(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_MAXFS;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_MAXFS;
+ }
+}
+
+/**
+ * \brief Set MDC clock divider.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_mck GMAC MCK.
+ *
+ * \return GMAC_OK if successfully.
+ */
+static inline uint8_t gmac_set_mdc_clock(Gmac* p_gmac, uint32_t ul_mck)
+{
+ uint32_t ul_clk;
+
+ if (ul_mck > GMAC_MCK_SPEED_240MHZ) {
+ return GMAC_INVALID;
+ } else if (ul_mck > GMAC_MCK_SPEED_160MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_96;
+ } else if (ul_mck > GMAC_MCK_SPEED_120MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_64;
+ } else if (ul_mck > GMAC_MCK_SPEED_80MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_48;
+ } else if (ul_mck > GMAC_MCK_SPEED_40MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_32;
+ } else if (ul_mck > GMAC_MCK_SPEED_20MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_16;
+ } else {
+ ul_clk = GMAC_NCFGR_CLK_MCK_8;
+ }
+ ;
+ p_gmac->GMAC_NCFGR = (p_gmac->GMAC_NCFGR & ~GMAC_NCFGR_CLK_Msk) | ul_clk;
+ return GMAC_OK;
+}
+
+/**
+ * \brief Enable/Disable retry test.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the GMAC receiver, else to enable it.
+ */
+static inline void gmac_enable_retry_test(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RTY;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RTY;
+ }
+}
+
+/**
+ * \brief Enable/Disable pause (when a valid pause frame is received).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable pause frame, else to enable it.
+ */
+static inline void gmac_enable_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_PEN;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_PEN;
+ }
+}
+
+/**
+ * \brief Set receive buffer offset to 0 ~ 3.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_set_rx_buffer_offset(Gmac* p_gmac, uint8_t uc_offset)
+{
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RXBUFO_Msk;
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RXBUFO(uc_offset);
+}
+
+/**
+ * \brief Enable/Disable receive length field checking.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable receive length field checking, else to enable it.
+ */
+static inline void gmac_enable_rx_length_check(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_LFERD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_LFERD;
+ }
+}
+
+/**
+ * \brief Enable/Disable discarding FCS field of received frames.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable discarding FCS field of received frames, else to enable it.
+ */
+static inline void gmac_enable_discard_fcs(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RFCS;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RFCS;
+ }
+}
+
+
+/**
+ * \brief Enable/Disable frames to be received in half-duplex mode
+ * while transmitting.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the received in half-duplex mode, else to enable it.
+ */
+static inline void gmac_enable_efrhd(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_EFRHD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_EFRHD;
+ }
+}
+
+/**
+ * \brief Enable/Disable ignore RX FCS.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable ignore RX FCS, else to enable it.
+ */
+static inline void gmac_enable_ignore_rx_fcs(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_IRXFCS;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_IRXFCS;
+ }
+}
+
+/**
+ * \brief Get Network Status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Network status.
+ */
+static inline uint32_t gmac_get_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_NSR;
+}
+
+/**
+ * \brief Get MDIO IN pin status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return MDIO IN pin status.
+ */
+static inline uint8_t gmac_get_MDIO(Gmac* p_gmac)
+{
+ return ((p_gmac->GMAC_NSR & GMAC_NSR_MDIO) > 0);
+}
+
+/**
+ * \brief Check if PHY is idle.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return 1 if PHY is idle.
+ */
+static inline uint8_t gmac_is_phy_idle(Gmac* p_gmac)
+{
+ return ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) > 0);
+}
+
+/**
+ * \brief Return transmit status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Transmit status.
+ */
+static inline uint32_t gmac_get_tx_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_TSR;
+}
+
+/**
+ * \brief Clear transmit status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_status Transmit status.
+ */
+static inline void gmac_clear_tx_status(Gmac* p_gmac, uint32_t ul_status)
+{
+ p_gmac->GMAC_TSR = ul_status;
+}
+
+/**
+ * \brief Return receive status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline uint32_t gmac_get_rx_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_RSR;
+}
+
+/**
+ * \brief Clear receive status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_status Receive status.
+ */
+static inline void gmac_clear_rx_status(Gmac* p_gmac, uint32_t ul_status)
+{
+ p_gmac->GMAC_RSR = ul_status;
+}
+
+/**
+ * \brief Set Rx Queue.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_addr Rx queue address.
+ */
+static inline void gmac_set_rx_queue(Gmac* p_gmac, uint32_t ul_addr)
+{
+ p_gmac->GMAC_RBQB = GMAC_RBQB_ADDR_Msk & ul_addr;
+}
+
+/**
+ * \brief Get Rx Queue Address.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Rx queue address.
+ */
+static inline uint32_t gmac_get_rx_queue(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_RBQB;
+}
+
+/**
+ * \brief Set Tx Queue.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_addr Tx queue address.
+ */
+static inline void gmac_set_tx_queue(Gmac* p_gmac, uint32_t ul_addr)
+{
+ p_gmac->GMAC_TBQB = GMAC_TBQB_ADDR_Msk & ul_addr;
+}
+
+/**
+ * \brief Get Tx Queue.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Rx queue address.
+ */
+static inline uint32_t gmac_get_tx_queue(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_TBQB;
+}
+
+/**
+ * \brief Enable interrupt(s).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_source Interrupt source(s) to be enabled.
+ */
+static inline void gmac_enable_interrupt(Gmac* p_gmac, uint32_t ul_source)
+{
+ p_gmac->GMAC_IER = ul_source;
+}
+
+/**
+ * \brief Disable interrupt(s).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_source Interrupt source(s) to be disabled.
+ */
+static inline void gmac_disable_interrupt(Gmac* p_gmac, uint32_t ul_source)
+{
+ p_gmac->GMAC_IDR = ul_source;
+}
+
+/**
+ * \brief Return interrupt status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Interrupt status.
+ */
+static inline uint32_t gmac_get_interrupt_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_ISR;
+}
+
+/**
+ * \brief Return interrupt mask.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Interrupt mask.
+ */
+static inline uint32_t gmac_get_interrupt_mask(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_IMR;
+}
+
+/**
+ * \brief Execute PHY maintenance command.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param uc_reg_addr Register address.
+ * \param uc_rw 1 to Read, 0 to write.
+ * \param us_data Data to be performed, write only.
+ */
+static inline void gmac_maintain_phy(Gmac* p_gmac,
+ uint8_t uc_phy_addr, uint8_t uc_reg_addr, uint8_t uc_rw,
+ uint16_t us_data)
+{
+ /* Wait until bus idle */
+ while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
+ /* Write maintain register */
+ p_gmac->GMAC_MAN = GMAC_MAN_WTN(GMAC_MAN_CODE_VALUE)
+ | GMAC_MAN_CLTTO
+ | GMAC_MAN_PHYA(uc_phy_addr)
+ | GMAC_MAN_REGA(uc_reg_addr)
+ | GMAC_MAN_OP((uc_rw ? GMAC_MAN_RW_TYPE : GMAC_MAN_READ_ONLY))
+ | GMAC_MAN_DATA(us_data);
+}
+
+/**
+ * \brief Get PHY maintenance data returned.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Get PHY data.
+ */
+static inline uint16_t gmac_get_phy_data(Gmac* p_gmac)
+{
+ /* Wait until bus idle */
+ while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
+ /* Return data */
+ return (uint16_t) (p_gmac->GMAC_MAN & GMAC_MAN_DATA_Msk);
+}
+
+/**
+ * \brief Set Hash.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_hash_top Hash top.
+ * \param ul_hash_bottom Hash bottom.
+ */
+static inline void gmac_set_hash(Gmac* p_gmac, uint32_t ul_hash_top,
+ uint32_t ul_hash_bottom)
+{
+ p_gmac->GMAC_HRB = ul_hash_bottom;
+ p_gmac->GMAC_HRT = ul_hash_top;
+}
+
+/**
+ * \brief Set 64 bits Hash.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ull_hash 64 bits hash value.
+ */
+static inline void gmac_set_hash64(Gmac* p_gmac, uint64_t ull_hash)
+{
+ p_gmac->GMAC_HRB = (uint32_t) ull_hash;
+ p_gmac->GMAC_HRT = (uint32_t) (ull_hash >> 32);
+}
+
+/**
+ * \brief Set MAC Address.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_index GMAC specific address register index.
+ * \param p_mac_addr GMAC address.
+ */
+static inline void gmac_set_address(Gmac* p_gmac, uint8_t uc_index,
+ uint8_t* p_mac_addr)
+{
+ p_gmac->GMAC_SA[uc_index].GMAC_SAB = (p_mac_addr[3] << 24)
+ | (p_mac_addr[2] << 16)
+ | (p_mac_addr[1] << 8)
+ | (p_mac_addr[0]);
+ p_gmac->GMAC_SA[uc_index].GMAC_SAT = (p_mac_addr[5] << 8)
+ | (p_mac_addr[4]);
+}
+
+/**
+ * \brief Set MAC Address via 2 dword.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_index GMAC specific address register index.
+ * \param ul_mac_top GMAC top address.
+ * \param ul_mac_bottom GMAC bottom address.
+ */
+static inline void gmac_set_address32(Gmac* p_gmac, uint8_t uc_index,
+ uint32_t ul_mac_top, uint32_t ul_mac_bottom)
+{
+ p_gmac->GMAC_SA[uc_index].GMAC_SAB = ul_mac_bottom;
+ p_gmac->GMAC_SA[uc_index].GMAC_SAT = ul_mac_top;
+}
+
+/**
+ * \brief Set MAC Address via int64.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_index GMAC specific address register index.
+ * \param ull_mac 64-bit GMAC address.
+ */
+static inline void gmac_set_address64(Gmac* p_gmac, uint8_t uc_index,
+ uint64_t ull_mac)
+{
+ p_gmac->GMAC_SA[uc_index].GMAC_SAB = (uint32_t) ull_mac;
+ p_gmac->GMAC_SA[uc_index].GMAC_SAT = (uint32_t) (ull_mac >> 32);
+}
+
+/**
+ * \brief Select media independent interface mode.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param mode Media independent interface mode.
+ */
+static inline void gmac_select_mii_mode(Gmac* p_gmac, gmac_mii_mode_t mode)
+{
+ switch (mode) {
+ case GMAC_PHY_MII:
+ case GMAC_PHY_RMII:
+ p_gmac->GMAC_UR |= GMAC_UR_RMIIMII;
+ break;
+
+ default:
+ p_gmac->GMAC_UR &= ~GMAC_UR_RMIIMII;
+ break;
+ }
+}
+
+uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
+ uint32_t* p_value);
+uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
+ uint8_t uc_address, uint32_t ul_value);
+void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
+ gmac_options_t* p_opt);
+uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
+ uint32_t ul_frame_size, uint32_t* p_rcv_size);
+uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
+ uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb);
+uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev);
+void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
+ gmac_dev_tx_cb_t func_rx_cb);
+uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
+ gmac_dev_wakeup_cb_t func_wakeup, uint8_t uc_threshold);
+void gmac_dev_reset(gmac_device_t* p_gmac_dev);
+void gmac_handler(gmac_device_t* p_gmac_dev);
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+}
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/**
+ * \page gmac_quickstart Quickstart guide for GMAC driver.
+ *
+ * This is the quickstart guide for the \ref gmac_group "Ethernet MAC",
+ * with step-by-step instructions on how to configure and use the driver in a
+ * selection of use cases.
+ *
+ * The use cases contain several code fragments. The code fragments in the
+ * steps for setup can be copied into a custom initialization function, while
+ * the steps for usage can be copied into, e.g., the main application function.
+ *
+ * \section gmac_basic_use_case Basic use case
+ * In the basic use case, the GMAC driver are configured for:
+ * - PHY component KSZ8051MNL is used
+ * - GMAC uses MII mode
+ * - The number of receive buffer is 16
+ * - The number of transfer buffer is 8
+ * - MAC address is set to 00-04-25-1c-a0-02
+ * - IP address is set to 192.168.0.2
+ * - IP address is set to 192.168.0.2
+ * - Gateway is set to 192.168.0.1
+ * - Network mask is 255.255.255.0
+ * - PHY operation max retry count is 1000000
+ * - GMAC is configured to not support copy all frame and support broadcast
+ * - The data will be read from the ethernet
+ *
+ * \section gmac_basic_use_case_setup Setup steps
+ *
+ * \subsection gmac_basic_use_case_setup_prereq Prerequisites
+ * -# \ref sysclk_group "System Clock Management (sysclock)"
+ * -# \ref pmc_group "Power Management Controller (pmc)"
+ * -# \ref ksz8051mnl_ethernet_phy_group "PHY component (KSZ8051MNL)"
+ *
+ * \subsection gmac_basic_use_case_setup_code Example code
+ * Content of conf_eth.h
+ * \code
+ * #define GMAC_RX_BUFFERS 16
+ * #define GMAC_TX_BUFFERS 8
+ * #define MAC_PHY_RETRY_MAX 1000000
+ * #define ETHERNET_CONF_ETHADDR0 0x00
+ * #define ETHERNET_CONF_ETHADDR0 0x00
+ * #define ETHERNET_CONF_ETHADDR1 0x04
+ * #define ETHERNET_CONF_ETHADDR2 0x25
+ * #define ETHERNET_CONF_ETHADDR3 0x1C
+ * #define ETHERNET_CONF_ETHADDR4 0xA0
+ * #define ETHERNET_CONF_ETHADDR5 0x02
+ * #define ETHERNET_CONF_IPADDR0 192
+ * #define ETHERNET_CONF_IPADDR1 168
+ * #define ETHERNET_CONF_IPADDR2 0
+ * #define ETHERNET_CONF_IPADDR3 2
+ * #define ETHERNET_CONF_GATEWAY_ADDR0 192
+ * #define ETHERNET_CONF_GATEWAY_ADDR1 168
+ * #define ETHERNET_CONF_GATEWAY_ADDR2 0
+ * #define ETHERNET_CONF_GATEWAY_ADDR3 1
+ * #define ETHERNET_CONF_NET_MASK0 255
+ * #define ETHERNET_CONF_NET_MASK1 255
+ * #define ETHERNET_CONF_NET_MASK2 255
+ * #define ETHERNET_CONF_NET_MASK3 0
+ * #define ETH_PHY_MODE ETH_PHY_MODE
+ * \endcode
+ *
+ * A specific gmac device and the receive data buffer must be defined; another ul_frm_size should be defined
+ * to trace the actual size of the data received.
+ * \code
+ * static gmac_device_t gs_gmac_dev;
+ * static volatile uint8_t gs_uc_eth_buffer[GMAC_FRAME_LENTGH_MAX];
+ *
+ * uint32_t ul_frm_size;
+ * \endcode
+ *
+ * Add to application C-file:
+ * \code
+ * void gmac_init(void)
+ * {
+ * sysclk_init();
+ *
+ * board_init();
+ *
+ * pmc_enable_periph_clk(ID_GMAC);
+ *
+ * gmac_option.uc_copy_all_frame = 0;
+ * gmac_option.uc_no_boardcast = 0;
+ * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
+ * gs_gmac_dev.p_hw = GMAC;
+ *
+ * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
+ *
+ * NVIC_EnableIRQ(GMAC_IRQn);
+ *
+ * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
+ *
+ * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
+ *
+ * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
+ * \endcode
+ *
+ * \subsection gmac_basic_use_case_setup_flow Workflow
+ * - Ensure that conf_eth.h is present and contains the
+ * following configuration symbol. This configuration file is used
+ * by the driver and should not be included by the application.
+ * -# Define the receiving buffer size used in the internal GMAC driver.
+ * The buffer size used for RX is GMAC_RX_BUFFERS * 128.
+ * If it was supposed receiving a large number of frame, the
+ * GMAC_RX_BUFFERS should be set higher. E.g., the application wants to accept
+ * a ping echo test of 2048, the GMAC_RX_BUFFERS should be set at least
+ * (2048/128)=16, and as there are additional frames coming, a preferred
+ * number is 24 depending on a normal Ethernet throughput.
+ * - \code
+ * #define GMAC_RX_BUFFERS 16
+ * \endcode
+ * -# Define the transmitting buffer size used in the internal GMAC driver.
+ * The buffer size used for TX is GMAC_TX_BUFFERS * 1518.
+ * - \code
+ * #define GMAC_TX_BUFFERS 8
+ * \endcode
+ * -# Define maximum retry time for a PHY read/write operation.
+ * - \code
+ * #define MAC_PHY_RETRY_MAX 1000000
+ * \endcode
+ * -# Define the MAC address. 00:04:25:1C:A0:02 is the address reserved
+ * for ATMEL, application should always change this address to its' own.
+ * - \code
+ * #define ETHERNET_CONF_ETHADDR0 0x00
+ * #define ETHERNET_CONF_ETHADDR1 0x04
+ * #define ETHERNET_CONF_ETHADDR2 0x25
+ * #define ETHERNET_CONF_ETHADDR3 0x1C
+ * #define ETHERNET_CONF_ETHADDR4 0xA0
+ * #define ETHERNET_CONF_ETHADDR5 0x02
+ * \endcode
+ * -# Define the IP address configration used in the application. When DHCP
+ * is enabled, this configuration is not effected.
+ * - \code
+ * #define ETHERNET_CONF_IPADDR0 192
+ * #define ETHERNET_CONF_IPADDR1 168
+ * #define ETHERNET_CONF_IPADDR2 0
+ * #define ETHERNET_CONF_IPADDR3 2
+ * #define ETHERNET_CONF_GATEWAY_ADDR0 192
+ * #define ETHERNET_CONF_GATEWAY_ADDR1 168
+ * #define ETHERNET_CONF_GATEWAY_ADDR2 0
+ * #define ETHERNET_CONF_GATEWAY_ADDR3 1
+ * #define ETHERNET_CONF_NET_MASK0 255
+ * #define ETHERNET_CONF_NET_MASK1 255
+ * #define ETHERNET_CONF_NET_MASK2 255
+ * #define ETHERNET_CONF_NET_MASK3 0
+ * \endcode
+ * -# Configure the PHY maintainance interface.
+ * - \code
+ * #define ETH_PHY_MODE GMAC_PHY_MII
+ * \endcode
+ * -# Enable the system clock:
+ * - \code sysclk_init(); \endcode
+ * -# Enable PIO configurations for GMAC:
+ * - \code board_init(); \endcode
+ * -# Enable PMC clock for GMAC:
+ * - \code pmc_enable_periph_clk(ID_GMAC); \endcode
+ * -# Set the GMAC options; it's set to copy all frame and support broadcast:
+ * - \code
+ * gmac_option.uc_copy_all_frame = 0;
+ * gmac_option.uc_no_boardcast = 0;
+ * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
+ * gs_gmac_dev.p_hw = GMAC;
+ * \endcode
+ * -# Initialize GMAC device with the filled option:
+ * - \code
+ * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
+ * \endcode
+ * -# Enable the interrupt service for GMAC:
+ * - \code
+ * NVIC_EnableIRQ(GMAC_IRQn);
+ * \endcode
+ * -# Initialize the PHY component:
+ * - \code
+ * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
+ * \endcode
+ * -# The link will be established based on auto negotiation.
+ * - \code
+ * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
+ * \endcode
+ * -# Establish the ethernet link; the network can be worked from now on:
+ * - \code
+ * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
+ * \endcode
+ *
+ * \section gmac_basic_use_case_usage Usage steps
+ * \subsection gmac_basic_use_case_usage_code Example code
+ * Add to, e.g., main loop in application C-file:
+ * \code
+ * gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size));
+ * \endcode
+ *
+ * \subsection gmac_basic_use_case_usage_flow Workflow
+ * -# Start reading the data from the ethernet:
+ * - \code gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size)); \endcode
+ */
+
+# define GMAC_STATS 0
+
+#if( GMAC_STATS != 0 )
+
+ /* Here below some code to study the types and
+ frequencies of GMAC interrupts. */
+ #define GMAC_IDX_RXUBR 0
+ #define GMAC_IDX_TUR 1
+ #define GMAC_IDX_RLEX 2
+ #define GMAC_IDX_TFC 3
+ #define GMAC_IDX_RCOMP 4
+ #define GMAC_IDX_TCOMP 5
+ #define GMAC_IDX_ROVR 6
+ #define GMAC_IDX_HRESP 7
+ #define GMAC_IDX_PFNZ 8
+ #define GMAC_IDX_PTZ 9
+
+ struct SGmacStats {
+ unsigned recvCount;
+ unsigned rovrCount;
+ unsigned bnaCount;
+ unsigned sendCount;
+ unsigned sovrCount;
+ unsigned incompCount;
+ unsigned truncCount;
+
+ unsigned intStatus[10];
+ };
+ extern struct SGmacStats gmacStats;
+
+ struct SIntPair {
+ const char *name;
+ unsigned mask;
+ int index;
+ };
+
+ #define MK_PAIR( NAME ) #NAME, GMAC_IER_##NAME, GMAC_IDX_##NAME
+ static const struct SIntPair intPairs[] = {
+ { MK_PAIR( RXUBR ) }, /* Enable receive used bit read interrupt. */
+ { MK_PAIR( TUR ) }, /* Enable transmit underrun interrupt. */
+ { MK_PAIR( RLEX ) }, /* Enable retry limit exceeded interrupt. */
+ { MK_PAIR( TFC ) }, /* Enable transmit buffers exhausted in mid-frame interrupt. */
+ { MK_PAIR( RCOMP ) }, /* Receive complete */
+ { MK_PAIR( TCOMP ) }, /* Enable transmit complete interrupt. */
+ { MK_PAIR( ROVR ) }, /* Enable receive overrun interrupt. */
+ { MK_PAIR( HRESP ) }, /* Enable Hresp not OK interrupt. */
+ { MK_PAIR( PFNZ ) }, /* Enable pause frame received interrupt. */
+ { MK_PAIR( PTZ ) } /* Enable pause time zero interrupt. */
+ };
+
+ void gmac_show_irq_counts ();
+
+#endif
+
+#endif /* GMAC_H_INCLUDED */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/instance/gmac.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/instance/gmac.h
index dd29dfe78..24d806d94 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/instance/gmac.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/instance/gmac.h
@@ -1,1349 +1,1349 @@
- /**
- * \file
- *
- * \brief GMAC (Ethernet MAC) driver for SAM.
- *
- * Copyright (c) 2013 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#ifndef GMAC_H_INCLUDED
-#define GMAC_H_INCLUDED
-
-#include "compiler.h"
-#include "component/gmac.h"
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-extern "C" {
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-/** The buffer addresses written into the descriptors must be aligned, so the
- last few bits are zero. These bits have special meaning for the GMAC
- peripheral and cannot be used as part of the address. */
-#define GMAC_RXD_ADDR_MASK 0xFFFFFFFC
-#define GMAC_RXD_WRAP (1ul << 1) /**< Wrap bit */
-#define GMAC_RXD_OWNERSHIP (1ul << 0) /**< Ownership bit */
-
-#define GMAC_RXD_BROADCAST (1ul << 31) /**< Broadcast detected */
-#define GMAC_RXD_MULTIHASH (1ul << 30) /**< Multicast hash match */
-#define GMAC_RXD_UNIHASH (1ul << 29) /**< Unicast hash match */
-#define GMAC_RXD_ADDR_FOUND (1ul << 27) /**< Specific address match found */
-#define GMAC_RXD_ADDR (3ul << 25) /**< Address match */
-#define GMAC_RXD_RXCOEN (1ul << 24) /**< RXCOEN related function */
-#define GMAC_RXD_TYPE (3ul << 22) /**< Type ID match */
-#define GMAC_RXD_VLAN (1ul << 21) /**< VLAN tag detected */
-#define GMAC_RXD_PRIORITY (1ul << 20) /**< Priority tag detected */
-#define GMAC_RXD_PRIORITY_MASK (3ul << 17) /**< VLAN priority */
-#define GMAC_RXD_CFI (1ul << 16) /**< Concatenation Format Indicator only if bit 21 is set */
-#define GMAC_RXD_EOF (1ul << 15) /**< End of frame */
-#define GMAC_RXD_SOF (1ul << 14) /**< Start of frame */
-#define GMAC_RXD_FCS (1ul << 13) /**< Frame check sequence */
-#define GMAC_RXD_OFFSET_MASK /**< Receive buffer offset */
-#define GMAC_RXD_LEN_MASK (0xFFF) /**< Length of frame including FCS (if selected) */
-#define GMAC_RXD_LENJUMBO_MASK (0x3FFF) /**< Jumbo frame length */
-
-#define GMAC_TXD_USED (1ul << 31) /**< Frame is transmitted */
-#define GMAC_TXD_WRAP (1ul << 30) /**< Last descriptor */
-#define GMAC_TXD_ERROR (1ul << 29) /**< Retry limit exceeded, error */
-#define GMAC_TXD_UNDERRUN (1ul << 28) /**< Transmit underrun */
-#define GMAC_TXD_EXHAUSTED (1ul << 27) /**< Buffer exhausted */
-#define GMAC_TXD_LATE (1ul << 26) /**< Late collision,transmit error */
-#define GMAC_TXD_CHECKSUM_ERROR (7ul << 20) /**< Checksum error */
-#define GMAC_TXD_NOCRC (1ul << 16) /**< No CRC */
-#define GMAC_TXD_LAST (1ul << 15) /**< Last buffer in frame */
-#define GMAC_TXD_LEN_MASK (0x1FFF) /**< Length of buffer */
-
-/** The MAC can support frame lengths up to 1536 bytes */
-#define GMAC_FRAME_LENTGH_MAX 1536
-
-#define GMAC_RX_UNITSIZE 128 /**< Fixed size for RX buffer */
-#define GMAC_TX_UNITSIZE 1518 /**< Size for ETH frame length */
-
-/** GMAC clock speed */
-#define GMAC_MCK_SPEED_240MHZ (240*1000*1000)
-#define GMAC_MCK_SPEED_160MHZ (160*1000*1000)
-#define GMAC_MCK_SPEED_120MHZ (120*1000*1000)
-#define GMAC_MCK_SPEED_80MHZ (80*1000*1000)
-#define GMAC_MCK_SPEED_40MHZ (40*1000*1000)
-#define GMAC_MCK_SPEED_20MHZ (20*1000*1000)
-
-/** GMAC maintain code default value*/
-#define GMAC_MAN_CODE_VALUE (10)
-
-/** GMAC maintain start of frame default value*/
-#define GMAC_MAN_SOF_VALUE (1)
-
-/** GMAC maintain read/write*/
-#define GMAC_MAN_RW_TYPE (2)
-
-/** GMAC maintain read only*/
-#define GMAC_MAN_READ_ONLY (1)
-
-/** GMAC address length */
-#define GMAC_ADDR_LENGTH (6)
-
-
-#define GMAC_DUPLEX_HALF 0
-#define GMAC_DUPLEX_FULL 1
-
-#define GMAC_SPEED_10M 0
-#define GMAC_SPEED_100M 1
-
-/**
- * \brief Return codes for GMAC APIs.
- */
-typedef enum {
- GMAC_OK = 0, /** 0 Operation OK */
- GMAC_TIMEOUT = 1, /** 1 GMAC operation timeout */
- GMAC_TX_BUSY, /** 2 TX in progress */
- GMAC_RX_NULL, /** 3 No data received */
- GMAC_SIZE_TOO_SMALL, /** 4 Buffer size not enough */
- GMAC_PARAM, /** 5 Parameter error, TX packet invalid or RX size too small */
- GMAC_INVALID = 0xFF, /* Invalid */
-} gmac_status_t;
-
-/**
- * \brief Media Independent Interface (MII) type.
- */
-typedef enum {
- GMAC_PHY_MII = 0, /** MII mode */
- GMAC_PHY_RMII = 1, /** Reduced MII mode */
- GMAC_PHY_INVALID = 0xFF, /* Invalid mode*/
-} gmac_mii_mode_t;
-
-/** Receive buffer descriptor struct */
-COMPILER_PACK_SET(8)
-typedef struct gmac_rx_descriptor {
- union gmac_rx_addr {
- uint32_t val;
- struct gmac_rx_addr_bm {
- uint32_t b_ownership:1, /**< User clear, GMAC sets this to 1 once it has successfully written a frame to memory */
- b_wrap:1, /**< Marks last descriptor in receive buffer */
- addr_dw:30; /**< Address in number of DW */
- } bm;
- } addr; /**< Address, Wrap & Ownership */
- union gmac_rx_status {
- uint32_t val;
- struct gmac_rx_status_bm {
- uint32_t len:13, /** 0..12 Length of frame including FCS */
- b_fcs:1, /** 13 Receive buffer offset, bits 13:12 of frame length for jumbo frame */
- b_sof:1, /** 14 Start of frame */
- b_eof:1, /** 15 End of frame */
- b_cfi:1, /** 16 Concatenation Format Indicator */
- vlan_priority:3, /** 17..19 VLAN priority (if VLAN detected) */
- b_priority_detected:1, /** 20 Priority tag detected */
- b_vlan_detected:1, /** 21 VLAN tag detected */
- b_type_id_match:2, /** 22..23 Type ID match */
- b_checksumoffload:1, /** 24 Checksum offload specific function */
- b_addrmatch:2, /** 25..26 Address register match */
- b_ext_addr_match:1, /** 27 External address match found */
- reserved:1, /** 28 */
- b_uni_hash_match:1, /** 29 Unicast hash match */
- b_multi_hash_match:1, /** 30 Multicast hash match */
- b_boardcast_detect:1; /** 31 Global broadcast address detected */
- } bm;
- } status;
-} gmac_rx_descriptor_t;
-
-/** Transmit buffer descriptor struct */
-COMPILER_PACK_SET(8)
-typedef struct gmac_tx_descriptor {
- uint32_t addr;
- union gmac_tx_status {
- uint32_t val;
- struct gmac_tx_status_bm {
- uint32_t len:14, /** 0..13 Length of buffer */
- reserved:1, /** 14 */
- b_last_buffer:1, /** 15 Last buffer (in the current frame) */
- b_no_crc:1, /** 16 No CRC */
- reserved1:3, /** 17..19 */
- b_checksumoffload:3, /** 20..22 Transmit checksum generation offload errors */
- reserved2:3, /** 23..25 */
- b_lco:1, /** 26 Late collision, transmit error detected */
- b_exhausted:1, /** 27 Buffer exhausted in mid frame */
- b_underrun:1, /** 28 Transmit underrun */
- b_error:1, /** 29 Retry limit exceeded, error detected */
- b_wrap:1, /** 30 Marks last descriptor in TD list */
- b_used:1; /** 31 User clear, GMAC sets this to 1 once a frame has been successfully transmitted */
- } bm;
- } status;
-} gmac_tx_descriptor_t;
-
-COMPILER_PACK_RESET()
-
-/**
- * \brief Input parameters when initializing the gmac module mode.
- */
-typedef struct gmac_options {
- /* Enable/Disable CopyAllFrame */
- uint8_t uc_copy_all_frame;
- /* Enable/Disable NoBroadCast */
- uint8_t uc_no_boardcast;
- /* MAC address */
- uint8_t uc_mac_addr[GMAC_ADDR_LENGTH];
-} gmac_options_t;
-
-/** TX callback */
-typedef void (*gmac_dev_tx_cb_t) (uint32_t ul_status, uint8_t *puc_buffer);
-/** RX callback */
-typedef void (*gmac_dev_rx_cb_t) (uint32_t ul_status);
-/** Wakeup callback */
-typedef void (*gmac_dev_wakeup_cb_t) (void);
-
-/**
- * GMAC driver structure.
- */
-typedef struct gmac_device {
-
- /** Pointer to HW register base */
- Gmac *p_hw;
- /**
- * Pointer to allocated TX buffer.
- * Section 3.6 of AMBA 2.0 spec states that burst should not cross
- * 1K Boundaries.
- * Receive buffer manager writes are burst of 2 words => 3 lsb bits
- * of the address shall be set to 0.
- */
- uint8_t *p_tx_buffer;
- /** Pointer to allocated RX buffer */
- uint8_t *p_rx_buffer;
- /** Pointer to Rx TDs (must be 8-byte aligned) */
- gmac_rx_descriptor_t *p_rx_dscr;
- /** Pointer to Tx TDs (must be 8-byte aligned) */
- gmac_tx_descriptor_t *p_tx_dscr;
- /** Optional callback to be invoked once a frame has been received */
- gmac_dev_rx_cb_t func_rx_cb;
-#if( GMAC_USES_WAKEUP_CALLBACK )
- /** Optional callback to be invoked once several TDs have been released */
- gmac_dev_wakeup_cb_t func_wakeup_cb;
-#endif
-#if( GMAC_USES_TX_CALLBACK != 0 )
- /** Optional callback list to be invoked once TD has been processed */
- gmac_dev_tx_cb_t *func_tx_cb_list;
-#endif
- /** RX TD list size */
- uint32_t ul_rx_list_size;
- /** RX index for current processing TD */
- uint32_t ul_rx_idx;
- /** TX TD list size */
- uint32_t ul_tx_list_size;
- /** Circular buffer head pointer by upper layer (buffer to be sent) */
- int32_t l_tx_head;
- /** Circular buffer tail pointer incremented by handlers (buffer sent) */
- int32_t l_tx_tail;
-
- /** Number of free TD before wakeup callback is invoked */
- uint32_t uc_wakeup_threshold;
-} gmac_device_t;
-
-/**
- * \brief Write network control value.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_ncr Network control value.
- */
-static inline void gmac_network_control(Gmac* p_gmac, uint32_t ul_ncr)
-{
- p_gmac->GMAC_NCR = ul_ncr;
-}
-
-/**
- * \brief Get network control value.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-
-static inline uint32_t gmac_get_network_control(Gmac* p_gmac)
-{
- return p_gmac->GMAC_NCR;
-}
-
-/**
- * \brief Enable/Disable GMAC receive.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable GMAC receiver, else to enable it.
- */
-static inline void gmac_enable_receive(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_RXEN;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_RXEN;
- }
-}
-
-/**
- * \brief Enable/Disable GMAC transmit.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable GMAC transmit, else to enable it.
- */
-static inline void gmac_enable_transmit(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_TXEN;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_TXEN;
- }
-}
-
-/**
- * \brief Enable/Disable GMAC management.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable GMAC management, else to enable it.
- */
-static inline void gmac_enable_management(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_MPE;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_MPE;
- }
-}
-
-/**
- * \brief Clear all statistics registers.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_clear_statistics(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_CLRSTAT;
-}
-
-/**
- * \brief Increase all statistics registers.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_increase_statistics(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_INCSTAT;
-}
-
-/**
- * \brief Enable/Disable statistics registers writing.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the statistics registers writing, else to enable it.
- */
-static inline void gmac_enable_statistics_write(Gmac* p_gmac,
- uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_WESTAT;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_WESTAT;
- }
-}
-
-/**
- * \brief In half-duplex mode, forces collisions on all received frames.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the back pressure, else to enable it.
- */
-static inline void gmac_enable_back_pressure(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_BP;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_BP;
- }
-}
-
-/**
- * \brief Start transmission.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_start_transmission(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TSTART;
-}
-
-/**
- * \brief Halt transmission.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_halt_transmission(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_THALT;
-}
-
-/**
- * \brief Transmit pause frame.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_tx_pause_frame(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TXPF;
-}
-
-/**
- * \brief Transmit zero quantum pause frame.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_tx_pause_zero_quantum_frame(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TXZQPF;
-}
-
-/**
- * \brief Read snapshot.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_read_snapshot(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_RDS;
-}
-
-/**
- * \brief Store receivetime stamp to memory.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to normal operation, else to enable the store.
- */
-static inline void gmac_store_rx_time_stamp(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_SRTSM;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_SRTSM;
- }
-}
-
-/**
- * \brief Enable PFC priority-based pause reception.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 1 to set the reception, 0 to disable.
- */
-static inline void gmac_enable_pfc_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_ENPBPR;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_ENPBPR;
- }
-}
-
-/**
- * \brief Transmit PFC priority-based pause reception.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_transmit_pfc_pause_frame(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TXPBPF;
-}
-
-/**
- * \brief Flush next packet.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_flush_next_packet(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_FNP;
-}
-
-/**
- * \brief Set up network configuration register.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_cfg Network configuration value.
- */
-static inline void gmac_set_configure(Gmac* p_gmac, uint32_t ul_cfg)
-{
- p_gmac->GMAC_NCFGR = ul_cfg;
-}
-
-/**
- * \brief Get network configuration.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Network configuration.
- */
-static inline uint32_t gmac_get_configure(Gmac* p_gmac)
-{
- return p_gmac->GMAC_NCFGR;
-}
-
-
-/* Get and set DMA Configuration Register */
-static inline void gmac_set_dma(Gmac* p_gmac, uint32_t ul_cfg)
-{
- p_gmac->GMAC_DCFGR = ul_cfg;
-}
-
-static inline uint32_t gmac_get_dma(Gmac* p_gmac)
-{
- return p_gmac->GMAC_DCFGR;
-}
-
-/**
- * \brief Set speed.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_speed 1 to indicate 100Mbps, 0 to 10Mbps.
- */
-static inline void gmac_set_speed(Gmac* p_gmac, uint8_t uc_speed)
-{
- if (uc_speed) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_SPD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_SPD;
- }
-}
-
-/**
- * \brief Enable/Disable Full-Duplex mode.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the Full-Duplex mode, else to enable it.
- */
-static inline void gmac_enable_full_duplex(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_FD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_FD;
- }
-}
-
-/**
- * \brief Enable/Disable Copy(Receive) All Valid Frames.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable copying all valid frames, else to enable it.
- */
-static inline void gmac_enable_copy_all(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_CAF;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_CAF;
- }
-}
-
-/**
- * \brief Enable/Disable jumbo frames (up to 10240 bytes).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the jumbo frames, else to enable it.
- */
-static inline void gmac_enable_jumbo_frames(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_JFRAME;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_JFRAME;
- }
-}
-
-/**
- * \brief Disable/Enable broadcast receiving.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 1 to disable the broadcast, else to enable it.
- */
-static inline void gmac_disable_broadcast(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_NBC;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_NBC;
- }
-}
-
-/**
- * \brief Enable/Disable multicast hash.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the multicast hash, else to enable it.
- */
-static inline void gmac_enable_multicast_hash(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_UNIHEN;
- }
-}
-
-/**
- * \brief Enable/Disable big frames (over 1518, up to 1536).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable big frames else to enable it.
- */
-static inline void gmac_enable_big_frame(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_MAXFS;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_MAXFS;
- }
-}
-
-/**
- * \brief Set MDC clock divider.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_mck GMAC MCK.
- *
- * \return GMAC_OK if successfully.
- */
-static inline uint8_t gmac_set_mdc_clock(Gmac* p_gmac, uint32_t ul_mck)
-{
- uint32_t ul_clk;
-
- if (ul_mck > GMAC_MCK_SPEED_240MHZ) {
- return GMAC_INVALID;
- } else if (ul_mck > GMAC_MCK_SPEED_160MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_96;
- } else if (ul_mck > GMAC_MCK_SPEED_120MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_64;
- } else if (ul_mck > GMAC_MCK_SPEED_80MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_48;
- } else if (ul_mck > GMAC_MCK_SPEED_40MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_32;
- } else if (ul_mck > GMAC_MCK_SPEED_20MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_16;
- } else {
- ul_clk = GMAC_NCFGR_CLK_MCK_8;
- }
- ;
- p_gmac->GMAC_NCFGR = (p_gmac->GMAC_NCFGR & ~GMAC_NCFGR_CLK_Msk) | ul_clk;
- return GMAC_OK;
-}
-
-/**
- * \brief Enable/Disable retry test.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the GMAC receiver, else to enable it.
- */
-static inline void gmac_enable_retry_test(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RTY;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RTY;
- }
-}
-
-/**
- * \brief Enable/Disable pause (when a valid pause frame is received).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable pause frame, else to enable it.
- */
-static inline void gmac_enable_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_PEN;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_PEN;
- }
-}
-
-/**
- * \brief Set receive buffer offset to 0 ~ 3.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_set_rx_buffer_offset(Gmac* p_gmac, uint8_t uc_offset)
-{
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RXBUFO_Msk;
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RXBUFO(uc_offset);
-}
-
-/**
- * \brief Enable/Disable receive length field checking.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable receive length field checking, else to enable it.
- */
-static inline void gmac_enable_rx_length_check(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_LFERD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_LFERD;
- }
-}
-
-/**
- * \brief Enable/Disable discarding FCS field of received frames.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable discarding FCS field of received frames, else to enable it.
- */
-static inline void gmac_enable_discard_fcs(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RFCS;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RFCS;
- }
-}
-
-
-/**
- * \brief Enable/Disable frames to be received in half-duplex mode
- * while transmitting.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the received in half-duplex mode, else to enable it.
- */
-static inline void gmac_enable_efrhd(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_EFRHD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_EFRHD;
- }
-}
-
-/**
- * \brief Enable/Disable ignore RX FCS.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable ignore RX FCS, else to enable it.
- */
-static inline void gmac_enable_ignore_rx_fcs(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_IRXFCS;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_IRXFCS;
- }
-}
-
-/**
- * \brief Get Network Status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Network status.
- */
-static inline uint32_t gmac_get_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_NSR;
-}
-
-/**
- * \brief Get MDIO IN pin status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return MDIO IN pin status.
- */
-static inline uint8_t gmac_get_MDIO(Gmac* p_gmac)
-{
- return ((p_gmac->GMAC_NSR & GMAC_NSR_MDIO) > 0);
-}
-
-/**
- * \brief Check if PHY is idle.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return 1 if PHY is idle.
- */
-static inline uint8_t gmac_is_phy_idle(Gmac* p_gmac)
-{
- return ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) > 0);
-}
-
-/**
- * \brief Return transmit status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Transmit status.
- */
-static inline uint32_t gmac_get_tx_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_TSR;
-}
-
-/**
- * \brief Clear transmit status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_status Transmit status.
- */
-static inline void gmac_clear_tx_status(Gmac* p_gmac, uint32_t ul_status)
-{
- p_gmac->GMAC_TSR = ul_status;
-}
-
-/**
- * \brief Return receive status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline uint32_t gmac_get_rx_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_RSR;
-}
-
-/**
- * \brief Clear receive status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_status Receive status.
- */
-static inline void gmac_clear_rx_status(Gmac* p_gmac, uint32_t ul_status)
-{
- p_gmac->GMAC_RSR = ul_status;
-}
-
-/**
- * \brief Set Rx Queue.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_addr Rx queue address.
- */
-static inline void gmac_set_rx_queue(Gmac* p_gmac, uint32_t ul_addr)
-{
- p_gmac->GMAC_RBQB = GMAC_RBQB_ADDR_Msk & ul_addr;
-}
-
-/**
- * \brief Get Rx Queue Address.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Rx queue address.
- */
-static inline uint32_t gmac_get_rx_queue(Gmac* p_gmac)
-{
- return p_gmac->GMAC_RBQB;
-}
-
-/**
- * \brief Set Tx Queue.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_addr Tx queue address.
- */
-static inline void gmac_set_tx_queue(Gmac* p_gmac, uint32_t ul_addr)
-{
- p_gmac->GMAC_TBQB = GMAC_TBQB_ADDR_Msk & ul_addr;
-}
-
-/**
- * \brief Get Tx Queue.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Rx queue address.
- */
-static inline uint32_t gmac_get_tx_queue(Gmac* p_gmac)
-{
- return p_gmac->GMAC_TBQB;
-}
-
-/**
- * \brief Enable interrupt(s).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_source Interrupt source(s) to be enabled.
- */
-static inline void gmac_enable_interrupt(Gmac* p_gmac, uint32_t ul_source)
-{
- p_gmac->GMAC_IER = ul_source;
-}
-
-/**
- * \brief Disable interrupt(s).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_source Interrupt source(s) to be disabled.
- */
-static inline void gmac_disable_interrupt(Gmac* p_gmac, uint32_t ul_source)
-{
- p_gmac->GMAC_IDR = ul_source;
-}
-
-/**
- * \brief Return interrupt status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Interrupt status.
- */
-static inline uint32_t gmac_get_interrupt_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_ISR;
-}
-
-/**
- * \brief Return interrupt mask.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Interrupt mask.
- */
-static inline uint32_t gmac_get_interrupt_mask(Gmac* p_gmac)
-{
- return p_gmac->GMAC_IMR;
-}
-
-/**
- * \brief Execute PHY maintenance command.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param uc_reg_addr Register address.
- * \param uc_rw 1 to Read, 0 to write.
- * \param us_data Data to be performed, write only.
- */
-static inline void gmac_maintain_phy(Gmac* p_gmac,
- uint8_t uc_phy_addr, uint8_t uc_reg_addr, uint8_t uc_rw,
- uint16_t us_data)
-{
- /* Wait until bus idle */
- while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
- /* Write maintain register */
- p_gmac->GMAC_MAN = GMAC_MAN_WTN(GMAC_MAN_CODE_VALUE)
- | GMAC_MAN_CLTTO
- | GMAC_MAN_PHYA(uc_phy_addr)
- | GMAC_MAN_REGA(uc_reg_addr)
- | GMAC_MAN_OP((uc_rw ? GMAC_MAN_RW_TYPE : GMAC_MAN_READ_ONLY))
- | GMAC_MAN_DATA(us_data);
-}
-
-/**
- * \brief Get PHY maintenance data returned.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Get PHY data.
- */
-static inline uint16_t gmac_get_phy_data(Gmac* p_gmac)
-{
- /* Wait until bus idle */
- while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
- /* Return data */
- return (uint16_t) (p_gmac->GMAC_MAN & GMAC_MAN_DATA_Msk);
-}
-
-/**
- * \brief Set Hash.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_hash_top Hash top.
- * \param ul_hash_bottom Hash bottom.
- */
-static inline void gmac_set_hash(Gmac* p_gmac, uint32_t ul_hash_top,
- uint32_t ul_hash_bottom)
-{
- p_gmac->GMAC_HRB = ul_hash_bottom;
- p_gmac->GMAC_HRT = ul_hash_top;
-}
-
-/**
- * \brief Set 64 bits Hash.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ull_hash 64 bits hash value.
- */
-static inline void gmac_set_hash64(Gmac* p_gmac, uint64_t ull_hash)
-{
- p_gmac->GMAC_HRB = (uint32_t) ull_hash;
- p_gmac->GMAC_HRT = (uint32_t) (ull_hash >> 32);
-}
-
-/**
- * \brief Set MAC Address.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_index GMAC specific address register index.
- * \param p_mac_addr GMAC address.
- */
-static inline void gmac_set_address(Gmac* p_gmac, uint8_t uc_index,
- uint8_t* p_mac_addr)
-{
- p_gmac->GMAC_SA[uc_index].GMAC_SAB = (p_mac_addr[3] << 24)
- | (p_mac_addr[2] << 16)
- | (p_mac_addr[1] << 8)
- | (p_mac_addr[0]);
- p_gmac->GMAC_SA[uc_index].GMAC_SAT = (p_mac_addr[5] << 8)
- | (p_mac_addr[4]);
-}
-
-/**
- * \brief Set MAC Address via 2 dword.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_index GMAC specific address register index.
- * \param ul_mac_top GMAC top address.
- * \param ul_mac_bottom GMAC bottom address.
- */
-static inline void gmac_set_address32(Gmac* p_gmac, uint8_t uc_index,
- uint32_t ul_mac_top, uint32_t ul_mac_bottom)
-{
- p_gmac->GMAC_SA[uc_index].GMAC_SAB = ul_mac_bottom;
- p_gmac->GMAC_SA[uc_index].GMAC_SAT = ul_mac_top;
-}
-
-/**
- * \brief Set MAC Address via int64.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_index GMAC specific address register index.
- * \param ull_mac 64-bit GMAC address.
- */
-static inline void gmac_set_address64(Gmac* p_gmac, uint8_t uc_index,
- uint64_t ull_mac)
-{
- p_gmac->GMAC_SA[uc_index].GMAC_SAB = (uint32_t) ull_mac;
- p_gmac->GMAC_SA[uc_index].GMAC_SAT = (uint32_t) (ull_mac >> 32);
-}
-
-/**
- * \brief Select media independent interface mode.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param mode Media independent interface mode.
- */
-static inline void gmac_select_mii_mode(Gmac* p_gmac, gmac_mii_mode_t mode)
-{
- switch (mode) {
- case GMAC_PHY_MII:
- case GMAC_PHY_RMII:
- p_gmac->GMAC_UR |= GMAC_UR_RMIIMII;
- break;
-
- default:
- p_gmac->GMAC_UR &= ~GMAC_UR_RMIIMII;
- break;
- }
-}
-
-uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
- uint32_t* p_value);
-uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
- uint8_t uc_address, uint32_t ul_value);
-void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
- gmac_options_t* p_opt);
-uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
- uint32_t ul_frame_size, uint32_t* p_rcv_size);
-uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
- uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb);
-uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev);
-void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
- gmac_dev_rx_cb_t func_rx_cb);
-uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
- gmac_dev_wakeup_cb_t func_wakeup, uint8_t uc_threshold);
-void gmac_dev_reset(gmac_device_t* p_gmac_dev);
-void gmac_handler(gmac_device_t* p_gmac_dev);
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-}
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-/**
- * \page gmac_quickstart Quickstart guide for GMAC driver.
- *
- * This is the quickstart guide for the \ref gmac_group "Ethernet MAC",
- * with step-by-step instructions on how to configure and use the driver in a
- * selection of use cases.
- *
- * The use cases contain several code fragments. The code fragments in the
- * steps for setup can be copied into a custom initialization function, while
- * the steps for usage can be copied into, e.g., the main application function.
- *
- * \section gmac_basic_use_case Basic use case
- * In the basic use case, the GMAC driver are configured for:
- * - PHY component KSZ8051MNL is used
- * - GMAC uses MII mode
- * - The number of receive buffer is 16
- * - The number of transfer buffer is 8
- * - MAC address is set to 00-04-25-1c-a0-02
- * - IP address is set to 192.168.0.2
- * - IP address is set to 192.168.0.2
- * - Gateway is set to 192.168.0.1
- * - Network mask is 255.255.255.0
- * - PHY operation max retry count is 1000000
- * - GMAC is configured to not support copy all frame and support broadcast
- * - The data will be read from the ethernet
- *
- * \section gmac_basic_use_case_setup Setup steps
- *
- * \subsection gmac_basic_use_case_setup_prereq Prerequisites
- * -# \ref sysclk_group "System Clock Management (sysclock)"
- * -# \ref pmc_group "Power Management Controller (pmc)"
- * -# \ref ksz8051mnl_ethernet_phy_group "PHY component (KSZ8051MNL)"
- *
- * \subsection gmac_basic_use_case_setup_code Example code
- * Content of conf_eth.h
- * \code
- * #define GMAC_RX_BUFFERS 16
- * #define GMAC_TX_BUFFERS 8
- * #define MAC_PHY_RETRY_MAX 1000000
- * #define ETHERNET_CONF_ETHADDR0 0x00
- * #define ETHERNET_CONF_ETHADDR0 0x00
- * #define ETHERNET_CONF_ETHADDR1 0x04
- * #define ETHERNET_CONF_ETHADDR2 0x25
- * #define ETHERNET_CONF_ETHADDR3 0x1C
- * #define ETHERNET_CONF_ETHADDR4 0xA0
- * #define ETHERNET_CONF_ETHADDR5 0x02
- * #define ETHERNET_CONF_IPADDR0 192
- * #define ETHERNET_CONF_IPADDR1 168
- * #define ETHERNET_CONF_IPADDR2 0
- * #define ETHERNET_CONF_IPADDR3 2
- * #define ETHERNET_CONF_GATEWAY_ADDR0 192
- * #define ETHERNET_CONF_GATEWAY_ADDR1 168
- * #define ETHERNET_CONF_GATEWAY_ADDR2 0
- * #define ETHERNET_CONF_GATEWAY_ADDR3 1
- * #define ETHERNET_CONF_NET_MASK0 255
- * #define ETHERNET_CONF_NET_MASK1 255
- * #define ETHERNET_CONF_NET_MASK2 255
- * #define ETHERNET_CONF_NET_MASK3 0
- * #define ETH_PHY_MODE ETH_PHY_MODE
- * \endcode
- *
- * A specific gmac device and the receive data buffer must be defined; another ul_frm_size should be defined
- * to trace the actual size of the data received.
- * \code
- * static gmac_device_t gs_gmac_dev;
- * static volatile uint8_t gs_uc_eth_buffer[GMAC_FRAME_LENTGH_MAX];
- *
- * uint32_t ul_frm_size;
- * \endcode
- *
- * Add to application C-file:
- * \code
- * void gmac_init(void)
- * {
- * sysclk_init();
- *
- * board_init();
- *
- * pmc_enable_periph_clk(ID_GMAC);
- *
- * gmac_option.uc_copy_all_frame = 0;
- * gmac_option.uc_no_boardcast = 0;
- * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
- * gs_gmac_dev.p_hw = GMAC;
- *
- * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
- *
- * NVIC_EnableIRQ(GMAC_IRQn);
- *
- * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
- *
- * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
- *
- * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
- * \endcode
- *
- * \subsection gmac_basic_use_case_setup_flow Workflow
- * - Ensure that conf_eth.h is present and contains the
- * following configuration symbol. This configuration file is used
- * by the driver and should not be included by the application.
- * -# Define the receiving buffer size used in the internal GMAC driver.
- * The buffer size used for RX is GMAC_RX_BUFFERS * 128.
- * If it was supposed receiving a large number of frame, the
- * GMAC_RX_BUFFERS should be set higher. E.g., the application wants to accept
- * a ping echo test of 2048, the GMAC_RX_BUFFERS should be set at least
- * (2048/128)=16, and as there are additional frames coming, a preferred
- * number is 24 depending on a normal Ethernet throughput.
- * - \code
- * #define GMAC_RX_BUFFERS 16
- * \endcode
- * -# Define the transmitting buffer size used in the internal GMAC driver.
- * The buffer size used for TX is GMAC_TX_BUFFERS * 1518.
- * - \code
- * #define GMAC_TX_BUFFERS 8
- * \endcode
- * -# Define maximum retry time for a PHY read/write operation.
- * - \code
- * #define MAC_PHY_RETRY_MAX 1000000
- * \endcode
- * -# Define the MAC address. 00:04:25:1C:A0:02 is the address reserved
- * for ATMEL, application should always change this address to its' own.
- * - \code
- * #define ETHERNET_CONF_ETHADDR0 0x00
- * #define ETHERNET_CONF_ETHADDR1 0x04
- * #define ETHERNET_CONF_ETHADDR2 0x25
- * #define ETHERNET_CONF_ETHADDR3 0x1C
- * #define ETHERNET_CONF_ETHADDR4 0xA0
- * #define ETHERNET_CONF_ETHADDR5 0x02
- * \endcode
- * -# Define the IP address configration used in the application. When DHCP
- * is enabled, this configuration is not effected.
- * - \code
- * #define ETHERNET_CONF_IPADDR0 192
- * #define ETHERNET_CONF_IPADDR1 168
- * #define ETHERNET_CONF_IPADDR2 0
- * #define ETHERNET_CONF_IPADDR3 2
- * #define ETHERNET_CONF_GATEWAY_ADDR0 192
- * #define ETHERNET_CONF_GATEWAY_ADDR1 168
- * #define ETHERNET_CONF_GATEWAY_ADDR2 0
- * #define ETHERNET_CONF_GATEWAY_ADDR3 1
- * #define ETHERNET_CONF_NET_MASK0 255
- * #define ETHERNET_CONF_NET_MASK1 255
- * #define ETHERNET_CONF_NET_MASK2 255
- * #define ETHERNET_CONF_NET_MASK3 0
- * \endcode
- * -# Configure the PHY maintainance interface.
- * - \code
- * #define ETH_PHY_MODE GMAC_PHY_MII
- * \endcode
- * -# Enable the system clock:
- * - \code sysclk_init(); \endcode
- * -# Enable PIO configurations for GMAC:
- * - \code board_init(); \endcode
- * -# Enable PMC clock for GMAC:
- * - \code pmc_enable_periph_clk(ID_GMAC); \endcode
- * -# Set the GMAC options; it's set to copy all frame and support broadcast:
- * - \code
- * gmac_option.uc_copy_all_frame = 0;
- * gmac_option.uc_no_boardcast = 0;
- * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
- * gs_gmac_dev.p_hw = GMAC;
- * \endcode
- * -# Initialize GMAC device with the filled option:
- * - \code
- * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
- * \endcode
- * -# Enable the interrupt service for GMAC:
- * - \code
- * NVIC_EnableIRQ(GMAC_IRQn);
- * \endcode
- * -# Initialize the PHY component:
- * - \code
- * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
- * \endcode
- * -# The link will be established based on auto negotiation.
- * - \code
- * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
- * \endcode
- * -# Establish the ethernet link; the network can be worked from now on:
- * - \code
- * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
- * \endcode
- *
- * \section gmac_basic_use_case_usage Usage steps
- * \subsection gmac_basic_use_case_usage_code Example code
- * Add to, e.g., main loop in application C-file:
- * \code
- * gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size));
- * \endcode
- *
- * \subsection gmac_basic_use_case_usage_flow Workflow
- * -# Start reading the data from the ethernet:
- * - \code gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size)); \endcode
- */
-
-# define GMAC_STATS 0
-
-#if( GMAC_STATS != 0 )
-
- /* Here below some code to study the types and
- frequencies of GMAC interrupts. */
- #define GMAC_IDX_RXUBR 0
- #define GMAC_IDX_TUR 1
- #define GMAC_IDX_RLEX 2
- #define GMAC_IDX_TFC 3
- #define GMAC_IDX_RCOMP 4
- #define GMAC_IDX_TCOMP 5
- #define GMAC_IDX_ROVR 6
- #define GMAC_IDX_HRESP 7
- #define GMAC_IDX_PFNZ 8
- #define GMAC_IDX_PTZ 9
-
- struct SGmacStats {
- unsigned recvCount;
- unsigned rovrCount;
- unsigned bnaCount;
- unsigned sendCount;
- unsigned sovrCount;
- unsigned incompCount;
- unsigned truncCount;
-
- unsigned intStatus[10];
- };
- extern struct SGmacStats gmacStats;
-
- struct SIntPair {
- const char *name;
- unsigned mask;
- int index;
- };
-
- #define MK_PAIR( NAME ) #NAME, GMAC_IER_##NAME, GMAC_IDX_##NAME
- static const struct SIntPair intPairs[] = {
- { MK_PAIR( RXUBR ) }, /* Enable receive used bit read interrupt. */
- { MK_PAIR( TUR ) }, /* Enable transmit underrun interrupt. */
- { MK_PAIR( RLEX ) }, /* Enable retry limit exceeded interrupt. */
- { MK_PAIR( TFC ) }, /* Enable transmit buffers exhausted in mid-frame interrupt. */
- { MK_PAIR( RCOMP ) }, /* Receive complete */
- { MK_PAIR( TCOMP ) }, /* Enable transmit complete interrupt. */
- { MK_PAIR( ROVR ) }, /* Enable receive overrun interrupt. */
- { MK_PAIR( HRESP ) }, /* Enable Hresp not OK interrupt. */
- { MK_PAIR( PFNZ ) }, /* Enable pause frame received interrupt. */
- { MK_PAIR( PTZ ) } /* Enable pause time zero interrupt. */
- };
-
- void gmac_show_irq_counts ();
-
-#endif
-
-#endif /* GMAC_H_INCLUDED */
+ /**
+ * \file
+ *
+ * \brief GMAC (Ethernet MAC) driver for SAM.
+ *
+ * Copyright (c) 2013 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#ifndef GMAC_H_INCLUDED
+#define GMAC_H_INCLUDED
+
+#include "compiler.h"
+#include "component/gmac.h"
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/** The buffer addresses written into the descriptors must be aligned, so the
+ last few bits are zero. These bits have special meaning for the GMAC
+ peripheral and cannot be used as part of the address. */
+#define GMAC_RXD_ADDR_MASK 0xFFFFFFFC
+#define GMAC_RXD_WRAP (1ul << 1) /**< Wrap bit */
+#define GMAC_RXD_OWNERSHIP (1ul << 0) /**< Ownership bit */
+
+#define GMAC_RXD_BROADCAST (1ul << 31) /**< Broadcast detected */
+#define GMAC_RXD_MULTIHASH (1ul << 30) /**< Multicast hash match */
+#define GMAC_RXD_UNIHASH (1ul << 29) /**< Unicast hash match */
+#define GMAC_RXD_ADDR_FOUND (1ul << 27) /**< Specific address match found */
+#define GMAC_RXD_ADDR (3ul << 25) /**< Address match */
+#define GMAC_RXD_RXCOEN (1ul << 24) /**< RXCOEN related function */
+#define GMAC_RXD_TYPE (3ul << 22) /**< Type ID match */
+#define GMAC_RXD_VLAN (1ul << 21) /**< VLAN tag detected */
+#define GMAC_RXD_PRIORITY (1ul << 20) /**< Priority tag detected */
+#define GMAC_RXD_PRIORITY_MASK (3ul << 17) /**< VLAN priority */
+#define GMAC_RXD_CFI (1ul << 16) /**< Concatenation Format Indicator only if bit 21 is set */
+#define GMAC_RXD_EOF (1ul << 15) /**< End of frame */
+#define GMAC_RXD_SOF (1ul << 14) /**< Start of frame */
+#define GMAC_RXD_FCS (1ul << 13) /**< Frame check sequence */
+#define GMAC_RXD_OFFSET_MASK /**< Receive buffer offset */
+#define GMAC_RXD_LEN_MASK (0xFFF) /**< Length of frame including FCS (if selected) */
+#define GMAC_RXD_LENJUMBO_MASK (0x3FFF) /**< Jumbo frame length */
+
+#define GMAC_TXD_USED (1ul << 31) /**< Frame is transmitted */
+#define GMAC_TXD_WRAP (1ul << 30) /**< Last descriptor */
+#define GMAC_TXD_ERROR (1ul << 29) /**< Retry limit exceeded, error */
+#define GMAC_TXD_UNDERRUN (1ul << 28) /**< Transmit underrun */
+#define GMAC_TXD_EXHAUSTED (1ul << 27) /**< Buffer exhausted */
+#define GMAC_TXD_LATE (1ul << 26) /**< Late collision,transmit error */
+#define GMAC_TXD_CHECKSUM_ERROR (7ul << 20) /**< Checksum error */
+#define GMAC_TXD_NOCRC (1ul << 16) /**< No CRC */
+#define GMAC_TXD_LAST (1ul << 15) /**< Last buffer in frame */
+#define GMAC_TXD_LEN_MASK (0x1FFF) /**< Length of buffer */
+
+/** The MAC can support frame lengths up to 1536 bytes */
+#define GMAC_FRAME_LENTGH_MAX 1536
+
+#define GMAC_RX_UNITSIZE 128 /**< Fixed size for RX buffer */
+#define GMAC_TX_UNITSIZE 1518 /**< Size for ETH frame length */
+
+/** GMAC clock speed */
+#define GMAC_MCK_SPEED_240MHZ (240*1000*1000)
+#define GMAC_MCK_SPEED_160MHZ (160*1000*1000)
+#define GMAC_MCK_SPEED_120MHZ (120*1000*1000)
+#define GMAC_MCK_SPEED_80MHZ (80*1000*1000)
+#define GMAC_MCK_SPEED_40MHZ (40*1000*1000)
+#define GMAC_MCK_SPEED_20MHZ (20*1000*1000)
+
+/** GMAC maintain code default value*/
+#define GMAC_MAN_CODE_VALUE (10)
+
+/** GMAC maintain start of frame default value*/
+#define GMAC_MAN_SOF_VALUE (1)
+
+/** GMAC maintain read/write*/
+#define GMAC_MAN_RW_TYPE (2)
+
+/** GMAC maintain read only*/
+#define GMAC_MAN_READ_ONLY (1)
+
+/** GMAC address length */
+#define GMAC_ADDR_LENGTH (6)
+
+
+#define GMAC_DUPLEX_HALF 0
+#define GMAC_DUPLEX_FULL 1
+
+#define GMAC_SPEED_10M 0
+#define GMAC_SPEED_100M 1
+
+/**
+ * \brief Return codes for GMAC APIs.
+ */
+typedef enum {
+ GMAC_OK = 0, /** 0 Operation OK */
+ GMAC_TIMEOUT = 1, /** 1 GMAC operation timeout */
+ GMAC_TX_BUSY, /** 2 TX in progress */
+ GMAC_RX_NULL, /** 3 No data received */
+ GMAC_SIZE_TOO_SMALL, /** 4 Buffer size not enough */
+ GMAC_PARAM, /** 5 Parameter error, TX packet invalid or RX size too small */
+ GMAC_INVALID = 0xFF, /* Invalid */
+} gmac_status_t;
+
+/**
+ * \brief Media Independent Interface (MII) type.
+ */
+typedef enum {
+ GMAC_PHY_MII = 0, /** MII mode */
+ GMAC_PHY_RMII = 1, /** Reduced MII mode */
+ GMAC_PHY_INVALID = 0xFF, /* Invalid mode*/
+} gmac_mii_mode_t;
+
+/** Receive buffer descriptor struct */
+COMPILER_PACK_SET(8)
+typedef struct gmac_rx_descriptor {
+ union gmac_rx_addr {
+ uint32_t val;
+ struct gmac_rx_addr_bm {
+ uint32_t b_ownership:1, /**< User clear, GMAC sets this to 1 once it has successfully written a frame to memory */
+ b_wrap:1, /**< Marks last descriptor in receive buffer */
+ addr_dw:30; /**< Address in number of DW */
+ } bm;
+ } addr; /**< Address, Wrap & Ownership */
+ union gmac_rx_status {
+ uint32_t val;
+ struct gmac_rx_status_bm {
+ uint32_t len:13, /** 0..12 Length of frame including FCS */
+ b_fcs:1, /** 13 Receive buffer offset, bits 13:12 of frame length for jumbo frame */
+ b_sof:1, /** 14 Start of frame */
+ b_eof:1, /** 15 End of frame */
+ b_cfi:1, /** 16 Concatenation Format Indicator */
+ vlan_priority:3, /** 17..19 VLAN priority (if VLAN detected) */
+ b_priority_detected:1, /** 20 Priority tag detected */
+ b_vlan_detected:1, /** 21 VLAN tag detected */
+ b_type_id_match:2, /** 22..23 Type ID match */
+ b_checksumoffload:1, /** 24 Checksum offload specific function */
+ b_addrmatch:2, /** 25..26 Address register match */
+ b_ext_addr_match:1, /** 27 External address match found */
+ reserved:1, /** 28 */
+ b_uni_hash_match:1, /** 29 Unicast hash match */
+ b_multi_hash_match:1, /** 30 Multicast hash match */
+ b_boardcast_detect:1; /** 31 Global broadcast address detected */
+ } bm;
+ } status;
+} gmac_rx_descriptor_t;
+
+/** Transmit buffer descriptor struct */
+COMPILER_PACK_SET(8)
+typedef struct gmac_tx_descriptor {
+ uint32_t addr;
+ union gmac_tx_status {
+ uint32_t val;
+ struct gmac_tx_status_bm {
+ uint32_t len:14, /** 0..13 Length of buffer */
+ reserved:1, /** 14 */
+ b_last_buffer:1, /** 15 Last buffer (in the current frame) */
+ b_no_crc:1, /** 16 No CRC */
+ reserved1:3, /** 17..19 */
+ b_checksumoffload:3, /** 20..22 Transmit checksum generation offload errors */
+ reserved2:3, /** 23..25 */
+ b_lco:1, /** 26 Late collision, transmit error detected */
+ b_exhausted:1, /** 27 Buffer exhausted in mid frame */
+ b_underrun:1, /** 28 Transmit underrun */
+ b_error:1, /** 29 Retry limit exceeded, error detected */
+ b_wrap:1, /** 30 Marks last descriptor in TD list */
+ b_used:1; /** 31 User clear, GMAC sets this to 1 once a frame has been successfully transmitted */
+ } bm;
+ } status;
+} gmac_tx_descriptor_t;
+
+COMPILER_PACK_RESET()
+
+/**
+ * \brief Input parameters when initializing the gmac module mode.
+ */
+typedef struct gmac_options {
+ /* Enable/Disable CopyAllFrame */
+ uint8_t uc_copy_all_frame;
+ /* Enable/Disable NoBroadCast */
+ uint8_t uc_no_boardcast;
+ /* MAC address */
+ uint8_t uc_mac_addr[GMAC_ADDR_LENGTH];
+} gmac_options_t;
+
+/** TX callback */
+typedef void (*gmac_dev_tx_cb_t) (uint32_t ul_status, uint8_t *puc_buffer);
+/** RX callback */
+typedef void (*gmac_dev_rx_cb_t) (uint32_t ul_status);
+/** Wakeup callback */
+typedef void (*gmac_dev_wakeup_cb_t) (void);
+
+/**
+ * GMAC driver structure.
+ */
+typedef struct gmac_device {
+
+ /** Pointer to HW register base */
+ Gmac *p_hw;
+ /**
+ * Pointer to allocated TX buffer.
+ * Section 3.6 of AMBA 2.0 spec states that burst should not cross
+ * 1K Boundaries.
+ * Receive buffer manager writes are burst of 2 words => 3 lsb bits
+ * of the address shall be set to 0.
+ */
+ uint8_t *p_tx_buffer;
+ /** Pointer to allocated RX buffer */
+ uint8_t *p_rx_buffer;
+ /** Pointer to Rx TDs (must be 8-byte aligned) */
+ gmac_rx_descriptor_t *p_rx_dscr;
+ /** Pointer to Tx TDs (must be 8-byte aligned) */
+ gmac_tx_descriptor_t *p_tx_dscr;
+ /** Optional callback to be invoked once a frame has been received */
+ gmac_dev_rx_cb_t func_rx_cb;
+#if( GMAC_USES_WAKEUP_CALLBACK )
+ /** Optional callback to be invoked once several TDs have been released */
+ gmac_dev_wakeup_cb_t func_wakeup_cb;
+#endif
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ /** Optional callback list to be invoked once TD has been processed */
+ gmac_dev_tx_cb_t *func_tx_cb_list;
+#endif
+ /** RX TD list size */
+ uint32_t ul_rx_list_size;
+ /** RX index for current processing TD */
+ uint32_t ul_rx_idx;
+ /** TX TD list size */
+ uint32_t ul_tx_list_size;
+ /** Circular buffer head pointer by upper layer (buffer to be sent) */
+ int32_t l_tx_head;
+ /** Circular buffer tail pointer incremented by handlers (buffer sent) */
+ int32_t l_tx_tail;
+
+ /** Number of free TD before wakeup callback is invoked */
+ uint32_t uc_wakeup_threshold;
+} gmac_device_t;
+
+/**
+ * \brief Write network control value.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_ncr Network control value.
+ */
+static inline void gmac_network_control(Gmac* p_gmac, uint32_t ul_ncr)
+{
+ p_gmac->GMAC_NCR = ul_ncr;
+}
+
+/**
+ * \brief Get network control value.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+
+static inline uint32_t gmac_get_network_control(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_NCR;
+}
+
+/**
+ * \brief Enable/Disable GMAC receive.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable GMAC receiver, else to enable it.
+ */
+static inline void gmac_enable_receive(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_RXEN;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_RXEN;
+ }
+}
+
+/**
+ * \brief Enable/Disable GMAC transmit.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable GMAC transmit, else to enable it.
+ */
+static inline void gmac_enable_transmit(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXEN;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_TXEN;
+ }
+}
+
+/**
+ * \brief Enable/Disable GMAC management.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable GMAC management, else to enable it.
+ */
+static inline void gmac_enable_management(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_MPE;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_MPE;
+ }
+}
+
+/**
+ * \brief Clear all statistics registers.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_clear_statistics(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_CLRSTAT;
+}
+
+/**
+ * \brief Increase all statistics registers.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_increase_statistics(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_INCSTAT;
+}
+
+/**
+ * \brief Enable/Disable statistics registers writing.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the statistics registers writing, else to enable it.
+ */
+static inline void gmac_enable_statistics_write(Gmac* p_gmac,
+ uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_WESTAT;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_WESTAT;
+ }
+}
+
+/**
+ * \brief In half-duplex mode, forces collisions on all received frames.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the back pressure, else to enable it.
+ */
+static inline void gmac_enable_back_pressure(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_BP;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_BP;
+ }
+}
+
+/**
+ * \brief Start transmission.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_start_transmission(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TSTART;
+}
+
+/**
+ * \brief Halt transmission.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_halt_transmission(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_THALT;
+}
+
+/**
+ * \brief Transmit pause frame.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_tx_pause_frame(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXPF;
+}
+
+/**
+ * \brief Transmit zero quantum pause frame.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_tx_pause_zero_quantum_frame(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXZQPF;
+}
+
+/**
+ * \brief Read snapshot.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_read_snapshot(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_RDS;
+}
+
+/**
+ * \brief Store receivetime stamp to memory.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to normal operation, else to enable the store.
+ */
+static inline void gmac_store_rx_time_stamp(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_SRTSM;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_SRTSM;
+ }
+}
+
+/**
+ * \brief Enable PFC priority-based pause reception.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 1 to set the reception, 0 to disable.
+ */
+static inline void gmac_enable_pfc_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_ENPBPR;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_ENPBPR;
+ }
+}
+
+/**
+ * \brief Transmit PFC priority-based pause reception.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_transmit_pfc_pause_frame(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXPBPF;
+}
+
+/**
+ * \brief Flush next packet.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_flush_next_packet(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_FNP;
+}
+
+/**
+ * \brief Set up network configuration register.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_cfg Network configuration value.
+ */
+static inline void gmac_set_configure(Gmac* p_gmac, uint32_t ul_cfg)
+{
+ p_gmac->GMAC_NCFGR = ul_cfg;
+}
+
+/**
+ * \brief Get network configuration.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Network configuration.
+ */
+static inline uint32_t gmac_get_configure(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_NCFGR;
+}
+
+
+/* Get and set DMA Configuration Register */
+static inline void gmac_set_dma(Gmac* p_gmac, uint32_t ul_cfg)
+{
+ p_gmac->GMAC_DCFGR = ul_cfg;
+}
+
+static inline uint32_t gmac_get_dma(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_DCFGR;
+}
+
+/**
+ * \brief Set speed.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_speed 1 to indicate 100Mbps, 0 to 10Mbps.
+ */
+static inline void gmac_set_speed(Gmac* p_gmac, uint8_t uc_speed)
+{
+ if (uc_speed) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_SPD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_SPD;
+ }
+}
+
+/**
+ * \brief Enable/Disable Full-Duplex mode.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the Full-Duplex mode, else to enable it.
+ */
+static inline void gmac_enable_full_duplex(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_FD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_FD;
+ }
+}
+
+/**
+ * \brief Enable/Disable Copy(Receive) All Valid Frames.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable copying all valid frames, else to enable it.
+ */
+static inline void gmac_enable_copy_all(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_CAF;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_CAF;
+ }
+}
+
+/**
+ * \brief Enable/Disable jumbo frames (up to 10240 bytes).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the jumbo frames, else to enable it.
+ */
+static inline void gmac_enable_jumbo_frames(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_JFRAME;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_JFRAME;
+ }
+}
+
+/**
+ * \brief Disable/Enable broadcast receiving.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 1 to disable the broadcast, else to enable it.
+ */
+static inline void gmac_disable_broadcast(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_NBC;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_NBC;
+ }
+}
+
+/**
+ * \brief Enable/Disable multicast hash.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the multicast hash, else to enable it.
+ */
+static inline void gmac_enable_multicast_hash(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_UNIHEN;
+ }
+}
+
+/**
+ * \brief Enable/Disable big frames (over 1518, up to 1536).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable big frames else to enable it.
+ */
+static inline void gmac_enable_big_frame(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_MAXFS;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_MAXFS;
+ }
+}
+
+/**
+ * \brief Set MDC clock divider.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_mck GMAC MCK.
+ *
+ * \return GMAC_OK if successfully.
+ */
+static inline uint8_t gmac_set_mdc_clock(Gmac* p_gmac, uint32_t ul_mck)
+{
+ uint32_t ul_clk;
+
+ if (ul_mck > GMAC_MCK_SPEED_240MHZ) {
+ return GMAC_INVALID;
+ } else if (ul_mck > GMAC_MCK_SPEED_160MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_96;
+ } else if (ul_mck > GMAC_MCK_SPEED_120MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_64;
+ } else if (ul_mck > GMAC_MCK_SPEED_80MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_48;
+ } else if (ul_mck > GMAC_MCK_SPEED_40MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_32;
+ } else if (ul_mck > GMAC_MCK_SPEED_20MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_16;
+ } else {
+ ul_clk = GMAC_NCFGR_CLK_MCK_8;
+ }
+ ;
+ p_gmac->GMAC_NCFGR = (p_gmac->GMAC_NCFGR & ~GMAC_NCFGR_CLK_Msk) | ul_clk;
+ return GMAC_OK;
+}
+
+/**
+ * \brief Enable/Disable retry test.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the GMAC receiver, else to enable it.
+ */
+static inline void gmac_enable_retry_test(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RTY;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RTY;
+ }
+}
+
+/**
+ * \brief Enable/Disable pause (when a valid pause frame is received).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable pause frame, else to enable it.
+ */
+static inline void gmac_enable_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_PEN;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_PEN;
+ }
+}
+
+/**
+ * \brief Set receive buffer offset to 0 ~ 3.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_set_rx_buffer_offset(Gmac* p_gmac, uint8_t uc_offset)
+{
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RXBUFO_Msk;
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RXBUFO(uc_offset);
+}
+
+/**
+ * \brief Enable/Disable receive length field checking.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable receive length field checking, else to enable it.
+ */
+static inline void gmac_enable_rx_length_check(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_LFERD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_LFERD;
+ }
+}
+
+/**
+ * \brief Enable/Disable discarding FCS field of received frames.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable discarding FCS field of received frames, else to enable it.
+ */
+static inline void gmac_enable_discard_fcs(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RFCS;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RFCS;
+ }
+}
+
+
+/**
+ * \brief Enable/Disable frames to be received in half-duplex mode
+ * while transmitting.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the received in half-duplex mode, else to enable it.
+ */
+static inline void gmac_enable_efrhd(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_EFRHD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_EFRHD;
+ }
+}
+
+/**
+ * \brief Enable/Disable ignore RX FCS.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable ignore RX FCS, else to enable it.
+ */
+static inline void gmac_enable_ignore_rx_fcs(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_IRXFCS;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_IRXFCS;
+ }
+}
+
+/**
+ * \brief Get Network Status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Network status.
+ */
+static inline uint32_t gmac_get_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_NSR;
+}
+
+/**
+ * \brief Get MDIO IN pin status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return MDIO IN pin status.
+ */
+static inline uint8_t gmac_get_MDIO(Gmac* p_gmac)
+{
+ return ((p_gmac->GMAC_NSR & GMAC_NSR_MDIO) > 0);
+}
+
+/**
+ * \brief Check if PHY is idle.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return 1 if PHY is idle.
+ */
+static inline uint8_t gmac_is_phy_idle(Gmac* p_gmac)
+{
+ return ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) > 0);
+}
+
+/**
+ * \brief Return transmit status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Transmit status.
+ */
+static inline uint32_t gmac_get_tx_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_TSR;
+}
+
+/**
+ * \brief Clear transmit status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_status Transmit status.
+ */
+static inline void gmac_clear_tx_status(Gmac* p_gmac, uint32_t ul_status)
+{
+ p_gmac->GMAC_TSR = ul_status;
+}
+
+/**
+ * \brief Return receive status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline uint32_t gmac_get_rx_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_RSR;
+}
+
+/**
+ * \brief Clear receive status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_status Receive status.
+ */
+static inline void gmac_clear_rx_status(Gmac* p_gmac, uint32_t ul_status)
+{
+ p_gmac->GMAC_RSR = ul_status;
+}
+
+/**
+ * \brief Set Rx Queue.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_addr Rx queue address.
+ */
+static inline void gmac_set_rx_queue(Gmac* p_gmac, uint32_t ul_addr)
+{
+ p_gmac->GMAC_RBQB = GMAC_RBQB_ADDR_Msk & ul_addr;
+}
+
+/**
+ * \brief Get Rx Queue Address.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Rx queue address.
+ */
+static inline uint32_t gmac_get_rx_queue(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_RBQB;
+}
+
+/**
+ * \brief Set Tx Queue.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_addr Tx queue address.
+ */
+static inline void gmac_set_tx_queue(Gmac* p_gmac, uint32_t ul_addr)
+{
+ p_gmac->GMAC_TBQB = GMAC_TBQB_ADDR_Msk & ul_addr;
+}
+
+/**
+ * \brief Get Tx Queue.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Rx queue address.
+ */
+static inline uint32_t gmac_get_tx_queue(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_TBQB;
+}
+
+/**
+ * \brief Enable interrupt(s).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_source Interrupt source(s) to be enabled.
+ */
+static inline void gmac_enable_interrupt(Gmac* p_gmac, uint32_t ul_source)
+{
+ p_gmac->GMAC_IER = ul_source;
+}
+
+/**
+ * \brief Disable interrupt(s).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_source Interrupt source(s) to be disabled.
+ */
+static inline void gmac_disable_interrupt(Gmac* p_gmac, uint32_t ul_source)
+{
+ p_gmac->GMAC_IDR = ul_source;
+}
+
+/**
+ * \brief Return interrupt status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Interrupt status.
+ */
+static inline uint32_t gmac_get_interrupt_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_ISR;
+}
+
+/**
+ * \brief Return interrupt mask.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Interrupt mask.
+ */
+static inline uint32_t gmac_get_interrupt_mask(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_IMR;
+}
+
+/**
+ * \brief Execute PHY maintenance command.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param uc_reg_addr Register address.
+ * \param uc_rw 1 to Read, 0 to write.
+ * \param us_data Data to be performed, write only.
+ */
+static inline void gmac_maintain_phy(Gmac* p_gmac,
+ uint8_t uc_phy_addr, uint8_t uc_reg_addr, uint8_t uc_rw,
+ uint16_t us_data)
+{
+ /* Wait until bus idle */
+ while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
+ /* Write maintain register */
+ p_gmac->GMAC_MAN = GMAC_MAN_WTN(GMAC_MAN_CODE_VALUE)
+ | GMAC_MAN_CLTTO
+ | GMAC_MAN_PHYA(uc_phy_addr)
+ | GMAC_MAN_REGA(uc_reg_addr)
+ | GMAC_MAN_OP((uc_rw ? GMAC_MAN_RW_TYPE : GMAC_MAN_READ_ONLY))
+ | GMAC_MAN_DATA(us_data);
+}
+
+/**
+ * \brief Get PHY maintenance data returned.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Get PHY data.
+ */
+static inline uint16_t gmac_get_phy_data(Gmac* p_gmac)
+{
+ /* Wait until bus idle */
+ while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
+ /* Return data */
+ return (uint16_t) (p_gmac->GMAC_MAN & GMAC_MAN_DATA_Msk);
+}
+
+/**
+ * \brief Set Hash.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_hash_top Hash top.
+ * \param ul_hash_bottom Hash bottom.
+ */
+static inline void gmac_set_hash(Gmac* p_gmac, uint32_t ul_hash_top,
+ uint32_t ul_hash_bottom)
+{
+ p_gmac->GMAC_HRB = ul_hash_bottom;
+ p_gmac->GMAC_HRT = ul_hash_top;
+}
+
+/**
+ * \brief Set 64 bits Hash.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ull_hash 64 bits hash value.
+ */
+static inline void gmac_set_hash64(Gmac* p_gmac, uint64_t ull_hash)
+{
+ p_gmac->GMAC_HRB = (uint32_t) ull_hash;
+ p_gmac->GMAC_HRT = (uint32_t) (ull_hash >> 32);
+}
+
+/**
+ * \brief Set MAC Address.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_index GMAC specific address register index.
+ * \param p_mac_addr GMAC address.
+ */
+static inline void gmac_set_address(Gmac* p_gmac, uint8_t uc_index,
+ uint8_t* p_mac_addr)
+{
+ p_gmac->GMAC_SA[uc_index].GMAC_SAB = (p_mac_addr[3] << 24)
+ | (p_mac_addr[2] << 16)
+ | (p_mac_addr[1] << 8)
+ | (p_mac_addr[0]);
+ p_gmac->GMAC_SA[uc_index].GMAC_SAT = (p_mac_addr[5] << 8)
+ | (p_mac_addr[4]);
+}
+
+/**
+ * \brief Set MAC Address via 2 dword.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_index GMAC specific address register index.
+ * \param ul_mac_top GMAC top address.
+ * \param ul_mac_bottom GMAC bottom address.
+ */
+static inline void gmac_set_address32(Gmac* p_gmac, uint8_t uc_index,
+ uint32_t ul_mac_top, uint32_t ul_mac_bottom)
+{
+ p_gmac->GMAC_SA[uc_index].GMAC_SAB = ul_mac_bottom;
+ p_gmac->GMAC_SA[uc_index].GMAC_SAT = ul_mac_top;
+}
+
+/**
+ * \brief Set MAC Address via int64.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_index GMAC specific address register index.
+ * \param ull_mac 64-bit GMAC address.
+ */
+static inline void gmac_set_address64(Gmac* p_gmac, uint8_t uc_index,
+ uint64_t ull_mac)
+{
+ p_gmac->GMAC_SA[uc_index].GMAC_SAB = (uint32_t) ull_mac;
+ p_gmac->GMAC_SA[uc_index].GMAC_SAT = (uint32_t) (ull_mac >> 32);
+}
+
+/**
+ * \brief Select media independent interface mode.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param mode Media independent interface mode.
+ */
+static inline void gmac_select_mii_mode(Gmac* p_gmac, gmac_mii_mode_t mode)
+{
+ switch (mode) {
+ case GMAC_PHY_MII:
+ case GMAC_PHY_RMII:
+ p_gmac->GMAC_UR |= GMAC_UR_RMIIMII;
+ break;
+
+ default:
+ p_gmac->GMAC_UR &= ~GMAC_UR_RMIIMII;
+ break;
+ }
+}
+
+uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
+ uint32_t* p_value);
+uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
+ uint8_t uc_address, uint32_t ul_value);
+void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
+ gmac_options_t* p_opt);
+uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
+ uint32_t ul_frame_size, uint32_t* p_rcv_size);
+uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
+ uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb);
+uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev);
+void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
+ gmac_dev_rx_cb_t func_rx_cb);
+uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
+ gmac_dev_wakeup_cb_t func_wakeup, uint8_t uc_threshold);
+void gmac_dev_reset(gmac_device_t* p_gmac_dev);
+void gmac_handler(gmac_device_t* p_gmac_dev);
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+}
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/**
+ * \page gmac_quickstart Quickstart guide for GMAC driver.
+ *
+ * This is the quickstart guide for the \ref gmac_group "Ethernet MAC",
+ * with step-by-step instructions on how to configure and use the driver in a
+ * selection of use cases.
+ *
+ * The use cases contain several code fragments. The code fragments in the
+ * steps for setup can be copied into a custom initialization function, while
+ * the steps for usage can be copied into, e.g., the main application function.
+ *
+ * \section gmac_basic_use_case Basic use case
+ * In the basic use case, the GMAC driver are configured for:
+ * - PHY component KSZ8051MNL is used
+ * - GMAC uses MII mode
+ * - The number of receive buffer is 16
+ * - The number of transfer buffer is 8
+ * - MAC address is set to 00-04-25-1c-a0-02
+ * - IP address is set to 192.168.0.2
+ * - IP address is set to 192.168.0.2
+ * - Gateway is set to 192.168.0.1
+ * - Network mask is 255.255.255.0
+ * - PHY operation max retry count is 1000000
+ * - GMAC is configured to not support copy all frame and support broadcast
+ * - The data will be read from the ethernet
+ *
+ * \section gmac_basic_use_case_setup Setup steps
+ *
+ * \subsection gmac_basic_use_case_setup_prereq Prerequisites
+ * -# \ref sysclk_group "System Clock Management (sysclock)"
+ * -# \ref pmc_group "Power Management Controller (pmc)"
+ * -# \ref ksz8051mnl_ethernet_phy_group "PHY component (KSZ8051MNL)"
+ *
+ * \subsection gmac_basic_use_case_setup_code Example code
+ * Content of conf_eth.h
+ * \code
+ * #define GMAC_RX_BUFFERS 16
+ * #define GMAC_TX_BUFFERS 8
+ * #define MAC_PHY_RETRY_MAX 1000000
+ * #define ETHERNET_CONF_ETHADDR0 0x00
+ * #define ETHERNET_CONF_ETHADDR0 0x00
+ * #define ETHERNET_CONF_ETHADDR1 0x04
+ * #define ETHERNET_CONF_ETHADDR2 0x25
+ * #define ETHERNET_CONF_ETHADDR3 0x1C
+ * #define ETHERNET_CONF_ETHADDR4 0xA0
+ * #define ETHERNET_CONF_ETHADDR5 0x02
+ * #define ETHERNET_CONF_IPADDR0 192
+ * #define ETHERNET_CONF_IPADDR1 168
+ * #define ETHERNET_CONF_IPADDR2 0
+ * #define ETHERNET_CONF_IPADDR3 2
+ * #define ETHERNET_CONF_GATEWAY_ADDR0 192
+ * #define ETHERNET_CONF_GATEWAY_ADDR1 168
+ * #define ETHERNET_CONF_GATEWAY_ADDR2 0
+ * #define ETHERNET_CONF_GATEWAY_ADDR3 1
+ * #define ETHERNET_CONF_NET_MASK0 255
+ * #define ETHERNET_CONF_NET_MASK1 255
+ * #define ETHERNET_CONF_NET_MASK2 255
+ * #define ETHERNET_CONF_NET_MASK3 0
+ * #define ETH_PHY_MODE ETH_PHY_MODE
+ * \endcode
+ *
+ * A specific gmac device and the receive data buffer must be defined; another ul_frm_size should be defined
+ * to trace the actual size of the data received.
+ * \code
+ * static gmac_device_t gs_gmac_dev;
+ * static volatile uint8_t gs_uc_eth_buffer[GMAC_FRAME_LENTGH_MAX];
+ *
+ * uint32_t ul_frm_size;
+ * \endcode
+ *
+ * Add to application C-file:
+ * \code
+ * void gmac_init(void)
+ * {
+ * sysclk_init();
+ *
+ * board_init();
+ *
+ * pmc_enable_periph_clk(ID_GMAC);
+ *
+ * gmac_option.uc_copy_all_frame = 0;
+ * gmac_option.uc_no_boardcast = 0;
+ * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
+ * gs_gmac_dev.p_hw = GMAC;
+ *
+ * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
+ *
+ * NVIC_EnableIRQ(GMAC_IRQn);
+ *
+ * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
+ *
+ * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
+ *
+ * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
+ * \endcode
+ *
+ * \subsection gmac_basic_use_case_setup_flow Workflow
+ * - Ensure that conf_eth.h is present and contains the
+ * following configuration symbol. This configuration file is used
+ * by the driver and should not be included by the application.
+ * -# Define the receiving buffer size used in the internal GMAC driver.
+ * The buffer size used for RX is GMAC_RX_BUFFERS * 128.
+ * If it was supposed receiving a large number of frame, the
+ * GMAC_RX_BUFFERS should be set higher. E.g., the application wants to accept
+ * a ping echo test of 2048, the GMAC_RX_BUFFERS should be set at least
+ * (2048/128)=16, and as there are additional frames coming, a preferred
+ * number is 24 depending on a normal Ethernet throughput.
+ * - \code
+ * #define GMAC_RX_BUFFERS 16
+ * \endcode
+ * -# Define the transmitting buffer size used in the internal GMAC driver.
+ * The buffer size used for TX is GMAC_TX_BUFFERS * 1518.
+ * - \code
+ * #define GMAC_TX_BUFFERS 8
+ * \endcode
+ * -# Define maximum retry time for a PHY read/write operation.
+ * - \code
+ * #define MAC_PHY_RETRY_MAX 1000000
+ * \endcode
+ * -# Define the MAC address. 00:04:25:1C:A0:02 is the address reserved
+ * for ATMEL, application should always change this address to its' own.
+ * - \code
+ * #define ETHERNET_CONF_ETHADDR0 0x00
+ * #define ETHERNET_CONF_ETHADDR1 0x04
+ * #define ETHERNET_CONF_ETHADDR2 0x25
+ * #define ETHERNET_CONF_ETHADDR3 0x1C
+ * #define ETHERNET_CONF_ETHADDR4 0xA0
+ * #define ETHERNET_CONF_ETHADDR5 0x02
+ * \endcode
+ * -# Define the IP address configration used in the application. When DHCP
+ * is enabled, this configuration is not effected.
+ * - \code
+ * #define ETHERNET_CONF_IPADDR0 192
+ * #define ETHERNET_CONF_IPADDR1 168
+ * #define ETHERNET_CONF_IPADDR2 0
+ * #define ETHERNET_CONF_IPADDR3 2
+ * #define ETHERNET_CONF_GATEWAY_ADDR0 192
+ * #define ETHERNET_CONF_GATEWAY_ADDR1 168
+ * #define ETHERNET_CONF_GATEWAY_ADDR2 0
+ * #define ETHERNET_CONF_GATEWAY_ADDR3 1
+ * #define ETHERNET_CONF_NET_MASK0 255
+ * #define ETHERNET_CONF_NET_MASK1 255
+ * #define ETHERNET_CONF_NET_MASK2 255
+ * #define ETHERNET_CONF_NET_MASK3 0
+ * \endcode
+ * -# Configure the PHY maintainance interface.
+ * - \code
+ * #define ETH_PHY_MODE GMAC_PHY_MII
+ * \endcode
+ * -# Enable the system clock:
+ * - \code sysclk_init(); \endcode
+ * -# Enable PIO configurations for GMAC:
+ * - \code board_init(); \endcode
+ * -# Enable PMC clock for GMAC:
+ * - \code pmc_enable_periph_clk(ID_GMAC); \endcode
+ * -# Set the GMAC options; it's set to copy all frame and support broadcast:
+ * - \code
+ * gmac_option.uc_copy_all_frame = 0;
+ * gmac_option.uc_no_boardcast = 0;
+ * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
+ * gs_gmac_dev.p_hw = GMAC;
+ * \endcode
+ * -# Initialize GMAC device with the filled option:
+ * - \code
+ * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
+ * \endcode
+ * -# Enable the interrupt service for GMAC:
+ * - \code
+ * NVIC_EnableIRQ(GMAC_IRQn);
+ * \endcode
+ * -# Initialize the PHY component:
+ * - \code
+ * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
+ * \endcode
+ * -# The link will be established based on auto negotiation.
+ * - \code
+ * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
+ * \endcode
+ * -# Establish the ethernet link; the network can be worked from now on:
+ * - \code
+ * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
+ * \endcode
+ *
+ * \section gmac_basic_use_case_usage Usage steps
+ * \subsection gmac_basic_use_case_usage_code Example code
+ * Add to, e.g., main loop in application C-file:
+ * \code
+ * gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size));
+ * \endcode
+ *
+ * \subsection gmac_basic_use_case_usage_flow Workflow
+ * -# Start reading the data from the ethernet:
+ * - \code gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size)); \endcode
+ */
+
+# define GMAC_STATS 0
+
+#if( GMAC_STATS != 0 )
+
+ /* Here below some code to study the types and
+ frequencies of GMAC interrupts. */
+ #define GMAC_IDX_RXUBR 0
+ #define GMAC_IDX_TUR 1
+ #define GMAC_IDX_RLEX 2
+ #define GMAC_IDX_TFC 3
+ #define GMAC_IDX_RCOMP 4
+ #define GMAC_IDX_TCOMP 5
+ #define GMAC_IDX_ROVR 6
+ #define GMAC_IDX_HRESP 7
+ #define GMAC_IDX_PFNZ 8
+ #define GMAC_IDX_PTZ 9
+
+ struct SGmacStats {
+ unsigned recvCount;
+ unsigned rovrCount;
+ unsigned bnaCount;
+ unsigned sendCount;
+ unsigned sovrCount;
+ unsigned incompCount;
+ unsigned truncCount;
+
+ unsigned intStatus[10];
+ };
+ extern struct SGmacStats gmacStats;
+
+ struct SIntPair {
+ const char *name;
+ unsigned mask;
+ int index;
+ };
+
+ #define MK_PAIR( NAME ) #NAME, GMAC_IER_##NAME, GMAC_IDX_##NAME
+ static const struct SIntPair intPairs[] = {
+ { MK_PAIR( RXUBR ) }, /* Enable receive used bit read interrupt. */
+ { MK_PAIR( TUR ) }, /* Enable transmit underrun interrupt. */
+ { MK_PAIR( RLEX ) }, /* Enable retry limit exceeded interrupt. */
+ { MK_PAIR( TFC ) }, /* Enable transmit buffers exhausted in mid-frame interrupt. */
+ { MK_PAIR( RCOMP ) }, /* Receive complete */
+ { MK_PAIR( TCOMP ) }, /* Enable transmit complete interrupt. */
+ { MK_PAIR( ROVR ) }, /* Enable receive overrun interrupt. */
+ { MK_PAIR( HRESP ) }, /* Enable Hresp not OK interrupt. */
+ { MK_PAIR( PFNZ ) }, /* Enable pause frame received interrupt. */
+ { MK_PAIR( PTZ ) } /* Enable pause time zero interrupt. */
+ };
+
+ void gmac_show_irq_counts ();
+
+#endif
+
+#endif /* GMAC_H_INCLUDED */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c
index 7cee711cd..e0d04e454 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c
@@ -1,267 +1,267 @@
-/*
-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. */
-#include <stdint.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* Hardware abstraction. */
-#include "FreeRTOS_IO.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "NetworkBufferManagement.h"
-
-/* Driver includes. */
-#include "lpc17xx_emac.h"
-#include "lpc17xx_pinsel.h"
-
-/* Demo includes. */
-#include "NetworkInterface.h"
-
-#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES != 1
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
-#else
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
-#endif
-
-/* When a packet is ready to be sent, if it cannot be sent immediately then the
-task performing the transmit will block for niTX_BUFFER_FREE_WAIT
-milliseconds. It will do this a maximum of niMAX_TX_ATTEMPTS before giving
-up. */
-#define niTX_BUFFER_FREE_WAIT ( pdMS_TO_TICKS( 2UL ) )
-#define niMAX_TX_ATTEMPTS ( 5 )
-
-/* The length of the queue used to send interrupt status words from the
-interrupt handler to the deferred handler task. */
-#define niINTERRUPT_QUEUE_LENGTH ( 10 )
-
-/*-----------------------------------------------------------*/
-
-/*
- * A deferred interrupt handler task that processes
- */
-static void prvEMACHandlerTask( void *pvParameters );
-
-/*-----------------------------------------------------------*/
-
-/* The queue used to communicate Ethernet events with the IP task. */
-extern QueueHandle_t xNetworkEventQueue;
-
-/* The semaphore used to wake the deferred interrupt handler task when an Rx
-interrupt is received. */
-static SemaphoreHandle_t xEMACRxEventSemaphore = NULL;
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-EMAC_CFG_Type Emac_Config;
-PINSEL_CFG_Type xPinConfig;
-BaseType_t xStatus, xReturn;
-extern uint8_t ucMACAddress[ 6 ];
-
- /* Enable Ethernet Pins */
- boardCONFIGURE_ENET_PINS( xPinConfig );
-
- Emac_Config.Mode = EMAC_MODE_AUTO;
- Emac_Config.pbEMAC_Addr = ucMACAddress;
- xStatus = EMAC_Init( &Emac_Config );
-
- LPC_EMAC->IntEnable &= ~( EMAC_INT_TX_DONE );
-
- if( xStatus != ERROR )
- {
- vSemaphoreCreateBinary( xEMACRxEventSemaphore );
- configASSERT( xEMACRxEventSemaphore );
-
- /* The handler task is created at the highest possible priority to
- ensure the interrupt handler can return directly to it. */
- xTaskCreate( prvEMACHandlerTask, "EMAC", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
-
- /* Enable the interrupt and set its priority to the minimum
- interrupt priority. */
- NVIC_SetPriority( ENET_IRQn, configMAC_INTERRUPT_PRIORITY );
- NVIC_EnableIRQ( ENET_IRQn );
-
- xReturn = pdPASS;
- }
- else
- {
- xReturn = pdFAIL;
- }
-
- configASSERT( xStatus != ERROR );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer )
-{
-BaseType_t xReturn = pdFAIL;
-int32_t x;
-extern void EMAC_StartTransmitNextBuffer( uint32_t ulLength );
-extern void EMAC_SetNextPacketToSend( uint8_t * pucBuffer );
-
-
- /* Attempt to obtain access to a Tx buffer. */
- for( x = 0; x < niMAX_TX_ATTEMPTS; x++ )
- {
- if( EMAC_CheckTransmitIndex() == TRUE )
- {
- /* Will the data fit in the Tx buffer? */
- if( pxNetworkBuffer->xDataLength < EMAC_ETH_MAX_FLEN ) /*_RB_ The size needs to come from FreeRTOSIPConfig.h. */
- {
- /* Assign the buffer to the Tx descriptor that is now known to
- be free. */
- EMAC_SetNextPacketToSend( pxNetworkBuffer->pucBuffer );
-
- /* The EMAC now owns the buffer. */
- pxNetworkBuffer->pucBuffer = NULL;
-
- /* Initiate the Tx. */
- EMAC_StartTransmitNextBuffer( pxNetworkBuffer->xDataLength );
- iptraceNETWORK_INTERFACE_TRANSMIT();
-
- /* The Tx has been initiated. */
- xReturn = pdPASS;
- }
- break;
- }
- else
- {
- vTaskDelay( niTX_BUFFER_FREE_WAIT );
- }
- }
-
- /* Finished with the network buffer. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-void ENET_IRQHandler( void )
-{
-uint32_t ulInterruptCause;
-
- while( ( ulInterruptCause = LPC_EMAC->IntStatus ) != 0 )
- {
- /* Clear the interrupt. */
- LPC_EMAC->IntClear = ulInterruptCause;
-
- /* Clear fatal error conditions. NOTE: The driver does not clear all
- errors, only those actually experienced. For future reference, range
- errors are not actually errors so can be ignored. */
- if( ( ulInterruptCause & EMAC_INT_TX_UNDERRUN ) != 0U )
- {
- LPC_EMAC->Command |= EMAC_CR_TX_RES;
- }
-
- /* Unblock the deferred interrupt handler task if the event was an
- Rx. */
- if( ( ulInterruptCause & EMAC_INT_RX_DONE ) != 0UL )
- {
- xSemaphoreGiveFromISR( xEMACRxEventSemaphore, NULL );
- }
- }
-
- /* ulInterruptCause is used for convenience here. A context switch is
- wanted, but coding portEND_SWITCHING_ISR( 1 ) would likely result in a
- compiler warning. */
- portEND_SWITCHING_ISR( ulInterruptCause );
-}
-/*-----------------------------------------------------------*/
-
-static void prvEMACHandlerTask( void *pvParameters )
-{
-size_t xDataLength;
-const uint16_t usCRCLength = 4;
-NetworkBufferDescriptor_t *pxNetworkBuffer;
-IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-
-/* This is not included in the header file for some reason. */
-extern uint8_t *EMAC_NextPacketToRead( void );
-
- ( void ) pvParameters;
- configASSERT( xEMACRxEventSemaphore );
-
- for( ;; )
- {
- /* Wait for the EMAC interrupt to indicate that another packet has been
- received. The while() loop is only needed if INCLUDE_vTaskSuspend is
- set to 0 in FreeRTOSConfig.h. */
- while( xSemaphoreTake( xEMACRxEventSemaphore, portMAX_DELAY ) == pdFALSE );
-
- /* At least one packet has been received. */
- while( EMAC_CheckReceiveIndex() != FALSE )
- {
- /* Obtain the length, minus the CRC. The CRC is four bytes
- but the length is already minus 1. */
- xDataLength = ( size_t ) EMAC_GetReceiveDataSize() - ( usCRCLength - 1U );
-
- if( xDataLength > 0U )
- {
- /* Obtain a network buffer to pass this data into the
- stack. No storage is required as the network buffer
- will point directly to the buffer that already holds
- the received data. */
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( 0, ( TickType_t ) 0 );
-
- if( pxNetworkBuffer != NULL )
- {
- pxNetworkBuffer->pucBuffer = EMAC_NextPacketToRead();
- pxNetworkBuffer->xDataLength = xDataLength;
- xRxEvent.pvData = ( void * ) pxNetworkBuffer;
-
- /* Data was received and stored. Send a message to the IP
- task to let it know. */
- if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- iptraceETHERNET_RX_EVENT_LOST();
- }
- }
- else
- {
- iptraceETHERNET_RX_EVENT_LOST();
- }
-
- iptraceNETWORK_INTERFACE_RECEIVE();
- }
-
- /* Release the frame. */
- EMAC_UpdateRxConsumeIndex();
- }
- }
-}
-/*-----------------------------------------------------------*/
-
+/*
+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. */
+#include <stdint.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* Hardware abstraction. */
+#include "FreeRTOS_IO.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "NetworkBufferManagement.h"
+
+/* Driver includes. */
+#include "lpc17xx_emac.h"
+#include "lpc17xx_pinsel.h"
+
+/* Demo includes. */
+#include "NetworkInterface.h"
+
+#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES != 1
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+#else
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+#endif
+
+/* When a packet is ready to be sent, if it cannot be sent immediately then the
+task performing the transmit will block for niTX_BUFFER_FREE_WAIT
+milliseconds. It will do this a maximum of niMAX_TX_ATTEMPTS before giving
+up. */
+#define niTX_BUFFER_FREE_WAIT ( pdMS_TO_TICKS( 2UL ) )
+#define niMAX_TX_ATTEMPTS ( 5 )
+
+/* The length of the queue used to send interrupt status words from the
+interrupt handler to the deferred handler task. */
+#define niINTERRUPT_QUEUE_LENGTH ( 10 )
+
+/*-----------------------------------------------------------*/
+
+/*
+ * A deferred interrupt handler task that processes
+ */
+static void prvEMACHandlerTask( void *pvParameters );
+
+/*-----------------------------------------------------------*/
+
+/* The queue used to communicate Ethernet events with the IP task. */
+extern QueueHandle_t xNetworkEventQueue;
+
+/* The semaphore used to wake the deferred interrupt handler task when an Rx
+interrupt is received. */
+static SemaphoreHandle_t xEMACRxEventSemaphore = NULL;
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+EMAC_CFG_Type Emac_Config;
+PINSEL_CFG_Type xPinConfig;
+BaseType_t xStatus, xReturn;
+extern uint8_t ucMACAddress[ 6 ];
+
+ /* Enable Ethernet Pins */
+ boardCONFIGURE_ENET_PINS( xPinConfig );
+
+ Emac_Config.Mode = EMAC_MODE_AUTO;
+ Emac_Config.pbEMAC_Addr = ucMACAddress;
+ xStatus = EMAC_Init( &Emac_Config );
+
+ LPC_EMAC->IntEnable &= ~( EMAC_INT_TX_DONE );
+
+ if( xStatus != ERROR )
+ {
+ vSemaphoreCreateBinary( xEMACRxEventSemaphore );
+ configASSERT( xEMACRxEventSemaphore );
+
+ /* The handler task is created at the highest possible priority to
+ ensure the interrupt handler can return directly to it. */
+ xTaskCreate( prvEMACHandlerTask, "EMAC", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
+
+ /* Enable the interrupt and set its priority to the minimum
+ interrupt priority. */
+ NVIC_SetPriority( ENET_IRQn, configMAC_INTERRUPT_PRIORITY );
+ NVIC_EnableIRQ( ENET_IRQn );
+
+ xReturn = pdPASS;
+ }
+ else
+ {
+ xReturn = pdFAIL;
+ }
+
+ configASSERT( xStatus != ERROR );
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer )
+{
+BaseType_t xReturn = pdFAIL;
+int32_t x;
+extern void EMAC_StartTransmitNextBuffer( uint32_t ulLength );
+extern void EMAC_SetNextPacketToSend( uint8_t * pucBuffer );
+
+
+ /* Attempt to obtain access to a Tx buffer. */
+ for( x = 0; x < niMAX_TX_ATTEMPTS; x++ )
+ {
+ if( EMAC_CheckTransmitIndex() == TRUE )
+ {
+ /* Will the data fit in the Tx buffer? */
+ if( pxNetworkBuffer->xDataLength < EMAC_ETH_MAX_FLEN ) /*_RB_ The size needs to come from FreeRTOSIPConfig.h. */
+ {
+ /* Assign the buffer to the Tx descriptor that is now known to
+ be free. */
+ EMAC_SetNextPacketToSend( pxNetworkBuffer->pucBuffer );
+
+ /* The EMAC now owns the buffer. */
+ pxNetworkBuffer->pucBuffer = NULL;
+
+ /* Initiate the Tx. */
+ EMAC_StartTransmitNextBuffer( pxNetworkBuffer->xDataLength );
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+
+ /* The Tx has been initiated. */
+ xReturn = pdPASS;
+ }
+ break;
+ }
+ else
+ {
+ vTaskDelay( niTX_BUFFER_FREE_WAIT );
+ }
+ }
+
+ /* Finished with the network buffer. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+void ENET_IRQHandler( void )
+{
+uint32_t ulInterruptCause;
+
+ while( ( ulInterruptCause = LPC_EMAC->IntStatus ) != 0 )
+ {
+ /* Clear the interrupt. */
+ LPC_EMAC->IntClear = ulInterruptCause;
+
+ /* Clear fatal error conditions. NOTE: The driver does not clear all
+ errors, only those actually experienced. For future reference, range
+ errors are not actually errors so can be ignored. */
+ if( ( ulInterruptCause & EMAC_INT_TX_UNDERRUN ) != 0U )
+ {
+ LPC_EMAC->Command |= EMAC_CR_TX_RES;
+ }
+
+ /* Unblock the deferred interrupt handler task if the event was an
+ Rx. */
+ if( ( ulInterruptCause & EMAC_INT_RX_DONE ) != 0UL )
+ {
+ xSemaphoreGiveFromISR( xEMACRxEventSemaphore, NULL );
+ }
+ }
+
+ /* ulInterruptCause is used for convenience here. A context switch is
+ wanted, but coding portEND_SWITCHING_ISR( 1 ) would likely result in a
+ compiler warning. */
+ portEND_SWITCHING_ISR( ulInterruptCause );
+}
+/*-----------------------------------------------------------*/
+
+static void prvEMACHandlerTask( void *pvParameters )
+{
+size_t xDataLength;
+const uint16_t usCRCLength = 4;
+NetworkBufferDescriptor_t *pxNetworkBuffer;
+IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+
+/* This is not included in the header file for some reason. */
+extern uint8_t *EMAC_NextPacketToRead( void );
+
+ ( void ) pvParameters;
+ configASSERT( xEMACRxEventSemaphore );
+
+ for( ;; )
+ {
+ /* Wait for the EMAC interrupt to indicate that another packet has been
+ received. The while() loop is only needed if INCLUDE_vTaskSuspend is
+ set to 0 in FreeRTOSConfig.h. */
+ while( xSemaphoreTake( xEMACRxEventSemaphore, portMAX_DELAY ) == pdFALSE );
+
+ /* At least one packet has been received. */
+ while( EMAC_CheckReceiveIndex() != FALSE )
+ {
+ /* Obtain the length, minus the CRC. The CRC is four bytes
+ but the length is already minus 1. */
+ xDataLength = ( size_t ) EMAC_GetReceiveDataSize() - ( usCRCLength - 1U );
+
+ if( xDataLength > 0U )
+ {
+ /* Obtain a network buffer to pass this data into the
+ stack. No storage is required as the network buffer
+ will point directly to the buffer that already holds
+ the received data. */
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( 0, ( TickType_t ) 0 );
+
+ if( pxNetworkBuffer != NULL )
+ {
+ pxNetworkBuffer->pucBuffer = EMAC_NextPacketToRead();
+ pxNetworkBuffer->xDataLength = xDataLength;
+ xRxEvent.pvData = ( void * ) pxNetworkBuffer;
+
+ /* Data was received and stored. Send a message to the IP
+ task to let it know. */
+ if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+ }
+ else
+ {
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ }
+
+ /* Release the frame. */
+ EMAC_UpdateRxConsumeIndex();
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/NetworkInterface.c
index 0b1f74d07..ac01d41af 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/NetworkInterface.c
@@ -1,1068 +1,1068 @@
-/*
-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. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-/* LPCOpen includes. */
-#include "chip.h"
-#include "lpc_phy.h"
-
-/* The size of the stack allocated to the task that handles Rx packets. */
-#define nwRX_TASK_STACK_SIZE 140
-
-#ifndef PHY_LS_HIGH_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
- receiving packets. */
- #define PHY_LS_HIGH_CHECK_TIME_MS 15000
-#endif
-
-#ifndef PHY_LS_LOW_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still low every second. */
- #define PHY_LS_LOW_CHECK_TIME_MS 1000
-#endif
-
-#ifndef configUSE_RMII
- #define configUSE_RMII 1
-#endif
-
-#ifndef configNUM_RX_DESCRIPTORS
- #error please define configNUM_RX_DESCRIPTORS in your FreeRTOSIPConfig.h
-#endif
-
-#ifndef configNUM_TX_DESCRIPTORS
- #error please define configNUM_TX_DESCRIPTORS in your FreeRTOSIPConfig.h
-#endif
-
-#ifndef NETWORK_IRQHandler
- #error NETWORK_IRQHandler must be defined to the name of the function that is installed in the interrupt vector table to handle Ethernet interrupts.
-#endif
-
-#if !defined( MAC_FF_HMC )
- /* Hash for multicast. */
- #define MAC_FF_HMC ( 1UL << 2UL )
-#endif
-
-#ifndef iptraceEMAC_TASK_STARTING
- #define iptraceEMAC_TASK_STARTING() do { } while( 0 )
-#endif
-
-/* Define the bits of .STATUS that indicate a reception error. */
-#define nwRX_STATUS_ERROR_BITS \
- ( RDES_CE /* CRC Error */ | \
- RDES_RE /* Receive Error */ | \
- RDES_DE /* Descriptor Error */ | \
- RDES_RWT /* Receive Watchdog Timeout */ | \
- RDES_LC /* Late Collision */ | \
- RDES_OE /* Overflow Error */ | \
- RDES_SAF /* Source Address Filter Fail */ | \
- RDES_AFM /* Destination Address Filter Fail */ | \
- RDES_LE /* Length Error */ )
-
-/* Define the EMAC status bits that should trigger an interrupt. */
-#define nwDMA_INTERRUPT_MASK \
- ( DMA_IE_TIE /* Transmit interrupt enable */ | \
- DMA_IE_TSE /* Transmit stopped enable */ | \
- DMA_IE_OVE /* Overflow interrupt enable */ | \
- DMA_IE_RIE /* Receive interrupt enable */ | \
- DMA_IE_NIE /* Normal interrupt summary enable */ | \
- DMA_IE_AIE /* Abnormal interrupt summary enable */ | \
- DMA_IE_RUE /* Receive buffer unavailable enable */ | \
- DMA_IE_UNE /* Underflow interrupt enable. */ | \
- DMA_IE_TJE /* Transmit jabber timeout enable */ | \
- DMA_IE_RSE /* Received stopped enable */ | \
- DMA_IE_RWE /* Receive watchdog timeout enable */ | \
- DMA_IE_FBE )/* Fatal bus error enable */
-
-/* Interrupt events to process. Currently only the RX/TX events are processed
-although code for other events is included to allow for possible future
-expansion. */
-#define EMAC_IF_RX_EVENT 1UL
-#define EMAC_IF_TX_EVENT 2UL
-#define EMAC_IF_ERR_EVENT 4UL
-#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
-
- /* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
- driver will filter incoming packets and only pass the stack those packets it
- considers need processing. */
- #if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
- #else
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
- #endif
-
-#if( ipconfigZERO_COPY_RX_DRIVER == 0 ) || ( ipconfigZERO_COPY_TX_DRIVER == 0 )
- #warning It is adviced to enable both macros
-#endif
-
-#ifndef configPLACE_IN_SECTION_RAM
- #define configPLACE_IN_SECTION_RAM
-/*
- #define configPLACE_IN_SECTION_RAM __attribute__ ((section(".ramfunc")))
-*/
-#endif
-
-/*-----------------------------------------------------------*/
-
-/*
- * Delay function passed into the library. The implementation uses FreeRTOS
- * calls so the scheduler must be started before the driver can be used.
- */
-static void prvDelay( uint32_t ulMilliSeconds );
-
-/*
- * Initialises the Tx and Rx descriptors respectively.
- */
-static void prvSetupTxDescriptors( void );
-static void prvSetupRxDescriptors( void );
-
-/*
- * A task that processes received frames.
- */
-static void prvEMACHandlerTask( void *pvParameters );
-
-/*
- * Sets up the MAC with the results of an auto-negotiation.
- */
-static BaseType_t prvSetLinkSpeed( void );
-
-/*
- * Generates a CRC for a MAC address that is then used to generate a hash index.
- */
-static uint32_t prvGenerateCRC32( const uint8_t *ucAddress );
-
-/*
- * Generates a hash index when setting a filter to permit a MAC address.
- */
-static uint32_t prvGetHashIndex( const uint8_t *ucAddress );
-
-/*
- * Update the hash table to allow a MAC address.
- */
-static void prvAddMACAddress( const uint8_t* ucMacAddress );
-
-/*
- * Sometimes the DMA will report received data as being longer than the actual
- * received from length. This function checks the reported length and corrects
- * if if necessary.
- */
-static void prvRemoveTrailingBytes( NetworkBufferDescriptor_t *pxDescriptor );
-
-/*-----------------------------------------------------------*/
-
-/* Bit map of outstanding ETH interrupt events for processing. Currently only
-the Rx and Tx interrupt is handled, although code is included for other events
-to enable future expansion. */
-static volatile uint32_t ulISREvents;
-
-/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
-static uint32_t ulPHYLinkStatus = 0;
-
-/* Tx descriptors and index. */
-static ENET_ENHTXDESC_T xDMATxDescriptors[ configNUM_TX_DESCRIPTORS ];
-
-/* ulNextFreeTxDescriptor is declared volatile, because it is accessed from
-to different tasks. */
-static volatile uint32_t ulNextFreeTxDescriptor;
-static uint32_t ulTxDescriptorToClear;
-
-/* Rx descriptors and index. */
-static ENET_ENHRXDESC_T xDMARxDescriptors[ configNUM_RX_DESCRIPTORS ];
-static uint32_t ulNextRxDescriptorToProcess;
-
-/* Must be defined externally - the demo applications define this in main.c. */
-extern uint8_t ucMACAddress[ 6 ];
-
-/* The handle of the task that processes Rx packets. The handle is required so
-the task can be notified when new packets arrive. */
-static TaskHandle_t xRxHanderTask = NULL;
-
-#if( ipconfigUSE_LLMNR == 1 )
- static const uint8_t xLLMNR_MACAddress[] = { '\x01', '\x00', '\x5E', '\x00', '\x00', '\xFC' };
-#endif /* ipconfigUSE_LLMNR == 1 */
-
-/* xTXDescriptorSemaphore is a counting semaphore with
-a maximum count of ETH_TXBUFNB, which is the number of
-DMA TX descriptors. */
-static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
-
-/*-----------------------------------------------------------*/
-
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-BaseType_t xReturn = pdPASS;
-
- /* The interrupt will be turned on when a link is established. */
- NVIC_DisableIRQ( ETHERNET_IRQn );
-
- /* Disable receive and transmit DMA processes. */
- LPC_ETHERNET->DMA_OP_MODE &= ~( DMA_OM_ST | DMA_OM_SR );
-
- /* Disable packet reception. */
- LPC_ETHERNET->MAC_CONFIG &= ~( MAC_CFG_RE | MAC_CFG_TE );
-
- /* Call the LPCOpen function to initialise the hardware. */
- Chip_ENET_Init( LPC_ETHERNET );
-
- /* Save MAC address. */
- Chip_ENET_SetADDR( LPC_ETHERNET, ucMACAddress );
-
- /* Clear all MAC address hash entries. */
- LPC_ETHERNET->MAC_HASHTABLE_HIGH = 0;
- LPC_ETHERNET->MAC_HASHTABLE_LOW = 0;
-
- #if( ipconfigUSE_LLMNR == 1 )
- {
- prvAddMACAddress( xLLMNR_MACAddress );
- }
- #endif /* ipconfigUSE_LLMNR == 1 */
-
- /* Promiscuous flag (PR) and Receive All flag (RA) set to zero. The
- registers MAC_HASHTABLE_[LOW|HIGH] will be loaded to allow certain
- multi-cast addresses. */
- LPC_ETHERNET->MAC_FRAME_FILTER = MAC_FF_HMC;
-
- #if( configUSE_RMII == 1 )
- {
- if( lpc_phy_init( pdTRUE, prvDelay ) != SUCCESS )
- {
- xReturn = pdFAIL;
- }
- }
- #else
- {
- #warning This path has not been tested.
- if( lpc_phy_init( pdFALSE, prvDelay ) != SUCCESS )
- {
- xReturn = pdFAIL;
- }
- }
- #endif
-
- if( xReturn == pdPASS )
- {
- /* Guard against the task being created more than once and the
- descriptors being initialised more than once. */
- if( xRxHanderTask == NULL )
- {
- xReturn = xTaskCreate( prvEMACHandlerTask, "EMAC", nwRX_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xRxHanderTask );
- configASSERT( xReturn );
- }
-
- if( xTXDescriptorSemaphore == NULL )
- {
- /* Create a counting semaphore, with a value of 'configNUM_TX_DESCRIPTORS'
- and a maximum of 'configNUM_TX_DESCRIPTORS'. */
- xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) configNUM_TX_DESCRIPTORS, ( UBaseType_t ) configNUM_TX_DESCRIPTORS );
- configASSERT( xTXDescriptorSemaphore );
- }
-
- /* Enable MAC interrupts. */
- LPC_ETHERNET->DMA_INT_EN = nwDMA_INTERRUPT_MASK;
- }
-
- if( xReturn != pdFAIL )
- {
- /* Auto-negotiate was already started. Wait for it to complete. */
- xReturn = prvSetLinkSpeed();
-
- if( xReturn == pdPASS )
- {
- /* Initialise the descriptors. */
- prvSetupTxDescriptors();
- prvSetupRxDescriptors();
-
- /* Clear all interrupts. */
- LPC_ETHERNET->DMA_STAT = DMA_ST_ALL;
-
- /* Enable receive and transmit DMA processes. */
- LPC_ETHERNET->DMA_OP_MODE |= DMA_OM_ST | DMA_OM_SR;
-
- /* Set Receiver / Transmitter Enable. */
- LPC_ETHERNET->MAC_CONFIG |= MAC_CFG_RE | MAC_CFG_TE;
-
- /* Start receive polling. */
- LPC_ETHERNET->DMA_REC_POLL_DEMAND = 1;
-
- /* Enable interrupts in the NVIC. */
- NVIC_SetPriority( ETHERNET_IRQn, configMAC_INTERRUPT_PRIORITY );
- NVIC_EnableIRQ( ETHERNET_IRQn );
- }
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-#define niBUFFER_1_PACKET_SIZE 1536
-
-static __attribute__ ((section("._ramAHB32"))) uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
-
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
-
-uint8_t *ucRAMBuffer = ucNetworkPackets;
-uint32_t ul;
-
- for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
- {
- pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
- *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
- ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
- }
-}
-/*-----------------------------------------------------------*/
-
-configPLACE_IN_SECTION_RAM
-static void vClearTXBuffers()
-{
-uint32_t ulLastDescriptor = ulNextFreeTxDescriptor;
-size_t uxCount = ( ( size_t ) configNUM_TX_DESCRIPTORS ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- NetworkBufferDescriptor_t *pxNetworkBuffer;
- uint8_t *ucPayLoad;
-#endif
-
- /* This function is called after a TX-completion interrupt.
- It will release each Network Buffer used in xNetworkInterfaceOutput().
- 'uxCount' represents the number of descriptors given to DMA for transmission.
- After sending a packet, the DMA will clear the 'TDES_OWN' bit. */
- while( ( uxCount > ( size_t ) 0u ) && ( ( xDMATxDescriptors[ ulTxDescriptorToClear ].CTRLSTAT & TDES_OWN ) == 0 ) )
- {
- if( ( ulTxDescriptorToClear == ulLastDescriptor ) && ( uxCount != ( size_t ) configNUM_TX_DESCRIPTORS ) )
- {
- break;
- }
-
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- ucPayLoad = ( uint8_t * )xDMATxDescriptors[ ulTxDescriptorToClear ].B1ADD;
- if( ucPayLoad != NULL )
- {
- /* B1ADD points to a pucEthernetBuffer of a Network Buffer descriptor. */
- pxNetworkBuffer = pxPacketBuffer_to_NetworkBuffer( ucPayLoad );
-
- configASSERT( pxNetworkBuffer != NULL );
-
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer ) ;
- xDMATxDescriptors[ ulTxDescriptorToClear ].B1ADD = ( uint32_t )0u;
- }
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
-
- /* Move onto the next descriptor, wrapping if necessary. */
- ulTxDescriptorToClear++;
- if( ulTxDescriptorToClear >= configNUM_TX_DESCRIPTORS )
- {
- ulTxDescriptorToClear = 0;
- }
-
- uxCount--;
- /* Tell the counting semaphore that one more TX descriptor is available. */
- xSemaphoreGive( xTXDescriptorSemaphore );
- }
-}
-
-/*-----------------------------------------------------------*/
-
-configPLACE_IN_SECTION_RAM
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t bReleaseAfterSend )
-{
-BaseType_t xReturn = pdFAIL;
-const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50 );
-
- /* Attempt to obtain access to a Tx descriptor. */
- do
- {
- if( xTXDescriptorSemaphore == NULL )
- {
- break;
- }
- if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
- {
- /* Time-out waiting for a free TX descriptor. */
- break;
- }
-
- /* If the descriptor is still owned by the DMA it can't be used. */
- if( ( xDMATxDescriptors[ ulNextFreeTxDescriptor ].CTRLSTAT & TDES_OWN ) != 0 )
- {
- /* The semaphore was taken, the TX DMA-descriptor is still not available.
- Actually that should not occur, the 'TDES_OWN' was already confirmed low in vClearTXBuffers(). */
- xSemaphoreGive( xTXDescriptorSemaphore );
- }
- else
- {
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* bReleaseAfterSend should always be set when using the zero
- copy driver. */
- configASSERT( bReleaseAfterSend != pdFALSE );
-
- /* The DMA's descriptor to point directly to the data in the
- network buffer descriptor. The data is not copied. */
- xDMATxDescriptors[ ulNextFreeTxDescriptor ].B1ADD = ( uint32_t ) pxDescriptor->pucEthernetBuffer;
-
- /* The DMA descriptor will 'own' this Network Buffer,
- until it has been sent. So don't release it now. */
- bReleaseAfterSend = false;
- }
- #else
- {
- /* The data is copied from the network buffer descriptor into
- the DMA's descriptor. */
- memcpy( ( void * ) xDMATxDescriptors[ ulNextFreeTxDescriptor ].B1ADD, ( void * ) pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength );
- }
- #endif
-
- xDMATxDescriptors[ ulNextFreeTxDescriptor ].BSIZE = ( uint32_t ) TDES_ENH_BS1( pxDescriptor->xDataLength );
-
- /* This descriptor is given back to the DMA. */
- xDMATxDescriptors[ ulNextFreeTxDescriptor ].CTRLSTAT |= TDES_OWN;
-
- /* Ensure the DMA is polling Tx descriptors. */
- LPC_ETHERNET->DMA_TRANS_POLL_DEMAND = 1;
-
- iptraceNETWORK_INTERFACE_TRANSMIT();
-
- /* Move onto the next descriptor, wrapping if necessary. */
- ulNextFreeTxDescriptor++;
- if( ulNextFreeTxDescriptor >= configNUM_TX_DESCRIPTORS )
- {
- ulNextFreeTxDescriptor = 0;
- }
-
- /* The Tx has been initiated. */
- xReturn = pdPASS;
- }
- } while( 0 );
-
- /* The buffer has been sent so can be released. */
- if( bReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static void prvDelay( uint32_t ulMilliSeconds )
-{
- /* Ensure the scheduler was started before attempting to use the scheduler to
- create a delay. */
- configASSERT( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING );
-
- vTaskDelay( pdMS_TO_TICKS( ulMilliSeconds ) );
-}
-/*-----------------------------------------------------------*/
-
-static void prvSetupTxDescriptors( void )
-{
-BaseType_t x;
-
- /* Start with Tx descriptors clear. */
- memset( ( void * ) xDMATxDescriptors, 0, sizeof( xDMATxDescriptors ) );
-
- /* Index to the next Tx descriptor to use. */
- ulNextFreeTxDescriptor = 0ul;
-
- /* Index to the next Tx descriptor to clear ( after transmission ). */
- ulTxDescriptorToClear = 0ul;
-
- for( x = 0; x < configNUM_TX_DESCRIPTORS; x++ )
- {
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* Nothing to do, B1ADD will be set when data is ready to transmit.
- Currently the memset above will have set it to NULL. */
- }
- #else
- {
- /* Allocate a buffer to the Tx descriptor. This is the most basic
- way of creating a driver as the data is then copied into the
- buffer. */
- xDMATxDescriptors[ x ].B1ADD = ( uint32_t ) pvPortMalloc( ipTOTAL_ETHERNET_FRAME_SIZE );
-
- /* Use an assert to check the allocation as +TCP applications will
- often not use a malloc() failed hook as the TCP stack will recover
- from allocation failures. */
- configASSERT( xDMATxDescriptors[ x ].B1ADD );
- }
- #endif
-
- /* Buffers hold an entire frame so all buffers are both the start and
- end of a frame. */
- /* TDES_ENH_TCH Second Address Chained. */
- /* TDES_ENH_CIC(n) Checksum Insertion Control, tried but it does not work for the LPC18xx... */
- /* TDES_ENH_FS First Segment. */
- /* TDES_ENH_LS Last Segment. */
- /* TDES_ENH_IC Interrupt on Completion. */
- xDMATxDescriptors[ x ].CTRLSTAT = TDES_ENH_TCH | TDES_ENH_CIC( 3 ) | TDES_ENH_FS | TDES_ENH_LS | TDES_ENH_IC;
- xDMATxDescriptors[ x ].B2ADD = ( uint32_t ) &xDMATxDescriptors[ x + 1 ];
- }
-
- xDMATxDescriptors[ configNUM_TX_DESCRIPTORS - 1 ].CTRLSTAT |= TDES_ENH_TER;
- xDMATxDescriptors[ configNUM_TX_DESCRIPTORS - 1 ].B2ADD = ( uint32_t ) &xDMATxDescriptors[ 0 ];
-
- /* Point the DMA to the base of the descriptor list. */
- LPC_ETHERNET->DMA_TRANS_DES_ADDR = ( uint32_t ) xDMATxDescriptors;
-}
-/*-----------------------------------------------------------*/
-
-static void prvSetupRxDescriptors( void )
-{
-BaseType_t x;
-#if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- NetworkBufferDescriptor_t *pxNetworkBuffer;
-#endif
-
- /* Index to the next Rx descriptor to use. */
- ulNextRxDescriptorToProcess = 0;
-
- /* Clear RX descriptor list. */
- memset( ( void * ) xDMARxDescriptors, 0, sizeof( xDMARxDescriptors ) );
-
- for( x = 0; x < configNUM_RX_DESCRIPTORS; x++ )
- {
- /* Allocate a buffer of the largest possible frame size as it is not
- known what size received frames will be. */
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- {
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, 0 );
-
- /* During start-up there should be enough Network Buffers available,
- so it is safe to use configASSERT().
- In case this assert fails, please check: configNUM_RX_DESCRIPTORS,
- ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, and in case BufferAllocation_2.c
- is included, check the amount of available heap. */
- configASSERT( pxNetworkBuffer != NULL );
-
- /* Pass the actual buffer to DMA. */
- xDMARxDescriptors[ x ].B1ADD = ( uint32_t ) pxNetworkBuffer->pucEthernetBuffer;
- }
- #else
- {
- /* All DMA descriptors are populated with permanent memory blocks.
- Their contents will be copy to Network Buffers. */
- xDMARxDescriptors[ x ].B1ADD = ( uint32_t ) pvPortMalloc( ipTOTAL_ETHERNET_FRAME_SIZE );
- }
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
-
- /* Use an assert to check the allocation as +TCP applications will often
- not use a malloc failed hook as the TCP stack will recover from
- allocation failures. */
- configASSERT( xDMARxDescriptors[ x ].B1ADD );
-
- xDMARxDescriptors[ x ].B2ADD = ( uint32_t ) &( xDMARxDescriptors[ x + 1 ] );
- xDMARxDescriptors[ x ].CTRL = ( uint32_t ) RDES_ENH_BS1( ipTOTAL_ETHERNET_FRAME_SIZE ) | RDES_ENH_RCH;
-
- /* The descriptor is available for use by the DMA. */
- xDMARxDescriptors[ x ].STATUS = RDES_OWN;
- }
-
- /* RDES_ENH_RER Receive End of Ring. */
- xDMARxDescriptors[ ( configNUM_RX_DESCRIPTORS - 1 ) ].CTRL |= RDES_ENH_RER;
- xDMARxDescriptors[ configNUM_RX_DESCRIPTORS - 1 ].B2ADD = ( uint32_t ) &( xDMARxDescriptors[ 0 ] );
-
- /* Point the DMA to the base of the descriptor list. */
- LPC_ETHERNET->DMA_REC_DES_ADDR = ( uint32_t ) xDMARxDescriptors;
-}
-/*-----------------------------------------------------------*/
-configPLACE_IN_SECTION_RAM
-static void prvRemoveTrailingBytes( NetworkBufferDescriptor_t *pxDescriptor )
-{
-size_t xExpectedLength;
-IPPacket_t *pxIPPacket;
-
- pxIPPacket = ( IPPacket_t * ) pxDescriptor->pucEthernetBuffer;
- /* Look at the actual length of the packet, translate it to a host-endial notation. */
- xExpectedLength = sizeof( EthernetHeader_t ) + ( size_t ) FreeRTOS_htons( pxIPPacket->xIPHeader.usLength );
-
- if( xExpectedLength == ( pxDescriptor->xDataLength + 4 ) )
- {
- pxDescriptor->xDataLength -= 4;
- }
- else
- {
- if( pxDescriptor->xDataLength > xExpectedLength )
- {
- pxDescriptor->xDataLength = ( size_t ) xExpectedLength;
- }
- }
-}
-/*-----------------------------------------------------------*/
-configPLACE_IN_SECTION_RAM
-BaseType_t xGetPhyLinkStatus( void )
-{
-BaseType_t xReturn;
-
- if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) == 0 )
- {
- xReturn = pdFALSE;
- }
- else
- {
- xReturn = pdTRUE;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-uint32_t ulDataAvailable;
-
-configPLACE_IN_SECTION_RAM
-static BaseType_t prvNetworkInterfaceInput()
-{
-BaseType_t xResult = pdFALSE;
-uint32_t ulStatus;
-eFrameProcessingResult_t eResult;
-const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
-const UBaseType_t uxMinimumBuffersRemaining = 3UL;
-uint16_t usLength;
-NetworkBufferDescriptor_t *pxDescriptor;
-#if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- NetworkBufferDescriptor_t *pxNewDescriptor;
-#endif /* ipconfigZERO_COPY_RX_DRIVER */
-#if( ipconfigUSE_LINKED_RX_MESSAGES == 0 )
- IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-#endif
-
- /* Process each descriptor that is not still in use by the DMA. */
- ulStatus = xDMARxDescriptors[ ulNextRxDescriptorToProcess ].STATUS;
- if( ( ulStatus & RDES_OWN ) == 0 )
- {
- /* Check packet for errors */
- if( ( ulStatus & nwRX_STATUS_ERROR_BITS ) != 0 )
- {
- /* There is some reception error. */
- intCount[ 3 ]++;
- /* Clear error bits. */
- ulStatus &= ~( ( uint32_t )nwRX_STATUS_ERROR_BITS );
- }
- else
- {
- xResult++;
-
- eResult = ipCONSIDER_FRAME_FOR_PROCESSING( ( const uint8_t * const ) ( xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD ) );
- if( eResult == eProcessBuffer )
- {
- if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) == 0 )
- {
- ulPHYLinkStatus |= PHY_LINK_CONNECTED;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d (message received)\n", ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != 0 ) );
- }
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- if( uxGetNumberOfFreeNetworkBuffers() > uxMinimumBuffersRemaining )
- {
- pxNewDescriptor = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, xDescriptorWaitTime );
- }
- else
- {
- /* Too risky to allocate a new Network Buffer. */
- pxNewDescriptor = NULL;
- }
- if( pxNewDescriptor != NULL )
- #else
- if( uxGetNumberOfFreeNetworkBuffers() > uxMinimumBuffersRemaining )
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
- {
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- const uint8_t *pucBuffer;
- #endif
-
- /* Get the actual length. */
- usLength = RDES_FLMSK( ulStatus );
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- {
- /* Replace the character buffer 'B1ADD'. */
- pucBuffer = ( const uint8_t * const ) ( xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD );
- xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD = ( uint32_t ) pxNewDescriptor->pucEthernetBuffer;
-
- /* 'B1ADD' contained the address of a 'pucEthernetBuffer' that
- belongs to a Network Buffer. Find the original Network Buffer. */
- pxDescriptor = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
- /* This zero-copy driver makes sure that every 'xDMARxDescriptors' contains
- a reference to a Network Buffer at any time.
- In case it runs out of Network Buffers, a DMA buffer won't be replaced,
- and the received messages is dropped. */
- configASSERT( pxDescriptor != NULL );
- }
- #else
- {
- /* Create a buffer of exactly the required length. */
- pxDescriptor = pxGetNetworkBufferWithDescriptor( usLength, xDescriptorWaitTime );
- }
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
-
- if( pxDescriptor != NULL )
- {
- pxDescriptor->xDataLength = ( size_t ) usLength;
- #if( ipconfigZERO_COPY_RX_DRIVER == 0 )
- {
- /* Copy the data into the allocated buffer. */
- memcpy( ( void * ) pxDescriptor->pucEthernetBuffer, ( void * ) xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD, usLength );
- }
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
- /* It is possible that more data was copied than
- actually makes up the frame. If this is the case
- adjust the length to remove any trailing bytes. */
- prvRemoveTrailingBytes( pxDescriptor );
-
- /* Pass the data to the TCP/IP task for processing. */
- xRxEvent.pvData = ( void * ) pxDescriptor;
- if( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime ) == pdFALSE )
- {
- /* Could not send the descriptor into the TCP/IP
- stack, it must be released. */
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
- else
- {
- iptraceNETWORK_INTERFACE_RECEIVE();
-
- /* The data that was available at the top of this
- loop has been sent, so is no longer available. */
- ulDataAvailable = pdFALSE;
- }
- }
- }
- }
- else
- {
- /* The packet is discarded as uninteresting. */
- ulDataAvailable = pdFALSE;
- }
- /* Got here because received data was sent to the IP task or the
- data contained an error and was discarded. Give the descriptor
- back to the DMA. */
- xDMARxDescriptors[ ulNextRxDescriptorToProcess ].STATUS = ulStatus | RDES_OWN;
-
- /* Move onto the next descriptor. */
- ulNextRxDescriptorToProcess++;
- if( ulNextRxDescriptorToProcess >= configNUM_RX_DESCRIPTORS )
- {
- ulNextRxDescriptorToProcess = 0;
- }
-
- ulStatus = xDMARxDescriptors[ ulNextRxDescriptorToProcess ].STATUS;
- } /* if( ( ulStatus & nwRX_STATUS_ERROR_BITS ) != 0 ) */
- } /* if( ( ulStatus & RDES_OWN ) == 0 ) */
-
- /* Restart receive polling. */
- LPC_ETHERNET->DMA_REC_POLL_DEMAND = 1;
-
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-configPLACE_IN_SECTION_RAM
-void NETWORK_IRQHandler( void )
-{
-BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-uint32_t ulDMAStatus;
-const uint32_t ulRxInterruptMask =
- DMA_ST_RI | /* Receive interrupt */
- DMA_ST_RU; /* Receive buffer unavailable */
-const uint32_t ulTxInterruptMask =
- DMA_ST_TI | /* Transmit interrupt */
- DMA_ST_TPS; /* Transmit process stopped */
-
- configASSERT( xRxHanderTask );
-
- /* Get pending interrupts. */
- ulDMAStatus = LPC_ETHERNET->DMA_STAT;
-
- /* RX group interrupt(s). */
- if( ( ulDMAStatus & ulRxInterruptMask ) != 0x00 )
- {
- /* Remember that an RX event has happened. */
- ulISREvents |= EMAC_IF_RX_EVENT;
- vTaskNotifyGiveFromISR( xRxHanderTask, &xHigherPriorityTaskWoken );
- intCount[ 0 ]++;
- }
-
- /* TX group interrupt(s). */
- if( ( ulDMAStatus & ulTxInterruptMask ) != 0x00 )
- {
- /* Remember that a TX event has happened. */
- ulISREvents |= EMAC_IF_TX_EVENT;
- vTaskNotifyGiveFromISR( xRxHanderTask, &xHigherPriorityTaskWoken );
- intCount[ 1 ]++;
- }
-
- /* Test for 'Abnormal interrupt summary'. */
- if( ( ulDMAStatus & DMA_ST_AIE ) != 0x00 )
- {
- /* The trace macro must be written such that it can be called from
- an interrupt. */
- iptraceETHERNET_RX_EVENT_LOST();
- }
-
- /* Clear pending interrupts */
- LPC_ETHERNET->DMA_STAT = ulDMAStatus;
-
- /* Context switch needed? */
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvSetLinkSpeed( void )
-{
-BaseType_t xReturn = pdFAIL;
-TickType_t xTimeOnEntering;
-uint32_t ulPhyStatus;
-const TickType_t xAutoNegotiateDelay = pdMS_TO_TICKS( 5000UL );
-
- /* Ensure polling does not starve lower priority tasks by temporarily
- setting the priority of this task to that of the idle task. */
- vTaskPrioritySet( NULL, tskIDLE_PRIORITY );
-
- xTimeOnEntering = xTaskGetTickCount();
- do
- {
- ulPhyStatus = lpcPHYStsPoll();
- if( ( ulPhyStatus & PHY_LINK_CONNECTED ) != 0x00 )
- {
- /* Set interface speed and duplex. */
- if( ( ulPhyStatus & PHY_LINK_SPEED100 ) != 0x00 )
- {
- Chip_ENET_SetSpeed( LPC_ETHERNET, 1 );
- }
- else
- {
- Chip_ENET_SetSpeed( LPC_ETHERNET, 0 );
- }
-
- if( ( ulPhyStatus & PHY_LINK_FULLDUPLX ) != 0x00 )
- {
- Chip_ENET_SetDuplex( LPC_ETHERNET, true );
- }
- else
- {
- Chip_ENET_SetDuplex( LPC_ETHERNET, false );
- }
-
- xReturn = pdPASS;
- break;
- }
- } while( ( xTaskGetTickCount() - xTimeOnEntering ) < xAutoNegotiateDelay );
-
- /* Reset the priority of this task back to its original value. */
- vTaskPrioritySet( NULL, ipconfigIP_TASK_PRIORITY );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static uint32_t prvGenerateCRC32( const uint8_t *ucAddress )
-{
-unsigned int j;
-const uint32_t Polynomial = 0xEDB88320;
-uint32_t crc = ~0ul;
-const uint8_t *pucCurrent = ( const uint8_t * ) ucAddress;
-const uint8_t *pucLast = pucCurrent + 6;
-
- /* Calculate normal CRC32 */
- while( pucCurrent < pucLast )
- {
- crc ^= *( pucCurrent++ );
- for( j = 0; j < 8; j++ )
- {
- if( ( crc & 1 ) != 0 )
- {
- crc = (crc >> 1) ^ Polynomial;
- }
- else
- {
- crc >>= 1;
- }
- }
- }
- return ~crc;
-}
-/*-----------------------------------------------------------*/
-
-static uint32_t prvGetHashIndex( const uint8_t *ucAddress )
-{
-uint32_t ulCrc = prvGenerateCRC32( ucAddress );
-uint32_t ulIndex = 0ul;
-BaseType_t xCount = 6;
-
- /* Take the lowest 6 bits of the CRC32 and reverse them */
- while( xCount-- )
- {
- ulIndex <<= 1;
- ulIndex |= ( ulCrc & 1 );
- ulCrc >>= 1;
- }
-
- /* This is the has value of 'ucAddress' */
- return ulIndex;
-}
-/*-----------------------------------------------------------*/
-
-static void prvAddMACAddress( const uint8_t* ucMacAddress )
-{
-BaseType_t xIndex;
-
- xIndex = prvGetHashIndex( ucMacAddress );
- if( xIndex >= 32 )
- {
- LPC_ETHERNET->MAC_HASHTABLE_HIGH |= ( 1u << ( xIndex - 32 ) );
- }
- else
- {
- LPC_ETHERNET->MAC_HASHTABLE_LOW |= ( 1u << xIndex );
- }
-}
-/*-----------------------------------------------------------*/
-
-configPLACE_IN_SECTION_RAM
-static void prvEMACHandlerTask( void *pvParameters )
-{
-TimeOut_t xPhyTime;
-TickType_t xPhyRemTime;
-UBaseType_t uxLastMinBufferCount = 0;
-UBaseType_t uxCurrentCount;
-BaseType_t xResult = 0;
-uint32_t ulStatus;
-const TickType_t xBlockTime = pdMS_TO_TICKS( 5000ul );
-
- /* Remove compiler warning about unused parameter. */
- ( void ) pvParameters;
-
- /* A possibility to set some additional task properties. */
- iptraceEMAC_TASK_STARTING();
-
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
-
- for( ;; )
- {
- 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( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- static UBaseType_t uxLastMinQueueSpace = 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 */
-
- ulTaskNotifyTake( pdTRUE, xBlockTime );
-
- xResult = ( BaseType_t ) 0;
-
- if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
- {
- /* Code to release TX buffers if zero-copy is used. */
- ulISREvents &= ~EMAC_IF_TX_EVENT;
- {
- /* Check if DMA packets have been delivered. */
- vClearTXBuffers();
- }
- }
-
- if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
- {
- ulISREvents &= ~EMAC_IF_RX_EVENT;
-
- xResult = prvNetworkInterfaceInput();
- if( xResult > 0 )
- {
- while( prvNetworkInterfaceInput() > 0 )
- {
- }
- }
- }
-
- if( xResult > 0 )
- {
- /* A packet was received. No need to check for the PHY status now,
- but set a timer to check it later on. */
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- xResult = 0;
- }
- else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
- {
- ulStatus = lpcPHYStsPoll();
-
- if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != ( ulStatus & PHY_LINK_CONNECTED ) )
- {
- ulPHYLinkStatus = ulStatus;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d (polled PHY)\n", ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != 0 ) );
- }
-
- vTaskSetTimeOutState( &xPhyTime );
- if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != 0 )
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- }
- else
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
- }
- }
- }
-}
-/*-----------------------------------------------------------*/
+/*
+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. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+/* LPCOpen includes. */
+#include "chip.h"
+#include "lpc_phy.h"
+
+/* The size of the stack allocated to the task that handles Rx packets. */
+#define nwRX_TASK_STACK_SIZE 140
+
+#ifndef PHY_LS_HIGH_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
+ receiving packets. */
+ #define PHY_LS_HIGH_CHECK_TIME_MS 15000
+#endif
+
+#ifndef PHY_LS_LOW_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still low every second. */
+ #define PHY_LS_LOW_CHECK_TIME_MS 1000
+#endif
+
+#ifndef configUSE_RMII
+ #define configUSE_RMII 1
+#endif
+
+#ifndef configNUM_RX_DESCRIPTORS
+ #error please define configNUM_RX_DESCRIPTORS in your FreeRTOSIPConfig.h
+#endif
+
+#ifndef configNUM_TX_DESCRIPTORS
+ #error please define configNUM_TX_DESCRIPTORS in your FreeRTOSIPConfig.h
+#endif
+
+#ifndef NETWORK_IRQHandler
+ #error NETWORK_IRQHandler must be defined to the name of the function that is installed in the interrupt vector table to handle Ethernet interrupts.
+#endif
+
+#if !defined( MAC_FF_HMC )
+ /* Hash for multicast. */
+ #define MAC_FF_HMC ( 1UL << 2UL )
+#endif
+
+#ifndef iptraceEMAC_TASK_STARTING
+ #define iptraceEMAC_TASK_STARTING() do { } while( 0 )
+#endif
+
+/* Define the bits of .STATUS that indicate a reception error. */
+#define nwRX_STATUS_ERROR_BITS \
+ ( RDES_CE /* CRC Error */ | \
+ RDES_RE /* Receive Error */ | \
+ RDES_DE /* Descriptor Error */ | \
+ RDES_RWT /* Receive Watchdog Timeout */ | \
+ RDES_LC /* Late Collision */ | \
+ RDES_OE /* Overflow Error */ | \
+ RDES_SAF /* Source Address Filter Fail */ | \
+ RDES_AFM /* Destination Address Filter Fail */ | \
+ RDES_LE /* Length Error */ )
+
+/* Define the EMAC status bits that should trigger an interrupt. */
+#define nwDMA_INTERRUPT_MASK \
+ ( DMA_IE_TIE /* Transmit interrupt enable */ | \
+ DMA_IE_TSE /* Transmit stopped enable */ | \
+ DMA_IE_OVE /* Overflow interrupt enable */ | \
+ DMA_IE_RIE /* Receive interrupt enable */ | \
+ DMA_IE_NIE /* Normal interrupt summary enable */ | \
+ DMA_IE_AIE /* Abnormal interrupt summary enable */ | \
+ DMA_IE_RUE /* Receive buffer unavailable enable */ | \
+ DMA_IE_UNE /* Underflow interrupt enable. */ | \
+ DMA_IE_TJE /* Transmit jabber timeout enable */ | \
+ DMA_IE_RSE /* Received stopped enable */ | \
+ DMA_IE_RWE /* Receive watchdog timeout enable */ | \
+ DMA_IE_FBE )/* Fatal bus error enable */
+
+/* Interrupt events to process. Currently only the RX/TX events are processed
+although code for other events is included to allow for possible future
+expansion. */
+#define EMAC_IF_RX_EVENT 1UL
+#define EMAC_IF_TX_EVENT 2UL
+#define EMAC_IF_ERR_EVENT 4UL
+#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
+
+ /* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
+ driver will filter incoming packets and only pass the stack those packets it
+ considers need processing. */
+ #if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+ #else
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+ #endif
+
+#if( ipconfigZERO_COPY_RX_DRIVER == 0 ) || ( ipconfigZERO_COPY_TX_DRIVER == 0 )
+ #warning It is adviced to enable both macros
+#endif
+
+#ifndef configPLACE_IN_SECTION_RAM
+ #define configPLACE_IN_SECTION_RAM
+/*
+ #define configPLACE_IN_SECTION_RAM __attribute__ ((section(".ramfunc")))
+*/
+#endif
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Delay function passed into the library. The implementation uses FreeRTOS
+ * calls so the scheduler must be started before the driver can be used.
+ */
+static void prvDelay( uint32_t ulMilliSeconds );
+
+/*
+ * Initialises the Tx and Rx descriptors respectively.
+ */
+static void prvSetupTxDescriptors( void );
+static void prvSetupRxDescriptors( void );
+
+/*
+ * A task that processes received frames.
+ */
+static void prvEMACHandlerTask( void *pvParameters );
+
+/*
+ * Sets up the MAC with the results of an auto-negotiation.
+ */
+static BaseType_t prvSetLinkSpeed( void );
+
+/*
+ * Generates a CRC for a MAC address that is then used to generate a hash index.
+ */
+static uint32_t prvGenerateCRC32( const uint8_t *ucAddress );
+
+/*
+ * Generates a hash index when setting a filter to permit a MAC address.
+ */
+static uint32_t prvGetHashIndex( const uint8_t *ucAddress );
+
+/*
+ * Update the hash table to allow a MAC address.
+ */
+static void prvAddMACAddress( const uint8_t* ucMacAddress );
+
+/*
+ * Sometimes the DMA will report received data as being longer than the actual
+ * received from length. This function checks the reported length and corrects
+ * if if necessary.
+ */
+static void prvRemoveTrailingBytes( NetworkBufferDescriptor_t *pxDescriptor );
+
+/*-----------------------------------------------------------*/
+
+/* Bit map of outstanding ETH interrupt events for processing. Currently only
+the Rx and Tx interrupt is handled, although code is included for other events
+to enable future expansion. */
+static volatile uint32_t ulISREvents;
+
+/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
+static uint32_t ulPHYLinkStatus = 0;
+
+/* Tx descriptors and index. */
+static ENET_ENHTXDESC_T xDMATxDescriptors[ configNUM_TX_DESCRIPTORS ];
+
+/* ulNextFreeTxDescriptor is declared volatile, because it is accessed from
+to different tasks. */
+static volatile uint32_t ulNextFreeTxDescriptor;
+static uint32_t ulTxDescriptorToClear;
+
+/* Rx descriptors and index. */
+static ENET_ENHRXDESC_T xDMARxDescriptors[ configNUM_RX_DESCRIPTORS ];
+static uint32_t ulNextRxDescriptorToProcess;
+
+/* Must be defined externally - the demo applications define this in main.c. */
+extern uint8_t ucMACAddress[ 6 ];
+
+/* The handle of the task that processes Rx packets. The handle is required so
+the task can be notified when new packets arrive. */
+static TaskHandle_t xRxHanderTask = NULL;
+
+#if( ipconfigUSE_LLMNR == 1 )
+ static const uint8_t xLLMNR_MACAddress[] = { '\x01', '\x00', '\x5E', '\x00', '\x00', '\xFC' };
+#endif /* ipconfigUSE_LLMNR == 1 */
+
+/* xTXDescriptorSemaphore is a counting semaphore with
+a maximum count of ETH_TXBUFNB, which is the number of
+DMA TX descriptors. */
+static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
+
+/*-----------------------------------------------------------*/
+
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+BaseType_t xReturn = pdPASS;
+
+ /* The interrupt will be turned on when a link is established. */
+ NVIC_DisableIRQ( ETHERNET_IRQn );
+
+ /* Disable receive and transmit DMA processes. */
+ LPC_ETHERNET->DMA_OP_MODE &= ~( DMA_OM_ST | DMA_OM_SR );
+
+ /* Disable packet reception. */
+ LPC_ETHERNET->MAC_CONFIG &= ~( MAC_CFG_RE | MAC_CFG_TE );
+
+ /* Call the LPCOpen function to initialise the hardware. */
+ Chip_ENET_Init( LPC_ETHERNET );
+
+ /* Save MAC address. */
+ Chip_ENET_SetADDR( LPC_ETHERNET, ucMACAddress );
+
+ /* Clear all MAC address hash entries. */
+ LPC_ETHERNET->MAC_HASHTABLE_HIGH = 0;
+ LPC_ETHERNET->MAC_HASHTABLE_LOW = 0;
+
+ #if( ipconfigUSE_LLMNR == 1 )
+ {
+ prvAddMACAddress( xLLMNR_MACAddress );
+ }
+ #endif /* ipconfigUSE_LLMNR == 1 */
+
+ /* Promiscuous flag (PR) and Receive All flag (RA) set to zero. The
+ registers MAC_HASHTABLE_[LOW|HIGH] will be loaded to allow certain
+ multi-cast addresses. */
+ LPC_ETHERNET->MAC_FRAME_FILTER = MAC_FF_HMC;
+
+ #if( configUSE_RMII == 1 )
+ {
+ if( lpc_phy_init( pdTRUE, prvDelay ) != SUCCESS )
+ {
+ xReturn = pdFAIL;
+ }
+ }
+ #else
+ {
+ #warning This path has not been tested.
+ if( lpc_phy_init( pdFALSE, prvDelay ) != SUCCESS )
+ {
+ xReturn = pdFAIL;
+ }
+ }
+ #endif
+
+ if( xReturn == pdPASS )
+ {
+ /* Guard against the task being created more than once and the
+ descriptors being initialised more than once. */
+ if( xRxHanderTask == NULL )
+ {
+ xReturn = xTaskCreate( prvEMACHandlerTask, "EMAC", nwRX_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xRxHanderTask );
+ configASSERT( xReturn );
+ }
+
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ /* Create a counting semaphore, with a value of 'configNUM_TX_DESCRIPTORS'
+ and a maximum of 'configNUM_TX_DESCRIPTORS'. */
+ xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) configNUM_TX_DESCRIPTORS, ( UBaseType_t ) configNUM_TX_DESCRIPTORS );
+ configASSERT( xTXDescriptorSemaphore );
+ }
+
+ /* Enable MAC interrupts. */
+ LPC_ETHERNET->DMA_INT_EN = nwDMA_INTERRUPT_MASK;
+ }
+
+ if( xReturn != pdFAIL )
+ {
+ /* Auto-negotiate was already started. Wait for it to complete. */
+ xReturn = prvSetLinkSpeed();
+
+ if( xReturn == pdPASS )
+ {
+ /* Initialise the descriptors. */
+ prvSetupTxDescriptors();
+ prvSetupRxDescriptors();
+
+ /* Clear all interrupts. */
+ LPC_ETHERNET->DMA_STAT = DMA_ST_ALL;
+
+ /* Enable receive and transmit DMA processes. */
+ LPC_ETHERNET->DMA_OP_MODE |= DMA_OM_ST | DMA_OM_SR;
+
+ /* Set Receiver / Transmitter Enable. */
+ LPC_ETHERNET->MAC_CONFIG |= MAC_CFG_RE | MAC_CFG_TE;
+
+ /* Start receive polling. */
+ LPC_ETHERNET->DMA_REC_POLL_DEMAND = 1;
+
+ /* Enable interrupts in the NVIC. */
+ NVIC_SetPriority( ETHERNET_IRQn, configMAC_INTERRUPT_PRIORITY );
+ NVIC_EnableIRQ( ETHERNET_IRQn );
+ }
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+#define niBUFFER_1_PACKET_SIZE 1536
+
+static __attribute__ ((section("._ramAHB32"))) uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
+
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
+{
+
+uint8_t *ucRAMBuffer = ucNetworkPackets;
+uint32_t ul;
+
+ for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
+ {
+ pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
+ *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
+ ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
+ }
+}
+/*-----------------------------------------------------------*/
+
+configPLACE_IN_SECTION_RAM
+static void vClearTXBuffers()
+{
+uint32_t ulLastDescriptor = ulNextFreeTxDescriptor;
+size_t uxCount = ( ( size_t ) configNUM_TX_DESCRIPTORS ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ NetworkBufferDescriptor_t *pxNetworkBuffer;
+ uint8_t *ucPayLoad;
+#endif
+
+ /* This function is called after a TX-completion interrupt.
+ It will release each Network Buffer used in xNetworkInterfaceOutput().
+ 'uxCount' represents the number of descriptors given to DMA for transmission.
+ After sending a packet, the DMA will clear the 'TDES_OWN' bit. */
+ while( ( uxCount > ( size_t ) 0u ) && ( ( xDMATxDescriptors[ ulTxDescriptorToClear ].CTRLSTAT & TDES_OWN ) == 0 ) )
+ {
+ if( ( ulTxDescriptorToClear == ulLastDescriptor ) && ( uxCount != ( size_t ) configNUM_TX_DESCRIPTORS ) )
+ {
+ break;
+ }
+
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ ucPayLoad = ( uint8_t * )xDMATxDescriptors[ ulTxDescriptorToClear ].B1ADD;
+ if( ucPayLoad != NULL )
+ {
+ /* B1ADD points to a pucEthernetBuffer of a Network Buffer descriptor. */
+ pxNetworkBuffer = pxPacketBuffer_to_NetworkBuffer( ucPayLoad );
+
+ configASSERT( pxNetworkBuffer != NULL );
+
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer ) ;
+ xDMATxDescriptors[ ulTxDescriptorToClear ].B1ADD = ( uint32_t )0u;
+ }
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+ /* Move onto the next descriptor, wrapping if necessary. */
+ ulTxDescriptorToClear++;
+ if( ulTxDescriptorToClear >= configNUM_TX_DESCRIPTORS )
+ {
+ ulTxDescriptorToClear = 0;
+ }
+
+ uxCount--;
+ /* Tell the counting semaphore that one more TX descriptor is available. */
+ xSemaphoreGive( xTXDescriptorSemaphore );
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+configPLACE_IN_SECTION_RAM
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t bReleaseAfterSend )
+{
+BaseType_t xReturn = pdFAIL;
+const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50 );
+
+ /* Attempt to obtain access to a Tx descriptor. */
+ do
+ {
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ break;
+ }
+ if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
+ {
+ /* Time-out waiting for a free TX descriptor. */
+ break;
+ }
+
+ /* If the descriptor is still owned by the DMA it can't be used. */
+ if( ( xDMATxDescriptors[ ulNextFreeTxDescriptor ].CTRLSTAT & TDES_OWN ) != 0 )
+ {
+ /* The semaphore was taken, the TX DMA-descriptor is still not available.
+ Actually that should not occur, the 'TDES_OWN' was already confirmed low in vClearTXBuffers(). */
+ xSemaphoreGive( xTXDescriptorSemaphore );
+ }
+ else
+ {
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* bReleaseAfterSend should always be set when using the zero
+ copy driver. */
+ configASSERT( bReleaseAfterSend != pdFALSE );
+
+ /* The DMA's descriptor to point directly to the data in the
+ network buffer descriptor. The data is not copied. */
+ xDMATxDescriptors[ ulNextFreeTxDescriptor ].B1ADD = ( uint32_t ) pxDescriptor->pucEthernetBuffer;
+
+ /* The DMA descriptor will 'own' this Network Buffer,
+ until it has been sent. So don't release it now. */
+ bReleaseAfterSend = false;
+ }
+ #else
+ {
+ /* The data is copied from the network buffer descriptor into
+ the DMA's descriptor. */
+ memcpy( ( void * ) xDMATxDescriptors[ ulNextFreeTxDescriptor ].B1ADD, ( void * ) pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength );
+ }
+ #endif
+
+ xDMATxDescriptors[ ulNextFreeTxDescriptor ].BSIZE = ( uint32_t ) TDES_ENH_BS1( pxDescriptor->xDataLength );
+
+ /* This descriptor is given back to the DMA. */
+ xDMATxDescriptors[ ulNextFreeTxDescriptor ].CTRLSTAT |= TDES_OWN;
+
+ /* Ensure the DMA is polling Tx descriptors. */
+ LPC_ETHERNET->DMA_TRANS_POLL_DEMAND = 1;
+
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+
+ /* Move onto the next descriptor, wrapping if necessary. */
+ ulNextFreeTxDescriptor++;
+ if( ulNextFreeTxDescriptor >= configNUM_TX_DESCRIPTORS )
+ {
+ ulNextFreeTxDescriptor = 0;
+ }
+
+ /* The Tx has been initiated. */
+ xReturn = pdPASS;
+ }
+ } while( 0 );
+
+ /* The buffer has been sent so can be released. */
+ if( bReleaseAfterSend != pdFALSE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static void prvDelay( uint32_t ulMilliSeconds )
+{
+ /* Ensure the scheduler was started before attempting to use the scheduler to
+ create a delay. */
+ configASSERT( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING );
+
+ vTaskDelay( pdMS_TO_TICKS( ulMilliSeconds ) );
+}
+/*-----------------------------------------------------------*/
+
+static void prvSetupTxDescriptors( void )
+{
+BaseType_t x;
+
+ /* Start with Tx descriptors clear. */
+ memset( ( void * ) xDMATxDescriptors, 0, sizeof( xDMATxDescriptors ) );
+
+ /* Index to the next Tx descriptor to use. */
+ ulNextFreeTxDescriptor = 0ul;
+
+ /* Index to the next Tx descriptor to clear ( after transmission ). */
+ ulTxDescriptorToClear = 0ul;
+
+ for( x = 0; x < configNUM_TX_DESCRIPTORS; x++ )
+ {
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* Nothing to do, B1ADD will be set when data is ready to transmit.
+ Currently the memset above will have set it to NULL. */
+ }
+ #else
+ {
+ /* Allocate a buffer to the Tx descriptor. This is the most basic
+ way of creating a driver as the data is then copied into the
+ buffer. */
+ xDMATxDescriptors[ x ].B1ADD = ( uint32_t ) pvPortMalloc( ipTOTAL_ETHERNET_FRAME_SIZE );
+
+ /* Use an assert to check the allocation as +TCP applications will
+ often not use a malloc() failed hook as the TCP stack will recover
+ from allocation failures. */
+ configASSERT( xDMATxDescriptors[ x ].B1ADD );
+ }
+ #endif
+
+ /* Buffers hold an entire frame so all buffers are both the start and
+ end of a frame. */
+ /* TDES_ENH_TCH Second Address Chained. */
+ /* TDES_ENH_CIC(n) Checksum Insertion Control, tried but it does not work for the LPC18xx... */
+ /* TDES_ENH_FS First Segment. */
+ /* TDES_ENH_LS Last Segment. */
+ /* TDES_ENH_IC Interrupt on Completion. */
+ xDMATxDescriptors[ x ].CTRLSTAT = TDES_ENH_TCH | TDES_ENH_CIC( 3 ) | TDES_ENH_FS | TDES_ENH_LS | TDES_ENH_IC;
+ xDMATxDescriptors[ x ].B2ADD = ( uint32_t ) &xDMATxDescriptors[ x + 1 ];
+ }
+
+ xDMATxDescriptors[ configNUM_TX_DESCRIPTORS - 1 ].CTRLSTAT |= TDES_ENH_TER;
+ xDMATxDescriptors[ configNUM_TX_DESCRIPTORS - 1 ].B2ADD = ( uint32_t ) &xDMATxDescriptors[ 0 ];
+
+ /* Point the DMA to the base of the descriptor list. */
+ LPC_ETHERNET->DMA_TRANS_DES_ADDR = ( uint32_t ) xDMATxDescriptors;
+}
+/*-----------------------------------------------------------*/
+
+static void prvSetupRxDescriptors( void )
+{
+BaseType_t x;
+#if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ NetworkBufferDescriptor_t *pxNetworkBuffer;
+#endif
+
+ /* Index to the next Rx descriptor to use. */
+ ulNextRxDescriptorToProcess = 0;
+
+ /* Clear RX descriptor list. */
+ memset( ( void * ) xDMARxDescriptors, 0, sizeof( xDMARxDescriptors ) );
+
+ for( x = 0; x < configNUM_RX_DESCRIPTORS; x++ )
+ {
+ /* Allocate a buffer of the largest possible frame size as it is not
+ known what size received frames will be. */
+
+ #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ {
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, 0 );
+
+ /* During start-up there should be enough Network Buffers available,
+ so it is safe to use configASSERT().
+ In case this assert fails, please check: configNUM_RX_DESCRIPTORS,
+ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, and in case BufferAllocation_2.c
+ is included, check the amount of available heap. */
+ configASSERT( pxNetworkBuffer != NULL );
+
+ /* Pass the actual buffer to DMA. */
+ xDMARxDescriptors[ x ].B1ADD = ( uint32_t ) pxNetworkBuffer->pucEthernetBuffer;
+ }
+ #else
+ {
+ /* All DMA descriptors are populated with permanent memory blocks.
+ Their contents will be copy to Network Buffers. */
+ xDMARxDescriptors[ x ].B1ADD = ( uint32_t ) pvPortMalloc( ipTOTAL_ETHERNET_FRAME_SIZE );
+ }
+ #endif /* ipconfigZERO_COPY_RX_DRIVER */
+
+ /* Use an assert to check the allocation as +TCP applications will often
+ not use a malloc failed hook as the TCP stack will recover from
+ allocation failures. */
+ configASSERT( xDMARxDescriptors[ x ].B1ADD );
+
+ xDMARxDescriptors[ x ].B2ADD = ( uint32_t ) &( xDMARxDescriptors[ x + 1 ] );
+ xDMARxDescriptors[ x ].CTRL = ( uint32_t ) RDES_ENH_BS1( ipTOTAL_ETHERNET_FRAME_SIZE ) | RDES_ENH_RCH;
+
+ /* The descriptor is available for use by the DMA. */
+ xDMARxDescriptors[ x ].STATUS = RDES_OWN;
+ }
+
+ /* RDES_ENH_RER Receive End of Ring. */
+ xDMARxDescriptors[ ( configNUM_RX_DESCRIPTORS - 1 ) ].CTRL |= RDES_ENH_RER;
+ xDMARxDescriptors[ configNUM_RX_DESCRIPTORS - 1 ].B2ADD = ( uint32_t ) &( xDMARxDescriptors[ 0 ] );
+
+ /* Point the DMA to the base of the descriptor list. */
+ LPC_ETHERNET->DMA_REC_DES_ADDR = ( uint32_t ) xDMARxDescriptors;
+}
+/*-----------------------------------------------------------*/
+configPLACE_IN_SECTION_RAM
+static void prvRemoveTrailingBytes( NetworkBufferDescriptor_t *pxDescriptor )
+{
+size_t xExpectedLength;
+IPPacket_t *pxIPPacket;
+
+ pxIPPacket = ( IPPacket_t * ) pxDescriptor->pucEthernetBuffer;
+ /* Look at the actual length of the packet, translate it to a host-endial notation. */
+ xExpectedLength = sizeof( EthernetHeader_t ) + ( size_t ) FreeRTOS_htons( pxIPPacket->xIPHeader.usLength );
+
+ if( xExpectedLength == ( pxDescriptor->xDataLength + 4 ) )
+ {
+ pxDescriptor->xDataLength -= 4;
+ }
+ else
+ {
+ if( pxDescriptor->xDataLength > xExpectedLength )
+ {
+ pxDescriptor->xDataLength = ( size_t ) xExpectedLength;
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+configPLACE_IN_SECTION_RAM
+BaseType_t xGetPhyLinkStatus( void )
+{
+BaseType_t xReturn;
+
+ if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) == 0 )
+ {
+ xReturn = pdFALSE;
+ }
+ else
+ {
+ xReturn = pdTRUE;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+uint32_t ulDataAvailable;
+
+configPLACE_IN_SECTION_RAM
+static BaseType_t prvNetworkInterfaceInput()
+{
+BaseType_t xResult = pdFALSE;
+uint32_t ulStatus;
+eFrameProcessingResult_t eResult;
+const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
+const UBaseType_t uxMinimumBuffersRemaining = 3UL;
+uint16_t usLength;
+NetworkBufferDescriptor_t *pxDescriptor;
+#if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ NetworkBufferDescriptor_t *pxNewDescriptor;
+#endif /* ipconfigZERO_COPY_RX_DRIVER */
+#if( ipconfigUSE_LINKED_RX_MESSAGES == 0 )
+ IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+#endif
+
+ /* Process each descriptor that is not still in use by the DMA. */
+ ulStatus = xDMARxDescriptors[ ulNextRxDescriptorToProcess ].STATUS;
+ if( ( ulStatus & RDES_OWN ) == 0 )
+ {
+ /* Check packet for errors */
+ if( ( ulStatus & nwRX_STATUS_ERROR_BITS ) != 0 )
+ {
+ /* There is some reception error. */
+ intCount[ 3 ]++;
+ /* Clear error bits. */
+ ulStatus &= ~( ( uint32_t )nwRX_STATUS_ERROR_BITS );
+ }
+ else
+ {
+ xResult++;
+
+ eResult = ipCONSIDER_FRAME_FOR_PROCESSING( ( const uint8_t * const ) ( xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD ) );
+ if( eResult == eProcessBuffer )
+ {
+ if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) == 0 )
+ {
+ ulPHYLinkStatus |= PHY_LINK_CONNECTED;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d (message received)\n", ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != 0 ) );
+ }
+
+ #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ if( uxGetNumberOfFreeNetworkBuffers() > uxMinimumBuffersRemaining )
+ {
+ pxNewDescriptor = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, xDescriptorWaitTime );
+ }
+ else
+ {
+ /* Too risky to allocate a new Network Buffer. */
+ pxNewDescriptor = NULL;
+ }
+ if( pxNewDescriptor != NULL )
+ #else
+ if( uxGetNumberOfFreeNetworkBuffers() > uxMinimumBuffersRemaining )
+ #endif /* ipconfigZERO_COPY_RX_DRIVER */
+ {
+ #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ const uint8_t *pucBuffer;
+ #endif
+
+ /* Get the actual length. */
+ usLength = RDES_FLMSK( ulStatus );
+
+ #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ {
+ /* Replace the character buffer 'B1ADD'. */
+ pucBuffer = ( const uint8_t * const ) ( xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD );
+ xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD = ( uint32_t ) pxNewDescriptor->pucEthernetBuffer;
+
+ /* 'B1ADD' contained the address of a 'pucEthernetBuffer' that
+ belongs to a Network Buffer. Find the original Network Buffer. */
+ pxDescriptor = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
+ /* This zero-copy driver makes sure that every 'xDMARxDescriptors' contains
+ a reference to a Network Buffer at any time.
+ In case it runs out of Network Buffers, a DMA buffer won't be replaced,
+ and the received messages is dropped. */
+ configASSERT( pxDescriptor != NULL );
+ }
+ #else
+ {
+ /* Create a buffer of exactly the required length. */
+ pxDescriptor = pxGetNetworkBufferWithDescriptor( usLength, xDescriptorWaitTime );
+ }
+ #endif /* ipconfigZERO_COPY_RX_DRIVER */
+
+ if( pxDescriptor != NULL )
+ {
+ pxDescriptor->xDataLength = ( size_t ) usLength;
+ #if( ipconfigZERO_COPY_RX_DRIVER == 0 )
+ {
+ /* Copy the data into the allocated buffer. */
+ memcpy( ( void * ) pxDescriptor->pucEthernetBuffer, ( void * ) xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD, usLength );
+ }
+ #endif /* ipconfigZERO_COPY_RX_DRIVER */
+ /* It is possible that more data was copied than
+ actually makes up the frame. If this is the case
+ adjust the length to remove any trailing bytes. */
+ prvRemoveTrailingBytes( pxDescriptor );
+
+ /* Pass the data to the TCP/IP task for processing. */
+ xRxEvent.pvData = ( void * ) pxDescriptor;
+ if( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime ) == pdFALSE )
+ {
+ /* Could not send the descriptor into the TCP/IP
+ stack, it must be released. */
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+ else
+ {
+ iptraceNETWORK_INTERFACE_RECEIVE();
+
+ /* The data that was available at the top of this
+ loop has been sent, so is no longer available. */
+ ulDataAvailable = pdFALSE;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* The packet is discarded as uninteresting. */
+ ulDataAvailable = pdFALSE;
+ }
+ /* Got here because received data was sent to the IP task or the
+ data contained an error and was discarded. Give the descriptor
+ back to the DMA. */
+ xDMARxDescriptors[ ulNextRxDescriptorToProcess ].STATUS = ulStatus | RDES_OWN;
+
+ /* Move onto the next descriptor. */
+ ulNextRxDescriptorToProcess++;
+ if( ulNextRxDescriptorToProcess >= configNUM_RX_DESCRIPTORS )
+ {
+ ulNextRxDescriptorToProcess = 0;
+ }
+
+ ulStatus = xDMARxDescriptors[ ulNextRxDescriptorToProcess ].STATUS;
+ } /* if( ( ulStatus & nwRX_STATUS_ERROR_BITS ) != 0 ) */
+ } /* if( ( ulStatus & RDES_OWN ) == 0 ) */
+
+ /* Restart receive polling. */
+ LPC_ETHERNET->DMA_REC_POLL_DEMAND = 1;
+
+ return xResult;
+}
+/*-----------------------------------------------------------*/
+
+configPLACE_IN_SECTION_RAM
+void NETWORK_IRQHandler( void )
+{
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+uint32_t ulDMAStatus;
+const uint32_t ulRxInterruptMask =
+ DMA_ST_RI | /* Receive interrupt */
+ DMA_ST_RU; /* Receive buffer unavailable */
+const uint32_t ulTxInterruptMask =
+ DMA_ST_TI | /* Transmit interrupt */
+ DMA_ST_TPS; /* Transmit process stopped */
+
+ configASSERT( xRxHanderTask );
+
+ /* Get pending interrupts. */
+ ulDMAStatus = LPC_ETHERNET->DMA_STAT;
+
+ /* RX group interrupt(s). */
+ if( ( ulDMAStatus & ulRxInterruptMask ) != 0x00 )
+ {
+ /* Remember that an RX event has happened. */
+ ulISREvents |= EMAC_IF_RX_EVENT;
+ vTaskNotifyGiveFromISR( xRxHanderTask, &xHigherPriorityTaskWoken );
+ intCount[ 0 ]++;
+ }
+
+ /* TX group interrupt(s). */
+ if( ( ulDMAStatus & ulTxInterruptMask ) != 0x00 )
+ {
+ /* Remember that a TX event has happened. */
+ ulISREvents |= EMAC_IF_TX_EVENT;
+ vTaskNotifyGiveFromISR( xRxHanderTask, &xHigherPriorityTaskWoken );
+ intCount[ 1 ]++;
+ }
+
+ /* Test for 'Abnormal interrupt summary'. */
+ if( ( ulDMAStatus & DMA_ST_AIE ) != 0x00 )
+ {
+ /* The trace macro must be written such that it can be called from
+ an interrupt. */
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+
+ /* Clear pending interrupts */
+ LPC_ETHERNET->DMA_STAT = ulDMAStatus;
+
+ /* Context switch needed? */
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvSetLinkSpeed( void )
+{
+BaseType_t xReturn = pdFAIL;
+TickType_t xTimeOnEntering;
+uint32_t ulPhyStatus;
+const TickType_t xAutoNegotiateDelay = pdMS_TO_TICKS( 5000UL );
+
+ /* Ensure polling does not starve lower priority tasks by temporarily
+ setting the priority of this task to that of the idle task. */
+ vTaskPrioritySet( NULL, tskIDLE_PRIORITY );
+
+ xTimeOnEntering = xTaskGetTickCount();
+ do
+ {
+ ulPhyStatus = lpcPHYStsPoll();
+ if( ( ulPhyStatus & PHY_LINK_CONNECTED ) != 0x00 )
+ {
+ /* Set interface speed and duplex. */
+ if( ( ulPhyStatus & PHY_LINK_SPEED100 ) != 0x00 )
+ {
+ Chip_ENET_SetSpeed( LPC_ETHERNET, 1 );
+ }
+ else
+ {
+ Chip_ENET_SetSpeed( LPC_ETHERNET, 0 );
+ }
+
+ if( ( ulPhyStatus & PHY_LINK_FULLDUPLX ) != 0x00 )
+ {
+ Chip_ENET_SetDuplex( LPC_ETHERNET, true );
+ }
+ else
+ {
+ Chip_ENET_SetDuplex( LPC_ETHERNET, false );
+ }
+
+ xReturn = pdPASS;
+ break;
+ }
+ } while( ( xTaskGetTickCount() - xTimeOnEntering ) < xAutoNegotiateDelay );
+
+ /* Reset the priority of this task back to its original value. */
+ vTaskPrioritySet( NULL, ipconfigIP_TASK_PRIORITY );
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static uint32_t prvGenerateCRC32( const uint8_t *ucAddress )
+{
+unsigned int j;
+const uint32_t Polynomial = 0xEDB88320;
+uint32_t crc = ~0ul;
+const uint8_t *pucCurrent = ( const uint8_t * ) ucAddress;
+const uint8_t *pucLast = pucCurrent + 6;
+
+ /* Calculate normal CRC32 */
+ while( pucCurrent < pucLast )
+ {
+ crc ^= *( pucCurrent++ );
+ for( j = 0; j < 8; j++ )
+ {
+ if( ( crc & 1 ) != 0 )
+ {
+ crc = (crc >> 1) ^ Polynomial;
+ }
+ else
+ {
+ crc >>= 1;
+ }
+ }
+ }
+ return ~crc;
+}
+/*-----------------------------------------------------------*/
+
+static uint32_t prvGetHashIndex( const uint8_t *ucAddress )
+{
+uint32_t ulCrc = prvGenerateCRC32( ucAddress );
+uint32_t ulIndex = 0ul;
+BaseType_t xCount = 6;
+
+ /* Take the lowest 6 bits of the CRC32 and reverse them */
+ while( xCount-- )
+ {
+ ulIndex <<= 1;
+ ulIndex |= ( ulCrc & 1 );
+ ulCrc >>= 1;
+ }
+
+ /* This is the has value of 'ucAddress' */
+ return ulIndex;
+}
+/*-----------------------------------------------------------*/
+
+static void prvAddMACAddress( const uint8_t* ucMacAddress )
+{
+BaseType_t xIndex;
+
+ xIndex = prvGetHashIndex( ucMacAddress );
+ if( xIndex >= 32 )
+ {
+ LPC_ETHERNET->MAC_HASHTABLE_HIGH |= ( 1u << ( xIndex - 32 ) );
+ }
+ else
+ {
+ LPC_ETHERNET->MAC_HASHTABLE_LOW |= ( 1u << xIndex );
+ }
+}
+/*-----------------------------------------------------------*/
+
+configPLACE_IN_SECTION_RAM
+static void prvEMACHandlerTask( void *pvParameters )
+{
+TimeOut_t xPhyTime;
+TickType_t xPhyRemTime;
+UBaseType_t uxLastMinBufferCount = 0;
+UBaseType_t uxCurrentCount;
+BaseType_t xResult = 0;
+uint32_t ulStatus;
+const TickType_t xBlockTime = pdMS_TO_TICKS( 5000ul );
+
+ /* Remove compiler warning about unused parameter. */
+ ( void ) pvParameters;
+
+ /* A possibility to set some additional task properties. */
+ iptraceEMAC_TASK_STARTING();
+
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+
+ for( ;; )
+ {
+ 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( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ {
+ static UBaseType_t uxLastMinQueueSpace = 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 */
+
+ ulTaskNotifyTake( pdTRUE, xBlockTime );
+
+ xResult = ( BaseType_t ) 0;
+
+ if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
+ {
+ /* Code to release TX buffers if zero-copy is used. */
+ ulISREvents &= ~EMAC_IF_TX_EVENT;
+ {
+ /* Check if DMA packets have been delivered. */
+ vClearTXBuffers();
+ }
+ }
+
+ if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
+ {
+ ulISREvents &= ~EMAC_IF_RX_EVENT;
+
+ xResult = prvNetworkInterfaceInput();
+ if( xResult > 0 )
+ {
+ while( prvNetworkInterfaceInput() > 0 )
+ {
+ }
+ }
+ }
+
+ if( xResult > 0 )
+ {
+ /* A packet was received. No need to check for the PHY status now,
+ but set a timer to check it later on. */
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ xResult = 0;
+ }
+ else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
+ {
+ ulStatus = lpcPHYStsPoll();
+
+ if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != ( ulStatus & PHY_LINK_CONNECTED ) )
+ {
+ ulPHYLinkStatus = ulStatus;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d (polled PHY)\n", ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != 0 ) );
+ }
+
+ vTaskSetTimeOutState( &xPhyTime );
+ if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != 0 )
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ }
+ else
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/NetworkInterface.c
index 6b926c811..e759141cc 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/NetworkInterface.c
@@ -1,331 +1,331 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2018 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 includes. */
-#include "FreeRTOS.h"
-#include "list.h"
-#include "queue.h"
-#include "semphr.h"
-#include "task.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-
-#include "m480_eth.h"
-
-/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
-driver will filter incoming packets and only pass the stack those packets it
-considers need processing. */
-#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
-#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
-#else
-#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
-#endif
-
-/* Default the size of the stack used by the EMAC deferred handler task to twice
-the size of the stack used by the idle task - but allow this to be overridden in
-FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
-#ifndef configEMAC_TASK_STACK_SIZE
- #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
-#endif
-
-
-static SemaphoreHandle_t xTXMutex = NULL;
-
-/* The handle of the task that processes Rx packets. The handle is required so
-the task can be notified when new packets arrive. */
-static TaskHandle_t xRxHanderTask = NULL;
-static TimerHandle_t xPhyHandlerTask = NULL;
-/*
- * A task that processes received frames.
- */
-static void prvEMACHandlerTask( void *pvParameters );
-static void prvPhyTmrCallback( TimerHandle_t xTimer );
-
-/* The size of each buffer when BufferAllocation_1 is used:
-http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */
-
-#define niBUFFER_1_PACKET_SIZE 1536
-#ifdef __ICCARM__
-#pragma data_alignment=4
-static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ]
-#else
-static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ((aligned(4)));
-#endif
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
- uint8_t hwaddr[6];
- BaseType_t xReturn = pdPASS;
-
- /* Init ETH */
- numaker_mac_address(hwaddr);
- FreeRTOS_UpdateMACAddress(hwaddr);
- FreeRTOS_printf( ("mac address %02x-%02x-%02x-%02x-%02x-%02x \r\n", hwaddr[0], hwaddr[1],hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5]) );
- /* Enable clock & set EMAC configuration */
- /* Enable MAC and DMA transmission and reception */
- if( numaker_eth_init(hwaddr) < 0)
- {
- xReturn = pdFAIL;
- } else {
- xReturn = pdPASS;
- /* Guard against the task being created more than once and the
- descriptors being initialized more than once. */
- /* Timer task to monitor PHY Link status */
- if( xPhyHandlerTask == NULL )
- {
- xPhyHandlerTask = xTimerCreate( "TimerPhy", pdMS_TO_TICKS( 1000 ), pdTRUE, 0, prvPhyTmrCallback );
- configASSERT(xPhyHandlerTask);
- xReturn = xTimerStart( xPhyHandlerTask, 0 ) ;
- configASSERT( xReturn );
- }
- /* Rx task */
- if( xRxHanderTask == NULL )
- {
- xReturn = xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xRxHanderTask );
- configASSERT( xReturn );
- }
-
- if( xTXMutex == NULL )
- {
- xTXMutex = xSemaphoreCreateMutex();
- configASSERT( xTXMutex );
- }
- }
-
- NVIC_SetPriority( EMAC_RX_IRQn, configMAC_INTERRUPT_PRIORITY );
- NVIC_SetPriority( EMAC_TX_IRQn, configMAC_INTERRUPT_PRIORITY );
-
- numaker_eth_enable_interrupts();
-
- FreeRTOS_printf( ("ETH-RX priority:%d\n",NVIC_GetPriority( EMAC_RX_IRQn)) );
-
- return xReturn;
-}
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t xReleaseAfterSend )
-{
- uint8_t *buffer=NULL;
-// FreeRTOS_printf(("<-- dataLength=%d\n",pxDescriptor->xDataLength));
- if( pxDescriptor->xDataLength >= PACKET_BUFFER_SIZE )
- {
- FreeRTOS_printf(("TX buffer length %d over %d\n", pxDescriptor->xDataLength, PACKET_BUFFER_SIZE));
- return pdFALSE;
- }
-
- buffer = numaker_eth_get_tx_buf();
- if( buffer == NULL )
- {
- NU_DEBUGF(("Eth TX slots are busy\n"));
- return pdFALSE;
- }
-
- /* Get exclusive access */
- xSemaphoreTake(xTXMutex, portMAX_DELAY);
- NU_DEBUGF(("%s ... buffer=0x%x\r\n",__FUNCTION__, buffer));
- //SendData: pt = pxDescriptor->pucBuffer, length = pxDescriptor->xDataLength
- memcpy(buffer, pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength);
- numaker_eth_trigger_tx(pxDescriptor->xDataLength, NULL);
- /* Call the standard trace macro to log the send event. */
- iptraceNETWORK_INTERFACE_TRANSMIT();
-
- if( xReleaseAfterSend != pdFALSE )
- {
- /* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet
- buffer. The Ethernet buffer is therefore no longer needed, and must be
- freed for re-use. */
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
-
- xSemaphoreGive(xTXMutex);
-
- return pdTRUE;
-}
-
-
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
-
- uint8_t *ucRAMBuffer = ucNetworkPackets;
- uint32_t ul;
-
- for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
- {
- pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
- *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
- ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
- }
-}
-
-
-BaseType_t xGetPhyLinkStatus( void )
-{
- BaseType_t xReturn;
-
- if( numaker_eth_link_ok() )
- {
- xReturn = pdPASS;
- }
- else
- {
- xReturn = pdFAIL;
- }
-
- return xReturn;
-}
-
-static void prvPhyTmrCallback( TimerHandle_t xTimer )
-{
- IPStackEvent_t xRxEvent;
- static BaseType_t lastLink = pdFAIL;
- BaseType_t currLink = xGetPhyLinkStatus();
- if( currLink != lastLink )
- {
- FreeRTOS_printf(("PHY Link %s\n", (currLink) ? "Up" : "Down"));
- if( !currLink )
- {
- xRxEvent.eEventType = eNetworkDownEvent;
- xSendEventStructToIPTask( &xRxEvent, 0 );
- }
- lastLink = currLink;
- }
-
-}
-
-
-static void prvEMACHandlerTask( void *pvParameters )
-{
- TimeOut_t xPhyTime;
- TickType_t xPhyRemTime;
- UBaseType_t uxLastMinBufferCount = 0;
- UBaseType_t uxCurrentCount;
- BaseType_t xResult = 0;
- uint32_t ulStatus;
- uint16_t dataLength = 0;
- uint8_t *buffer = NULL;
- NetworkBufferDescriptor_t *pxBufferDescriptor = NULL;
- IPStackEvent_t xRxEvent;
- const TickType_t xBlockTime = pdMS_TO_TICKS( 5000ul );
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
- /* A possibility to set some additional task properties. */
-
- for( ;; )
- {
- 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 ) );
- }
-
- /* No events to process now, wait for the next. */
- ulTaskNotifyTake( pdFALSE, portMAX_DELAY );
- while(1)
- {
- /* get received frame */
- if ( numaker_eth_get_rx_buf(&dataLength, &buffer) != 0) {
- /* The event was lost because a network buffer was not available.
- Call the standard trace macro to log the occurrence. */
- iptraceETHERNET_RX_EVENT_LOST();
- break;
- }
-
- /* Allocate a network buffer descriptor that points to a buffer
- large enough to hold the received frame. As this is the simple
- rather than efficient example the received data will just be copied
- into this buffer. */
-
- pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( PACKET_BUFFER_SIZE, 0 );
-
- if( pxBufferDescriptor != NULL )
- {
- memcpy( pxBufferDescriptor->pucEthernetBuffer, buffer, dataLength );
-// FreeRTOS_printf(("--> dataLength=%d\n",dataLength));
- pxBufferDescriptor->xDataLength = dataLength;
- } else {
- numaker_eth_rx_next();
- iptraceETHERNET_RX_EVENT_LOST();
- break;
- }
- /* The event about to be sent to the TCP/IP is an Rx event. */
- xRxEvent.eEventType = eNetworkRxEvent;
-
- /* pvData is used to point to the network buffer descriptor that
- now references the received data. */
- xRxEvent.pvData = ( void * ) pxBufferDescriptor;
-
- /* Send the data to the TCP/IP stack. */
- if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
- {
- /* The buffer could not be sent to the IP task so the buffer
- must be released. */
- vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
-
- /* Make a call to the standard trace macro to log the
- occurrence. */
-
- iptraceETHERNET_RX_EVENT_LOST();
- } else
- {
- /* The message was successfully sent to the TCP/IP stack.
- Call the standard trace macro to log the occurrence. */
- iptraceNETWORK_INTERFACE_RECEIVE();
- }
- numaker_eth_rx_next();
- }
- numaker_eth_trigger_rx();
- }
-}
-
-void xNetworkCallback(char event)
-{
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
- switch (event)
- {
- case 'R': //For RX event
- /* Wakeup the prvEMACHandlerTask. */
- if( xRxHanderTask != NULL )
- {
- vTaskNotifyGiveFromISR( xRxHanderTask, &xHigherPriorityTaskWoken );
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
- }
- break;
- case 'T': //For TX event
- // ack of tx done, no-op in this stage
- break;
- default:
- break;
- }
-}
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2018 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 includes. */
+#include "FreeRTOS.h"
+#include "list.h"
+#include "queue.h"
+#include "semphr.h"
+#include "task.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+
+#include "m480_eth.h"
+
+/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
+driver will filter incoming packets and only pass the stack those packets it
+considers need processing. */
+#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
+#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+#else
+#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+#endif
+
+/* Default the size of the stack used by the EMAC deferred handler task to twice
+the size of the stack used by the idle task - but allow this to be overridden in
+FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
+#ifndef configEMAC_TASK_STACK_SIZE
+ #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
+#endif
+
+
+static SemaphoreHandle_t xTXMutex = NULL;
+
+/* The handle of the task that processes Rx packets. The handle is required so
+the task can be notified when new packets arrive. */
+static TaskHandle_t xRxHanderTask = NULL;
+static TimerHandle_t xPhyHandlerTask = NULL;
+/*
+ * A task that processes received frames.
+ */
+static void prvEMACHandlerTask( void *pvParameters );
+static void prvPhyTmrCallback( TimerHandle_t xTimer );
+
+/* The size of each buffer when BufferAllocation_1 is used:
+http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */
+
+#define niBUFFER_1_PACKET_SIZE 1536
+#ifdef __ICCARM__
+#pragma data_alignment=4
+static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ]
+#else
+static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ((aligned(4)));
+#endif
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+ uint8_t hwaddr[6];
+ BaseType_t xReturn = pdPASS;
+
+ /* Init ETH */
+ numaker_mac_address(hwaddr);
+ FreeRTOS_UpdateMACAddress(hwaddr);
+ FreeRTOS_printf( ("mac address %02x-%02x-%02x-%02x-%02x-%02x \r\n", hwaddr[0], hwaddr[1],hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5]) );
+ /* Enable clock & set EMAC configuration */
+ /* Enable MAC and DMA transmission and reception */
+ if( numaker_eth_init(hwaddr) < 0)
+ {
+ xReturn = pdFAIL;
+ } else {
+ xReturn = pdPASS;
+ /* Guard against the task being created more than once and the
+ descriptors being initialized more than once. */
+ /* Timer task to monitor PHY Link status */
+ if( xPhyHandlerTask == NULL )
+ {
+ xPhyHandlerTask = xTimerCreate( "TimerPhy", pdMS_TO_TICKS( 1000 ), pdTRUE, 0, prvPhyTmrCallback );
+ configASSERT(xPhyHandlerTask);
+ xReturn = xTimerStart( xPhyHandlerTask, 0 ) ;
+ configASSERT( xReturn );
+ }
+ /* Rx task */
+ if( xRxHanderTask == NULL )
+ {
+ xReturn = xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xRxHanderTask );
+ configASSERT( xReturn );
+ }
+
+ if( xTXMutex == NULL )
+ {
+ xTXMutex = xSemaphoreCreateMutex();
+ configASSERT( xTXMutex );
+ }
+ }
+
+ NVIC_SetPriority( EMAC_RX_IRQn, configMAC_INTERRUPT_PRIORITY );
+ NVIC_SetPriority( EMAC_TX_IRQn, configMAC_INTERRUPT_PRIORITY );
+
+ numaker_eth_enable_interrupts();
+
+ FreeRTOS_printf( ("ETH-RX priority:%d\n",NVIC_GetPriority( EMAC_RX_IRQn)) );
+
+ return xReturn;
+}
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t xReleaseAfterSend )
+{
+ uint8_t *buffer=NULL;
+// FreeRTOS_printf(("<-- dataLength=%d\n",pxDescriptor->xDataLength));
+ if( pxDescriptor->xDataLength >= PACKET_BUFFER_SIZE )
+ {
+ FreeRTOS_printf(("TX buffer length %d over %d\n", pxDescriptor->xDataLength, PACKET_BUFFER_SIZE));
+ return pdFALSE;
+ }
+
+ buffer = numaker_eth_get_tx_buf();
+ if( buffer == NULL )
+ {
+ NU_DEBUGF(("Eth TX slots are busy\n"));
+ return pdFALSE;
+ }
+
+ /* Get exclusive access */
+ xSemaphoreTake(xTXMutex, portMAX_DELAY);
+ NU_DEBUGF(("%s ... buffer=0x%x\r\n",__FUNCTION__, buffer));
+ //SendData: pt = pxDescriptor->pucBuffer, length = pxDescriptor->xDataLength
+ memcpy(buffer, pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength);
+ numaker_eth_trigger_tx(pxDescriptor->xDataLength, NULL);
+ /* Call the standard trace macro to log the send event. */
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+
+ if( xReleaseAfterSend != pdFALSE )
+ {
+ /* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet
+ buffer. The Ethernet buffer is therefore no longer needed, and must be
+ freed for re-use. */
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+
+ xSemaphoreGive(xTXMutex);
+
+ return pdTRUE;
+}
+
+
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
+{
+
+ uint8_t *ucRAMBuffer = ucNetworkPackets;
+ uint32_t ul;
+
+ for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
+ {
+ pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
+ *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
+ ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
+ }
+}
+
+
+BaseType_t xGetPhyLinkStatus( void )
+{
+ BaseType_t xReturn;
+
+ if( numaker_eth_link_ok() )
+ {
+ xReturn = pdPASS;
+ }
+ else
+ {
+ xReturn = pdFAIL;
+ }
+
+ return xReturn;
+}
+
+static void prvPhyTmrCallback( TimerHandle_t xTimer )
+{
+ IPStackEvent_t xRxEvent;
+ static BaseType_t lastLink = pdFAIL;
+ BaseType_t currLink = xGetPhyLinkStatus();
+ if( currLink != lastLink )
+ {
+ FreeRTOS_printf(("PHY Link %s\n", (currLink) ? "Up" : "Down"));
+ if( !currLink )
+ {
+ xRxEvent.eEventType = eNetworkDownEvent;
+ xSendEventStructToIPTask( &xRxEvent, 0 );
+ }
+ lastLink = currLink;
+ }
+
+}
+
+
+static void prvEMACHandlerTask( void *pvParameters )
+{
+ TimeOut_t xPhyTime;
+ TickType_t xPhyRemTime;
+ UBaseType_t uxLastMinBufferCount = 0;
+ UBaseType_t uxCurrentCount;
+ BaseType_t xResult = 0;
+ uint32_t ulStatus;
+ uint16_t dataLength = 0;
+ uint8_t *buffer = NULL;
+ NetworkBufferDescriptor_t *pxBufferDescriptor = NULL;
+ IPStackEvent_t xRxEvent;
+ const TickType_t xBlockTime = pdMS_TO_TICKS( 5000ul );
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+ /* A possibility to set some additional task properties. */
+
+ for( ;; )
+ {
+ 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 ) );
+ }
+
+ /* No events to process now, wait for the next. */
+ ulTaskNotifyTake( pdFALSE, portMAX_DELAY );
+ while(1)
+ {
+ /* get received frame */
+ if ( numaker_eth_get_rx_buf(&dataLength, &buffer) != 0) {
+ /* The event was lost because a network buffer was not available.
+ Call the standard trace macro to log the occurrence. */
+ iptraceETHERNET_RX_EVENT_LOST();
+ break;
+ }
+
+ /* Allocate a network buffer descriptor that points to a buffer
+ large enough to hold the received frame. As this is the simple
+ rather than efficient example the received data will just be copied
+ into this buffer. */
+
+ pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( PACKET_BUFFER_SIZE, 0 );
+
+ if( pxBufferDescriptor != NULL )
+ {
+ memcpy( pxBufferDescriptor->pucEthernetBuffer, buffer, dataLength );
+// FreeRTOS_printf(("--> dataLength=%d\n",dataLength));
+ pxBufferDescriptor->xDataLength = dataLength;
+ } else {
+ numaker_eth_rx_next();
+ iptraceETHERNET_RX_EVENT_LOST();
+ break;
+ }
+ /* The event about to be sent to the TCP/IP is an Rx event. */
+ xRxEvent.eEventType = eNetworkRxEvent;
+
+ /* pvData is used to point to the network buffer descriptor that
+ now references the received data. */
+ xRxEvent.pvData = ( void * ) pxBufferDescriptor;
+
+ /* Send the data to the TCP/IP stack. */
+ if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
+ {
+ /* The buffer could not be sent to the IP task so the buffer
+ must be released. */
+ vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
+
+ /* Make a call to the standard trace macro to log the
+ occurrence. */
+
+ iptraceETHERNET_RX_EVENT_LOST();
+ } else
+ {
+ /* The message was successfully sent to the TCP/IP stack.
+ Call the standard trace macro to log the occurrence. */
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ }
+ numaker_eth_rx_next();
+ }
+ numaker_eth_trigger_rx();
+ }
+}
+
+void xNetworkCallback(char event)
+{
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ switch (event)
+ {
+ case 'R': //For RX event
+ /* Wakeup the prvEMACHandlerTask. */
+ if( xRxHanderTask != NULL )
+ {
+ vTaskNotifyGiveFromISR( xRxHanderTask, &xHigherPriorityTaskWoken );
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+ }
+ break;
+ case 'T': //For TX event
+ // ack of tx done, no-op in this stage
+ break;
+ default:
+ break;
+ }
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.c
index cf862da3e..2d45661d0 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.c
@@ -1,448 +1,448 @@
-/**************************************************************************//**
- * @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of Nuvoton Technology Corp. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*****************************************************************************/
-#include "FreeRTOS.h"
-#include "list.h"
-#include "FreeRTOS_IP.h"
-
-#include "m480_eth.h"
-
-#define ETH_TRIGGER_RX() do{EMAC->RXST = 0;}while(0)
-#define ETH_TRIGGER_TX() do{EMAC->TXST = 0;}while(0)
-#define ETH_ENABLE_TX() do{EMAC->CTL |= EMAC_CTL_TXON;}while(0)
-#define ETH_ENABLE_RX() do{EMAC->CTL |= EMAC_CTL_RXON;}while(0)
-#define ETH_DISABLE_TX() do{EMAC->CTL &= ~EMAC_CTL_TXON;}while(0)
-#define ETH_DISABLE_RX() do{EMAC->CTL &= ~EMAC_CTL_RXON;}while(0)
-
-
-struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
-struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
-#ifdef __ICCARM__
-#pragma data_alignment=4
-struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM];
-struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM];
-uint8_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
-uint8_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
-#else
-struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
-struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
-uint8_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE] __attribute__ ((aligned(4)));
-uint8_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE] __attribute__ ((aligned(4)));
-#endif
-struct eth_descriptor volatile *cur_tx_desc_ptr, *cur_rx_desc_ptr, *fin_tx_desc_ptr;
-
-
-// PTP source clock is 84MHz (Real chip using PLL). Each tick is 11.90ns
-// Assume we want to set each tick to 100ns.
-// Increase register = (100 * 2^31) / (10^9) = 214.71 =~ 215 = 0xD7
-// Addend register = 2^32 * tick_freq / (84MHz), where tick_freq = (2^31 / 215) MHz
-// From above equation, addend register = 2^63 / (84M * 215) ~= 510707200 = 0x1E70C600
-
-
-
-static void mdio_write(uint8_t addr, uint8_t reg, uint16_t val)
-{
-
- EMAC->MIIMDAT = val;
- EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_WRITE_Msk | EMAC_MIIMCTL_MDCON_Msk;
-
- while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
-
-}
-
-
-static uint16_t mdio_read(uint8_t addr, uint8_t reg)
-{
- EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_MDCON_Msk;
- while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
-
- return(EMAC->MIIMDAT);
-}
-
-static int reset_phy(void)
-{
-
- uint16_t reg;
- uint32_t delayCnt;
-
-
- mdio_write(CONFIG_PHY_ADDR, MII_BMCR, BMCR_RESET);
-
- delayCnt = 2000;
- while(delayCnt-- > 0) {
- if((mdio_read(CONFIG_PHY_ADDR, MII_BMCR) & BMCR_RESET) == 0)
- break;
-
- }
-
- if(delayCnt == 0) {
- NU_DEBUGF(("Reset phy failed\n"));
- return(-1);
- }
-
- mdio_write(CONFIG_PHY_ADDR, MII_ADVERTISE, ADVERTISE_CSMA |
- ADVERTISE_10HALF |
- ADVERTISE_10FULL |
- ADVERTISE_100HALF |
- ADVERTISE_100FULL);
-
- reg = mdio_read(CONFIG_PHY_ADDR, MII_BMCR);
- mdio_write(CONFIG_PHY_ADDR, MII_BMCR, reg | BMCR_ANRESTART);
-
- delayCnt = 200000;
- while(delayCnt-- > 0) {
- if((mdio_read(CONFIG_PHY_ADDR, MII_BMSR) & (BMSR_ANEGCOMPLETE | BMSR_LSTATUS))
- == (BMSR_ANEGCOMPLETE | BMSR_LSTATUS))
- break;
- }
-
- if(delayCnt == 0) {
- NU_DEBUGF(("AN failed. Set to 100 FULL\n"));
- EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
- return(-1);
- } else {
- reg = mdio_read(CONFIG_PHY_ADDR, MII_LPA);
-
- if(reg & ADVERTISE_100FULL) {
- NU_DEBUGF(("100 full\n"));
- EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
- } else if(reg & ADVERTISE_100HALF) {
- NU_DEBUGF(("100 half\n"));
- EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_FUDUP_Msk) | EMAC_CTL_OPMODE_Msk;
- } else if(reg & ADVERTISE_10FULL) {
- NU_DEBUGF(("10 full\n"));
- EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_OPMODE_Msk) | EMAC_CTL_FUDUP_Msk;
- } else {
- NU_DEBUGF(("10 half\n"));
- EMAC->CTL &= ~(EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
- }
- }
- FreeRTOS_printf(("PHY ID 1:0x%x\r\n", mdio_read(CONFIG_PHY_ADDR, MII_PHYSID1)));
- FreeRTOS_printf(("PHY ID 2:0x%x\r\n", mdio_read(CONFIG_PHY_ADDR, MII_PHYSID2)));
-
- return(0);
-}
-
-
-static void init_tx_desc(void)
-{
- uint32_t i;
-
-
- cur_tx_desc_ptr = fin_tx_desc_ptr = &tx_desc[0];
-
- for(i = 0; i < TX_DESCRIPTOR_NUM; i++) {
- tx_desc[i].status1 = TXFD_PADEN | TXFD_CRCAPP | TXFD_INTEN;
- tx_desc[i].buf = &tx_buf[i][0];
- tx_desc[i].status2 = 0;
- tx_desc[i].next = &tx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
-
- }
- EMAC->TXDSA = (unsigned int)&tx_desc[0];
- return;
-}
-
-static void init_rx_desc(void)
-{
- uint32_t i;
-
-
- cur_rx_desc_ptr = &rx_desc[0];
-
- for(i = 0; i < RX_DESCRIPTOR_NUM; i++) {
- rx_desc[i].status1 = OWNERSHIP_EMAC;
- rx_desc[i].buf = &rx_buf[i][0];
- rx_desc[i].status2 = 0;
- rx_desc[i].next = &rx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
- }
- EMAC->RXDSA = (unsigned int)&rx_desc[0];
- return;
-}
-
-void numaker_set_mac_addr(uint8_t *addr)
-{
-
- EMAC->CAM0M = (addr[0] << 24) |
- (addr[1] << 16) |
- (addr[2] << 8) |
- addr[3];
-
- EMAC->CAM0L = (addr[4] << 24) |
- (addr[5] << 16);
-
-
-}
-
-static void __eth_clk_pin_init()
-{
- /* Unlock protected registers */
- SYS_UnlockReg();
-
- /* Enable IP clock */
- CLK_EnableModuleClock(EMAC_MODULE);
-
- // Configure MDC clock rate to HCLK / (127 + 1) = 1.25 MHz if system is running at 160 MH
- CLK_SetModuleClock(EMAC_MODULE, 0, CLK_CLKDIV3_EMAC(127));
-
- /* Update System Core Clock */
- SystemCoreClockUpdate();
-
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init I/O Multi-function */
- /*---------------------------------------------------------------------------------------------------------*/
- // Configure RMII pins
- SYS->GPA_MFPL &= ~(SYS_GPA_MFPL_PA6MFP_Msk | SYS_GPA_MFPL_PA7MFP_Msk);
- SYS->GPA_MFPL |= SYS_GPA_MFPL_PA6MFP_EMAC_RMII_RXERR | SYS_GPA_MFPL_PA7MFP_EMAC_RMII_CRSDV;
- SYS->GPC_MFPL &= ~(SYS_GPC_MFPL_PC6MFP_Msk | SYS_GPC_MFPL_PC7MFP_Msk);
- SYS->GPC_MFPL |= SYS_GPC_MFPL_PC6MFP_EMAC_RMII_RXD1 | SYS_GPC_MFPL_PC7MFP_EMAC_RMII_RXD0;
- SYS->GPC_MFPH &= ~SYS_GPC_MFPH_PC8MFP_Msk;
- SYS->GPC_MFPH |= SYS_GPC_MFPH_PC8MFP_EMAC_RMII_REFCLK;
- SYS->GPE_MFPH &= ~(SYS_GPE_MFPH_PE8MFP_Msk | SYS_GPE_MFPH_PE9MFP_Msk | SYS_GPE_MFPH_PE10MFP_Msk |
- SYS_GPE_MFPH_PE11MFP_Msk | SYS_GPE_MFPH_PE12MFP_Msk);
- SYS->GPE_MFPH |= SYS_GPE_MFPH_PE8MFP_EMAC_RMII_MDC |
- SYS_GPE_MFPH_PE9MFP_EMAC_RMII_MDIO |
- SYS_GPE_MFPH_PE10MFP_EMAC_RMII_TXD0 |
- SYS_GPE_MFPH_PE11MFP_EMAC_RMII_TXD1 |
- SYS_GPE_MFPH_PE12MFP_EMAC_RMII_TXEN;
-
- // Enable high slew rate on all RMII TX output pins
- PE->SLEWCTL = (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN10_Pos) |
- (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN11_Pos) |
- (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN12_Pos);
-
-
- /* Lock protected registers */
- SYS_LockReg();
-
-
-}
-
-int numaker_eth_init(uint8_t *mac_addr)
-{
- int ret = 0;
- // init CLK & pins
- __eth_clk_pin_init();
-
- // Reset MAC
- EMAC->CTL = EMAC_CTL_RST_Msk;
- while(EMAC->CTL & EMAC_CTL_RST_Msk) {}
-
- init_tx_desc();
- init_rx_desc();
-
- numaker_set_mac_addr(mac_addr); // need to reconfigure hardware address 'cos we just RESET emc...
-
-
- /* Configure the MAC interrupt enable register. */
- EMAC->INTEN = EMAC_INTEN_RXIEN_Msk |
- EMAC_INTEN_TXIEN_Msk |
- EMAC_INTEN_RXGDIEN_Msk |
- EMAC_INTEN_TXCPIEN_Msk |
- EMAC_INTEN_RXBEIEN_Msk |
- EMAC_INTEN_TXBEIEN_Msk |
- EMAC_INTEN_RDUIEN_Msk |
- EMAC_INTEN_TSALMIEN_Msk |
- EMAC_INTEN_WOLIEN_Msk;
-
- /* Configure the MAC control register. */
- EMAC->CTL = EMAC_CTL_STRIPCRC_Msk | EMAC_CTL_RMIIEN_Msk;
-
- /* Accept packets for us and all broadcast and multicast packets */
- EMAC->CAMCTL = EMAC_CAMCTL_CMPEN_Msk |
- EMAC_CAMCTL_AMP_Msk |
- EMAC_CAMCTL_ABP_Msk;
- EMAC->CAMEN = 1; // Enable CAM entry 0
-
- ret= reset_phy();
-
- EMAC_ENABLE_RX();
- EMAC_ENABLE_TX();
- return ret;
-}
-
-
-
-void ETH_halt(void)
-{
-
- EMAC->CTL &= ~(EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk);
-}
-
-unsigned int m_status;
-
-void EMAC_RX_IRQHandler(void)
-{
-// NU_DEBUGF(("%s ... \r\n", __FUNCTION__));
- m_status = EMAC->INTSTS & 0xFFFF;
- EMAC->INTSTS = m_status;
- if (m_status & EMAC_INTSTS_RXBEIF_Msk) {
- // Shouldn't goes here, unless descriptor corrupted
- NU_DEBUGF(("RX descriptor corrupted \r\n"));
- //return;
- }
- // FIX ME: for rx-event, to ack rx_isr into event queue
- xNetworkCallback('R');
-}
-
-
-void numaker_eth_trigger_rx(void)
-{
- ETH_TRIGGER_RX();
-}
-
-int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf)
-{
- unsigned int cur_entry, status;
-
- cur_entry = EMAC->CRXDSA;
- if ((cur_entry == (uint32_t)cur_rx_desc_ptr) && (!(m_status & EMAC_INTSTS_RDUIF_Msk))) // cur_entry may equal to cur_rx_desc_ptr if RDU occures
- return -1;
- status = cur_rx_desc_ptr->status1;
-
- if(status & OWNERSHIP_EMAC)
- return -1;
-
- if (status & RXFD_RXGD) {
- *buf = cur_rx_desc_ptr->buf;
- *len = status & 0xFFFF;
- }
- return 0;
-}
-
-void numaker_eth_rx_next(void)
-{
- cur_rx_desc_ptr->status1 = OWNERSHIP_EMAC;
- cur_rx_desc_ptr = cur_rx_desc_ptr->next;
-}
-
-void EMAC_TX_IRQHandler(void)
-{
- unsigned int cur_entry, status;
-
- status = EMAC->INTSTS & 0xFFFF0000;
- EMAC->INTSTS = status;
- if(status & EMAC_INTSTS_TXBEIF_Msk) {
- // Shouldn't goes here, unless descriptor corrupted
- return;
- }
-
- cur_entry = EMAC->CTXDSA;
-
- while (cur_entry != (uint32_t)fin_tx_desc_ptr) {
-
- fin_tx_desc_ptr = fin_tx_desc_ptr->next;
- }
- // FIX ME: for tx-event, no-op at this stage
- xNetworkCallback('T');
-}
-
-uint8_t *numaker_eth_get_tx_buf(void)
-{
- if(cur_tx_desc_ptr->status1 & OWNERSHIP_EMAC)
- return(NULL);
- else
- return(cur_tx_desc_ptr->buf);
-}
-
-void numaker_eth_trigger_tx(uint16_t length, void *p)
-{
- struct eth_descriptor volatile *desc;
- cur_tx_desc_ptr->status2 = (unsigned int)length;
- desc = cur_tx_desc_ptr->next; // in case TX is transmitting and overwrite next pointer before we can update cur_tx_desc_ptr
- cur_tx_desc_ptr->status1 |= OWNERSHIP_EMAC;
- cur_tx_desc_ptr = desc;
-
- ETH_TRIGGER_TX();
-
-}
-
-int numaker_eth_link_ok(void)
-{
- /* first, a dummy read to latch */
- mdio_read(CONFIG_PHY_ADDR, MII_BMSR);
- if(mdio_read(CONFIG_PHY_ADDR, MII_BMSR) & BMSR_LSTATUS)
- return 1;
- return 0;
-}
-
-//void numaker_eth_set_cb(eth_callback_t eth_cb, void *userData)
-//{
-// nu_eth_txrx_cb = eth_cb;
-// nu_userData = userData;
-//}
-
-// Provide ethernet devices with a semi-unique MAC address
-void numaker_mac_address(uint8_t *mac)
-{
- uint32_t uID1;
- // Fetch word 0
- uint32_t word0 = *(uint32_t *)0x7F804; // 2KB Data Flash at 0x7F800
- // Fetch word 1
- // we only want bottom 16 bits of word1 (MAC bits 32-47)
- // and bit 9 forced to 1, bit 8 forced to 0
- // Locally administered MAC, reduced conflicts
- // http://en.wikipedia.org/wiki/MAC_address
- uint32_t word1 = *(uint32_t *)0x7F800; // 2KB Data Flash at 0x7F800
-
- if( word0 == 0xFFFFFFFF ) // Not burn any mac address at 1st 2 words of Data Flash
- {
- // with a semi-unique MAC address from the UUID
- /* Enable FMC ISP function */
- SYS_UnlockReg();
- FMC_Open();
- // = FMC_ReadUID(0);
- uID1 = FMC_ReadUID(1);
- word1 = (uID1 & 0x003FFFFF) | ((uID1 & 0x030000) << 6) >> 8;
- word0 = ((FMC_ReadUID(0) >> 4) << 20) | ((uID1 & 0xFF)<<12) | (FMC_ReadUID(2) & 0xFFF);
- /* Disable FMC ISP function */
- FMC_Close();
- /* Lock protected registers */
- SYS_LockReg();
- }
-
- word1 |= 0x00000200;
- word1 &= 0x0000FEFF;
-
- mac[0] = (word1 & 0x0000ff00) >> 8;
- mac[1] = (word1 & 0x000000ff);
- mac[2] = (word0 & 0xff000000) >> 24;
- mac[3] = (word0 & 0x00ff0000) >> 16;
- mac[4] = (word0 & 0x0000ff00) >> 8;
- mac[5] = (word0 & 0x000000ff);
-
- NU_DEBUGF(("mac address %02x-%02x-%02x-%02x-%02x-%02x \r\n", mac[0], mac[1],mac[2],mac[3],mac[4],mac[5]));
-}
-
-void numaker_eth_enable_interrupts(void) {
- EMAC->INTEN |= EMAC_INTEN_RXIEN_Msk |
- EMAC_INTEN_TXIEN_Msk ;
- NVIC_EnableIRQ(EMAC_RX_IRQn);
- NVIC_EnableIRQ(EMAC_TX_IRQn);
-}
-
-void numaker_eth_disable_interrupts(void) {
- NVIC_DisableIRQ(EMAC_RX_IRQn);
- NVIC_DisableIRQ(EMAC_TX_IRQn);
-}
+/**************************************************************************//**
+ * @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Nuvoton Technology Corp. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*****************************************************************************/
+#include "FreeRTOS.h"
+#include "list.h"
+#include "FreeRTOS_IP.h"
+
+#include "m480_eth.h"
+
+#define ETH_TRIGGER_RX() do{EMAC->RXST = 0;}while(0)
+#define ETH_TRIGGER_TX() do{EMAC->TXST = 0;}while(0)
+#define ETH_ENABLE_TX() do{EMAC->CTL |= EMAC_CTL_TXON;}while(0)
+#define ETH_ENABLE_RX() do{EMAC->CTL |= EMAC_CTL_RXON;}while(0)
+#define ETH_DISABLE_TX() do{EMAC->CTL &= ~EMAC_CTL_TXON;}while(0)
+#define ETH_DISABLE_RX() do{EMAC->CTL &= ~EMAC_CTL_RXON;}while(0)
+
+
+struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
+struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
+#ifdef __ICCARM__
+#pragma data_alignment=4
+struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM];
+struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM];
+uint8_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
+uint8_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
+#else
+struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
+struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
+uint8_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE] __attribute__ ((aligned(4)));
+uint8_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE] __attribute__ ((aligned(4)));
+#endif
+struct eth_descriptor volatile *cur_tx_desc_ptr, *cur_rx_desc_ptr, *fin_tx_desc_ptr;
+
+
+// PTP source clock is 84MHz (Real chip using PLL). Each tick is 11.90ns
+// Assume we want to set each tick to 100ns.
+// Increase register = (100 * 2^31) / (10^9) = 214.71 =~ 215 = 0xD7
+// Addend register = 2^32 * tick_freq / (84MHz), where tick_freq = (2^31 / 215) MHz
+// From above equation, addend register = 2^63 / (84M * 215) ~= 510707200 = 0x1E70C600
+
+
+
+static void mdio_write(uint8_t addr, uint8_t reg, uint16_t val)
+{
+
+ EMAC->MIIMDAT = val;
+ EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_WRITE_Msk | EMAC_MIIMCTL_MDCON_Msk;
+
+ while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
+
+}
+
+
+static uint16_t mdio_read(uint8_t addr, uint8_t reg)
+{
+ EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_MDCON_Msk;
+ while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
+
+ return(EMAC->MIIMDAT);
+}
+
+static int reset_phy(void)
+{
+
+ uint16_t reg;
+ uint32_t delayCnt;
+
+
+ mdio_write(CONFIG_PHY_ADDR, MII_BMCR, BMCR_RESET);
+
+ delayCnt = 2000;
+ while(delayCnt-- > 0) {
+ if((mdio_read(CONFIG_PHY_ADDR, MII_BMCR) & BMCR_RESET) == 0)
+ break;
+
+ }
+
+ if(delayCnt == 0) {
+ NU_DEBUGF(("Reset phy failed\n"));
+ return(-1);
+ }
+
+ mdio_write(CONFIG_PHY_ADDR, MII_ADVERTISE, ADVERTISE_CSMA |
+ ADVERTISE_10HALF |
+ ADVERTISE_10FULL |
+ ADVERTISE_100HALF |
+ ADVERTISE_100FULL);
+
+ reg = mdio_read(CONFIG_PHY_ADDR, MII_BMCR);
+ mdio_write(CONFIG_PHY_ADDR, MII_BMCR, reg | BMCR_ANRESTART);
+
+ delayCnt = 200000;
+ while(delayCnt-- > 0) {
+ if((mdio_read(CONFIG_PHY_ADDR, MII_BMSR) & (BMSR_ANEGCOMPLETE | BMSR_LSTATUS))
+ == (BMSR_ANEGCOMPLETE | BMSR_LSTATUS))
+ break;
+ }
+
+ if(delayCnt == 0) {
+ NU_DEBUGF(("AN failed. Set to 100 FULL\n"));
+ EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
+ return(-1);
+ } else {
+ reg = mdio_read(CONFIG_PHY_ADDR, MII_LPA);
+
+ if(reg & ADVERTISE_100FULL) {
+ NU_DEBUGF(("100 full\n"));
+ EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
+ } else if(reg & ADVERTISE_100HALF) {
+ NU_DEBUGF(("100 half\n"));
+ EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_FUDUP_Msk) | EMAC_CTL_OPMODE_Msk;
+ } else if(reg & ADVERTISE_10FULL) {
+ NU_DEBUGF(("10 full\n"));
+ EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_OPMODE_Msk) | EMAC_CTL_FUDUP_Msk;
+ } else {
+ NU_DEBUGF(("10 half\n"));
+ EMAC->CTL &= ~(EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
+ }
+ }
+ FreeRTOS_printf(("PHY ID 1:0x%x\r\n", mdio_read(CONFIG_PHY_ADDR, MII_PHYSID1)));
+ FreeRTOS_printf(("PHY ID 2:0x%x\r\n", mdio_read(CONFIG_PHY_ADDR, MII_PHYSID2)));
+
+ return(0);
+}
+
+
+static void init_tx_desc(void)
+{
+ uint32_t i;
+
+
+ cur_tx_desc_ptr = fin_tx_desc_ptr = &tx_desc[0];
+
+ for(i = 0; i < TX_DESCRIPTOR_NUM; i++) {
+ tx_desc[i].status1 = TXFD_PADEN | TXFD_CRCAPP | TXFD_INTEN;
+ tx_desc[i].buf = &tx_buf[i][0];
+ tx_desc[i].status2 = 0;
+ tx_desc[i].next = &tx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
+
+ }
+ EMAC->TXDSA = (unsigned int)&tx_desc[0];
+ return;
+}
+
+static void init_rx_desc(void)
+{
+ uint32_t i;
+
+
+ cur_rx_desc_ptr = &rx_desc[0];
+
+ for(i = 0; i < RX_DESCRIPTOR_NUM; i++) {
+ rx_desc[i].status1 = OWNERSHIP_EMAC;
+ rx_desc[i].buf = &rx_buf[i][0];
+ rx_desc[i].status2 = 0;
+ rx_desc[i].next = &rx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
+ }
+ EMAC->RXDSA = (unsigned int)&rx_desc[0];
+ return;
+}
+
+void numaker_set_mac_addr(uint8_t *addr)
+{
+
+ EMAC->CAM0M = (addr[0] << 24) |
+ (addr[1] << 16) |
+ (addr[2] << 8) |
+ addr[3];
+
+ EMAC->CAM0L = (addr[4] << 24) |
+ (addr[5] << 16);
+
+
+}
+
+static void __eth_clk_pin_init()
+{
+ /* Unlock protected registers */
+ SYS_UnlockReg();
+
+ /* Enable IP clock */
+ CLK_EnableModuleClock(EMAC_MODULE);
+
+ // Configure MDC clock rate to HCLK / (127 + 1) = 1.25 MHz if system is running at 160 MH
+ CLK_SetModuleClock(EMAC_MODULE, 0, CLK_CLKDIV3_EMAC(127));
+
+ /* Update System Core Clock */
+ SystemCoreClockUpdate();
+
+ /*---------------------------------------------------------------------------------------------------------*/
+ /* Init I/O Multi-function */
+ /*---------------------------------------------------------------------------------------------------------*/
+ // Configure RMII pins
+ SYS->GPA_MFPL &= ~(SYS_GPA_MFPL_PA6MFP_Msk | SYS_GPA_MFPL_PA7MFP_Msk);
+ SYS->GPA_MFPL |= SYS_GPA_MFPL_PA6MFP_EMAC_RMII_RXERR | SYS_GPA_MFPL_PA7MFP_EMAC_RMII_CRSDV;
+ SYS->GPC_MFPL &= ~(SYS_GPC_MFPL_PC6MFP_Msk | SYS_GPC_MFPL_PC7MFP_Msk);
+ SYS->GPC_MFPL |= SYS_GPC_MFPL_PC6MFP_EMAC_RMII_RXD1 | SYS_GPC_MFPL_PC7MFP_EMAC_RMII_RXD0;
+ SYS->GPC_MFPH &= ~SYS_GPC_MFPH_PC8MFP_Msk;
+ SYS->GPC_MFPH |= SYS_GPC_MFPH_PC8MFP_EMAC_RMII_REFCLK;
+ SYS->GPE_MFPH &= ~(SYS_GPE_MFPH_PE8MFP_Msk | SYS_GPE_MFPH_PE9MFP_Msk | SYS_GPE_MFPH_PE10MFP_Msk |
+ SYS_GPE_MFPH_PE11MFP_Msk | SYS_GPE_MFPH_PE12MFP_Msk);
+ SYS->GPE_MFPH |= SYS_GPE_MFPH_PE8MFP_EMAC_RMII_MDC |
+ SYS_GPE_MFPH_PE9MFP_EMAC_RMII_MDIO |
+ SYS_GPE_MFPH_PE10MFP_EMAC_RMII_TXD0 |
+ SYS_GPE_MFPH_PE11MFP_EMAC_RMII_TXD1 |
+ SYS_GPE_MFPH_PE12MFP_EMAC_RMII_TXEN;
+
+ // Enable high slew rate on all RMII TX output pins
+ PE->SLEWCTL = (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN10_Pos) |
+ (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN11_Pos) |
+ (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN12_Pos);
+
+
+ /* Lock protected registers */
+ SYS_LockReg();
+
+
+}
+
+int numaker_eth_init(uint8_t *mac_addr)
+{
+ int ret = 0;
+ // init CLK & pins
+ __eth_clk_pin_init();
+
+ // Reset MAC
+ EMAC->CTL = EMAC_CTL_RST_Msk;
+ while(EMAC->CTL & EMAC_CTL_RST_Msk) {}
+
+ init_tx_desc();
+ init_rx_desc();
+
+ numaker_set_mac_addr(mac_addr); // need to reconfigure hardware address 'cos we just RESET emc...
+
+
+ /* Configure the MAC interrupt enable register. */
+ EMAC->INTEN = EMAC_INTEN_RXIEN_Msk |
+ EMAC_INTEN_TXIEN_Msk |
+ EMAC_INTEN_RXGDIEN_Msk |
+ EMAC_INTEN_TXCPIEN_Msk |
+ EMAC_INTEN_RXBEIEN_Msk |
+ EMAC_INTEN_TXBEIEN_Msk |
+ EMAC_INTEN_RDUIEN_Msk |
+ EMAC_INTEN_TSALMIEN_Msk |
+ EMAC_INTEN_WOLIEN_Msk;
+
+ /* Configure the MAC control register. */
+ EMAC->CTL = EMAC_CTL_STRIPCRC_Msk | EMAC_CTL_RMIIEN_Msk;
+
+ /* Accept packets for us and all broadcast and multicast packets */
+ EMAC->CAMCTL = EMAC_CAMCTL_CMPEN_Msk |
+ EMAC_CAMCTL_AMP_Msk |
+ EMAC_CAMCTL_ABP_Msk;
+ EMAC->CAMEN = 1; // Enable CAM entry 0
+
+ ret= reset_phy();
+
+ EMAC_ENABLE_RX();
+ EMAC_ENABLE_TX();
+ return ret;
+}
+
+
+
+void ETH_halt(void)
+{
+
+ EMAC->CTL &= ~(EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk);
+}
+
+unsigned int m_status;
+
+void EMAC_RX_IRQHandler(void)
+{
+// NU_DEBUGF(("%s ... \r\n", __FUNCTION__));
+ m_status = EMAC->INTSTS & 0xFFFF;
+ EMAC->INTSTS = m_status;
+ if (m_status & EMAC_INTSTS_RXBEIF_Msk) {
+ // Shouldn't goes here, unless descriptor corrupted
+ NU_DEBUGF(("RX descriptor corrupted \r\n"));
+ //return;
+ }
+ // FIX ME: for rx-event, to ack rx_isr into event queue
+ xNetworkCallback('R');
+}
+
+
+void numaker_eth_trigger_rx(void)
+{
+ ETH_TRIGGER_RX();
+}
+
+int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf)
+{
+ unsigned int cur_entry, status;
+
+ cur_entry = EMAC->CRXDSA;
+ if ((cur_entry == (uint32_t)cur_rx_desc_ptr) && (!(m_status & EMAC_INTSTS_RDUIF_Msk))) // cur_entry may equal to cur_rx_desc_ptr if RDU occures
+ return -1;
+ status = cur_rx_desc_ptr->status1;
+
+ if(status & OWNERSHIP_EMAC)
+ return -1;
+
+ if (status & RXFD_RXGD) {
+ *buf = cur_rx_desc_ptr->buf;
+ *len = status & 0xFFFF;
+ }
+ return 0;
+}
+
+void numaker_eth_rx_next(void)
+{
+ cur_rx_desc_ptr->status1 = OWNERSHIP_EMAC;
+ cur_rx_desc_ptr = cur_rx_desc_ptr->next;
+}
+
+void EMAC_TX_IRQHandler(void)
+{
+ unsigned int cur_entry, status;
+
+ status = EMAC->INTSTS & 0xFFFF0000;
+ EMAC->INTSTS = status;
+ if(status & EMAC_INTSTS_TXBEIF_Msk) {
+ // Shouldn't goes here, unless descriptor corrupted
+ return;
+ }
+
+ cur_entry = EMAC->CTXDSA;
+
+ while (cur_entry != (uint32_t)fin_tx_desc_ptr) {
+
+ fin_tx_desc_ptr = fin_tx_desc_ptr->next;
+ }
+ // FIX ME: for tx-event, no-op at this stage
+ xNetworkCallback('T');
+}
+
+uint8_t *numaker_eth_get_tx_buf(void)
+{
+ if(cur_tx_desc_ptr->status1 & OWNERSHIP_EMAC)
+ return(NULL);
+ else
+ return(cur_tx_desc_ptr->buf);
+}
+
+void numaker_eth_trigger_tx(uint16_t length, void *p)
+{
+ struct eth_descriptor volatile *desc;
+ cur_tx_desc_ptr->status2 = (unsigned int)length;
+ desc = cur_tx_desc_ptr->next; // in case TX is transmitting and overwrite next pointer before we can update cur_tx_desc_ptr
+ cur_tx_desc_ptr->status1 |= OWNERSHIP_EMAC;
+ cur_tx_desc_ptr = desc;
+
+ ETH_TRIGGER_TX();
+
+}
+
+int numaker_eth_link_ok(void)
+{
+ /* first, a dummy read to latch */
+ mdio_read(CONFIG_PHY_ADDR, MII_BMSR);
+ if(mdio_read(CONFIG_PHY_ADDR, MII_BMSR) & BMSR_LSTATUS)
+ return 1;
+ return 0;
+}
+
+//void numaker_eth_set_cb(eth_callback_t eth_cb, void *userData)
+//{
+// nu_eth_txrx_cb = eth_cb;
+// nu_userData = userData;
+//}
+
+// Provide ethernet devices with a semi-unique MAC address
+void numaker_mac_address(uint8_t *mac)
+{
+ uint32_t uID1;
+ // Fetch word 0
+ uint32_t word0 = *(uint32_t *)0x7F804; // 2KB Data Flash at 0x7F800
+ // Fetch word 1
+ // we only want bottom 16 bits of word1 (MAC bits 32-47)
+ // and bit 9 forced to 1, bit 8 forced to 0
+ // Locally administered MAC, reduced conflicts
+ // http://en.wikipedia.org/wiki/MAC_address
+ uint32_t word1 = *(uint32_t *)0x7F800; // 2KB Data Flash at 0x7F800
+
+ if( word0 == 0xFFFFFFFF ) // Not burn any mac address at 1st 2 words of Data Flash
+ {
+ // with a semi-unique MAC address from the UUID
+ /* Enable FMC ISP function */
+ SYS_UnlockReg();
+ FMC_Open();
+ // = FMC_ReadUID(0);
+ uID1 = FMC_ReadUID(1);
+ word1 = (uID1 & 0x003FFFFF) | ((uID1 & 0x030000) << 6) >> 8;
+ word0 = ((FMC_ReadUID(0) >> 4) << 20) | ((uID1 & 0xFF)<<12) | (FMC_ReadUID(2) & 0xFFF);
+ /* Disable FMC ISP function */
+ FMC_Close();
+ /* Lock protected registers */
+ SYS_LockReg();
+ }
+
+ word1 |= 0x00000200;
+ word1 &= 0x0000FEFF;
+
+ mac[0] = (word1 & 0x0000ff00) >> 8;
+ mac[1] = (word1 & 0x000000ff);
+ mac[2] = (word0 & 0xff000000) >> 24;
+ mac[3] = (word0 & 0x00ff0000) >> 16;
+ mac[4] = (word0 & 0x0000ff00) >> 8;
+ mac[5] = (word0 & 0x000000ff);
+
+ NU_DEBUGF(("mac address %02x-%02x-%02x-%02x-%02x-%02x \r\n", mac[0], mac[1],mac[2],mac[3],mac[4],mac[5]));
+}
+
+void numaker_eth_enable_interrupts(void) {
+ EMAC->INTEN |= EMAC_INTEN_RXIEN_Msk |
+ EMAC_INTEN_TXIEN_Msk ;
+ NVIC_EnableIRQ(EMAC_RX_IRQn);
+ NVIC_EnableIRQ(EMAC_TX_IRQn);
+}
+
+void numaker_eth_disable_interrupts(void) {
+ NVIC_DisableIRQ(EMAC_RX_IRQn);
+ NVIC_DisableIRQ(EMAC_TX_IRQn);
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.h
index 3d370bca7..4e4d98d6d 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.h
@@ -1,164 +1,164 @@
-/**************************************************************************//**
- * @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of Nuvoton Technology Corp. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*****************************************************************************/
-#include "M480.h"
-#ifndef _M480_ETH_
-#define _M480_ETH_
-
-/* Generic MII registers. */
-
-#define MII_BMCR 0x00 /* Basic mode control register */
-#define MII_BMSR 0x01 /* Basic mode status register */
-#define MII_PHYSID1 0x02 /* PHYS ID 1 */
-#define MII_PHYSID2 0x03 /* PHYS ID 2 */
-#define MII_ADVERTISE 0x04 /* Advertisement control reg */
-#define MII_LPA 0x05 /* Link partner ability reg */
-#define MII_EXPANSION 0x06 /* Expansion register */
-#define MII_DCOUNTER 0x12 /* Disconnect counter */
-#define MII_FCSCOUNTER 0x13 /* False carrier counter */
-#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
-#define MII_RERRCOUNTER 0x15 /* Receive error counter */
-#define MII_SREVISION 0x16 /* Silicon revision */
-#define MII_RESV1 0x17 /* Reserved... */
-#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
-#define MII_PHYADDR 0x19 /* PHY address */
-#define MII_RESV2 0x1a /* Reserved... */
-#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
-#define MII_NCONFIG 0x1c /* Network interface config */
-
-/* Basic mode control register. */
-#define BMCR_RESV 0x007f /* Unused... */
-#define BMCR_CTST 0x0080 /* Collision test */
-#define BMCR_FULLDPLX 0x0100 /* Full duplex */
-#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
-#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
-#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
-#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
-#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
-#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
-#define BMCR_RESET 0x8000 /* Reset the DP83840 */
-
-/* Basic mode status register. */
-#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
-#define BMSR_JCD 0x0002 /* Jabber detected */
-#define BMSR_LSTATUS 0x0004 /* Link status */
-#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
-#define BMSR_RFAULT 0x0010 /* Remote fault detected */
-#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
-#define BMSR_RESV 0x07c0 /* Unused... */
-#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
-#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
-#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
-#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
-#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
-
-/* Advertisement control register. */
-#define ADVERTISE_SLCT 0x001f /* Selector bits */
-#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
-#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
-#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
-#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
-#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
-#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
-#define ADVERTISE_RESV 0x1c00 /* Unused... */
-#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
-#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
-#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
-
-#define RX_DESCRIPTOR_NUM 4 //8 // Max Number of Rx Frame Descriptors
-#define TX_DESCRIPTOR_NUM 2 //4 // Max number of Tx Frame Descriptors
-
-#define PACKET_BUFFER_SIZE 1520
-
-#define CONFIG_PHY_ADDR 1
-
-
-// Frame Descriptor's Owner bit
-#define OWNERSHIP_EMAC 0x80000000 // 1 = EMAC
-//#define OWNERSHIP_CPU 0x7fffffff // 0 = CPU
-
-
-
-// Rx Frame Descriptor Status
-#define RXFD_RXGD 0x00100000 // Receiving Good Packet Received
-#define RXFD_RTSAS 0x00800000 // RX Time Stamp Available
-
-
-// Tx Frame Descriptor's Control bits
-#define TXFD_TTSEN 0x08 // Tx Time Stamp Enable
-#define TXFD_INTEN 0x04 // Interrupt Enable
-#define TXFD_CRCAPP 0x02 // Append CRC
-#define TXFD_PADEN 0x01 // Padding Enable
-
-// Tx Frame Descriptor Status
-#define TXFD_TXCP 0x00080000 // Transmission Completion
-#define TXFD_TTSAS 0x08000000 // TX Time Stamp Available
-
-// Tx/Rx buffer descriptor structure
-struct eth_descriptor;
-struct eth_descriptor {
- uint32_t status1;
- uint8_t *buf;
- uint32_t status2;
- struct eth_descriptor *next;
-#ifdef TIME_STAMPING
- uint32_t backup1;
- uint32_t backup2;
- uint32_t reserved1;
- uint32_t reserved2;
-#endif
-};
-
-#ifdef TIME_STAMPING
-
-#define ETH_TS_ENABLE() do{EMAC->TSCTL = EMAC_TSCTL_TSEN_Msk;}while(0)
-#define ETH_TS_START() do{EMAC->TSCTL |= (EMAC_TSCTL_TSMODE_Msk | EMAC_TSCTL_TSIEN_Msk);}while(0)
-s32_t ETH_settime(u32_t sec, u32_t nsec);
-s32_t ETH_gettime(u32_t *sec, u32_t *nsec);
-s32_t ETH_updatetime(u32_t neg, u32_t sec, u32_t nsec);
-s32_t ETH_adjtimex(int ppm);
-void ETH_setinc(void);
-
-#endif
-
-#ifdef NU_TRACE
-#define NU_DEBUGF(x) { printf x; }
-#else
-#define NU_DEBUGF(x)
-#endif
-
-void numaker_set_mac_addr(uint8_t *addr);
-int numaker_eth_init(uint8_t *mac_addr);
-uint8_t *numaker_eth_get_tx_buf(void);
-void numaker_eth_trigger_tx(uint16_t length, void *p);
-int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf);
-void numaker_eth_rx_next(void);
-void numaker_eth_trigger_rx(void);
-int numaker_eth_link_ok(void);
-void numaker_mac_address(uint8_t *mac);
-void numaker_eth_enable_interrupts(void);
-void numaker_eth_disable_interrupts(void);
-
-#endif /* _M480_ETH_ */
+/**************************************************************************//**
+ * @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Nuvoton Technology Corp. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*****************************************************************************/
+#include "M480.h"
+#ifndef _M480_ETH_
+#define _M480_ETH_
+
+/* Generic MII registers. */
+
+#define MII_BMCR 0x00 /* Basic mode control register */
+#define MII_BMSR 0x01 /* Basic mode status register */
+#define MII_PHYSID1 0x02 /* PHYS ID 1 */
+#define MII_PHYSID2 0x03 /* PHYS ID 2 */
+#define MII_ADVERTISE 0x04 /* Advertisement control reg */
+#define MII_LPA 0x05 /* Link partner ability reg */
+#define MII_EXPANSION 0x06 /* Expansion register */
+#define MII_DCOUNTER 0x12 /* Disconnect counter */
+#define MII_FCSCOUNTER 0x13 /* False carrier counter */
+#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
+#define MII_RERRCOUNTER 0x15 /* Receive error counter */
+#define MII_SREVISION 0x16 /* Silicon revision */
+#define MII_RESV1 0x17 /* Reserved... */
+#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
+#define MII_PHYADDR 0x19 /* PHY address */
+#define MII_RESV2 0x1a /* Reserved... */
+#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
+#define MII_NCONFIG 0x1c /* Network interface config */
+
+/* Basic mode control register. */
+#define BMCR_RESV 0x007f /* Unused... */
+#define BMCR_CTST 0x0080 /* Collision test */
+#define BMCR_FULLDPLX 0x0100 /* Full duplex */
+#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
+#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
+#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
+#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
+#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
+#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
+#define BMCR_RESET 0x8000 /* Reset the DP83840 */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
+#define BMSR_JCD 0x0002 /* Jabber detected */
+#define BMSR_LSTATUS 0x0004 /* Link status */
+#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
+#define BMSR_RFAULT 0x0010 /* Remote fault detected */
+#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
+#define BMSR_RESV 0x07c0 /* Unused... */
+#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
+#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
+#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
+
+/* Advertisement control register. */
+#define ADVERTISE_SLCT 0x001f /* Selector bits */
+#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
+#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
+#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
+#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
+#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
+#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
+#define ADVERTISE_RESV 0x1c00 /* Unused... */
+#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
+#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
+#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
+
+#define RX_DESCRIPTOR_NUM 4 //8 // Max Number of Rx Frame Descriptors
+#define TX_DESCRIPTOR_NUM 2 //4 // Max number of Tx Frame Descriptors
+
+#define PACKET_BUFFER_SIZE 1520
+
+#define CONFIG_PHY_ADDR 1
+
+
+// Frame Descriptor's Owner bit
+#define OWNERSHIP_EMAC 0x80000000 // 1 = EMAC
+//#define OWNERSHIP_CPU 0x7fffffff // 0 = CPU
+
+
+
+// Rx Frame Descriptor Status
+#define RXFD_RXGD 0x00100000 // Receiving Good Packet Received
+#define RXFD_RTSAS 0x00800000 // RX Time Stamp Available
+
+
+// Tx Frame Descriptor's Control bits
+#define TXFD_TTSEN 0x08 // Tx Time Stamp Enable
+#define TXFD_INTEN 0x04 // Interrupt Enable
+#define TXFD_CRCAPP 0x02 // Append CRC
+#define TXFD_PADEN 0x01 // Padding Enable
+
+// Tx Frame Descriptor Status
+#define TXFD_TXCP 0x00080000 // Transmission Completion
+#define TXFD_TTSAS 0x08000000 // TX Time Stamp Available
+
+// Tx/Rx buffer descriptor structure
+struct eth_descriptor;
+struct eth_descriptor {
+ uint32_t status1;
+ uint8_t *buf;
+ uint32_t status2;
+ struct eth_descriptor *next;
+#ifdef TIME_STAMPING
+ uint32_t backup1;
+ uint32_t backup2;
+ uint32_t reserved1;
+ uint32_t reserved2;
+#endif
+};
+
+#ifdef TIME_STAMPING
+
+#define ETH_TS_ENABLE() do{EMAC->TSCTL = EMAC_TSCTL_TSEN_Msk;}while(0)
+#define ETH_TS_START() do{EMAC->TSCTL |= (EMAC_TSCTL_TSMODE_Msk | EMAC_TSCTL_TSIEN_Msk);}while(0)
+s32_t ETH_settime(u32_t sec, u32_t nsec);
+s32_t ETH_gettime(u32_t *sec, u32_t *nsec);
+s32_t ETH_updatetime(u32_t neg, u32_t sec, u32_t nsec);
+s32_t ETH_adjtimex(int ppm);
+void ETH_setinc(void);
+
+#endif
+
+#ifdef NU_TRACE
+#define NU_DEBUGF(x) { printf x; }
+#else
+#define NU_DEBUGF(x)
+#endif
+
+void numaker_set_mac_addr(uint8_t *addr);
+int numaker_eth_init(uint8_t *mac_addr);
+uint8_t *numaker_eth_get_tx_buf(void);
+void numaker_eth_trigger_tx(uint16_t length, void *p);
+int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf);
+void numaker_eth_rx_next(void);
+void numaker_eth_trigger_rx(void);
+int numaker_eth_link_ok(void);
+void numaker_mac_address(uint8_t *mac);
+void numaker_eth_enable_interrupts(void);
+void numaker_eth_disable_interrupts(void);
+
+#endif /* _M480_ETH_ */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c
index 139979cce..ebcbfbec9 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c
@@ -1,622 +1,622 @@
-/***********************************************************************************************************************
-* DISCLAIMER
-* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
-* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
-* applicable laws, including copyright laws.
-* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
-* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
-* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
-* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
-* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
-* this software. By using this software, you agree to the additional terms and conditions found by accessing the
-* following link:
-* http://www.renesas.com/disclaimer
-*
-* Copyright (C) 2018 Renesas Electronics Corporation. All rights reserved.
-***********************************************************************************************************************/
-
-/***********************************************************************************************************************
-* File Name : NetworkInterface.c
-* Device(s) : RX
-* Description : Interfaces FreeRTOS TCP/IP stack to RX Ethernet driver.
-***********************************************************************************************************************/
-
-/***********************************************************************************************************************
-* History : DD.MM.YYYY Version Description
-* : 07.03.2018 0.1 Development
-***********************************************************************************************************************/
-
-/***********************************************************************************************************************
-* Includes <System Includes> , "Project Includes"
-***********************************************************************************************************************/
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_IP_Private.h"
-/*#include "FreeRTOS_DNS.h" */
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-#include "r_ether_rx_if.h"
-#include "r_pinset.h"
-
-/***********************************************************************************************************************
- * Macro definitions
- **********************************************************************************************************************/
-#define ETHER_BUFSIZE_MIN 60
-
-#if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M )
- #if ETHER_CFG_MODE_SEL == 0
- #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC0_MII()
- #elif ETHER_CFG_MODE_SEL == 1
- #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC0_RMII()
- #endif
-#elif defined( BSP_MCU_RX63N )
- #if ETHER_CFG_MODE_SEL == 0
- #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC_MII()
- #elif ETHER_CFG_MODE_SEL == 1
- #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC_RMII()
- #endif
-#endif /* if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M ) */
-
-#ifndef PHY_LS_HIGH_CHECK_TIME_MS
-
-/* Check if the LinkSStatus in the PHY is still high after 2 seconds of not
- * receiving packets. */
- #define PHY_LS_HIGH_CHECK_TIME_MS 2000
-#endif
-
-#ifndef PHY_LS_LOW_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still low every second. */
- #define PHY_LS_LOW_CHECK_TIME_MS 1000
-#endif
-
-/***********************************************************************************************************************
- * Private global variables and functions
- **********************************************************************************************************************/
-typedef enum
-{
- eMACInit, /* Must initialise MAC. */
- eMACPass, /* Initialisation was successful. */
- eMACFailed, /* Initialisation failed. */
-} eMAC_INIT_STATUS_TYPE;
-
-static TaskHandle_t ether_receive_check_task_handle = 0;
-static TaskHandle_t ether_link_check_task_handle = 0;
-static TaskHandle_t xTaskToNotify = NULL;
-static BaseType_t xPHYLinkStatus;
-static BaseType_t xReportedStatus;
-static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
-
-static int16_t SendData( uint8_t * pucBuffer,
- size_t length );
-static int InitializeNetwork( void );
-static void prvEMACDeferredInterruptHandlerTask( void * pvParameters );
-static void clear_all_ether_rx_discriptors( uint32_t event );
-
-int32_t callback_ether_regist( void );
-void EINT_Trig_isr( void * );
-void get_random_number( uint8_t * data,
- uint32_t len );
-
-void prvLinkStatusChange( BaseType_t xStatus );
-#if ( ipconfigHAS_PRINTF != 0 )
- static void prvMonitorResources( void );
-#endif
-
-/***********************************************************************************************************************
- * Function Name: xNetworkInterfaceInitialise ()
- * Description : Initialization of Ethernet driver.
- * Arguments : none
- * Return Value : pdPASS, pdFAIL
- **********************************************************************************************************************/
-BaseType_t xNetworkInterfaceInitialise( void )
-{
- BaseType_t xReturn;
-
- if( xMacInitStatus == eMACInit )
- {
- /*
- * Perform the hardware specific network initialization here using the Ethernet driver library to initialize the
- * Ethernet hardware, initialize DMA descriptors, and perform a PHY auto-negotiation to obtain a network link.
- *
- * InitialiseNetwork() uses Ethernet peripheral driver library function, and returns 0 if the initialization fails.
- */
- if( InitializeNetwork() == pdFALSE )
- {
- xMacInitStatus = eMACFailed;
- }
- else
- {
- /* Indicate that the MAC initialisation succeeded. */
- xMacInitStatus = eMACPass;
- }
-
- FreeRTOS_printf( ( "InitializeNetwork returns %s\n", ( xMacInitStatus == eMACPass ) ? "OK" : " Fail" ) );
- }
-
- if( xMacInitStatus == eMACPass )
- {
- xReturn = xPHYLinkStatus;
- }
- else
- {
- xReturn = pdFAIL;
- }
-
- FreeRTOS_printf( ( "xNetworkInterfaceInitialise returns %d\n", xReturn ) );
-
- return xReturn;
-} /* End of function xNetworkInterfaceInitialise() */
-
-
-/***********************************************************************************************************************
- * Function Name: xNetworkInterfaceOutput ()
- * Description : Simple network output interface.
- * Arguments : pxDescriptor, xReleaseAfterSend
- * Return Value : pdTRUE, pdFALSE
- **********************************************************************************************************************/
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
- BaseType_t xReleaseAfterSend )
-{
- BaseType_t xReturn = pdFALSE;
-
- /* Simple network interfaces (as opposed to more efficient zero copy network
- * interfaces) just use Ethernet peripheral driver library functions to copy
- * data from the FreeRTOS+TCP buffer into the peripheral driver's own buffer.
- * This example assumes SendData() is a peripheral driver library function that
- * takes a pointer to the start of the data to be sent and the length of the
- * data to be sent as two separate parameters. The start of the data is located
- * by pxDescriptor->pucEthernetBuffer. The length of the data is located
- * by pxDescriptor->xDataLength. */
- if( xPHYLinkStatus != 0 )
- {
- if( SendData( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength ) >= 0 )
- {
- xReturn = pdTRUE;
- /* Call the standard trace macro to log the send event. */
- iptraceNETWORK_INTERFACE_TRANSMIT();
- }
- }
- else
- {
- /* As the PHY Link Status is low, it makes no sense trying to deliver a packet. */
- }
-
- if( xReleaseAfterSend != pdFALSE )
- {
- /* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet
- * buffer. The Ethernet buffer is therefore no longer needed, and must be
- * freed for re-use. */
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
-
- return xReturn;
-} /* End of function xNetworkInterfaceOutput() */
-
-
-#if ( ipconfigHAS_PRINTF != 0 )
- static void prvMonitorResources()
- {
- static UBaseType_t uxLastMinBufferCount = 0u;
- static UBaseType_t uxCurrentBufferCount = 0u;
- static size_t uxMinLastSize = 0uL;
- static size_t uxCurLastSize = 0uL;
- size_t uxMinSize;
- size_t uxCurSize;
-
- uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
-
- if( uxLastMinBufferCount != uxCurrentBufferCount )
- {
- /* The logging produced below may be helpful
- * while tuning +TCP: see how many buffers are in use. */
- uxLastMinBufferCount = uxCurrentBufferCount;
- FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
- uxGetNumberOfFreeNetworkBuffers(), uxCurrentBufferCount ) );
- }
-
- uxMinSize = xPortGetMinimumEverFreeHeapSize();
- uxCurSize = xPortGetFreeHeapSize();
-
- if( uxMinLastSize != uxMinSize )
- {
- uxCurLastSize = uxCurSize;
- uxMinLastSize = uxMinSize;
- FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", uxCurSize, uxMinSize ) );
- }
-
- #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- static UBaseType_t uxLastMinQueueSpace = 0;
- UBaseType_t uxCurrentCount = 0u;
-
- 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 */
- }
-#endif /* ( ipconfigHAS_PRINTF != 0 ) */
-
-/***********************************************************************************************************************
- * Function Name: prvEMACDeferredInterruptHandlerTask ()
- * Description : The deferred interrupt handler is a standard RTOS task.
- * Arguments : pvParameters
- * Return Value : none
- **********************************************************************************************************************/
-static void prvEMACDeferredInterruptHandlerTask( void * pvParameters )
-{
- NetworkBufferDescriptor_t * pxBufferDescriptor;
- int32_t xBytesReceived = 0;
-
- /* Avoid compiler warning about unreferenced parameter. */
- ( void ) pvParameters;
-
- /* Used to indicate that xSendEventStructToIPTask() is being called because
- * of an Ethernet receive event. */
- IPStackEvent_t xRxEvent;
-
- uint8_t * buffer_pointer;
-
- /* Some variables related to monitoring the PHY. */
- TimeOut_t xPhyTime;
- TickType_t xPhyRemTime;
- const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
-
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
-
- FreeRTOS_printf( ( "Deferred Interrupt Handler Task started\n" ) );
- xTaskToNotify = ether_receive_check_task_handle;
-
- for( ; ; )
- {
- #if ( ipconfigHAS_PRINTF != 0 )
- {
- prvMonitorResources();
- }
- #endif /* ipconfigHAS_PRINTF != 0 ) */
-
- /* Wait for the Ethernet MAC interrupt to indicate that another packet
- * has been received. */
- if( xBytesReceived <= 0 )
- {
- ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
- }
-
- /* See how much data was received. */
- xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
-
- if( xBytesReceived < 0 )
- {
- /* This is an error. Logged. */
- FreeRTOS_printf( ( "R_ETHER_Read_ZC2: rc = %d\n", xBytesReceived ) );
- }
- else if( xBytesReceived > 0 )
- {
- /* Allocate a network buffer descriptor that points to a buffer
- * large enough to hold the received frame. As this is the simple
- * rather than efficient example the received data will just be copied
- * into this buffer. */
- pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( ( size_t ) xBytesReceived, 0 );
-
- if( pxBufferDescriptor != NULL )
- {
- /* pxBufferDescriptor->pucEthernetBuffer now points to an Ethernet
- * buffer large enough to hold the received data. Copy the
- * received data into pcNetworkBuffer->pucEthernetBuffer. Here it
- * is assumed ReceiveData() is a peripheral driver function that
- * copies the received data into a buffer passed in as the function's
- * parameter. Remember! While is is a simple robust technique -
- * it is not efficient. An example that uses a zero copy technique
- * is provided further down this page. */
- memcpy( pxBufferDescriptor->pucEthernetBuffer, buffer_pointer, ( size_t ) xBytesReceived );
- /*ReceiveData( pxBufferDescriptor->pucEthernetBuffer ); */
-
- /* Set the actual packet length, in case a larger buffer was returned. */
- pxBufferDescriptor->xDataLength = ( size_t ) xBytesReceived;
-
- R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
-
- /* See if the data contained in the received Ethernet frame needs
- * to be processed. NOTE! It is preferable to do this in
- * the interrupt service routine itself, which would remove the need
- * to unblock this task for packets that don't need processing. */
- if( eConsiderFrameForProcessing( pxBufferDescriptor->pucEthernetBuffer ) == eProcessBuffer )
- {
- /* The event about to be sent to the TCP/IP is an Rx event. */
- xRxEvent.eEventType = eNetworkRxEvent;
-
- /* pvData is used to point to the network buffer descriptor that
- * now references the received data. */
- xRxEvent.pvData = ( void * ) pxBufferDescriptor;
-
- /* Send the data to the TCP/IP stack. */
- if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
- {
- /* The buffer could not be sent to the IP task so the buffer must be released. */
- vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
-
- /* Make a call to the standard trace macro to log the occurrence. */
- iptraceETHERNET_RX_EVENT_LOST();
- clear_all_ether_rx_discriptors( 0 );
- }
- else
- {
- /* The message was successfully sent to the TCP/IP stack.
- * Call the standard trace macro to log the occurrence. */
- iptraceNETWORK_INTERFACE_RECEIVE();
- R_NOP();
- }
- }
- else
- {
- /* The Ethernet frame can be dropped, but the Ethernet buffer must be released. */
- vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
- }
- }
- else
- {
- /* The event was lost because a network buffer was not available.
- * Call the standard trace macro to log the occurrence. */
- iptraceETHERNET_RX_EVENT_LOST();
- clear_all_ether_rx_discriptors( 1 );
- FreeRTOS_printf( ( "R_ETHER_Read_ZC2: Cleared descriptors\n" ) );
- }
- }
-
- if( xBytesReceived > 0 )
- {
- /* A packet was received. No need to check for the PHY status now,
- * but set a timer to check it later on. */
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
-
- /* Indicate that the Link Status is high, so that
- * xNetworkInterfaceOutput() can send packets. */
- if( xPHYLinkStatus == 0 )
- {
- xPHYLinkStatus = 1;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS assume %d\n", xPHYLinkStatus ) );
- }
- }
- else if( ( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) )
- {
- R_ETHER_LinkProcess( 0 );
-
- if( xPHYLinkStatus != xReportedStatus )
- {
- xPHYLinkStatus = xReportedStatus;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", xPHYLinkStatus ) );
- }
-
- vTaskSetTimeOutState( &xPhyTime );
-
- if( xPHYLinkStatus != 0 )
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- }
- else
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
- }
- }
- }
-} /* End of function prvEMACDeferredInterruptHandlerTask() */
-
-
-/***********************************************************************************************************************
- * Function Name: vNetworkInterfaceAllocateRAMToBuffers ()
- * Description : .
- * Arguments : pxNetworkBuffers
- * Return Value : none
- **********************************************************************************************************************/
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
- uint32_t ul;
- uint8_t * buffer_address;
-
- R_EXTERN_SEC( B_ETHERNET_BUFFERS_1 )
-
- buffer_address = R_SECTOP( B_ETHERNET_BUFFERS_1 );
-
- for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
- {
- pxNetworkBuffers[ ul ].pucEthernetBuffer = ( buffer_address + ( ETHER_CFG_BUFSIZE * ul ) );
- }
-} /* End of function vNetworkInterfaceAllocateRAMToBuffers() */
-
-
-/***********************************************************************************************************************
- * Function Name: prvLinkStatusChange ()
- * Description : Function will be called when the Link Status of the phy has changed ( see ether_callback.c )
- * Arguments : xStatus : true when statyus has become high
- * Return Value : void
- **********************************************************************************************************************/
-void prvLinkStatusChange( BaseType_t xStatus )
-{
- if( xReportedStatus != xStatus )
- {
- FreeRTOS_printf( ( "prvLinkStatusChange( %d )\n", xStatus ) );
- xReportedStatus = xStatus;
- }
-}
-
-/***********************************************************************************************************************
- * Function Name: InitializeNetwork ()
- * Description :
- * Arguments : none
- * Return Value : pdTRUE, pdFALSE
- **********************************************************************************************************************/
-static int InitializeNetwork( void )
-{
- ether_return_t eth_ret;
- BaseType_t return_code = pdFALSE;
- ether_param_t param;
- uint8_t myethaddr[ 6 ] =
- {
- configMAC_ADDR0,
- configMAC_ADDR1,
- configMAC_ADDR2,
- configMAC_ADDR3,
- configMAC_ADDR4,
- configMAC_ADDR5
- }; /*XXX Fix me */
-
- R_ETHER_PinSet_CHANNEL_0();
- R_ETHER_Initial();
- callback_ether_regist();
-
- param.channel = ETHER_CHANNEL_0;
- eth_ret = R_ETHER_Control( CONTROL_POWER_ON, param ); /* PHY mode settings, module stop cancellation */
-
- if( ETHER_SUCCESS != eth_ret )
- {
- return pdFALSE;
- }
-
- eth_ret = R_ETHER_Open_ZC2( ETHER_CHANNEL_0, myethaddr, ETHER_FLAG_OFF );
-
- if( ETHER_SUCCESS != eth_ret )
- {
- return pdFALSE;
- }
-
- return_code = xTaskCreate( prvEMACDeferredInterruptHandlerTask,
- "ETHER_RECEIVE_CHECK_TASK",
- 512u,
- 0,
- configMAX_PRIORITIES - 1,
- &ether_receive_check_task_handle );
-
- if( pdFALSE == return_code )
- {
- return pdFALSE;
- }
-
- return pdTRUE;
-} /* End of function InitializeNetwork() */
-
-
-/***********************************************************************************************************************
- * Function Name: SendData ()
- * Description :
- * Arguments : pucBuffer, length
- * Return Value : 0 success, negative fail
- **********************************************************************************************************************/
-static int16_t SendData( uint8_t * pucBuffer,
- size_t length ) /*TODO complete stub function */
-{
- ether_return_t ret;
- uint8_t * pwrite_buffer;
- uint16_t write_buf_size;
-
- /* (1) Retrieve the transmit buffer location controlled by the descriptor. */
- ret = R_ETHER_Write_ZC2_GetBuf( ETHER_CHANNEL_0, ( void ** ) &pwrite_buffer, &write_buf_size );
-
- if( ETHER_SUCCESS == ret )
- {
- if( write_buf_size >= length )
- {
- memcpy( pwrite_buffer, pucBuffer, length );
- }
-
- if( length < ETHER_BUFSIZE_MIN ) /*under minimum*/
- {
- memset( ( pwrite_buffer + length ), 0, ( ETHER_BUFSIZE_MIN - length ) ); /*padding*/
- length = ETHER_BUFSIZE_MIN; /*resize*/
- }
-
- ret = R_ETHER_Write_ZC2_SetBuf( ETHER_CHANNEL_0, ( uint16_t ) length );
- ret = R_ETHER_CheckWrite( ETHER_CHANNEL_0 );
- }
-
- if( ETHER_SUCCESS != ret )
- {
- return -5; /* XXX return meaningful value */
- }
- else
- {
- return 0;
- }
-} /* End of function SendData() */
-
-
-/***********************************************************************************************************************
-* Function Name: EINT_Trig_isr
-* Description : Standard frame received interrupt handler
-* Arguments : ectrl - EDMAC and ETHERC control structure
-* Return Value : None
-* Note : This callback function is executed when EINT0 interrupt occurred.
-***********************************************************************************************************************/
-void EINT_Trig_isr( void * ectrl )
-{
- ether_cb_arg_t * pdecode;
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- pdecode = ( ether_cb_arg_t * ) ectrl;
-
- if( pdecode->status_eesr & 0x00040000 ) /* EDMAC FR (Frame Receive Event) interrupt */
- {
- if( xTaskToNotify != NULL )
- {
- vTaskNotifyGiveFromISR( ether_receive_check_task_handle, &xHigherPriorityTaskWoken );
- }
-
- /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch
- * should be performed to ensure the interrupt returns directly to the highest
- * priority task. The macro used for this purpose is dependent on the port in
- * use and may be called portEND_SWITCHING_ISR(). */
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
- /*TODO complete interrupt handler for other events. */
- }
-} /* End of function EINT_Trig_isr() */
-
-
-static void clear_all_ether_rx_discriptors( uint32_t event )
-{
- int32_t xBytesReceived;
- uint8_t * buffer_pointer;
-
- /* Avoid compiler warning about unreferenced parameter. */
- ( void ) event;
-
- while( 1 )
- {
- /* See how much data was received. */
- xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
-
- if( 0 > xBytesReceived )
- {
- /* This is an error. Ignored. */
- }
- else if( 0 < xBytesReceived )
- {
- R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
- iptraceETHERNET_RX_EVENT_LOST();
- }
- else
- {
- break;
- }
- }
-}
-
-/***********************************************************************************************************************
- * End of file "NetworkInterface.c"
- **********************************************************************************************************************/
+/***********************************************************************************************************************
+* DISCLAIMER
+* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
+* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
+* applicable laws, including copyright laws.
+* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
+* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
+* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
+* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
+* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
+* this software. By using this software, you agree to the additional terms and conditions found by accessing the
+* following link:
+* http://www.renesas.com/disclaimer
+*
+* Copyright (C) 2018 Renesas Electronics Corporation. All rights reserved.
+***********************************************************************************************************************/
+
+/***********************************************************************************************************************
+* File Name : NetworkInterface.c
+* Device(s) : RX
+* Description : Interfaces FreeRTOS TCP/IP stack to RX Ethernet driver.
+***********************************************************************************************************************/
+
+/***********************************************************************************************************************
+* History : DD.MM.YYYY Version Description
+* : 07.03.2018 0.1 Development
+***********************************************************************************************************************/
+
+/***********************************************************************************************************************
+* Includes <System Includes> , "Project Includes"
+***********************************************************************************************************************/
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_IP_Private.h"
+/*#include "FreeRTOS_DNS.h" */
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+#include "r_ether_rx_if.h"
+#include "r_pinset.h"
+
+/***********************************************************************************************************************
+ * Macro definitions
+ **********************************************************************************************************************/
+#define ETHER_BUFSIZE_MIN 60
+
+#if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M )
+ #if ETHER_CFG_MODE_SEL == 0
+ #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC0_MII()
+ #elif ETHER_CFG_MODE_SEL == 1
+ #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC0_RMII()
+ #endif
+#elif defined( BSP_MCU_RX63N )
+ #if ETHER_CFG_MODE_SEL == 0
+ #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC_MII()
+ #elif ETHER_CFG_MODE_SEL == 1
+ #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC_RMII()
+ #endif
+#endif /* if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M ) */
+
+#ifndef PHY_LS_HIGH_CHECK_TIME_MS
+
+/* Check if the LinkSStatus in the PHY is still high after 2 seconds of not
+ * receiving packets. */
+ #define PHY_LS_HIGH_CHECK_TIME_MS 2000
+#endif
+
+#ifndef PHY_LS_LOW_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still low every second. */
+ #define PHY_LS_LOW_CHECK_TIME_MS 1000
+#endif
+
+/***********************************************************************************************************************
+ * Private global variables and functions
+ **********************************************************************************************************************/
+typedef enum
+{
+ eMACInit, /* Must initialise MAC. */
+ eMACPass, /* Initialisation was successful. */
+ eMACFailed, /* Initialisation failed. */
+} eMAC_INIT_STATUS_TYPE;
+
+static TaskHandle_t ether_receive_check_task_handle = 0;
+static TaskHandle_t ether_link_check_task_handle = 0;
+static TaskHandle_t xTaskToNotify = NULL;
+static BaseType_t xPHYLinkStatus;
+static BaseType_t xReportedStatus;
+static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
+
+static int16_t SendData( uint8_t * pucBuffer,
+ size_t length );
+static int InitializeNetwork( void );
+static void prvEMACDeferredInterruptHandlerTask( void * pvParameters );
+static void clear_all_ether_rx_discriptors( uint32_t event );
+
+int32_t callback_ether_regist( void );
+void EINT_Trig_isr( void * );
+void get_random_number( uint8_t * data,
+ uint32_t len );
+
+void prvLinkStatusChange( BaseType_t xStatus );
+#if ( ipconfigHAS_PRINTF != 0 )
+ static void prvMonitorResources( void );
+#endif
+
+/***********************************************************************************************************************
+ * Function Name: xNetworkInterfaceInitialise ()
+ * Description : Initialization of Ethernet driver.
+ * Arguments : none
+ * Return Value : pdPASS, pdFAIL
+ **********************************************************************************************************************/
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+ BaseType_t xReturn;
+
+ if( xMacInitStatus == eMACInit )
+ {
+ /*
+ * Perform the hardware specific network initialization here using the Ethernet driver library to initialize the
+ * Ethernet hardware, initialize DMA descriptors, and perform a PHY auto-negotiation to obtain a network link.
+ *
+ * InitialiseNetwork() uses Ethernet peripheral driver library function, and returns 0 if the initialization fails.
+ */
+ if( InitializeNetwork() == pdFALSE )
+ {
+ xMacInitStatus = eMACFailed;
+ }
+ else
+ {
+ /* Indicate that the MAC initialisation succeeded. */
+ xMacInitStatus = eMACPass;
+ }
+
+ FreeRTOS_printf( ( "InitializeNetwork returns %s\n", ( xMacInitStatus == eMACPass ) ? "OK" : " Fail" ) );
+ }
+
+ if( xMacInitStatus == eMACPass )
+ {
+ xReturn = xPHYLinkStatus;
+ }
+ else
+ {
+ xReturn = pdFAIL;
+ }
+
+ FreeRTOS_printf( ( "xNetworkInterfaceInitialise returns %d\n", xReturn ) );
+
+ return xReturn;
+} /* End of function xNetworkInterfaceInitialise() */
+
+
+/***********************************************************************************************************************
+ * Function Name: xNetworkInterfaceOutput ()
+ * Description : Simple network output interface.
+ * Arguments : pxDescriptor, xReleaseAfterSend
+ * Return Value : pdTRUE, pdFALSE
+ **********************************************************************************************************************/
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
+ BaseType_t xReleaseAfterSend )
+{
+ BaseType_t xReturn = pdFALSE;
+
+ /* Simple network interfaces (as opposed to more efficient zero copy network
+ * interfaces) just use Ethernet peripheral driver library functions to copy
+ * data from the FreeRTOS+TCP buffer into the peripheral driver's own buffer.
+ * This example assumes SendData() is a peripheral driver library function that
+ * takes a pointer to the start of the data to be sent and the length of the
+ * data to be sent as two separate parameters. The start of the data is located
+ * by pxDescriptor->pucEthernetBuffer. The length of the data is located
+ * by pxDescriptor->xDataLength. */
+ if( xPHYLinkStatus != 0 )
+ {
+ if( SendData( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength ) >= 0 )
+ {
+ xReturn = pdTRUE;
+ /* Call the standard trace macro to log the send event. */
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+ }
+ }
+ else
+ {
+ /* As the PHY Link Status is low, it makes no sense trying to deliver a packet. */
+ }
+
+ if( xReleaseAfterSend != pdFALSE )
+ {
+ /* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet
+ * buffer. The Ethernet buffer is therefore no longer needed, and must be
+ * freed for re-use. */
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+
+ return xReturn;
+} /* End of function xNetworkInterfaceOutput() */
+
+
+#if ( ipconfigHAS_PRINTF != 0 )
+ static void prvMonitorResources()
+ {
+ static UBaseType_t uxLastMinBufferCount = 0u;
+ static UBaseType_t uxCurrentBufferCount = 0u;
+ static size_t uxMinLastSize = 0uL;
+ static size_t uxCurLastSize = 0uL;
+ size_t uxMinSize;
+ size_t uxCurSize;
+
+ uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
+
+ if( uxLastMinBufferCount != uxCurrentBufferCount )
+ {
+ /* The logging produced below may be helpful
+ * while tuning +TCP: see how many buffers are in use. */
+ uxLastMinBufferCount = uxCurrentBufferCount;
+ FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
+ uxGetNumberOfFreeNetworkBuffers(), uxCurrentBufferCount ) );
+ }
+
+ uxMinSize = xPortGetMinimumEverFreeHeapSize();
+ uxCurSize = xPortGetFreeHeapSize();
+
+ if( uxMinLastSize != uxMinSize )
+ {
+ uxCurLastSize = uxCurSize;
+ uxMinLastSize = uxMinSize;
+ FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", uxCurSize, uxMinSize ) );
+ }
+
+ #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ {
+ static UBaseType_t uxLastMinQueueSpace = 0;
+ UBaseType_t uxCurrentCount = 0u;
+
+ 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 */
+ }
+#endif /* ( ipconfigHAS_PRINTF != 0 ) */
+
+/***********************************************************************************************************************
+ * Function Name: prvEMACDeferredInterruptHandlerTask ()
+ * Description : The deferred interrupt handler is a standard RTOS task.
+ * Arguments : pvParameters
+ * Return Value : none
+ **********************************************************************************************************************/
+static void prvEMACDeferredInterruptHandlerTask( void * pvParameters )
+{
+ NetworkBufferDescriptor_t * pxBufferDescriptor;
+ int32_t xBytesReceived = 0;
+
+ /* Avoid compiler warning about unreferenced parameter. */
+ ( void ) pvParameters;
+
+ /* Used to indicate that xSendEventStructToIPTask() is being called because
+ * of an Ethernet receive event. */
+ IPStackEvent_t xRxEvent;
+
+ uint8_t * buffer_pointer;
+
+ /* Some variables related to monitoring the PHY. */
+ TimeOut_t xPhyTime;
+ TickType_t xPhyRemTime;
+ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
+
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+
+ FreeRTOS_printf( ( "Deferred Interrupt Handler Task started\n" ) );
+ xTaskToNotify = ether_receive_check_task_handle;
+
+ for( ; ; )
+ {
+ #if ( ipconfigHAS_PRINTF != 0 )
+ {
+ prvMonitorResources();
+ }
+ #endif /* ipconfigHAS_PRINTF != 0 ) */
+
+ /* Wait for the Ethernet MAC interrupt to indicate that another packet
+ * has been received. */
+ if( xBytesReceived <= 0 )
+ {
+ ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
+ }
+
+ /* See how much data was received. */
+ xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
+
+ if( xBytesReceived < 0 )
+ {
+ /* This is an error. Logged. */
+ FreeRTOS_printf( ( "R_ETHER_Read_ZC2: rc = %d\n", xBytesReceived ) );
+ }
+ else if( xBytesReceived > 0 )
+ {
+ /* Allocate a network buffer descriptor that points to a buffer
+ * large enough to hold the received frame. As this is the simple
+ * rather than efficient example the received data will just be copied
+ * into this buffer. */
+ pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( ( size_t ) xBytesReceived, 0 );
+
+ if( pxBufferDescriptor != NULL )
+ {
+ /* pxBufferDescriptor->pucEthernetBuffer now points to an Ethernet
+ * buffer large enough to hold the received data. Copy the
+ * received data into pcNetworkBuffer->pucEthernetBuffer. Here it
+ * is assumed ReceiveData() is a peripheral driver function that
+ * copies the received data into a buffer passed in as the function's
+ * parameter. Remember! While is is a simple robust technique -
+ * it is not efficient. An example that uses a zero copy technique
+ * is provided further down this page. */
+ memcpy( pxBufferDescriptor->pucEthernetBuffer, buffer_pointer, ( size_t ) xBytesReceived );
+ /*ReceiveData( pxBufferDescriptor->pucEthernetBuffer ); */
+
+ /* Set the actual packet length, in case a larger buffer was returned. */
+ pxBufferDescriptor->xDataLength = ( size_t ) xBytesReceived;
+
+ R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
+
+ /* See if the data contained in the received Ethernet frame needs
+ * to be processed. NOTE! It is preferable to do this in
+ * the interrupt service routine itself, which would remove the need
+ * to unblock this task for packets that don't need processing. */
+ if( eConsiderFrameForProcessing( pxBufferDescriptor->pucEthernetBuffer ) == eProcessBuffer )
+ {
+ /* The event about to be sent to the TCP/IP is an Rx event. */
+ xRxEvent.eEventType = eNetworkRxEvent;
+
+ /* pvData is used to point to the network buffer descriptor that
+ * now references the received data. */
+ xRxEvent.pvData = ( void * ) pxBufferDescriptor;
+
+ /* Send the data to the TCP/IP stack. */
+ if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
+ {
+ /* The buffer could not be sent to the IP task so the buffer must be released. */
+ vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
+
+ /* Make a call to the standard trace macro to log the occurrence. */
+ iptraceETHERNET_RX_EVENT_LOST();
+ clear_all_ether_rx_discriptors( 0 );
+ }
+ else
+ {
+ /* The message was successfully sent to the TCP/IP stack.
+ * Call the standard trace macro to log the occurrence. */
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ R_NOP();
+ }
+ }
+ else
+ {
+ /* The Ethernet frame can be dropped, but the Ethernet buffer must be released. */
+ vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
+ }
+ }
+ else
+ {
+ /* The event was lost because a network buffer was not available.
+ * Call the standard trace macro to log the occurrence. */
+ iptraceETHERNET_RX_EVENT_LOST();
+ clear_all_ether_rx_discriptors( 1 );
+ FreeRTOS_printf( ( "R_ETHER_Read_ZC2: Cleared descriptors\n" ) );
+ }
+ }
+
+ if( xBytesReceived > 0 )
+ {
+ /* A packet was received. No need to check for the PHY status now,
+ * but set a timer to check it later on. */
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+
+ /* Indicate that the Link Status is high, so that
+ * xNetworkInterfaceOutput() can send packets. */
+ if( xPHYLinkStatus == 0 )
+ {
+ xPHYLinkStatus = 1;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS assume %d\n", xPHYLinkStatus ) );
+ }
+ }
+ else if( ( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) )
+ {
+ R_ETHER_LinkProcess( 0 );
+
+ if( xPHYLinkStatus != xReportedStatus )
+ {
+ xPHYLinkStatus = xReportedStatus;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", xPHYLinkStatus ) );
+ }
+
+ vTaskSetTimeOutState( &xPhyTime );
+
+ if( xPHYLinkStatus != 0 )
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ }
+ else
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+ }
+ }
+ }
+} /* End of function prvEMACDeferredInterruptHandlerTask() */
+
+
+/***********************************************************************************************************************
+ * Function Name: vNetworkInterfaceAllocateRAMToBuffers ()
+ * Description : .
+ * Arguments : pxNetworkBuffers
+ * Return Value : none
+ **********************************************************************************************************************/
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
+{
+ uint32_t ul;
+ uint8_t * buffer_address;
+
+ R_EXTERN_SEC( B_ETHERNET_BUFFERS_1 )
+
+ buffer_address = R_SECTOP( B_ETHERNET_BUFFERS_1 );
+
+ for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
+ {
+ pxNetworkBuffers[ ul ].pucEthernetBuffer = ( buffer_address + ( ETHER_CFG_BUFSIZE * ul ) );
+ }
+} /* End of function vNetworkInterfaceAllocateRAMToBuffers() */
+
+
+/***********************************************************************************************************************
+ * Function Name: prvLinkStatusChange ()
+ * Description : Function will be called when the Link Status of the phy has changed ( see ether_callback.c )
+ * Arguments : xStatus : true when statyus has become high
+ * Return Value : void
+ **********************************************************************************************************************/
+void prvLinkStatusChange( BaseType_t xStatus )
+{
+ if( xReportedStatus != xStatus )
+ {
+ FreeRTOS_printf( ( "prvLinkStatusChange( %d )\n", xStatus ) );
+ xReportedStatus = xStatus;
+ }
+}
+
+/***********************************************************************************************************************
+ * Function Name: InitializeNetwork ()
+ * Description :
+ * Arguments : none
+ * Return Value : pdTRUE, pdFALSE
+ **********************************************************************************************************************/
+static int InitializeNetwork( void )
+{
+ ether_return_t eth_ret;
+ BaseType_t return_code = pdFALSE;
+ ether_param_t param;
+ uint8_t myethaddr[ 6 ] =
+ {
+ configMAC_ADDR0,
+ configMAC_ADDR1,
+ configMAC_ADDR2,
+ configMAC_ADDR3,
+ configMAC_ADDR4,
+ configMAC_ADDR5
+ }; /*XXX Fix me */
+
+ R_ETHER_PinSet_CHANNEL_0();
+ R_ETHER_Initial();
+ callback_ether_regist();
+
+ param.channel = ETHER_CHANNEL_0;
+ eth_ret = R_ETHER_Control( CONTROL_POWER_ON, param ); /* PHY mode settings, module stop cancellation */
+
+ if( ETHER_SUCCESS != eth_ret )
+ {
+ return pdFALSE;
+ }
+
+ eth_ret = R_ETHER_Open_ZC2( ETHER_CHANNEL_0, myethaddr, ETHER_FLAG_OFF );
+
+ if( ETHER_SUCCESS != eth_ret )
+ {
+ return pdFALSE;
+ }
+
+ return_code = xTaskCreate( prvEMACDeferredInterruptHandlerTask,
+ "ETHER_RECEIVE_CHECK_TASK",
+ 512u,
+ 0,
+ configMAX_PRIORITIES - 1,
+ &ether_receive_check_task_handle );
+
+ if( pdFALSE == return_code )
+ {
+ return pdFALSE;
+ }
+
+ return pdTRUE;
+} /* End of function InitializeNetwork() */
+
+
+/***********************************************************************************************************************
+ * Function Name: SendData ()
+ * Description :
+ * Arguments : pucBuffer, length
+ * Return Value : 0 success, negative fail
+ **********************************************************************************************************************/
+static int16_t SendData( uint8_t * pucBuffer,
+ size_t length ) /*TODO complete stub function */
+{
+ ether_return_t ret;
+ uint8_t * pwrite_buffer;
+ uint16_t write_buf_size;
+
+ /* (1) Retrieve the transmit buffer location controlled by the descriptor. */
+ ret = R_ETHER_Write_ZC2_GetBuf( ETHER_CHANNEL_0, ( void ** ) &pwrite_buffer, &write_buf_size );
+
+ if( ETHER_SUCCESS == ret )
+ {
+ if( write_buf_size >= length )
+ {
+ memcpy( pwrite_buffer, pucBuffer, length );
+ }
+
+ if( length < ETHER_BUFSIZE_MIN ) /*under minimum*/
+ {
+ memset( ( pwrite_buffer + length ), 0, ( ETHER_BUFSIZE_MIN - length ) ); /*padding*/
+ length = ETHER_BUFSIZE_MIN; /*resize*/
+ }
+
+ ret = R_ETHER_Write_ZC2_SetBuf( ETHER_CHANNEL_0, ( uint16_t ) length );
+ ret = R_ETHER_CheckWrite( ETHER_CHANNEL_0 );
+ }
+
+ if( ETHER_SUCCESS != ret )
+ {
+ return -5; /* XXX return meaningful value */
+ }
+ else
+ {
+ return 0;
+ }
+} /* End of function SendData() */
+
+
+/***********************************************************************************************************************
+* Function Name: EINT_Trig_isr
+* Description : Standard frame received interrupt handler
+* Arguments : ectrl - EDMAC and ETHERC control structure
+* Return Value : None
+* Note : This callback function is executed when EINT0 interrupt occurred.
+***********************************************************************************************************************/
+void EINT_Trig_isr( void * ectrl )
+{
+ ether_cb_arg_t * pdecode;
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+
+ pdecode = ( ether_cb_arg_t * ) ectrl;
+
+ if( pdecode->status_eesr & 0x00040000 ) /* EDMAC FR (Frame Receive Event) interrupt */
+ {
+ if( xTaskToNotify != NULL )
+ {
+ vTaskNotifyGiveFromISR( ether_receive_check_task_handle, &xHigherPriorityTaskWoken );
+ }
+
+ /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch
+ * should be performed to ensure the interrupt returns directly to the highest
+ * priority task. The macro used for this purpose is dependent on the port in
+ * use and may be called portEND_SWITCHING_ISR(). */
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+ /*TODO complete interrupt handler for other events. */
+ }
+} /* End of function EINT_Trig_isr() */
+
+
+static void clear_all_ether_rx_discriptors( uint32_t event )
+{
+ int32_t xBytesReceived;
+ uint8_t * buffer_pointer;
+
+ /* Avoid compiler warning about unreferenced parameter. */
+ ( void ) event;
+
+ while( 1 )
+ {
+ /* See how much data was received. */
+ xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
+
+ if( 0 > xBytesReceived )
+ {
+ /* This is an error. Ignored. */
+ }
+ else if( 0 < xBytesReceived )
+ {
+ R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+ else
+ {
+ break;
+ }
+ }
+}
+
+/***********************************************************************************************************************
+ * End of file "NetworkInterface.c"
+ **********************************************************************************************************************/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/ether_callback.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/ether_callback.c
index 8cb38ce30..c42d8a20b 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/ether_callback.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/ether_callback.c
@@ -1,177 +1,177 @@
-/***********************************************************************************************************************
-* DISCLAIMER
-* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
-* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
-* applicable laws, including copyright laws.
-* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
-* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
-* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
-* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
-* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
-* this software. By using this software, you agree to the additional terms and conditions found by accessing the
-* following link:
-* http://www.renesas.com/disclaimer
-*
-* Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved.
-***********************************************************************************************************************/
-/***********************************************************************************************************************
-* File Name : ether_callback.c
-* Version : ----
-* Description : This module solves all the world's problems
-***********************************************************************************************************************/
-/**********************************************************************************************************************
-* History : DD.MM.YYYY Version Description
-* : 05.01.2015 ---- Clean up source code.
-***********************************************************************************************************************/
-
-/***********************************************************************************************************************
-Includes <System Includes> , "Project Includes"
-***********************************************************************************************************************/
-#include "r_ether_rx_if.h"
-
-/***********************************************************************************************************************
-Private global variables and functions
-***********************************************************************************************************************/
-int32_t callback_ether_regist(void);
-void callback_ether(void * pparam);
-static void callback_wakeon_lan(uint32_t channel);
-static void callback_link_on(uint32_t channel);
-static void callback_link_off(uint32_t channel);
-
-volatile uint8_t pause_enable = ETHER_FLAG_OFF;
-volatile uint8_t magic_packet_detect[ETHER_CHANNEL_MAX];
-volatile uint8_t link_detect[ETHER_CHANNEL_MAX];
-
-void EINT_Trig_isr(void *);
-
-/*
- * When that Link Status changes, the following function will be called:
- */
-void prvLinkStatusChange( BaseType_t xStatus );
-
-/***********************************************************************************************************************
-* Function Name: callback_ether
-* Description : Regist of callback function
-* Arguments : -
-* Return Value : 0: success, -1:failed
-***********************************************************************************************************************/
-int32_t callback_ether_regist(void)
-{
- ether_param_t param;
- ether_cb_t cb_func;
-
- int32_t ret;
-
- /* Set the callback function (LAN cable connect/disconnect event) */
- cb_func.pcb_func = &callback_ether;
- param.ether_callback = cb_func;
- ret = R_ETHER_Control(CONTROL_SET_CALLBACK, param);
- if (ETHER_SUCCESS != ret)
- {
- return -1;
- }
-
- /* Set the callback function (Ether interrupt event) */
- cb_func.pcb_int_hnd = &EINT_Trig_isr;
- param.ether_callback = cb_func;
- ret = R_ETHER_Control(CONTROL_SET_INT_HANDLER, param);
- if (ETHER_SUCCESS != ret)
- {
- return -1;
- }
- return 0;
-} /* End of function callback_ether_regist() */
-
-/***********************************************************************************************************************
-* Function Name: callback_ether
-* Description : Sample of the callback function
-* Arguments : pparam -
-*
-* Return Value : none
-***********************************************************************************************************************/
-void callback_ether(void * pparam)
-{
- ether_cb_arg_t * pdecode;
- uint32_t channel;
-
- pdecode = (ether_cb_arg_t *)pparam;
- channel = pdecode->channel; /* Get Ethernet channel number */
-
- switch (pdecode->event_id)
- {
- /* Callback function that notifies user to have detected magic packet. */
- case ETHER_CB_EVENT_ID_WAKEON_LAN:
- callback_wakeon_lan(channel);
- break;
-
- /* Callback function that notifies user to have become Link up. */
- case ETHER_CB_EVENT_ID_LINK_ON:
- callback_link_on(channel);
- break;
-
- /* Callback function that notifies user to have become Link down. */
- case ETHER_CB_EVENT_ID_LINK_OFF:
- callback_link_off(channel);
- break;
-
- default:
- break;
- }
-} /* End of function callback_ether() */
-
-/***********************************************************************************************************************
-* Function Name: callback_wakeon_lan
-* Description :
-* Arguments : channel -
-* Ethernet channel number
-* Return Value : none
-***********************************************************************************************************************/
-static void callback_wakeon_lan(uint32_t channel)
-{
- if (ETHER_CHANNEL_MAX > channel)
- {
- magic_packet_detect[channel] = 1;
-
- /* Please add necessary processing when magic packet is detected. */
- }
-} /* End of function callback_wakeon_lan() */
-
-/***********************************************************************************************************************
-* Function Name: callback_link_on
-* Description :
-* Arguments : channel -
-* Ethernet channel number
-* Return Value : none
-***********************************************************************************************************************/
-static void callback_link_on(uint32_t channel)
-{
- if (ETHER_CHANNEL_MAX > channel)
- {
- link_detect[channel] = ETHER_FLAG_ON_LINK_ON;
-
- /* Please add necessary processing when becoming Link up. */
- prvLinkStatusChange( 1 );
- }
-} /* End of function callback_link_on() */
-
-/***********************************************************************************************************************
-* Function Name: callback_link_off
-* Description :
-* Arguments : channel -
-* Ethernet channel number
-* Return Value : none
-***********************************************************************************************************************/
-static void callback_link_off(uint32_t channel)
-{
- if (ETHER_CHANNEL_MAX > channel)
- {
- link_detect[channel] = ETHER_FLAG_ON_LINK_OFF;
-
- /* Please add necessary processing when becoming Link down. */
- prvLinkStatusChange( 0 );
- }
-} /* End of function ether_cb_link_off() */
-
-/* End of File */
+/***********************************************************************************************************************
+* DISCLAIMER
+* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
+* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
+* applicable laws, including copyright laws.
+* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
+* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
+* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
+* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
+* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
+* this software. By using this software, you agree to the additional terms and conditions found by accessing the
+* following link:
+* http://www.renesas.com/disclaimer
+*
+* Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved.
+***********************************************************************************************************************/
+/***********************************************************************************************************************
+* File Name : ether_callback.c
+* Version : ----
+* Description : This module solves all the world's problems
+***********************************************************************************************************************/
+/**********************************************************************************************************************
+* History : DD.MM.YYYY Version Description
+* : 05.01.2015 ---- Clean up source code.
+***********************************************************************************************************************/
+
+/***********************************************************************************************************************
+Includes <System Includes> , "Project Includes"
+***********************************************************************************************************************/
+#include "r_ether_rx_if.h"
+
+/***********************************************************************************************************************
+Private global variables and functions
+***********************************************************************************************************************/
+int32_t callback_ether_regist(void);
+void callback_ether(void * pparam);
+static void callback_wakeon_lan(uint32_t channel);
+static void callback_link_on(uint32_t channel);
+static void callback_link_off(uint32_t channel);
+
+volatile uint8_t pause_enable = ETHER_FLAG_OFF;
+volatile uint8_t magic_packet_detect[ETHER_CHANNEL_MAX];
+volatile uint8_t link_detect[ETHER_CHANNEL_MAX];
+
+void EINT_Trig_isr(void *);
+
+/*
+ * When that Link Status changes, the following function will be called:
+ */
+void prvLinkStatusChange( BaseType_t xStatus );
+
+/***********************************************************************************************************************
+* Function Name: callback_ether
+* Description : Regist of callback function
+* Arguments : -
+* Return Value : 0: success, -1:failed
+***********************************************************************************************************************/
+int32_t callback_ether_regist(void)
+{
+ ether_param_t param;
+ ether_cb_t cb_func;
+
+ int32_t ret;
+
+ /* Set the callback function (LAN cable connect/disconnect event) */
+ cb_func.pcb_func = &callback_ether;
+ param.ether_callback = cb_func;
+ ret = R_ETHER_Control(CONTROL_SET_CALLBACK, param);
+ if (ETHER_SUCCESS != ret)
+ {
+ return -1;
+ }
+
+ /* Set the callback function (Ether interrupt event) */
+ cb_func.pcb_int_hnd = &EINT_Trig_isr;
+ param.ether_callback = cb_func;
+ ret = R_ETHER_Control(CONTROL_SET_INT_HANDLER, param);
+ if (ETHER_SUCCESS != ret)
+ {
+ return -1;
+ }
+ return 0;
+} /* End of function callback_ether_regist() */
+
+/***********************************************************************************************************************
+* Function Name: callback_ether
+* Description : Sample of the callback function
+* Arguments : pparam -
+*
+* Return Value : none
+***********************************************************************************************************************/
+void callback_ether(void * pparam)
+{
+ ether_cb_arg_t * pdecode;
+ uint32_t channel;
+
+ pdecode = (ether_cb_arg_t *)pparam;
+ channel = pdecode->channel; /* Get Ethernet channel number */
+
+ switch (pdecode->event_id)
+ {
+ /* Callback function that notifies user to have detected magic packet. */
+ case ETHER_CB_EVENT_ID_WAKEON_LAN:
+ callback_wakeon_lan(channel);
+ break;
+
+ /* Callback function that notifies user to have become Link up. */
+ case ETHER_CB_EVENT_ID_LINK_ON:
+ callback_link_on(channel);
+ break;
+
+ /* Callback function that notifies user to have become Link down. */
+ case ETHER_CB_EVENT_ID_LINK_OFF:
+ callback_link_off(channel);
+ break;
+
+ default:
+ break;
+ }
+} /* End of function callback_ether() */
+
+/***********************************************************************************************************************
+* Function Name: callback_wakeon_lan
+* Description :
+* Arguments : channel -
+* Ethernet channel number
+* Return Value : none
+***********************************************************************************************************************/
+static void callback_wakeon_lan(uint32_t channel)
+{
+ if (ETHER_CHANNEL_MAX > channel)
+ {
+ magic_packet_detect[channel] = 1;
+
+ /* Please add necessary processing when magic packet is detected. */
+ }
+} /* End of function callback_wakeon_lan() */
+
+/***********************************************************************************************************************
+* Function Name: callback_link_on
+* Description :
+* Arguments : channel -
+* Ethernet channel number
+* Return Value : none
+***********************************************************************************************************************/
+static void callback_link_on(uint32_t channel)
+{
+ if (ETHER_CHANNEL_MAX > channel)
+ {
+ link_detect[channel] = ETHER_FLAG_ON_LINK_ON;
+
+ /* Please add necessary processing when becoming Link up. */
+ prvLinkStatusChange( 1 );
+ }
+} /* End of function callback_link_on() */
+
+/***********************************************************************************************************************
+* Function Name: callback_link_off
+* Description :
+* Arguments : channel -
+* Ethernet channel number
+* Return Value : none
+***********************************************************************************************************************/
+static void callback_link_off(uint32_t channel)
+{
+ if (ETHER_CHANNEL_MAX > channel)
+ {
+ link_detect[channel] = ETHER_FLAG_ON_LINK_OFF;
+
+ /* Please add necessary processing when becoming Link down. */
+ prvLinkStatusChange( 0 );
+ }
+} /* End of function ether_cb_link_off() */
+
+/* End of File */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c
index adc603c52..44d19f3a9 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c
@@ -1,118 +1,118 @@
-/*
-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. */
-#include <stdint.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "NetworkBufferManagement.h"
-
-/* Hardware includes. */
-#include "hwEthernet.h"
-
-/* Demo includes. */
-#include "NetworkInterface.h"
-
-#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES != 1
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
-#else
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
-#endif
-
-/* When a packet is ready to be sent, if it cannot be sent immediately then the
-task performing the transmit will block for niTX_BUFFER_FREE_WAIT
-milliseconds. It will do this a maximum of niMAX_TX_ATTEMPTS before giving
-up. */
-#define niTX_BUFFER_FREE_WAIT ( ( TickType_t ) 2UL / portTICK_PERIOD_MS )
-#define niMAX_TX_ATTEMPTS ( 5 )
-
-/* The length of the queue used to send interrupt status words from the
-interrupt handler to the deferred handler task. */
-#define niINTERRUPT_QUEUE_LENGTH ( 10 )
-
-/*-----------------------------------------------------------*/
-
-/*
- * A deferred interrupt handler task that processes
- */
-extern void vEMACHandlerTask( void *pvParameters );
-
-/*-----------------------------------------------------------*/
-
-/* The queue used to communicate Ethernet events with the IP task. */
-extern QueueHandle_t xNetworkEventQueue;
-
-/* The semaphore used to wake the deferred interrupt handler task when an Rx
-interrupt is received. */
-SemaphoreHandle_t xEMACRxEventSemaphore = NULL;
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-BaseType_t xStatus, xReturn;
-extern uint8_t ucMACAddress[ 6 ];
-
- /* Initialise the MAC. */
- vInitEmac();
-
- while( lEMACWaitForLink() != pdPASS )
- {
- vTaskDelay( 20 );
- }
-
- vSemaphoreCreateBinary( xEMACRxEventSemaphore );
- configASSERT( xEMACRxEventSemaphore );
-
- /* The handler task is created at the highest possible priority to
- ensure the interrupt handler can return directly to it. */
- xTaskCreate( vEMACHandlerTask, "EMAC", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
- xReturn = pdPASS;
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer )
-{
-extern void vEMACCopyWrite( uint8_t * pucBuffer, uint16_t usLength );
-
- vEMACCopyWrite( pxNetworkBuffer->pucBuffer, pxNetworkBuffer->xDataLength );
-
- /* Finished with the network buffer. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
-
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-
+/*
+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. */
+#include <stdint.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "NetworkBufferManagement.h"
+
+/* Hardware includes. */
+#include "hwEthernet.h"
+
+/* Demo includes. */
+#include "NetworkInterface.h"
+
+#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES != 1
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+#else
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+#endif
+
+/* When a packet is ready to be sent, if it cannot be sent immediately then the
+task performing the transmit will block for niTX_BUFFER_FREE_WAIT
+milliseconds. It will do this a maximum of niMAX_TX_ATTEMPTS before giving
+up. */
+#define niTX_BUFFER_FREE_WAIT ( ( TickType_t ) 2UL / portTICK_PERIOD_MS )
+#define niMAX_TX_ATTEMPTS ( 5 )
+
+/* The length of the queue used to send interrupt status words from the
+interrupt handler to the deferred handler task. */
+#define niINTERRUPT_QUEUE_LENGTH ( 10 )
+
+/*-----------------------------------------------------------*/
+
+/*
+ * A deferred interrupt handler task that processes
+ */
+extern void vEMACHandlerTask( void *pvParameters );
+
+/*-----------------------------------------------------------*/
+
+/* The queue used to communicate Ethernet events with the IP task. */
+extern QueueHandle_t xNetworkEventQueue;
+
+/* The semaphore used to wake the deferred interrupt handler task when an Rx
+interrupt is received. */
+SemaphoreHandle_t xEMACRxEventSemaphore = NULL;
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+BaseType_t xStatus, xReturn;
+extern uint8_t ucMACAddress[ 6 ];
+
+ /* Initialise the MAC. */
+ vInitEmac();
+
+ while( lEMACWaitForLink() != pdPASS )
+ {
+ vTaskDelay( 20 );
+ }
+
+ vSemaphoreCreateBinary( xEMACRxEventSemaphore );
+ configASSERT( xEMACRxEventSemaphore );
+
+ /* The handler task is created at the highest possible priority to
+ ensure the interrupt handler can return directly to it. */
+ xTaskCreate( vEMACHandlerTask, "EMAC", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
+ xReturn = pdPASS;
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer )
+{
+extern void vEMACCopyWrite( uint8_t * pucBuffer, uint16_t usLength );
+
+ vEMACCopyWrite( pxNetworkBuffer->pucBuffer, pxNetworkBuffer->xDataLength );
+
+ /* Finished with the network buffer. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+
+ return pdTRUE;
+}
+/*-----------------------------------------------------------*/
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/FaultInjection.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/FaultInjection.c
index 8e64a40cc..502fbd661 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/FaultInjection.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/FaultInjection.c
@@ -1,175 +1,175 @@
-#define xBUFFER_CACHE_SIZE 10
-#define xMAX_FAULT_INJECTION_RATE 15
-#define xMIN_FAULT_INJECTION_RATE 3
-#define xNUM_FAULT_TYPES 1
-
-static NetworkBufferDescriptor_t *xNetworkBufferCache[ xBUFFER_CACHE_SIZE ] = { 0 };
-
-#define xFAULT_LOG_SIZE 2048
-uint32_t ulInjectedFault[ xFAULT_LOG_SIZE ];
-uint32_t ulFaultLogIndex = 0;
-
-static BaseType_t prvCachePacket( NetworkBufferDescriptor_t *pxNetworkBufferIn )
-{
-BaseType_t x, xReturn = pdFALSE;
-
- for( x = 0; x < xBUFFER_CACHE_SIZE; x++ )
- {
- if( xNetworkBufferCache[ x ] == NULL )
- {
- xNetworkBufferCache[ x ] = pxNetworkBufferIn;
- xReturn = pdTRUE;
- break;
- }
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static NetworkBufferDescriptor_t *prvGetCachedPacket( void )
-{
-BaseType_t x;
-NetworkBufferDescriptor_t *pxReturn = NULL;
-
- for( x = ( xBUFFER_CACHE_SIZE - 1 ); x >= 0; x-- )
- {
- if( xNetworkBufferCache[ x ] != NULL )
- {
- pxReturn = xNetworkBufferCache[ x ];
- xNetworkBufferCache[ x ] = NULL;
- break;
- }
- }
-
- return pxReturn;
-}
-/*-----------------------------------------------------------*/
-
-static NetworkBufferDescriptor_t *prvDuplicatePacket( NetworkBufferDescriptor_t * pxOriginalPacket, const uint8_t *pucPacketData )
-{
-NetworkBufferDescriptor_t *pxReturn;
-
- /* Obtain a new descriptor. */
- pxReturn = pxGetNetworkBufferWithDescriptor( pxOriginalPacket->xDataLength, 0 );
-
- if( pxReturn != NULL )
- {
- /* Copy in the packet data. */
- pxReturn->xDataLength = pxOriginalPacket->xDataLength;
- memcpy( pxReturn->pucEthernetBuffer, pucPacketData, pxOriginalPacket->xDataLength );
- }
-
- return pxReturn;
-}
-/*-----------------------------------------------------------*/
-
-static NetworkBufferDescriptor_t *prvRxFaultInjection( NetworkBufferDescriptor_t *pxNetworkBufferIn, const uint8_t *pucPacketData )
-{
-static uint32_t ulCallCount = 0, ulNextFaultCallCount = 0;
-NetworkBufferDescriptor_t *pxReturn = pxNetworkBufferIn;
-IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-uint32_t ulFault;
-
-return pxNetworkBufferIn;
-
- ulCallCount++;
-
- if( ulCallCount > ulNextFaultCallCount )
- {
- xApplicationGetRandomNumber( &( ulNextFaultCallCount ) );
- ulNextFaultCallCount = ulNextFaultCallCount % xMAX_FAULT_INJECTION_RATE;
- if( ulNextFaultCallCount < xMIN_FAULT_INJECTION_RATE )
- {
- ulNextFaultCallCount = xMIN_FAULT_INJECTION_RATE;
- }
-
- ulCallCount = 0;
-
- xApplicationGetRandomNumber( &( ulFault ) );
- ulFault = ulFault % xNUM_FAULT_TYPES;
-
- if( ulFaultLogIndex < xFAULT_LOG_SIZE )
- {
- ulInjectedFault[ ulFaultLogIndex ] = ulFault;
- ulFaultLogIndex++;
- }
-
- switch( ulFault )
- {
- case 0:
- /* Just drop the packet. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
- pxReturn = NULL;
- break;
-
- case 1:
- /* Store the packet in the cache for later. */
- if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
- {
- /* The packet may get sent later, it is not being sent
- now. */
- pxReturn = NULL;
- }
- break;
-
- case 2:
- /* Send a cached packet. */
- pxReturn = prvGetCachedPacket();
- if( pxReturn != NULL )
- {
- /* A cached packet was obtained so drop the original
- packet. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
- }
- else
- {
- /* Could not obtain a packet from the cache so just return
- the packet that was passed in. */
- pxReturn = pxNetworkBufferIn;
- }
- break;
-
- case 4:
-
- /* Send a duplicate of the packet right away. */
- pxReturn = prvDuplicatePacket( pxNetworkBufferIn, pucPacketData );
-
- /* Send the original packet to the stack. */
- xRxEvent.pvData = ( void * ) pxNetworkBufferIn;
- if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
- }
- break;
-
- case 5:
-
- /* Send both a cached packet and the current packet. */
- xRxEvent.pvData = ( void * ) prvGetCachedPacket();
- if( xRxEvent.pvData != NULL )
- {
- if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
- }
- }
- break;
-
- case 6:
- case 7:
- case 8:
- /* Store the packet in the cache for later. */
- if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
- {
- /* The packet may get sent later, it is not being sent
- now. */
- pxReturn = NULL;
- }
- break;
- }
- }
-
- return pxReturn;
-}
-/*-----------------------------------------------------------*/
+#define xBUFFER_CACHE_SIZE 10
+#define xMAX_FAULT_INJECTION_RATE 15
+#define xMIN_FAULT_INJECTION_RATE 3
+#define xNUM_FAULT_TYPES 1
+
+static NetworkBufferDescriptor_t *xNetworkBufferCache[ xBUFFER_CACHE_SIZE ] = { 0 };
+
+#define xFAULT_LOG_SIZE 2048
+uint32_t ulInjectedFault[ xFAULT_LOG_SIZE ];
+uint32_t ulFaultLogIndex = 0;
+
+static BaseType_t prvCachePacket( NetworkBufferDescriptor_t *pxNetworkBufferIn )
+{
+BaseType_t x, xReturn = pdFALSE;
+
+ for( x = 0; x < xBUFFER_CACHE_SIZE; x++ )
+ {
+ if( xNetworkBufferCache[ x ] == NULL )
+ {
+ xNetworkBufferCache[ x ] = pxNetworkBufferIn;
+ xReturn = pdTRUE;
+ break;
+ }
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static NetworkBufferDescriptor_t *prvGetCachedPacket( void )
+{
+BaseType_t x;
+NetworkBufferDescriptor_t *pxReturn = NULL;
+
+ for( x = ( xBUFFER_CACHE_SIZE - 1 ); x >= 0; x-- )
+ {
+ if( xNetworkBufferCache[ x ] != NULL )
+ {
+ pxReturn = xNetworkBufferCache[ x ];
+ xNetworkBufferCache[ x ] = NULL;
+ break;
+ }
+ }
+
+ return pxReturn;
+}
+/*-----------------------------------------------------------*/
+
+static NetworkBufferDescriptor_t *prvDuplicatePacket( NetworkBufferDescriptor_t * pxOriginalPacket, const uint8_t *pucPacketData )
+{
+NetworkBufferDescriptor_t *pxReturn;
+
+ /* Obtain a new descriptor. */
+ pxReturn = pxGetNetworkBufferWithDescriptor( pxOriginalPacket->xDataLength, 0 );
+
+ if( pxReturn != NULL )
+ {
+ /* Copy in the packet data. */
+ pxReturn->xDataLength = pxOriginalPacket->xDataLength;
+ memcpy( pxReturn->pucEthernetBuffer, pucPacketData, pxOriginalPacket->xDataLength );
+ }
+
+ return pxReturn;
+}
+/*-----------------------------------------------------------*/
+
+static NetworkBufferDescriptor_t *prvRxFaultInjection( NetworkBufferDescriptor_t *pxNetworkBufferIn, const uint8_t *pucPacketData )
+{
+static uint32_t ulCallCount = 0, ulNextFaultCallCount = 0;
+NetworkBufferDescriptor_t *pxReturn = pxNetworkBufferIn;
+IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+uint32_t ulFault;
+
+return pxNetworkBufferIn;
+
+ ulCallCount++;
+
+ if( ulCallCount > ulNextFaultCallCount )
+ {
+ xApplicationGetRandomNumber( &( ulNextFaultCallCount ) );
+ ulNextFaultCallCount = ulNextFaultCallCount % xMAX_FAULT_INJECTION_RATE;
+ if( ulNextFaultCallCount < xMIN_FAULT_INJECTION_RATE )
+ {
+ ulNextFaultCallCount = xMIN_FAULT_INJECTION_RATE;
+ }
+
+ ulCallCount = 0;
+
+ xApplicationGetRandomNumber( &( ulFault ) );
+ ulFault = ulFault % xNUM_FAULT_TYPES;
+
+ if( ulFaultLogIndex < xFAULT_LOG_SIZE )
+ {
+ ulInjectedFault[ ulFaultLogIndex ] = ulFault;
+ ulFaultLogIndex++;
+ }
+
+ switch( ulFault )
+ {
+ case 0:
+ /* Just drop the packet. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
+ pxReturn = NULL;
+ break;
+
+ case 1:
+ /* Store the packet in the cache for later. */
+ if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
+ {
+ /* The packet may get sent later, it is not being sent
+ now. */
+ pxReturn = NULL;
+ }
+ break;
+
+ case 2:
+ /* Send a cached packet. */
+ pxReturn = prvGetCachedPacket();
+ if( pxReturn != NULL )
+ {
+ /* A cached packet was obtained so drop the original
+ packet. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
+ }
+ else
+ {
+ /* Could not obtain a packet from the cache so just return
+ the packet that was passed in. */
+ pxReturn = pxNetworkBufferIn;
+ }
+ break;
+
+ case 4:
+
+ /* Send a duplicate of the packet right away. */
+ pxReturn = prvDuplicatePacket( pxNetworkBufferIn, pucPacketData );
+
+ /* Send the original packet to the stack. */
+ xRxEvent.pvData = ( void * ) pxNetworkBufferIn;
+ if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
+ }
+ break;
+
+ case 5:
+
+ /* Send both a cached packet and the current packet. */
+ xRxEvent.pvData = ( void * ) prvGetCachedPacket();
+ if( xRxEvent.pvData != NULL )
+ {
+ if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
+ }
+ }
+ break;
+
+ case 6:
+ case 7:
+ case 8:
+ /* Store the packet in the cache for later. */
+ if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
+ {
+ /* The packet may get sent later, it is not being sent
+ now. */
+ pxReturn = NULL;
+ }
+ break;
+ }
+ }
+
+ return pxReturn;
+}
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c
index c4a12515b..474629e46 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c
@@ -1,634 +1,634 @@
-/*
-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
-*/
-
-/* WinPCap includes. */
-#define HAVE_REMOTE
-#include "pcap.h"
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-
-/* Thread-safe circular buffers are being used to pass data to and from the PCAP
-access functions. */
-#include "Win32-Extensions.h"
-#include "FreeRTOS_Stream_Buffer.h"
-
-/* Sizes of the thread safe circular buffers used to pass data to and from the
-WinPCAP Windows threads. */
-#define xSEND_BUFFER_SIZE 32768
-#define xRECV_BUFFER_SIZE 32768
-
-/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
-driver will filter incoming packets and only pass the stack those packets it
-considers need processing. */
-#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
-#else
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
-#endif
-
-/* Used to insert test code only. */
-#define niDISRUPT_PACKETS 0
-
-/*-----------------------------------------------------------*/
-
-/*
- * Windows threads that are outside of the control of the FreeRTOS simulator are
- * used to interface with the WinPCAP libraries.
- */
-DWORD WINAPI prvWinPcapRecvThread( void *pvParam );
-DWORD WINAPI prvWinPcapSendThread( void *pvParam );
-
-/*
- * Print out a numbered list of network interfaces that are available on the
- * host computer.
- */
-static pcap_if_t * prvPrintAvailableNetworkInterfaces( void );
-
-/*
- * Open the network interface. The number of the interface to be opened is set
- * by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
- */
-static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces );
-static int prvOpenInterface( const char *pucName );
-
-/*
- * Configure the capture filter to allow blocking reads, and to filter out
- * packets that are not of interest to this demo.
- */
-static void prvConfigureCaptureBehaviour( void );
-
-/*
- * A function that simulates Ethernet interrupts by periodically polling the
- * WinPCap interface for new data.
- */
-static void prvInterruptSimulatorTask( void *pvParameters );
-
-/*
- * Create the buffers that are used to pass data between the FreeRTOS simulator
- * and the Win32 threads that manage WinPCAP.
- */
-static void prvCreateThreadSafeBuffers( void );
-
-/*
- * Utility function used to format print messages only.
- */
-static const char *prvRemoveSpaces( char *pcBuffer, int aBuflen, const char *pcMessage );
-
-/*-----------------------------------------------------------*/
-
-/* Required by the WinPCap library. */
-static char cErrorBuffer[ PCAP_ERRBUF_SIZE ];
-
-/* An event used to wake up the Win32 thread that sends data through the WinPCAP
-library. */
-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 xConfigNetworkInterfaceToUse = configNETWORK_INTERFACE_TO_USE;
-
-/* Handles to the Windows threads that handle the PCAP IO. */
-static HANDLE vWinPcapRecvThreadHandle = NULL;
-static HANDLE vWinPcapSendThreadHandle = NULL;;
-
-/* The interface being used by WinPCap. */
-static pcap_t *pxOpenedInterfaceHandle = NULL;
-
-/* Circular buffers used by the PCAP Win32 threads. */
-static StreamBuffer_t *xSendBuffer = NULL;
-static StreamBuffer_t *xRecvBuffer = NULL;
-
-/* The MAC address initially set to the constants defined in FreeRTOSConfig.h. */
-extern uint8_t ucMACAddress[ 6 ];
-
-/* Logs the number of WinPCAP send failures, for viewing in the debugger only. */
-static volatile uint32_t ulWinPCAPSendFailures = 0;
-
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-BaseType_t xReturn = pdFALSE;
-pcap_if_t *pxAllNetworkInterfaces;
-
- /* Query the computer the simulation is being executed on to find the
- network interfaces it has installed. */
- pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces();
-
- /* Open the network interface. The number of the interface to be opened is
- set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
- Calling this function will set the pxOpenedInterfaceHandle variable. If,
- after calling this function, pxOpenedInterfaceHandle is equal to NULL, then
- the interface could not be opened. */
- if( pxAllNetworkInterfaces != NULL )
- {
- prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces );
- }
-
- if( pxOpenedInterfaceHandle != NULL )
- {
- xReturn = pdPASS;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static void prvCreateThreadSafeBuffers( void )
-{
- /* The buffer used to pass data to be transmitted from a FreeRTOS task to
- the Win32 thread that sends via the WinPCAP library. */
- if( xSendBuffer == NULL)
- {
- xSendBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xSendBuffer ) - sizeof( xSendBuffer->ucArray ) + xSEND_BUFFER_SIZE + 1 );
- configASSERT( xSendBuffer );
- memset( xSendBuffer, '\0', sizeof( *xSendBuffer ) - sizeof( xSendBuffer->ucArray ) );
- xSendBuffer->LENGTH = xSEND_BUFFER_SIZE + 1;
- }
-
- /* The buffer used to pass received data from the Win32 thread that receives
- via the WinPCAP library to the FreeRTOS task. */
- if( xRecvBuffer == NULL)
- {
- xRecvBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xRecvBuffer ) - sizeof( xRecvBuffer->ucArray ) + xRECV_BUFFER_SIZE + 1 );
- configASSERT( xRecvBuffer );
- memset( xRecvBuffer, '\0', sizeof( *xRecvBuffer ) - sizeof( xRecvBuffer->ucArray ) );
- xRecvBuffer->LENGTH = xRECV_BUFFER_SIZE + 1;
- }
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t bReleaseAfterSend )
-{
-size_t xSpace;
-
- iptraceNETWORK_INTERFACE_TRANSMIT();
- configASSERT( xIsCallingFromIPTask() == pdTRUE );
-
- /* Both the length of the data being sent and the actual data being sent
- are placed in the thread safe buffer used to pass data between the FreeRTOS
- tasks and the Win32 thread that sends data via the WinPCAP library. Drop
- the packet if there is insufficient space in the buffer to hold both. */
- xSpace = uxStreamBufferGetSpace( xSendBuffer );
-
- if( ( pxNetworkBuffer->xDataLength <= ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) &&
- ( xSpace >= ( pxNetworkBuffer->xDataLength + sizeof( pxNetworkBuffer->xDataLength ) ) ) )
- {
- /* First write in the length of the data, then write in the data
- itself. */
- uxStreamBufferAdd( xSendBuffer, 0, ( const uint8_t * ) &( pxNetworkBuffer->xDataLength ), sizeof( pxNetworkBuffer->xDataLength ) );
- uxStreamBufferAdd( xSendBuffer, 0, ( const uint8_t * ) pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength );
- }
- else
- {
- FreeRTOS_debug_printf( ( "xNetworkInterfaceOutput: send buffers full to store %lu\n", pxNetworkBuffer->xDataLength ) );
- }
-
- /* Kick the Tx task in either case in case it doesn't know the buffer is
- full. */
- SetEvent( pvSendEvent );
-
- /* The buffer has been sent so can be released. */
- if( bReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- }
-
- return pdPASS;
-}
-/*-----------------------------------------------------------*/
-
-static pcap_if_t * prvPrintAvailableNetworkInterfaces( void )
-{
-pcap_if_t * pxAllNetworkInterfaces = NULL, *xInterface;
-int32_t lInterfaceNumber = 1;
-char cBuffer[ 512 ];
-static BaseType_t xInvalidInterfaceDetected = pdFALSE;
-
- if( xInvalidInterfaceDetected == pdFALSE )
- {
- if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL, &pxAllNetworkInterfaces, cErrorBuffer ) == -1 )
- {
- printf( "Could not obtain a list of network interfaces\n%s\n", cErrorBuffer );
- pxAllNetworkInterfaces = NULL;
- }
- else
- {
- printf( "\r\n\r\nThe following network interfaces are available:\r\n\r\n" );
- }
-
- if( pxAllNetworkInterfaces != NULL )
- {
- /* Print out the list of network interfaces. The first in the list
- is interface '1', not interface '0'. */
- for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next )
- {
- /* The descriptions of the devices can be full of spaces, clean them
- a little. printf() can only be used here because the network is not
- up yet - so no other network tasks will be running. */
- printf( "Interface %d - %s\n", lInterfaceNumber, prvRemoveSpaces( cBuffer, sizeof( cBuffer ), xInterface->name ) );
- printf( " (%s)\n", prvRemoveSpaces(cBuffer, sizeof( cBuffer ), xInterface->description ? xInterface->description : "No description" ) );
- printf( "\n" );
- lInterfaceNumber++;
- }
- }
-
- if( lInterfaceNumber == 1 )
- {
- /* The interface number was never incremented, so the above for() loop
- did not execute meaning no interfaces were found. */
- printf( " \nNo network interfaces were found.\n" );
- pxAllNetworkInterfaces = NULL;
- }
-
- 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( ( xConfigNetworkInterfaceToUse < 1L ) || ( xConfigNetworkInterfaceToUse >= lInterfaceNumber ) )
- {
- 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" );
- xInvalidInterfaceDetected = pdTRUE;
-
- if( pxAllNetworkInterfaces != NULL )
- {
- /* Free the device list, as no devices are going to be opened. */
- pcap_freealldevs( pxAllNetworkInterfaces );
- pxAllNetworkInterfaces = NULL;
- }
- }
- else
- {
- printf( "Attempting to open interface number %d.\n", xConfigNetworkInterfaceToUse );
- }
- }
-
- return pxAllNetworkInterfaces;
-}
-/*-----------------------------------------------------------*/
-
-static int prvOpenInterface( const char *pucName )
-{
-static char pucInterfaceName[ 256 ];
-
- if( pucName != NULL )
- {
- strncpy( pucInterfaceName, pucName, sizeof( pucInterfaceName ) );
- }
-
- pxOpenedInterfaceHandle = pcap_open( pucInterfaceName, /* The name of the selected interface. */
- ipTOTAL_ETHERNET_FRAME_SIZE, /* The size of the packet to capture. */
- PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscuous mode as the MAC and
- IP address is going to be "simulated", and
- not be the real MAC and IP address. This allows
- traffic to the simulated IP address to be routed
- to uIP, and traffic to the real IP address to be
- routed to the Windows TCP/IP stack. */
- 100,
- NULL, /* No authentication is required as this is
- not a remote capture session. */
- cErrorBuffer
- );
-
- if ( pxOpenedInterfaceHandle == NULL )
- {
- printf( "\n%s is not supported by WinPcap and cannot be opened\n", pucInterfaceName );
- return 1;
- }
- else
- {
- /* Configure the capture filter to allow blocking reads, and to filter
- out packets that are not of interest to this demo. */
- prvConfigureCaptureBehaviour();
- }
- return 0;
-}
-/*-----------------------------------------------------------*/
-
-static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces )
-{
-pcap_if_t *pxInterface;
-int32_t x;
-
- /* Walk the list of devices until the selected device is located. */
- pxInterface = pxAllNetworkInterfaces;
- for( x = 0L; x < ( xConfigNetworkInterfaceToUse - 1L ); x++ )
- {
- pxInterface = pxInterface->next;
- }
-
- /* 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. */
- pcap_freealldevs( pxAllNetworkInterfaces );
-}
-/*-----------------------------------------------------------*/
-
-static void prvConfigureCaptureBehaviour( void )
-{
-struct bpf_program xFilterCode;
-uint32_t ulNetMask;
-
- /* Set up a filter so only the packets of interest are passed to the IP
- stack. cErrorBuffer is used for convenience to create the string. Don't
- confuse this with an error message. */
- sprintf( cErrorBuffer, "broadcast or multicast or ether host %x:%x:%x:%x:%x:%x",
- ucMACAddress[0], ucMACAddress[1], ucMACAddress[2], ucMACAddress[3], ucMACAddress[4], ucMACAddress[5] );
-
- ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0;
-
- if( pcap_compile( pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 )
- {
- printf( "\nThe packet filter string is invalid\n" );
- }
- else
- {
- if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 )
- {
- 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 );
- }
-
- /* Create the buffers used to pass packets between the FreeRTOS simulator
- and the Win32 threads that are handling WinPCAP. */
- prvCreateThreadSafeBuffers();
-
- if( pvSendEvent == NULL )
- {
- /* Create event used to signal the Win32 WinPCAP Tx thread. */
- pvSendEvent = CreateEvent( NULL, FALSE, TRUE, NULL );
-
- /* Create the Win32 thread that handles WinPCAP Rx. */
- vWinPcapRecvThreadHandle = CreateThread(
- NULL, /* Pointer to thread security attributes. */
- 0, /* Initial thread stack size, in bytes. */
- prvWinPcapRecvThread, /* Pointer to thread function. */
- NULL, /* Argument for new thread. */
- 0, /* Creation flags. */
- NULL );
-
- /* Use the cores that are not used by the FreeRTOS tasks. */
- SetThreadAffinityMask( vWinPcapRecvThreadHandle, ~0x01u );
-
- /* Create the Win32 thread that handlers WinPCAP Tx. */
- vWinPcapSendThreadHandle = CreateThread(
- NULL, /* Pointer to thread security attributes. */
- 0, /* initial thread stack size, in bytes. */
- prvWinPcapSendThread, /* Pointer to thread function. */
- NULL, /* Argument for new thread. */
- 0, /* Creation flags. */
- NULL );
-
- /* Use the cores that are not used by the FreeRTOS tasks. */
- SetThreadAffinityMask( vWinPcapSendThreadHandle, ~0x01u );
-
- /* Create a task that simulates an interrupt in a real system. This will
- block waiting for packets, then send a message to the IP task when data
- is available. */
- xTaskCreate( prvInterruptSimulatorTask, "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, configMAC_ISR_SIMULATOR_PRIORITY, NULL );
- }
-}
-/*-----------------------------------------------------------*/
-
-/* WinPCAP function. */
-void pcap_callback( u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data )
-{
- (void)user;
-
- /* THIS IS CALLED FROM A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS
- OR TO PRINT OUT MESSAGES HERE. */
-
- /* Pass data to the FreeRTOS simulator on a thread safe circular buffer. */
- if( ( pkt_header->caplen <= ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) &&
- ( uxStreamBufferGetSpace( xRecvBuffer ) >= ( ( ( size_t ) pkt_header->caplen ) + sizeof( *pkt_header ) ) ) )
- {
- uxStreamBufferAdd( xRecvBuffer, 0, ( const uint8_t* ) pkt_header, sizeof( *pkt_header ) );
- uxStreamBufferAdd( xRecvBuffer, 0, ( const uint8_t* ) pkt_data, ( size_t ) pkt_header->caplen );
- }
-}
-/*-----------------------------------------------------------*/
-
-DWORD WINAPI prvWinPcapRecvThread ( void *pvParam )
-{
- ( void ) pvParam;
-
- /* THIS IS A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS OR TO PRINT
- OUT MESSAGES HERE. */
-
- for( ;; )
- {
- pcap_dispatch( pxOpenedInterfaceHandle, 1, pcap_callback, ( u_char * ) "mydata" );
- }
-}
-/*-----------------------------------------------------------*/
-
-DWORD WINAPI prvWinPcapSendThread( void *pvParam )
-{
-size_t xLength;
-uint8_t ucBuffer[ ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ];
-static char cErrorMessage[ 1024 ];
-const DWORD xMaxMSToWait = 1000;
-
- /* THIS IS A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS OR TO PRINT
- OUT MESSAGES HERE. */
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParam;
-
- for( ;; )
- {
- /* Wait until notified of something to send. */
- WaitForSingleObject( pvSendEvent, xMaxMSToWait );
-
- /* Is there more than the length value stored in the circular buffer
- used to pass data from the FreeRTOS simulator into this Win32 thread? */
- while( uxStreamBufferGetSize( xSendBuffer ) > sizeof( xLength ) )
- {
- uxStreamBufferGet( xSendBuffer, 0, ( uint8_t * ) &xLength, sizeof( xLength ), pdFALSE );
- uxStreamBufferGet( xSendBuffer, 0, ( uint8_t* ) ucBuffer, xLength, pdFALSE );
- if( pcap_sendpacket( pxOpenedInterfaceHandle, ucBuffer, xLength ) != 0 )
- {
- ulWinPCAPSendFailures++;
- }
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvInterruptSimulatorTask( void *pvParameters )
-{
-struct pcap_pkthdr xHeader;
-static struct pcap_pkthdr *pxHeader;
-const uint8_t *pucPacketData;
-uint8_t ucRecvBuffer[ ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ];
-NetworkBufferDescriptor_t *pxNetworkBuffer;
-IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-eFrameProcessingResult_t eResult;
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
-
- for( ;; )
- {
- /* Does the circular buffer used to pass data from the Win32 thread that
- handles WinPCAP Rx into the FreeRTOS simulator contain another packet? */
- if( uxStreamBufferGetSize( xRecvBuffer ) > sizeof( xHeader ) )
- {
- /* Get the next packet. */
- uxStreamBufferGet( xRecvBuffer, 0, (uint8_t*)&xHeader, sizeof( xHeader ), pdFALSE );
- uxStreamBufferGet( xRecvBuffer, 0, (uint8_t*)ucRecvBuffer, ( size_t ) xHeader.len, pdFALSE );
- pucPacketData = ucRecvBuffer;
- pxHeader = &xHeader;
-
- iptraceNETWORK_INTERFACE_RECEIVE();
-
- /* Check for minimal size. */
- if( pxHeader->len >= sizeof( EthernetHeader_t ) )
- {
- eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
- }
- else
- {
- eResult = eReleaseBuffer;
- }
-
- if( eResult == eProcessBuffer )
- {
- /* Will the data fit into the frame buffer? */
- if( pxHeader->len <= ipTOTAL_ETHERNET_FRAME_SIZE )
- {
- /* Obtain a buffer into which the data can be placed. This
- is only an interrupt simulator, not a real interrupt, so it
- is ok to call the task level function here, but note that
- some buffer implementations cannot be called from a real
- interrupt. */
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( pxHeader->len, 0 );
-
- if( pxNetworkBuffer != NULL )
- {
- memcpy( pxNetworkBuffer->pucEthernetBuffer, pucPacketData, pxHeader->len );
- pxNetworkBuffer->xDataLength = ( size_t ) pxHeader->len;
-
- #if( niDISRUPT_PACKETS == 1 )
- {
- pxNetworkBuffer = vRxFaultInjection( pxNetworkBuffer, pucPacketData );
- }
- #endif /* niDISRUPT_PACKETS */
-
- if( pxNetworkBuffer != NULL )
- {
- xRxEvent.pvData = ( void * ) pxNetworkBuffer;
-
- /* Data was received and stored. Send a message to
- the IP task to let it know. */
- if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
- {
- /* The buffer could not be sent to the stack so
- must be released again. This is only an
- interrupt simulator, not a real interrupt, so it
- is ok to use the task level function here, but
- note no all buffer implementations will allow
- this function to be executed from a real
- interrupt. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- iptraceETHERNET_RX_EVENT_LOST();
- }
- }
- else
- {
- /* The packet was already released or stored inside
- vRxFaultInjection(). Don't release it here. */
- }
- }
- else
- {
- iptraceETHERNET_RX_EVENT_LOST();
- }
- }
- else
- {
- /* Log that a packet was dropped because it would have
- overflowed the buffer, but there may be more buffers to
- process. */
- }
- }
- }
- else
- {
- /* There is no real way of simulating an interrupt. Make sure
- other tasks can run. */
- vTaskDelay( configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY );
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-static const char *prvRemoveSpaces( char *pcBuffer, int aBuflen, const char *pcMessage )
-{
- char *pcTarget = pcBuffer;
-
- /* Utility function used to formap messages being printed only. */
- while( ( *pcMessage != 0 ) && ( pcTarget < ( pcBuffer + aBuflen - 1 ) ) )
- {
- *( pcTarget++ ) = *pcMessage;
-
- if( isspace( *pcMessage ) != pdFALSE )
- {
- while( isspace( *pcMessage ) != pdFALSE )
- {
- pcMessage++;
- }
- }
- else
- {
- pcMessage++;
- }
- }
-
- *pcTarget = '\0';
-
- return pcBuffer;
-}
+/*
+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
+*/
+
+/* WinPCap includes. */
+#define HAVE_REMOTE
+#include "pcap.h"
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+
+/* Thread-safe circular buffers are being used to pass data to and from the PCAP
+access functions. */
+#include "Win32-Extensions.h"
+#include "FreeRTOS_Stream_Buffer.h"
+
+/* Sizes of the thread safe circular buffers used to pass data to and from the
+WinPCAP Windows threads. */
+#define xSEND_BUFFER_SIZE 32768
+#define xRECV_BUFFER_SIZE 32768
+
+/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
+driver will filter incoming packets and only pass the stack those packets it
+considers need processing. */
+#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+#else
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+#endif
+
+/* Used to insert test code only. */
+#define niDISRUPT_PACKETS 0
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Windows threads that are outside of the control of the FreeRTOS simulator are
+ * used to interface with the WinPCAP libraries.
+ */
+DWORD WINAPI prvWinPcapRecvThread( void *pvParam );
+DWORD WINAPI prvWinPcapSendThread( void *pvParam );
+
+/*
+ * Print out a numbered list of network interfaces that are available on the
+ * host computer.
+ */
+static pcap_if_t * prvPrintAvailableNetworkInterfaces( void );
+
+/*
+ * Open the network interface. The number of the interface to be opened is set
+ * by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
+ */
+static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces );
+static int prvOpenInterface( const char *pucName );
+
+/*
+ * Configure the capture filter to allow blocking reads, and to filter out
+ * packets that are not of interest to this demo.
+ */
+static void prvConfigureCaptureBehaviour( void );
+
+/*
+ * A function that simulates Ethernet interrupts by periodically polling the
+ * WinPCap interface for new data.
+ */
+static void prvInterruptSimulatorTask( void *pvParameters );
+
+/*
+ * Create the buffers that are used to pass data between the FreeRTOS simulator
+ * and the Win32 threads that manage WinPCAP.
+ */
+static void prvCreateThreadSafeBuffers( void );
+
+/*
+ * Utility function used to format print messages only.
+ */
+static const char *prvRemoveSpaces( char *pcBuffer, int aBuflen, const char *pcMessage );
+
+/*-----------------------------------------------------------*/
+
+/* Required by the WinPCap library. */
+static char cErrorBuffer[ PCAP_ERRBUF_SIZE ];
+
+/* An event used to wake up the Win32 thread that sends data through the WinPCAP
+library. */
+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 xConfigNetworkInterfaceToUse = configNETWORK_INTERFACE_TO_USE;
+
+/* Handles to the Windows threads that handle the PCAP IO. */
+static HANDLE vWinPcapRecvThreadHandle = NULL;
+static HANDLE vWinPcapSendThreadHandle = NULL;;
+
+/* The interface being used by WinPCap. */
+static pcap_t *pxOpenedInterfaceHandle = NULL;
+
+/* Circular buffers used by the PCAP Win32 threads. */
+static StreamBuffer_t *xSendBuffer = NULL;
+static StreamBuffer_t *xRecvBuffer = NULL;
+
+/* The MAC address initially set to the constants defined in FreeRTOSConfig.h. */
+extern uint8_t ucMACAddress[ 6 ];
+
+/* Logs the number of WinPCAP send failures, for viewing in the debugger only. */
+static volatile uint32_t ulWinPCAPSendFailures = 0;
+
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+BaseType_t xReturn = pdFALSE;
+pcap_if_t *pxAllNetworkInterfaces;
+
+ /* Query the computer the simulation is being executed on to find the
+ network interfaces it has installed. */
+ pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces();
+
+ /* Open the network interface. The number of the interface to be opened is
+ set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
+ Calling this function will set the pxOpenedInterfaceHandle variable. If,
+ after calling this function, pxOpenedInterfaceHandle is equal to NULL, then
+ the interface could not be opened. */
+ if( pxAllNetworkInterfaces != NULL )
+ {
+ prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces );
+ }
+
+ if( pxOpenedInterfaceHandle != NULL )
+ {
+ xReturn = pdPASS;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static void prvCreateThreadSafeBuffers( void )
+{
+ /* The buffer used to pass data to be transmitted from a FreeRTOS task to
+ the Win32 thread that sends via the WinPCAP library. */
+ if( xSendBuffer == NULL)
+ {
+ xSendBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xSendBuffer ) - sizeof( xSendBuffer->ucArray ) + xSEND_BUFFER_SIZE + 1 );
+ configASSERT( xSendBuffer );
+ memset( xSendBuffer, '\0', sizeof( *xSendBuffer ) - sizeof( xSendBuffer->ucArray ) );
+ xSendBuffer->LENGTH = xSEND_BUFFER_SIZE + 1;
+ }
+
+ /* The buffer used to pass received data from the Win32 thread that receives
+ via the WinPCAP library to the FreeRTOS task. */
+ if( xRecvBuffer == NULL)
+ {
+ xRecvBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xRecvBuffer ) - sizeof( xRecvBuffer->ucArray ) + xRECV_BUFFER_SIZE + 1 );
+ configASSERT( xRecvBuffer );
+ memset( xRecvBuffer, '\0', sizeof( *xRecvBuffer ) - sizeof( xRecvBuffer->ucArray ) );
+ xRecvBuffer->LENGTH = xRECV_BUFFER_SIZE + 1;
+ }
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t bReleaseAfterSend )
+{
+size_t xSpace;
+
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+ configASSERT( xIsCallingFromIPTask() == pdTRUE );
+
+ /* Both the length of the data being sent and the actual data being sent
+ are placed in the thread safe buffer used to pass data between the FreeRTOS
+ tasks and the Win32 thread that sends data via the WinPCAP library. Drop
+ the packet if there is insufficient space in the buffer to hold both. */
+ xSpace = uxStreamBufferGetSpace( xSendBuffer );
+
+ if( ( pxNetworkBuffer->xDataLength <= ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) &&
+ ( xSpace >= ( pxNetworkBuffer->xDataLength + sizeof( pxNetworkBuffer->xDataLength ) ) ) )
+ {
+ /* First write in the length of the data, then write in the data
+ itself. */
+ uxStreamBufferAdd( xSendBuffer, 0, ( const uint8_t * ) &( pxNetworkBuffer->xDataLength ), sizeof( pxNetworkBuffer->xDataLength ) );
+ uxStreamBufferAdd( xSendBuffer, 0, ( const uint8_t * ) pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength );
+ }
+ else
+ {
+ FreeRTOS_debug_printf( ( "xNetworkInterfaceOutput: send buffers full to store %lu\n", pxNetworkBuffer->xDataLength ) );
+ }
+
+ /* Kick the Tx task in either case in case it doesn't know the buffer is
+ full. */
+ SetEvent( pvSendEvent );
+
+ /* The buffer has been sent so can be released. */
+ if( bReleaseAfterSend != pdFALSE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ }
+
+ return pdPASS;
+}
+/*-----------------------------------------------------------*/
+
+static pcap_if_t * prvPrintAvailableNetworkInterfaces( void )
+{
+pcap_if_t * pxAllNetworkInterfaces = NULL, *xInterface;
+int32_t lInterfaceNumber = 1;
+char cBuffer[ 512 ];
+static BaseType_t xInvalidInterfaceDetected = pdFALSE;
+
+ if( xInvalidInterfaceDetected == pdFALSE )
+ {
+ if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL, &pxAllNetworkInterfaces, cErrorBuffer ) == -1 )
+ {
+ printf( "Could not obtain a list of network interfaces\n%s\n", cErrorBuffer );
+ pxAllNetworkInterfaces = NULL;
+ }
+ else
+ {
+ printf( "\r\n\r\nThe following network interfaces are available:\r\n\r\n" );
+ }
+
+ if( pxAllNetworkInterfaces != NULL )
+ {
+ /* Print out the list of network interfaces. The first in the list
+ is interface '1', not interface '0'. */
+ for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next )
+ {
+ /* The descriptions of the devices can be full of spaces, clean them
+ a little. printf() can only be used here because the network is not
+ up yet - so no other network tasks will be running. */
+ printf( "Interface %d - %s\n", lInterfaceNumber, prvRemoveSpaces( cBuffer, sizeof( cBuffer ), xInterface->name ) );
+ printf( " (%s)\n", prvRemoveSpaces(cBuffer, sizeof( cBuffer ), xInterface->description ? xInterface->description : "No description" ) );
+ printf( "\n" );
+ lInterfaceNumber++;
+ }
+ }
+
+ if( lInterfaceNumber == 1 )
+ {
+ /* The interface number was never incremented, so the above for() loop
+ did not execute meaning no interfaces were found. */
+ printf( " \nNo network interfaces were found.\n" );
+ pxAllNetworkInterfaces = NULL;
+ }
+
+ 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( ( xConfigNetworkInterfaceToUse < 1L ) || ( xConfigNetworkInterfaceToUse >= lInterfaceNumber ) )
+ {
+ 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" );
+ xInvalidInterfaceDetected = pdTRUE;
+
+ if( pxAllNetworkInterfaces != NULL )
+ {
+ /* Free the device list, as no devices are going to be opened. */
+ pcap_freealldevs( pxAllNetworkInterfaces );
+ pxAllNetworkInterfaces = NULL;
+ }
+ }
+ else
+ {
+ printf( "Attempting to open interface number %d.\n", xConfigNetworkInterfaceToUse );
+ }
+ }
+
+ return pxAllNetworkInterfaces;
+}
+/*-----------------------------------------------------------*/
+
+static int prvOpenInterface( const char *pucName )
+{
+static char pucInterfaceName[ 256 ];
+
+ if( pucName != NULL )
+ {
+ strncpy( pucInterfaceName, pucName, sizeof( pucInterfaceName ) );
+ }
+
+ pxOpenedInterfaceHandle = pcap_open( pucInterfaceName, /* The name of the selected interface. */
+ ipTOTAL_ETHERNET_FRAME_SIZE, /* The size of the packet to capture. */
+ PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscuous mode as the MAC and
+ IP address is going to be "simulated", and
+ not be the real MAC and IP address. This allows
+ traffic to the simulated IP address to be routed
+ to uIP, and traffic to the real IP address to be
+ routed to the Windows TCP/IP stack. */
+ 100,
+ NULL, /* No authentication is required as this is
+ not a remote capture session. */
+ cErrorBuffer
+ );
+
+ if ( pxOpenedInterfaceHandle == NULL )
+ {
+ printf( "\n%s is not supported by WinPcap and cannot be opened\n", pucInterfaceName );
+ return 1;
+ }
+ else
+ {
+ /* Configure the capture filter to allow blocking reads, and to filter
+ out packets that are not of interest to this demo. */
+ prvConfigureCaptureBehaviour();
+ }
+ return 0;
+}
+/*-----------------------------------------------------------*/
+
+static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces )
+{
+pcap_if_t *pxInterface;
+int32_t x;
+
+ /* Walk the list of devices until the selected device is located. */
+ pxInterface = pxAllNetworkInterfaces;
+ for( x = 0L; x < ( xConfigNetworkInterfaceToUse - 1L ); x++ )
+ {
+ pxInterface = pxInterface->next;
+ }
+
+ /* 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. */
+ pcap_freealldevs( pxAllNetworkInterfaces );
+}
+/*-----------------------------------------------------------*/
+
+static void prvConfigureCaptureBehaviour( void )
+{
+struct bpf_program xFilterCode;
+uint32_t ulNetMask;
+
+ /* Set up a filter so only the packets of interest are passed to the IP
+ stack. cErrorBuffer is used for convenience to create the string. Don't
+ confuse this with an error message. */
+ sprintf( cErrorBuffer, "broadcast or multicast or ether host %x:%x:%x:%x:%x:%x",
+ ucMACAddress[0], ucMACAddress[1], ucMACAddress[2], ucMACAddress[3], ucMACAddress[4], ucMACAddress[5] );
+
+ ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0;
+
+ if( pcap_compile( pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 )
+ {
+ printf( "\nThe packet filter string is invalid\n" );
+ }
+ else
+ {
+ if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 )
+ {
+ 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 );
+ }
+
+ /* Create the buffers used to pass packets between the FreeRTOS simulator
+ and the Win32 threads that are handling WinPCAP. */
+ prvCreateThreadSafeBuffers();
+
+ if( pvSendEvent == NULL )
+ {
+ /* Create event used to signal the Win32 WinPCAP Tx thread. */
+ pvSendEvent = CreateEvent( NULL, FALSE, TRUE, NULL );
+
+ /* Create the Win32 thread that handles WinPCAP Rx. */
+ vWinPcapRecvThreadHandle = CreateThread(
+ NULL, /* Pointer to thread security attributes. */
+ 0, /* Initial thread stack size, in bytes. */
+ prvWinPcapRecvThread, /* Pointer to thread function. */
+ NULL, /* Argument for new thread. */
+ 0, /* Creation flags. */
+ NULL );
+
+ /* Use the cores that are not used by the FreeRTOS tasks. */
+ SetThreadAffinityMask( vWinPcapRecvThreadHandle, ~0x01u );
+
+ /* Create the Win32 thread that handlers WinPCAP Tx. */
+ vWinPcapSendThreadHandle = CreateThread(
+ NULL, /* Pointer to thread security attributes. */
+ 0, /* initial thread stack size, in bytes. */
+ prvWinPcapSendThread, /* Pointer to thread function. */
+ NULL, /* Argument for new thread. */
+ 0, /* Creation flags. */
+ NULL );
+
+ /* Use the cores that are not used by the FreeRTOS tasks. */
+ SetThreadAffinityMask( vWinPcapSendThreadHandle, ~0x01u );
+
+ /* Create a task that simulates an interrupt in a real system. This will
+ block waiting for packets, then send a message to the IP task when data
+ is available. */
+ xTaskCreate( prvInterruptSimulatorTask, "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, configMAC_ISR_SIMULATOR_PRIORITY, NULL );
+ }
+}
+/*-----------------------------------------------------------*/
+
+/* WinPCAP function. */
+void pcap_callback( u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data )
+{
+ (void)user;
+
+ /* THIS IS CALLED FROM A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS
+ OR TO PRINT OUT MESSAGES HERE. */
+
+ /* Pass data to the FreeRTOS simulator on a thread safe circular buffer. */
+ if( ( pkt_header->caplen <= ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) &&
+ ( uxStreamBufferGetSpace( xRecvBuffer ) >= ( ( ( size_t ) pkt_header->caplen ) + sizeof( *pkt_header ) ) ) )
+ {
+ uxStreamBufferAdd( xRecvBuffer, 0, ( const uint8_t* ) pkt_header, sizeof( *pkt_header ) );
+ uxStreamBufferAdd( xRecvBuffer, 0, ( const uint8_t* ) pkt_data, ( size_t ) pkt_header->caplen );
+ }
+}
+/*-----------------------------------------------------------*/
+
+DWORD WINAPI prvWinPcapRecvThread ( void *pvParam )
+{
+ ( void ) pvParam;
+
+ /* THIS IS A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS OR TO PRINT
+ OUT MESSAGES HERE. */
+
+ for( ;; )
+ {
+ pcap_dispatch( pxOpenedInterfaceHandle, 1, pcap_callback, ( u_char * ) "mydata" );
+ }
+}
+/*-----------------------------------------------------------*/
+
+DWORD WINAPI prvWinPcapSendThread( void *pvParam )
+{
+size_t xLength;
+uint8_t ucBuffer[ ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ];
+static char cErrorMessage[ 1024 ];
+const DWORD xMaxMSToWait = 1000;
+
+ /* THIS IS A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS OR TO PRINT
+ OUT MESSAGES HERE. */
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParam;
+
+ for( ;; )
+ {
+ /* Wait until notified of something to send. */
+ WaitForSingleObject( pvSendEvent, xMaxMSToWait );
+
+ /* Is there more than the length value stored in the circular buffer
+ used to pass data from the FreeRTOS simulator into this Win32 thread? */
+ while( uxStreamBufferGetSize( xSendBuffer ) > sizeof( xLength ) )
+ {
+ uxStreamBufferGet( xSendBuffer, 0, ( uint8_t * ) &xLength, sizeof( xLength ), pdFALSE );
+ uxStreamBufferGet( xSendBuffer, 0, ( uint8_t* ) ucBuffer, xLength, pdFALSE );
+ if( pcap_sendpacket( pxOpenedInterfaceHandle, ucBuffer, xLength ) != 0 )
+ {
+ ulWinPCAPSendFailures++;
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvInterruptSimulatorTask( void *pvParameters )
+{
+struct pcap_pkthdr xHeader;
+static struct pcap_pkthdr *pxHeader;
+const uint8_t *pucPacketData;
+uint8_t ucRecvBuffer[ ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ];
+NetworkBufferDescriptor_t *pxNetworkBuffer;
+IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+eFrameProcessingResult_t eResult;
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+
+ for( ;; )
+ {
+ /* Does the circular buffer used to pass data from the Win32 thread that
+ handles WinPCAP Rx into the FreeRTOS simulator contain another packet? */
+ if( uxStreamBufferGetSize( xRecvBuffer ) > sizeof( xHeader ) )
+ {
+ /* Get the next packet. */
+ uxStreamBufferGet( xRecvBuffer, 0, (uint8_t*)&xHeader, sizeof( xHeader ), pdFALSE );
+ uxStreamBufferGet( xRecvBuffer, 0, (uint8_t*)ucRecvBuffer, ( size_t ) xHeader.len, pdFALSE );
+ pucPacketData = ucRecvBuffer;
+ pxHeader = &xHeader;
+
+ iptraceNETWORK_INTERFACE_RECEIVE();
+
+ /* Check for minimal size. */
+ if( pxHeader->len >= sizeof( EthernetHeader_t ) )
+ {
+ eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
+ }
+ else
+ {
+ eResult = eReleaseBuffer;
+ }
+
+ if( eResult == eProcessBuffer )
+ {
+ /* Will the data fit into the frame buffer? */
+ if( pxHeader->len <= ipTOTAL_ETHERNET_FRAME_SIZE )
+ {
+ /* Obtain a buffer into which the data can be placed. This
+ is only an interrupt simulator, not a real interrupt, so it
+ is ok to call the task level function here, but note that
+ some buffer implementations cannot be called from a real
+ interrupt. */
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( pxHeader->len, 0 );
+
+ if( pxNetworkBuffer != NULL )
+ {
+ memcpy( pxNetworkBuffer->pucEthernetBuffer, pucPacketData, pxHeader->len );
+ pxNetworkBuffer->xDataLength = ( size_t ) pxHeader->len;
+
+ #if( niDISRUPT_PACKETS == 1 )
+ {
+ pxNetworkBuffer = vRxFaultInjection( pxNetworkBuffer, pucPacketData );
+ }
+ #endif /* niDISRUPT_PACKETS */
+
+ if( pxNetworkBuffer != NULL )
+ {
+ xRxEvent.pvData = ( void * ) pxNetworkBuffer;
+
+ /* Data was received and stored. Send a message to
+ the IP task to let it know. */
+ if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
+ {
+ /* The buffer could not be sent to the stack so
+ must be released again. This is only an
+ interrupt simulator, not a real interrupt, so it
+ is ok to use the task level function here, but
+ note no all buffer implementations will allow
+ this function to be executed from a real
+ interrupt. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+ }
+ else
+ {
+ /* The packet was already released or stored inside
+ vRxFaultInjection(). Don't release it here. */
+ }
+ }
+ else
+ {
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+ }
+ else
+ {
+ /* Log that a packet was dropped because it would have
+ overflowed the buffer, but there may be more buffers to
+ process. */
+ }
+ }
+ }
+ else
+ {
+ /* There is no real way of simulating an interrupt. Make sure
+ other tasks can run. */
+ vTaskDelay( configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY );
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+static const char *prvRemoveSpaces( char *pcBuffer, int aBuflen, const char *pcMessage )
+{
+ char *pcTarget = pcBuffer;
+
+ /* Utility function used to formap messages being printed only. */
+ while( ( *pcMessage != 0 ) && ( pcTarget < ( pcBuffer + aBuflen - 1 ) ) )
+ {
+ *( pcTarget++ ) = *pcMessage;
+
+ if( isspace( *pcMessage ) != pdFALSE )
+ {
+ while( isspace( *pcMessage ) != pdFALSE )
+ {
+ pcMessage++;
+ }
+ }
+ else
+ {
+ pcMessage++;
+ }
+ }
+
+ *pcTarget = '\0';
+
+ return pcBuffer;
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c
index c8f965395..1c11976cb 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c
@@ -1,398 +1,398 @@
-/*
-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. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-/* Xilinx library files. */
-#include <xemacps.h>
-#include "Zynq/x_topology.h"
-#include "Zynq/x_emacpsif.h"
-#include "Zynq/x_emacpsif_hw.h"
-
-/* Provided memory configured as uncached. */
-#include "uncached_memory.h"
-
-#ifndef BMSR_LINK_STATUS
- #define BMSR_LINK_STATUS 0x0004UL
-#endif
-
-#ifndef PHY_LS_HIGH_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
- receiving packets. */
- #define PHY_LS_HIGH_CHECK_TIME_MS 15000
-#endif
-
-#ifndef PHY_LS_LOW_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still low every second. */
- #define PHY_LS_LOW_CHECK_TIME_MS 1000
-#endif
-
-/* The size of each buffer when BufferAllocation_1 is used:
-http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */
-#define niBUFFER_1_PACKET_SIZE 1536
-
-/* Naming and numbering of PHY registers. */
-#define PHY_REG_01_BMSR 0x01 /* Basic mode status register */
-
-#ifndef iptraceEMAC_TASK_STARTING
- #define iptraceEMAC_TASK_STARTING() do { } while( 0 )
-#endif
-
-/* Default the size of the stack used by the EMAC deferred handler task to twice
-the size of the stack used by the idle task - but allow this to be overridden in
-FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
-#ifndef configEMAC_TASK_STACK_SIZE
- #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
-#endif
-
-/*-----------------------------------------------------------*/
-
-/*
- * Look for the link to be up every few milliseconds until either xMaxTime time
- * has passed or a link is found.
- */
-static BaseType_t prvGMACWaitLS( TickType_t xMaxTime );
-
-/*
- * A deferred interrupt handler for all MAC/DMA interrupt sources.
- */
-static void prvEMACHandlerTask( void *pvParameters );
-
-/*-----------------------------------------------------------*/
-
-/* EMAC data/descriptions. */
-static xemacpsif_s xEMACpsif;
-struct xtopology_t xXTopology =
-{
- .emac_baseaddr = XPAR_PS7_ETHERNET_0_BASEADDR,
- .emac_type = xemac_type_emacps,
- .intc_baseaddr = 0x0,
- .intc_emac_intr = 0x0,
- .scugic_baseaddr = XPAR_PS7_SCUGIC_0_BASEADDR,
- .scugic_emac_intr = 0x36,
-};
-
-XEmacPs_Config mac_config =
-{
- .DeviceId = XPAR_PS7_ETHERNET_0_DEVICE_ID, /**< Unique ID of device */
- .BaseAddress = XPAR_PS7_ETHERNET_0_BASEADDR /**< Physical base address of IPIF registers */
-};
-
-extern int phy_detected;
-
-/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
-static uint32_t ulPHYLinkStatus = 0;
-
-#if( ipconfigUSE_LLMNR == 1 )
- static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
-#endif
-
-/* ucMACAddress as it appears in main.c */
-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;
-
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-uint32_t ulLinkSpeed, ulDMAReg;
-BaseType_t xStatus, xLinkStatus;
-XEmacPs *pxEMAC_PS;
-const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pdMS_TO_TICKS( 1000UL );
-
- /* Guard against the init function being called more than once. */
- if( xEMACTaskHandle == NULL )
- {
- pxEMAC_PS = &( xEMACpsif.emacps );
- memset( &xEMACpsif, '\0', sizeof( xEMACpsif ) );
-
- xStatus = XEmacPs_CfgInitialize( pxEMAC_PS, &mac_config, mac_config.BaseAddress);
- if( xStatus != XST_SUCCESS )
- {
- FreeRTOS_printf( ( "xEMACInit: EmacPs Configuration Failed....\n" ) );
- }
-
- /* Initialize the mac and set the MAC address. */
- XEmacPs_SetMacAddress( pxEMAC_PS, ( void * ) ucMACAddress, 1 );
-
- #if( ipconfigUSE_LLMNR == 1 )
- {
- /* Also add LLMNR multicast MAC address. */
- XEmacPs_SetMacAddress( pxEMAC_PS, ( void * )xLLMNR_MACAddress, 2 );
- }
- #endif /* ipconfigUSE_LLMNR == 1 */
-
- XEmacPs_SetMdioDivisor( pxEMAC_PS, MDC_DIV_224 );
- ulLinkSpeed = Phy_Setup( pxEMAC_PS );
- XEmacPs_SetOperatingSpeed( pxEMAC_PS, ulLinkSpeed);
-
- /* Setting the operating speed of the MAC needs a delay. */
- vTaskDelay( pdMS_TO_TICKS( 25UL ) );
-
- ulDMAReg = XEmacPs_ReadReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET);
-
- /* DISC_WHEN_NO_AHB: when set, the GEM DMA will automatically discard receive
- packets from the receiver packet buffer memory when no AHB resource is available. */
- XEmacPs_WriteReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET,
- ulDMAReg | XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK);
-
- setup_isr( &xEMACpsif );
- init_dma( &xEMACpsif );
- start_emacps( &xEMACpsif );
-
- prvGMACWaitLS( xWaitLinkDelay );
-
- /* The deferred interrupt handler task is created at the highest
- possible priority to ensure the interrupt handler can return directly
- to it. The task's handle is stored in xEMACTaskHandle so interrupts can
- notify the task when there is something to process. */
- xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
- }
- else
- {
- /* Initialisation was already performed, just wait for the link. */
- prvGMACWaitLS( xWaitRelinkDelay );
- }
-
- /* Only return pdTRUE when the Link Status of the PHY is high, otherwise the
- DHCP process and all other communication will fail. */
- xLinkStatus = xGetPhyLinkStatus();
-
- return ( xLinkStatus != pdFALSE );
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )
-{
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- iptraceNETWORK_INTERFACE_TRANSMIT();
- emacps_send_message( &xEMACpsif, pxBuffer, bReleaseAfterSend );
- }
- else if( bReleaseAfterSend != pdFALSE )
- {
- /* No link. */
- vReleaseNetworkBufferAndDescriptor( pxBuffer );
- }
-
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-static inline unsigned long ulReadMDIO( unsigned ulRegister )
-{
-uint16_t usValue;
-
- XEmacPs_PhyRead( &( xEMACpsif.emacps ), phy_detected, ulRegister, &usValue );
- return usValue;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvGMACWaitLS( TickType_t xMaxTime )
-{
-TickType_t xStartTime, xEndTime;
-const TickType_t xShortDelay = pdMS_TO_TICKS( 20UL );
-BaseType_t xReturn;
-
- xStartTime = xTaskGetTickCount();
-
- for( ;; )
- {
- xEndTime = xTaskGetTickCount();
-
- if( xEndTime - xStartTime > xMaxTime )
- {
- xReturn = pdFALSE;
- break;
- }
- ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- xReturn = pdTRUE;
- break;
- }
-
- vTaskDelay( xShortDelay );
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
-static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
-uint8_t *ucRAMBuffer = ucNetworkPackets;
-uint32_t ul;
-
- for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
- {
- pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
- *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
- ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
- }
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xGetPhyLinkStatus( void )
-{
-BaseType_t xReturn;
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
- {
- xReturn = pdFALSE;
- }
- else
- {
- xReturn = pdTRUE;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static void prvEMACHandlerTask( void *pvParameters )
-{
-TimeOut_t xPhyTime;
-TickType_t xPhyRemTime;
-UBaseType_t uxLastMinBufferCount = 0;
-UBaseType_t uxCurrentCount;
-BaseType_t xResult = 0;
-uint32_t xStatus;
-const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
-
- /* A possibility to set some additional task properties like calling
- portTASK_USES_FLOATING_POINT() */
- iptraceEMAC_TASK_STARTING();
-
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
-
- for( ;; )
- {
- 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( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- static UBaseType_t uxLastMinQueueSpace = 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 */
-
- if( ( xEMACpsif.isr_events & EMAC_IF_ALL_EVENT ) == 0 )
- {
- /* No events to process now, wait for the next. */
- ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
- }
-
- if( ( xEMACpsif.isr_events & EMAC_IF_RX_EVENT ) != 0 )
- {
- xEMACpsif.isr_events &= ~EMAC_IF_RX_EVENT;
- xResult = emacps_check_rx( &xEMACpsif );
- }
-
- if( ( xEMACpsif.isr_events & EMAC_IF_TX_EVENT ) != 0 )
- {
- xEMACpsif.isr_events &= ~EMAC_IF_TX_EVENT;
- emacps_check_tx( &xEMACpsif );
- }
-
- if( ( xEMACpsif.isr_events & EMAC_IF_ERR_EVENT ) != 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,
- but set a timer to check it later on. */
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- xResult = 0;
- }
- else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
- {
- xStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
- {
- ulPHYLinkStatus = xStatus;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
- }
-
- vTaskSetTimeOutState( &xPhyTime );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- }
- else
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
- }
- }
- }
-}
-/*-----------------------------------------------------------*/
+/*
+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. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+/* Xilinx library files. */
+#include <xemacps.h>
+#include "Zynq/x_topology.h"
+#include "Zynq/x_emacpsif.h"
+#include "Zynq/x_emacpsif_hw.h"
+
+/* Provided memory configured as uncached. */
+#include "uncached_memory.h"
+
+#ifndef BMSR_LINK_STATUS
+ #define BMSR_LINK_STATUS 0x0004UL
+#endif
+
+#ifndef PHY_LS_HIGH_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
+ receiving packets. */
+ #define PHY_LS_HIGH_CHECK_TIME_MS 15000
+#endif
+
+#ifndef PHY_LS_LOW_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still low every second. */
+ #define PHY_LS_LOW_CHECK_TIME_MS 1000
+#endif
+
+/* The size of each buffer when BufferAllocation_1 is used:
+http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */
+#define niBUFFER_1_PACKET_SIZE 1536
+
+/* Naming and numbering of PHY registers. */
+#define PHY_REG_01_BMSR 0x01 /* Basic mode status register */
+
+#ifndef iptraceEMAC_TASK_STARTING
+ #define iptraceEMAC_TASK_STARTING() do { } while( 0 )
+#endif
+
+/* Default the size of the stack used by the EMAC deferred handler task to twice
+the size of the stack used by the idle task - but allow this to be overridden in
+FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
+#ifndef configEMAC_TASK_STACK_SIZE
+ #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
+#endif
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Look for the link to be up every few milliseconds until either xMaxTime time
+ * has passed or a link is found.
+ */
+static BaseType_t prvGMACWaitLS( TickType_t xMaxTime );
+
+/*
+ * A deferred interrupt handler for all MAC/DMA interrupt sources.
+ */
+static void prvEMACHandlerTask( void *pvParameters );
+
+/*-----------------------------------------------------------*/
+
+/* EMAC data/descriptions. */
+static xemacpsif_s xEMACpsif;
+struct xtopology_t xXTopology =
+{
+ .emac_baseaddr = XPAR_PS7_ETHERNET_0_BASEADDR,
+ .emac_type = xemac_type_emacps,
+ .intc_baseaddr = 0x0,
+ .intc_emac_intr = 0x0,
+ .scugic_baseaddr = XPAR_PS7_SCUGIC_0_BASEADDR,
+ .scugic_emac_intr = 0x36,
+};
+
+XEmacPs_Config mac_config =
+{
+ .DeviceId = XPAR_PS7_ETHERNET_0_DEVICE_ID, /**< Unique ID of device */
+ .BaseAddress = XPAR_PS7_ETHERNET_0_BASEADDR /**< Physical base address of IPIF registers */
+};
+
+extern int phy_detected;
+
+/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
+static uint32_t ulPHYLinkStatus = 0;
+
+#if( ipconfigUSE_LLMNR == 1 )
+ static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
+#endif
+
+/* ucMACAddress as it appears in main.c */
+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;
+
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+uint32_t ulLinkSpeed, ulDMAReg;
+BaseType_t xStatus, xLinkStatus;
+XEmacPs *pxEMAC_PS;
+const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pdMS_TO_TICKS( 1000UL );
+
+ /* Guard against the init function being called more than once. */
+ if( xEMACTaskHandle == NULL )
+ {
+ pxEMAC_PS = &( xEMACpsif.emacps );
+ memset( &xEMACpsif, '\0', sizeof( xEMACpsif ) );
+
+ xStatus = XEmacPs_CfgInitialize( pxEMAC_PS, &mac_config, mac_config.BaseAddress);
+ if( xStatus != XST_SUCCESS )
+ {
+ FreeRTOS_printf( ( "xEMACInit: EmacPs Configuration Failed....\n" ) );
+ }
+
+ /* Initialize the mac and set the MAC address. */
+ XEmacPs_SetMacAddress( pxEMAC_PS, ( void * ) ucMACAddress, 1 );
+
+ #if( ipconfigUSE_LLMNR == 1 )
+ {
+ /* Also add LLMNR multicast MAC address. */
+ XEmacPs_SetMacAddress( pxEMAC_PS, ( void * )xLLMNR_MACAddress, 2 );
+ }
+ #endif /* ipconfigUSE_LLMNR == 1 */
+
+ XEmacPs_SetMdioDivisor( pxEMAC_PS, MDC_DIV_224 );
+ ulLinkSpeed = Phy_Setup( pxEMAC_PS );
+ XEmacPs_SetOperatingSpeed( pxEMAC_PS, ulLinkSpeed);
+
+ /* Setting the operating speed of the MAC needs a delay. */
+ vTaskDelay( pdMS_TO_TICKS( 25UL ) );
+
+ ulDMAReg = XEmacPs_ReadReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET);
+
+ /* DISC_WHEN_NO_AHB: when set, the GEM DMA will automatically discard receive
+ packets from the receiver packet buffer memory when no AHB resource is available. */
+ XEmacPs_WriteReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET,
+ ulDMAReg | XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK);
+
+ setup_isr( &xEMACpsif );
+ init_dma( &xEMACpsif );
+ start_emacps( &xEMACpsif );
+
+ prvGMACWaitLS( xWaitLinkDelay );
+
+ /* The deferred interrupt handler task is created at the highest
+ possible priority to ensure the interrupt handler can return directly
+ to it. The task's handle is stored in xEMACTaskHandle so interrupts can
+ notify the task when there is something to process. */
+ xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
+ }
+ else
+ {
+ /* Initialisation was already performed, just wait for the link. */
+ prvGMACWaitLS( xWaitRelinkDelay );
+ }
+
+ /* Only return pdTRUE when the Link Status of the PHY is high, otherwise the
+ DHCP process and all other communication will fail. */
+ xLinkStatus = xGetPhyLinkStatus();
+
+ return ( xLinkStatus != pdFALSE );
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )
+{
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+ emacps_send_message( &xEMACpsif, pxBuffer, bReleaseAfterSend );
+ }
+ else if( bReleaseAfterSend != pdFALSE )
+ {
+ /* No link. */
+ vReleaseNetworkBufferAndDescriptor( pxBuffer );
+ }
+
+ return pdTRUE;
+}
+/*-----------------------------------------------------------*/
+
+static inline unsigned long ulReadMDIO( unsigned ulRegister )
+{
+uint16_t usValue;
+
+ XEmacPs_PhyRead( &( xEMACpsif.emacps ), phy_detected, ulRegister, &usValue );
+ return usValue;
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvGMACWaitLS( TickType_t xMaxTime )
+{
+TickType_t xStartTime, xEndTime;
+const TickType_t xShortDelay = pdMS_TO_TICKS( 20UL );
+BaseType_t xReturn;
+
+ xStartTime = xTaskGetTickCount();
+
+ for( ;; )
+ {
+ xEndTime = xTaskGetTickCount();
+
+ if( xEndTime - xStartTime > xMaxTime )
+ {
+ xReturn = pdFALSE;
+ break;
+ }
+ ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xReturn = pdTRUE;
+ break;
+ }
+
+ vTaskDelay( xShortDelay );
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
+{
+static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
+uint8_t *ucRAMBuffer = ucNetworkPackets;
+uint32_t ul;
+
+ for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
+ {
+ pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
+ *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
+ ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
+ }
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xGetPhyLinkStatus( void )
+{
+BaseType_t xReturn;
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
+ {
+ xReturn = pdFALSE;
+ }
+ else
+ {
+ xReturn = pdTRUE;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static void prvEMACHandlerTask( void *pvParameters )
+{
+TimeOut_t xPhyTime;
+TickType_t xPhyRemTime;
+UBaseType_t uxLastMinBufferCount = 0;
+UBaseType_t uxCurrentCount;
+BaseType_t xResult = 0;
+uint32_t xStatus;
+const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+
+ /* A possibility to set some additional task properties like calling
+ portTASK_USES_FLOATING_POINT() */
+ iptraceEMAC_TASK_STARTING();
+
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+
+ for( ;; )
+ {
+ 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( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ {
+ static UBaseType_t uxLastMinQueueSpace = 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 */
+
+ if( ( xEMACpsif.isr_events & EMAC_IF_ALL_EVENT ) == 0 )
+ {
+ /* No events to process now, wait for the next. */
+ ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
+ }
+
+ if( ( xEMACpsif.isr_events & EMAC_IF_RX_EVENT ) != 0 )
+ {
+ xEMACpsif.isr_events &= ~EMAC_IF_RX_EVENT;
+ xResult = emacps_check_rx( &xEMACpsif );
+ }
+
+ if( ( xEMACpsif.isr_events & EMAC_IF_TX_EVENT ) != 0 )
+ {
+ xEMACpsif.isr_events &= ~EMAC_IF_TX_EVENT;
+ emacps_check_tx( &xEMACpsif );
+ }
+
+ if( ( xEMACpsif.isr_events & EMAC_IF_ERR_EVENT ) != 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,
+ but set a timer to check it later on. */
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ xResult = 0;
+ }
+ else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
+ {
+ xStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
+ {
+ ulPHYLinkStatus = xStatus;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
+ }
+
+ vTaskSetTimeOutState( &xPhyTime );
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ }
+ else
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h
index 2f1b0df20..823dee0d3 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h
@@ -1,144 +1,144 @@
-/*
- * Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
- *
- * Xilinx, Inc.
- * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
- * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
- * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
- * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
- * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
- * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
- * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
- * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
- * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
- * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-#ifndef __NETIF_XEMACPSIF_H__
-#define __NETIF_XEMACPSIF_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-
-#include "xstatus.h"
-#include "sleep.h"
-#include "xparameters.h"
-#include "xparameters_ps.h" /* defines XPAR values */
-#include "xil_types.h"
-#include "xil_assert.h"
-#include "xil_io.h"
-#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 */
-
-//#include "netif/xpqueue.h"
-//#include "xlwipconfig.h"
-
-void xemacpsif_setmac(uint32_t index, uint8_t *addr);
-uint8_t* xemacpsif_getmac(uint32_t index);
-//int xemacpsif_init(struct netif *netif);
-//int xemacpsif_input(struct netif *netif);
-#ifdef NOTNOW_BHILL
-unsigned get_IEEE_phy_speed(XLlTemac *xlltemacp);
-#endif
-
-/* xaxiemacif_hw.c */
-void xemacps_error_handler(XEmacPs * Temac);
-
-struct xBD_TYPE {
- uint32_t address;
- uint32_t flags;
-};
-
-/*
- * Missing declaration in 'src/xemacps_hw.h' :
- * When set, the GEM DMA will automatically
- * discard receive packets from the receiver packet
- * buffer memory when no AHB resource is
- * available.
- * When low, then received packets will remain to be
- * stored in the SRAM based packet buffer until
- * AHB buffer resource next becomes available.
- */
-#define XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK 0x01000000
-
-#define EMAC_IF_RX_EVENT 1
-#define EMAC_IF_TX_EVENT 2
-#define EMAC_IF_ERR_EVENT 4
-#define EMAC_IF_ALL_EVENT 7
-
-/* structure within each netif, encapsulating all information required for
- * using a particular temac instance
- */
-typedef struct {
- XEmacPs emacps;
-
- /* pointers to memory holding buffer descriptors (used only with SDMA) */
- struct xBD_TYPE *rxSegments;
- struct xBD_TYPE *txSegments;
-
- unsigned char *tx_space;
- unsigned uTxUnitSize;
-
- char *remain_mem;
- unsigned remain_siz;
-
- volatile int rxHead, rxTail;
- volatile int txHead, txTail;
-
- volatile int txBusy;
-
- volatile uint32_t isr_events;
-
- unsigned int last_rx_frms_cntr;
-
-} xemacpsif_s;
-
-//extern xemacpsif_s xemacpsif;
-
-int is_tx_space_available(xemacpsif_s *emac);
-
-/* xaxiemacif_dma.c */
-
-struct xNETWORK_BUFFER;
-
-int emacps_check_rx( xemacpsif_s *xemacpsif );
-void emacps_check_tx( xemacpsif_s *xemacpsif );
-int emacps_check_errors( xemacpsif_s *xemacps );
-void emacps_set_rx_buffers( xemacpsif_s *xemacpsif, u32 ulCount );
-
-extern XStatus emacps_send_message(xemacpsif_s *xemacpsif, struct xNETWORK_BUFFER *pxBuffer, int iReleaseAfterSend );
-extern unsigned Phy_Setup( XEmacPs *xemacpsp );
-extern void setup_isr( xemacpsif_s *xemacpsif );
-extern XStatus init_dma( xemacpsif_s *xemacpsif );
-extern void start_emacps( xemacpsif_s *xemacpsif );
-
-void EmacEnableIntr(void);
-void EmacDisableIntr(void);
-
-XStatus init_axi_dma(xemacpsif_s *xemacpsif);
-void process_sent_bds( xemacpsif_s *xemacpsif );
-
-void emacps_send_handler(void *arg);
-void emacps_recv_handler(void *arg);
-void emacps_error_handler(void *arg,u8 Direction, u32 ErrorWord);
-void HandleTxErrors(xemacpsif_s *xemacpsif);
-XEmacPs_Config *xemacps_lookup_config(unsigned mac_base);
-
-void clean_dma_txdescs(xemacpsif_s *xemacpsif);
-void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __NETIF_XAXIEMACIF_H__ */
+/*
+ * Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
+ *
+ * Xilinx, Inc.
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+ * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+ * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
+ * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
+ * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
+ * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+ * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+ * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
+ * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
+ * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __NETIF_XEMACPSIF_H__
+#define __NETIF_XEMACPSIF_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#include "xstatus.h"
+#include "sleep.h"
+#include "xparameters.h"
+#include "xparameters_ps.h" /* defines XPAR values */
+#include "xil_types.h"
+#include "xil_assert.h"
+#include "xil_io.h"
+#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 */
+
+//#include "netif/xpqueue.h"
+//#include "xlwipconfig.h"
+
+void xemacpsif_setmac(uint32_t index, uint8_t *addr);
+uint8_t* xemacpsif_getmac(uint32_t index);
+//int xemacpsif_init(struct netif *netif);
+//int xemacpsif_input(struct netif *netif);
+#ifdef NOTNOW_BHILL
+unsigned get_IEEE_phy_speed(XLlTemac *xlltemacp);
+#endif
+
+/* xaxiemacif_hw.c */
+void xemacps_error_handler(XEmacPs * Temac);
+
+struct xBD_TYPE {
+ uint32_t address;
+ uint32_t flags;
+};
+
+/*
+ * Missing declaration in 'src/xemacps_hw.h' :
+ * When set, the GEM DMA will automatically
+ * discard receive packets from the receiver packet
+ * buffer memory when no AHB resource is
+ * available.
+ * When low, then received packets will remain to be
+ * stored in the SRAM based packet buffer until
+ * AHB buffer resource next becomes available.
+ */
+#define XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK 0x01000000
+
+#define EMAC_IF_RX_EVENT 1
+#define EMAC_IF_TX_EVENT 2
+#define EMAC_IF_ERR_EVENT 4
+#define EMAC_IF_ALL_EVENT 7
+
+/* structure within each netif, encapsulating all information required for
+ * using a particular temac instance
+ */
+typedef struct {
+ XEmacPs emacps;
+
+ /* pointers to memory holding buffer descriptors (used only with SDMA) */
+ struct xBD_TYPE *rxSegments;
+ struct xBD_TYPE *txSegments;
+
+ unsigned char *tx_space;
+ unsigned uTxUnitSize;
+
+ char *remain_mem;
+ unsigned remain_siz;
+
+ volatile int rxHead, rxTail;
+ volatile int txHead, txTail;
+
+ volatile int txBusy;
+
+ volatile uint32_t isr_events;
+
+ unsigned int last_rx_frms_cntr;
+
+} xemacpsif_s;
+
+//extern xemacpsif_s xemacpsif;
+
+int is_tx_space_available(xemacpsif_s *emac);
+
+/* xaxiemacif_dma.c */
+
+struct xNETWORK_BUFFER;
+
+int emacps_check_rx( xemacpsif_s *xemacpsif );
+void emacps_check_tx( xemacpsif_s *xemacpsif );
+int emacps_check_errors( xemacpsif_s *xemacps );
+void emacps_set_rx_buffers( xemacpsif_s *xemacpsif, u32 ulCount );
+
+extern XStatus emacps_send_message(xemacpsif_s *xemacpsif, struct xNETWORK_BUFFER *pxBuffer, int iReleaseAfterSend );
+extern unsigned Phy_Setup( XEmacPs *xemacpsp );
+extern void setup_isr( xemacpsif_s *xemacpsif );
+extern XStatus init_dma( xemacpsif_s *xemacpsif );
+extern void start_emacps( xemacpsif_s *xemacpsif );
+
+void EmacEnableIntr(void);
+void EmacDisableIntr(void);
+
+XStatus init_axi_dma(xemacpsif_s *xemacpsif);
+void process_sent_bds( xemacpsif_s *xemacpsif );
+
+void emacps_send_handler(void *arg);
+void emacps_recv_handler(void *arg);
+void emacps_error_handler(void *arg,u8 Direction, u32 ErrorWord);
+void HandleTxErrors(xemacpsif_s *xemacpsif);
+XEmacPs_Config *xemacps_lookup_config(unsigned mac_base);
+
+void clean_dma_txdescs(xemacpsif_s *xemacpsif);
+void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __NETIF_XAXIEMACIF_H__ */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
index 13a62852d..fc09d2183 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
@@ -1,626 +1,626 @@
-/*
-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 "Zynq/x_emacpsif.h"
-#include "Zynq/x_topology.h"
-#include "xstatus.h"
-
-#include "xparameters.h"
-#include "xparameters_ps.h"
-#include "xil_exception.h"
-#include "xil_mmu.h"
-
-#include "FreeRTOS.h"
-#include "task.h"
-#include "timers.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-
-#include "uncached_memory.h"
-
-/* Two defines used to set or clear the EMAC interrupt */
-#define INTC_BASE_ADDR XPAR_SCUGIC_CPU_BASEADDR
-#define INTC_DIST_BASE_ADDR XPAR_SCUGIC_DIST_BASEADDR
-
-
-
-#if( ipconfigPACKET_FILLER_SIZE != 2 )
- #error Please define ipconfigPACKET_FILLER_SIZE as the value '2'
-#endif
-#define TX_OFFSET ipconfigPACKET_FILLER_SIZE
-
-#define RX_BUFFER_ALIGNMENT 14
-
-/* Defined in NetworkInterface.c */
-extern TaskHandle_t xEMACTaskHandle;
-
-/*
- pxDMA_tx_buffers: these are character arrays, each one is big enough to hold 1 MTU.
- The actual TX buffers are located in uncached RAM.
-*/
-static unsigned char *pxDMA_tx_buffers[ ipconfigNIC_N_TX_DESC ] = { NULL };
-
-/*
- pxDMA_rx_buffers: these are pointers to 'NetworkBufferDescriptor_t'.
- Once a message has been received by the EMAC, the descriptor can be passed
- immediately to the IP-task.
-*/
-static NetworkBufferDescriptor_t *pxDMA_rx_buffers[ ipconfigNIC_N_RX_DESC ] = { NULL };
-
-/*
- The FreeRTOS+TCP port is using a fixed 'topology', which is declared in
- ./portable/NetworkInterface/Zynq/NetworkInterface.c
-*/
-extern struct xtopology_t xXTopology;
-
-static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
-
-/*
- The FreeRTOS+TCP port does not make use of "src/xemacps_bdring.c".
- In stead 'struct xemacpsif_s' has a "head" and a "tail" index.
- "head" is the next index to be written, used.
- "tail" is the next index to be read, freed.
-*/
-
-int is_tx_space_available( xemacpsif_s *xemacpsif )
-{
-size_t uxCount;
-
- if( xTXDescriptorSemaphore != NULL )
- {
- uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
- }
- else
- {
- uxCount = ( UBaseType_t ) 0u;
- }
-
- return uxCount;
-}
-
-void emacps_check_tx( xemacpsif_s *xemacpsif )
-{
-int tail = xemacpsif->txTail;
-int head = xemacpsif->txHead;
-size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
-
- /* uxCount is the number of TX descriptors that are in use by the DMA. */
- /* When done, "TXBUF_USED" will be set. */
-
- while( ( uxCount > 0 ) && ( ( xemacpsif->txSegments[ tail ].flags & XEMACPS_TXBUF_USED_MASK ) != 0 ) )
- {
- if( ( tail == head ) && ( uxCount != ipconfigNIC_N_TX_DESC ) )
- {
- break;
- }
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
-#warning ipconfigZERO_COPY_TX_DRIVER is defined
- {
- void *pvBuffer = pxDMA_tx_buffers[ tail ];
- NetworkBufferDescriptor_t *pxBuffer;
-
- if( pvBuffer != NULL )
- {
- pxDMA_tx_buffers[ tail ] = NULL;
- pxBuffer = pxPacketBuffer_to_NetworkBuffer( pvBuffer );
- if( pxBuffer != NULL )
- {
- vReleaseNetworkBufferAndDescriptor( pxBuffer );
- }
- else
- {
- FreeRTOS_printf( ( "emacps_check_tx: Can not find network buffer\n" ) );
- }
- }
- }
-#endif
- /* Clear all but the "used" and "wrap" bits. */
- if( tail < ipconfigNIC_N_TX_DESC - 1 )
- {
- xemacpsif->txSegments[ tail ].flags = XEMACPS_TXBUF_USED_MASK;
- }
- else
- {
- xemacpsif->txSegments[ tail ].flags = XEMACPS_TXBUF_USED_MASK | XEMACPS_TXBUF_WRAP_MASK;
- }
- uxCount--;
- /* Tell the counting semaphore that one more TX descriptor is available. */
- xSemaphoreGive( xTXDescriptorSemaphore );
- if( ++tail == ipconfigNIC_N_TX_DESC )
- {
- tail = 0;
- }
- xemacpsif->txTail = tail;
- }
-
- return;
-}
-
-void emacps_send_handler(void *arg)
-{
-xemacpsif_s *xemacpsif;
-BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- xemacpsif = (xemacpsif_s *)(arg);
-
- /* In this port for FreeRTOS+TCP, the EMAC interrupts will only set a bit in
- "isr_events". The task in NetworkInterface will wake-up and do the necessary work.
- */
- xemacpsif->isr_events |= EMAC_IF_TX_EVENT;
- xemacpsif->txBusy = pdFALSE;
-
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
- }
-
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
-}
-
-static BaseType_t xValidLength( BaseType_t xLength )
-{
-BaseType_t xReturn;
-
- if( ( xLength >= ( BaseType_t ) sizeof( struct xARP_PACKET ) ) && ( ( ( uint32_t ) xLength ) <= ipTOTAL_ETHERNET_FRAME_SIZE ) )
- {
- xReturn = pdTRUE;
- }
- else
- {
- xReturn = pdFALSE;
- }
-
- return xReturn;
-}
-
-XStatus emacps_send_message(xemacpsif_s *xemacpsif, NetworkBufferDescriptor_t *pxBuffer, int iReleaseAfterSend )
-{
-int head = xemacpsif->txHead;
-int iHasSent = 0;
-uint32_t ulBaseAddress = xemacpsif->emacps.Config.BaseAddress;
-TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* This driver wants to own all network buffers which are to be transmitted. */
- configASSERT( iReleaseAfterSend != pdFALSE );
- }
- #endif
-
- /* Open a do {} while ( 0 ) loop to be able to call break. */
- do
- {
- uint32_t ulFlags = 0;
-
- if( xValidLength( pxBuffer->xDataLength ) != pdTRUE )
- {
- break;
- }
-
- if( xTXDescriptorSemaphore == NULL )
- {
- break;
- }
-
- if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
- {
- FreeRTOS_printf( ( "emacps_send_message: Time-out waiting for TX buffer\n" ) );
- break;
- }
-
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- /* Pass the pointer (and its ownership) directly to DMA. */
- pxDMA_tx_buffers[ head ] = pxBuffer->pucEthernetBuffer;
- if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
- {
- Xil_DCacheFlushRange( ( unsigned )pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength );
- }
- /* Buffer has been transferred, do not release it. */
- iReleaseAfterSend = pdFALSE;
-#else
- if( pxDMA_tx_buffers[ head ] == NULL )
- {
- FreeRTOS_printf( ( "emacps_send_message: pxDMA_tx_buffers[ %d ] == NULL\n", head ) );
- break;
- }
- /* Copy the message to unbuffered space in RAM. */
- memcpy( pxDMA_tx_buffers[ head ], pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength );
-#endif
- /* Packets will be sent one-by-one, so for each packet
- the TXBUF_LAST bit will be set. */
- ulFlags |= XEMACPS_TXBUF_LAST_MASK;
- ulFlags |= ( pxBuffer->xDataLength & XEMACPS_TXBUF_LEN_MASK );
- if( head == ( ipconfigNIC_N_TX_DESC - 1 ) )
- {
- ulFlags |= XEMACPS_TXBUF_WRAP_MASK;
- }
-
- /* Copy the address of the buffer and set the flags. */
- xemacpsif->txSegments[ head ].address = ( uint32_t )pxDMA_tx_buffers[ head ];
- xemacpsif->txSegments[ head ].flags = ulFlags;
-
- iHasSent = pdTRUE;
- if( ++head == ipconfigNIC_N_TX_DESC )
- {
- head = 0;
- }
- /* Update the TX-head index. These variable are declared volatile so they will be
- accessed as little as possible. */
- xemacpsif->txHead = head;
- } while( pdFALSE );
-
- if( iReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxBuffer );
- pxBuffer = NULL;
- }
-
- /* Data Synchronization Barrier */
- dsb();
-
- if( iHasSent != pdFALSE )
- {
- /* Make STARTTX high */
- uint32_t ulValue = XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET);
- /* Start transmit */
- xemacpsif->txBusy = pdTRUE;
- XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) );
- }
- dsb();
-
- return 0;
-}
-
-void emacps_recv_handler(void *arg)
-{
- xemacpsif_s *xemacpsif;
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- xemacpsif = (xemacpsif_s *)(arg);
- xemacpsif->isr_events |= EMAC_IF_RX_EVENT;
-
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
- }
-
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
-}
-
-static NetworkBufferDescriptor_t *ethMsg = NULL;
-static NetworkBufferDescriptor_t *ethLast = NULL;
-
-static void passEthMessages( void )
-{
-IPStackEvent_t xRxEvent;
-
- xRxEvent.eEventType = eNetworkRxEvent;
- xRxEvent.pvData = ( void * ) ethMsg;
-
- 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
- {
- NetworkBufferDescriptor_t *xNext = ethMsg->pxNextBuffer;
- vReleaseNetworkBufferAndDescriptor( ethMsg );
- ethMsg = xNext;
- } while( ethMsg != NULL );
-
- iptraceETHERNET_RX_EVENT_LOST();
- FreeRTOS_printf( ( "passEthMessages: Can not queue return packet!\n" ) );
- }
-
- ethMsg = ethLast = NULL;
-}
-
-int emacps_check_rx( xemacpsif_s *xemacpsif )
-{
-NetworkBufferDescriptor_t *pxBuffer, *pxNewBuffer;
-int rx_bytes;
-volatile int msgCount = 0;
-int head = xemacpsif->rxHead;
-
- /* There seems to be an issue (SI# 692601), see comments below. */
- resetrx_on_no_rxdata(xemacpsif);
-
- /* 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. */
- for( ;; )
- {
- if( ( ( xemacpsif->rxSegments[ head ].address & XEMACPS_RXBUF_NEW_MASK ) == 0 ) ||
- ( pxDMA_rx_buffers[ head ] == NULL ) )
- {
- break;
- }
-
- pxNewBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
- if( pxNewBuffer == NULL )
- {
- /* A packet has been received, but there is no replacement for this Network Buffer.
- The packet will be dropped, and it Network Buffer will stay in place. */
- FreeRTOS_printf( ("emacps_check_rx: unable to allocate a Netwrok Buffer\n" ) );
- pxNewBuffer = ( NetworkBufferDescriptor_t * )pxDMA_rx_buffers[ head ];
- }
- else
- {
- pxBuffer = ( NetworkBufferDescriptor_t * )pxDMA_rx_buffers[ head ];
-
- /* Just avoiding to use or refer to the same buffer again */
- pxDMA_rx_buffers[ head ] = pxNewBuffer;
-
- /*
- * Adjust the buffer size to the actual number of bytes received.
- */
- rx_bytes = xemacpsif->rxSegments[ head ].flags & XEMACPS_RXBUF_LEN_MASK;
-
- pxBuffer->xDataLength = rx_bytes;
-
- if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
- {
- Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)rx_bytes );
- }
-
- /* store it in the receive queue, where it'll be processed by a
- different handler. */
- iptraceNETWORK_INTERFACE_RECEIVE();
- pxBuffer->pxNextBuffer = NULL;
-
- if( ethMsg == NULL )
- {
- // Becomes the first message
- ethMsg = pxBuffer;
- }
- else if( ethLast != NULL )
- {
- // Add to the tail
- ethLast->pxNextBuffer = pxBuffer;
- }
-
- ethLast = pxBuffer;
- msgCount++;
- }
- {
- if( ucIsCachedMemory( pxNewBuffer->pucEthernetBuffer ) != 0 )
- {
- Xil_DCacheInvalidateRange( ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
- }
- {
- uint32_t addr = ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;
- if( head == ( ipconfigNIC_N_RX_DESC - 1 ) )
- {
- addr |= XEMACPS_RXBUF_WRAP_MASK;
- }
- /* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */
- xemacpsif->rxSegments[ head ].address = addr;
- xemacpsif->rxSegments[ head ].flags = 0;
- }
- }
-
- if( ++head == ipconfigNIC_N_RX_DESC )
- {
- head = 0;
- }
- xemacpsif->rxHead = head;
- }
-
- if( ethMsg != NULL )
- {
- passEthMessages( );
- }
-
- return msgCount;
-}
-
-void clean_dma_txdescs(xemacpsif_s *xemacpsif)
-{
-int index;
-unsigned char *ucTxBuffer;
-
- /* Clear all TX descriptors and assign uncached memory to each descriptor.
- "tx_space" points to the first available TX buffer. */
- ucTxBuffer = xemacpsif->tx_space;
-
- for( index = 0; index < ipconfigNIC_N_TX_DESC; index++ )
- {
- xemacpsif->txSegments[ index ].address = ( uint32_t )ucTxBuffer;
- xemacpsif->txSegments[ index ].flags = XEMACPS_TXBUF_USED_MASK;
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- pxDMA_tx_buffers[ index ] = ( void* )NULL;
-#else
- pxDMA_tx_buffers[ index ] = ( void* )( ucTxBuffer + TX_OFFSET );
-#endif
- ucTxBuffer += xemacpsif->uTxUnitSize;
- }
- xemacpsif->txSegments[ ipconfigNIC_N_TX_DESC - 1 ].flags =
- XEMACPS_TXBUF_USED_MASK | XEMACPS_TXBUF_WRAP_MASK;
-}
-
-XStatus init_dma(xemacpsif_s *xemacpsif)
-{
- NetworkBufferDescriptor_t *pxBuffer;
-
- int iIndex;
- UBaseType_t xRxSize;
- UBaseType_t xTxSize;
- struct xtopology_t *xtopologyp = &xXTopology;
-
- xRxSize = ipconfigNIC_N_RX_DESC * sizeof( xemacpsif->rxSegments[ 0 ] );
-
- xTxSize = ipconfigNIC_N_TX_DESC * sizeof( xemacpsif->txSegments[ 0 ] );
-
- /* Also round-up to 4KB */
- xemacpsif->uTxUnitSize = ( ipTOTAL_ETHERNET_FRAME_SIZE + 0x1000ul ) & ~0xffful;
- /*
- * We allocate 65536 bytes for RX BDs which can accommodate a
- * maximum of 8192 BDs which is much more than any application
- * will ever need.
- */
- xemacpsif->rxSegments = ( struct xBD_TYPE * )( pucGetUncachedMemory ( xRxSize ) );
- xemacpsif->txSegments = ( struct xBD_TYPE * )( pucGetUncachedMemory ( xTxSize ) );
- xemacpsif->tx_space = ( unsigned char * )( pucGetUncachedMemory ( ipconfigNIC_N_TX_DESC * xemacpsif->uTxUnitSize ) );
-
- /* These variables will be used in XEmacPs_Start (see src/xemacps.c). */
- xemacpsif->emacps.RxBdRing.BaseBdAddr = ( uint32_t ) xemacpsif->rxSegments;
- xemacpsif->emacps.TxBdRing.BaseBdAddr = ( uint32_t ) xemacpsif->txSegments;
-
- if( xTXDescriptorSemaphore == NULL )
- {
- xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ipconfigNIC_N_TX_DESC, ( UBaseType_t ) ipconfigNIC_N_TX_DESC );
- configASSERT( xTXDescriptorSemaphore );
- }
- /*
- * Allocate RX descriptors, 1 RxBD at a time.
- */
- for( iIndex = 0; iIndex < ipconfigNIC_N_RX_DESC; iIndex++ )
- {
- pxBuffer = pxDMA_rx_buffers[ iIndex ];
- if( pxBuffer == NULL )
- {
- pxBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
- if( pxBuffer == NULL )
- {
- FreeRTOS_printf( ("Unable to allocate a network buffer in recv_handler\n" ) );
- return -1;
- }
- }
-
- xemacpsif->rxSegments[ iIndex ].flags = 0;
- xemacpsif->rxSegments[ iIndex ].address = ( ( uint32_t )pxBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;
-
- pxDMA_rx_buffers[ iIndex ] = pxBuffer;
- /* Make sure this memory is not in cache for now. */
- if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
- {
- Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE,
- (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
- }
- }
-
- xemacpsif->rxSegments[ ipconfigNIC_N_RX_DESC - 1 ].address |= XEMACPS_RXBUF_WRAP_MASK;
-
- memset( xemacpsif->tx_space, '\0', ipconfigNIC_N_TX_DESC * xemacpsif->uTxUnitSize );
-
- clean_dma_txdescs( xemacpsif );
-
- {
- uint32_t value;
- value = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_DMACR_OFFSET );
-
- // 1xxxx: Attempt to use INCR16 AHB bursts
- value = ( value & ~( XEMACPS_DMACR_BLENGTH_MASK ) ) | XEMACPS_DMACR_INCR16_AHB_BURST;
-#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
- value |= XEMACPS_DMACR_TCPCKSUM_MASK;
-#else
-#warning Are you sure the EMAC should not calculate outgoing checksums?
- value &= ~XEMACPS_DMACR_TCPCKSUM_MASK;
-#endif
- XEmacPs_WriteReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_DMACR_OFFSET, value );
- }
- {
- uint32_t value;
- value = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCFG_OFFSET );
-
- /* Network buffers are 32-bit aligned + 2 bytes (because ipconfigPACKET_FILLER_SIZE = 2 ).
- Now tell the EMAC that received messages should be stored at "address + 2". */
- value = ( value & ~XEMACPS_NWCFG_RXOFFS_MASK ) | 0x8000;
-
-#if( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM != 0 )
- value |= XEMACPS_NWCFG_RXCHKSUMEN_MASK;
-#else
-#warning Are you sure the EMAC should not calculate incoming checksums?
- value &= ~XEMACPS_NWCFG_RXCHKSUMEN_MASK;
-#endif
- XEmacPs_WriteReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCFG_OFFSET, value );
- }
-
- /*
- * Connect the device driver handler that will be called when an
- * interrupt for the device occurs, the handler defined above performs
- * the specific interrupt processing for the device.
- */
- XScuGic_RegisterHandler(INTC_BASE_ADDR, xtopologyp->scugic_emac_intr,
- (Xil_ExceptionHandler)XEmacPs_IntrHandler,
- (void *)&xemacpsif->emacps);
- /*
- * Enable the interrupt for emacps.
- */
- EmacEnableIntr( );
-
- return 0;
-}
-
-/*
- * resetrx_on_no_rxdata():
- *
- * It is called at regular intervals through the API xemacpsif_resetrx_on_no_rxdata
- * called by the user.
- * The EmacPs has a HW bug (SI# 692601) on the Rx path for heavy Rx traffic.
- * Under heavy Rx traffic because of the HW bug there are times when the Rx path
- * becomes unresponsive. The workaround for it is to check for the Rx path for
- * traffic (by reading the stats registers regularly). If the stats register
- * does not increment for sometime (proving no Rx traffic), the function resets
- * the Rx data path.
- *
- */
-
-void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif)
-{
- unsigned long regctrl;
- unsigned long tempcntr;
-
- tempcntr = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXCNT_OFFSET );
- if ( ( tempcntr == 0 ) && ( xemacpsif->last_rx_frms_cntr == 0 ) )
- {
- regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET);
- regctrl &= (~XEMACPS_NWCTRL_RXEN_MASK);
- XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET, regctrl);
- regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET);
- regctrl |= (XEMACPS_NWCTRL_RXEN_MASK);
- XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET, regctrl);
- }
- xemacpsif->last_rx_frms_cntr = tempcntr;
-}
-
-void EmacDisableIntr(void)
-{
- XScuGic_DisableIntr(INTC_DIST_BASE_ADDR, xXTopology.scugic_emac_intr);
-}
-
-void EmacEnableIntr(void)
-{
- XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, xXTopology.scugic_emac_intr);
-}
-
+/*
+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 "Zynq/x_emacpsif.h"
+#include "Zynq/x_topology.h"
+#include "xstatus.h"
+
+#include "xparameters.h"
+#include "xparameters_ps.h"
+#include "xil_exception.h"
+#include "xil_mmu.h"
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "timers.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+
+#include "uncached_memory.h"
+
+/* Two defines used to set or clear the EMAC interrupt */
+#define INTC_BASE_ADDR XPAR_SCUGIC_CPU_BASEADDR
+#define INTC_DIST_BASE_ADDR XPAR_SCUGIC_DIST_BASEADDR
+
+
+
+#if( ipconfigPACKET_FILLER_SIZE != 2 )
+ #error Please define ipconfigPACKET_FILLER_SIZE as the value '2'
+#endif
+#define TX_OFFSET ipconfigPACKET_FILLER_SIZE
+
+#define RX_BUFFER_ALIGNMENT 14
+
+/* Defined in NetworkInterface.c */
+extern TaskHandle_t xEMACTaskHandle;
+
+/*
+ pxDMA_tx_buffers: these are character arrays, each one is big enough to hold 1 MTU.
+ The actual TX buffers are located in uncached RAM.
+*/
+static unsigned char *pxDMA_tx_buffers[ ipconfigNIC_N_TX_DESC ] = { NULL };
+
+/*
+ pxDMA_rx_buffers: these are pointers to 'NetworkBufferDescriptor_t'.
+ Once a message has been received by the EMAC, the descriptor can be passed
+ immediately to the IP-task.
+*/
+static NetworkBufferDescriptor_t *pxDMA_rx_buffers[ ipconfigNIC_N_RX_DESC ] = { NULL };
+
+/*
+ The FreeRTOS+TCP port is using a fixed 'topology', which is declared in
+ ./portable/NetworkInterface/Zynq/NetworkInterface.c
+*/
+extern struct xtopology_t xXTopology;
+
+static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
+
+/*
+ The FreeRTOS+TCP port does not make use of "src/xemacps_bdring.c".
+ In stead 'struct xemacpsif_s' has a "head" and a "tail" index.
+ "head" is the next index to be written, used.
+ "tail" is the next index to be read, freed.
+*/
+
+int is_tx_space_available( xemacpsif_s *xemacpsif )
+{
+size_t uxCount;
+
+ if( xTXDescriptorSemaphore != NULL )
+ {
+ uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
+ }
+ else
+ {
+ uxCount = ( UBaseType_t ) 0u;
+ }
+
+ return uxCount;
+}
+
+void emacps_check_tx( xemacpsif_s *xemacpsif )
+{
+int tail = xemacpsif->txTail;
+int head = xemacpsif->txHead;
+size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
+
+ /* uxCount is the number of TX descriptors that are in use by the DMA. */
+ /* When done, "TXBUF_USED" will be set. */
+
+ while( ( uxCount > 0 ) && ( ( xemacpsif->txSegments[ tail ].flags & XEMACPS_TXBUF_USED_MASK ) != 0 ) )
+ {
+ if( ( tail == head ) && ( uxCount != ipconfigNIC_N_TX_DESC ) )
+ {
+ break;
+ }
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+#warning ipconfigZERO_COPY_TX_DRIVER is defined
+ {
+ void *pvBuffer = pxDMA_tx_buffers[ tail ];
+ NetworkBufferDescriptor_t *pxBuffer;
+
+ if( pvBuffer != NULL )
+ {
+ pxDMA_tx_buffers[ tail ] = NULL;
+ pxBuffer = pxPacketBuffer_to_NetworkBuffer( pvBuffer );
+ if( pxBuffer != NULL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxBuffer );
+ }
+ else
+ {
+ FreeRTOS_printf( ( "emacps_check_tx: Can not find network buffer\n" ) );
+ }
+ }
+ }
+#endif
+ /* Clear all but the "used" and "wrap" bits. */
+ if( tail < ipconfigNIC_N_TX_DESC - 1 )
+ {
+ xemacpsif->txSegments[ tail ].flags = XEMACPS_TXBUF_USED_MASK;
+ }
+ else
+ {
+ xemacpsif->txSegments[ tail ].flags = XEMACPS_TXBUF_USED_MASK | XEMACPS_TXBUF_WRAP_MASK;
+ }
+ uxCount--;
+ /* Tell the counting semaphore that one more TX descriptor is available. */
+ xSemaphoreGive( xTXDescriptorSemaphore );
+ if( ++tail == ipconfigNIC_N_TX_DESC )
+ {
+ tail = 0;
+ }
+ xemacpsif->txTail = tail;
+ }
+
+ return;
+}
+
+void emacps_send_handler(void *arg)
+{
+xemacpsif_s *xemacpsif;
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+
+ xemacpsif = (xemacpsif_s *)(arg);
+
+ /* In this port for FreeRTOS+TCP, the EMAC interrupts will only set a bit in
+ "isr_events". The task in NetworkInterface will wake-up and do the necessary work.
+ */
+ xemacpsif->isr_events |= EMAC_IF_TX_EVENT;
+ xemacpsif->txBusy = pdFALSE;
+
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
+ }
+
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+static BaseType_t xValidLength( BaseType_t xLength )
+{
+BaseType_t xReturn;
+
+ if( ( xLength >= ( BaseType_t ) sizeof( struct xARP_PACKET ) ) && ( ( ( uint32_t ) xLength ) <= ipTOTAL_ETHERNET_FRAME_SIZE ) )
+ {
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+}
+
+XStatus emacps_send_message(xemacpsif_s *xemacpsif, NetworkBufferDescriptor_t *pxBuffer, int iReleaseAfterSend )
+{
+int head = xemacpsif->txHead;
+int iHasSent = 0;
+uint32_t ulBaseAddress = xemacpsif->emacps.Config.BaseAddress;
+TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* This driver wants to own all network buffers which are to be transmitted. */
+ configASSERT( iReleaseAfterSend != pdFALSE );
+ }
+ #endif
+
+ /* Open a do {} while ( 0 ) loop to be able to call break. */
+ do
+ {
+ uint32_t ulFlags = 0;
+
+ if( xValidLength( pxBuffer->xDataLength ) != pdTRUE )
+ {
+ break;
+ }
+
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ break;
+ }
+
+ if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
+ {
+ FreeRTOS_printf( ( "emacps_send_message: Time-out waiting for TX buffer\n" ) );
+ break;
+ }
+
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ /* Pass the pointer (and its ownership) directly to DMA. */
+ pxDMA_tx_buffers[ head ] = pxBuffer->pucEthernetBuffer;
+ if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
+ {
+ Xil_DCacheFlushRange( ( unsigned )pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength );
+ }
+ /* Buffer has been transferred, do not release it. */
+ iReleaseAfterSend = pdFALSE;
+#else
+ if( pxDMA_tx_buffers[ head ] == NULL )
+ {
+ FreeRTOS_printf( ( "emacps_send_message: pxDMA_tx_buffers[ %d ] == NULL\n", head ) );
+ break;
+ }
+ /* Copy the message to unbuffered space in RAM. */
+ memcpy( pxDMA_tx_buffers[ head ], pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength );
+#endif
+ /* Packets will be sent one-by-one, so for each packet
+ the TXBUF_LAST bit will be set. */
+ ulFlags |= XEMACPS_TXBUF_LAST_MASK;
+ ulFlags |= ( pxBuffer->xDataLength & XEMACPS_TXBUF_LEN_MASK );
+ if( head == ( ipconfigNIC_N_TX_DESC - 1 ) )
+ {
+ ulFlags |= XEMACPS_TXBUF_WRAP_MASK;
+ }
+
+ /* Copy the address of the buffer and set the flags. */
+ xemacpsif->txSegments[ head ].address = ( uint32_t )pxDMA_tx_buffers[ head ];
+ xemacpsif->txSegments[ head ].flags = ulFlags;
+
+ iHasSent = pdTRUE;
+ if( ++head == ipconfigNIC_N_TX_DESC )
+ {
+ head = 0;
+ }
+ /* Update the TX-head index. These variable are declared volatile so they will be
+ accessed as little as possible. */
+ xemacpsif->txHead = head;
+ } while( pdFALSE );
+
+ if( iReleaseAfterSend != pdFALSE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxBuffer );
+ pxBuffer = NULL;
+ }
+
+ /* Data Synchronization Barrier */
+ dsb();
+
+ if( iHasSent != pdFALSE )
+ {
+ /* Make STARTTX high */
+ uint32_t ulValue = XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET);
+ /* Start transmit */
+ xemacpsif->txBusy = pdTRUE;
+ XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) );
+ }
+ dsb();
+
+ return 0;
+}
+
+void emacps_recv_handler(void *arg)
+{
+ xemacpsif_s *xemacpsif;
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+
+ xemacpsif = (xemacpsif_s *)(arg);
+ xemacpsif->isr_events |= EMAC_IF_RX_EVENT;
+
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
+ }
+
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+static NetworkBufferDescriptor_t *ethMsg = NULL;
+static NetworkBufferDescriptor_t *ethLast = NULL;
+
+static void passEthMessages( void )
+{
+IPStackEvent_t xRxEvent;
+
+ xRxEvent.eEventType = eNetworkRxEvent;
+ xRxEvent.pvData = ( void * ) ethMsg;
+
+ 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
+ {
+ NetworkBufferDescriptor_t *xNext = ethMsg->pxNextBuffer;
+ vReleaseNetworkBufferAndDescriptor( ethMsg );
+ ethMsg = xNext;
+ } while( ethMsg != NULL );
+
+ iptraceETHERNET_RX_EVENT_LOST();
+ FreeRTOS_printf( ( "passEthMessages: Can not queue return packet!\n" ) );
+ }
+
+ ethMsg = ethLast = NULL;
+}
+
+int emacps_check_rx( xemacpsif_s *xemacpsif )
+{
+NetworkBufferDescriptor_t *pxBuffer, *pxNewBuffer;
+int rx_bytes;
+volatile int msgCount = 0;
+int head = xemacpsif->rxHead;
+
+ /* There seems to be an issue (SI# 692601), see comments below. */
+ resetrx_on_no_rxdata(xemacpsif);
+
+ /* 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. */
+ for( ;; )
+ {
+ if( ( ( xemacpsif->rxSegments[ head ].address & XEMACPS_RXBUF_NEW_MASK ) == 0 ) ||
+ ( pxDMA_rx_buffers[ head ] == NULL ) )
+ {
+ break;
+ }
+
+ pxNewBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
+ if( pxNewBuffer == NULL )
+ {
+ /* A packet has been received, but there is no replacement for this Network Buffer.
+ The packet will be dropped, and it Network Buffer will stay in place. */
+ FreeRTOS_printf( ("emacps_check_rx: unable to allocate a Netwrok Buffer\n" ) );
+ pxNewBuffer = ( NetworkBufferDescriptor_t * )pxDMA_rx_buffers[ head ];
+ }
+ else
+ {
+ pxBuffer = ( NetworkBufferDescriptor_t * )pxDMA_rx_buffers[ head ];
+
+ /* Just avoiding to use or refer to the same buffer again */
+ pxDMA_rx_buffers[ head ] = pxNewBuffer;
+
+ /*
+ * Adjust the buffer size to the actual number of bytes received.
+ */
+ rx_bytes = xemacpsif->rxSegments[ head ].flags & XEMACPS_RXBUF_LEN_MASK;
+
+ pxBuffer->xDataLength = rx_bytes;
+
+ if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
+ {
+ Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)rx_bytes );
+ }
+
+ /* store it in the receive queue, where it'll be processed by a
+ different handler. */
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ pxBuffer->pxNextBuffer = NULL;
+
+ if( ethMsg == NULL )
+ {
+ // Becomes the first message
+ ethMsg = pxBuffer;
+ }
+ else if( ethLast != NULL )
+ {
+ // Add to the tail
+ ethLast->pxNextBuffer = pxBuffer;
+ }
+
+ ethLast = pxBuffer;
+ msgCount++;
+ }
+ {
+ if( ucIsCachedMemory( pxNewBuffer->pucEthernetBuffer ) != 0 )
+ {
+ Xil_DCacheInvalidateRange( ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
+ }
+ {
+ uint32_t addr = ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;
+ if( head == ( ipconfigNIC_N_RX_DESC - 1 ) )
+ {
+ addr |= XEMACPS_RXBUF_WRAP_MASK;
+ }
+ /* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */
+ xemacpsif->rxSegments[ head ].address = addr;
+ xemacpsif->rxSegments[ head ].flags = 0;
+ }
+ }
+
+ if( ++head == ipconfigNIC_N_RX_DESC )
+ {
+ head = 0;
+ }
+ xemacpsif->rxHead = head;
+ }
+
+ if( ethMsg != NULL )
+ {
+ passEthMessages( );
+ }
+
+ return msgCount;
+}
+
+void clean_dma_txdescs(xemacpsif_s *xemacpsif)
+{
+int index;
+unsigned char *ucTxBuffer;
+
+ /* Clear all TX descriptors and assign uncached memory to each descriptor.
+ "tx_space" points to the first available TX buffer. */
+ ucTxBuffer = xemacpsif->tx_space;
+
+ for( index = 0; index < ipconfigNIC_N_TX_DESC; index++ )
+ {
+ xemacpsif->txSegments[ index ].address = ( uint32_t )ucTxBuffer;
+ xemacpsif->txSegments[ index ].flags = XEMACPS_TXBUF_USED_MASK;
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ pxDMA_tx_buffers[ index ] = ( void* )NULL;
+#else
+ pxDMA_tx_buffers[ index ] = ( void* )( ucTxBuffer + TX_OFFSET );
+#endif
+ ucTxBuffer += xemacpsif->uTxUnitSize;
+ }
+ xemacpsif->txSegments[ ipconfigNIC_N_TX_DESC - 1 ].flags =
+ XEMACPS_TXBUF_USED_MASK | XEMACPS_TXBUF_WRAP_MASK;
+}
+
+XStatus init_dma(xemacpsif_s *xemacpsif)
+{
+ NetworkBufferDescriptor_t *pxBuffer;
+
+ int iIndex;
+ UBaseType_t xRxSize;
+ UBaseType_t xTxSize;
+ struct xtopology_t *xtopologyp = &xXTopology;
+
+ xRxSize = ipconfigNIC_N_RX_DESC * sizeof( xemacpsif->rxSegments[ 0 ] );
+
+ xTxSize = ipconfigNIC_N_TX_DESC * sizeof( xemacpsif->txSegments[ 0 ] );
+
+ /* Also round-up to 4KB */
+ xemacpsif->uTxUnitSize = ( ipTOTAL_ETHERNET_FRAME_SIZE + 0x1000ul ) & ~0xffful;
+ /*
+ * We allocate 65536 bytes for RX BDs which can accommodate a
+ * maximum of 8192 BDs which is much more than any application
+ * will ever need.
+ */
+ xemacpsif->rxSegments = ( struct xBD_TYPE * )( pucGetUncachedMemory ( xRxSize ) );
+ xemacpsif->txSegments = ( struct xBD_TYPE * )( pucGetUncachedMemory ( xTxSize ) );
+ xemacpsif->tx_space = ( unsigned char * )( pucGetUncachedMemory ( ipconfigNIC_N_TX_DESC * xemacpsif->uTxUnitSize ) );
+
+ /* These variables will be used in XEmacPs_Start (see src/xemacps.c). */
+ xemacpsif->emacps.RxBdRing.BaseBdAddr = ( uint32_t ) xemacpsif->rxSegments;
+ xemacpsif->emacps.TxBdRing.BaseBdAddr = ( uint32_t ) xemacpsif->txSegments;
+
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ipconfigNIC_N_TX_DESC, ( UBaseType_t ) ipconfigNIC_N_TX_DESC );
+ configASSERT( xTXDescriptorSemaphore );
+ }
+ /*
+ * Allocate RX descriptors, 1 RxBD at a time.
+ */
+ for( iIndex = 0; iIndex < ipconfigNIC_N_RX_DESC; iIndex++ )
+ {
+ pxBuffer = pxDMA_rx_buffers[ iIndex ];
+ if( pxBuffer == NULL )
+ {
+ pxBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
+ if( pxBuffer == NULL )
+ {
+ FreeRTOS_printf( ("Unable to allocate a network buffer in recv_handler\n" ) );
+ return -1;
+ }
+ }
+
+ xemacpsif->rxSegments[ iIndex ].flags = 0;
+ xemacpsif->rxSegments[ iIndex ].address = ( ( uint32_t )pxBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;
+
+ pxDMA_rx_buffers[ iIndex ] = pxBuffer;
+ /* Make sure this memory is not in cache for now. */
+ if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
+ {
+ Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE,
+ (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
+ }
+ }
+
+ xemacpsif->rxSegments[ ipconfigNIC_N_RX_DESC - 1 ].address |= XEMACPS_RXBUF_WRAP_MASK;
+
+ memset( xemacpsif->tx_space, '\0', ipconfigNIC_N_TX_DESC * xemacpsif->uTxUnitSize );
+
+ clean_dma_txdescs( xemacpsif );
+
+ {
+ uint32_t value;
+ value = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_DMACR_OFFSET );
+
+ // 1xxxx: Attempt to use INCR16 AHB bursts
+ value = ( value & ~( XEMACPS_DMACR_BLENGTH_MASK ) ) | XEMACPS_DMACR_INCR16_AHB_BURST;
+#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
+ value |= XEMACPS_DMACR_TCPCKSUM_MASK;
+#else
+#warning Are you sure the EMAC should not calculate outgoing checksums?
+ value &= ~XEMACPS_DMACR_TCPCKSUM_MASK;
+#endif
+ XEmacPs_WriteReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_DMACR_OFFSET, value );
+ }
+ {
+ uint32_t value;
+ value = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCFG_OFFSET );
+
+ /* Network buffers are 32-bit aligned + 2 bytes (because ipconfigPACKET_FILLER_SIZE = 2 ).
+ Now tell the EMAC that received messages should be stored at "address + 2". */
+ value = ( value & ~XEMACPS_NWCFG_RXOFFS_MASK ) | 0x8000;
+
+#if( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM != 0 )
+ value |= XEMACPS_NWCFG_RXCHKSUMEN_MASK;
+#else
+#warning Are you sure the EMAC should not calculate incoming checksums?
+ value &= ~XEMACPS_NWCFG_RXCHKSUMEN_MASK;
+#endif
+ XEmacPs_WriteReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCFG_OFFSET, value );
+ }
+
+ /*
+ * Connect the device driver handler that will be called when an
+ * interrupt for the device occurs, the handler defined above performs
+ * the specific interrupt processing for the device.
+ */
+ XScuGic_RegisterHandler(INTC_BASE_ADDR, xtopologyp->scugic_emac_intr,
+ (Xil_ExceptionHandler)XEmacPs_IntrHandler,
+ (void *)&xemacpsif->emacps);
+ /*
+ * Enable the interrupt for emacps.
+ */
+ EmacEnableIntr( );
+
+ return 0;
+}
+
+/*
+ * resetrx_on_no_rxdata():
+ *
+ * It is called at regular intervals through the API xemacpsif_resetrx_on_no_rxdata
+ * called by the user.
+ * The EmacPs has a HW bug (SI# 692601) on the Rx path for heavy Rx traffic.
+ * Under heavy Rx traffic because of the HW bug there are times when the Rx path
+ * becomes unresponsive. The workaround for it is to check for the Rx path for
+ * traffic (by reading the stats registers regularly). If the stats register
+ * does not increment for sometime (proving no Rx traffic), the function resets
+ * the Rx data path.
+ *
+ */
+
+void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif)
+{
+ unsigned long regctrl;
+ unsigned long tempcntr;
+
+ tempcntr = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXCNT_OFFSET );
+ if ( ( tempcntr == 0 ) && ( xemacpsif->last_rx_frms_cntr == 0 ) )
+ {
+ regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
+ XEMACPS_NWCTRL_OFFSET);
+ regctrl &= (~XEMACPS_NWCTRL_RXEN_MASK);
+ XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
+ XEMACPS_NWCTRL_OFFSET, regctrl);
+ regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET);
+ regctrl |= (XEMACPS_NWCTRL_RXEN_MASK);
+ XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET, regctrl);
+ }
+ xemacpsif->last_rx_frms_cntr = tempcntr;
+}
+
+void EmacDisableIntr(void)
+{
+ XScuGic_DisableIntr(INTC_DIST_BASE_ADDR, xXTopology.scugic_emac_intr);
+}
+
+void EmacEnableIntr(void)
+{
+ XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, xXTopology.scugic_emac_intr);
+}
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
index be00f4f9c..e9443cda8 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
@@ -1,243 +1,243 @@
-/*
- * Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
- *
- * Xilinx, Inc.
- * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
- * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
- * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
- * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
- * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
- * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
- * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
- * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
- * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
- * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "Zynq/x_emacpsif.h"
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-
-///* FreeRTOS+TCP includes. */
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-
-extern TaskHandle_t xEMACTaskHandle;
-
-/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
- *** to run it on a PEEP board
- ***/
-
-unsigned int link_speed = 100;
-
-void setup_isr( xemacpsif_s *xemacpsif )
-{
- /*
- * Setup callbacks
- */
- XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMASEND,
- (void *) emacps_send_handler,
- (void *) xemacpsif);
-
- XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMARECV,
- (void *) emacps_recv_handler,
- (void *) xemacpsif);
-
- XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_ERROR,
- (void *) emacps_error_handler,
- (void *) xemacpsif);
-}
-
-void start_emacps (xemacpsif_s *xemacps)
-{
- /* start the temac */
- XEmacPs_Start(&xemacps->emacps);
-}
-
-extern struct xtopology_t xXTopology;
-
-volatile int error_msg_count = 0;
-volatile const char *last_err_msg = "";
-
-struct xERROR_MSG {
- void *arg;
- u8 Direction;
- u32 ErrorWord;
-};
-
-static struct xERROR_MSG xErrorList[ 8 ];
-static BaseType_t xErrorHead, xErrorTail;
-
-void emacps_error_handler(void *arg, u8 Direction, u32 ErrorWord)
-{
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
- xemacpsif_s *xemacpsif;
- BaseType_t xNextHead = xErrorHead;
-
- xemacpsif = (xemacpsif_s *)(arg);
-
- if( ( Direction != XEMACPS_SEND ) || (ErrorWord != XEMACPS_TXSR_USEDREAD_MASK ) )
- {
- if( ++xNextHead == ( sizeof( xErrorList ) / sizeof( xErrorList[ 0 ] ) ) )
- xNextHead = 0;
- if( xNextHead != xErrorTail )
- {
-
- xErrorList[ xErrorHead ].arg = arg;
- xErrorList[ xErrorHead ].Direction = Direction;
- xErrorList[ xErrorHead ].ErrorWord = ErrorWord;
-
- xErrorHead = xNextHead;
-
- xemacpsif = (xemacpsif_s *)(arg);
- xemacpsif->isr_events |= EMAC_IF_ERR_EVENT;
- }
-
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
- }
-
- }
-
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
-}
-
-static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord);
-
-int emacps_check_errors( xemacpsif_s *xemacps )
-{
-int xResult;
-
- ( void ) xemacps;
-
- if( xErrorHead == xErrorTail )
- {
- xResult = 0;
- }
- else
- {
- xResult = 1;
- emacps_handle_error(
- xErrorList[ xErrorTail ].arg,
- xErrorList[ xErrorTail ].Direction,
- xErrorList[ xErrorTail ].ErrorWord );
- }
-
- return xResult;
-}
-
-BaseType_t xNetworkInterfaceInitialise( void );
-
-static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
-{
- xemacpsif_s *xemacpsif;
- struct xtopology_t *xtopologyp;
- XEmacPs *xemacps;
-
- xemacpsif = (xemacpsif_s *)(arg);
-
- xtopologyp = &xXTopology;
-
- xemacps = &xemacpsif->emacps;
-
- /* Do not appear to be used. */
- ( void ) xemacps;
- ( void ) xtopologyp;
-
- last_err_msg = NULL;
-
- if( ErrorWord != 0 )
- {
- switch (Direction) {
- case XEMACPS_RECV:
- if( ( ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK ) != 0 )
- {
- last_err_msg = "Receive DMA error";
- xNetworkInterfaceInitialise( );
- }
- if( ( ErrorWord & XEMACPS_RXSR_RXOVR_MASK ) != 0 )
- {
- last_err_msg = "Receive over run";
- emacps_recv_handler(arg);
- }
- if( ( ErrorWord & XEMACPS_RXSR_BUFFNA_MASK ) != 0 )
- {
- last_err_msg = "Receive buffer not available";
- emacps_recv_handler(arg);
- }
- break;
- case XEMACPS_SEND:
- if( ( ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK ) != 0 )
- {
- last_err_msg = "Transmit DMA error";
- xNetworkInterfaceInitialise( );
- }
- if( ( ErrorWord & XEMACPS_TXSR_URUN_MASK ) != 0 )
- {
- last_err_msg = "Transmit under run";
- HandleTxErrors( xemacpsif );
- }
- if( ( ErrorWord & XEMACPS_TXSR_BUFEXH_MASK ) != 0 )
- {
- last_err_msg = "Transmit buffer exhausted";
- HandleTxErrors( xemacpsif );
- }
- if( ( ErrorWord & XEMACPS_TXSR_RXOVR_MASK ) != 0 )
- {
- last_err_msg = "Transmit retry excessed limits";
- HandleTxErrors( xemacpsif );
- }
- if( ( ErrorWord & XEMACPS_TXSR_FRAMERX_MASK ) != 0 )
- {
- last_err_msg = "Transmit collision";
- emacps_check_tx( xemacpsif );
- }
- break;
- }
- }
- // Break on this statement and inspect error_msg if you like
- if( last_err_msg != NULL )
- {
- error_msg_count++;
- FreeRTOS_printf( ( "emacps_handle_error: %s\n", last_err_msg ) );
- }
-}
-
-extern XEmacPs_Config mac_config;
-
-void HandleTxErrors(xemacpsif_s *xemacpsif)
-{
- u32 netctrlreg;
-
- //taskENTER_CRITICAL()
- {
- netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET);
- netctrlreg = netctrlreg & (~XEMACPS_NWCTRL_TXEN_MASK);
- XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET, netctrlreg);
-
- clean_dma_txdescs( xemacpsif );
- netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET);
- netctrlreg = netctrlreg | (XEMACPS_NWCTRL_TXEN_MASK);
- XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET, netctrlreg);
- }
- //taskEXIT_CRITICAL( );
-}
+/*
+ * Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
+ *
+ * Xilinx, Inc.
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+ * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+ * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
+ * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
+ * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
+ * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+ * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+ * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
+ * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
+ * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "Zynq/x_emacpsif.h"
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+
+///* FreeRTOS+TCP includes. */
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+
+extern TaskHandle_t xEMACTaskHandle;
+
+/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
+ *** to run it on a PEEP board
+ ***/
+
+unsigned int link_speed = 100;
+
+void setup_isr( xemacpsif_s *xemacpsif )
+{
+ /*
+ * Setup callbacks
+ */
+ XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMASEND,
+ (void *) emacps_send_handler,
+ (void *) xemacpsif);
+
+ XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMARECV,
+ (void *) emacps_recv_handler,
+ (void *) xemacpsif);
+
+ XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_ERROR,
+ (void *) emacps_error_handler,
+ (void *) xemacpsif);
+}
+
+void start_emacps (xemacpsif_s *xemacps)
+{
+ /* start the temac */
+ XEmacPs_Start(&xemacps->emacps);
+}
+
+extern struct xtopology_t xXTopology;
+
+volatile int error_msg_count = 0;
+volatile const char *last_err_msg = "";
+
+struct xERROR_MSG {
+ void *arg;
+ u8 Direction;
+ u32 ErrorWord;
+};
+
+static struct xERROR_MSG xErrorList[ 8 ];
+static BaseType_t xErrorHead, xErrorTail;
+
+void emacps_error_handler(void *arg, u8 Direction, u32 ErrorWord)
+{
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ xemacpsif_s *xemacpsif;
+ BaseType_t xNextHead = xErrorHead;
+
+ xemacpsif = (xemacpsif_s *)(arg);
+
+ if( ( Direction != XEMACPS_SEND ) || (ErrorWord != XEMACPS_TXSR_USEDREAD_MASK ) )
+ {
+ if( ++xNextHead == ( sizeof( xErrorList ) / sizeof( xErrorList[ 0 ] ) ) )
+ xNextHead = 0;
+ if( xNextHead != xErrorTail )
+ {
+
+ xErrorList[ xErrorHead ].arg = arg;
+ xErrorList[ xErrorHead ].Direction = Direction;
+ xErrorList[ xErrorHead ].ErrorWord = ErrorWord;
+
+ xErrorHead = xNextHead;
+
+ xemacpsif = (xemacpsif_s *)(arg);
+ xemacpsif->isr_events |= EMAC_IF_ERR_EVENT;
+ }
+
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
+ }
+
+ }
+
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord);
+
+int emacps_check_errors( xemacpsif_s *xemacps )
+{
+int xResult;
+
+ ( void ) xemacps;
+
+ if( xErrorHead == xErrorTail )
+ {
+ xResult = 0;
+ }
+ else
+ {
+ xResult = 1;
+ emacps_handle_error(
+ xErrorList[ xErrorTail ].arg,
+ xErrorList[ xErrorTail ].Direction,
+ xErrorList[ xErrorTail ].ErrorWord );
+ }
+
+ return xResult;
+}
+
+BaseType_t xNetworkInterfaceInitialise( void );
+
+static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
+{
+ xemacpsif_s *xemacpsif;
+ struct xtopology_t *xtopologyp;
+ XEmacPs *xemacps;
+
+ xemacpsif = (xemacpsif_s *)(arg);
+
+ xtopologyp = &xXTopology;
+
+ xemacps = &xemacpsif->emacps;
+
+ /* Do not appear to be used. */
+ ( void ) xemacps;
+ ( void ) xtopologyp;
+
+ last_err_msg = NULL;
+
+ if( ErrorWord != 0 )
+ {
+ switch (Direction) {
+ case XEMACPS_RECV:
+ if( ( ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK ) != 0 )
+ {
+ last_err_msg = "Receive DMA error";
+ xNetworkInterfaceInitialise( );
+ }
+ if( ( ErrorWord & XEMACPS_RXSR_RXOVR_MASK ) != 0 )
+ {
+ last_err_msg = "Receive over run";
+ emacps_recv_handler(arg);
+ }
+ if( ( ErrorWord & XEMACPS_RXSR_BUFFNA_MASK ) != 0 )
+ {
+ last_err_msg = "Receive buffer not available";
+ emacps_recv_handler(arg);
+ }
+ break;
+ case XEMACPS_SEND:
+ if( ( ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK ) != 0 )
+ {
+ last_err_msg = "Transmit DMA error";
+ xNetworkInterfaceInitialise( );
+ }
+ if( ( ErrorWord & XEMACPS_TXSR_URUN_MASK ) != 0 )
+ {
+ last_err_msg = "Transmit under run";
+ HandleTxErrors( xemacpsif );
+ }
+ if( ( ErrorWord & XEMACPS_TXSR_BUFEXH_MASK ) != 0 )
+ {
+ last_err_msg = "Transmit buffer exhausted";
+ HandleTxErrors( xemacpsif );
+ }
+ if( ( ErrorWord & XEMACPS_TXSR_RXOVR_MASK ) != 0 )
+ {
+ last_err_msg = "Transmit retry excessed limits";
+ HandleTxErrors( xemacpsif );
+ }
+ if( ( ErrorWord & XEMACPS_TXSR_FRAMERX_MASK ) != 0 )
+ {
+ last_err_msg = "Transmit collision";
+ emacps_check_tx( xemacpsif );
+ }
+ break;
+ }
+ }
+ // Break on this statement and inspect error_msg if you like
+ if( last_err_msg != NULL )
+ {
+ error_msg_count++;
+ FreeRTOS_printf( ( "emacps_handle_error: %s\n", last_err_msg ) );
+ }
+}
+
+extern XEmacPs_Config mac_config;
+
+void HandleTxErrors(xemacpsif_s *xemacpsif)
+{
+ u32 netctrlreg;
+
+ //taskENTER_CRITICAL()
+ {
+ netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
+ XEMACPS_NWCTRL_OFFSET);
+ netctrlreg = netctrlreg & (~XEMACPS_NWCTRL_TXEN_MASK);
+ XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
+ XEMACPS_NWCTRL_OFFSET, netctrlreg);
+
+ clean_dma_txdescs( xemacpsif );
+ netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
+ XEMACPS_NWCTRL_OFFSET);
+ netctrlreg = netctrlreg | (XEMACPS_NWCTRL_TXEN_MASK);
+ XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
+ XEMACPS_NWCTRL_OFFSET, netctrlreg);
+ }
+ //taskEXIT_CRITICAL( );
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.h
index 7b0e4fd36..f3c424a4b 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.h
@@ -1,39 +1,39 @@
-/*
- * Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
- *
- * Xilinx, Inc.
- * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
- * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
- * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
- * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
- * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
- * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
- * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
- * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
- * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
- * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-#ifndef __XEMACPSIF_HW_H_
-#define __XEMACPSIF_HW_H_
-
-#include "Zynq/x_emacpsif.h"
-//#include "lwip/netif.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-XEmacPs_Config * lookup_config(unsigned mac_base);
-
-//void init_emacps(xemacpsif_s *xemacpsif, struct netif *netif);
-
-int emacps_check_errors( xemacpsif_s *xemacps );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/*
+ * Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
+ *
+ * Xilinx, Inc.
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+ * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+ * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
+ * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
+ * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
+ * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+ * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+ * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
+ * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
+ * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __XEMACPSIF_HW_H_
+#define __XEMACPSIF_HW_H_
+
+#include "Zynq/x_emacpsif.h"
+//#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+XEmacPs_Config * lookup_config(unsigned mac_base);
+
+//void init_emacps(xemacpsif_s *xemacpsif, struct netif *netif);
+
+int emacps_check_errors( xemacpsif_s *xemacps );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
index 742ff8b96..12b8c60c8 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
@@ -1,585 +1,585 @@
-/*
- * Copyright (c) 2007-2008, Advanced Micro Devices, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Advanced Micro Devices, Inc. nor the names
- * of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Some portions copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
- *
- * Xilinx, Inc.
- * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
- * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
- * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
- * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
- * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
- * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
- * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
- * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
- * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
- * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "Zynq/x_emacpsif.h"
-//#include "lwipopts.h"
-#include "xparameters_ps.h"
-#include "xparameters.h"
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-///* FreeRTOS+TCP includes. */
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-
-int phy_detected = 0;
-
-/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
- *** to run it on a PEEP board
- ***/
-
-/* Advertisement control register. */
-#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
-#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
-#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
-#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
-
-#define ADVERTISE_100_AND_10 (ADVERTISE_10FULL | ADVERTISE_100FULL | \
- ADVERTISE_10HALF | ADVERTISE_100HALF)
-#define ADVERTISE_100 (ADVERTISE_100FULL | ADVERTISE_100HALF)
-#define ADVERTISE_10 (ADVERTISE_10FULL | ADVERTISE_10HALF)
-
-#define ADVERTISE_1000 0x0300
-
-
-//#define PHY_REG_00_BMCR 0x00 // Basic mode control register
-//#define PHY_REG_01_BMSR 0x01 // Basic mode status register
-//#define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1
-//#define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2
-//#define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg
-
-#define IEEE_CONTROL_REG_OFFSET 0
-#define IEEE_STATUS_REG_OFFSET 1
-#define IEEE_AUTONEGO_ADVERTISE_REG 4
-#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5
-#define IEEE_1000_ADVERTISE_REG_OFFSET 9
-#define IEEE_PARTNER_ABILITIES_3_REG_OFFSET 10
-#define IEEE_COPPER_SPECIFIC_CONTROL_REG 16
-#define IEEE_SPECIFIC_STATUS_REG 17
-#define IEEE_COPPER_SPECIFIC_STATUS_REG_2 19
-#define IEEE_CONTROL_REG_MAC 21
-#define IEEE_PAGE_ADDRESS_REGISTER 22
-
-
-#define IEEE_CTRL_1GBPS_LINKSPEED_MASK 0x2040
-#define IEEE_CTRL_LINKSPEED_MASK 0x0040
-#define IEEE_CTRL_LINKSPEED_1000M 0x0040
-#define IEEE_CTRL_LINKSPEED_100M 0x2000
-#define IEEE_CTRL_LINKSPEED_10M 0x0000
-#define IEEE_CTRL_RESET_MASK 0x8000
-#define IEEE_CTRL_AUTONEGOTIATE_ENABLE 0x1000
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#define IEEE_CTRL_RESET 0x9140
-#define IEEE_CTRL_ISOLATE_DISABLE 0xFBFF
-#endif
-#define IEEE_STAT_AUTONEGOTIATE_CAPABLE 0x0008
-#define IEEE_STAT_AUTONEGOTIATE_COMPLETE 0x0020
-#define IEEE_STAT_AUTONEGOTIATE_RESTART 0x0200
-#define IEEE_STAT_1GBPS_EXTENSIONS 0x0100
-#define IEEE_AN1_ABILITY_MASK 0x1FE0
-#define IEEE_AN3_ABILITY_MASK_1GBPS 0x0C00
-#define IEEE_AN1_ABILITY_MASK_100MBPS 0x0380
-#define IEEE_AN1_ABILITY_MASK_10MBPS 0x0060
-#define IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK 0x0030
-
-#define IEEE_ASYMMETRIC_PAUSE_MASK 0x0800
-#define IEEE_PAUSE_MASK 0x0400
-#define IEEE_AUTONEG_ERROR_MASK 0x8000
-
-#define PHY_DETECT_REG 1
-#define PHY_DETECT_MASK 0x1808
-
-#define XEMACPS_GMII2RGMII_SPEED1000_FD 0x140
-#define XEMACPS_GMII2RGMII_SPEED100_FD 0x2100
-#define XEMACPS_GMII2RGMII_SPEED10_FD 0x100
-#define XEMACPS_GMII2RGMII_REG_NUM 0x10
-
-/* Frequency setting */
-#define SLCR_LOCK_ADDR (XPS_SYS_CTRL_BASEADDR + 0x4)
-#define SLCR_UNLOCK_ADDR (XPS_SYS_CTRL_BASEADDR + 0x8)
-#define SLCR_GEM0_CLK_CTRL_ADDR (XPS_SYS_CTRL_BASEADDR + 0x140)
-#define SLCR_GEM1_CLK_CTRL_ADDR (XPS_SYS_CTRL_BASEADDR + 0x144)
-#ifdef PEEP
-#define SLCR_GEM_10M_CLK_CTRL_VALUE 0x00103031
-#define SLCR_GEM_100M_CLK_CTRL_VALUE 0x00103001
-#define SLCR_GEM_1G_CLK_CTRL_VALUE 0x00103011
-#endif
-#define SLCR_LOCK_KEY_VALUE 0x767B
-#define SLCR_UNLOCK_KEY_VALUE 0xDF0D
-#define SLCR_ADDR_GEM_RST_CTRL (XPS_SYS_CTRL_BASEADDR + 0x214)
-#define EMACPS_SLCR_DIV_MASK 0xFC0FC0FF
-
-#define EMAC0_BASE_ADDRESS 0xE000B000
-#define EMAC1_BASE_ADDRESS 0xE000C000
-
-static int detect_phy(XEmacPs *xemacpsp)
-{
- u16 phy_reg;
- u32 phy_addr;
-
- for (phy_addr = 31; phy_addr > 0; phy_addr--) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_DETECT_REG,
- &phy_reg);
-
- if ((phy_reg != 0xFFFF) &&
- ((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
- /* Found a valid PHY address */
- FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected at address %d.\r\n",
- phy_addr));
- FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected.\n" ) );
- phy_detected = phy_addr;
- return phy_addr;
- }
- }
-
- FreeRTOS_printf( ("XEmacPs detect_phy: No PHY detected. Assuming a PHY at address 0\n" ) );
-
- /* default to zero */
- return 0;
-}
-
-#ifdef PEEP
-unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
-{
-
- u16 control;
- u16 status;
- u16 partner_capabilities;
- u16 partner_capabilities_1000;
- u16 phylinkspeed;
- u32 phy_addr = detect_phy(xemacpsp);
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
- ADVERTISE_1000);
- /* Advertise PHY speed of 100 and 10 Mbps */
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
- ADVERTISE_100_AND_10);
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
- &control);
- control |= (IEEE_CTRL_AUTONEGOTIATE_ENABLE |
- IEEE_STAT_AUTONEGOTIATE_RESTART);
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
-
- /* Read PHY control and status registers is successful. */
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
-
- if ((control & IEEE_CTRL_AUTONEGOTIATE_ENABLE) && (status &
- IEEE_STAT_AUTONEGOTIATE_CAPABLE)) {
-
- while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
- &status);
- }
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_1_REG_OFFSET,
- &partner_capabilities);
-
- if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_3_REG_OFFSET,
- &partner_capabilities_1000);
- if (partner_capabilities_1000 & IEEE_AN3_ABILITY_MASK_1GBPS)
- return 1000;
- }
-
- if (partner_capabilities & IEEE_AN1_ABILITY_MASK_100MBPS)
- return 100;
- if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
- return 10;
-
- xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",
- __FUNCTION__);
- return 10;
-
- } else {
-
- /* Update TEMAC speed accordingly */
- if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
- /* Get commanded link speed */
- phylinkspeed = control & IEEE_CTRL_1GBPS_LINKSPEED_MASK;
-
- switch (phylinkspeed) {
- case (IEEE_CTRL_LINKSPEED_1000M):
- return 1000;
- case (IEEE_CTRL_LINKSPEED_100M):
- return 100;
- case (IEEE_CTRL_LINKSPEED_10M):
- return 10;
- default:
- xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",
- __FUNCTION__, phylinkspeed);
- return 10;
- }
-
- } else {
-
- return (control & IEEE_CTRL_LINKSPEED_MASK) ? 100 : 10;
-
- }
- }
-}
-
-#else /* Zynq */
-unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
-{
- u16 temp;
- u16 control;
- u16 status;
- u16 partner_capabilities;
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
- u32 phy_addr = XPAR_PCSPMA_SGMII_PHYADDR;
-#else
- u32 phy_addr = detect_phy(xemacpsp);
-#endif
- xil_printf("Start PHY autonegotiation \r\n");
-
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#else
- XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
- control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
- control |= IEEE_ASYMMETRIC_PAUSE_MASK;
- control |= IEEE_PAUSE_MASK;
- control |= ADVERTISE_100;
- control |= ADVERTISE_10;
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
- &control);
- control |= ADVERTISE_1000;
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
- control);
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
- &control);
- control |= (7 << 12); /* max number of gigabit attempts */
- control |= (1 << 11); /* enable downshift */
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
- control);
-#endif
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
- control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
- control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
- control &= IEEE_CTRL_ISOLATE_DISABLE;
-#endif
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
-
-
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#else
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
- control |= IEEE_CTRL_RESET_MASK;
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
-
- while (1) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
- if (control & IEEE_CTRL_RESET_MASK)
- continue;
- else
- break;
- }
-#endif
- xil_printf("Waiting for PHY to complete autonegotiation.\r\n");
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
- while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
- sleep(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 \r\n");
- }
-#endif
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
- &status);
- }
-
- xil_printf("autonegotiation complete \r\n");
-
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#else
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_SPECIFIC_STATUS_REG, &partner_capabilities);
-#endif
-
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
- xil_printf("Waiting for Link to be up; Polling for SGMII core Reg \r\n");
- XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
- while(!(temp & 0x8000)) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
- }
- if((temp & 0x0C00) == 0x0800) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
- return 1000;
- }
- else if((temp & 0x0C00) == 0x0400) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
- return 100;
- }
- else if((temp & 0x0C00) == 0x0000) {
- 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\r\n");
- XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
- XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
- return 10;
- }
-#else
- if ( ((partner_capabilities >> 14) & 3) == 2)/* 1000Mbps */
- return 1000;
- else if ( ((partner_capabilities >> 14) & 3) == 1)/* 100Mbps */
- return 100;
- else /* 10Mbps */
- return 10;
-#endif
-}
-#endif
-
-unsigned configure_IEEE_phy_speed(XEmacPs *xemacpsp, unsigned speed)
-{
- u16 control;
- u32 phy_addr = detect_phy(xemacpsp);
-
- XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
- control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
- control |= IEEE_ASYMMETRIC_PAUSE_MASK;
- control |= IEEE_PAUSE_MASK;
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
- control &= ~IEEE_CTRL_LINKSPEED_1000M;
- control &= ~IEEE_CTRL_LINKSPEED_100M;
- control &= ~IEEE_CTRL_LINKSPEED_10M;
-
- if (speed == 1000) {
- control |= IEEE_CTRL_LINKSPEED_1000M;
- }
-
- else if (speed == 100) {
- control |= IEEE_CTRL_LINKSPEED_100M;
- /* Dont advertise PHY speed of 1000 Mbps */
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, 0);
- /* Dont advertise PHY speed of 10 Mbps */
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
- ADVERTISE_100);
- }
-
- else if (speed == 10) {
- control |= IEEE_CTRL_LINKSPEED_10M;
- /* Dont advertise PHY speed of 1000 Mbps */
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
- 0);
- /* Dont advertise PHY speed of 100 Mbps */
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
- ADVERTISE_10);
- }
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
- control | IEEE_CTRL_RESET_MASK);
- {
- volatile int wait;
- for (wait=0; wait < 100000; wait++);
- }
- return 0;
-}
-
-static void SetUpSLCRDivisors(int mac_baseaddr, int speed)
-{
- volatile u32 slcrBaseAddress;
-#ifndef PEEP
- u32 SlcrDiv0;
- u32 SlcrDiv1=0;
- u32 SlcrTxClkCntrl;
-#endif
-
- *(volatile unsigned int *)(SLCR_UNLOCK_ADDR) = SLCR_UNLOCK_KEY_VALUE;
-
- if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
- slcrBaseAddress = SLCR_GEM0_CLK_CTRL_ADDR;
- } else {
- slcrBaseAddress = SLCR_GEM1_CLK_CTRL_ADDR;
- }
-#ifdef PEEP
- if (speed == 1000) {
- *(volatile unsigned int *)(slcrBaseAddress) =
- SLCR_GEM_1G_CLK_CTRL_VALUE;
- } else if (speed == 100) {
- *(volatile unsigned int *)(slcrBaseAddress) =
- SLCR_GEM_100M_CLK_CTRL_VALUE;
- } else {
- *(volatile unsigned int *)(slcrBaseAddress) =
- SLCR_GEM_10M_CLK_CTRL_VALUE;
- }
-#else
- if (speed == 1000) {
- if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
-#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0
- SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0;
- SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV1;
-#endif
- } else {
-#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0
- SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0;
- SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV1;
-#endif
- }
- } else if (speed == 100) {
- if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
-#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0
- SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0;
- SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV1;
-#endif
- } else {
-#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0
- SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0;
- SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV1;
-#endif
- }
- } else {
- if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
-#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0
- SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0;
- SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV1;
-#endif
- } else {
-#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0
- SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0;
- SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV1;
-#endif
- }
- }
- SlcrTxClkCntrl = *(volatile unsigned int *)(slcrBaseAddress);
- SlcrTxClkCntrl &= EMACPS_SLCR_DIV_MASK;
- SlcrTxClkCntrl |= (SlcrDiv1 << 20);
- SlcrTxClkCntrl |= (SlcrDiv0 << 8);
- *(volatile unsigned int *)(slcrBaseAddress) = SlcrTxClkCntrl;
-#endif
- *(volatile unsigned int *)(SLCR_LOCK_ADDR) = SLCR_LOCK_KEY_VALUE;
- return;
-}
-
-
-unsigned link_speed;
-unsigned Phy_Setup (XEmacPs *xemacpsp)
-{
- unsigned long conv_present = 0;
- unsigned long convspeeddupsetting = 0;
- unsigned long convphyaddr = 0;
-
-#ifdef XPAR_GMII2RGMIICON_0N_ETH0_ADDR
- convphyaddr = XPAR_GMII2RGMIICON_0N_ETH0_ADDR;
- conv_present = 1;
-#else
-#ifdef XPAR_GMII2RGMIICON_0N_ETH1_ADDR
- convphyaddr = XPAR_GMII2RGMIICON_0N_ETH1_ADDR;
- conv_present = 1;
-#endif
-#endif
-
-#ifdef ipconfigNIC_LINKSPEED_AUTODETECT
- link_speed = get_IEEE_phy_speed(xemacpsp);
- if (link_speed == 1000) {
- SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
- convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
- } else if (link_speed == 100) {
- SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
- convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
- } else {
- SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
- convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
- }
-#elif defined(ipconfigNIC_LINKSPEED1000)
- SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
- link_speed = 1000;
- configure_IEEE_phy_speed(xemacpsp, link_speed);
- convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
- sleep(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);
-#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);
-#endif
- if (conv_present) {
- XEmacPs_PhyWrite(xemacpsp, convphyaddr,
- XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
- }
-
- xil_printf("link speed: %d\r\n", link_speed);
- return link_speed;
-}
-
+/*
+ * Copyright (c) 2007-2008, Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the names
+ * of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Some portions copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
+ *
+ * Xilinx, Inc.
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+ * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+ * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
+ * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
+ * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
+ * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+ * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+ * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
+ * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
+ * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "Zynq/x_emacpsif.h"
+//#include "lwipopts.h"
+#include "xparameters_ps.h"
+#include "xparameters.h"
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+///* FreeRTOS+TCP includes. */
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+
+int phy_detected = 0;
+
+/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
+ *** to run it on a PEEP board
+ ***/
+
+/* Advertisement control register. */
+#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
+#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
+#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
+#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
+
+#define ADVERTISE_100_AND_10 (ADVERTISE_10FULL | ADVERTISE_100FULL | \
+ ADVERTISE_10HALF | ADVERTISE_100HALF)
+#define ADVERTISE_100 (ADVERTISE_100FULL | ADVERTISE_100HALF)
+#define ADVERTISE_10 (ADVERTISE_10FULL | ADVERTISE_10HALF)
+
+#define ADVERTISE_1000 0x0300
+
+
+//#define PHY_REG_00_BMCR 0x00 // Basic mode control register
+//#define PHY_REG_01_BMSR 0x01 // Basic mode status register
+//#define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1
+//#define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2
+//#define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg
+
+#define IEEE_CONTROL_REG_OFFSET 0
+#define IEEE_STATUS_REG_OFFSET 1
+#define IEEE_AUTONEGO_ADVERTISE_REG 4
+#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5
+#define IEEE_1000_ADVERTISE_REG_OFFSET 9
+#define IEEE_PARTNER_ABILITIES_3_REG_OFFSET 10
+#define IEEE_COPPER_SPECIFIC_CONTROL_REG 16
+#define IEEE_SPECIFIC_STATUS_REG 17
+#define IEEE_COPPER_SPECIFIC_STATUS_REG_2 19
+#define IEEE_CONTROL_REG_MAC 21
+#define IEEE_PAGE_ADDRESS_REGISTER 22
+
+
+#define IEEE_CTRL_1GBPS_LINKSPEED_MASK 0x2040
+#define IEEE_CTRL_LINKSPEED_MASK 0x0040
+#define IEEE_CTRL_LINKSPEED_1000M 0x0040
+#define IEEE_CTRL_LINKSPEED_100M 0x2000
+#define IEEE_CTRL_LINKSPEED_10M 0x0000
+#define IEEE_CTRL_RESET_MASK 0x8000
+#define IEEE_CTRL_AUTONEGOTIATE_ENABLE 0x1000
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+#define IEEE_CTRL_RESET 0x9140
+#define IEEE_CTRL_ISOLATE_DISABLE 0xFBFF
+#endif
+#define IEEE_STAT_AUTONEGOTIATE_CAPABLE 0x0008
+#define IEEE_STAT_AUTONEGOTIATE_COMPLETE 0x0020
+#define IEEE_STAT_AUTONEGOTIATE_RESTART 0x0200
+#define IEEE_STAT_1GBPS_EXTENSIONS 0x0100
+#define IEEE_AN1_ABILITY_MASK 0x1FE0
+#define IEEE_AN3_ABILITY_MASK_1GBPS 0x0C00
+#define IEEE_AN1_ABILITY_MASK_100MBPS 0x0380
+#define IEEE_AN1_ABILITY_MASK_10MBPS 0x0060
+#define IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK 0x0030
+
+#define IEEE_ASYMMETRIC_PAUSE_MASK 0x0800
+#define IEEE_PAUSE_MASK 0x0400
+#define IEEE_AUTONEG_ERROR_MASK 0x8000
+
+#define PHY_DETECT_REG 1
+#define PHY_DETECT_MASK 0x1808
+
+#define XEMACPS_GMII2RGMII_SPEED1000_FD 0x140
+#define XEMACPS_GMII2RGMII_SPEED100_FD 0x2100
+#define XEMACPS_GMII2RGMII_SPEED10_FD 0x100
+#define XEMACPS_GMII2RGMII_REG_NUM 0x10
+
+/* Frequency setting */
+#define SLCR_LOCK_ADDR (XPS_SYS_CTRL_BASEADDR + 0x4)
+#define SLCR_UNLOCK_ADDR (XPS_SYS_CTRL_BASEADDR + 0x8)
+#define SLCR_GEM0_CLK_CTRL_ADDR (XPS_SYS_CTRL_BASEADDR + 0x140)
+#define SLCR_GEM1_CLK_CTRL_ADDR (XPS_SYS_CTRL_BASEADDR + 0x144)
+#ifdef PEEP
+#define SLCR_GEM_10M_CLK_CTRL_VALUE 0x00103031
+#define SLCR_GEM_100M_CLK_CTRL_VALUE 0x00103001
+#define SLCR_GEM_1G_CLK_CTRL_VALUE 0x00103011
+#endif
+#define SLCR_LOCK_KEY_VALUE 0x767B
+#define SLCR_UNLOCK_KEY_VALUE 0xDF0D
+#define SLCR_ADDR_GEM_RST_CTRL (XPS_SYS_CTRL_BASEADDR + 0x214)
+#define EMACPS_SLCR_DIV_MASK 0xFC0FC0FF
+
+#define EMAC0_BASE_ADDRESS 0xE000B000
+#define EMAC1_BASE_ADDRESS 0xE000C000
+
+static int detect_phy(XEmacPs *xemacpsp)
+{
+ u16 phy_reg;
+ u32 phy_addr;
+
+ for (phy_addr = 31; phy_addr > 0; phy_addr--) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_DETECT_REG,
+ &phy_reg);
+
+ if ((phy_reg != 0xFFFF) &&
+ ((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
+ /* Found a valid PHY address */
+ FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected at address %d.\r\n",
+ phy_addr));
+ FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected.\n" ) );
+ phy_detected = phy_addr;
+ return phy_addr;
+ }
+ }
+
+ FreeRTOS_printf( ("XEmacPs detect_phy: No PHY detected. Assuming a PHY at address 0\n" ) );
+
+ /* default to zero */
+ return 0;
+}
+
+#ifdef PEEP
+unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
+{
+
+ u16 control;
+ u16 status;
+ u16 partner_capabilities;
+ u16 partner_capabilities_1000;
+ u16 phylinkspeed;
+ u32 phy_addr = detect_phy(xemacpsp);
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
+ ADVERTISE_1000);
+ /* Advertise PHY speed of 100 and 10 Mbps */
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
+ ADVERTISE_100_AND_10);
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
+ &control);
+ control |= (IEEE_CTRL_AUTONEGOTIATE_ENABLE |
+ IEEE_STAT_AUTONEGOTIATE_RESTART);
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
+
+ /* Read PHY control and status registers is successful. */
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
+
+ if ((control & IEEE_CTRL_AUTONEGOTIATE_ENABLE) && (status &
+ IEEE_STAT_AUTONEGOTIATE_CAPABLE)) {
+
+ while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
+ &status);
+ }
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_1_REG_OFFSET,
+ &partner_capabilities);
+
+ if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_3_REG_OFFSET,
+ &partner_capabilities_1000);
+ if (partner_capabilities_1000 & IEEE_AN3_ABILITY_MASK_1GBPS)
+ return 1000;
+ }
+
+ if (partner_capabilities & IEEE_AN1_ABILITY_MASK_100MBPS)
+ return 100;
+ if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
+ return 10;
+
+ xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",
+ __FUNCTION__);
+ return 10;
+
+ } else {
+
+ /* Update TEMAC speed accordingly */
+ if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
+ /* Get commanded link speed */
+ phylinkspeed = control & IEEE_CTRL_1GBPS_LINKSPEED_MASK;
+
+ switch (phylinkspeed) {
+ case (IEEE_CTRL_LINKSPEED_1000M):
+ return 1000;
+ case (IEEE_CTRL_LINKSPEED_100M):
+ return 100;
+ case (IEEE_CTRL_LINKSPEED_10M):
+ return 10;
+ default:
+ xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",
+ __FUNCTION__, phylinkspeed);
+ return 10;
+ }
+
+ } else {
+
+ return (control & IEEE_CTRL_LINKSPEED_MASK) ? 100 : 10;
+
+ }
+ }
+}
+
+#else /* Zynq */
+unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
+{
+ u16 temp;
+ u16 control;
+ u16 status;
+ u16 partner_capabilities;
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+ u32 phy_addr = XPAR_PCSPMA_SGMII_PHYADDR;
+#else
+ u32 phy_addr = detect_phy(xemacpsp);
+#endif
+ xil_printf("Start PHY autonegotiation \r\n");
+
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+#else
+ XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
+ control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
+ control |= IEEE_ASYMMETRIC_PAUSE_MASK;
+ control |= IEEE_PAUSE_MASK;
+ control |= ADVERTISE_100;
+ control |= ADVERTISE_10;
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
+ &control);
+ control |= ADVERTISE_1000;
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
+ control);
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
+ &control);
+ control |= (7 << 12); /* max number of gigabit attempts */
+ control |= (1 << 11); /* enable downshift */
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
+ control);
+#endif
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
+ control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
+ control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+ control &= IEEE_CTRL_ISOLATE_DISABLE;
+#endif
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
+
+
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+#else
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
+ control |= IEEE_CTRL_RESET_MASK;
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
+
+ while (1) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
+ if (control & IEEE_CTRL_RESET_MASK)
+ continue;
+ else
+ break;
+ }
+#endif
+ xil_printf("Waiting for PHY to complete autonegotiation.\r\n");
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
+ while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
+ sleep(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 \r\n");
+ }
+#endif
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
+ &status);
+ }
+
+ xil_printf("autonegotiation complete \r\n");
+
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+#else
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_SPECIFIC_STATUS_REG, &partner_capabilities);
+#endif
+
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+ xil_printf("Waiting for Link to be up; Polling for SGMII core Reg \r\n");
+ XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
+ while(!(temp & 0x8000)) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
+ }
+ if((temp & 0x0C00) == 0x0800) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
+ return 1000;
+ }
+ else if((temp & 0x0C00) == 0x0400) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
+ return 100;
+ }
+ else if((temp & 0x0C00) == 0x0000) {
+ 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\r\n");
+ XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
+ return 10;
+ }
+#else
+ if ( ((partner_capabilities >> 14) & 3) == 2)/* 1000Mbps */
+ return 1000;
+ else if ( ((partner_capabilities >> 14) & 3) == 1)/* 100Mbps */
+ return 100;
+ else /* 10Mbps */
+ return 10;
+#endif
+}
+#endif
+
+unsigned configure_IEEE_phy_speed(XEmacPs *xemacpsp, unsigned speed)
+{
+ u16 control;
+ u32 phy_addr = detect_phy(xemacpsp);
+
+ XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
+ control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
+ control |= IEEE_ASYMMETRIC_PAUSE_MASK;
+ control |= IEEE_PAUSE_MASK;
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
+ control &= ~IEEE_CTRL_LINKSPEED_1000M;
+ control &= ~IEEE_CTRL_LINKSPEED_100M;
+ control &= ~IEEE_CTRL_LINKSPEED_10M;
+
+ if (speed == 1000) {
+ control |= IEEE_CTRL_LINKSPEED_1000M;
+ }
+
+ else if (speed == 100) {
+ control |= IEEE_CTRL_LINKSPEED_100M;
+ /* Dont advertise PHY speed of 1000 Mbps */
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, 0);
+ /* Dont advertise PHY speed of 10 Mbps */
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
+ ADVERTISE_100);
+ }
+
+ else if (speed == 10) {
+ control |= IEEE_CTRL_LINKSPEED_10M;
+ /* Dont advertise PHY speed of 1000 Mbps */
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
+ 0);
+ /* Dont advertise PHY speed of 100 Mbps */
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
+ ADVERTISE_10);
+ }
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
+ control | IEEE_CTRL_RESET_MASK);
+ {
+ volatile int wait;
+ for (wait=0; wait < 100000; wait++);
+ }
+ return 0;
+}
+
+static void SetUpSLCRDivisors(int mac_baseaddr, int speed)
+{
+ volatile u32 slcrBaseAddress;
+#ifndef PEEP
+ u32 SlcrDiv0;
+ u32 SlcrDiv1=0;
+ u32 SlcrTxClkCntrl;
+#endif
+
+ *(volatile unsigned int *)(SLCR_UNLOCK_ADDR) = SLCR_UNLOCK_KEY_VALUE;
+
+ if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
+ slcrBaseAddress = SLCR_GEM0_CLK_CTRL_ADDR;
+ } else {
+ slcrBaseAddress = SLCR_GEM1_CLK_CTRL_ADDR;
+ }
+#ifdef PEEP
+ if (speed == 1000) {
+ *(volatile unsigned int *)(slcrBaseAddress) =
+ SLCR_GEM_1G_CLK_CTRL_VALUE;
+ } else if (speed == 100) {
+ *(volatile unsigned int *)(slcrBaseAddress) =
+ SLCR_GEM_100M_CLK_CTRL_VALUE;
+ } else {
+ *(volatile unsigned int *)(slcrBaseAddress) =
+ SLCR_GEM_10M_CLK_CTRL_VALUE;
+ }
+#else
+ if (speed == 1000) {
+ if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
+#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0
+ SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0;
+ SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV1;
+#endif
+ } else {
+#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0
+ SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0;
+ SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV1;
+#endif
+ }
+ } else if (speed == 100) {
+ if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
+#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0
+ SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0;
+ SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV1;
+#endif
+ } else {
+#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0
+ SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0;
+ SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV1;
+#endif
+ }
+ } else {
+ if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
+#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0
+ SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0;
+ SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV1;
+#endif
+ } else {
+#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0
+ SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0;
+ SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV1;
+#endif
+ }
+ }
+ SlcrTxClkCntrl = *(volatile unsigned int *)(slcrBaseAddress);
+ SlcrTxClkCntrl &= EMACPS_SLCR_DIV_MASK;
+ SlcrTxClkCntrl |= (SlcrDiv1 << 20);
+ SlcrTxClkCntrl |= (SlcrDiv0 << 8);
+ *(volatile unsigned int *)(slcrBaseAddress) = SlcrTxClkCntrl;
+#endif
+ *(volatile unsigned int *)(SLCR_LOCK_ADDR) = SLCR_LOCK_KEY_VALUE;
+ return;
+}
+
+
+unsigned link_speed;
+unsigned Phy_Setup (XEmacPs *xemacpsp)
+{
+ unsigned long conv_present = 0;
+ unsigned long convspeeddupsetting = 0;
+ unsigned long convphyaddr = 0;
+
+#ifdef XPAR_GMII2RGMIICON_0N_ETH0_ADDR
+ convphyaddr = XPAR_GMII2RGMIICON_0N_ETH0_ADDR;
+ conv_present = 1;
+#else
+#ifdef XPAR_GMII2RGMIICON_0N_ETH1_ADDR
+ convphyaddr = XPAR_GMII2RGMIICON_0N_ETH1_ADDR;
+ conv_present = 1;
+#endif
+#endif
+
+#ifdef ipconfigNIC_LINKSPEED_AUTODETECT
+ link_speed = get_IEEE_phy_speed(xemacpsp);
+ if (link_speed == 1000) {
+ SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
+ convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
+ } else if (link_speed == 100) {
+ SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
+ convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
+ } else {
+ SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
+ convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
+ }
+#elif defined(ipconfigNIC_LINKSPEED1000)
+ SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
+ link_speed = 1000;
+ configure_IEEE_phy_speed(xemacpsp, link_speed);
+ convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
+ sleep(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);
+#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);
+#endif
+ if (conv_present) {
+ XEmacPs_PhyWrite(xemacpsp, convphyaddr,
+ XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
+ }
+
+ xil_printf("link speed: %d\r\n", link_speed);
+ return link_speed;
+}
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_topology.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_topology.h
index 1d8fede15..bb5178346 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_topology.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_topology.h
@@ -1,46 +1,46 @@
-/*
- * Copyright (c) 2007-2013 Xilinx, Inc. All rights reserved.
- *
- * Xilinx, Inc.
- * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
- * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
- * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
- * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
- * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
- * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
- * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
- * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
- * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
- * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-#ifndef __XTOPOLOGY_H_
-#define __XTOPOLOGY_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum xemac_types { xemac_type_unknown = -1, xemac_type_xps_emaclite, xemac_type_xps_ll_temac, xemac_type_axi_ethernet, xemac_type_emacps };
-
-struct xtopology_t {
- unsigned emac_baseaddr;
- enum xemac_types emac_type;
- unsigned intc_baseaddr;
- unsigned intc_emac_intr; /* valid only for xemac_type_xps_emaclite */
- unsigned scugic_baseaddr; /* valid only for Zynq */
- unsigned scugic_emac_intr; /* valid only for GEM */
-};
-
-extern int x_topology_n_emacs;
-extern struct xtopology_t x_topology[];
-
-int x_topology_find_index(unsigned base);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/*
+ * Copyright (c) 2007-2013 Xilinx, Inc. All rights reserved.
+ *
+ * Xilinx, Inc.
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+ * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+ * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
+ * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
+ * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
+ * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+ * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+ * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
+ * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
+ * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __XTOPOLOGY_H_
+#define __XTOPOLOGY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum xemac_types { xemac_type_unknown = -1, xemac_type_xps_emaclite, xemac_type_xps_ll_temac, xemac_type_axi_ethernet, xemac_type_emacps };
+
+struct xtopology_t {
+ unsigned emac_baseaddr;
+ enum xemac_types emac_type;
+ unsigned intc_baseaddr;
+ unsigned intc_emac_intr; /* valid only for xemac_type_xps_emaclite */
+ unsigned scugic_baseaddr; /* valid only for Zynq */
+ unsigned scugic_emac_intr; /* valid only for GEM */
+};
+
+extern int x_topology_n_emacs;
+extern struct xtopology_t x_topology[];
+
+int x_topology_find_index(unsigned base);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/board_family/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/board_family/NetworkInterface.c
index 4692c12c4..aa0a646b4 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/board_family/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/board_family/NetworkInterface.c
@@ -1,63 +1,63 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2018 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 includes. */
-#include "FreeRTOS.h"
-#include "list.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-
-/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
-driver will filter incoming packets and only pass the stack those packets it
-considers need processing. */
-#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
-#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
-#else
-#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
-#endif
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
- /* FIX ME. */
- return pdFALSE;
-}
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
-{
- /* FIX ME. */
- return pdFALSE;
-}
-
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
- /* FIX ME. */
-}
-
-BaseType_t xGetPhyLinkStatus( void )
-{
- /* FIX ME. */
- return pdFALSE;
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2018 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 includes. */
+#include "FreeRTOS.h"
+#include "list.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+
+/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
+driver will filter incoming packets and only pass the stack those packets it
+considers need processing. */
+#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
+#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+#else
+#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+#endif
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+ /* FIX ME. */
+ return pdFALSE;
+}
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
+{
+ /* FIX ME. */
+ return pdFALSE;
+}
+
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
+{
+ /* FIX ME. */
+}
+
+BaseType_t xGetPhyLinkStatus( void )
+{
+ /* FIX ME. */
+ return pdFALSE;
} \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c
index e4ae1168f..544e5ba09 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c
@@ -1,1272 +1,1272 @@
-/*
-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. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-#include "sam4e_xplained_pro.h"
-#include "hr_gettime.h"
-#include "conf_eth.h"
-#include "ksz8851snl.h"
-#include "ksz8851snl_reg.h"
-
-/* Some files from the Atmel Software Framework */
-#include <sysclk.h>
-#include <pdc/pdc.h>
-#include <spi/spi.h>
-
-/*
- Sending a packet:
-
- 1) Called by UP-task, add buffer to the TX-list:
- xNetworkInterfaceOutput()
- tx_buffers[ us_tx_head ] = pxNetworkBuffer;
- tx_busy[ us_tx_head ] = pdTRUE;
- us_tx_head++;
-
- 2) Called by EMAC-Task: start SPI transfer
- ksz8851snl_update()
- if( ul_spi_pdc_status == SPI_PDC_IDLE )
- {
- if( ( tx_busy[ us_tx_tail ] != pdFALSE ) &&
- ( us_pending_frame == 0 ) &&
- ( ul_had_intn_interrupt == 0 ) )
- {
- // disable all interrupts.
- ksz8851_reg_write( REG_INT_MASK, 0 );
- Bring KSZ8851SNL_CSN_GPIO low
- ksz8851_fifo_write( pxNetworkBuffer->pucEthernetBuffer, xLength, xLength );
- ul_spi_pdc_status = SPI_PDC_TX_START;
- tx_cur_buffer = pxNetworkBuffer;
- }
- }
- 3) Wait for SPI RXBUFF interrupt
- SPI_Handler()
- if( ul_spi_pdc_status == SPI_PDC_TX_START )
- {
- if( SPI_Status & SPI_SR_RXBUFF )
- {
- ul_spi_pdc_status = SPI_PDC_TX_COMPLETE;
- }
- }
-
- 4) Called by EMAC-Task: finish SPI transfer
- ksz8851snl_update()
- if( ul_spi_pdc_status == SPI_PDC_TX_COMPLETE )
- {
- ul_spi_pdc_status = SPI_PDC_IDLE;
- Bring KSZ8851SNL_CSN_GPIO high
- // TX step12: disable TXQ write access.
- ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
- // TX step12.1: enqueue frame in TXQ.
- ksz8851_reg_setbits( REG_TXQ_CMD, TXQ_ENQUEUE );
-
- // RX step13: enable INT_RX flag.
- ksz8851_reg_write( REG_INT_MASK, INT_RX );
-
- // Buffer sent, free the corresponding buffer and mark descriptor as owned by software.
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
-
- tx_buffers[ us_tx_tail ] = NULL;
- tx_busy[ us_tx_tail ] = pdFALSE;
- us_tx_tail++
- }
-
- Receiving a packet:
-
- 1) Wait for a INTN interrupt
- INTN_Handler()
- ul_had_intn_interrupt = 1
- vTaskNotifyGiveFromISR(); // Wake up the EMAC task
-
- 2) Called by EMAC-Task: check for new fragments and start SPI transfer
- ksz8851snl_update()
- if( ul_spi_pdc_status == SPI_PDC_IDLE )
- {
- if( ( ul_had_intn_interrupt != 0 ) || ( us_pending_frame > 0 ) )
- {
- if( us_pending_frame == 0 )
- {
- us_pending_frame = ksz8851_reg_read(REG_RX_FRAME_CNT_THRES) >> 8;
- if( us_pending_frame == 0 )
- {
- break;
- }
- }
- // RX step2: disable all interrupts.
- ksz8851_reg_write( REG_INT_MASK, 0 );
- Check if there is a valid packet: REG_RX_FHR_STATUS
- Read the length of the next fragment: REG_RX_FHR_BYTE_CNT
- ul_spi_pdc_status = SPI_PDC_RX_START;
- gpio_set_pin_low(KSZ8851SNL_CSN_GPIO);
- // Start SPI data transfer
- ksz8851_fifo_read( pxNetworkBuffer->pucEthernetBuffer, xReadLength );
- }
- }
-
- 3) Wait for SPI RXBUFF interrupt
- SPI_Handler()
- if( ul_spi_pdc_status == SPI_PDC_RX_START:
- {
- if( ( ulCurrentSPIStatus & SPI_SR_RXBUFF ) != 0 )
- {
- // Transfer complete, disable SPI RXBUFF interrupt.
- spi_disable_interrupt( KSZ8851SNL_SPI, SPI_IDR_RXBUFF );
-
- ul_spi_pdc_status = SPI_PDC_RX_COMPLETE;
- }
- }
- }
-
- 4) Finish SPI transfer
- ksz8851snl_update()
- if( ul_spi_pdc_status == SPI_PDC_RX_COMPLETE )
- {
- ul_spi_pdc_status = SPI_PDC_IDLE;
- Bring KSZ8851SNL_CSN_GPIO high
- // RX step21: end RXQ read access.
- ksz8851_reg_clrbits(REG_RXQ_CMD, RXQ_START);
- // RX step22-23: update frame count to be read.
- us_pending_frame--
- // RX step24: enable INT_RX flag if transfer complete.
- if( us_pending_frame == 0 )
- {
- // Allow more RX interrupts.
- ksz8851_reg_write( REG_INT_MASK, INT_RX );
- }
-
- // Mark descriptor ready to be read.
- rx_ready[ rxHead ] = pdTRUE;
- rxHead++
- }
-*/
-
-#define PHY_REG_00_BMCR 0x00 // Basic mode control register
-#define PHY_REG_01_BMSR 0x01 // Basic mode status register
-#define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1
-#define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2
-#define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg
-#define PHY_REG_05_LPA 0x05 // Link partner ability reg
-#define PHY_REG_06_ANER 0x06 // 6 RW Auto-Negotiation Expansion Register
-#define PHY_REG_07_ANNPTR 0x07 // 7 RW Auto-Negotiation Next Page TX
-#define PHY_REG_08_RESERVED0 0x08 // 0x08..0x0Fh 8-15 RW RESERVED
-
-#define BMSR_LINK_STATUS 0x0004 //!< Link status
-
-#ifndef PHY_LS_HIGH_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
- receiving packets. */
- #define PHY_LS_HIGH_CHECK_TIME_MS 15000
-#endif
-
-#ifndef PHY_LS_LOW_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still low every second. */
- #define PHY_LS_LOW_CHECK_TIME_MS 1000
-#endif
-
-/* Interrupt events to process. Currently only the Rx event is processed
-although code for other events is included to allow for possible future
-expansion. */
-#define EMAC_IF_RX_EVENT 1UL
-#define EMAC_IF_TX_EVENT 2UL
-#define EMAC_IF_ERR_EVENT 4UL
-#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
-
-#define ETHERNET_CONF_PHY_ADDR BOARD_GMAC_PHY_ADDR
-
-#ifdef ipconfigHAS_TX_CRC_OFFLOADING
- #undef ipconfigHAS_TX_CRC_OFFLOADING
-#endif
-/* Override this define because the KSZ8851 is programmed to set all outgoing CRC's */
-#define ipconfigHAS_TX_CRC_OFFLOADING 1
-
-#ifndef EMAC_MAX_BLOCK_TIME_MS
- #define EMAC_MAX_BLOCK_TIME_MS 100ul
-#endif
-
-/* Default the size of the stack used by the EMAC deferred handler task to 4x
-the size of the stack used by the idle task - but allow this to be overridden in
-FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
-#ifndef configEMAC_TASK_STACK_SIZE
- #define configEMAC_TASK_STACK_SIZE ( 6 * configMINIMAL_STACK_SIZE )
-#endif
-
-#define SPI_PDC_IDLE 0
-#define SPI_PDC_RX_START 1
-#define SPI_PDC_TX_ERROR 2
-#define SPI_PDC_RX_COMPLETE 3
-#define SPI_PDC_TX_START 4
-#define SPI_PDC_RX_ERROR 5
-#define SPI_PDC_TX_COMPLETE 6
-
-/**
- * ksz8851snl driver structure.
- */
-typedef struct {
- /** Set to 1 when owner is software (ready to read), 0 for Micrel. */
- uint32_t rx_ready[MICREL_RX_BUFFERS];
- /** Set to 1 when owner is Micrel, 0 for software. */
- uint32_t tx_busy[MICREL_TX_BUFFERS];
- /** RX NetworkBufferDescriptor_t pointer list */
- NetworkBufferDescriptor_t *rx_buffers[MICREL_RX_BUFFERS];
- /** TX NetworkBufferDescriptor_t pointer list */
- NetworkBufferDescriptor_t *tx_buffers[MICREL_TX_BUFFERS];
- NetworkBufferDescriptor_t *tx_cur_buffer;
-
- /** Circular buffer head pointer for packet received. */
- uint32_t us_rx_head;
- /** Circular buffer tail pointer for packet to be read. */
- uint32_t us_rx_tail;
- /** Circular buffer head pointer by upper layer (buffer to be sent). */
- uint32_t us_tx_head;
- /** Circular buffer tail pointer incremented by handlers (buffer sent). */
- uint32_t us_tx_tail;
-
- uint32_t ul_total_tx;
- uint32_t ul_total_rx;
- uint32_t tx_space;
-
- /** Still experimental: hash table to allow certain multicast addresses. */
- uint16_t pusHashTable[ 4 ];
-
- /* ul_spi_pdc_status has "SPI_PDC_xxx" values. */
- volatile uint32_t ul_spi_pdc_status;
-
- /* ul_had_intn_interrupt becomes true within the INTN interrupt. */
- volatile uint32_t ul_had_intn_interrupt;
-
- uint16_t us_pending_frame;
-} xKSZ8851_Device_t;
-
-/* SPI PDC register base.
-Declared in ASF\sam\components\ksz8851snl\ksz8851snl.c */
-extern Pdc *g_p_spi_pdc;
-
-/* Temporary buffer for PDC reception.
-declared in ASF\sam\components\ksz8851snl\ksz8851snl.c */
-extern uint8_t tmpbuf[1536];
-
-COMPILER_ALIGNED(8)
-static xKSZ8851_Device_t xMicrelDevice;
-
-static TaskHandle_t xTransmitHandle;
-
-/*-----------------------------------------------------------*/
-
-/*
- * Wait a fixed time for the link status to indicate the network is up.
- */
-static BaseType_t xGMACWaitLS( TickType_t xMaxTime );
-
-/*
- * A deferred interrupt handler task that processes GMAC interrupts.
- */
-static void prvEMACHandlerTask( void *pvParameters );
-
-/*
- * Try to obtain an Rx packet from the hardware.
- */
-static uint32_t prvEMACRxPoll( void );
-
-static inline unsigned long ulReadMDIO( unsigned uAddress );
-
-static void ksz8851snl_low_level_init( void );
-
-static NetworkBufferDescriptor_t *ksz8851snl_low_level_input( void );
-
-/*-----------------------------------------------------------*/
-
-/* Bit map of outstanding ETH interrupt events for processing. Currently only
-the Rx interrupt is handled, although code is included for other events to
-enable future expansion. */
-static volatile uint32_t ulISREvents;
-
-/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
-static uint32_t ulPHYLinkStatus = 0;
-static volatile BaseType_t xGMACSwitchRequired;
-
-static void ksz8851snl_update( void );
-
-static void ksz8851snl_rx_init( void );
-
-static void ksz8851snl_tx_init( void );
-
-/* 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;
-
-
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-const TickType_t x5_Seconds = 5000UL;
-
- if( xEMACTaskHandle == NULL )
- {
- ksz8851snl_low_level_init();
-
- /* Wait at most 5 seconds for a Link Status in the PHY. */
- xGMACWaitLS( pdMS_TO_TICKS( x5_Seconds ) );
-
- /* The handler task is created at the highest possible priority to
- ensure the interrupt handler can return directly to it. */
- xTaskCreate( prvEMACHandlerTask, "KSZ8851", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
- configASSERT( xEMACTaskHandle );
- }
-
- /* When returning non-zero, the stack will become active and
- start DHCP (in configured) */
- ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xGetPhyLinkStatus( void )
-{
-BaseType_t xResult;
-
- /* This function returns true if the Link Status in the PHY is high. */
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- xResult = pdTRUE;
- }
- else
- {
- xResult = pdFALSE;
- }
-
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t bReleaseAfterSend )
-{
-BaseType_t xResult = pdFALSE;
-int txHead = xMicrelDevice.us_tx_head;
-
- /* Make sure the next descriptor is free. */
- if( xMicrelDevice.tx_busy[ txHead ] != pdFALSE )
- {
- /* All TX buffers busy. */
- }
- else if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
- {
- /* Output: LS low. */
- }
- else
- {
- /* Pass the packet. */
- xMicrelDevice.tx_buffers[ txHead ] = pxNetworkBuffer;
- /* The descriptor is now owned by Micrel. */
- xMicrelDevice.tx_busy[ txHead ] = pdTRUE;
-
- /* Move the head pointer. */
- if( ++txHead == MICREL_TX_BUFFERS )
- {
- txHead = 0;
- }
- xMicrelDevice.us_tx_head = txHead;
- if( xEMACTaskHandle != NULL )
- {
- xTaskNotifyGive( xEMACTaskHandle );
- }
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 1 )
- #warning Please ipconfigZERO_COPY_TX_DRIVER as 1
- #endif
- configASSERT( bReleaseAfterSend != pdFALSE );
- xResult = pdTRUE;
- }
- if( ( xResult == pdFALSE ) && ( bReleaseAfterSend != pdFALSE ) )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- }
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-/* This Micrel has numbered it's PHY registers in a different way.
-Translate the register index. */
-static int ks8851_phy_reg( int reg )
-{
- switch (reg) {
- case PHY_REG_00_BMCR:
- return REG_PHY_CNTL; // P1MBCR;
- case PHY_REG_01_BMSR:
- return REG_PHY_STATUS;
- case PHY_REG_02_PHYSID1:
- return REG_PHY_ID_LOW;
- case PHY_REG_03_PHYSID2:
- return REG_PHY_ID_HIGH;
- case PHY_REG_04_ADVERTISE:
- return REG_PHY_AUTO_NEGOTIATION;
- case PHY_REG_05_LPA:
- return REG_PHY_REMOTE_CAPABILITY;
- }
-
- return 0x0;
-}
-/*-----------------------------------------------------------*/
-
-static inline unsigned long ulReadMDIO( unsigned uAddress )
-{
-uint16_t usPHYStatus;
-int ks8851_reg = ks8851_phy_reg( uAddress );
-
- if( ks8851_reg != 0 )
- {
- usPHYStatus = ksz8851_reg_read( ks8851_reg );
- }
- else
- {
- /* Other addresses not yet implemented. */
- usPHYStatus = 0;
- }
- return usPHYStatus;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t xGMACWaitLS( TickType_t xMaxTime )
-{
-TickType_t xStartTime = xTaskGetTickCount();
-TickType_t xEndTime;
-BaseType_t xReturn;
-const TickType_t xShortTime = pdMS_TO_TICKS( 100UL );
-const uint32_t ulHz_Per_MHz = 1000000UL;
-
- for( ;; )
- {
- xEndTime = xTaskGetTickCount();
-
- if( ( xEndTime - xStartTime ) > xMaxTime )
- {
- /* Wated more than xMaxTime, return. */
- xReturn = pdFALSE;
- break;
- }
-
- /* Check the link status again. */
- ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- /* Link is up - return. */
- xReturn = pdTRUE;
- break;
- }
-
- /* Link is down - wait in the Blocked state for a short while (to allow
- other tasks to execute) before checking again. */
- vTaskDelay( xShortTime );
- }
-
- FreeRTOS_printf( ( "xGMACWaitLS: %ld freq %lu Mz\n",
- xReturn,
- sysclk_get_cpu_hz() / ulHz_Per_MHz ) );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static void vPioSetPinHigh(uint32_t ul_pin)
-{
- Pio *p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));
- // Value to be driven on the I/O line: 1.
- p_pio->PIO_SODR = 1 << (ul_pin & 0x1F);
-}
-
-/**
- * \brief Handler for SPI interrupt.
- */
-void SPI_Handler(void)
-{
-BaseType_t xDoWakeup = pdFALSE;
-BaseType_t xKSZTaskWoken = pdFALSE;
-uint32_t ulCurrentSPIStatus;
-uint32_t ulEnabledSPIStatus;
-
- ulCurrentSPIStatus = spi_read_status( KSZ8851SNL_SPI );
- ulEnabledSPIStatus = spi_read_interrupt_mask( KSZ8851SNL_SPI );
- ulCurrentSPIStatus &= ulEnabledSPIStatus;
- spi_disable_interrupt( KSZ8851SNL_SPI, ulCurrentSPIStatus );
-
-
- switch( xMicrelDevice.ul_spi_pdc_status )
- {
- case SPI_PDC_RX_START:
- {
- if( ( ulCurrentSPIStatus & SPI_SR_OVRES ) != 0 )
- {
- pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_RX_ERROR;
- xDoWakeup = pdTRUE;
- }
- else
- {
- if( ( ulCurrentSPIStatus & SPI_SR_RXBUFF ) != 0 )
- {
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_RX_COMPLETE;
- xDoWakeup = pdTRUE;
- }
- }
- }
- break;
-
- case SPI_PDC_TX_START:
- {
- /* Middle of TX. */
- if( ( ulCurrentSPIStatus & SPI_SR_OVRES ) != 0 )
- {
- pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_TX_ERROR;
- xDoWakeup = pdTRUE;
- }
- else
- {
- if( ( ulCurrentSPIStatus & SPI_SR_ENDRX ) != 0 )
- {
- /* Enable RX complete interrupt. */
- spi_enable_interrupt( KSZ8851SNL_SPI, SPI_IER_RXBUFF );
- }
- /* End of TX. */
- if( ( ulCurrentSPIStatus & SPI_END_OF_TX ) != 0 )
- {
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_TX_COMPLETE;
- xDoWakeup = pdTRUE;
- }
- }
- }
- break;
- } /* switch( xMicrelDevice.ul_spi_pdc_status ) */
-
- if( xDoWakeup != pdFALSE )
- {
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xKSZTaskWoken );
- }
- }
- else
- {
- }
- portEND_SWITCHING_ISR( xKSZTaskWoken );
-}
-/*-----------------------------------------------------------*/
-
-static void INTN_Handler(uint32_t id, uint32_t mask)
-{
-BaseType_t xKSZTaskWoken = pdFALSE;
-
- if( ( id == INTN_ID ) &&
- ( mask == INTN_PIN_MSK ) )
- {
- /* Clear the PIO interrupt flags. */
- pio_get_interrupt_status( INTN_PIO );
-
- /* Set the INTN flag. */
- xMicrelDevice.ul_had_intn_interrupt++;
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &( xKSZTaskWoken ) );
- }
- }
- portEND_SWITCHING_ISR( xKSZTaskWoken );
-}
-/*-----------------------------------------------------------*/
-
-/**
- * \brief Populate the RX descriptor ring buffers with pbufs.
- *
- * \param p_ksz8851snl_dev Pointer to driver data structure.
- */
-static void ksz8851snl_rx_populate_queue( void )
-{
- uint32_t ul_index = 0;
- NetworkBufferDescriptor_t *pxNetworkBuffer;
-
- /* Set up the RX descriptors */
- for (ul_index = 0; ul_index < MICREL_RX_BUFFERS; ul_index++) {
- if( xMicrelDevice.rx_buffers[ ul_index ] == NULL )
- {
- /* Allocate a new NetworkBufferDescriptor_t with the maximum size. */
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( ipconfigNETWORK_MTU + 36, 100 );
- if( pxNetworkBuffer == NULL )
- {
- FreeRTOS_printf( ( "ksz8851snl_rx_populate_queue: NetworkBufferDescriptor_t allocation failure\n" ) );
- configASSERT( 1 == 2 );
- }
-
- /* Make sure lwIP is well configured so one NetworkBufferDescriptor_t can contain the maximum packet size. */
- //LWIP_ASSERT("ksz8851snl_rx_populate_queue: NetworkBufferDescriptor_t size too small!", pbuf_clen(pxNetworkBuffer) <= 1);
-
- /* Save NetworkBufferDescriptor_t pointer to be sent to lwIP upper layer. */
- xMicrelDevice.rx_buffers[ ul_index ] = pxNetworkBuffer;
- /* Pass it to Micrel for reception. */
- xMicrelDevice.rx_ready[ ul_index ] = pdFALSE;
- }
- }
-}
-
-unsigned tx_space, wait_tx_space, tx_status, fhr_status;
-unsigned rx_debug = 0;
-/**
- * \brief Update Micrel state machine and perform required actions.
- *
- * \param netif the lwIP network interface structure for this ethernetif.
- */
-static void ksz8851snl_update()
-{
- uint16_t txmir = 0;
-
-/* Check for free PDC. */
- switch( xMicrelDevice.ul_spi_pdc_status )
- {
- case SPI_PDC_TX_ERROR:
- {
- uint32_t ulValue;
- // /* TX step11: end TX transfer. */
- gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
-
- vTaskDelay( 2 ); gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
- vTaskDelay( 1 ); gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
- vTaskDelay( 1 );
-
- /* Disable asynchronous transfer mode. */
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
-
- /* TX step12: disable TXQ write access. */
- ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
-
- ulValue = ksz8851snl_reset_tx();
-
- xMicrelDevice.tx_space = ksz8851_reg_read( REG_TX_MEM_INFO ) & TX_MEM_AVAILABLE_MASK;
-
- FreeRTOS_printf( ("SPI_PDC_TX_ERROR %02X\n", ulValue ) );
- }
- break;
-
- case SPI_PDC_RX_ERROR:
- {
- uint32_t ulValue;
- /* TX step11: end TX transfer. */
- gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
-
- vTaskDelay( 2 ); gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
- vTaskDelay( 1 ); gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
- vTaskDelay( 1 );
-
- /* Disable asynchronous transfer mode. */
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
-
- /* TX step12: disable TXQ write access. */
- ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
-
- //ulValue = ksz8851snl_reset_rx();
- ulValue = ksz8851snl_reinit();
-
- xGMACWaitLS( pdMS_TO_TICKS( 5000UL ) );
-
- FreeRTOS_printf( ("SPI_PDC_RX_ERROR %02X\n", ulValue ) );
- }
- break;
- }
- switch( xMicrelDevice.ul_spi_pdc_status )
- {
- case SPI_PDC_IDLE:
- {
- int txTail = xMicrelDevice.us_tx_tail;
-
- /*
- * ========================== Handle RX ==========================
- */
- if( ( xMicrelDevice.ul_had_intn_interrupt != 0 ) || ( xMicrelDevice.us_pending_frame > 0 ) )
- {
- int rxHead = xMicrelDevice.us_rx_head;
- NetworkBufferDescriptor_t *pxNetworkBuffer;
-#warning try
- xMicrelDevice.ul_had_intn_interrupt = 0;
-
- if( xMicrelDevice.us_pending_frame == 0 )
- {
- uint16_t int_status;
- /* RX step1: read interrupt status for INT_RX flag. */
- int_status = ksz8851_reg_read( REG_INT_STATUS );
-
-
- /* RX step2: disable all interrupts. */
- ksz8851_reg_write( REG_INT_MASK, 0 );
-
- /* RX step3: clear INT_RX flag. */
- ksz8851_reg_setbits( REG_INT_STATUS, INT_RX );
-
- /* RX step4-5: check for received frames. */
- xMicrelDevice.us_pending_frame = ksz8851_reg_read(REG_RX_FRAME_CNT_THRES) >> 8;
- if( xMicrelDevice.us_pending_frame == 0 )
- {
- /* RX step24: enable INT_RX flag. */
- ksz8851_reg_write(REG_INT_MASK, INT_RX);
- return;
- }
- }
-#warning try
- xMicrelDevice.ul_had_intn_interrupt = 0;
-
- /* Now xMicrelDevice.us_pending_frame != 0 */
-
- /* Don't break Micrel state machine, wait for a free descriptor first! */
- if( xMicrelDevice.rx_ready[ rxHead ] != pdFALSE )
- {
- FreeRTOS_printf( ( "ksz8851snl_update: out of free descriptor! [tail=%u head=%u]\n",
- xMicrelDevice.us_rx_tail, rxHead ) );
- return;
- }
- pxNetworkBuffer = xMicrelDevice.rx_buffers[ rxHead ];
-
- if( pxNetworkBuffer == NULL )
- {
- ksz8851snl_rx_populate_queue();
- FreeRTOS_printf( ( "ksz8851snl_update: no buffer set [head=%u]\n", rxHead ) );
- return;
- }
-
- /* RX step6: get RX packet status. */
- fhr_status = ksz8851_reg_read( REG_RX_FHR_STATUS );
- if( ( ( fhr_status & RX_VALID ) == 0 ) || ( ( fhr_status & RX_ERRORS ) != 0 ) )
- {
- ksz8851_reg_setbits(REG_RXQ_CMD, RXQ_CMD_FREE_PACKET);
- FreeRTOS_printf( ( "ksz8851snl_update: RX packet error!\n" ) );
-
- /* RX step4-5: check for received frames. */
- xMicrelDevice.us_pending_frame = ksz8851_reg_read(REG_RX_FRAME_CNT_THRES) >> 8;
- if( xMicrelDevice.us_pending_frame == 0 )
- {
- /* RX step24: enable INT_RX flag. */
- ksz8851_reg_write(REG_INT_MASK, INT_RX);
- }
- ulISREvents |= EMAC_IF_ERR_EVENT;
- }
- else
- {
- size_t xLength;
- /* RX step7: read frame length. */
- xLength = ksz8851_reg_read(REG_RX_FHR_BYTE_CNT) & RX_BYTE_CNT_MASK;
-
- /* RX step8: Drop packet if len is invalid or no descriptor available. */
- if( xLength == 0 )
- {
- ksz8851_reg_setbits( REG_RXQ_CMD, RXQ_CMD_FREE_PACKET );
- FreeRTOS_printf( ( "ksz8851snl_update: RX bad len!\n" ) );
- ulISREvents |= EMAC_IF_ERR_EVENT;
- }
- else
- {
- size_t xReadLength = xLength;
-
- xMicrelDevice.ul_total_rx++;
- /* RX step9: reset RX frame pointer. */
- ksz8851_reg_clrbits(REG_RX_ADDR_PTR, ADDR_PTR_MASK);
-
- /* RX step10: start RXQ read access. */
- ksz8851_reg_setbits(REG_RXQ_CMD, RXQ_START);
- /* RX step11-17: start asynchronous FIFO read operation. */
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_RX_START;
- gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
- if( ( xReadLength & ( sizeof( size_t ) - 1 ) ) != 0 )
- {
- xReadLength = ( xReadLength | ( sizeof( size_t ) - 1 ) ) + 1;
- }
-
- /* Pass the buffer minus 2 bytes, see ksz8851snl.c: RXQ_TWOBYTE_OFFSET. */
- ksz8851_fifo_read( pxNetworkBuffer->pucEthernetBuffer - 2, xReadLength );
- /* Remove CRC and update buffer length. */
- xLength -= 4;
- pxNetworkBuffer->xDataLength = xLength;
- /* Wait for SPI interrupt to set status 'SPI_PDC_RX_COMPLETE'. */
- }
- }
- break;
- } /* ul_had_intn_interrupt || us_pending_frame */
- /*
- * ========================== Handle TX ==========================
- */
-
- /* Fetch next packet to be sent. */
- if( ( xMicrelDevice.tx_busy[ txTail ] != pdFALSE ) &&
- ( xMicrelDevice.us_pending_frame == 0 ) &&
- ( xMicrelDevice.ul_had_intn_interrupt == 0 ) )
- {
- NetworkBufferDescriptor_t *pxNetworkBuffer = xMicrelDevice.tx_buffers[ txTail ];
- size_t xLength = pxNetworkBuffer->xDataLength;
- int iIndex = xLength;
-
- xLength = 4 * ( ( xLength + 3 ) / 4 );
- while( iIndex < ( int ) xLength )
- {
- pxNetworkBuffer->pucEthernetBuffer[ iIndex ] = '\0';
- iIndex++;
- }
- pxNetworkBuffer->xDataLength = xLength;
-
- /* TX step1: check if TXQ memory size is available for transmit. */
- txmir = ksz8851_reg_read( REG_TX_MEM_INFO );
- txmir = txmir & TX_MEM_AVAILABLE_MASK;
-
- if( txmir < ( xLength + 8 ) )
- {
- if( wait_tx_space == pdFALSE )
- {
- tx_status = ksz8851_reg_read( REG_TX_STATUS );
- fhr_status = ksz8851_reg_read( REG_RX_FHR_STATUS );
- wait_tx_space = pdTRUE;
- }
- //return;
- rx_debug = 1;
- tx_space = txmir;
- }
- else
- {
- tx_space = txmir;
-
- /* TX step2: disable all interrupts. */
- ksz8851_reg_write( REG_INT_MASK, 0 );
-
- xMicrelDevice.tx_space -= xLength;
-
- /* TX step3: enable TXQ write access. */
- ksz8851_reg_setbits( REG_RXQ_CMD, RXQ_START );
- /* TX step4-8: perform FIFO write operation. */
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_TX_START;
- xMicrelDevice.tx_cur_buffer = pxNetworkBuffer;
- /* Bring SPI SS low. */
- gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
- xMicrelDevice.ul_total_tx++;
-
- ksz8851_fifo_write( pxNetworkBuffer->pucEthernetBuffer, xLength, xLength );
- }
- }
- }
- break; /* SPI_PDC_IDLE */
-
- case SPI_PDC_RX_COMPLETE:
- {
- int rxHead = xMicrelDevice.us_rx_head;
- /* RX step18-19: pad with dummy data to keep dword alignment. */
- /* Packet lengths will be rounded up to a multiple of "sizeof size_t". */
-// xLength = xMicrelDevice.rx_buffers[ rxHead ]->xDataLength & 3;
-// if( xLength != 0 )
-// {
-// ksz8851_fifo_dummy( 4 - xLength );
-// }
-
- /* RX step20: end RX transfer. */
- gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
-
- /* Disable asynchronous transfer mode. */
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
-
- /* RX step21: end RXQ read access. */
- ksz8851_reg_clrbits(REG_RXQ_CMD, RXQ_START);
-
- /* RX step22-23: update frame count to be read. */
- xMicrelDevice.us_pending_frame -= 1;
-
- /* RX step24: enable INT_RX flag if transfer complete. */
- if( xMicrelDevice.us_pending_frame == 0 )
- {
- ksz8851_reg_write(REG_INT_MASK, INT_RX);
- }
-
- /* Mark descriptor ready to be read. */
- xMicrelDevice.rx_ready[ rxHead ] = pdTRUE;
- if( ++rxHead == MICREL_RX_BUFFERS )
- {
- rxHead = 0;
- }
- xMicrelDevice.us_rx_head = rxHead;
- if( rx_debug != 0 )
- {
- uint32_t txmir;
- rx_debug = 0;
- txmir = ksz8851_reg_read( REG_TX_MEM_INFO );
- txmir = txmir & TX_MEM_AVAILABLE_MASK;
- }
- /* Tell prvEMACHandlerTask that RX packets are available. */
- ulISREvents |= EMAC_IF_RX_EVENT;
- } /* case SPI_PDC_RX_COMPLETE */
- break;
-
- case SPI_PDC_TX_COMPLETE:
- {
- int txTail = xMicrelDevice.us_tx_tail;
- NetworkBufferDescriptor_t *pxNetworkBuffer = xMicrelDevice.tx_buffers[ txTail ];
-
- size_t xLength;
- /* TX step9-10: pad with dummy data to keep dword alignment. */
- /* Not necessary: length is already a multiple of 4. */
- xLength = pxNetworkBuffer->xDataLength & 3;
- if( xLength != 0 )
- {
-// ksz8851_fifo_dummy( 4 - xLength );
- }
-
-// /* TX step11: end TX transfer. */
- gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
-
- /* Disable asynchronous transfer mode. */
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
-
- /* TX step12: disable TXQ write access. */
- ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
-
- xMicrelDevice.tx_space = ksz8851_reg_read( REG_TX_MEM_INFO ) & TX_MEM_AVAILABLE_MASK;
-
- /* TX step12.1: enqueue frame in TXQ. */
- ksz8851_reg_setbits( REG_TXQ_CMD, TXQ_ENQUEUE );
-
- /* RX step13: enable INT_RX flag. */
-// ksz8851_reg_write( REG_INT_MASK, INT_RX );
- /* Buffer sent, free the corresponding buffer and mark descriptor as owned by software. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
-
- xMicrelDevice.tx_buffers[ txTail ] = NULL;
- xMicrelDevice.tx_busy[ txTail ] = pdFALSE;
- if( ++txTail == MICREL_TX_BUFFERS )
- {
- txTail = 0;
- }
-
- xMicrelDevice.us_tx_tail = txTail;
- /* Experiment. */
- //xMicrelDevice.ul_had_intn_interrupt = 1;
- if( xTransmitHandle != NULL )
- {
- xTaskNotifyGive( xTransmitHandle );
- }
-#warning moved downward
- /* RX step13: enable INT_RX flag. */
- ksz8851_reg_write( REG_INT_MASK, INT_RX );
- /* Prevent the EMAC task from sleeping a single time. */
- ulISREvents |= EMAC_IF_TX_EVENT;
- } /* case SPI_PDC_TX_COMPLETE */
- break;
- } /* switch( xMicrelDevice.ul_spi_pdc_status ) */
-}
-
-/**
- * \brief Set up the RX descriptor ring buffers.
- *
- * This function sets up the descriptor list used for RX packets.
- *
- */
-static void ksz8851snl_rx_init()
-{
- uint32_t ul_index = 0;
-
- /* Init pointer index. */
- xMicrelDevice.us_rx_head = 0;
- xMicrelDevice.us_rx_tail = 0;
-
- /* Set up the RX descriptors. */
- for (ul_index = 0; ul_index < MICREL_RX_BUFFERS; ul_index++) {
- xMicrelDevice.rx_buffers[ul_index] = NULL;
- xMicrelDevice.rx_ready[ul_index] = pdFALSE;
- }
-
- /* Build RX buffer and descriptors. */
- ksz8851snl_rx_populate_queue();
-}
-
-/**
- * \brief Set up the TX descriptor ring buffers.
- *
- * This function sets up the descriptor list used for TX packets.
- *
- */
-static void ksz8851snl_tx_init()
-{
- uint32_t ul_index = 0;
-
- /* Init TX index pointer. */
- xMicrelDevice.us_tx_head = 0;
- xMicrelDevice.us_tx_tail = 0;
-
- /* Set up the TX descriptors */
- for( ul_index = 0; ul_index < MICREL_TX_BUFFERS; ul_index++ )
- {
- xMicrelDevice.tx_busy[ul_index] = pdFALSE;
- }
- xMicrelDevice.tx_space = 6144;
-}
-
-/**
- * \brief Initialize ksz8851snl ethernet controller.
- *
- * \note Called from ethernetif_init().
- *
- * \param netif the lwIP network interface structure for this ethernetif.
- */
-static void ksz8851snl_low_level_init( void )
-{
- ksz8851snl_rx_init();
- ksz8851snl_tx_init();
-
- /* Enable NVIC interrupts. */
- NVIC_SetPriority(SPI_IRQn, INT_PRIORITY_SPI);
- NVIC_EnableIRQ(SPI_IRQn);
-
- /* Initialize SPI link. */
- if( ksz8851snl_init() < 0 )
- {
- FreeRTOS_printf( ( "ksz8851snl_low_level_init: failed to initialize the Micrel driver!\n" ) );
- configASSERT(0 == 1);
- }
- memset( xMicrelDevice.pusHashTable, 255, sizeof( xMicrelDevice.pusHashTable ) );
- ksz8851_reg_write( REG_MAC_HASH_0, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 0 ] ) );
- ksz8851_reg_write( REG_MAC_HASH_2, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 1 ] ) );
- ksz8851_reg_write( REG_MAC_HASH_4, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 2 ] ) );
- ksz8851_reg_write( REG_MAC_HASH_6, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 3 ] ) );
-
- /* Initialize interrupt line INTN. */
- configure_intn( INTN_Handler );
-}
-
-/**
- * \brief Use pre-allocated pbuf as DMA source and return the incoming packet.
- *
- * \param netif the lwIP network interface structure for this ethernetif.
- *
- * \return a pbuf filled with the received packet (including MAC header).
- * 0 on memory error.
- */
-static NetworkBufferDescriptor_t *ksz8851snl_low_level_input( void )
-{
-NetworkBufferDescriptor_t *pxNetworkBuffer = NULL;
-int rxTail = xMicrelDevice.us_rx_tail;
-
- /* Check that descriptor is owned by software (ie packet received). */
- if( xMicrelDevice.rx_ready[ rxTail ] != pdFALSE )
- {
-
- /* Fetch pre-allocated buffer */
- pxNetworkBuffer = xMicrelDevice.rx_buffers[ rxTail ];
-
- /* Remove this pbuf from its descriptor. */
- xMicrelDevice.rx_buffers[ rxTail ] = NULL;
-
- /* Clears rx_ready and sets rx_buffers. */
- ksz8851snl_rx_populate_queue();
-
- if( ++rxTail == MICREL_RX_BUFFERS )
- {
- rxTail = 0;
- }
- xMicrelDevice.us_rx_tail = rxTail;
- }
-
- return pxNetworkBuffer;
-}
-/*-----------------------------------------------------------*/
-
-static uint32_t prvEMACRxPoll( void )
-{
-NetworkBufferDescriptor_t *pxNetworkBuffer;
-IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-uint32_t ulReturnValue = 0;
-
- for( ;; )
- {
- /* Only for logging. */
- int rxTail = xMicrelDevice.us_rx_tail;
- EthernetHeader_t *pxEthernetHeader;
-
- pxNetworkBuffer = ksz8851snl_low_level_input();
-
- if( pxNetworkBuffer == NULL )
- {
- break;
- }
- pxEthernetHeader = ( EthernetHeader_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
-
- if( ( pxEthernetHeader->usFrameType != ipIPv4_FRAME_TYPE ) &&
- ( pxEthernetHeader->usFrameType != ipARP_FRAME_TYPE ) )
- {
- FreeRTOS_printf( ( "Frame type %02X received\n", pxEthernetHeader->usFrameType ) );
- }
- ulReturnValue++;
-
- xRxEvent.pvData = ( void * )pxNetworkBuffer;
- /* Send the descriptor to the IP task for processing. */
- if( xSendEventStructToIPTask( &xRxEvent, 100UL ) != pdTRUE )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- iptraceETHERNET_RX_EVENT_LOST();
- FreeRTOS_printf( ( "prvEMACRxPoll: Can not queue return packet!\n" ) );
- }
- }
-
- return ulReturnValue;
-}
-/*-----------------------------------------------------------*/
-
-static void prvEMACHandlerTask( void *pvParameters )
-{
-TimeOut_t xPhyTime;
-TickType_t xPhyRemTime;
-TickType_t xLoggingTime;
-UBaseType_t uxLastMinBufferCount = 0;
-UBaseType_t uxCurrentCount;
-BaseType_t xResult = 0;
-uint32_t xStatus;
-const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );
-#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- UBaseType_t uxLastMinQueueSpace = 0;
-#endif
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
-
- configASSERT( xEMACTaskHandle );
-
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
- xLoggingTime = xTaskGetTickCount();
-
- for( ;; )
- {
- 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( 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 */
-
- /* Run the state-machine of the ksz8851 driver. */
- ksz8851snl_update();
-
- if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
- {
- /* No events to process now, wait for the next. */
- ulTaskNotifyTake( pdTRUE, ulMaxBlockTime );
- }
-
- if( ( xTaskGetTickCount() - xLoggingTime ) > 10000 )
- {
- xLoggingTime += 10000;
- FreeRTOS_printf( ( "Now Tx/Rx %7d /%7d\n",
- xMicrelDevice.ul_total_tx, xMicrelDevice.ul_total_rx ) );
- }
-
- if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
- {
- ulISREvents &= ~EMAC_IF_RX_EVENT;
-
- /* Wait for the EMAC interrupt to indicate that another packet has been
- received. */
- xResult = prvEMACRxPoll();
- }
-
- if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
- {
- /* Future extension: code to release TX buffers if zero-copy is used. */
- ulISREvents &= ~EMAC_IF_TX_EVENT;
- }
-
- if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
- {
- /* Future extension: logging about errors that occurred. */
- ulISREvents &= ~EMAC_IF_ERR_EVENT;
- }
-
- if( xResult > 0 )
- {
- /* As long as packets are being received, assume that
- the Link Status is high. */
- ulPHYLinkStatus |= BMSR_LINK_STATUS;
- /* A packet was received. No need to check for the PHY status now,
- but set a timer to check it later on. */
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- xResult = 0;
- }
- else if( ( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE ) &&
- ( xMicrelDevice.ul_spi_pdc_status == SPI_PDC_IDLE ) )
- {
- /* Check the link status again. */
- xStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
- {
- ulPHYLinkStatus = xStatus;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
- }
-
- vTaskSetTimeOutState( &xPhyTime );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- }
- else
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
- }
- }
- }
-}
-/*-----------------------------------------------------------*/
+/*
+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. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+#include "sam4e_xplained_pro.h"
+#include "hr_gettime.h"
+#include "conf_eth.h"
+#include "ksz8851snl.h"
+#include "ksz8851snl_reg.h"
+
+/* Some files from the Atmel Software Framework */
+#include <sysclk.h>
+#include <pdc/pdc.h>
+#include <spi/spi.h>
+
+/*
+ Sending a packet:
+
+ 1) Called by UP-task, add buffer to the TX-list:
+ xNetworkInterfaceOutput()
+ tx_buffers[ us_tx_head ] = pxNetworkBuffer;
+ tx_busy[ us_tx_head ] = pdTRUE;
+ us_tx_head++;
+
+ 2) Called by EMAC-Task: start SPI transfer
+ ksz8851snl_update()
+ if( ul_spi_pdc_status == SPI_PDC_IDLE )
+ {
+ if( ( tx_busy[ us_tx_tail ] != pdFALSE ) &&
+ ( us_pending_frame == 0 ) &&
+ ( ul_had_intn_interrupt == 0 ) )
+ {
+ // disable all interrupts.
+ ksz8851_reg_write( REG_INT_MASK, 0 );
+ Bring KSZ8851SNL_CSN_GPIO low
+ ksz8851_fifo_write( pxNetworkBuffer->pucEthernetBuffer, xLength, xLength );
+ ul_spi_pdc_status = SPI_PDC_TX_START;
+ tx_cur_buffer = pxNetworkBuffer;
+ }
+ }
+ 3) Wait for SPI RXBUFF interrupt
+ SPI_Handler()
+ if( ul_spi_pdc_status == SPI_PDC_TX_START )
+ {
+ if( SPI_Status & SPI_SR_RXBUFF )
+ {
+ ul_spi_pdc_status = SPI_PDC_TX_COMPLETE;
+ }
+ }
+
+ 4) Called by EMAC-Task: finish SPI transfer
+ ksz8851snl_update()
+ if( ul_spi_pdc_status == SPI_PDC_TX_COMPLETE )
+ {
+ ul_spi_pdc_status = SPI_PDC_IDLE;
+ Bring KSZ8851SNL_CSN_GPIO high
+ // TX step12: disable TXQ write access.
+ ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
+ // TX step12.1: enqueue frame in TXQ.
+ ksz8851_reg_setbits( REG_TXQ_CMD, TXQ_ENQUEUE );
+
+ // RX step13: enable INT_RX flag.
+ ksz8851_reg_write( REG_INT_MASK, INT_RX );
+
+ // Buffer sent, free the corresponding buffer and mark descriptor as owned by software.
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+
+ tx_buffers[ us_tx_tail ] = NULL;
+ tx_busy[ us_tx_tail ] = pdFALSE;
+ us_tx_tail++
+ }
+
+ Receiving a packet:
+
+ 1) Wait for a INTN interrupt
+ INTN_Handler()
+ ul_had_intn_interrupt = 1
+ vTaskNotifyGiveFromISR(); // Wake up the EMAC task
+
+ 2) Called by EMAC-Task: check for new fragments and start SPI transfer
+ ksz8851snl_update()
+ if( ul_spi_pdc_status == SPI_PDC_IDLE )
+ {
+ if( ( ul_had_intn_interrupt != 0 ) || ( us_pending_frame > 0 ) )
+ {
+ if( us_pending_frame == 0 )
+ {
+ us_pending_frame = ksz8851_reg_read(REG_RX_FRAME_CNT_THRES) >> 8;
+ if( us_pending_frame == 0 )
+ {
+ break;
+ }
+ }
+ // RX step2: disable all interrupts.
+ ksz8851_reg_write( REG_INT_MASK, 0 );
+ Check if there is a valid packet: REG_RX_FHR_STATUS
+ Read the length of the next fragment: REG_RX_FHR_BYTE_CNT
+ ul_spi_pdc_status = SPI_PDC_RX_START;
+ gpio_set_pin_low(KSZ8851SNL_CSN_GPIO);
+ // Start SPI data transfer
+ ksz8851_fifo_read( pxNetworkBuffer->pucEthernetBuffer, xReadLength );
+ }
+ }
+
+ 3) Wait for SPI RXBUFF interrupt
+ SPI_Handler()
+ if( ul_spi_pdc_status == SPI_PDC_RX_START:
+ {
+ if( ( ulCurrentSPIStatus & SPI_SR_RXBUFF ) != 0 )
+ {
+ // Transfer complete, disable SPI RXBUFF interrupt.
+ spi_disable_interrupt( KSZ8851SNL_SPI, SPI_IDR_RXBUFF );
+
+ ul_spi_pdc_status = SPI_PDC_RX_COMPLETE;
+ }
+ }
+ }
+
+ 4) Finish SPI transfer
+ ksz8851snl_update()
+ if( ul_spi_pdc_status == SPI_PDC_RX_COMPLETE )
+ {
+ ul_spi_pdc_status = SPI_PDC_IDLE;
+ Bring KSZ8851SNL_CSN_GPIO high
+ // RX step21: end RXQ read access.
+ ksz8851_reg_clrbits(REG_RXQ_CMD, RXQ_START);
+ // RX step22-23: update frame count to be read.
+ us_pending_frame--
+ // RX step24: enable INT_RX flag if transfer complete.
+ if( us_pending_frame == 0 )
+ {
+ // Allow more RX interrupts.
+ ksz8851_reg_write( REG_INT_MASK, INT_RX );
+ }
+
+ // Mark descriptor ready to be read.
+ rx_ready[ rxHead ] = pdTRUE;
+ rxHead++
+ }
+*/
+
+#define PHY_REG_00_BMCR 0x00 // Basic mode control register
+#define PHY_REG_01_BMSR 0x01 // Basic mode status register
+#define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1
+#define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2
+#define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg
+#define PHY_REG_05_LPA 0x05 // Link partner ability reg
+#define PHY_REG_06_ANER 0x06 // 6 RW Auto-Negotiation Expansion Register
+#define PHY_REG_07_ANNPTR 0x07 // 7 RW Auto-Negotiation Next Page TX
+#define PHY_REG_08_RESERVED0 0x08 // 0x08..0x0Fh 8-15 RW RESERVED
+
+#define BMSR_LINK_STATUS 0x0004 //!< Link status
+
+#ifndef PHY_LS_HIGH_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
+ receiving packets. */
+ #define PHY_LS_HIGH_CHECK_TIME_MS 15000
+#endif
+
+#ifndef PHY_LS_LOW_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still low every second. */
+ #define PHY_LS_LOW_CHECK_TIME_MS 1000
+#endif
+
+/* Interrupt events to process. Currently only the Rx event is processed
+although code for other events is included to allow for possible future
+expansion. */
+#define EMAC_IF_RX_EVENT 1UL
+#define EMAC_IF_TX_EVENT 2UL
+#define EMAC_IF_ERR_EVENT 4UL
+#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
+
+#define ETHERNET_CONF_PHY_ADDR BOARD_GMAC_PHY_ADDR
+
+#ifdef ipconfigHAS_TX_CRC_OFFLOADING
+ #undef ipconfigHAS_TX_CRC_OFFLOADING
+#endif
+/* Override this define because the KSZ8851 is programmed to set all outgoing CRC's */
+#define ipconfigHAS_TX_CRC_OFFLOADING 1
+
+#ifndef EMAC_MAX_BLOCK_TIME_MS
+ #define EMAC_MAX_BLOCK_TIME_MS 100ul
+#endif
+
+/* Default the size of the stack used by the EMAC deferred handler task to 4x
+the size of the stack used by the idle task - but allow this to be overridden in
+FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
+#ifndef configEMAC_TASK_STACK_SIZE
+ #define configEMAC_TASK_STACK_SIZE ( 6 * configMINIMAL_STACK_SIZE )
+#endif
+
+#define SPI_PDC_IDLE 0
+#define SPI_PDC_RX_START 1
+#define SPI_PDC_TX_ERROR 2
+#define SPI_PDC_RX_COMPLETE 3
+#define SPI_PDC_TX_START 4
+#define SPI_PDC_RX_ERROR 5
+#define SPI_PDC_TX_COMPLETE 6
+
+/**
+ * ksz8851snl driver structure.
+ */
+typedef struct {
+ /** Set to 1 when owner is software (ready to read), 0 for Micrel. */
+ uint32_t rx_ready[MICREL_RX_BUFFERS];
+ /** Set to 1 when owner is Micrel, 0 for software. */
+ uint32_t tx_busy[MICREL_TX_BUFFERS];
+ /** RX NetworkBufferDescriptor_t pointer list */
+ NetworkBufferDescriptor_t *rx_buffers[MICREL_RX_BUFFERS];
+ /** TX NetworkBufferDescriptor_t pointer list */
+ NetworkBufferDescriptor_t *tx_buffers[MICREL_TX_BUFFERS];
+ NetworkBufferDescriptor_t *tx_cur_buffer;
+
+ /** Circular buffer head pointer for packet received. */
+ uint32_t us_rx_head;
+ /** Circular buffer tail pointer for packet to be read. */
+ uint32_t us_rx_tail;
+ /** Circular buffer head pointer by upper layer (buffer to be sent). */
+ uint32_t us_tx_head;
+ /** Circular buffer tail pointer incremented by handlers (buffer sent). */
+ uint32_t us_tx_tail;
+
+ uint32_t ul_total_tx;
+ uint32_t ul_total_rx;
+ uint32_t tx_space;
+
+ /** Still experimental: hash table to allow certain multicast addresses. */
+ uint16_t pusHashTable[ 4 ];
+
+ /* ul_spi_pdc_status has "SPI_PDC_xxx" values. */
+ volatile uint32_t ul_spi_pdc_status;
+
+ /* ul_had_intn_interrupt becomes true within the INTN interrupt. */
+ volatile uint32_t ul_had_intn_interrupt;
+
+ uint16_t us_pending_frame;
+} xKSZ8851_Device_t;
+
+/* SPI PDC register base.
+Declared in ASF\sam\components\ksz8851snl\ksz8851snl.c */
+extern Pdc *g_p_spi_pdc;
+
+/* Temporary buffer for PDC reception.
+declared in ASF\sam\components\ksz8851snl\ksz8851snl.c */
+extern uint8_t tmpbuf[1536];
+
+COMPILER_ALIGNED(8)
+static xKSZ8851_Device_t xMicrelDevice;
+
+static TaskHandle_t xTransmitHandle;
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Wait a fixed time for the link status to indicate the network is up.
+ */
+static BaseType_t xGMACWaitLS( TickType_t xMaxTime );
+
+/*
+ * A deferred interrupt handler task that processes GMAC interrupts.
+ */
+static void prvEMACHandlerTask( void *pvParameters );
+
+/*
+ * Try to obtain an Rx packet from the hardware.
+ */
+static uint32_t prvEMACRxPoll( void );
+
+static inline unsigned long ulReadMDIO( unsigned uAddress );
+
+static void ksz8851snl_low_level_init( void );
+
+static NetworkBufferDescriptor_t *ksz8851snl_low_level_input( void );
+
+/*-----------------------------------------------------------*/
+
+/* Bit map of outstanding ETH interrupt events for processing. Currently only
+the Rx interrupt is handled, although code is included for other events to
+enable future expansion. */
+static volatile uint32_t ulISREvents;
+
+/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
+static uint32_t ulPHYLinkStatus = 0;
+static volatile BaseType_t xGMACSwitchRequired;
+
+static void ksz8851snl_update( void );
+
+static void ksz8851snl_rx_init( void );
+
+static void ksz8851snl_tx_init( void );
+
+/* 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;
+
+
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+const TickType_t x5_Seconds = 5000UL;
+
+ if( xEMACTaskHandle == NULL )
+ {
+ ksz8851snl_low_level_init();
+
+ /* Wait at most 5 seconds for a Link Status in the PHY. */
+ xGMACWaitLS( pdMS_TO_TICKS( x5_Seconds ) );
+
+ /* The handler task is created at the highest possible priority to
+ ensure the interrupt handler can return directly to it. */
+ xTaskCreate( prvEMACHandlerTask, "KSZ8851", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
+ configASSERT( xEMACTaskHandle );
+ }
+
+ /* When returning non-zero, the stack will become active and
+ start DHCP (in configured) */
+ ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xGetPhyLinkStatus( void )
+{
+BaseType_t xResult;
+
+ /* This function returns true if the Link Status in the PHY is high. */
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xResult = pdTRUE;
+ }
+ else
+ {
+ xResult = pdFALSE;
+ }
+
+ return xResult;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t bReleaseAfterSend )
+{
+BaseType_t xResult = pdFALSE;
+int txHead = xMicrelDevice.us_tx_head;
+
+ /* Make sure the next descriptor is free. */
+ if( xMicrelDevice.tx_busy[ txHead ] != pdFALSE )
+ {
+ /* All TX buffers busy. */
+ }
+ else if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
+ {
+ /* Output: LS low. */
+ }
+ else
+ {
+ /* Pass the packet. */
+ xMicrelDevice.tx_buffers[ txHead ] = pxNetworkBuffer;
+ /* The descriptor is now owned by Micrel. */
+ xMicrelDevice.tx_busy[ txHead ] = pdTRUE;
+
+ /* Move the head pointer. */
+ if( ++txHead == MICREL_TX_BUFFERS )
+ {
+ txHead = 0;
+ }
+ xMicrelDevice.us_tx_head = txHead;
+ if( xEMACTaskHandle != NULL )
+ {
+ xTaskNotifyGive( xEMACTaskHandle );
+ }
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 1 )
+ #warning Please ipconfigZERO_COPY_TX_DRIVER as 1
+ #endif
+ configASSERT( bReleaseAfterSend != pdFALSE );
+ xResult = pdTRUE;
+ }
+ if( ( xResult == pdFALSE ) && ( bReleaseAfterSend != pdFALSE ) )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ }
+ return xResult;
+}
+/*-----------------------------------------------------------*/
+
+/* This Micrel has numbered it's PHY registers in a different way.
+Translate the register index. */
+static int ks8851_phy_reg( int reg )
+{
+ switch (reg) {
+ case PHY_REG_00_BMCR:
+ return REG_PHY_CNTL; // P1MBCR;
+ case PHY_REG_01_BMSR:
+ return REG_PHY_STATUS;
+ case PHY_REG_02_PHYSID1:
+ return REG_PHY_ID_LOW;
+ case PHY_REG_03_PHYSID2:
+ return REG_PHY_ID_HIGH;
+ case PHY_REG_04_ADVERTISE:
+ return REG_PHY_AUTO_NEGOTIATION;
+ case PHY_REG_05_LPA:
+ return REG_PHY_REMOTE_CAPABILITY;
+ }
+
+ return 0x0;
+}
+/*-----------------------------------------------------------*/
+
+static inline unsigned long ulReadMDIO( unsigned uAddress )
+{
+uint16_t usPHYStatus;
+int ks8851_reg = ks8851_phy_reg( uAddress );
+
+ if( ks8851_reg != 0 )
+ {
+ usPHYStatus = ksz8851_reg_read( ks8851_reg );
+ }
+ else
+ {
+ /* Other addresses not yet implemented. */
+ usPHYStatus = 0;
+ }
+ return usPHYStatus;
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t xGMACWaitLS( TickType_t xMaxTime )
+{
+TickType_t xStartTime = xTaskGetTickCount();
+TickType_t xEndTime;
+BaseType_t xReturn;
+const TickType_t xShortTime = pdMS_TO_TICKS( 100UL );
+const uint32_t ulHz_Per_MHz = 1000000UL;
+
+ for( ;; )
+ {
+ xEndTime = xTaskGetTickCount();
+
+ if( ( xEndTime - xStartTime ) > xMaxTime )
+ {
+ /* Wated more than xMaxTime, return. */
+ xReturn = pdFALSE;
+ break;
+ }
+
+ /* Check the link status again. */
+ ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ /* Link is up - return. */
+ xReturn = pdTRUE;
+ break;
+ }
+
+ /* Link is down - wait in the Blocked state for a short while (to allow
+ other tasks to execute) before checking again. */
+ vTaskDelay( xShortTime );
+ }
+
+ FreeRTOS_printf( ( "xGMACWaitLS: %ld freq %lu Mz\n",
+ xReturn,
+ sysclk_get_cpu_hz() / ulHz_Per_MHz ) );
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static void vPioSetPinHigh(uint32_t ul_pin)
+{
+ Pio *p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));
+ // Value to be driven on the I/O line: 1.
+ p_pio->PIO_SODR = 1 << (ul_pin & 0x1F);
+}
+
+/**
+ * \brief Handler for SPI interrupt.
+ */
+void SPI_Handler(void)
+{
+BaseType_t xDoWakeup = pdFALSE;
+BaseType_t xKSZTaskWoken = pdFALSE;
+uint32_t ulCurrentSPIStatus;
+uint32_t ulEnabledSPIStatus;
+
+ ulCurrentSPIStatus = spi_read_status( KSZ8851SNL_SPI );
+ ulEnabledSPIStatus = spi_read_interrupt_mask( KSZ8851SNL_SPI );
+ ulCurrentSPIStatus &= ulEnabledSPIStatus;
+ spi_disable_interrupt( KSZ8851SNL_SPI, ulCurrentSPIStatus );
+
+
+ switch( xMicrelDevice.ul_spi_pdc_status )
+ {
+ case SPI_PDC_RX_START:
+ {
+ if( ( ulCurrentSPIStatus & SPI_SR_OVRES ) != 0 )
+ {
+ pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_RX_ERROR;
+ xDoWakeup = pdTRUE;
+ }
+ else
+ {
+ if( ( ulCurrentSPIStatus & SPI_SR_RXBUFF ) != 0 )
+ {
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_RX_COMPLETE;
+ xDoWakeup = pdTRUE;
+ }
+ }
+ }
+ break;
+
+ case SPI_PDC_TX_START:
+ {
+ /* Middle of TX. */
+ if( ( ulCurrentSPIStatus & SPI_SR_OVRES ) != 0 )
+ {
+ pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_TX_ERROR;
+ xDoWakeup = pdTRUE;
+ }
+ else
+ {
+ if( ( ulCurrentSPIStatus & SPI_SR_ENDRX ) != 0 )
+ {
+ /* Enable RX complete interrupt. */
+ spi_enable_interrupt( KSZ8851SNL_SPI, SPI_IER_RXBUFF );
+ }
+ /* End of TX. */
+ if( ( ulCurrentSPIStatus & SPI_END_OF_TX ) != 0 )
+ {
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_TX_COMPLETE;
+ xDoWakeup = pdTRUE;
+ }
+ }
+ }
+ break;
+ } /* switch( xMicrelDevice.ul_spi_pdc_status ) */
+
+ if( xDoWakeup != pdFALSE )
+ {
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xKSZTaskWoken );
+ }
+ }
+ else
+ {
+ }
+ portEND_SWITCHING_ISR( xKSZTaskWoken );
+}
+/*-----------------------------------------------------------*/
+
+static void INTN_Handler(uint32_t id, uint32_t mask)
+{
+BaseType_t xKSZTaskWoken = pdFALSE;
+
+ if( ( id == INTN_ID ) &&
+ ( mask == INTN_PIN_MSK ) )
+ {
+ /* Clear the PIO interrupt flags. */
+ pio_get_interrupt_status( INTN_PIO );
+
+ /* Set the INTN flag. */
+ xMicrelDevice.ul_had_intn_interrupt++;
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, &( xKSZTaskWoken ) );
+ }
+ }
+ portEND_SWITCHING_ISR( xKSZTaskWoken );
+}
+/*-----------------------------------------------------------*/
+
+/**
+ * \brief Populate the RX descriptor ring buffers with pbufs.
+ *
+ * \param p_ksz8851snl_dev Pointer to driver data structure.
+ */
+static void ksz8851snl_rx_populate_queue( void )
+{
+ uint32_t ul_index = 0;
+ NetworkBufferDescriptor_t *pxNetworkBuffer;
+
+ /* Set up the RX descriptors */
+ for (ul_index = 0; ul_index < MICREL_RX_BUFFERS; ul_index++) {
+ if( xMicrelDevice.rx_buffers[ ul_index ] == NULL )
+ {
+ /* Allocate a new NetworkBufferDescriptor_t with the maximum size. */
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( ipconfigNETWORK_MTU + 36, 100 );
+ if( pxNetworkBuffer == NULL )
+ {
+ FreeRTOS_printf( ( "ksz8851snl_rx_populate_queue: NetworkBufferDescriptor_t allocation failure\n" ) );
+ configASSERT( 1 == 2 );
+ }
+
+ /* Make sure lwIP is well configured so one NetworkBufferDescriptor_t can contain the maximum packet size. */
+ //LWIP_ASSERT("ksz8851snl_rx_populate_queue: NetworkBufferDescriptor_t size too small!", pbuf_clen(pxNetworkBuffer) <= 1);
+
+ /* Save NetworkBufferDescriptor_t pointer to be sent to lwIP upper layer. */
+ xMicrelDevice.rx_buffers[ ul_index ] = pxNetworkBuffer;
+ /* Pass it to Micrel for reception. */
+ xMicrelDevice.rx_ready[ ul_index ] = pdFALSE;
+ }
+ }
+}
+
+unsigned tx_space, wait_tx_space, tx_status, fhr_status;
+unsigned rx_debug = 0;
+/**
+ * \brief Update Micrel state machine and perform required actions.
+ *
+ * \param netif the lwIP network interface structure for this ethernetif.
+ */
+static void ksz8851snl_update()
+{
+ uint16_t txmir = 0;
+
+/* Check for free PDC. */
+ switch( xMicrelDevice.ul_spi_pdc_status )
+ {
+ case SPI_PDC_TX_ERROR:
+ {
+ uint32_t ulValue;
+ // /* TX step11: end TX transfer. */
+ gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
+
+ vTaskDelay( 2 ); gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
+ vTaskDelay( 1 ); gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
+ vTaskDelay( 1 );
+
+ /* Disable asynchronous transfer mode. */
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
+
+ /* TX step12: disable TXQ write access. */
+ ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
+
+ ulValue = ksz8851snl_reset_tx();
+
+ xMicrelDevice.tx_space = ksz8851_reg_read( REG_TX_MEM_INFO ) & TX_MEM_AVAILABLE_MASK;
+
+ FreeRTOS_printf( ("SPI_PDC_TX_ERROR %02X\n", ulValue ) );
+ }
+ break;
+
+ case SPI_PDC_RX_ERROR:
+ {
+ uint32_t ulValue;
+ /* TX step11: end TX transfer. */
+ gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
+
+ vTaskDelay( 2 ); gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
+ vTaskDelay( 1 ); gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
+ vTaskDelay( 1 );
+
+ /* Disable asynchronous transfer mode. */
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
+
+ /* TX step12: disable TXQ write access. */
+ ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
+
+ //ulValue = ksz8851snl_reset_rx();
+ ulValue = ksz8851snl_reinit();
+
+ xGMACWaitLS( pdMS_TO_TICKS( 5000UL ) );
+
+ FreeRTOS_printf( ("SPI_PDC_RX_ERROR %02X\n", ulValue ) );
+ }
+ break;
+ }
+ switch( xMicrelDevice.ul_spi_pdc_status )
+ {
+ case SPI_PDC_IDLE:
+ {
+ int txTail = xMicrelDevice.us_tx_tail;
+
+ /*
+ * ========================== Handle RX ==========================
+ */
+ if( ( xMicrelDevice.ul_had_intn_interrupt != 0 ) || ( xMicrelDevice.us_pending_frame > 0 ) )
+ {
+ int rxHead = xMicrelDevice.us_rx_head;
+ NetworkBufferDescriptor_t *pxNetworkBuffer;
+#warning try
+ xMicrelDevice.ul_had_intn_interrupt = 0;
+
+ if( xMicrelDevice.us_pending_frame == 0 )
+ {
+ uint16_t int_status;
+ /* RX step1: read interrupt status for INT_RX flag. */
+ int_status = ksz8851_reg_read( REG_INT_STATUS );
+
+
+ /* RX step2: disable all interrupts. */
+ ksz8851_reg_write( REG_INT_MASK, 0 );
+
+ /* RX step3: clear INT_RX flag. */
+ ksz8851_reg_setbits( REG_INT_STATUS, INT_RX );
+
+ /* RX step4-5: check for received frames. */
+ xMicrelDevice.us_pending_frame = ksz8851_reg_read(REG_RX_FRAME_CNT_THRES) >> 8;
+ if( xMicrelDevice.us_pending_frame == 0 )
+ {
+ /* RX step24: enable INT_RX flag. */
+ ksz8851_reg_write(REG_INT_MASK, INT_RX);
+ return;
+ }
+ }
+#warning try
+ xMicrelDevice.ul_had_intn_interrupt = 0;
+
+ /* Now xMicrelDevice.us_pending_frame != 0 */
+
+ /* Don't break Micrel state machine, wait for a free descriptor first! */
+ if( xMicrelDevice.rx_ready[ rxHead ] != pdFALSE )
+ {
+ FreeRTOS_printf( ( "ksz8851snl_update: out of free descriptor! [tail=%u head=%u]\n",
+ xMicrelDevice.us_rx_tail, rxHead ) );
+ return;
+ }
+ pxNetworkBuffer = xMicrelDevice.rx_buffers[ rxHead ];
+
+ if( pxNetworkBuffer == NULL )
+ {
+ ksz8851snl_rx_populate_queue();
+ FreeRTOS_printf( ( "ksz8851snl_update: no buffer set [head=%u]\n", rxHead ) );
+ return;
+ }
+
+ /* RX step6: get RX packet status. */
+ fhr_status = ksz8851_reg_read( REG_RX_FHR_STATUS );
+ if( ( ( fhr_status & RX_VALID ) == 0 ) || ( ( fhr_status & RX_ERRORS ) != 0 ) )
+ {
+ ksz8851_reg_setbits(REG_RXQ_CMD, RXQ_CMD_FREE_PACKET);
+ FreeRTOS_printf( ( "ksz8851snl_update: RX packet error!\n" ) );
+
+ /* RX step4-5: check for received frames. */
+ xMicrelDevice.us_pending_frame = ksz8851_reg_read(REG_RX_FRAME_CNT_THRES) >> 8;
+ if( xMicrelDevice.us_pending_frame == 0 )
+ {
+ /* RX step24: enable INT_RX flag. */
+ ksz8851_reg_write(REG_INT_MASK, INT_RX);
+ }
+ ulISREvents |= EMAC_IF_ERR_EVENT;
+ }
+ else
+ {
+ size_t xLength;
+ /* RX step7: read frame length. */
+ xLength = ksz8851_reg_read(REG_RX_FHR_BYTE_CNT) & RX_BYTE_CNT_MASK;
+
+ /* RX step8: Drop packet if len is invalid or no descriptor available. */
+ if( xLength == 0 )
+ {
+ ksz8851_reg_setbits( REG_RXQ_CMD, RXQ_CMD_FREE_PACKET );
+ FreeRTOS_printf( ( "ksz8851snl_update: RX bad len!\n" ) );
+ ulISREvents |= EMAC_IF_ERR_EVENT;
+ }
+ else
+ {
+ size_t xReadLength = xLength;
+
+ xMicrelDevice.ul_total_rx++;
+ /* RX step9: reset RX frame pointer. */
+ ksz8851_reg_clrbits(REG_RX_ADDR_PTR, ADDR_PTR_MASK);
+
+ /* RX step10: start RXQ read access. */
+ ksz8851_reg_setbits(REG_RXQ_CMD, RXQ_START);
+ /* RX step11-17: start asynchronous FIFO read operation. */
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_RX_START;
+ gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
+ if( ( xReadLength & ( sizeof( size_t ) - 1 ) ) != 0 )
+ {
+ xReadLength = ( xReadLength | ( sizeof( size_t ) - 1 ) ) + 1;
+ }
+
+ /* Pass the buffer minus 2 bytes, see ksz8851snl.c: RXQ_TWOBYTE_OFFSET. */
+ ksz8851_fifo_read( pxNetworkBuffer->pucEthernetBuffer - 2, xReadLength );
+ /* Remove CRC and update buffer length. */
+ xLength -= 4;
+ pxNetworkBuffer->xDataLength = xLength;
+ /* Wait for SPI interrupt to set status 'SPI_PDC_RX_COMPLETE'. */
+ }
+ }
+ break;
+ } /* ul_had_intn_interrupt || us_pending_frame */
+ /*
+ * ========================== Handle TX ==========================
+ */
+
+ /* Fetch next packet to be sent. */
+ if( ( xMicrelDevice.tx_busy[ txTail ] != pdFALSE ) &&
+ ( xMicrelDevice.us_pending_frame == 0 ) &&
+ ( xMicrelDevice.ul_had_intn_interrupt == 0 ) )
+ {
+ NetworkBufferDescriptor_t *pxNetworkBuffer = xMicrelDevice.tx_buffers[ txTail ];
+ size_t xLength = pxNetworkBuffer->xDataLength;
+ int iIndex = xLength;
+
+ xLength = 4 * ( ( xLength + 3 ) / 4 );
+ while( iIndex < ( int ) xLength )
+ {
+ pxNetworkBuffer->pucEthernetBuffer[ iIndex ] = '\0';
+ iIndex++;
+ }
+ pxNetworkBuffer->xDataLength = xLength;
+
+ /* TX step1: check if TXQ memory size is available for transmit. */
+ txmir = ksz8851_reg_read( REG_TX_MEM_INFO );
+ txmir = txmir & TX_MEM_AVAILABLE_MASK;
+
+ if( txmir < ( xLength + 8 ) )
+ {
+ if( wait_tx_space == pdFALSE )
+ {
+ tx_status = ksz8851_reg_read( REG_TX_STATUS );
+ fhr_status = ksz8851_reg_read( REG_RX_FHR_STATUS );
+ wait_tx_space = pdTRUE;
+ }
+ //return;
+ rx_debug = 1;
+ tx_space = txmir;
+ }
+ else
+ {
+ tx_space = txmir;
+
+ /* TX step2: disable all interrupts. */
+ ksz8851_reg_write( REG_INT_MASK, 0 );
+
+ xMicrelDevice.tx_space -= xLength;
+
+ /* TX step3: enable TXQ write access. */
+ ksz8851_reg_setbits( REG_RXQ_CMD, RXQ_START );
+ /* TX step4-8: perform FIFO write operation. */
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_TX_START;
+ xMicrelDevice.tx_cur_buffer = pxNetworkBuffer;
+ /* Bring SPI SS low. */
+ gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
+ xMicrelDevice.ul_total_tx++;
+
+ ksz8851_fifo_write( pxNetworkBuffer->pucEthernetBuffer, xLength, xLength );
+ }
+ }
+ }
+ break; /* SPI_PDC_IDLE */
+
+ case SPI_PDC_RX_COMPLETE:
+ {
+ int rxHead = xMicrelDevice.us_rx_head;
+ /* RX step18-19: pad with dummy data to keep dword alignment. */
+ /* Packet lengths will be rounded up to a multiple of "sizeof size_t". */
+// xLength = xMicrelDevice.rx_buffers[ rxHead ]->xDataLength & 3;
+// if( xLength != 0 )
+// {
+// ksz8851_fifo_dummy( 4 - xLength );
+// }
+
+ /* RX step20: end RX transfer. */
+ gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
+
+ /* Disable asynchronous transfer mode. */
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
+
+ /* RX step21: end RXQ read access. */
+ ksz8851_reg_clrbits(REG_RXQ_CMD, RXQ_START);
+
+ /* RX step22-23: update frame count to be read. */
+ xMicrelDevice.us_pending_frame -= 1;
+
+ /* RX step24: enable INT_RX flag if transfer complete. */
+ if( xMicrelDevice.us_pending_frame == 0 )
+ {
+ ksz8851_reg_write(REG_INT_MASK, INT_RX);
+ }
+
+ /* Mark descriptor ready to be read. */
+ xMicrelDevice.rx_ready[ rxHead ] = pdTRUE;
+ if( ++rxHead == MICREL_RX_BUFFERS )
+ {
+ rxHead = 0;
+ }
+ xMicrelDevice.us_rx_head = rxHead;
+ if( rx_debug != 0 )
+ {
+ uint32_t txmir;
+ rx_debug = 0;
+ txmir = ksz8851_reg_read( REG_TX_MEM_INFO );
+ txmir = txmir & TX_MEM_AVAILABLE_MASK;
+ }
+ /* Tell prvEMACHandlerTask that RX packets are available. */
+ ulISREvents |= EMAC_IF_RX_EVENT;
+ } /* case SPI_PDC_RX_COMPLETE */
+ break;
+
+ case SPI_PDC_TX_COMPLETE:
+ {
+ int txTail = xMicrelDevice.us_tx_tail;
+ NetworkBufferDescriptor_t *pxNetworkBuffer = xMicrelDevice.tx_buffers[ txTail ];
+
+ size_t xLength;
+ /* TX step9-10: pad with dummy data to keep dword alignment. */
+ /* Not necessary: length is already a multiple of 4. */
+ xLength = pxNetworkBuffer->xDataLength & 3;
+ if( xLength != 0 )
+ {
+// ksz8851_fifo_dummy( 4 - xLength );
+ }
+
+// /* TX step11: end TX transfer. */
+ gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
+
+ /* Disable asynchronous transfer mode. */
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
+
+ /* TX step12: disable TXQ write access. */
+ ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
+
+ xMicrelDevice.tx_space = ksz8851_reg_read( REG_TX_MEM_INFO ) & TX_MEM_AVAILABLE_MASK;
+
+ /* TX step12.1: enqueue frame in TXQ. */
+ ksz8851_reg_setbits( REG_TXQ_CMD, TXQ_ENQUEUE );
+
+ /* RX step13: enable INT_RX flag. */
+// ksz8851_reg_write( REG_INT_MASK, INT_RX );
+ /* Buffer sent, free the corresponding buffer and mark descriptor as owned by software. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+
+ xMicrelDevice.tx_buffers[ txTail ] = NULL;
+ xMicrelDevice.tx_busy[ txTail ] = pdFALSE;
+ if( ++txTail == MICREL_TX_BUFFERS )
+ {
+ txTail = 0;
+ }
+
+ xMicrelDevice.us_tx_tail = txTail;
+ /* Experiment. */
+ //xMicrelDevice.ul_had_intn_interrupt = 1;
+ if( xTransmitHandle != NULL )
+ {
+ xTaskNotifyGive( xTransmitHandle );
+ }
+#warning moved downward
+ /* RX step13: enable INT_RX flag. */
+ ksz8851_reg_write( REG_INT_MASK, INT_RX );
+ /* Prevent the EMAC task from sleeping a single time. */
+ ulISREvents |= EMAC_IF_TX_EVENT;
+ } /* case SPI_PDC_TX_COMPLETE */
+ break;
+ } /* switch( xMicrelDevice.ul_spi_pdc_status ) */
+}
+
+/**
+ * \brief Set up the RX descriptor ring buffers.
+ *
+ * This function sets up the descriptor list used for RX packets.
+ *
+ */
+static void ksz8851snl_rx_init()
+{
+ uint32_t ul_index = 0;
+
+ /* Init pointer index. */
+ xMicrelDevice.us_rx_head = 0;
+ xMicrelDevice.us_rx_tail = 0;
+
+ /* Set up the RX descriptors. */
+ for (ul_index = 0; ul_index < MICREL_RX_BUFFERS; ul_index++) {
+ xMicrelDevice.rx_buffers[ul_index] = NULL;
+ xMicrelDevice.rx_ready[ul_index] = pdFALSE;
+ }
+
+ /* Build RX buffer and descriptors. */
+ ksz8851snl_rx_populate_queue();
+}
+
+/**
+ * \brief Set up the TX descriptor ring buffers.
+ *
+ * This function sets up the descriptor list used for TX packets.
+ *
+ */
+static void ksz8851snl_tx_init()
+{
+ uint32_t ul_index = 0;
+
+ /* Init TX index pointer. */
+ xMicrelDevice.us_tx_head = 0;
+ xMicrelDevice.us_tx_tail = 0;
+
+ /* Set up the TX descriptors */
+ for( ul_index = 0; ul_index < MICREL_TX_BUFFERS; ul_index++ )
+ {
+ xMicrelDevice.tx_busy[ul_index] = pdFALSE;
+ }
+ xMicrelDevice.tx_space = 6144;
+}
+
+/**
+ * \brief Initialize ksz8851snl ethernet controller.
+ *
+ * \note Called from ethernetif_init().
+ *
+ * \param netif the lwIP network interface structure for this ethernetif.
+ */
+static void ksz8851snl_low_level_init( void )
+{
+ ksz8851snl_rx_init();
+ ksz8851snl_tx_init();
+
+ /* Enable NVIC interrupts. */
+ NVIC_SetPriority(SPI_IRQn, INT_PRIORITY_SPI);
+ NVIC_EnableIRQ(SPI_IRQn);
+
+ /* Initialize SPI link. */
+ if( ksz8851snl_init() < 0 )
+ {
+ FreeRTOS_printf( ( "ksz8851snl_low_level_init: failed to initialize the Micrel driver!\n" ) );
+ configASSERT(0 == 1);
+ }
+ memset( xMicrelDevice.pusHashTable, 255, sizeof( xMicrelDevice.pusHashTable ) );
+ ksz8851_reg_write( REG_MAC_HASH_0, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 0 ] ) );
+ ksz8851_reg_write( REG_MAC_HASH_2, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 1 ] ) );
+ ksz8851_reg_write( REG_MAC_HASH_4, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 2 ] ) );
+ ksz8851_reg_write( REG_MAC_HASH_6, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 3 ] ) );
+
+ /* Initialize interrupt line INTN. */
+ configure_intn( INTN_Handler );
+}
+
+/**
+ * \brief Use pre-allocated pbuf as DMA source and return the incoming packet.
+ *
+ * \param netif the lwIP network interface structure for this ethernetif.
+ *
+ * \return a pbuf filled with the received packet (including MAC header).
+ * 0 on memory error.
+ */
+static NetworkBufferDescriptor_t *ksz8851snl_low_level_input( void )
+{
+NetworkBufferDescriptor_t *pxNetworkBuffer = NULL;
+int rxTail = xMicrelDevice.us_rx_tail;
+
+ /* Check that descriptor is owned by software (ie packet received). */
+ if( xMicrelDevice.rx_ready[ rxTail ] != pdFALSE )
+ {
+
+ /* Fetch pre-allocated buffer */
+ pxNetworkBuffer = xMicrelDevice.rx_buffers[ rxTail ];
+
+ /* Remove this pbuf from its descriptor. */
+ xMicrelDevice.rx_buffers[ rxTail ] = NULL;
+
+ /* Clears rx_ready and sets rx_buffers. */
+ ksz8851snl_rx_populate_queue();
+
+ if( ++rxTail == MICREL_RX_BUFFERS )
+ {
+ rxTail = 0;
+ }
+ xMicrelDevice.us_rx_tail = rxTail;
+ }
+
+ return pxNetworkBuffer;
+}
+/*-----------------------------------------------------------*/
+
+static uint32_t prvEMACRxPoll( void )
+{
+NetworkBufferDescriptor_t *pxNetworkBuffer;
+IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+uint32_t ulReturnValue = 0;
+
+ for( ;; )
+ {
+ /* Only for logging. */
+ int rxTail = xMicrelDevice.us_rx_tail;
+ EthernetHeader_t *pxEthernetHeader;
+
+ pxNetworkBuffer = ksz8851snl_low_level_input();
+
+ if( pxNetworkBuffer == NULL )
+ {
+ break;
+ }
+ pxEthernetHeader = ( EthernetHeader_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
+
+ if( ( pxEthernetHeader->usFrameType != ipIPv4_FRAME_TYPE ) &&
+ ( pxEthernetHeader->usFrameType != ipARP_FRAME_TYPE ) )
+ {
+ FreeRTOS_printf( ( "Frame type %02X received\n", pxEthernetHeader->usFrameType ) );
+ }
+ ulReturnValue++;
+
+ xRxEvent.pvData = ( void * )pxNetworkBuffer;
+ /* Send the descriptor to the IP task for processing. */
+ if( xSendEventStructToIPTask( &xRxEvent, 100UL ) != pdTRUE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ iptraceETHERNET_RX_EVENT_LOST();
+ FreeRTOS_printf( ( "prvEMACRxPoll: Can not queue return packet!\n" ) );
+ }
+ }
+
+ return ulReturnValue;
+}
+/*-----------------------------------------------------------*/
+
+static void prvEMACHandlerTask( void *pvParameters )
+{
+TimeOut_t xPhyTime;
+TickType_t xPhyRemTime;
+TickType_t xLoggingTime;
+UBaseType_t uxLastMinBufferCount = 0;
+UBaseType_t uxCurrentCount;
+BaseType_t xResult = 0;
+uint32_t xStatus;
+const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );
+#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ UBaseType_t uxLastMinQueueSpace = 0;
+#endif
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+
+ configASSERT( xEMACTaskHandle );
+
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+ xLoggingTime = xTaskGetTickCount();
+
+ for( ;; )
+ {
+ 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( 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 */
+
+ /* Run the state-machine of the ksz8851 driver. */
+ ksz8851snl_update();
+
+ if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
+ {
+ /* No events to process now, wait for the next. */
+ ulTaskNotifyTake( pdTRUE, ulMaxBlockTime );
+ }
+
+ if( ( xTaskGetTickCount() - xLoggingTime ) > 10000 )
+ {
+ xLoggingTime += 10000;
+ FreeRTOS_printf( ( "Now Tx/Rx %7d /%7d\n",
+ xMicrelDevice.ul_total_tx, xMicrelDevice.ul_total_rx ) );
+ }
+
+ if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
+ {
+ ulISREvents &= ~EMAC_IF_RX_EVENT;
+
+ /* Wait for the EMAC interrupt to indicate that another packet has been
+ received. */
+ xResult = prvEMACRxPoll();
+ }
+
+ if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
+ {
+ /* Future extension: code to release TX buffers if zero-copy is used. */
+ ulISREvents &= ~EMAC_IF_TX_EVENT;
+ }
+
+ if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
+ {
+ /* Future extension: logging about errors that occurred. */
+ ulISREvents &= ~EMAC_IF_ERR_EVENT;
+ }
+
+ if( xResult > 0 )
+ {
+ /* As long as packets are being received, assume that
+ the Link Status is high. */
+ ulPHYLinkStatus |= BMSR_LINK_STATUS;
+ /* A packet was received. No need to check for the PHY status now,
+ but set a timer to check it later on. */
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ xResult = 0;
+ }
+ else if( ( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE ) &&
+ ( xMicrelDevice.ul_spi_pdc_status == SPI_PDC_IDLE ) )
+ {
+ /* Check the link status again. */
+ xStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
+ {
+ ulPHYLinkStatus = xStatus;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
+ }
+
+ vTaskSetTimeOutState( &xPhyTime );
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ }
+ else
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/mw300_rd/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/mw300_rd/NetworkInterface.c
index df5bd7cfe..87161fd39 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/mw300_rd/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/mw300_rd/NetworkInterface.c
@@ -1,217 +1,217 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2018 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 includes. */
-#include "FreeRTOS.h"
-#include "list.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "FreeRTOS_DNS.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-#include "wifi-decl.h"
-#include "wmerrno.h"
-#include "wifi.h"
-
-#include <wmlog.h>
-
-#define net_e(...) \
- wmlog_e("freertos_tcp", ##__VA_ARGS__)
-#define net_w(...) \
- wmlog_w("freertos_tcp", ##__VA_ARGS__)
-#define net_d(...) \
- wmlog("freertos_tcp", ##__VA_ARGS__)
-
-#if 0 //this is lwip structure.
-#define MAX_INTERFACES_SUPPORTED 3
-static struct netif *netif_arr[MAX_INTERFACES_SUPPORTED];
-#endif
-
-/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
-driver will filter incoming packets and only pass the stack those packets it
-considers need processing. */
-#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
-#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
-#else
-#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
-#endif
-
-#define IP_ADDR_ANY ((ip_addr_t *)&ip_addr_any)
-#define IP_ADDR_BROADCAST ((ip_addr_t *)&ip_addr_broadcast)
-
-/** 255.255.255.255 */
-#define IPADDR_NONE ((u32_t)0xffffffffUL)
-/** 127.0.0.1 */
-#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL)
-/** 0.0.0.0 */
-#define IPADDR_ANY ((u32_t)0x00000000UL)
-/** 255.255.255.255 */
-#define IPADDR_BROADCAST ((u32_t)0xffffffffUL)
-
-/** 255.255.255.255 */
-#define INADDR_NONE IPADDR_NONE
-/** 127.0.0.1 */
-#define INADDR_LOOPBACK IPADDR_LOOPBACK
-/** 0.0.0.0 */
-#define INADDR_ANY IPADDR_ANY
-/** 255.255.255.255 */
-#define INADDR_BROADCAST IPADDR_BROADCAST
-
-enum if_state_t {
- INTERFACE_DOWN = 0,
- INTERFACE_UP,
-};
-struct ip_addr {
- u32_t addr;
-};
-
-#define MLAN_BSS_TYPE_STA 0
-
-extern uint8_t outbuf[2048];
-extern bool mlan_is_amsdu(const t_u8 *rcvdata);
-extern t_u8 *mlan_get_payload(const t_u8 *rcvdata, t_u16 *payload_len, int *interface);
-extern int wrapper_wlan_handle_amsdu_rx_packet(const t_u8 *rcvdata, const t_u16 datalen);
-extern int wrapper_wlan_handle_rx_packet(const t_u16 datalen, const t_u8 *rcvdata, NetworkBufferDescriptor_t *pxNetworkBuffer);
-static volatile uint32_t xInterfaceState = INTERFACE_DOWN;
-
-static int process_data_packet(const t_u8 *databuf, const t_u16 datalen)
-{
- int interface = BSS_TYPE_STA;
- t_u8 *payload = NULL;
- t_u16 payload_len = 0;
- const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
-
- NetworkBufferDescriptor_t *pxNetworkBuffer;
- IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-
- payload = (t_u8 *)mlan_get_payload(databuf, &payload_len, &interface);
-
- if( eConsiderFrameForProcessing( payload ) != eProcessBuffer ) {
- net_d("Dropping packet\r\n");
- return WM_SUCCESS;
- }
-
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor(/*payload_len*/datalen, xDescriptorWaitTime);
-
- if (pxNetworkBuffer != NULL) {
- /* Set the packet size, in case a larger buffer was returned. */
- pxNetworkBuffer->xDataLength = payload_len;
-
- /* Copy the packet data. */
- memcpy(pxNetworkBuffer->pucEthernetBuffer, payload, payload_len);
-
- xRxEvent.pvData = (void *) pxNetworkBuffer;
- if ( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime) == pdFAIL ) {
- wmprintf("Failed to enqueue packet to network stack %p, len %d", payload, payload_len);
- vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
- return WM_FAIL;
- }
- }
- return WM_SUCCESS;
-}
-
-/* Callback function called from the wifi module */
-void handle_data_packet(const t_u8 interface, const t_u8 *rcvdata,
- const t_u16 datalen)
-{
- if (interface == BSS_TYPE_STA)
- process_data_packet(rcvdata, datalen);
-}
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
- uint8_t ret;
- mac_addr_t mac_addr;
-
- ret = wifi_get_device_mac_addr(&mac_addr);
- if (ret != WM_SUCCESS) {
- net_d("Failed to get mac address");
- }
-
- FreeRTOS_UpdateMACAddress(mac_addr.mac);
-
- return ( xInterfaceState == INTERFACE_UP && ret == WM_SUCCESS ) ? pdTRUE : pdFALSE;
-}
-
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
- /* FIX ME. */
-}
-
-BaseType_t xGetPhyLinkStatus( void )
-{
- /* FIX ME. */
- return pdFALSE;
-}
-void vNetworkNotifyIFDown()
-{
- IPStackEvent_t xRxEvent = { eNetworkDownEvent, NULL };
- xInterfaceState = INTERFACE_DOWN;
- if( xSendEventStructToIPTask( &xRxEvent, 0 ) != pdPASS ) {
- /* Could not send the message, so it is still pending. */
- net_e("Could not send network down event");
- }
- else {
- /* Message was sent so it is not pending. */
- net_d("Sent network down event");
- }
-}
-
-void vNetworkNotifyIFUp()
-{
- xInterfaceState = INTERFACE_UP;
-}
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t *const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
-{
- uint8_t pkt_len;
-
- if (pxNetworkBuffer == NULL ||
- pxNetworkBuffer->pucEthernetBuffer == NULL ||
- pxNetworkBuffer->xDataLength == 0) {
- net_d("Incorrect params");
- return pdFALSE;
- }
- memset(outbuf, 0x00, sizeof(outbuf));
- pkt_len = 22 + 4; /* sizeof(TxPD) + INTF_HEADER_LEN */
- memcpy((u8_t *) outbuf + pkt_len, (u8_t *) pxNetworkBuffer->pucEthernetBuffer,
- pxNetworkBuffer->xDataLength);
- int ret = wifi_low_level_output(BSS_TYPE_STA, outbuf + pkt_len, pxNetworkBuffer->xDataLength);
- if (ret != WM_SUCCESS) {
- net_e("Failed output %p, length %d, error %d \r\n", pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, ret);
- }
-
- if (xReleaseAfterSend != pdFALSE) {
- vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
- }
-
- return ret == WM_SUCCESS ? pdTRUE : pdFALSE;
-}
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2018 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 includes. */
+#include "FreeRTOS.h"
+#include "list.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_DNS.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+#include "wifi-decl.h"
+#include "wmerrno.h"
+#include "wifi.h"
+
+#include <wmlog.h>
+
+#define net_e(...) \
+ wmlog_e("freertos_tcp", ##__VA_ARGS__)
+#define net_w(...) \
+ wmlog_w("freertos_tcp", ##__VA_ARGS__)
+#define net_d(...) \
+ wmlog("freertos_tcp", ##__VA_ARGS__)
+
+#if 0 //this is lwip structure.
+#define MAX_INTERFACES_SUPPORTED 3
+static struct netif *netif_arr[MAX_INTERFACES_SUPPORTED];
+#endif
+
+/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
+driver will filter incoming packets and only pass the stack those packets it
+considers need processing. */
+#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
+#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+#else
+#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+#endif
+
+#define IP_ADDR_ANY ((ip_addr_t *)&ip_addr_any)
+#define IP_ADDR_BROADCAST ((ip_addr_t *)&ip_addr_broadcast)
+
+/** 255.255.255.255 */
+#define IPADDR_NONE ((u32_t)0xffffffffUL)
+/** 127.0.0.1 */
+#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL)
+/** 0.0.0.0 */
+#define IPADDR_ANY ((u32_t)0x00000000UL)
+/** 255.255.255.255 */
+#define IPADDR_BROADCAST ((u32_t)0xffffffffUL)
+
+/** 255.255.255.255 */
+#define INADDR_NONE IPADDR_NONE
+/** 127.0.0.1 */
+#define INADDR_LOOPBACK IPADDR_LOOPBACK
+/** 0.0.0.0 */
+#define INADDR_ANY IPADDR_ANY
+/** 255.255.255.255 */
+#define INADDR_BROADCAST IPADDR_BROADCAST
+
+enum if_state_t {
+ INTERFACE_DOWN = 0,
+ INTERFACE_UP,
+};
+struct ip_addr {
+ u32_t addr;
+};
+
+#define MLAN_BSS_TYPE_STA 0
+
+extern uint8_t outbuf[2048];
+extern bool mlan_is_amsdu(const t_u8 *rcvdata);
+extern t_u8 *mlan_get_payload(const t_u8 *rcvdata, t_u16 *payload_len, int *interface);
+extern int wrapper_wlan_handle_amsdu_rx_packet(const t_u8 *rcvdata, const t_u16 datalen);
+extern int wrapper_wlan_handle_rx_packet(const t_u16 datalen, const t_u8 *rcvdata, NetworkBufferDescriptor_t *pxNetworkBuffer);
+static volatile uint32_t xInterfaceState = INTERFACE_DOWN;
+
+static int process_data_packet(const t_u8 *databuf, const t_u16 datalen)
+{
+ int interface = BSS_TYPE_STA;
+ t_u8 *payload = NULL;
+ t_u16 payload_len = 0;
+ const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
+
+ NetworkBufferDescriptor_t *pxNetworkBuffer;
+ IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+
+ payload = (t_u8 *)mlan_get_payload(databuf, &payload_len, &interface);
+
+ if( eConsiderFrameForProcessing( payload ) != eProcessBuffer ) {
+ net_d("Dropping packet\r\n");
+ return WM_SUCCESS;
+ }
+
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor(/*payload_len*/datalen, xDescriptorWaitTime);
+
+ if (pxNetworkBuffer != NULL) {
+ /* Set the packet size, in case a larger buffer was returned. */
+ pxNetworkBuffer->xDataLength = payload_len;
+
+ /* Copy the packet data. */
+ memcpy(pxNetworkBuffer->pucEthernetBuffer, payload, payload_len);
+
+ xRxEvent.pvData = (void *) pxNetworkBuffer;
+ if ( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime) == pdFAIL ) {
+ wmprintf("Failed to enqueue packet to network stack %p, len %d", payload, payload_len);
+ vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
+ return WM_FAIL;
+ }
+ }
+ return WM_SUCCESS;
+}
+
+/* Callback function called from the wifi module */
+void handle_data_packet(const t_u8 interface, const t_u8 *rcvdata,
+ const t_u16 datalen)
+{
+ if (interface == BSS_TYPE_STA)
+ process_data_packet(rcvdata, datalen);
+}
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+ uint8_t ret;
+ mac_addr_t mac_addr;
+
+ ret = wifi_get_device_mac_addr(&mac_addr);
+ if (ret != WM_SUCCESS) {
+ net_d("Failed to get mac address");
+ }
+
+ FreeRTOS_UpdateMACAddress(mac_addr.mac);
+
+ return ( xInterfaceState == INTERFACE_UP && ret == WM_SUCCESS ) ? pdTRUE : pdFALSE;
+}
+
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
+{
+ /* FIX ME. */
+}
+
+BaseType_t xGetPhyLinkStatus( void )
+{
+ /* FIX ME. */
+ return pdFALSE;
+}
+void vNetworkNotifyIFDown()
+{
+ IPStackEvent_t xRxEvent = { eNetworkDownEvent, NULL };
+ xInterfaceState = INTERFACE_DOWN;
+ if( xSendEventStructToIPTask( &xRxEvent, 0 ) != pdPASS ) {
+ /* Could not send the message, so it is still pending. */
+ net_e("Could not send network down event");
+ }
+ else {
+ /* Message was sent so it is not pending. */
+ net_d("Sent network down event");
+ }
+}
+
+void vNetworkNotifyIFUp()
+{
+ xInterfaceState = INTERFACE_UP;
+}
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t *const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
+{
+ uint8_t pkt_len;
+
+ if (pxNetworkBuffer == NULL ||
+ pxNetworkBuffer->pucEthernetBuffer == NULL ||
+ pxNetworkBuffer->xDataLength == 0) {
+ net_d("Incorrect params");
+ return pdFALSE;
+ }
+ memset(outbuf, 0x00, sizeof(outbuf));
+ pkt_len = 22 + 4; /* sizeof(TxPD) + INTF_HEADER_LEN */
+ memcpy((u8_t *) outbuf + pkt_len, (u8_t *) pxNetworkBuffer->pucEthernetBuffer,
+ pxNetworkBuffer->xDataLength);
+ int ret = wifi_low_level_output(BSS_TYPE_STA, outbuf + pkt_len, pxNetworkBuffer->xDataLength);
+ if (ret != WM_SUCCESS) {
+ net_e("Failed output %p, length %d, error %d \r\n", pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, ret);
+ }
+
+ if (xReleaseAfterSend != pdFALSE) {
+ vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
+ }
+
+ return ret == WM_SUCCESS ? pdTRUE : pdFALSE;
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c
index f00ae1fe8..531e878ea 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c
@@ -1,620 +1,620 @@
-/*
- * FreeRTOS+TCP Labs Build 160919 (C) 2016 Real Time Engineers ltd.
- * Authors include Hein Tibosch and Richard Barry
- *
- *******************************************************************************
- ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ***
- *** ***
- *** ***
- *** FREERTOS+TCP IS STILL IN THE LAB (mainly because the FTP and HTTP ***
- *** demos have a dependency on FreeRTOS+FAT, which is only in the Labs ***
- *** download): ***
- *** ***
- *** FreeRTOS+TCP is functional and has been used in commercial products ***
- *** for some time. Be aware however that we are still refining its ***
- *** design, the source code does not yet quite conform to the strict ***
- *** coding and style standards mandated by Real Time Engineers ltd., and ***
- *** the documentation and testing is not necessarily complete. ***
- *** ***
- *** PLEASE REPORT EXPERIENCES USING THE SUPPORT RESOURCES FOUND ON THE ***
- *** URL: http://www.FreeRTOS.org/contact Active early adopters may, at ***
- *** the sole discretion of Real Time Engineers Ltd., be offered versions ***
- *** under a license other than that described below. ***
- *** ***
- *** ***
- ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ***
- *******************************************************************************
- *
- * FreeRTOS+TCP can be used under two different free open source licenses. The
- * license that applies is dependent on the processor on which FreeRTOS+TCP is
- * executed, as follows:
- *
- * If FreeRTOS+TCP is executed on one of the processors listed under the Special
- * License Arrangements heading of the FreeRTOS+TCP license information web
- * page, then it can be used under the terms of the FreeRTOS Open Source
- * License. If FreeRTOS+TCP is used on any other processor, then it can be used
- * under the terms of the GNU General Public License V2. Links to the relevant
- * licenses follow:
- *
- * The FreeRTOS+TCP License Information Page: http://www.FreeRTOS.org/tcp_license
- * The FreeRTOS Open Source License: http://www.FreeRTOS.org/license
- * The GNU General Public License Version 2: http://www.FreeRTOS.org/gpl-2.0.txt
- *
- * FreeRTOS+TCP is distributed in the hope that it will be useful. You cannot
- * use FreeRTOS+TCP unless you agree that you use the software 'as is'.
- * FreeRTOS+TCP is provided WITHOUT ANY WARRANTY; without even the implied
- * warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they
- * implied, expressed, or statutory.
- *
- * 1 tab == 4 spaces!
- *
- * http://www.FreeRTOS.org
- * http://www.FreeRTOS.org/plus
- * http://www.FreeRTOS.org/labs
- *
- */
-
-/******************************************************************************
-*
-* See the following web page for essential buffer allocation scheme usage and
-* configuration details:
-* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html
-*
-******************************************************************************/
-
-/* THIS FILE SHOULD NOT BE USED IF THE PROJECT INCLUDES A MEMORY ALLOCATOR
- * THAT WILL FRAGMENT THE HEAP MEMORY. For example, heap_2 must not be used,
- * heap_4 can be used. */
-
-/* Standard includes. */
-#include <stdint.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkInterface.h"
-#include "NetworkBufferManagement.h"
-
-#include "tcpip/tcpip.h"
-#include "tcpip/src/tcpip_private.h"
-
-#include "NetworkConfig.h"
-
-/* The obtained network buffer must be large enough to hold a packet that might
- * replace the packet that was requested to be sent. */
-#if ipconfigUSE_TCP == 1
- #define baMINIMAL_BUFFER_SIZE sizeof( TCPPacket_t )
-#else
- #define baMINIMAL_BUFFER_SIZE sizeof( ARPPacket_t )
-#endif /* ipconfigUSE_TCP == 1 */
-
-/*_RB_ This is too complex not to have an explanation. */
-#if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
- #define ASSERT_CONCAT_( a, b ) a ## b
- #define ASSERT_CONCAT( a, b ) ASSERT_CONCAT_( a, b )
- #define STATIC_ASSERT( e ) \
- ; enum { ASSERT_CONCAT( assert_line_, __LINE__ ) = 1 / ( !!( e ) ) }
-
- STATIC_ASSERT( ipconfigETHERNET_MINIMUM_PACKET_BYTES <= baMINIMAL_BUFFER_SIZE );
-#endif
-
-/* A list of free (available) NetworkBufferDescriptor_t structures. */
-static List_t xFreeBuffersList;
-
-/* Some statistics about the use of buffers. */
-static size_t uxMinimumFreeNetworkBuffers;
-
-/* Declares the pool of NetworkBufferDescriptor_t structures that are available
- * to the system. All the network buffers referenced from xFreeBuffersList exist
- * in this array. The array is not accessed directly except during initialisation,
- * when the xFreeBuffersList is filled (as all the buffers are free when the system
- * is booted). */
-static NetworkBufferDescriptor_t xNetworkBufferDescriptors[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];
-
-/* This constant is defined as false to let FreeRTOS_TCP_IP.c know that the
- * network buffers have a variable size: resizing may be necessary */
-const BaseType_t xBufferAllocFixedSize = pdFALSE;
-
-/* The semaphore used to obtain network buffers. */
-static SemaphoreHandle_t xNetworkBufferSemaphore = NULL;
-
-/*-----------------------------------------------------------*/
-
-#ifdef PIC32_USE_ETHERNET
-
- /* PIC32 specific stuff */
- /* */
-
- /* MAC packet acknowledgment, once MAC is done with it */
- static bool PIC32_MacPacketAcknowledge( TCPIP_MAC_PACKET * pPkt,
- const void * param );
-
- /* allocates a MAC packet that holds a data buffer that can be used by both: */
- /* - the FreeRTOSIP (NetworkBufferDescriptor_t->pucEthernetBuffer) */
- /* - the Harmony MAC driver: TCPIP_MAC_PACKET->pDSeg->segLoad */
- /* from the beginning of the buffer: */
- /* - 4 bytes pointer to the network descriptor (FreeRTOS) */
- /* - 4 bytes pointer to the MAC packet (pic32_NetworkInterface.c) */
- /* - 2 bytes offset from the MAC packet (Harmony MAC driver: segLoadOffset) */
- /* */
- /* NOTE: segLoadLen should NOT include: */
- /* - the TCPIP_MAC_FRAME_OFFSET (== ipBUFFER_PADDING which should be == 10!) */
- /* - the sizeof(TCPIP_MAC_ETHERNET_HEADER) */
- /* These are added by the MAC packet allocation! */
- /* */
- static uint8_t * PIC32_PktAlloc( uint16_t pktLen,
- uint16_t segLoadLen,
- TCPIP_MAC_PACKET_ACK_FUNC ackF,
- TCPIP_MAC_PACKET ** pPtrPkt )
- {
- uint8_t * pBuff = 0;
-
- /* allocate standard packet */
- TCPIP_MAC_PACKET * pPkt = TCPIP_PKT_PacketAlloc( pktLen, segLoadLen, 0 );
-
- /* set the MAC packet pointer in the packet */
- if( pPkt != 0 )
- {
- pBuff = pPkt->pDSeg->segLoad;
- TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pBuff - PIC32_BUFFER_PKT_PTR_OSSET );
- configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
- *ppkt = pPkt; /* store the packet it comes from */
- pPkt->ackFunc = ackF;
- pPkt->ackParam = 0;
- }
-
- if( pPtrPkt != 0 )
- {
- *pPtrPkt = pPkt;
- }
-
- return pBuff;
- }
-
-
-
- /* standard PIC32 MAC allocation function for a MAC packet */
- /* this packet saves room for the FreeRTOS network descriptor */
- /* at the beginning of the data buffer */
- /* see NetworkBufferAllocate */
- /* Note: flags parameter is ignored since that's used in the Harmony stack only */
- TCPIP_MAC_PACKET * PIC32_MacPacketAllocate( uint16_t pktLen,
- uint16_t segLoadLen,
- TCPIP_MAC_PACKET_FLAGS flags )
- {
- TCPIP_MAC_PACKET * pPkt;
-
- PIC32_PktAlloc( pktLen, segLoadLen, 0, &pPkt );
-
- return pPkt;
- }
-
- /* standard PIC32 MAC packet acknowledgment */
- /* function called once MAC is done with it */
- static bool PIC32_MacPacketAcknowledge( TCPIP_MAC_PACKET * pPkt,
- const void * param )
- {
- configASSERT( ( pPkt != 0 ) );
-
- TCPIP_PKT_PacketFree( pPkt );
-
- return false;
- }
-
- /* associates the current MAC packet with a network descriptor */
- /* mainly for RX packet */
- void PIC32_MacAssociate( TCPIP_MAC_PACKET * pRxPkt,
- NetworkBufferDescriptor_t * pxBufferDescriptor,
- size_t pktLength )
- {
- uint8_t * pPktBuff = pRxPkt->pDSeg->segLoad;
-
- pxBufferDescriptor->pucEthernetBuffer = pPktBuff;
- pxBufferDescriptor->xDataLength = pktLength;
-
- /* make sure this is a properly allocated packet */
- TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pPktBuff - PIC32_BUFFER_PKT_PTR_OSSET );
- configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
-
- if( *ppkt != pRxPkt )
- {
- configASSERT( false );
- }
-
- /* set the proper descriptor info */
- NetworkBufferDescriptor_t ** ppDcpt = ( NetworkBufferDescriptor_t ** ) ( pPktBuff - ipBUFFER_PADDING );
- configASSERT( ( ( uint32_t ) ppDcpt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
- *ppDcpt = pxBufferDescriptor;
- }
-
- /* debug functionality */
- void PIC32_MacPacketOrphan( TCPIP_MAC_PACKET * pPkt )
- {
- TCPIP_PKT_PacketFree( pPkt );
- configASSERT( false );
- }
-
- /* FreeRTOS allocation functions */
-
- /* allocates a buffer that can be used by both: */
- /* - the FreeRTOSIP (NetworkBufferDescriptor_t->pucEthernetBuffer) */
- /* - the Harmony MAC driver: TCPIP_MAC_PACKET */
- /* See PIC32_PktAlloc for details */
- /* */
- /* NOTE: reqLength should NOT include the ipBUFFER_PADDING (which should be == 10!) */
- /* or the sizeof(TCPIP_MAC_ETHERNET_HEADER) */
- /* These are added by the MAC packet allocation! */
- /* */
- uint8_t * NetworkBufferAllocate( size_t reqLength )
- {
- return PIC32_PktAlloc( sizeof( TCPIP_MAC_PACKET ), reqLength, PIC32_MacPacketAcknowledge, 0 );
- }
-
- /* deallocates a network buffer previously allocated */
- /* with NetworkBufferAllocate */
- void NetworkBufferFree( uint8_t * pNetworkBuffer )
- {
- if( pNetworkBuffer != 0 )
- {
- TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pNetworkBuffer - PIC32_BUFFER_PKT_PTR_OSSET );
- configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
- TCPIP_MAC_PACKET * pPkt = *ppkt;
- configASSERT( ( pPkt != 0 ) );
-
- if( pPkt->ackFunc != 0 )
- {
- ( *pPkt->ackFunc )( pPkt, pPkt->ackParam );
- }
- else
- { /* ??? */
- PIC32_MacPacketOrphan( pPkt );
- }
- }
- }
-
-#endif /* #ifdef PIC32_USE_ETHERNET */
-
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkBuffersInitialise( void )
-{
- BaseType_t xReturn, x;
-
- /* Only initialise the buffers and their associated kernel objects if they
- * have not been initialised before. */
- if( xNetworkBufferSemaphore == NULL )
- {
- xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS );
- configASSERT( xNetworkBufferSemaphore );
-
- if( xNetworkBufferSemaphore != NULL )
- {
- #if ( configQUEUE_REGISTRY_SIZE > 0 )
- {
- vQueueAddToRegistry( xNetworkBufferSemaphore, "NetBufSem" );
- }
- #endif /* configQUEUE_REGISTRY_SIZE */
-
- /* If the trace recorder code is included name the semaphore for viewing
- * in FreeRTOS+Trace. */
- #if ( ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 )
- {
- extern QueueHandle_t xNetworkEventQueue;
- vTraceSetQueueName( xNetworkEventQueue, "IPStackEvent" );
- vTraceSetQueueName( xNetworkBufferSemaphore, "NetworkBufferCount" );
- }
- #endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 */
-
- vListInitialise( &xFreeBuffersList );
-
- /* Initialise all the network buffers. No storage is allocated to
- * the buffers yet. */
- for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
- {
- /* Initialise and set the owner of the buffer list items. */
- xNetworkBufferDescriptors[ x ].pucEthernetBuffer = NULL;
- vListInitialiseItem( &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
- listSET_LIST_ITEM_OWNER( &( xNetworkBufferDescriptors[ x ].xBufferListItem ), &xNetworkBufferDescriptors[ x ] );
-
- /* Currently, all buffers are available for use. */
- vListInsert( &xFreeBuffersList, &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
- }
-
- uxMinimumFreeNetworkBuffers = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS;
- }
- }
-
- if( xNetworkBufferSemaphore == NULL )
- {
- xReturn = pdFAIL;
- }
- else
- {
- xReturn = pdPASS;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-uint8_t * pucGetNetworkBuffer( size_t * pxRequestedSizeBytes )
-{
- uint8_t * pucEthernetBuffer;
- size_t xSize = *pxRequestedSizeBytes;
-
- if( xSize < baMINIMAL_BUFFER_SIZE )
- {
- /* Buffers must be at least large enough to hold a TCP-packet with
- * headers, or an ARP packet, in case TCP is not included. */
- xSize = baMINIMAL_BUFFER_SIZE;
- }
-
- /* Round up xSize to the nearest multiple of N bytes,
- * where N equals 'sizeof( size_t )'. */
- if( ( xSize & ( sizeof( size_t ) - 1u ) ) != 0u )
- {
- xSize = ( xSize | ( sizeof( size_t ) - 1u ) ) + 1u;
- }
-
- *pxRequestedSizeBytes = xSize;
-
- /* Allocate a buffer large enough to store the requested Ethernet frame size
- * and a pointer to a network buffer structure (hence the addition of
- * ipBUFFER_PADDING bytes). */
-
- #ifdef PIC32_USE_ETHERNET
- pucEthernetBuffer = NetworkBufferAllocate( xSize - sizeof( TCPIP_MAC_ETHERNET_HEADER ) );
- #else
- pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xSize + ipBUFFER_PADDING );
- #endif /* #ifdef PIC32_USE_ETHERNET */
-
- configASSERT( pucEthernetBuffer );
-
- if( pucEthernetBuffer != NULL )
- {
- /* Enough space is left at the start of the buffer to place a pointer to
- * the network buffer structure that references this Ethernet buffer.
- * Return a pointer to the start of the Ethernet buffer itself. */
- #ifndef PIC32_USE_ETHERNET
- pucEthernetBuffer += ipBUFFER_PADDING;
- #endif /* #ifndef PIC32_USE_ETHERNET */
- }
-
- return pucEthernetBuffer;
-}
-/*-----------------------------------------------------------*/
-
-void vReleaseNetworkBuffer( uint8_t * pucEthernetBuffer )
-{
- /* There is space before the Ethernet buffer in which a pointer to the
- * network buffer that references this Ethernet buffer is stored. Remove the
- * space before freeing the buffer. */
- #ifdef PIC32_USE_ETHERNET
- NetworkBufferFree( pucEthernetBuffer );
- #else
- if( pucEthernetBuffer != NULL )
- {
- pucEthernetBuffer -= ipBUFFER_PADDING;
- vPortFree( ( void * ) pucEthernetBuffer );
- }
- #endif /* #ifdef PIC32_USE_ETHERNET */
-}
-/*-----------------------------------------------------------*/
-
-NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes,
- TickType_t xBlockTimeTicks )
-{
- NetworkBufferDescriptor_t * pxReturn = NULL;
- size_t uxCount;
-
- if( ( xRequestedSizeBytes != 0u ) && ( xRequestedSizeBytes < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
- {
- /* ARP packets can replace application packets, so the storage must be
- * at least large enough to hold an ARP. */
- xRequestedSizeBytes = baMINIMAL_BUFFER_SIZE;
- }
-
- #ifdef PIC32_USE_ETHERNET
- if( xRequestedSizeBytes != 0u )
- {
- #endif /* #ifdef PIC32_USE_ETHERNET */
- xRequestedSizeBytes += 2u;
-
- if( ( xRequestedSizeBytes & ( sizeof( size_t ) - 1u ) ) != 0u )
- {
- xRequestedSizeBytes = ( xRequestedSizeBytes | ( sizeof( size_t ) - 1u ) ) + 1u;
- }
- #ifdef PIC32_USE_ETHERNET
- }
- #endif /* #ifdef PIC32_USE_ETHERNET */
-
- /* 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 );
- 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. */
-
- #ifdef PIC32_USE_ETHERNET
- pxReturn->pucEthernetBuffer = NetworkBufferAllocate( xRequestedSizeBytes - sizeof( TCPIP_MAC_ETHERNET_HEADER ) );
- #else
- pxReturn->pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xRequestedSizeBytes + ipBUFFER_PADDING );
- #endif /* #ifdef PIC32_USE_ETHERNET */
-
- 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. */
- #ifdef PIC32_USE_ETHERNET
- *( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer - ipBUFFER_PADDING ) ) = pxReturn;
- #else
- *( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer ) ) = pxReturn;
- pxReturn->pucEthernetBuffer += ipBUFFER_PADDING;
- #endif /* #ifdef PIC32_USE_ETHERNET */
-
- /* 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 )
- {
- iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER();
- }
- else
- {
- iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
- }
-
- return pxReturn;
-}
-/*-----------------------------------------------------------*/
-
-void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
-{
- BaseType_t xListItemAlreadyInFreeList;
-
- /* Ensure the buffer is returned to the list of free buffers before the
- * counting semaphore is 'given' to say a buffer is available. Release the
- * storage allocated to the buffer payload. THIS FILE SHOULD NOT BE USED
- * IF THE PROJECT INCLUDES A MEMORY ALLOCATOR THAT WILL FRAGMENT THE HEAP
- * MEMORY. For example, heap_2 must not be used, heap_4 can be used. */
- vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
- pxNetworkBuffer->pucEthernetBuffer = NULL;
-
- taskENTER_CRITICAL();
- {
- xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
-
- if( xListItemAlreadyInFreeList == pdFALSE )
- {
- vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
- }
- }
- taskEXIT_CRITICAL();
-
- /*
- * Update the network state machine, unless the program fails to release its 'xNetworkBufferSemaphore'.
- * The program should only try to release its semaphore if 'xListItemAlreadyInFreeList' is false.
- */
- if( xListItemAlreadyInFreeList == pdFALSE )
- {
- if ( xSemaphoreGive( xNetworkBufferSemaphore ) == pdTRUE )
- {
- iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
- }
- }
- else
- {
- iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
- }
-}
-/*-----------------------------------------------------------*/
-
-/*
- * Returns the number of free network buffers
- */
-UBaseType_t uxGetNumberOfFreeNetworkBuffers( void )
-{
- return listCURRENT_LIST_LENGTH( &xFreeBuffersList );
-}
-/*-----------------------------------------------------------*/
-
-UBaseType_t uxGetMinimumFreeNetworkBuffers( void )
-{
- return uxMinimumFreeNetworkBuffers;
-}
-/*-----------------------------------------------------------*/
-
-NetworkBufferDescriptor_t * pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer,
- size_t xNewSizeBytes )
-{
- size_t xOriginalLength;
- uint8_t * pucBuffer;
-
- #ifdef PIC32_USE_ETHERNET
- xOriginalLength = pxNetworkBuffer->xDataLength;
- #else
- xOriginalLength = pxNetworkBuffer->xDataLength + ipBUFFER_PADDING;
- xNewSizeBytes = xNewSizeBytes + ipBUFFER_PADDING;
- #endif /* #ifdef PIC32_USE_ETHERNET */
-
- pucBuffer = pucGetNetworkBuffer( &( xNewSizeBytes ) );
-
- if( pucBuffer == NULL )
- {
- /* In case the allocation fails, return NULL. */
- pxNetworkBuffer = NULL;
- }
- else
- {
- pxNetworkBuffer->xDataLength = xNewSizeBytes;
- if( xNewSizeBytes > xOriginalLength )
- {
- xNewSizeBytes = xOriginalLength;
- }
-
- #ifdef PIC32_USE_ETHERNET
- memcpy( pucBuffer, pxNetworkBuffer->pucEthernetBuffer, xNewSizeBytes );
- *( ( NetworkBufferDescriptor_t ** ) ( pucBuffer - ipBUFFER_PADDING ) ) = pxNetworkBuffer;
- #else
- memcpy( pucBuffer - ipBUFFER_PADDING, pxNetworkBuffer->pucEthernetBuffer - ipBUFFER_PADDING, xNewSizeBytes );
- #endif /* #ifdef PIC32_USE_ETHERNET */
-
- vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
- pxNetworkBuffer->pucEthernetBuffer = pucBuffer;
- }
-
- return pxNetworkBuffer;
-}
+/*
+ * FreeRTOS+TCP Labs Build 160919 (C) 2016 Real Time Engineers ltd.
+ * Authors include Hein Tibosch and Richard Barry
+ *
+ *******************************************************************************
+ ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ***
+ *** ***
+ *** ***
+ *** FREERTOS+TCP IS STILL IN THE LAB (mainly because the FTP and HTTP ***
+ *** demos have a dependency on FreeRTOS+FAT, which is only in the Labs ***
+ *** download): ***
+ *** ***
+ *** FreeRTOS+TCP is functional and has been used in commercial products ***
+ *** for some time. Be aware however that we are still refining its ***
+ *** design, the source code does not yet quite conform to the strict ***
+ *** coding and style standards mandated by Real Time Engineers ltd., and ***
+ *** the documentation and testing is not necessarily complete. ***
+ *** ***
+ *** PLEASE REPORT EXPERIENCES USING THE SUPPORT RESOURCES FOUND ON THE ***
+ *** URL: http://www.FreeRTOS.org/contact Active early adopters may, at ***
+ *** the sole discretion of Real Time Engineers Ltd., be offered versions ***
+ *** under a license other than that described below. ***
+ *** ***
+ *** ***
+ ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ***
+ *******************************************************************************
+ *
+ * FreeRTOS+TCP can be used under two different free open source licenses. The
+ * license that applies is dependent on the processor on which FreeRTOS+TCP is
+ * executed, as follows:
+ *
+ * If FreeRTOS+TCP is executed on one of the processors listed under the Special
+ * License Arrangements heading of the FreeRTOS+TCP license information web
+ * page, then it can be used under the terms of the FreeRTOS Open Source
+ * License. If FreeRTOS+TCP is used on any other processor, then it can be used
+ * under the terms of the GNU General Public License V2. Links to the relevant
+ * licenses follow:
+ *
+ * The FreeRTOS+TCP License Information Page: http://www.FreeRTOS.org/tcp_license
+ * The FreeRTOS Open Source License: http://www.FreeRTOS.org/license
+ * The GNU General Public License Version 2: http://www.FreeRTOS.org/gpl-2.0.txt
+ *
+ * FreeRTOS+TCP is distributed in the hope that it will be useful. You cannot
+ * use FreeRTOS+TCP unless you agree that you use the software 'as is'.
+ * FreeRTOS+TCP is provided WITHOUT ANY WARRANTY; without even the implied
+ * warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they
+ * implied, expressed, or statutory.
+ *
+ * 1 tab == 4 spaces!
+ *
+ * http://www.FreeRTOS.org
+ * http://www.FreeRTOS.org/plus
+ * http://www.FreeRTOS.org/labs
+ *
+ */
+
+/******************************************************************************
+*
+* See the following web page for essential buffer allocation scheme usage and
+* configuration details:
+* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html
+*
+******************************************************************************/
+
+/* THIS FILE SHOULD NOT BE USED IF THE PROJECT INCLUDES A MEMORY ALLOCATOR
+ * THAT WILL FRAGMENT THE HEAP MEMORY. For example, heap_2 must not be used,
+ * heap_4 can be used. */
+
+/* Standard includes. */
+#include <stdint.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkInterface.h"
+#include "NetworkBufferManagement.h"
+
+#include "tcpip/tcpip.h"
+#include "tcpip/src/tcpip_private.h"
+
+#include "NetworkConfig.h"
+
+/* The obtained network buffer must be large enough to hold a packet that might
+ * replace the packet that was requested to be sent. */
+#if ipconfigUSE_TCP == 1
+ #define baMINIMAL_BUFFER_SIZE sizeof( TCPPacket_t )
+#else
+ #define baMINIMAL_BUFFER_SIZE sizeof( ARPPacket_t )
+#endif /* ipconfigUSE_TCP == 1 */
+
+/*_RB_ This is too complex not to have an explanation. */
+#if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
+ #define ASSERT_CONCAT_( a, b ) a ## b
+ #define ASSERT_CONCAT( a, b ) ASSERT_CONCAT_( a, b )
+ #define STATIC_ASSERT( e ) \
+ ; enum { ASSERT_CONCAT( assert_line_, __LINE__ ) = 1 / ( !!( e ) ) }
+
+ STATIC_ASSERT( ipconfigETHERNET_MINIMUM_PACKET_BYTES <= baMINIMAL_BUFFER_SIZE );
+#endif
+
+/* A list of free (available) NetworkBufferDescriptor_t structures. */
+static List_t xFreeBuffersList;
+
+/* Some statistics about the use of buffers. */
+static size_t uxMinimumFreeNetworkBuffers;
+
+/* Declares the pool of NetworkBufferDescriptor_t structures that are available
+ * to the system. All the network buffers referenced from xFreeBuffersList exist
+ * in this array. The array is not accessed directly except during initialisation,
+ * when the xFreeBuffersList is filled (as all the buffers are free when the system
+ * is booted). */
+static NetworkBufferDescriptor_t xNetworkBufferDescriptors[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];
+
+/* This constant is defined as false to let FreeRTOS_TCP_IP.c know that the
+ * network buffers have a variable size: resizing may be necessary */
+const BaseType_t xBufferAllocFixedSize = pdFALSE;
+
+/* The semaphore used to obtain network buffers. */
+static SemaphoreHandle_t xNetworkBufferSemaphore = NULL;
+
+/*-----------------------------------------------------------*/
+
+#ifdef PIC32_USE_ETHERNET
+
+ /* PIC32 specific stuff */
+ /* */
+
+ /* MAC packet acknowledgment, once MAC is done with it */
+ static bool PIC32_MacPacketAcknowledge( TCPIP_MAC_PACKET * pPkt,
+ const void * param );
+
+ /* allocates a MAC packet that holds a data buffer that can be used by both: */
+ /* - the FreeRTOSIP (NetworkBufferDescriptor_t->pucEthernetBuffer) */
+ /* - the Harmony MAC driver: TCPIP_MAC_PACKET->pDSeg->segLoad */
+ /* from the beginning of the buffer: */
+ /* - 4 bytes pointer to the network descriptor (FreeRTOS) */
+ /* - 4 bytes pointer to the MAC packet (pic32_NetworkInterface.c) */
+ /* - 2 bytes offset from the MAC packet (Harmony MAC driver: segLoadOffset) */
+ /* */
+ /* NOTE: segLoadLen should NOT include: */
+ /* - the TCPIP_MAC_FRAME_OFFSET (== ipBUFFER_PADDING which should be == 10!) */
+ /* - the sizeof(TCPIP_MAC_ETHERNET_HEADER) */
+ /* These are added by the MAC packet allocation! */
+ /* */
+ static uint8_t * PIC32_PktAlloc( uint16_t pktLen,
+ uint16_t segLoadLen,
+ TCPIP_MAC_PACKET_ACK_FUNC ackF,
+ TCPIP_MAC_PACKET ** pPtrPkt )
+ {
+ uint8_t * pBuff = 0;
+
+ /* allocate standard packet */
+ TCPIP_MAC_PACKET * pPkt = TCPIP_PKT_PacketAlloc( pktLen, segLoadLen, 0 );
+
+ /* set the MAC packet pointer in the packet */
+ if( pPkt != 0 )
+ {
+ pBuff = pPkt->pDSeg->segLoad;
+ TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pBuff - PIC32_BUFFER_PKT_PTR_OSSET );
+ configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
+ *ppkt = pPkt; /* store the packet it comes from */
+ pPkt->ackFunc = ackF;
+ pPkt->ackParam = 0;
+ }
+
+ if( pPtrPkt != 0 )
+ {
+ *pPtrPkt = pPkt;
+ }
+
+ return pBuff;
+ }
+
+
+
+ /* standard PIC32 MAC allocation function for a MAC packet */
+ /* this packet saves room for the FreeRTOS network descriptor */
+ /* at the beginning of the data buffer */
+ /* see NetworkBufferAllocate */
+ /* Note: flags parameter is ignored since that's used in the Harmony stack only */
+ TCPIP_MAC_PACKET * PIC32_MacPacketAllocate( uint16_t pktLen,
+ uint16_t segLoadLen,
+ TCPIP_MAC_PACKET_FLAGS flags )
+ {
+ TCPIP_MAC_PACKET * pPkt;
+
+ PIC32_PktAlloc( pktLen, segLoadLen, 0, &pPkt );
+
+ return pPkt;
+ }
+
+ /* standard PIC32 MAC packet acknowledgment */
+ /* function called once MAC is done with it */
+ static bool PIC32_MacPacketAcknowledge( TCPIP_MAC_PACKET * pPkt,
+ const void * param )
+ {
+ configASSERT( ( pPkt != 0 ) );
+
+ TCPIP_PKT_PacketFree( pPkt );
+
+ return false;
+ }
+
+ /* associates the current MAC packet with a network descriptor */
+ /* mainly for RX packet */
+ void PIC32_MacAssociate( TCPIP_MAC_PACKET * pRxPkt,
+ NetworkBufferDescriptor_t * pxBufferDescriptor,
+ size_t pktLength )
+ {
+ uint8_t * pPktBuff = pRxPkt->pDSeg->segLoad;
+
+ pxBufferDescriptor->pucEthernetBuffer = pPktBuff;
+ pxBufferDescriptor->xDataLength = pktLength;
+
+ /* make sure this is a properly allocated packet */
+ TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pPktBuff - PIC32_BUFFER_PKT_PTR_OSSET );
+ configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
+
+ if( *ppkt != pRxPkt )
+ {
+ configASSERT( false );
+ }
+
+ /* set the proper descriptor info */
+ NetworkBufferDescriptor_t ** ppDcpt = ( NetworkBufferDescriptor_t ** ) ( pPktBuff - ipBUFFER_PADDING );
+ configASSERT( ( ( uint32_t ) ppDcpt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
+ *ppDcpt = pxBufferDescriptor;
+ }
+
+ /* debug functionality */
+ void PIC32_MacPacketOrphan( TCPIP_MAC_PACKET * pPkt )
+ {
+ TCPIP_PKT_PacketFree( pPkt );
+ configASSERT( false );
+ }
+
+ /* FreeRTOS allocation functions */
+
+ /* allocates a buffer that can be used by both: */
+ /* - the FreeRTOSIP (NetworkBufferDescriptor_t->pucEthernetBuffer) */
+ /* - the Harmony MAC driver: TCPIP_MAC_PACKET */
+ /* See PIC32_PktAlloc for details */
+ /* */
+ /* NOTE: reqLength should NOT include the ipBUFFER_PADDING (which should be == 10!) */
+ /* or the sizeof(TCPIP_MAC_ETHERNET_HEADER) */
+ /* These are added by the MAC packet allocation! */
+ /* */
+ uint8_t * NetworkBufferAllocate( size_t reqLength )
+ {
+ return PIC32_PktAlloc( sizeof( TCPIP_MAC_PACKET ), reqLength, PIC32_MacPacketAcknowledge, 0 );
+ }
+
+ /* deallocates a network buffer previously allocated */
+ /* with NetworkBufferAllocate */
+ void NetworkBufferFree( uint8_t * pNetworkBuffer )
+ {
+ if( pNetworkBuffer != 0 )
+ {
+ TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pNetworkBuffer - PIC32_BUFFER_PKT_PTR_OSSET );
+ configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
+ TCPIP_MAC_PACKET * pPkt = *ppkt;
+ configASSERT( ( pPkt != 0 ) );
+
+ if( pPkt->ackFunc != 0 )
+ {
+ ( *pPkt->ackFunc )( pPkt, pPkt->ackParam );
+ }
+ else
+ { /* ??? */
+ PIC32_MacPacketOrphan( pPkt );
+ }
+ }
+ }
+
+#endif /* #ifdef PIC32_USE_ETHERNET */
+
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkBuffersInitialise( void )
+{
+ BaseType_t xReturn, x;
+
+ /* Only initialise the buffers and their associated kernel objects if they
+ * have not been initialised before. */
+ if( xNetworkBufferSemaphore == NULL )
+ {
+ xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS );
+ configASSERT( xNetworkBufferSemaphore );
+
+ if( xNetworkBufferSemaphore != NULL )
+ {
+ #if ( configQUEUE_REGISTRY_SIZE > 0 )
+ {
+ vQueueAddToRegistry( xNetworkBufferSemaphore, "NetBufSem" );
+ }
+ #endif /* configQUEUE_REGISTRY_SIZE */
+
+ /* If the trace recorder code is included name the semaphore for viewing
+ * in FreeRTOS+Trace. */
+ #if ( ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 )
+ {
+ extern QueueHandle_t xNetworkEventQueue;
+ vTraceSetQueueName( xNetworkEventQueue, "IPStackEvent" );
+ vTraceSetQueueName( xNetworkBufferSemaphore, "NetworkBufferCount" );
+ }
+ #endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 */
+
+ vListInitialise( &xFreeBuffersList );
+
+ /* Initialise all the network buffers. No storage is allocated to
+ * the buffers yet. */
+ for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
+ {
+ /* Initialise and set the owner of the buffer list items. */
+ xNetworkBufferDescriptors[ x ].pucEthernetBuffer = NULL;
+ vListInitialiseItem( &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
+ listSET_LIST_ITEM_OWNER( &( xNetworkBufferDescriptors[ x ].xBufferListItem ), &xNetworkBufferDescriptors[ x ] );
+
+ /* Currently, all buffers are available for use. */
+ vListInsert( &xFreeBuffersList, &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
+ }
+
+ uxMinimumFreeNetworkBuffers = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS;
+ }
+ }
+
+ if( xNetworkBufferSemaphore == NULL )
+ {
+ xReturn = pdFAIL;
+ }
+ else
+ {
+ xReturn = pdPASS;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+uint8_t * pucGetNetworkBuffer( size_t * pxRequestedSizeBytes )
+{
+ uint8_t * pucEthernetBuffer;
+ size_t xSize = *pxRequestedSizeBytes;
+
+ if( xSize < baMINIMAL_BUFFER_SIZE )
+ {
+ /* Buffers must be at least large enough to hold a TCP-packet with
+ * headers, or an ARP packet, in case TCP is not included. */
+ xSize = baMINIMAL_BUFFER_SIZE;
+ }
+
+ /* Round up xSize to the nearest multiple of N bytes,
+ * where N equals 'sizeof( size_t )'. */
+ if( ( xSize & ( sizeof( size_t ) - 1u ) ) != 0u )
+ {
+ xSize = ( xSize | ( sizeof( size_t ) - 1u ) ) + 1u;
+ }
+
+ *pxRequestedSizeBytes = xSize;
+
+ /* Allocate a buffer large enough to store the requested Ethernet frame size
+ * and a pointer to a network buffer structure (hence the addition of
+ * ipBUFFER_PADDING bytes). */
+
+ #ifdef PIC32_USE_ETHERNET
+ pucEthernetBuffer = NetworkBufferAllocate( xSize - sizeof( TCPIP_MAC_ETHERNET_HEADER ) );
+ #else
+ pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xSize + ipBUFFER_PADDING );
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+
+ configASSERT( pucEthernetBuffer );
+
+ if( pucEthernetBuffer != NULL )
+ {
+ /* Enough space is left at the start of the buffer to place a pointer to
+ * the network buffer structure that references this Ethernet buffer.
+ * Return a pointer to the start of the Ethernet buffer itself. */
+ #ifndef PIC32_USE_ETHERNET
+ pucEthernetBuffer += ipBUFFER_PADDING;
+ #endif /* #ifndef PIC32_USE_ETHERNET */
+ }
+
+ return pucEthernetBuffer;
+}
+/*-----------------------------------------------------------*/
+
+void vReleaseNetworkBuffer( uint8_t * pucEthernetBuffer )
+{
+ /* There is space before the Ethernet buffer in which a pointer to the
+ * network buffer that references this Ethernet buffer is stored. Remove the
+ * space before freeing the buffer. */
+ #ifdef PIC32_USE_ETHERNET
+ NetworkBufferFree( pucEthernetBuffer );
+ #else
+ if( pucEthernetBuffer != NULL )
+ {
+ pucEthernetBuffer -= ipBUFFER_PADDING;
+ vPortFree( ( void * ) pucEthernetBuffer );
+ }
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+}
+/*-----------------------------------------------------------*/
+
+NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes,
+ TickType_t xBlockTimeTicks )
+{
+ NetworkBufferDescriptor_t * pxReturn = NULL;
+ size_t uxCount;
+
+ if( ( xRequestedSizeBytes != 0u ) && ( xRequestedSizeBytes < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
+ {
+ /* ARP packets can replace application packets, so the storage must be
+ * at least large enough to hold an ARP. */
+ xRequestedSizeBytes = baMINIMAL_BUFFER_SIZE;
+ }
+
+ #ifdef PIC32_USE_ETHERNET
+ if( xRequestedSizeBytes != 0u )
+ {
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+ xRequestedSizeBytes += 2u;
+
+ if( ( xRequestedSizeBytes & ( sizeof( size_t ) - 1u ) ) != 0u )
+ {
+ xRequestedSizeBytes = ( xRequestedSizeBytes | ( sizeof( size_t ) - 1u ) ) + 1u;
+ }
+ #ifdef PIC32_USE_ETHERNET
+ }
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+
+ /* 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 );
+ 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. */
+
+ #ifdef PIC32_USE_ETHERNET
+ pxReturn->pucEthernetBuffer = NetworkBufferAllocate( xRequestedSizeBytes - sizeof( TCPIP_MAC_ETHERNET_HEADER ) );
+ #else
+ pxReturn->pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xRequestedSizeBytes + ipBUFFER_PADDING );
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+
+ 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. */
+ #ifdef PIC32_USE_ETHERNET
+ *( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer - ipBUFFER_PADDING ) ) = pxReturn;
+ #else
+ *( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer ) ) = pxReturn;
+ pxReturn->pucEthernetBuffer += ipBUFFER_PADDING;
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+
+ /* 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 )
+ {
+ iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER();
+ }
+ else
+ {
+ iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
+ }
+
+ return pxReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
+{
+ BaseType_t xListItemAlreadyInFreeList;
+
+ /* Ensure the buffer is returned to the list of free buffers before the
+ * counting semaphore is 'given' to say a buffer is available. Release the
+ * storage allocated to the buffer payload. THIS FILE SHOULD NOT BE USED
+ * IF THE PROJECT INCLUDES A MEMORY ALLOCATOR THAT WILL FRAGMENT THE HEAP
+ * MEMORY. For example, heap_2 must not be used, heap_4 can be used. */
+ vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
+ pxNetworkBuffer->pucEthernetBuffer = NULL;
+
+ taskENTER_CRITICAL();
+ {
+ xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
+
+ if( xListItemAlreadyInFreeList == pdFALSE )
+ {
+ vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
+ }
+ }
+ taskEXIT_CRITICAL();
+
+ /*
+ * Update the network state machine, unless the program fails to release its 'xNetworkBufferSemaphore'.
+ * The program should only try to release its semaphore if 'xListItemAlreadyInFreeList' is false.
+ */
+ if( xListItemAlreadyInFreeList == pdFALSE )
+ {
+ if ( xSemaphoreGive( xNetworkBufferSemaphore ) == pdTRUE )
+ {
+ iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
+ }
+ }
+ else
+ {
+ iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
+ }
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Returns the number of free network buffers
+ */
+UBaseType_t uxGetNumberOfFreeNetworkBuffers( void )
+{
+ return listCURRENT_LIST_LENGTH( &xFreeBuffersList );
+}
+/*-----------------------------------------------------------*/
+
+UBaseType_t uxGetMinimumFreeNetworkBuffers( void )
+{
+ return uxMinimumFreeNetworkBuffers;
+}
+/*-----------------------------------------------------------*/
+
+NetworkBufferDescriptor_t * pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer,
+ size_t xNewSizeBytes )
+{
+ size_t xOriginalLength;
+ uint8_t * pucBuffer;
+
+ #ifdef PIC32_USE_ETHERNET
+ xOriginalLength = pxNetworkBuffer->xDataLength;
+ #else
+ xOriginalLength = pxNetworkBuffer->xDataLength + ipBUFFER_PADDING;
+ xNewSizeBytes = xNewSizeBytes + ipBUFFER_PADDING;
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+
+ pucBuffer = pucGetNetworkBuffer( &( xNewSizeBytes ) );
+
+ if( pucBuffer == NULL )
+ {
+ /* In case the allocation fails, return NULL. */
+ pxNetworkBuffer = NULL;
+ }
+ else
+ {
+ pxNetworkBuffer->xDataLength = xNewSizeBytes;
+ if( xNewSizeBytes > xOriginalLength )
+ {
+ xNewSizeBytes = xOriginalLength;
+ }
+
+ #ifdef PIC32_USE_ETHERNET
+ memcpy( pucBuffer, pxNetworkBuffer->pucEthernetBuffer, xNewSizeBytes );
+ *( ( NetworkBufferDescriptor_t ** ) ( pucBuffer - ipBUFFER_PADDING ) ) = pxNetworkBuffer;
+ #else
+ memcpy( pucBuffer - ipBUFFER_PADDING, pxNetworkBuffer->pucEthernetBuffer - ipBUFFER_PADDING, xNewSizeBytes );
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+
+ vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
+ pxNetworkBuffer->pucEthernetBuffer = pucBuffer;
+ }
+
+ return pxNetworkBuffer;
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c
index 5fe4438bd..1b7584c44 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c
@@ -1,889 +1,889 @@
-/*******************************************************************************
-* Network Interface file
-*
-* Summary:
-* Network Interface file for FreeRTOS-Plus-TCP stack
-*
-* Description:
-* - Interfaces PIC32 to the FreeRTOS TCP/IP stack
-*******************************************************************************/
-
-/*******************************************************************************
-* File Name: pic32_NetworkInterface.c
-* Copyright 2017 Microchip Technology Incorporated and its subsidiaries.
-*
-* 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
-*******************************************************************************/
-#include <sys/kmem.h>
-
-#include "FreeRTOS.h"
-#include "semphr.h"
-#include "event_groups.h"
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_IP_Private.h"
-
-#include "NetworkInterface.h"
-#include "NetworkBufferManagement.h"
-
-
-#include "NetworkInterface.h"
-#include "NetworkConfig.h"
-
-#include "peripheral/eth/plib_eth.h"
-
-#include "system_config.h"
-#include "system/console/sys_console.h"
-#include "system/debug/sys_debug.h"
-#include "system/command/sys_command.h"
-
-#include "driver/ethmac/drv_ethmac.h"
-#include "driver/miim/drv_miim.h"
-
-#include "tcpip/tcpip.h"
-#include "tcpip/src/tcpip_private.h"
-#include "tcpip/src/link_list.h"
-
-#ifdef PIC32_USE_ETHERNET
-
- /* local definitions and data */
-
- /* debug messages */
- #if ( PIC32_MAC_DEBUG_MESSAGES != 0 )
- #define PIC32_MAC_DbgPrint( format, ... ) SYS_CONSOLE_PRINT( format, ## __VA_ARGS__ )
- #else
- #define PIC32_MAC_DbgPrint( format, ... )
- #endif /* (PIC32_MAC_DEBUG_MESSAGES != 0) */
-
- typedef enum
- {
- PIC32_MAC_EVENT_INIT_NONE = 0x000, /* no event/invalid */
-
- PIC32_MAC_EVENT_INIT_DONE = 0x001, /* initialization done event */
- PIC32_MAC_EVENT_TIMEOUT = 0x002, /* periodic timeout event */
- PIC32_MAC_EVENT_IF_PENDING = 0x004, /* an interface event signal: RX, TX, errors. etc. */
- } PIC32_MAC_EVENT_TYPE;
-
- typedef enum
- {
- eMACInit, /* Must initialise MAC. */
- eMACPass, /* Initialisation was successful. */
- eMACFailed, /* Initialisation failed. */
- } eMAC_INIT_STATUS_TYPE;
-
- static TCPIP_STACK_HEAP_HANDLE macHeapHandle;
-
- static const TCPIP_MAC_OBJECT * macObject; /* the one and only MAC object; */
-
- static SYS_MODULE_OBJ macObjHandle; /* the MAC object instance, obtained at initialization */
- static TCPIP_MAC_HANDLE macCliHandle; /* client handle */
- static volatile SYS_STATUS macObjStatus; /* current MAC status */
-
- static TaskHandle_t macTaskHandle;
-
- static TimerHandle_t macTmrHandle;
-
- static bool macLinkStatus; /* true if link is ON */
-
- static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
-
- /* local prototypes */
- static bool StartInitMac( void );
- static void StartInitCleanup( void );
-
- static void SetMacCtrl( TCPIP_MAC_MODULE_CTRL * pMacCtrl );
-
- static bool MacSyncFunction( void * synchHandle,
- TCPIP_MAC_SYNCH_REQUEST req );
-
- /* the PIC32 MAC task function */
- static void MacHandlerTask( void * params );
-
- /* MAC interrupt event function */
- static void MAC_EventFunction( TCPIP_MAC_EVENT event,
- const void * eventParam );
-
- /* timer callback for link maintenance, etc; */
- static void MacTmrCallback( TimerHandle_t xTimer );
-
- /* MAC RX packets functions */
- static void MacRxPackets( void );
- static void MacProcessRxPacket( TCPIP_MAC_PACKET * pRxPkt );
-
-
- /* memory allocation mapping to FreeRTOS */
- static void * _malloc( size_t nBytes )
- {
- return pvPortMalloc( nBytes );
- }
-
- /*-----------------------------------------------------------*/
-
- static void * _calloc( size_t nElems,
- size_t elemSize )
- {
- size_t nBytes = nElems * elemSize;
-
- void * ptr = pvPortMalloc( nBytes );
-
- if( ptr != 0 )
- {
- memset( ptr, 0, nBytes );
- }
-
- return ptr;
- }
-
- /*-----------------------------------------------------------*/
-
- static void _free( void * pBuff )
- {
- vPortFree( pBuff );
- }
-
- /* extern references */
- /* */
- /* use the configuration data from the system_init.c */
- extern const TCPIP_NETWORK_CONFIG TCPIP_HOSTS_CONFIGURATION[];
-
- /* BufferAllocation_2.c:: packet allocation function */
- extern TCPIP_MAC_PACKET * PIC32_MacPacketAllocate( uint16_t pktLen,
- uint16_t segLoadLen,
- TCPIP_MAC_PACKET_FLAGS flags );
-
- extern void PIC32_MacAssociate( TCPIP_MAC_PACKET * pRxPkt,
- NetworkBufferDescriptor_t * pxBufferDescriptor,
- size_t pktLength );
- extern void PIC32_MacPacketOrphan( TCPIP_MAC_PACKET * pPkt );
-
- /* cannot use the system_init.c::tcpipHeapConfig because FreeRTOS does not have a calloc function! */
- /* we build it here! */
-
- /* make sure we're running with external heap! Redirect to FreeRTOS. */
- #if !defined( TCPIP_STACK_USE_EXTERNAL_HEAP ) || defined( TCPIP_STACK_USE_INTERNAL_HEAP ) || defined( TCPIP_STACK_USE_INTERNAL_HEAP_POOL )
- #error "TCPIP_STACK_USE_EXTERNAL_HEAP should be defined for this project!"
- #endif
-
- static const TCPIP_STACK_HEAP_EXTERNAL_CONFIG tcpipHeapConfig =
- {
- .heapType = TCPIP_STACK_HEAP_TYPE_EXTERNAL_HEAP,
- .heapFlags = TCPIP_STACK_HEAP_FLAG_ALLOC_UNCACHED | TCPIP_STACK_HEAP_FLAG_NO_MTHREAD_SYNC,
- .heapUsage = TCPIP_STACK_HEAP_USE_DEFAULT,
- .malloc_fnc = _malloc,
- .calloc_fnc = _calloc,
- .free_fnc = _free,
- };
-
- #if ( PIC32_MAC_DEBUG_COMMANDS != 0 )
- static int _Command_MacInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
- int argc,
- char ** argv );
- static int _Command_NetInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
- int argc,
- char ** argv );
- static int _Command_Version( SYS_CMD_DEVICE_NODE * pCmdIO,
- int argc,
- char ** argv );
-
- static const SYS_CMD_DESCRIPTOR macCmdTbl[] =
- {
- { "macinfo", _Command_MacInfo, ": Check MAC statistics" },
- { "netinfo", _Command_NetInfo, ": Net info" },
- { "version", _Command_Version, ": Version info" },
- };
- #endif /* (PIC32_MAC_DEBUG_COMMANDS != 0) */
-
-
- /* FreeRTOS implementation functions */
- BaseType_t xNetworkInterfaceInitialise( void )
- {
- BaseType_t xResult;
-
- if( xMacInitStatus == eMACInit )
- {
- /* This is the first time this function is called. */
- if( StartInitMac() != false )
- {
- /* Indicate that the MAC initialisation succeeded. */
- xMacInitStatus = eMACPass;
- }
- else
- {
- xMacInitStatus = eMACFailed;
- }
- }
-
- if( xMacInitStatus == eMACPass )
- {
- xResult = xGetPhyLinkStatus();
- }
- else
- {
- xResult = pdFAIL;
- }
-
- PIC32_MAC_DbgPrint( "xNetworkInterfaceInitialise: %d %d\r\n", ( int ) xMacInitStatus, ( int ) xResult );
-
- return xResult;
- }
-
-
- /*-----------------------------------------------------------*/
-
- BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
- BaseType_t xReleaseAfterSend )
- {
- TCPIP_MAC_RES macRes;
- TCPIP_MAC_PACKET * pTxPkt;
-
- BaseType_t retRes = pdFALSE;
-
-
- if( ( pxDescriptor != 0 ) && ( pxDescriptor->pucEthernetBuffer != 0 ) && ( pxDescriptor->xDataLength != 0 ) )
- {
- TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pxDescriptor->pucEthernetBuffer - PIC32_BUFFER_PKT_PTR_OSSET );
- configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
- pTxPkt = *ppkt;
- configASSERT( pTxPkt != 0 );
-
- /* prepare the packet for transmission */
- /* set the correct data length: */
- configASSERT( pTxPkt->pDSeg->segSize >= pTxPkt->pDSeg->segLen );
- pTxPkt->pDSeg->segLen = pxDescriptor->xDataLength;
- pTxPkt->next = 0; /* unlink it */
- macRes = ( macObject->TCPIP_MAC_PacketTx )( macCliHandle, pTxPkt );
-
- if( macRes >= 0 )
- {
- retRes = pdTRUE;
- pxDescriptor->pucEthernetBuffer = 0; /* it will be released by the MAC driver once it's transmitted */
- iptraceNETWORK_INTERFACE_TRANSMIT();
- }
-
- /* else same error occurred; this normally should not happen! But the buffer is left in there so it shold be freed! */
-
- /* The buffer has been sent so can be released. */
- if( xReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
- }
-
- return retRes;
- }
-
-
- /************************************* Section: helper functions ************************************************** */
- /* */
-
- void PIC32_GetMACAddress( uint8_t macAdd[ 6 ] )
- {
- #if defined( __PIC32MZ__ ) || defined( __PIC32MX__ )
- PLIB_ETH_MACGetAddress( ETH_ID_0, macAdd );
- #else
- #error "MAC Address: not supported architecture!"
- #endif
- }
-
-
- /*-----------------------------------------------------------*/
-
- const void * const PIC32_GetMacConfigData( void )
- {
- #if defined( __PIC32MZ__ ) || defined( __PIC32MX__ )
- extern const TCPIP_MODULE_MAC_PIC32INT_CONFIG tcpipMACPIC32INTInitData;
-
- return &tcpipMACPIC32INTInitData;
- #else
- #error "MAC Address: not supported architecture!"
- #endif
- }
-
- /************************************* Section: worker code ************************************************** */
- /* */
-
-
- static bool StartInitMac( void )
- {
- TCPIP_MAC_MODULE_CTRL macCtrl;
- SYS_MODULE_INIT moduleInit;
- EventBits_t evBits;
-
-
- /* perform some initialization of all variables so that we can cleanup what failed */
- /* if something failed, the routine will be called again and again by FreeRTOS! */
- macHeapHandle = 0;
- macObjHandle = 0;
- macCliHandle = 0;
- macTmrHandle = 0;
- macTaskHandle = 0;
- macObject = TCPIP_HOSTS_CONFIGURATION[ 0 ].pMacObject; /* the MAC object we use */
- macObjStatus = SYS_STATUS_UNINITIALIZED;
- macLinkStatus = false;
-
- int netUpFail = 0;
-
- while( true )
- {
- /* start the allocator */
- macHeapHandle = TCPIP_HEAP_Create( ( const TCPIP_STACK_HEAP_CONFIG * ) &tcpipHeapConfig, 0 );
-
- if( macHeapHandle == 0 )
- {
- netUpFail = 1;
- break;
- }
-
- if( TCPIP_PKT_Initialize( macHeapHandle, 0, 0 ) == false )
- {
- netUpFail = 2;
- break;
- }
-
- moduleInit.sys.powerState = SYS_MODULE_POWER_RUN_FULL;
-
- /* Initialize the MAC. MAC address is defined to 0x000000000000 in
- * FreeRTOSConfig.h and therefore it will be initialized to the
- * factory programmed MAC address. */
- SetMacCtrl( &macCtrl );
- /* Set the mac address in the FreeRTOS+TCP stack. */
- FreeRTOS_UpdateMACAddress( macCtrl.ifPhyAddress.v );
-
- TCPIP_MAC_INIT macInit =
- {
- .moduleInit = { moduleInit.value },
- .macControl = &macCtrl,
- .moduleData = PIC32_GetMacConfigData(),
- };
-
- macObjHandle = ( macObject->TCPIP_MAC_Initialize )( TCPIP_MODULE_MAC_PIC32INT, &macInit.moduleInit );
-
- if( macObjHandle == SYS_MODULE_OBJ_INVALID )
- {
- macObjHandle = 0;
- netUpFail = 4;
- break;
- }
-
- /* open the MAC */
- macCliHandle = ( macObject->TCPIP_MAC_Open )( TCPIP_MODULE_MAC_PIC32INT, DRV_IO_INTENT_READWRITE );
-
- if( macCliHandle == DRV_HANDLE_INVALID )
- {
- macCliHandle = 0;
- netUpFail = 5;
- break;
- }
-
- if( !( macObject->TCPIP_MAC_EventMaskSet )( macCliHandle, ( TCPIP_MAC_EV_RX_DONE | TCPIP_MAC_EV_TX_DONE | TCPIP_MAC_EV_RXTX_ERRORS ), true ) )
- {
- netUpFail = 6;
- break;
- }
-
- /* completed the MAC initialization */
- /* continue the initialization */
- macTmrHandle = xTimerCreate( PIC32_MAC_TIMER_NAME, PIC32_MAC_TIMER_PERIOD, pdTRUE, 0, MacTmrCallback );
-
- if( ( macTmrHandle == 0 ) || ( xTimerStart( macTmrHandle, 0 ) != pdPASS ) )
- {
- netUpFail = 8;
- break;
- }
-
- /* spawn the PIC32 MAC task function */
- /* and wait for its event signal */
- macObjStatus = SYS_STATUS_BUSY;
-
- if( xTaskCreate( MacHandlerTask, PIC32_MAC_TASK_NAME, PIC32_MAC_TASK_STACK_SIZE, xTaskGetCurrentTaskHandle(), PIC32_MAC_TASK_PRI, &macTaskHandle ) != pdPASS )
- { /* failed */
- netUpFail = 9;
- break;
- }
-
- xTaskNotifyWait( PIC32_MAC_EVENT_INIT_DONE, PIC32_MAC_EVENT_INIT_DONE, &evBits, PIC32_MAC_INIT_TIMEOUT );
-
- if( ( evBits & PIC32_MAC_EVENT_INIT_DONE ) == 0 )
- { /* timed out */
- netUpFail = 10;
- break;
- }
-
- if( macObjStatus != SYS_STATUS_READY )
- { /* failed somehow ??? */
- netUpFail = 11;
- break;
- }
-
- netUpFail = 0;
- break;
- }
-
- if( netUpFail == 0 )
- {
- PIC32_MAC_DbgPrint( " MAC Init success!\r\n" );
-
- #if ( PIC32_MAC_DEBUG_COMMANDS != 0 )
- /* create command group */
- if( !SYS_CMD_ADDGRP( macCmdTbl, sizeof( macCmdTbl ) / sizeof( *macCmdTbl ), "mac", ": mac commands" ) )
- {
- PIC32_MAC_DbgPrint( "Failed to create MAC Commands\r\n" );
- }
- #endif /* (PIC32_MAC_DEBUG_COMMANDS != 0) */
-
- return true;
- }
- else
- {
- StartInitCleanup();
- PIC32_MAC_DbgPrint( "MAC Init failed: %d!\r\n", netUpFail );
-
- return false;
- }
- }
-
- /*-----------------------------------------------------------*/
-
- static void StartInitCleanup( void )
- {
- if( macHeapHandle != 0 )
- {
- TCPIP_HEAP_Delete( macHeapHandle );
- macHeapHandle = 0;
- }
-
- if( macObjHandle != 0 )
- {
- ( macObject->TCPIP_MAC_Deinitialize )( macObjHandle );
- macObjHandle = 0;
- }
-
- if( macTmrHandle != 0 )
- {
- xTimerDelete( macTmrHandle, portMAX_DELAY );
- macTmrHandle = 0;
- }
-
- if( macTaskHandle != 0 )
- {
- vTaskDelete( macTaskHandle );
- macTaskHandle = 0;
- }
- }
-
- /*-----------------------------------------------------------*/
-
- static void SetMacCtrl( TCPIP_MAC_MODULE_CTRL * pMacCtrl )
- {
- TCPIP_MAC_ADDR macAdd;
- uint8_t unsetMACAddr[ 6 ] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* not set MAC address */
-
- pMacCtrl->nIfs = 1;
-
- pMacCtrl->mallocF = TCPIP_HEAP_MallocOutline;
- pMacCtrl->callocF = TCPIP_HEAP_CallocOutline;
- pMacCtrl->freeF = TCPIP_HEAP_FreeOutline;
- pMacCtrl->memH = macHeapHandle;
-
-
- pMacCtrl->pktAllocF = PIC32_MacPacketAllocate;
- pMacCtrl->pktFreeF = ( TCPIP_MAC_PKT_FreeF ) _TCPIP_PKT_FREE_FNC;
- pMacCtrl->pktAckF = ( TCPIP_MAC_PKT_AckF ) _TCPIP_PKT_ACK_FNC;
-
- pMacCtrl->synchF = MacSyncFunction;
-
- pMacCtrl->eventF = MAC_EventFunction;
- pMacCtrl->eventParam = 0;
-
- pMacCtrl->moduleId = TCPIP_MODULE_MAC_PIC32INT;
- pMacCtrl->netIx = 0;
- pMacCtrl->macAction = TCPIP_MAC_ACTION_INIT;
- pMacCtrl->powerMode = TCPIP_MAC_POWER_FULL;
-
- macAdd.v[ 0 ] = configMAC_ADDR0;
- macAdd.v[ 1 ] = configMAC_ADDR1;
- macAdd.v[ 2 ] = configMAC_ADDR2;
- macAdd.v[ 3 ] = configMAC_ADDR3;
- macAdd.v[ 4 ] = configMAC_ADDR4;
- macAdd.v[ 5 ] = configMAC_ADDR5;
-
- if( memcmp( macAdd.v, unsetMACAddr, sizeof( unsetMACAddr ) ) == 0 )
- { /* if unspecified we use the factory pre-programmed address */
- PIC32_GetMACAddress( pMacCtrl->ifPhyAddress.v );
- }
- else
- { /* use the config suggested one */
- memcpy( pMacCtrl->ifPhyAddress.v, macAdd.v, sizeof( macAdd ) );
- }
- }
-
- /*-----------------------------------------------------------*/
-
- static bool MacSyncFunction( void * synchHandle,
- TCPIP_MAC_SYNCH_REQUEST req )
- {
- switch( req )
- {
- case TCPIP_MAC_SYNCH_REQUEST_OBJ_CREATE:
- vSemaphoreCreateBinary( *( SemaphoreHandle_t * ) synchHandle );
-
- return ( *( SemaphoreHandle_t * ) synchHandle == NULL ) ? false : true;
-
- case TCPIP_MAC_SYNCH_REQUEST_OBJ_DELETE:
- vSemaphoreDelete( *( SemaphoreHandle_t * ) synchHandle );
- *( SemaphoreHandle_t * ) synchHandle = NULL;
-
- return true;
-
- case TCPIP_MAC_SYNCH_REQUEST_OBJ_LOCK:
-
- return ( xSemaphoreTake( *( SemaphoreHandle_t * ) synchHandle, portMAX_DELAY ) == pdTRUE ) ? true : false;
-
- case TCPIP_MAC_SYNCH_REQUEST_OBJ_UNLOCK:
-
- return ( xSemaphoreGive( *( SemaphoreHandle_t * ) synchHandle ) == pdTRUE ) ? true : false;
-
- case TCPIP_MAC_SYNCH_REQUEST_CRIT_ENTER:
- vTaskSuspendAll();
-
- return true;
-
- case TCPIP_MAC_SYNCH_REQUEST_CRIT_LEAVE:
- xTaskResumeAll();
-
- return true;
-
- default:
-
- return false;
- }
- }
-
-
- /*-----------------------------------------------------------*/
-
- static void MacHandlerTask( void * params )
- {
- EventBits_t evBits;
-
- /* perform the MAC initialization */
- while( macObjStatus == SYS_STATUS_BUSY )
- {
- /* process the underlying MAC module tasks */
- ( macObject->TCPIP_MAC_Tasks )( macObjHandle );
-
- SYS_STATUS macStatus = ( macObject->TCPIP_MAC_Status )( macObjHandle );
-
- if( macStatus == SYS_STATUS_BUSY )
- { /* still pending */
- vTaskDelay( PIC32_MAC_TASK_INIT_PENDING_DELAY );
- }
- else
- { /* completed ...somehow */
- macObjStatus = macStatus;
-
- xTaskNotify( ( TaskHandle_t ) params, PIC32_MAC_EVENT_INIT_DONE, eSetBits );
-
- if( macStatus != SYS_STATUS_READY )
- { /* failed miserably */
- vTaskDelete( 0 );
- }
-
- /* done, up and running */
- }
- }
-
- while( true )
- {
- xTaskNotifyWait( PIC32_MAC_EVENT_TIMEOUT | PIC32_MAC_EVENT_IF_PENDING, PIC32_MAC_EVENT_TIMEOUT | PIC32_MAC_EVENT_IF_PENDING, &evBits, portMAX_DELAY );
-
- if( ( evBits & PIC32_MAC_EVENT_TIMEOUT ) != 0 )
- { /* timeout occurred... */
- ( macObject->TCPIP_MAC_Tasks )( macObjHandle );
- bool linkCurr = ( macObject->TCPIP_MAC_LinkCheck )( macCliHandle ); /* check link status */
-
- if( macLinkStatus != linkCurr )
- { /* link status changed; some event could ve fired here if needed */
- PIC32_MAC_DbgPrint( " MAC link: %s!\r\n", linkCurr ? "ON" : "OFF" );
- macLinkStatus = linkCurr;
- }
- }
-
- if( ( evBits & PIC32_MAC_EVENT_IF_PENDING ) != 0 )
- { /* IF events signal */
- TCPIP_MAC_EVENT activeEvents = ( macObject->TCPIP_MAC_EventPendingGet )( macCliHandle );
-
- if( activeEvents != TCPIP_MAC_EV_NONE )
- {
- /* acknowledge the events */
- ( macObject->TCPIP_MAC_EventAcknowledge )( macCliHandle, activeEvents );
-
- /* check for RX */
- if( ( activeEvents & ( TCPIP_MAC_EV_RX_DONE | TCPIP_MAC_EV_RX_OVFLOW | TCPIP_MAC_EV_RX_BUFNA ) ) != 0 )
- { /* RX packets available */
- MacRxPackets();
- }
-
- /* call the driver process function; */
- /* PIC32 driver requests it through TCPIP_MAC_ParametersGet() which is bypassed here! */
- ( macObject->TCPIP_MAC_Process )( macCliHandle );
- }
- }
-
- /* do what you have to do and then wait for another event... */
- }
- }
-
- /*-----------------------------------------------------------*/
-
- static void MacTmrCallback( TimerHandle_t xTimer )
- {
- xTaskNotify( macTaskHandle, PIC32_MAC_EVENT_TIMEOUT, eSetBits );
- }
-
- /* MAC interrupt event function */
- /* MAC signals an event, probably from within ISR */
- /* we care just for RX related events */
- static void MAC_EventFunction( TCPIP_MAC_EVENT event,
- const void * eventParam )
- {
- BaseType_t xHigherPriorityTaskWoken;
-
- if( ( event & ( TCPIP_MAC_EV_RX_DONE | TCPIP_MAC_EV_TX_DONE | TCPIP_MAC_EV_RXTX_ERRORS ) ) != 0 )
- {
- xHigherPriorityTaskWoken = pdFALSE;
- xTaskNotifyFromISR( macTaskHandle, PIC32_MAC_EVENT_IF_PENDING, eSetBits, &xHigherPriorityTaskWoken );
-
- if( xHigherPriorityTaskWoken )
- {
- portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
- }
- }
- }
-
- /*-----------------------------------------------------------*/
-
- BaseType_t xGetPhyLinkStatus( void )
- {
- return macLinkStatus == true ? pdPASS : pdFAIL;
- }
-
-
- /* receive packets from the MAC driver */
- static void MacRxPackets( void )
- {
- TCPIP_MAC_PACKET * pRxPkt;
-
- /* get all the new MAC packets */
- while( ( pRxPkt = ( macObject->TCPIP_MAC_PacketRx )( macCliHandle, 0, 0 ) ) != 0 )
- {
- MacProcessRxPacket( pRxPkt );
- }
- }
-
- /*-----------------------------------------------------------*/
-
- static void MacProcessRxPacket( TCPIP_MAC_PACKET * pRxPkt )
- {
- bool pktSuccess, pktLost;
- size_t pktLength;
- TCPIP_MAC_DATA_SEGMENT * pSeg;
- uint8_t * pPktBuff;
- NetworkBufferDescriptor_t * pxBufferDescriptor;
- IPStackEvent_t xRxEvent;
-
- pxBufferDescriptor = 0;
- pktSuccess = pktLost = false;
-
- while( true )
- {
- pktLength = 0;
- int nSegs = 0;
- pSeg = pRxPkt->pDSeg;
- pPktBuff = pSeg->segLoad;
-
- /* calculate the packet size */
- do
- {
- pktLength += pSeg->segLen;
- pSeg = pSeg->next;
- nSegs++;
- } while( pSeg != 0 );
-
- if( nSegs > 1 )
- { /* no support in FreeRTOS for multi segment packets! */
- break;
- }
-
- /* sizeof(TCPIP_MAC_ETHERNET_HEADER) is subtracted by the driver */
- /* but FreeRTOS needs the whole frame! */
- pktLength += sizeof( TCPIP_MAC_ETHERNET_HEADER );
-
- if( eConsiderFrameForProcessing( pPktBuff ) != eProcessBuffer )
- {
- break;
- }
-
- /* get the network descriptor (no data buffer) to hold this packet */
- pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( 0, 0 );
-
- if( pxBufferDescriptor == 0 )
- {
- pktLost = true;
- break;
- }
-
- PIC32_MacAssociate( pRxPkt, pxBufferDescriptor, pktLength );
-
- xRxEvent.eEventType = eNetworkRxEvent;
- xRxEvent.pvData = ( void * ) pxBufferDescriptor;
-
- /* Send the data to the TCP/IP stack */
- if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
- { /* failed */
- pktLost = true;
- }
- else
- { /* success */
- pktSuccess = true;
- iptraceNETWORK_INTERFACE_RECEIVE();
- }
-
- break;
- }
-
- if( !pktSuccess )
- { /* smth went wrong; nothing sent to the */
- if( pxBufferDescriptor != 0 )
- {
- pxBufferDescriptor->pucEthernetBuffer = 0;
- vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
- }
-
- if( pktLost )
- {
- iptraceETHERNET_RX_EVENT_LOST();
- }
-
- /* acknowledge the packet to the MAC driver */
- if( pRxPkt->ackFunc )
- {
- ( *pRxPkt->ackFunc )( pRxPkt, pRxPkt->ackParam );
- }
- else
- {
- PIC32_MacPacketOrphan( pRxPkt );
- }
- }
- }
-
- #if ( PIC32_MAC_DEBUG_COMMANDS != 0 )
- /* */
- static int _Command_MacInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
- int argc,
- char ** argv )
- {
- TCPIP_MAC_RES macRes;
- TCPIP_MAC_RX_STATISTICS rxStatistics;
- TCPIP_MAC_TX_STATISTICS txStatistics;
- TCPIP_MAC_STATISTICS_REG_ENTRY regEntries[ 8 ];
- TCPIP_MAC_STATISTICS_REG_ENTRY * pRegEntry;
- int jx, hwEntries;
- char entryName[ sizeof( pRegEntry->registerName ) + 1 ];
-
- const void * cmdIoParam = pCmdIO->cmdIoParam;
-
- if( argc != 1 )
- {
- ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "Usage: macinfo \r\n" );
- ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "Ex: macinfo \r\n" );
-
- return false;
- }
-
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "Interface: %s driver statistics\r\n", macObject->macName );
- macRes = ( macObject->TCPIP_MAC_StatisticsGet )( macCliHandle, &rxStatistics, &txStatistics );
-
- if( macRes == TCPIP_MAC_RES_OK )
- {
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "\tnRxOkPackets: %d, nRxPendBuffers: %d, nRxSchedBuffers: %d, ",
- rxStatistics.nRxOkPackets, rxStatistics.nRxPendBuffers, rxStatistics.nRxSchedBuffers );
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "nRxErrorPackets: %d, nRxFragmentErrors: %d\r\n", rxStatistics.nRxErrorPackets, rxStatistics.nRxFragmentErrors );
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "\tnTxOkPackets: %d, nTxPendBuffers: %d, nTxErrorPackets: %d, nTxQueueFull: %d\r\n",
- txStatistics.nTxOkPackets, txStatistics.nTxPendBuffers, txStatistics.nTxErrorPackets, txStatistics.nTxQueueFull );
- }
- else
- {
- ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "\tnot supported\r\n" );
- }
-
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "Interface: %s hardware statistics\r\n", macObject->macName );
- macRes = ( macObject->TCPIP_MAC_RegisterStatisticsGet )( macCliHandle, regEntries, sizeof( regEntries ) / sizeof( *regEntries ), &hwEntries );
-
- if( macRes == TCPIP_MAC_RES_OK )
- {
- entryName[ sizeof( entryName ) - 1 ] = 0;
-
- for( jx = 0, pRegEntry = regEntries; jx < hwEntries && jx < sizeof( regEntries ) / sizeof( *regEntries ); jx++, pRegEntry++ )
- {
- strncpy( entryName, pRegEntry->registerName, sizeof( entryName ) - 1 );
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "\t%s: 0x%8x\r\n", entryName, pRegEntry->registerValue );
- }
- }
- else
- {
- ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "\tnot supported\r\n" );
- }
-
- return true;
- }
-
- /*-----------------------------------------------------------*/
-
- static int _Command_NetInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
- int argc,
- char ** argv )
- {
- const void * cmdIoParam = pCmdIO->cmdIoParam;
-
- union
- {
- uint32_t ul;
- uint8_t b[ 4 ];
- }
- sUl;
-
- sUl.ul = FreeRTOS_GetIPAddress();
-
- bool linkUp = FreeRTOS_IsNetworkUp() == pdTRUE;
-
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "IP address: %d.%d.%d.%d\r\n", sUl.b[ 0 ], sUl.b[ 1 ], sUl.b[ 2 ], sUl.b[ 3 ] );
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "Link is: %s\r\n", linkUp ? "Up" : "Down" );
-
- return true;
- }
-
-#include "aws_application_version.h"
-
-static int _Command_Version(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv)
-{
- configPRINTF( ( "App version - maj: %d, min: %d, build: %d\r\n", xAppFirmwareVersion.u.x.ucMajor, xAppFirmwareVersion.u.x.ucMinor, xAppFirmwareVersion.u.x.usBuild) );
- return 0;
-}
-
- #endif /* (PIC32_MAC_DEBUG_COMMANDS != 0) */
-#endif /* #ifdef PIC32_USE_ETHERNET */
+/*******************************************************************************
+* Network Interface file
+*
+* Summary:
+* Network Interface file for FreeRTOS-Plus-TCP stack
+*
+* Description:
+* - Interfaces PIC32 to the FreeRTOS TCP/IP stack
+*******************************************************************************/
+
+/*******************************************************************************
+* File Name: pic32_NetworkInterface.c
+* Copyright 2017 Microchip Technology Incorporated and its subsidiaries.
+*
+* 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
+*******************************************************************************/
+#include <sys/kmem.h>
+
+#include "FreeRTOS.h"
+#include "semphr.h"
+#include "event_groups.h"
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_IP_Private.h"
+
+#include "NetworkInterface.h"
+#include "NetworkBufferManagement.h"
+
+
+#include "NetworkInterface.h"
+#include "NetworkConfig.h"
+
+#include "peripheral/eth/plib_eth.h"
+
+#include "system_config.h"
+#include "system/console/sys_console.h"
+#include "system/debug/sys_debug.h"
+#include "system/command/sys_command.h"
+
+#include "driver/ethmac/drv_ethmac.h"
+#include "driver/miim/drv_miim.h"
+
+#include "tcpip/tcpip.h"
+#include "tcpip/src/tcpip_private.h"
+#include "tcpip/src/link_list.h"
+
+#ifdef PIC32_USE_ETHERNET
+
+ /* local definitions and data */
+
+ /* debug messages */
+ #if ( PIC32_MAC_DEBUG_MESSAGES != 0 )
+ #define PIC32_MAC_DbgPrint( format, ... ) SYS_CONSOLE_PRINT( format, ## __VA_ARGS__ )
+ #else
+ #define PIC32_MAC_DbgPrint( format, ... )
+ #endif /* (PIC32_MAC_DEBUG_MESSAGES != 0) */
+
+ typedef enum
+ {
+ PIC32_MAC_EVENT_INIT_NONE = 0x000, /* no event/invalid */
+
+ PIC32_MAC_EVENT_INIT_DONE = 0x001, /* initialization done event */
+ PIC32_MAC_EVENT_TIMEOUT = 0x002, /* periodic timeout event */
+ PIC32_MAC_EVENT_IF_PENDING = 0x004, /* an interface event signal: RX, TX, errors. etc. */
+ } PIC32_MAC_EVENT_TYPE;
+
+ typedef enum
+ {
+ eMACInit, /* Must initialise MAC. */
+ eMACPass, /* Initialisation was successful. */
+ eMACFailed, /* Initialisation failed. */
+ } eMAC_INIT_STATUS_TYPE;
+
+ static TCPIP_STACK_HEAP_HANDLE macHeapHandle;
+
+ static const TCPIP_MAC_OBJECT * macObject; /* the one and only MAC object; */
+
+ static SYS_MODULE_OBJ macObjHandle; /* the MAC object instance, obtained at initialization */
+ static TCPIP_MAC_HANDLE macCliHandle; /* client handle */
+ static volatile SYS_STATUS macObjStatus; /* current MAC status */
+
+ static TaskHandle_t macTaskHandle;
+
+ static TimerHandle_t macTmrHandle;
+
+ static bool macLinkStatus; /* true if link is ON */
+
+ static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
+
+ /* local prototypes */
+ static bool StartInitMac( void );
+ static void StartInitCleanup( void );
+
+ static void SetMacCtrl( TCPIP_MAC_MODULE_CTRL * pMacCtrl );
+
+ static bool MacSyncFunction( void * synchHandle,
+ TCPIP_MAC_SYNCH_REQUEST req );
+
+ /* the PIC32 MAC task function */
+ static void MacHandlerTask( void * params );
+
+ /* MAC interrupt event function */
+ static void MAC_EventFunction( TCPIP_MAC_EVENT event,
+ const void * eventParam );
+
+ /* timer callback for link maintenance, etc; */
+ static void MacTmrCallback( TimerHandle_t xTimer );
+
+ /* MAC RX packets functions */
+ static void MacRxPackets( void );
+ static void MacProcessRxPacket( TCPIP_MAC_PACKET * pRxPkt );
+
+
+ /* memory allocation mapping to FreeRTOS */
+ static void * _malloc( size_t nBytes )
+ {
+ return pvPortMalloc( nBytes );
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static void * _calloc( size_t nElems,
+ size_t elemSize )
+ {
+ size_t nBytes = nElems * elemSize;
+
+ void * ptr = pvPortMalloc( nBytes );
+
+ if( ptr != 0 )
+ {
+ memset( ptr, 0, nBytes );
+ }
+
+ return ptr;
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static void _free( void * pBuff )
+ {
+ vPortFree( pBuff );
+ }
+
+ /* extern references */
+ /* */
+ /* use the configuration data from the system_init.c */
+ extern const TCPIP_NETWORK_CONFIG TCPIP_HOSTS_CONFIGURATION[];
+
+ /* BufferAllocation_2.c:: packet allocation function */
+ extern TCPIP_MAC_PACKET * PIC32_MacPacketAllocate( uint16_t pktLen,
+ uint16_t segLoadLen,
+ TCPIP_MAC_PACKET_FLAGS flags );
+
+ extern void PIC32_MacAssociate( TCPIP_MAC_PACKET * pRxPkt,
+ NetworkBufferDescriptor_t * pxBufferDescriptor,
+ size_t pktLength );
+ extern void PIC32_MacPacketOrphan( TCPIP_MAC_PACKET * pPkt );
+
+ /* cannot use the system_init.c::tcpipHeapConfig because FreeRTOS does not have a calloc function! */
+ /* we build it here! */
+
+ /* make sure we're running with external heap! Redirect to FreeRTOS. */
+ #if !defined( TCPIP_STACK_USE_EXTERNAL_HEAP ) || defined( TCPIP_STACK_USE_INTERNAL_HEAP ) || defined( TCPIP_STACK_USE_INTERNAL_HEAP_POOL )
+ #error "TCPIP_STACK_USE_EXTERNAL_HEAP should be defined for this project!"
+ #endif
+
+ static const TCPIP_STACK_HEAP_EXTERNAL_CONFIG tcpipHeapConfig =
+ {
+ .heapType = TCPIP_STACK_HEAP_TYPE_EXTERNAL_HEAP,
+ .heapFlags = TCPIP_STACK_HEAP_FLAG_ALLOC_UNCACHED | TCPIP_STACK_HEAP_FLAG_NO_MTHREAD_SYNC,
+ .heapUsage = TCPIP_STACK_HEAP_USE_DEFAULT,
+ .malloc_fnc = _malloc,
+ .calloc_fnc = _calloc,
+ .free_fnc = _free,
+ };
+
+ #if ( PIC32_MAC_DEBUG_COMMANDS != 0 )
+ static int _Command_MacInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
+ int argc,
+ char ** argv );
+ static int _Command_NetInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
+ int argc,
+ char ** argv );
+ static int _Command_Version( SYS_CMD_DEVICE_NODE * pCmdIO,
+ int argc,
+ char ** argv );
+
+ static const SYS_CMD_DESCRIPTOR macCmdTbl[] =
+ {
+ { "macinfo", _Command_MacInfo, ": Check MAC statistics" },
+ { "netinfo", _Command_NetInfo, ": Net info" },
+ { "version", _Command_Version, ": Version info" },
+ };
+ #endif /* (PIC32_MAC_DEBUG_COMMANDS != 0) */
+
+
+ /* FreeRTOS implementation functions */
+ BaseType_t xNetworkInterfaceInitialise( void )
+ {
+ BaseType_t xResult;
+
+ if( xMacInitStatus == eMACInit )
+ {
+ /* This is the first time this function is called. */
+ if( StartInitMac() != false )
+ {
+ /* Indicate that the MAC initialisation succeeded. */
+ xMacInitStatus = eMACPass;
+ }
+ else
+ {
+ xMacInitStatus = eMACFailed;
+ }
+ }
+
+ if( xMacInitStatus == eMACPass )
+ {
+ xResult = xGetPhyLinkStatus();
+ }
+ else
+ {
+ xResult = pdFAIL;
+ }
+
+ PIC32_MAC_DbgPrint( "xNetworkInterfaceInitialise: %d %d\r\n", ( int ) xMacInitStatus, ( int ) xResult );
+
+ return xResult;
+ }
+
+
+ /*-----------------------------------------------------------*/
+
+ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
+ BaseType_t xReleaseAfterSend )
+ {
+ TCPIP_MAC_RES macRes;
+ TCPIP_MAC_PACKET * pTxPkt;
+
+ BaseType_t retRes = pdFALSE;
+
+
+ if( ( pxDescriptor != 0 ) && ( pxDescriptor->pucEthernetBuffer != 0 ) && ( pxDescriptor->xDataLength != 0 ) )
+ {
+ TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pxDescriptor->pucEthernetBuffer - PIC32_BUFFER_PKT_PTR_OSSET );
+ configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
+ pTxPkt = *ppkt;
+ configASSERT( pTxPkt != 0 );
+
+ /* prepare the packet for transmission */
+ /* set the correct data length: */
+ configASSERT( pTxPkt->pDSeg->segSize >= pTxPkt->pDSeg->segLen );
+ pTxPkt->pDSeg->segLen = pxDescriptor->xDataLength;
+ pTxPkt->next = 0; /* unlink it */
+ macRes = ( macObject->TCPIP_MAC_PacketTx )( macCliHandle, pTxPkt );
+
+ if( macRes >= 0 )
+ {
+ retRes = pdTRUE;
+ pxDescriptor->pucEthernetBuffer = 0; /* it will be released by the MAC driver once it's transmitted */
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+ }
+
+ /* else same error occurred; this normally should not happen! But the buffer is left in there so it shold be freed! */
+
+ /* The buffer has been sent so can be released. */
+ if( xReleaseAfterSend != pdFALSE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+ }
+
+ return retRes;
+ }
+
+
+ /************************************* Section: helper functions ************************************************** */
+ /* */
+
+ void PIC32_GetMACAddress( uint8_t macAdd[ 6 ] )
+ {
+ #if defined( __PIC32MZ__ ) || defined( __PIC32MX__ )
+ PLIB_ETH_MACGetAddress( ETH_ID_0, macAdd );
+ #else
+ #error "MAC Address: not supported architecture!"
+ #endif
+ }
+
+
+ /*-----------------------------------------------------------*/
+
+ const void * const PIC32_GetMacConfigData( void )
+ {
+ #if defined( __PIC32MZ__ ) || defined( __PIC32MX__ )
+ extern const TCPIP_MODULE_MAC_PIC32INT_CONFIG tcpipMACPIC32INTInitData;
+
+ return &tcpipMACPIC32INTInitData;
+ #else
+ #error "MAC Address: not supported architecture!"
+ #endif
+ }
+
+ /************************************* Section: worker code ************************************************** */
+ /* */
+
+
+ static bool StartInitMac( void )
+ {
+ TCPIP_MAC_MODULE_CTRL macCtrl;
+ SYS_MODULE_INIT moduleInit;
+ EventBits_t evBits;
+
+
+ /* perform some initialization of all variables so that we can cleanup what failed */
+ /* if something failed, the routine will be called again and again by FreeRTOS! */
+ macHeapHandle = 0;
+ macObjHandle = 0;
+ macCliHandle = 0;
+ macTmrHandle = 0;
+ macTaskHandle = 0;
+ macObject = TCPIP_HOSTS_CONFIGURATION[ 0 ].pMacObject; /* the MAC object we use */
+ macObjStatus = SYS_STATUS_UNINITIALIZED;
+ macLinkStatus = false;
+
+ int netUpFail = 0;
+
+ while( true )
+ {
+ /* start the allocator */
+ macHeapHandle = TCPIP_HEAP_Create( ( const TCPIP_STACK_HEAP_CONFIG * ) &tcpipHeapConfig, 0 );
+
+ if( macHeapHandle == 0 )
+ {
+ netUpFail = 1;
+ break;
+ }
+
+ if( TCPIP_PKT_Initialize( macHeapHandle, 0, 0 ) == false )
+ {
+ netUpFail = 2;
+ break;
+ }
+
+ moduleInit.sys.powerState = SYS_MODULE_POWER_RUN_FULL;
+
+ /* Initialize the MAC. MAC address is defined to 0x000000000000 in
+ * FreeRTOSConfig.h and therefore it will be initialized to the
+ * factory programmed MAC address. */
+ SetMacCtrl( &macCtrl );
+ /* Set the mac address in the FreeRTOS+TCP stack. */
+ FreeRTOS_UpdateMACAddress( macCtrl.ifPhyAddress.v );
+
+ TCPIP_MAC_INIT macInit =
+ {
+ .moduleInit = { moduleInit.value },
+ .macControl = &macCtrl,
+ .moduleData = PIC32_GetMacConfigData(),
+ };
+
+ macObjHandle = ( macObject->TCPIP_MAC_Initialize )( TCPIP_MODULE_MAC_PIC32INT, &macInit.moduleInit );
+
+ if( macObjHandle == SYS_MODULE_OBJ_INVALID )
+ {
+ macObjHandle = 0;
+ netUpFail = 4;
+ break;
+ }
+
+ /* open the MAC */
+ macCliHandle = ( macObject->TCPIP_MAC_Open )( TCPIP_MODULE_MAC_PIC32INT, DRV_IO_INTENT_READWRITE );
+
+ if( macCliHandle == DRV_HANDLE_INVALID )
+ {
+ macCliHandle = 0;
+ netUpFail = 5;
+ break;
+ }
+
+ if( !( macObject->TCPIP_MAC_EventMaskSet )( macCliHandle, ( TCPIP_MAC_EV_RX_DONE | TCPIP_MAC_EV_TX_DONE | TCPIP_MAC_EV_RXTX_ERRORS ), true ) )
+ {
+ netUpFail = 6;
+ break;
+ }
+
+ /* completed the MAC initialization */
+ /* continue the initialization */
+ macTmrHandle = xTimerCreate( PIC32_MAC_TIMER_NAME, PIC32_MAC_TIMER_PERIOD, pdTRUE, 0, MacTmrCallback );
+
+ if( ( macTmrHandle == 0 ) || ( xTimerStart( macTmrHandle, 0 ) != pdPASS ) )
+ {
+ netUpFail = 8;
+ break;
+ }
+
+ /* spawn the PIC32 MAC task function */
+ /* and wait for its event signal */
+ macObjStatus = SYS_STATUS_BUSY;
+
+ if( xTaskCreate( MacHandlerTask, PIC32_MAC_TASK_NAME, PIC32_MAC_TASK_STACK_SIZE, xTaskGetCurrentTaskHandle(), PIC32_MAC_TASK_PRI, &macTaskHandle ) != pdPASS )
+ { /* failed */
+ netUpFail = 9;
+ break;
+ }
+
+ xTaskNotifyWait( PIC32_MAC_EVENT_INIT_DONE, PIC32_MAC_EVENT_INIT_DONE, &evBits, PIC32_MAC_INIT_TIMEOUT );
+
+ if( ( evBits & PIC32_MAC_EVENT_INIT_DONE ) == 0 )
+ { /* timed out */
+ netUpFail = 10;
+ break;
+ }
+
+ if( macObjStatus != SYS_STATUS_READY )
+ { /* failed somehow ??? */
+ netUpFail = 11;
+ break;
+ }
+
+ netUpFail = 0;
+ break;
+ }
+
+ if( netUpFail == 0 )
+ {
+ PIC32_MAC_DbgPrint( " MAC Init success!\r\n" );
+
+ #if ( PIC32_MAC_DEBUG_COMMANDS != 0 )
+ /* create command group */
+ if( !SYS_CMD_ADDGRP( macCmdTbl, sizeof( macCmdTbl ) / sizeof( *macCmdTbl ), "mac", ": mac commands" ) )
+ {
+ PIC32_MAC_DbgPrint( "Failed to create MAC Commands\r\n" );
+ }
+ #endif /* (PIC32_MAC_DEBUG_COMMANDS != 0) */
+
+ return true;
+ }
+ else
+ {
+ StartInitCleanup();
+ PIC32_MAC_DbgPrint( "MAC Init failed: %d!\r\n", netUpFail );
+
+ return false;
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static void StartInitCleanup( void )
+ {
+ if( macHeapHandle != 0 )
+ {
+ TCPIP_HEAP_Delete( macHeapHandle );
+ macHeapHandle = 0;
+ }
+
+ if( macObjHandle != 0 )
+ {
+ ( macObject->TCPIP_MAC_Deinitialize )( macObjHandle );
+ macObjHandle = 0;
+ }
+
+ if( macTmrHandle != 0 )
+ {
+ xTimerDelete( macTmrHandle, portMAX_DELAY );
+ macTmrHandle = 0;
+ }
+
+ if( macTaskHandle != 0 )
+ {
+ vTaskDelete( macTaskHandle );
+ macTaskHandle = 0;
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static void SetMacCtrl( TCPIP_MAC_MODULE_CTRL * pMacCtrl )
+ {
+ TCPIP_MAC_ADDR macAdd;
+ uint8_t unsetMACAddr[ 6 ] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* not set MAC address */
+
+ pMacCtrl->nIfs = 1;
+
+ pMacCtrl->mallocF = TCPIP_HEAP_MallocOutline;
+ pMacCtrl->callocF = TCPIP_HEAP_CallocOutline;
+ pMacCtrl->freeF = TCPIP_HEAP_FreeOutline;
+ pMacCtrl->memH = macHeapHandle;
+
+
+ pMacCtrl->pktAllocF = PIC32_MacPacketAllocate;
+ pMacCtrl->pktFreeF = ( TCPIP_MAC_PKT_FreeF ) _TCPIP_PKT_FREE_FNC;
+ pMacCtrl->pktAckF = ( TCPIP_MAC_PKT_AckF ) _TCPIP_PKT_ACK_FNC;
+
+ pMacCtrl->synchF = MacSyncFunction;
+
+ pMacCtrl->eventF = MAC_EventFunction;
+ pMacCtrl->eventParam = 0;
+
+ pMacCtrl->moduleId = TCPIP_MODULE_MAC_PIC32INT;
+ pMacCtrl->netIx = 0;
+ pMacCtrl->macAction = TCPIP_MAC_ACTION_INIT;
+ pMacCtrl->powerMode = TCPIP_MAC_POWER_FULL;
+
+ macAdd.v[ 0 ] = configMAC_ADDR0;
+ macAdd.v[ 1 ] = configMAC_ADDR1;
+ macAdd.v[ 2 ] = configMAC_ADDR2;
+ macAdd.v[ 3 ] = configMAC_ADDR3;
+ macAdd.v[ 4 ] = configMAC_ADDR4;
+ macAdd.v[ 5 ] = configMAC_ADDR5;
+
+ if( memcmp( macAdd.v, unsetMACAddr, sizeof( unsetMACAddr ) ) == 0 )
+ { /* if unspecified we use the factory pre-programmed address */
+ PIC32_GetMACAddress( pMacCtrl->ifPhyAddress.v );
+ }
+ else
+ { /* use the config suggested one */
+ memcpy( pMacCtrl->ifPhyAddress.v, macAdd.v, sizeof( macAdd ) );
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static bool MacSyncFunction( void * synchHandle,
+ TCPIP_MAC_SYNCH_REQUEST req )
+ {
+ switch( req )
+ {
+ case TCPIP_MAC_SYNCH_REQUEST_OBJ_CREATE:
+ vSemaphoreCreateBinary( *( SemaphoreHandle_t * ) synchHandle );
+
+ return ( *( SemaphoreHandle_t * ) synchHandle == NULL ) ? false : true;
+
+ case TCPIP_MAC_SYNCH_REQUEST_OBJ_DELETE:
+ vSemaphoreDelete( *( SemaphoreHandle_t * ) synchHandle );
+ *( SemaphoreHandle_t * ) synchHandle = NULL;
+
+ return true;
+
+ case TCPIP_MAC_SYNCH_REQUEST_OBJ_LOCK:
+
+ return ( xSemaphoreTake( *( SemaphoreHandle_t * ) synchHandle, portMAX_DELAY ) == pdTRUE ) ? true : false;
+
+ case TCPIP_MAC_SYNCH_REQUEST_OBJ_UNLOCK:
+
+ return ( xSemaphoreGive( *( SemaphoreHandle_t * ) synchHandle ) == pdTRUE ) ? true : false;
+
+ case TCPIP_MAC_SYNCH_REQUEST_CRIT_ENTER:
+ vTaskSuspendAll();
+
+ return true;
+
+ case TCPIP_MAC_SYNCH_REQUEST_CRIT_LEAVE:
+ xTaskResumeAll();
+
+ return true;
+
+ default:
+
+ return false;
+ }
+ }
+
+
+ /*-----------------------------------------------------------*/
+
+ static void MacHandlerTask( void * params )
+ {
+ EventBits_t evBits;
+
+ /* perform the MAC initialization */
+ while( macObjStatus == SYS_STATUS_BUSY )
+ {
+ /* process the underlying MAC module tasks */
+ ( macObject->TCPIP_MAC_Tasks )( macObjHandle );
+
+ SYS_STATUS macStatus = ( macObject->TCPIP_MAC_Status )( macObjHandle );
+
+ if( macStatus == SYS_STATUS_BUSY )
+ { /* still pending */
+ vTaskDelay( PIC32_MAC_TASK_INIT_PENDING_DELAY );
+ }
+ else
+ { /* completed ...somehow */
+ macObjStatus = macStatus;
+
+ xTaskNotify( ( TaskHandle_t ) params, PIC32_MAC_EVENT_INIT_DONE, eSetBits );
+
+ if( macStatus != SYS_STATUS_READY )
+ { /* failed miserably */
+ vTaskDelete( 0 );
+ }
+
+ /* done, up and running */
+ }
+ }
+
+ while( true )
+ {
+ xTaskNotifyWait( PIC32_MAC_EVENT_TIMEOUT | PIC32_MAC_EVENT_IF_PENDING, PIC32_MAC_EVENT_TIMEOUT | PIC32_MAC_EVENT_IF_PENDING, &evBits, portMAX_DELAY );
+
+ if( ( evBits & PIC32_MAC_EVENT_TIMEOUT ) != 0 )
+ { /* timeout occurred... */
+ ( macObject->TCPIP_MAC_Tasks )( macObjHandle );
+ bool linkCurr = ( macObject->TCPIP_MAC_LinkCheck )( macCliHandle ); /* check link status */
+
+ if( macLinkStatus != linkCurr )
+ { /* link status changed; some event could ve fired here if needed */
+ PIC32_MAC_DbgPrint( " MAC link: %s!\r\n", linkCurr ? "ON" : "OFF" );
+ macLinkStatus = linkCurr;
+ }
+ }
+
+ if( ( evBits & PIC32_MAC_EVENT_IF_PENDING ) != 0 )
+ { /* IF events signal */
+ TCPIP_MAC_EVENT activeEvents = ( macObject->TCPIP_MAC_EventPendingGet )( macCliHandle );
+
+ if( activeEvents != TCPIP_MAC_EV_NONE )
+ {
+ /* acknowledge the events */
+ ( macObject->TCPIP_MAC_EventAcknowledge )( macCliHandle, activeEvents );
+
+ /* check for RX */
+ if( ( activeEvents & ( TCPIP_MAC_EV_RX_DONE | TCPIP_MAC_EV_RX_OVFLOW | TCPIP_MAC_EV_RX_BUFNA ) ) != 0 )
+ { /* RX packets available */
+ MacRxPackets();
+ }
+
+ /* call the driver process function; */
+ /* PIC32 driver requests it through TCPIP_MAC_ParametersGet() which is bypassed here! */
+ ( macObject->TCPIP_MAC_Process )( macCliHandle );
+ }
+ }
+
+ /* do what you have to do and then wait for another event... */
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static void MacTmrCallback( TimerHandle_t xTimer )
+ {
+ xTaskNotify( macTaskHandle, PIC32_MAC_EVENT_TIMEOUT, eSetBits );
+ }
+
+ /* MAC interrupt event function */
+ /* MAC signals an event, probably from within ISR */
+ /* we care just for RX related events */
+ static void MAC_EventFunction( TCPIP_MAC_EVENT event,
+ const void * eventParam )
+ {
+ BaseType_t xHigherPriorityTaskWoken;
+
+ if( ( event & ( TCPIP_MAC_EV_RX_DONE | TCPIP_MAC_EV_TX_DONE | TCPIP_MAC_EV_RXTX_ERRORS ) ) != 0 )
+ {
+ xHigherPriorityTaskWoken = pdFALSE;
+ xTaskNotifyFromISR( macTaskHandle, PIC32_MAC_EVENT_IF_PENDING, eSetBits, &xHigherPriorityTaskWoken );
+
+ if( xHigherPriorityTaskWoken )
+ {
+ portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
+ }
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+ BaseType_t xGetPhyLinkStatus( void )
+ {
+ return macLinkStatus == true ? pdPASS : pdFAIL;
+ }
+
+
+ /* receive packets from the MAC driver */
+ static void MacRxPackets( void )
+ {
+ TCPIP_MAC_PACKET * pRxPkt;
+
+ /* get all the new MAC packets */
+ while( ( pRxPkt = ( macObject->TCPIP_MAC_PacketRx )( macCliHandle, 0, 0 ) ) != 0 )
+ {
+ MacProcessRxPacket( pRxPkt );
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static void MacProcessRxPacket( TCPIP_MAC_PACKET * pRxPkt )
+ {
+ bool pktSuccess, pktLost;
+ size_t pktLength;
+ TCPIP_MAC_DATA_SEGMENT * pSeg;
+ uint8_t * pPktBuff;
+ NetworkBufferDescriptor_t * pxBufferDescriptor;
+ IPStackEvent_t xRxEvent;
+
+ pxBufferDescriptor = 0;
+ pktSuccess = pktLost = false;
+
+ while( true )
+ {
+ pktLength = 0;
+ int nSegs = 0;
+ pSeg = pRxPkt->pDSeg;
+ pPktBuff = pSeg->segLoad;
+
+ /* calculate the packet size */
+ do
+ {
+ pktLength += pSeg->segLen;
+ pSeg = pSeg->next;
+ nSegs++;
+ } while( pSeg != 0 );
+
+ if( nSegs > 1 )
+ { /* no support in FreeRTOS for multi segment packets! */
+ break;
+ }
+
+ /* sizeof(TCPIP_MAC_ETHERNET_HEADER) is subtracted by the driver */
+ /* but FreeRTOS needs the whole frame! */
+ pktLength += sizeof( TCPIP_MAC_ETHERNET_HEADER );
+
+ if( eConsiderFrameForProcessing( pPktBuff ) != eProcessBuffer )
+ {
+ break;
+ }
+
+ /* get the network descriptor (no data buffer) to hold this packet */
+ pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( 0, 0 );
+
+ if( pxBufferDescriptor == 0 )
+ {
+ pktLost = true;
+ break;
+ }
+
+ PIC32_MacAssociate( pRxPkt, pxBufferDescriptor, pktLength );
+
+ xRxEvent.eEventType = eNetworkRxEvent;
+ xRxEvent.pvData = ( void * ) pxBufferDescriptor;
+
+ /* Send the data to the TCP/IP stack */
+ if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
+ { /* failed */
+ pktLost = true;
+ }
+ else
+ { /* success */
+ pktSuccess = true;
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ }
+
+ break;
+ }
+
+ if( !pktSuccess )
+ { /* smth went wrong; nothing sent to the */
+ if( pxBufferDescriptor != 0 )
+ {
+ pxBufferDescriptor->pucEthernetBuffer = 0;
+ vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
+ }
+
+ if( pktLost )
+ {
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+
+ /* acknowledge the packet to the MAC driver */
+ if( pRxPkt->ackFunc )
+ {
+ ( *pRxPkt->ackFunc )( pRxPkt, pRxPkt->ackParam );
+ }
+ else
+ {
+ PIC32_MacPacketOrphan( pRxPkt );
+ }
+ }
+ }
+
+ #if ( PIC32_MAC_DEBUG_COMMANDS != 0 )
+ /* */
+ static int _Command_MacInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
+ int argc,
+ char ** argv )
+ {
+ TCPIP_MAC_RES macRes;
+ TCPIP_MAC_RX_STATISTICS rxStatistics;
+ TCPIP_MAC_TX_STATISTICS txStatistics;
+ TCPIP_MAC_STATISTICS_REG_ENTRY regEntries[ 8 ];
+ TCPIP_MAC_STATISTICS_REG_ENTRY * pRegEntry;
+ int jx, hwEntries;
+ char entryName[ sizeof( pRegEntry->registerName ) + 1 ];
+
+ const void * cmdIoParam = pCmdIO->cmdIoParam;
+
+ if( argc != 1 )
+ {
+ ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "Usage: macinfo \r\n" );
+ ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "Ex: macinfo \r\n" );
+
+ return false;
+ }
+
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "Interface: %s driver statistics\r\n", macObject->macName );
+ macRes = ( macObject->TCPIP_MAC_StatisticsGet )( macCliHandle, &rxStatistics, &txStatistics );
+
+ if( macRes == TCPIP_MAC_RES_OK )
+ {
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "\tnRxOkPackets: %d, nRxPendBuffers: %d, nRxSchedBuffers: %d, ",
+ rxStatistics.nRxOkPackets, rxStatistics.nRxPendBuffers, rxStatistics.nRxSchedBuffers );
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "nRxErrorPackets: %d, nRxFragmentErrors: %d\r\n", rxStatistics.nRxErrorPackets, rxStatistics.nRxFragmentErrors );
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "\tnTxOkPackets: %d, nTxPendBuffers: %d, nTxErrorPackets: %d, nTxQueueFull: %d\r\n",
+ txStatistics.nTxOkPackets, txStatistics.nTxPendBuffers, txStatistics.nTxErrorPackets, txStatistics.nTxQueueFull );
+ }
+ else
+ {
+ ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "\tnot supported\r\n" );
+ }
+
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "Interface: %s hardware statistics\r\n", macObject->macName );
+ macRes = ( macObject->TCPIP_MAC_RegisterStatisticsGet )( macCliHandle, regEntries, sizeof( regEntries ) / sizeof( *regEntries ), &hwEntries );
+
+ if( macRes == TCPIP_MAC_RES_OK )
+ {
+ entryName[ sizeof( entryName ) - 1 ] = 0;
+
+ for( jx = 0, pRegEntry = regEntries; jx < hwEntries && jx < sizeof( regEntries ) / sizeof( *regEntries ); jx++, pRegEntry++ )
+ {
+ strncpy( entryName, pRegEntry->registerName, sizeof( entryName ) - 1 );
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "\t%s: 0x%8x\r\n", entryName, pRegEntry->registerValue );
+ }
+ }
+ else
+ {
+ ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "\tnot supported\r\n" );
+ }
+
+ return true;
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static int _Command_NetInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
+ int argc,
+ char ** argv )
+ {
+ const void * cmdIoParam = pCmdIO->cmdIoParam;
+
+ union
+ {
+ uint32_t ul;
+ uint8_t b[ 4 ];
+ }
+ sUl;
+
+ sUl.ul = FreeRTOS_GetIPAddress();
+
+ bool linkUp = FreeRTOS_IsNetworkUp() == pdTRUE;
+
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "IP address: %d.%d.%d.%d\r\n", sUl.b[ 0 ], sUl.b[ 1 ], sUl.b[ 2 ], sUl.b[ 3 ] );
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "Link is: %s\r\n", linkUp ? "Up" : "Down" );
+
+ return true;
+ }
+
+#include "aws_application_version.h"
+
+static int _Command_Version(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv)
+{
+ configPRINTF( ( "App version - maj: %d, min: %d, build: %d\r\n", xAppFirmwareVersion.u.x.ucMajor, xAppFirmwareVersion.u.x.ucMinor, xAppFirmwareVersion.u.x.usBuild) );
+ return 0;
+}
+
+ #endif /* (PIC32_MAC_DEBUG_COMMANDS != 0) */
+#endif /* #ifdef PIC32_USE_ETHERNET */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_wifi.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_wifi.c
index fc8335ebe..a24cfe8ad 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_wifi.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_wifi.c
@@ -1,192 +1,192 @@
-/*******************************************************************************
-* Network Interface file
-*
-* Summary:
-* Network Interface file for FreeRTOS-Plus-TCP stack
-*
-* Description:
-* - Interfaces PIC32 to the FreeRTOS TCP/IP stack
-*******************************************************************************/
-
-/*******************************************************************************
-* File Name: pic32_NetworkInterface.c
-* Copyright 2017 Microchip Technology Incorporated and its subsidiaries.
-*
-* 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
-*******************************************************************************/
-#ifndef PIC32_USE_ETHERNET
-#include <sys/kmem.h>
-
-#include "FreeRTOS.h"
-#include "semphr.h"
-#include "event_groups.h"
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_IP_Private.h"
-
-#include "NetworkInterface.h"
-#include "NetworkBufferManagement.h"
-#include "peripheral/eth/plib_eth.h"
-
-#include "system_config.h"
-#include "system/console/sys_console.h"
-#include "system/debug/sys_debug.h"
-#include "system/command/sys_command.h"
-
-#include "driver/ethmac/drv_ethmac.h"
-#include "driver/miim/drv_miim.h"
-#include "m2m_types.h"
-
-#include "tcpip/tcpip.h"
-#include "tcpip/src/tcpip_private.h"
-#include "tcpip/src/link_list.h"
-#include "wilc1000_task.h"
-
-#include "NetworkConfig.h"
-
-
- #include "iot_wifi.h"
-
- /* local definitions and data */
-
-
- /* FreeRTOS implementation functions */
- BaseType_t xNetworkInterfaceInitialise( void )
- {
- WIFINetworkParams_t xNetworkParams;
-
- xNetworkParams.pcSSID = clientcredentialWIFI_SSID;
- xNetworkParams.ucSSIDLength = sizeof( clientcredentialWIFI_SSID );
- xNetworkParams.pcPassword = clientcredentialWIFI_PASSWORD;
- xNetworkParams.ucPasswordLength = sizeof( clientcredentialWIFI_PASSWORD );
- xNetworkParams.xSecurity = clientcredentialWIFI_SECURITY;
- xNetworkParams.cChannel = M2M_WIFI_CH_ALL; /* Scan all channels (255) */
-
- /*Turn WiFi ON */
- if( WIFI_On() != eWiFiSuccess )
- {
- return pdFAIL;
- }
-
- /* Connect to the AP */
- if( WIFI_ConnectAP( &xNetworkParams ) != eWiFiSuccess )
- {
- return pdFAIL;
- }
-
- return pdPASS;
- }
-
-
- /*-----------------------------------------------------------*/
-
- BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
- BaseType_t xReleaseAfterSend )
- {
- BaseType_t retRes = pdFALSE;
-
- if( ( pxDescriptor != 0 ) && ( pxDescriptor->pucEthernetBuffer != 0 ) && ( pxDescriptor->xDataLength != 0 ) )
- {
- /* There you go */
- if( WDRV_EXT_DataSend( pxDescriptor->xDataLength, pxDescriptor->pucEthernetBuffer ) == 0 )
- {
- retRes = pdTRUE;
- }
-
- /* The buffer has been sent so can be released. */
- if( xReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
- }
-
- return retRes;
- }
-
-
- /************************************* Section: helper functions ************************************************** */
- /* */
-
-
-
- /************************************* Section: worker code ************************************************** */
- /* */
-
- void xNetworkFrameReceived( uint32_t len,
- uint8_t const * const frame )
- {
- bool pktSuccess, pktLost;
- NetworkBufferDescriptor_t * pxNetworkBuffer = NULL;
- IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-
- pktSuccess = pktLost = false;
-
- while( true )
- {
- if( eConsiderFrameForProcessing( frame ) != eProcessBuffer )
- {
- break;
- }
-
- /* get the network descriptor (no data buffer) to hold this packet */
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( len, 0 );
-
- if( pxNetworkBuffer == NULL )
- {
- pktLost = true;
- break;
- }
-
- /* Set the actual packet length, in case a larger buffer was
- returned. */
- pxNetworkBuffer->xDataLength = len;
-
- /* Copy the packet. */
- memcpy( pxNetworkBuffer->pucEthernetBuffer, frame, len );
-
- /* Send the data to the TCP/IP stack. */
- xRxEvent.pvData = ( void * ) pxNetworkBuffer;
-
- if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
- { /* failed */
- pktLost = true;
- }
- else
- { /* success */
- pktSuccess = true;
- iptraceNETWORK_INTERFACE_RECEIVE();
- }
-
- break;
- }
-
- if( !pktSuccess )
- { /* smth went wrong; nothing sent to the */
- if( pxNetworkBuffer != NULL )
- {
- pxNetworkBuffer->pucEthernetBuffer = 0;
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- }
-
- if( pktLost )
- {
- iptraceETHERNET_RX_EVENT_LOST();
- }
- }
- }
-
-#endif /* #ifndef PIC32_USE_ETHERNET */
+/*******************************************************************************
+* Network Interface file
+*
+* Summary:
+* Network Interface file for FreeRTOS-Plus-TCP stack
+*
+* Description:
+* - Interfaces PIC32 to the FreeRTOS TCP/IP stack
+*******************************************************************************/
+
+/*******************************************************************************
+* File Name: pic32_NetworkInterface.c
+* Copyright 2017 Microchip Technology Incorporated and its subsidiaries.
+*
+* 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
+*******************************************************************************/
+#ifndef PIC32_USE_ETHERNET
+#include <sys/kmem.h>
+
+#include "FreeRTOS.h"
+#include "semphr.h"
+#include "event_groups.h"
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_IP_Private.h"
+
+#include "NetworkInterface.h"
+#include "NetworkBufferManagement.h"
+#include "peripheral/eth/plib_eth.h"
+
+#include "system_config.h"
+#include "system/console/sys_console.h"
+#include "system/debug/sys_debug.h"
+#include "system/command/sys_command.h"
+
+#include "driver/ethmac/drv_ethmac.h"
+#include "driver/miim/drv_miim.h"
+#include "m2m_types.h"
+
+#include "tcpip/tcpip.h"
+#include "tcpip/src/tcpip_private.h"
+#include "tcpip/src/link_list.h"
+#include "wilc1000_task.h"
+
+#include "NetworkConfig.h"
+
+
+ #include "iot_wifi.h"
+
+ /* local definitions and data */
+
+
+ /* FreeRTOS implementation functions */
+ BaseType_t xNetworkInterfaceInitialise( void )
+ {
+ WIFINetworkParams_t xNetworkParams;
+
+ xNetworkParams.pcSSID = clientcredentialWIFI_SSID;
+ xNetworkParams.ucSSIDLength = sizeof( clientcredentialWIFI_SSID );
+ xNetworkParams.pcPassword = clientcredentialWIFI_PASSWORD;
+ xNetworkParams.ucPasswordLength = sizeof( clientcredentialWIFI_PASSWORD );
+ xNetworkParams.xSecurity = clientcredentialWIFI_SECURITY;
+ xNetworkParams.cChannel = M2M_WIFI_CH_ALL; /* Scan all channels (255) */
+
+ /*Turn WiFi ON */
+ if( WIFI_On() != eWiFiSuccess )
+ {
+ return pdFAIL;
+ }
+
+ /* Connect to the AP */
+ if( WIFI_ConnectAP( &xNetworkParams ) != eWiFiSuccess )
+ {
+ return pdFAIL;
+ }
+
+ return pdPASS;
+ }
+
+
+ /*-----------------------------------------------------------*/
+
+ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
+ BaseType_t xReleaseAfterSend )
+ {
+ BaseType_t retRes = pdFALSE;
+
+ if( ( pxDescriptor != 0 ) && ( pxDescriptor->pucEthernetBuffer != 0 ) && ( pxDescriptor->xDataLength != 0 ) )
+ {
+ /* There you go */
+ if( WDRV_EXT_DataSend( pxDescriptor->xDataLength, pxDescriptor->pucEthernetBuffer ) == 0 )
+ {
+ retRes = pdTRUE;
+ }
+
+ /* The buffer has been sent so can be released. */
+ if( xReleaseAfterSend != pdFALSE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+ }
+
+ return retRes;
+ }
+
+
+ /************************************* Section: helper functions ************************************************** */
+ /* */
+
+
+
+ /************************************* Section: worker code ************************************************** */
+ /* */
+
+ void xNetworkFrameReceived( uint32_t len,
+ uint8_t const * const frame )
+ {
+ bool pktSuccess, pktLost;
+ NetworkBufferDescriptor_t * pxNetworkBuffer = NULL;
+ IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+
+ pktSuccess = pktLost = false;
+
+ while( true )
+ {
+ if( eConsiderFrameForProcessing( frame ) != eProcessBuffer )
+ {
+ break;
+ }
+
+ /* get the network descriptor (no data buffer) to hold this packet */
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( len, 0 );
+
+ if( pxNetworkBuffer == NULL )
+ {
+ pktLost = true;
+ break;
+ }
+
+ /* Set the actual packet length, in case a larger buffer was
+ returned. */
+ pxNetworkBuffer->xDataLength = len;
+
+ /* Copy the packet. */
+ memcpy( pxNetworkBuffer->pucEthernetBuffer, frame, len );
+
+ /* Send the data to the TCP/IP stack. */
+ xRxEvent.pvData = ( void * ) pxNetworkBuffer;
+
+ if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
+ { /* failed */
+ pktLost = true;
+ }
+ else
+ { /* success */
+ pktSuccess = true;
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ }
+
+ break;
+ }
+
+ if( !pktSuccess )
+ { /* smth went wrong; nothing sent to the */
+ if( pxNetworkBuffer != NULL )
+ {
+ pxNetworkBuffer->pucEthernetBuffer = 0;
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ }
+
+ if( pktLost )
+ {
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+ }
+ }
+
+#endif /* #ifndef PIC32_USE_ETHERNET */
diff --git a/FreeRTOS/History.txt b/FreeRTOS/History.txt
index 566db43d7..f7a545575 100644
--- a/FreeRTOS/History.txt
+++ b/FreeRTOS/History.txt
@@ -1,6 +1,6 @@
Documentation and download available at http://www.FreeRTOS.org/
-Changes between FreeRTOS V10.2.1 and FreeRTOS V10.3.0 released TBD
+Changes between FreeRTOS V10.2.1 and FreeRTOS V10.3.0 released February 7 2020
See http://www.FreeRTOS.org/FreeRTOS-V10.3.x.html
diff --git a/FreeRTOS/Source/include/task.h b/FreeRTOS/Source/include/task.h
index 286c5f221..b861483d0 100644
--- a/FreeRTOS/Source/include/task.h
+++ b/FreeRTOS/Source/include/task.h
@@ -43,10 +43,10 @@ extern "C" {
* MACROS AND DEFINITIONS
*----------------------------------------------------------*/
-#define tskKERNEL_VERSION_NUMBER "V10.2.1"
+#define tskKERNEL_VERSION_NUMBER "V10.3.0"
#define tskKERNEL_VERSION_MAJOR 10
-#define tskKERNEL_VERSION_MINOR 2
-#define tskKERNEL_VERSION_BUILD 1
+#define tskKERNEL_VERSION_MINOR 3
+#define tskKERNEL_VERSION_BUILD 0
/* MPU region parameters passed in ulParameters
* of MemoryRegion_t struct. */
diff --git a/Upgrading to FreeRTOS V10.3.0.url b/Upgrading to FreeRTOS V10.3.0.url
new file mode 100644
index 000000000..a30f01875
--- /dev/null
+++ b/Upgrading to FreeRTOS V10.3.0.url
@@ -0,0 +1,5 @@
+[{000214A0-0000-0000-C000-000000000046}]
+Prop3=19,11
+[InternetShortcut]
+IDList=
+URL=https://www.freertos.org/FreeRTOS-V10.3.x.html