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 0000000..17aca57
--- /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 0000000..cdbad17
--- /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 0000000..7fe533a
--- /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 3528269..83c96a0 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 ae40ac9..6eb069f 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 fc72c6a..fe9e296 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 6729df0..8ea5fa0 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 e4a3ba9..948f9a6 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 d741a2a..fca3ece 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 dd29dfe..24d806d 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 7cee711..e0d04e4 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 0b1f74d..ac01d41 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 6b926c8..e759141 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;
- }
-}
-