Initial version

This commit is contained in:
2019-06-28 23:08:36 +02:00
commit 4d8973e20b
2426 changed files with 948029 additions and 0 deletions

View File

@ -0,0 +1,649 @@
/*
* 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
#if( ipconfigZERO_COPY_RX_DRIVER != 0 )
#warning The EMAC of SAM4E has fixed-size RX buffers so ZERO_COPY_RX is not possible
#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( 0u, ( 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;
}
/*-----------------------------------------------------------*/
void vCheckBuffersAndQueue( void )
{
static UBaseType_t uxLastMinBufferCount = 0;
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
static UBaseType_t uxLastMinQueueSpace;
#endif
static UBaseType_t uxCurrentCount;
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
{
uxCurrentCount = uxGetMinimumIPQueueSpace();
if( uxLastMinQueueSpace != uxCurrentCount )
{
/* The logging produced below may be helpful
while tuning +TCP: see how many buffers are in use. */
uxLastMinQueueSpace = uxCurrentCount;
FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
}
}
#endif /* ipconfigCHECK_IP_QUEUE_SPACE */
uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
if( uxLastMinBufferCount != uxCurrentCount )
{
/* The logging produced below may be helpful
while tuning +TCP: see how many buffers are in use. */
uxLastMinBufferCount = uxCurrentCount;
FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
}
}
static void prvEMACHandlerTask( void *pvParameters )
{
TimeOut_t xPhyTime;
TickType_t xPhyRemTime;
UBaseType_t uxCount;
#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( ;; )
{
vCheckBuffersAndQueue();
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 );
}
}
}
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +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_ */

View File

@ -0,0 +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
/**
* \}
*/

View File

@ -0,0 +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 */

View File

@ -0,0 +1,945 @@
/**
* \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.
* http://community.atmel.com/forum/sam4e-gmac-transmit-checksum-offload-enablesolved
*/
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