mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-04 05:13:51 -04:00
This commit is contained in:
parent
589dd9f149
commit
7cf721ccf7
36 changed files with 15170 additions and 15098 deletions
|
@ -1,398 +1,398 @@
|
|||
/*
|
||||
FreeRTOS+TCP V2.0.11
|
||||
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
http://aws.amazon.com/freertos
|
||||
http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
#include "NetworkInterface.h"
|
||||
|
||||
/* Xilinx library files. */
|
||||
#include <xemacps.h>
|
||||
#include "Zynq/x_topology.h"
|
||||
#include "Zynq/x_emacpsif.h"
|
||||
#include "Zynq/x_emacpsif_hw.h"
|
||||
|
||||
/* Provided memory configured as uncached. */
|
||||
#include "uncached_memory.h"
|
||||
|
||||
#ifndef BMSR_LINK_STATUS
|
||||
#define BMSR_LINK_STATUS 0x0004UL
|
||||
#endif
|
||||
|
||||
#ifndef PHY_LS_HIGH_CHECK_TIME_MS
|
||||
/* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
|
||||
receiving packets. */
|
||||
#define PHY_LS_HIGH_CHECK_TIME_MS 15000
|
||||
#endif
|
||||
|
||||
#ifndef PHY_LS_LOW_CHECK_TIME_MS
|
||||
/* Check if the LinkSStatus in the PHY is still low every second. */
|
||||
#define PHY_LS_LOW_CHECK_TIME_MS 1000
|
||||
#endif
|
||||
|
||||
/* The size of each buffer when BufferAllocation_1 is used:
|
||||
http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */
|
||||
#define niBUFFER_1_PACKET_SIZE 1536
|
||||
|
||||
/* Naming and numbering of PHY registers. */
|
||||
#define PHY_REG_01_BMSR 0x01 /* Basic mode status register */
|
||||
|
||||
#ifndef iptraceEMAC_TASK_STARTING
|
||||
#define iptraceEMAC_TASK_STARTING() do { } while( 0 )
|
||||
#endif
|
||||
|
||||
/* Default the size of the stack used by the EMAC deferred handler task to twice
|
||||
the size of the stack used by the idle task - but allow this to be overridden in
|
||||
FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
|
||||
#ifndef configEMAC_TASK_STACK_SIZE
|
||||
#define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Look for the link to be up every few milliseconds until either xMaxTime time
|
||||
* has passed or a link is found.
|
||||
*/
|
||||
static BaseType_t prvGMACWaitLS( TickType_t xMaxTime );
|
||||
|
||||
/*
|
||||
* A deferred interrupt handler for all MAC/DMA interrupt sources.
|
||||
*/
|
||||
static void prvEMACHandlerTask( void *pvParameters );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* EMAC data/descriptions. */
|
||||
static xemacpsif_s xEMACpsif;
|
||||
struct xtopology_t xXTopology =
|
||||
{
|
||||
.emac_baseaddr = XPAR_PS7_ETHERNET_0_BASEADDR,
|
||||
.emac_type = xemac_type_emacps,
|
||||
.intc_baseaddr = 0x0,
|
||||
.intc_emac_intr = 0x0,
|
||||
.scugic_baseaddr = XPAR_PS7_SCUGIC_0_BASEADDR,
|
||||
.scugic_emac_intr = 0x36,
|
||||
};
|
||||
|
||||
XEmacPs_Config mac_config =
|
||||
{
|
||||
.DeviceId = XPAR_PS7_ETHERNET_0_DEVICE_ID, /**< Unique ID of device */
|
||||
.BaseAddress = XPAR_PS7_ETHERNET_0_BASEADDR /**< Physical base address of IPIF registers */
|
||||
};
|
||||
|
||||
extern int phy_detected;
|
||||
|
||||
/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
|
||||
static uint32_t ulPHYLinkStatus = 0;
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
|
||||
#endif
|
||||
|
||||
/* ucMACAddress as it appears in main.c */
|
||||
extern const uint8_t ucMACAddress[ 6 ];
|
||||
|
||||
/* Holds the handle of the task used as a deferred interrupt processor. The
|
||||
handle is used so direct notifications can be sent to the task for all EMAC/DMA
|
||||
related interrupts. */
|
||||
TaskHandle_t xEMACTaskHandle = NULL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xNetworkInterfaceInitialise( void )
|
||||
{
|
||||
uint32_t ulLinkSpeed, ulDMAReg;
|
||||
BaseType_t xStatus, xLinkStatus;
|
||||
XEmacPs *pxEMAC_PS;
|
||||
const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pdMS_TO_TICKS( 1000UL );
|
||||
|
||||
/* Guard against the init function being called more than once. */
|
||||
if( xEMACTaskHandle == NULL )
|
||||
{
|
||||
pxEMAC_PS = &( xEMACpsif.emacps );
|
||||
memset( &xEMACpsif, '\0', sizeof( xEMACpsif ) );
|
||||
|
||||
xStatus = XEmacPs_CfgInitialize( pxEMAC_PS, &mac_config, mac_config.BaseAddress);
|
||||
if( xStatus != XST_SUCCESS )
|
||||
{
|
||||
FreeRTOS_printf( ( "xEMACInit: EmacPs Configuration Failed....\n" ) );
|
||||
}
|
||||
|
||||
/* Initialize the mac and set the MAC address. */
|
||||
XEmacPs_SetMacAddress( pxEMAC_PS, ( void * ) ucMACAddress, 1 );
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
{
|
||||
/* Also add LLMNR multicast MAC address. */
|
||||
XEmacPs_SetMacAddress( pxEMAC_PS, ( void * )xLLMNR_MACAddress, 2 );
|
||||
}
|
||||
#endif /* ipconfigUSE_LLMNR == 1 */
|
||||
|
||||
XEmacPs_SetMdioDivisor( pxEMAC_PS, MDC_DIV_224 );
|
||||
ulLinkSpeed = Phy_Setup( pxEMAC_PS );
|
||||
XEmacPs_SetOperatingSpeed( pxEMAC_PS, ulLinkSpeed);
|
||||
|
||||
/* Setting the operating speed of the MAC needs a delay. */
|
||||
vTaskDelay( pdMS_TO_TICKS( 25UL ) );
|
||||
|
||||
ulDMAReg = XEmacPs_ReadReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET);
|
||||
|
||||
/* DISC_WHEN_NO_AHB: when set, the GEM DMA will automatically discard receive
|
||||
packets from the receiver packet buffer memory when no AHB resource is available. */
|
||||
XEmacPs_WriteReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET,
|
||||
ulDMAReg | XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK);
|
||||
|
||||
setup_isr( &xEMACpsif );
|
||||
init_dma( &xEMACpsif );
|
||||
start_emacps( &xEMACpsif );
|
||||
|
||||
prvGMACWaitLS( xWaitLinkDelay );
|
||||
|
||||
/* The deferred interrupt handler task is created at the highest
|
||||
possible priority to ensure the interrupt handler can return directly
|
||||
to it. The task's handle is stored in xEMACTaskHandle so interrupts can
|
||||
notify the task when there is something to process. */
|
||||
xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialisation was already performed, just wait for the link. */
|
||||
prvGMACWaitLS( xWaitRelinkDelay );
|
||||
}
|
||||
|
||||
/* Only return pdTRUE when the Link Status of the PHY is high, otherwise the
|
||||
DHCP process and all other communication will fail. */
|
||||
xLinkStatus = xGetPhyLinkStatus();
|
||||
|
||||
return ( xLinkStatus != pdFALSE );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )
|
||||
{
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
|
||||
{
|
||||
iptraceNETWORK_INTERFACE_TRANSMIT();
|
||||
emacps_send_message( &xEMACpsif, pxBuffer, bReleaseAfterSend );
|
||||
}
|
||||
else if( bReleaseAfterSend != pdFALSE )
|
||||
{
|
||||
/* No link. */
|
||||
vReleaseNetworkBufferAndDescriptor( pxBuffer );
|
||||
}
|
||||
|
||||
return pdTRUE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static inline unsigned long ulReadMDIO( unsigned ulRegister )
|
||||
{
|
||||
uint16_t usValue;
|
||||
|
||||
XEmacPs_PhyRead( &( xEMACpsif.emacps ), phy_detected, ulRegister, &usValue );
|
||||
return usValue;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvGMACWaitLS( TickType_t xMaxTime )
|
||||
{
|
||||
TickType_t xStartTime, xEndTime;
|
||||
const TickType_t xShortDelay = pdMS_TO_TICKS( 20UL );
|
||||
BaseType_t xReturn;
|
||||
|
||||
xStartTime = xTaskGetTickCount();
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
xEndTime = xTaskGetTickCount();
|
||||
|
||||
if( xEndTime - xStartTime > xMaxTime )
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
break;
|
||||
}
|
||||
ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
|
||||
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
vTaskDelay( xShortDelay );
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
|
||||
{
|
||||
static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
|
||||
uint8_t *ucRAMBuffer = ucNetworkPackets;
|
||||
uint32_t ul;
|
||||
|
||||
for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
|
||||
{
|
||||
pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
|
||||
*( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
|
||||
ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xGetPhyLinkStatus( void )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvEMACHandlerTask( void *pvParameters )
|
||||
{
|
||||
TimeOut_t xPhyTime;
|
||||
TickType_t xPhyRemTime;
|
||||
UBaseType_t uxLastMinBufferCount = 0;
|
||||
UBaseType_t uxCurrentCount;
|
||||
BaseType_t xResult = 0;
|
||||
uint32_t xStatus;
|
||||
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
|
||||
|
||||
/* Remove compiler warnings about unused parameters. */
|
||||
( void ) pvParameters;
|
||||
|
||||
/* A possibility to set some additional task properties like calling
|
||||
portTASK_USES_FLOATING_POINT() */
|
||||
iptraceEMAC_TASK_STARTING();
|
||||
|
||||
vTaskSetTimeOutState( &xPhyTime );
|
||||
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
|
||||
if( uxLastMinBufferCount != uxCurrentCount )
|
||||
{
|
||||
/* The logging produced below may be helpful
|
||||
while tuning +TCP: see how many buffers are in use. */
|
||||
uxLastMinBufferCount = uxCurrentCount;
|
||||
FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
|
||||
uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
|
||||
}
|
||||
|
||||
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
|
||||
{
|
||||
static UBaseType_t uxLastMinQueueSpace = 0;
|
||||
|
||||
uxCurrentCount = uxGetMinimumIPQueueSpace();
|
||||
if( uxLastMinQueueSpace != uxCurrentCount )
|
||||
{
|
||||
/* The logging produced below may be helpful
|
||||
while tuning +TCP: see how many buffers are in use. */
|
||||
uxLastMinQueueSpace = uxCurrentCount;
|
||||
FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigCHECK_IP_QUEUE_SPACE */
|
||||
|
||||
if( ( xEMACpsif.isr_events & EMAC_IF_ALL_EVENT ) == 0 )
|
||||
{
|
||||
/* No events to process now, wait for the next. */
|
||||
ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
|
||||
}
|
||||
|
||||
if( ( xEMACpsif.isr_events & EMAC_IF_RX_EVENT ) != 0 )
|
||||
{
|
||||
xEMACpsif.isr_events &= ~EMAC_IF_RX_EVENT;
|
||||
xResult = emacps_check_rx( &xEMACpsif );
|
||||
}
|
||||
|
||||
if( ( xEMACpsif.isr_events & EMAC_IF_TX_EVENT ) != 0 )
|
||||
{
|
||||
xEMACpsif.isr_events &= ~EMAC_IF_TX_EVENT;
|
||||
emacps_check_tx( &xEMACpsif );
|
||||
}
|
||||
|
||||
if( ( xEMACpsif.isr_events & EMAC_IF_ERR_EVENT ) != 0 )
|
||||
{
|
||||
xEMACpsif.isr_events &= ~EMAC_IF_ERR_EVENT;
|
||||
emacps_check_errors( &xEMACpsif );
|
||||
}
|
||||
|
||||
if( xResult > 0 )
|
||||
{
|
||||
/* A packet was received. No need to check for the PHY status now,
|
||||
but set a timer to check it later on. */
|
||||
vTaskSetTimeOutState( &xPhyTime );
|
||||
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
|
||||
xResult = 0;
|
||||
}
|
||||
else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
|
||||
{
|
||||
xStatus = ulReadMDIO( PHY_REG_01_BMSR );
|
||||
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
|
||||
{
|
||||
ulPHYLinkStatus = xStatus;
|
||||
FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
|
||||
}
|
||||
|
||||
vTaskSetTimeOutState( &xPhyTime );
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
|
||||
{
|
||||
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
|
||||
}
|
||||
else
|
||||
{
|
||||
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
/*
|
||||
FreeRTOS+TCP V2.0.11
|
||||
Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
http://aws.amazon.com/freertos
|
||||
http://www.FreeRTOS.org
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
#include "NetworkInterface.h"
|
||||
|
||||
/* Xilinx library files. */
|
||||
#include <xemacps.h>
|
||||
#include "Zynq/x_topology.h"
|
||||
#include "Zynq/x_emacpsif.h"
|
||||
#include "Zynq/x_emacpsif_hw.h"
|
||||
|
||||
/* Provided memory configured as uncached. */
|
||||
#include "uncached_memory.h"
|
||||
|
||||
#ifndef BMSR_LINK_STATUS
|
||||
#define BMSR_LINK_STATUS 0x0004UL
|
||||
#endif
|
||||
|
||||
#ifndef PHY_LS_HIGH_CHECK_TIME_MS
|
||||
/* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
|
||||
receiving packets. */
|
||||
#define PHY_LS_HIGH_CHECK_TIME_MS 15000
|
||||
#endif
|
||||
|
||||
#ifndef PHY_LS_LOW_CHECK_TIME_MS
|
||||
/* Check if the LinkSStatus in the PHY is still low every second. */
|
||||
#define PHY_LS_LOW_CHECK_TIME_MS 1000
|
||||
#endif
|
||||
|
||||
/* The size of each buffer when BufferAllocation_1 is used:
|
||||
http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */
|
||||
#define niBUFFER_1_PACKET_SIZE 1536
|
||||
|
||||
/* Naming and numbering of PHY registers. */
|
||||
#define PHY_REG_01_BMSR 0x01 /* Basic mode status register */
|
||||
|
||||
#ifndef iptraceEMAC_TASK_STARTING
|
||||
#define iptraceEMAC_TASK_STARTING() do { } while( 0 )
|
||||
#endif
|
||||
|
||||
/* Default the size of the stack used by the EMAC deferred handler task to twice
|
||||
the size of the stack used by the idle task - but allow this to be overridden in
|
||||
FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
|
||||
#ifndef configEMAC_TASK_STACK_SIZE
|
||||
#define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Look for the link to be up every few milliseconds until either xMaxTime time
|
||||
* has passed or a link is found.
|
||||
*/
|
||||
static BaseType_t prvGMACWaitLS( TickType_t xMaxTime );
|
||||
|
||||
/*
|
||||
* A deferred interrupt handler for all MAC/DMA interrupt sources.
|
||||
*/
|
||||
static void prvEMACHandlerTask( void *pvParameters );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* EMAC data/descriptions. */
|
||||
static xemacpsif_s xEMACpsif;
|
||||
struct xtopology_t xXTopology =
|
||||
{
|
||||
.emac_baseaddr = XPAR_PS7_ETHERNET_0_BASEADDR,
|
||||
.emac_type = xemac_type_emacps,
|
||||
.intc_baseaddr = 0x0,
|
||||
.intc_emac_intr = 0x0,
|
||||
.scugic_baseaddr = XPAR_PS7_SCUGIC_0_BASEADDR,
|
||||
.scugic_emac_intr = 0x36,
|
||||
};
|
||||
|
||||
XEmacPs_Config mac_config =
|
||||
{
|
||||
.DeviceId = XPAR_PS7_ETHERNET_0_DEVICE_ID, /**< Unique ID of device */
|
||||
.BaseAddress = XPAR_PS7_ETHERNET_0_BASEADDR /**< Physical base address of IPIF registers */
|
||||
};
|
||||
|
||||
extern int phy_detected;
|
||||
|
||||
/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
|
||||
static uint32_t ulPHYLinkStatus = 0;
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
|
||||
#endif
|
||||
|
||||
/* ucMACAddress as it appears in main.c */
|
||||
extern const uint8_t ucMACAddress[ 6 ];
|
||||
|
||||
/* Holds the handle of the task used as a deferred interrupt processor. The
|
||||
handle is used so direct notifications can be sent to the task for all EMAC/DMA
|
||||
related interrupts. */
|
||||
TaskHandle_t xEMACTaskHandle = NULL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xNetworkInterfaceInitialise( void )
|
||||
{
|
||||
uint32_t ulLinkSpeed, ulDMAReg;
|
||||
BaseType_t xStatus, xLinkStatus;
|
||||
XEmacPs *pxEMAC_PS;
|
||||
const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pdMS_TO_TICKS( 1000UL );
|
||||
|
||||
/* Guard against the init function being called more than once. */
|
||||
if( xEMACTaskHandle == NULL )
|
||||
{
|
||||
pxEMAC_PS = &( xEMACpsif.emacps );
|
||||
memset( &xEMACpsif, '\0', sizeof( xEMACpsif ) );
|
||||
|
||||
xStatus = XEmacPs_CfgInitialize( pxEMAC_PS, &mac_config, mac_config.BaseAddress);
|
||||
if( xStatus != XST_SUCCESS )
|
||||
{
|
||||
FreeRTOS_printf( ( "xEMACInit: EmacPs Configuration Failed....\n" ) );
|
||||
}
|
||||
|
||||
/* Initialize the mac and set the MAC address. */
|
||||
XEmacPs_SetMacAddress( pxEMAC_PS, ( void * ) ucMACAddress, 1 );
|
||||
|
||||
#if( ipconfigUSE_LLMNR == 1 )
|
||||
{
|
||||
/* Also add LLMNR multicast MAC address. */
|
||||
XEmacPs_SetMacAddress( pxEMAC_PS, ( void * )xLLMNR_MACAddress, 2 );
|
||||
}
|
||||
#endif /* ipconfigUSE_LLMNR == 1 */
|
||||
|
||||
XEmacPs_SetMdioDivisor( pxEMAC_PS, MDC_DIV_224 );
|
||||
ulLinkSpeed = Phy_Setup( pxEMAC_PS );
|
||||
XEmacPs_SetOperatingSpeed( pxEMAC_PS, ulLinkSpeed);
|
||||
|
||||
/* Setting the operating speed of the MAC needs a delay. */
|
||||
vTaskDelay( pdMS_TO_TICKS( 25UL ) );
|
||||
|
||||
ulDMAReg = XEmacPs_ReadReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET);
|
||||
|
||||
/* DISC_WHEN_NO_AHB: when set, the GEM DMA will automatically discard receive
|
||||
packets from the receiver packet buffer memory when no AHB resource is available. */
|
||||
XEmacPs_WriteReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET,
|
||||
ulDMAReg | XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK);
|
||||
|
||||
setup_isr( &xEMACpsif );
|
||||
init_dma( &xEMACpsif );
|
||||
start_emacps( &xEMACpsif );
|
||||
|
||||
prvGMACWaitLS( xWaitLinkDelay );
|
||||
|
||||
/* The deferred interrupt handler task is created at the highest
|
||||
possible priority to ensure the interrupt handler can return directly
|
||||
to it. The task's handle is stored in xEMACTaskHandle so interrupts can
|
||||
notify the task when there is something to process. */
|
||||
xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialisation was already performed, just wait for the link. */
|
||||
prvGMACWaitLS( xWaitRelinkDelay );
|
||||
}
|
||||
|
||||
/* Only return pdTRUE when the Link Status of the PHY is high, otherwise the
|
||||
DHCP process and all other communication will fail. */
|
||||
xLinkStatus = xGetPhyLinkStatus();
|
||||
|
||||
return ( xLinkStatus != pdFALSE );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )
|
||||
{
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
|
||||
{
|
||||
iptraceNETWORK_INTERFACE_TRANSMIT();
|
||||
emacps_send_message( &xEMACpsif, pxBuffer, bReleaseAfterSend );
|
||||
}
|
||||
else if( bReleaseAfterSend != pdFALSE )
|
||||
{
|
||||
/* No link. */
|
||||
vReleaseNetworkBufferAndDescriptor( pxBuffer );
|
||||
}
|
||||
|
||||
return pdTRUE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static inline unsigned long ulReadMDIO( unsigned ulRegister )
|
||||
{
|
||||
uint16_t usValue;
|
||||
|
||||
XEmacPs_PhyRead( &( xEMACpsif.emacps ), phy_detected, ulRegister, &usValue );
|
||||
return usValue;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvGMACWaitLS( TickType_t xMaxTime )
|
||||
{
|
||||
TickType_t xStartTime, xEndTime;
|
||||
const TickType_t xShortDelay = pdMS_TO_TICKS( 20UL );
|
||||
BaseType_t xReturn;
|
||||
|
||||
xStartTime = xTaskGetTickCount();
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
xEndTime = xTaskGetTickCount();
|
||||
|
||||
if( xEndTime - xStartTime > xMaxTime )
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
break;
|
||||
}
|
||||
ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
|
||||
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
vTaskDelay( xShortDelay );
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
|
||||
{
|
||||
static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
|
||||
uint8_t *ucRAMBuffer = ucNetworkPackets;
|
||||
uint32_t ul;
|
||||
|
||||
for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
|
||||
{
|
||||
pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
|
||||
*( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
|
||||
ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xGetPhyLinkStatus( void )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvEMACHandlerTask( void *pvParameters )
|
||||
{
|
||||
TimeOut_t xPhyTime;
|
||||
TickType_t xPhyRemTime;
|
||||
UBaseType_t uxLastMinBufferCount = 0;
|
||||
UBaseType_t uxCurrentCount;
|
||||
BaseType_t xResult = 0;
|
||||
uint32_t xStatus;
|
||||
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
|
||||
|
||||
/* Remove compiler warnings about unused parameters. */
|
||||
( void ) pvParameters;
|
||||
|
||||
/* A possibility to set some additional task properties like calling
|
||||
portTASK_USES_FLOATING_POINT() */
|
||||
iptraceEMAC_TASK_STARTING();
|
||||
|
||||
vTaskSetTimeOutState( &xPhyTime );
|
||||
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
|
||||
if( uxLastMinBufferCount != uxCurrentCount )
|
||||
{
|
||||
/* The logging produced below may be helpful
|
||||
while tuning +TCP: see how many buffers are in use. */
|
||||
uxLastMinBufferCount = uxCurrentCount;
|
||||
FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
|
||||
uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
|
||||
}
|
||||
|
||||
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
|
||||
{
|
||||
static UBaseType_t uxLastMinQueueSpace = 0;
|
||||
|
||||
uxCurrentCount = uxGetMinimumIPQueueSpace();
|
||||
if( uxLastMinQueueSpace != uxCurrentCount )
|
||||
{
|
||||
/* The logging produced below may be helpful
|
||||
while tuning +TCP: see how many buffers are in use. */
|
||||
uxLastMinQueueSpace = uxCurrentCount;
|
||||
FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
|
||||
}
|
||||
}
|
||||
#endif /* ipconfigCHECK_IP_QUEUE_SPACE */
|
||||
|
||||
if( ( xEMACpsif.isr_events & EMAC_IF_ALL_EVENT ) == 0 )
|
||||
{
|
||||
/* No events to process now, wait for the next. */
|
||||
ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
|
||||
}
|
||||
|
||||
if( ( xEMACpsif.isr_events & EMAC_IF_RX_EVENT ) != 0 )
|
||||
{
|
||||
xEMACpsif.isr_events &= ~EMAC_IF_RX_EVENT;
|
||||
xResult = emacps_check_rx( &xEMACpsif );
|
||||
}
|
||||
|
||||
if( ( xEMACpsif.isr_events & EMAC_IF_TX_EVENT ) != 0 )
|
||||
{
|
||||
xEMACpsif.isr_events &= ~EMAC_IF_TX_EVENT;
|
||||
emacps_check_tx( &xEMACpsif );
|
||||
}
|
||||
|
||||
if( ( xEMACpsif.isr_events & EMAC_IF_ERR_EVENT ) != 0 )
|
||||
{
|
||||
xEMACpsif.isr_events &= ~EMAC_IF_ERR_EVENT;
|
||||
emacps_check_errors( &xEMACpsif );
|
||||
}
|
||||
|
||||
if( xResult > 0 )
|
||||
{
|
||||
/* A packet was received. No need to check for the PHY status now,
|
||||
but set a timer to check it later on. */
|
||||
vTaskSetTimeOutState( &xPhyTime );
|
||||
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
|
||||
xResult = 0;
|
||||
}
|
||||
else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
|
||||
{
|
||||
xStatus = ulReadMDIO( PHY_REG_01_BMSR );
|
||||
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
|
||||
{
|
||||
ulPHYLinkStatus = xStatus;
|
||||
FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
|
||||
}
|
||||
|
||||
vTaskSetTimeOutState( &xPhyTime );
|
||||
if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
|
||||
{
|
||||
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
|
||||
}
|
||||
else
|
||||
{
|
||||
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
@ -1,144 +1,144 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Xilinx, Inc.
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
|
||||
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
|
||||
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
|
||||
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
|
||||
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NETIF_XEMACPSIF_H__
|
||||
#define __NETIF_XEMACPSIF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "xstatus.h"
|
||||
#include "sleep.h"
|
||||
#include "xparameters.h"
|
||||
#include "xparameters_ps.h" /* defines XPAR values */
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xil_io.h"
|
||||
#include "xil_exception.h"
|
||||
#include "xpseudo_asm.h"
|
||||
#include "xil_cache.h"
|
||||
#include "xil_printf.h"
|
||||
#include "xuartps.h"
|
||||
#include "xscugic.h"
|
||||
#include "xemacps.h" /* defines XEmacPs API */
|
||||
|
||||
//#include "netif/xpqueue.h"
|
||||
//#include "xlwipconfig.h"
|
||||
|
||||
void xemacpsif_setmac(uint32_t index, uint8_t *addr);
|
||||
uint8_t* xemacpsif_getmac(uint32_t index);
|
||||
//int xemacpsif_init(struct netif *netif);
|
||||
//int xemacpsif_input(struct netif *netif);
|
||||
#ifdef NOTNOW_BHILL
|
||||
unsigned get_IEEE_phy_speed(XLlTemac *xlltemacp);
|
||||
#endif
|
||||
|
||||
/* xaxiemacif_hw.c */
|
||||
void xemacps_error_handler(XEmacPs * Temac);
|
||||
|
||||
struct xBD_TYPE {
|
||||
uint32_t address;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
/*
|
||||
* Missing declaration in 'src/xemacps_hw.h' :
|
||||
* When set, the GEM DMA will automatically
|
||||
* discard receive packets from the receiver packet
|
||||
* buffer memory when no AHB resource is
|
||||
* available.
|
||||
* When low, then received packets will remain to be
|
||||
* stored in the SRAM based packet buffer until
|
||||
* AHB buffer resource next becomes available.
|
||||
*/
|
||||
#define XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK 0x01000000
|
||||
|
||||
#define EMAC_IF_RX_EVENT 1
|
||||
#define EMAC_IF_TX_EVENT 2
|
||||
#define EMAC_IF_ERR_EVENT 4
|
||||
#define EMAC_IF_ALL_EVENT 7
|
||||
|
||||
/* structure within each netif, encapsulating all information required for
|
||||
* using a particular temac instance
|
||||
*/
|
||||
typedef struct {
|
||||
XEmacPs emacps;
|
||||
|
||||
/* pointers to memory holding buffer descriptors (used only with SDMA) */
|
||||
struct xBD_TYPE *rxSegments;
|
||||
struct xBD_TYPE *txSegments;
|
||||
|
||||
unsigned char *tx_space;
|
||||
unsigned uTxUnitSize;
|
||||
|
||||
char *remain_mem;
|
||||
unsigned remain_siz;
|
||||
|
||||
volatile int rxHead, rxTail;
|
||||
volatile int txHead, txTail;
|
||||
|
||||
volatile int txBusy;
|
||||
|
||||
volatile uint32_t isr_events;
|
||||
|
||||
unsigned int last_rx_frms_cntr;
|
||||
|
||||
} xemacpsif_s;
|
||||
|
||||
//extern xemacpsif_s xemacpsif;
|
||||
|
||||
int is_tx_space_available(xemacpsif_s *emac);
|
||||
|
||||
/* xaxiemacif_dma.c */
|
||||
|
||||
struct xNETWORK_BUFFER;
|
||||
|
||||
int emacps_check_rx( xemacpsif_s *xemacpsif );
|
||||
void emacps_check_tx( xemacpsif_s *xemacpsif );
|
||||
int emacps_check_errors( xemacpsif_s *xemacps );
|
||||
void emacps_set_rx_buffers( xemacpsif_s *xemacpsif, u32 ulCount );
|
||||
|
||||
extern XStatus emacps_send_message(xemacpsif_s *xemacpsif, struct xNETWORK_BUFFER *pxBuffer, int iReleaseAfterSend );
|
||||
extern unsigned Phy_Setup( XEmacPs *xemacpsp );
|
||||
extern void setup_isr( xemacpsif_s *xemacpsif );
|
||||
extern XStatus init_dma( xemacpsif_s *xemacpsif );
|
||||
extern void start_emacps( xemacpsif_s *xemacpsif );
|
||||
|
||||
void EmacEnableIntr(void);
|
||||
void EmacDisableIntr(void);
|
||||
|
||||
XStatus init_axi_dma(xemacpsif_s *xemacpsif);
|
||||
void process_sent_bds( xemacpsif_s *xemacpsif );
|
||||
|
||||
void emacps_send_handler(void *arg);
|
||||
void emacps_recv_handler(void *arg);
|
||||
void emacps_error_handler(void *arg,u8 Direction, u32 ErrorWord);
|
||||
void HandleTxErrors(xemacpsif_s *xemacpsif);
|
||||
XEmacPs_Config *xemacps_lookup_config(unsigned mac_base);
|
||||
|
||||
void clean_dma_txdescs(xemacpsif_s *xemacpsif);
|
||||
void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __NETIF_XAXIEMACIF_H__ */
|
||||
/*
|
||||
* Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Xilinx, Inc.
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
|
||||
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
|
||||
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
|
||||
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
|
||||
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NETIF_XEMACPSIF_H__
|
||||
#define __NETIF_XEMACPSIF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "xstatus.h"
|
||||
#include "sleep.h"
|
||||
#include "xparameters.h"
|
||||
#include "xparameters_ps.h" /* defines XPAR values */
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xil_io.h"
|
||||
#include "xil_exception.h"
|
||||
#include "xpseudo_asm.h"
|
||||
#include "xil_cache.h"
|
||||
#include "xil_printf.h"
|
||||
#include "xuartps.h"
|
||||
#include "xscugic.h"
|
||||
#include "xemacps.h" /* defines XEmacPs API */
|
||||
|
||||
//#include "netif/xpqueue.h"
|
||||
//#include "xlwipconfig.h"
|
||||
|
||||
void xemacpsif_setmac(uint32_t index, uint8_t *addr);
|
||||
uint8_t* xemacpsif_getmac(uint32_t index);
|
||||
//int xemacpsif_init(struct netif *netif);
|
||||
//int xemacpsif_input(struct netif *netif);
|
||||
#ifdef NOTNOW_BHILL
|
||||
unsigned get_IEEE_phy_speed(XLlTemac *xlltemacp);
|
||||
#endif
|
||||
|
||||
/* xaxiemacif_hw.c */
|
||||
void xemacps_error_handler(XEmacPs * Temac);
|
||||
|
||||
struct xBD_TYPE {
|
||||
uint32_t address;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
/*
|
||||
* Missing declaration in 'src/xemacps_hw.h' :
|
||||
* When set, the GEM DMA will automatically
|
||||
* discard receive packets from the receiver packet
|
||||
* buffer memory when no AHB resource is
|
||||
* available.
|
||||
* When low, then received packets will remain to be
|
||||
* stored in the SRAM based packet buffer until
|
||||
* AHB buffer resource next becomes available.
|
||||
*/
|
||||
#define XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK 0x01000000
|
||||
|
||||
#define EMAC_IF_RX_EVENT 1
|
||||
#define EMAC_IF_TX_EVENT 2
|
||||
#define EMAC_IF_ERR_EVENT 4
|
||||
#define EMAC_IF_ALL_EVENT 7
|
||||
|
||||
/* structure within each netif, encapsulating all information required for
|
||||
* using a particular temac instance
|
||||
*/
|
||||
typedef struct {
|
||||
XEmacPs emacps;
|
||||
|
||||
/* pointers to memory holding buffer descriptors (used only with SDMA) */
|
||||
struct xBD_TYPE *rxSegments;
|
||||
struct xBD_TYPE *txSegments;
|
||||
|
||||
unsigned char *tx_space;
|
||||
unsigned uTxUnitSize;
|
||||
|
||||
char *remain_mem;
|
||||
unsigned remain_siz;
|
||||
|
||||
volatile int rxHead, rxTail;
|
||||
volatile int txHead, txTail;
|
||||
|
||||
volatile int txBusy;
|
||||
|
||||
volatile uint32_t isr_events;
|
||||
|
||||
unsigned int last_rx_frms_cntr;
|
||||
|
||||
} xemacpsif_s;
|
||||
|
||||
//extern xemacpsif_s xemacpsif;
|
||||
|
||||
int is_tx_space_available(xemacpsif_s *emac);
|
||||
|
||||
/* xaxiemacif_dma.c */
|
||||
|
||||
struct xNETWORK_BUFFER;
|
||||
|
||||
int emacps_check_rx( xemacpsif_s *xemacpsif );
|
||||
void emacps_check_tx( xemacpsif_s *xemacpsif );
|
||||
int emacps_check_errors( xemacpsif_s *xemacps );
|
||||
void emacps_set_rx_buffers( xemacpsif_s *xemacpsif, u32 ulCount );
|
||||
|
||||
extern XStatus emacps_send_message(xemacpsif_s *xemacpsif, struct xNETWORK_BUFFER *pxBuffer, int iReleaseAfterSend );
|
||||
extern unsigned Phy_Setup( XEmacPs *xemacpsp );
|
||||
extern void setup_isr( xemacpsif_s *xemacpsif );
|
||||
extern XStatus init_dma( xemacpsif_s *xemacpsif );
|
||||
extern void start_emacps( xemacpsif_s *xemacpsif );
|
||||
|
||||
void EmacEnableIntr(void);
|
||||
void EmacDisableIntr(void);
|
||||
|
||||
XStatus init_axi_dma(xemacpsif_s *xemacpsif);
|
||||
void process_sent_bds( xemacpsif_s *xemacpsif );
|
||||
|
||||
void emacps_send_handler(void *arg);
|
||||
void emacps_recv_handler(void *arg);
|
||||
void emacps_error_handler(void *arg,u8 Direction, u32 ErrorWord);
|
||||
void HandleTxErrors(xemacpsif_s *xemacpsif);
|
||||
XEmacPs_Config *xemacps_lookup_config(unsigned mac_base);
|
||||
|
||||
void clean_dma_txdescs(xemacpsif_s *xemacpsif);
|
||||
void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __NETIF_XAXIEMACIF_H__ */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,243 +1,243 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Xilinx, Inc.
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
|
||||
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
|
||||
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
|
||||
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
|
||||
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Zynq/x_emacpsif.h"
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
|
||||
///* FreeRTOS+TCP includes. */
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
|
||||
extern TaskHandle_t xEMACTaskHandle;
|
||||
|
||||
/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
|
||||
*** to run it on a PEEP board
|
||||
***/
|
||||
|
||||
unsigned int link_speed = 100;
|
||||
|
||||
void setup_isr( xemacpsif_s *xemacpsif )
|
||||
{
|
||||
/*
|
||||
* Setup callbacks
|
||||
*/
|
||||
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMASEND,
|
||||
(void *) emacps_send_handler,
|
||||
(void *) xemacpsif);
|
||||
|
||||
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMARECV,
|
||||
(void *) emacps_recv_handler,
|
||||
(void *) xemacpsif);
|
||||
|
||||
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_ERROR,
|
||||
(void *) emacps_error_handler,
|
||||
(void *) xemacpsif);
|
||||
}
|
||||
|
||||
void start_emacps (xemacpsif_s *xemacps)
|
||||
{
|
||||
/* start the temac */
|
||||
XEmacPs_Start(&xemacps->emacps);
|
||||
}
|
||||
|
||||
extern struct xtopology_t xXTopology;
|
||||
|
||||
volatile int error_msg_count = 0;
|
||||
volatile const char *last_err_msg = "";
|
||||
|
||||
struct xERROR_MSG {
|
||||
void *arg;
|
||||
u8 Direction;
|
||||
u32 ErrorWord;
|
||||
};
|
||||
|
||||
static struct xERROR_MSG xErrorList[ 8 ];
|
||||
static BaseType_t xErrorHead, xErrorTail;
|
||||
|
||||
void emacps_error_handler(void *arg, u8 Direction, u32 ErrorWord)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xemacpsif_s *xemacpsif;
|
||||
BaseType_t xNextHead = xErrorHead;
|
||||
|
||||
xemacpsif = (xemacpsif_s *)(arg);
|
||||
|
||||
if( ( Direction != XEMACPS_SEND ) || (ErrorWord != XEMACPS_TXSR_USEDREAD_MASK ) )
|
||||
{
|
||||
if( ++xNextHead == ( sizeof( xErrorList ) / sizeof( xErrorList[ 0 ] ) ) )
|
||||
xNextHead = 0;
|
||||
if( xNextHead != xErrorTail )
|
||||
{
|
||||
|
||||
xErrorList[ xErrorHead ].arg = arg;
|
||||
xErrorList[ xErrorHead ].Direction = Direction;
|
||||
xErrorList[ xErrorHead ].ErrorWord = ErrorWord;
|
||||
|
||||
xErrorHead = xNextHead;
|
||||
|
||||
xemacpsif = (xemacpsif_s *)(arg);
|
||||
xemacpsif->isr_events |= EMAC_IF_ERR_EVENT;
|
||||
}
|
||||
|
||||
if( xEMACTaskHandle != NULL )
|
||||
{
|
||||
vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
|
||||
static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord);
|
||||
|
||||
int emacps_check_errors( xemacpsif_s *xemacps )
|
||||
{
|
||||
int xResult;
|
||||
|
||||
( void ) xemacps;
|
||||
|
||||
if( xErrorHead == xErrorTail )
|
||||
{
|
||||
xResult = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
xResult = 1;
|
||||
emacps_handle_error(
|
||||
xErrorList[ xErrorTail ].arg,
|
||||
xErrorList[ xErrorTail ].Direction,
|
||||
xErrorList[ xErrorTail ].ErrorWord );
|
||||
}
|
||||
|
||||
return xResult;
|
||||
}
|
||||
|
||||
BaseType_t xNetworkInterfaceInitialise( void );
|
||||
|
||||
static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
|
||||
{
|
||||
xemacpsif_s *xemacpsif;
|
||||
struct xtopology_t *xtopologyp;
|
||||
XEmacPs *xemacps;
|
||||
|
||||
xemacpsif = (xemacpsif_s *)(arg);
|
||||
|
||||
xtopologyp = &xXTopology;
|
||||
|
||||
xemacps = &xemacpsif->emacps;
|
||||
|
||||
/* Do not appear to be used. */
|
||||
( void ) xemacps;
|
||||
( void ) xtopologyp;
|
||||
|
||||
last_err_msg = NULL;
|
||||
|
||||
if( ErrorWord != 0 )
|
||||
{
|
||||
switch (Direction) {
|
||||
case XEMACPS_RECV:
|
||||
if( ( ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Receive DMA error";
|
||||
xNetworkInterfaceInitialise( );
|
||||
}
|
||||
if( ( ErrorWord & XEMACPS_RXSR_RXOVR_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Receive over run";
|
||||
emacps_recv_handler(arg);
|
||||
}
|
||||
if( ( ErrorWord & XEMACPS_RXSR_BUFFNA_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Receive buffer not available";
|
||||
emacps_recv_handler(arg);
|
||||
}
|
||||
break;
|
||||
case XEMACPS_SEND:
|
||||
if( ( ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Transmit DMA error";
|
||||
xNetworkInterfaceInitialise( );
|
||||
}
|
||||
if( ( ErrorWord & XEMACPS_TXSR_URUN_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Transmit under run";
|
||||
HandleTxErrors( xemacpsif );
|
||||
}
|
||||
if( ( ErrorWord & XEMACPS_TXSR_BUFEXH_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Transmit buffer exhausted";
|
||||
HandleTxErrors( xemacpsif );
|
||||
}
|
||||
if( ( ErrorWord & XEMACPS_TXSR_RXOVR_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Transmit retry excessed limits";
|
||||
HandleTxErrors( xemacpsif );
|
||||
}
|
||||
if( ( ErrorWord & XEMACPS_TXSR_FRAMERX_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Transmit collision";
|
||||
emacps_check_tx( xemacpsif );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Break on this statement and inspect error_msg if you like
|
||||
if( last_err_msg != NULL )
|
||||
{
|
||||
error_msg_count++;
|
||||
FreeRTOS_printf( ( "emacps_handle_error: %s\n", last_err_msg ) );
|
||||
}
|
||||
}
|
||||
|
||||
extern XEmacPs_Config mac_config;
|
||||
|
||||
void HandleTxErrors(xemacpsif_s *xemacpsif)
|
||||
{
|
||||
u32 netctrlreg;
|
||||
|
||||
//taskENTER_CRITICAL()
|
||||
{
|
||||
netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
netctrlreg = netctrlreg & (~XEMACPS_NWCTRL_TXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, netctrlreg);
|
||||
|
||||
clean_dma_txdescs( xemacpsif );
|
||||
netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
netctrlreg = netctrlreg | (XEMACPS_NWCTRL_TXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, netctrlreg);
|
||||
}
|
||||
//taskEXIT_CRITICAL( );
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Xilinx, Inc.
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
|
||||
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
|
||||
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
|
||||
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
|
||||
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Zynq/x_emacpsif.h"
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
|
||||
///* FreeRTOS+TCP includes. */
|
||||
/* FreeRTOS+TCP includes. */
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "NetworkBufferManagement.h"
|
||||
|
||||
extern TaskHandle_t xEMACTaskHandle;
|
||||
|
||||
/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
|
||||
*** to run it on a PEEP board
|
||||
***/
|
||||
|
||||
unsigned int link_speed = 100;
|
||||
|
||||
void setup_isr( xemacpsif_s *xemacpsif )
|
||||
{
|
||||
/*
|
||||
* Setup callbacks
|
||||
*/
|
||||
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMASEND,
|
||||
(void *) emacps_send_handler,
|
||||
(void *) xemacpsif);
|
||||
|
||||
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMARECV,
|
||||
(void *) emacps_recv_handler,
|
||||
(void *) xemacpsif);
|
||||
|
||||
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_ERROR,
|
||||
(void *) emacps_error_handler,
|
||||
(void *) xemacpsif);
|
||||
}
|
||||
|
||||
void start_emacps (xemacpsif_s *xemacps)
|
||||
{
|
||||
/* start the temac */
|
||||
XEmacPs_Start(&xemacps->emacps);
|
||||
}
|
||||
|
||||
extern struct xtopology_t xXTopology;
|
||||
|
||||
volatile int error_msg_count = 0;
|
||||
volatile const char *last_err_msg = "";
|
||||
|
||||
struct xERROR_MSG {
|
||||
void *arg;
|
||||
u8 Direction;
|
||||
u32 ErrorWord;
|
||||
};
|
||||
|
||||
static struct xERROR_MSG xErrorList[ 8 ];
|
||||
static BaseType_t xErrorHead, xErrorTail;
|
||||
|
||||
void emacps_error_handler(void *arg, u8 Direction, u32 ErrorWord)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xemacpsif_s *xemacpsif;
|
||||
BaseType_t xNextHead = xErrorHead;
|
||||
|
||||
xemacpsif = (xemacpsif_s *)(arg);
|
||||
|
||||
if( ( Direction != XEMACPS_SEND ) || (ErrorWord != XEMACPS_TXSR_USEDREAD_MASK ) )
|
||||
{
|
||||
if( ++xNextHead == ( sizeof( xErrorList ) / sizeof( xErrorList[ 0 ] ) ) )
|
||||
xNextHead = 0;
|
||||
if( xNextHead != xErrorTail )
|
||||
{
|
||||
|
||||
xErrorList[ xErrorHead ].arg = arg;
|
||||
xErrorList[ xErrorHead ].Direction = Direction;
|
||||
xErrorList[ xErrorHead ].ErrorWord = ErrorWord;
|
||||
|
||||
xErrorHead = xNextHead;
|
||||
|
||||
xemacpsif = (xemacpsif_s *)(arg);
|
||||
xemacpsif->isr_events |= EMAC_IF_ERR_EVENT;
|
||||
}
|
||||
|
||||
if( xEMACTaskHandle != NULL )
|
||||
{
|
||||
vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
|
||||
static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord);
|
||||
|
||||
int emacps_check_errors( xemacpsif_s *xemacps )
|
||||
{
|
||||
int xResult;
|
||||
|
||||
( void ) xemacps;
|
||||
|
||||
if( xErrorHead == xErrorTail )
|
||||
{
|
||||
xResult = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
xResult = 1;
|
||||
emacps_handle_error(
|
||||
xErrorList[ xErrorTail ].arg,
|
||||
xErrorList[ xErrorTail ].Direction,
|
||||
xErrorList[ xErrorTail ].ErrorWord );
|
||||
}
|
||||
|
||||
return xResult;
|
||||
}
|
||||
|
||||
BaseType_t xNetworkInterfaceInitialise( void );
|
||||
|
||||
static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
|
||||
{
|
||||
xemacpsif_s *xemacpsif;
|
||||
struct xtopology_t *xtopologyp;
|
||||
XEmacPs *xemacps;
|
||||
|
||||
xemacpsif = (xemacpsif_s *)(arg);
|
||||
|
||||
xtopologyp = &xXTopology;
|
||||
|
||||
xemacps = &xemacpsif->emacps;
|
||||
|
||||
/* Do not appear to be used. */
|
||||
( void ) xemacps;
|
||||
( void ) xtopologyp;
|
||||
|
||||
last_err_msg = NULL;
|
||||
|
||||
if( ErrorWord != 0 )
|
||||
{
|
||||
switch (Direction) {
|
||||
case XEMACPS_RECV:
|
||||
if( ( ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Receive DMA error";
|
||||
xNetworkInterfaceInitialise( );
|
||||
}
|
||||
if( ( ErrorWord & XEMACPS_RXSR_RXOVR_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Receive over run";
|
||||
emacps_recv_handler(arg);
|
||||
}
|
||||
if( ( ErrorWord & XEMACPS_RXSR_BUFFNA_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Receive buffer not available";
|
||||
emacps_recv_handler(arg);
|
||||
}
|
||||
break;
|
||||
case XEMACPS_SEND:
|
||||
if( ( ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Transmit DMA error";
|
||||
xNetworkInterfaceInitialise( );
|
||||
}
|
||||
if( ( ErrorWord & XEMACPS_TXSR_URUN_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Transmit under run";
|
||||
HandleTxErrors( xemacpsif );
|
||||
}
|
||||
if( ( ErrorWord & XEMACPS_TXSR_BUFEXH_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Transmit buffer exhausted";
|
||||
HandleTxErrors( xemacpsif );
|
||||
}
|
||||
if( ( ErrorWord & XEMACPS_TXSR_RXOVR_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Transmit retry excessed limits";
|
||||
HandleTxErrors( xemacpsif );
|
||||
}
|
||||
if( ( ErrorWord & XEMACPS_TXSR_FRAMERX_MASK ) != 0 )
|
||||
{
|
||||
last_err_msg = "Transmit collision";
|
||||
emacps_check_tx( xemacpsif );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Break on this statement and inspect error_msg if you like
|
||||
if( last_err_msg != NULL )
|
||||
{
|
||||
error_msg_count++;
|
||||
FreeRTOS_printf( ( "emacps_handle_error: %s\n", last_err_msg ) );
|
||||
}
|
||||
}
|
||||
|
||||
extern XEmacPs_Config mac_config;
|
||||
|
||||
void HandleTxErrors(xemacpsif_s *xemacpsif)
|
||||
{
|
||||
u32 netctrlreg;
|
||||
|
||||
//taskENTER_CRITICAL()
|
||||
{
|
||||
netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
netctrlreg = netctrlreg & (~XEMACPS_NWCTRL_TXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, netctrlreg);
|
||||
|
||||
clean_dma_txdescs( xemacpsif );
|
||||
netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
netctrlreg = netctrlreg | (XEMACPS_NWCTRL_TXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, netctrlreg);
|
||||
}
|
||||
//taskEXIT_CRITICAL( );
|
||||
}
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Xilinx, Inc.
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
|
||||
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
|
||||
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
|
||||
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
|
||||
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XEMACPSIF_HW_H_
|
||||
#define __XEMACPSIF_HW_H_
|
||||
|
||||
#include "Zynq/x_emacpsif.h"
|
||||
//#include "lwip/netif.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
XEmacPs_Config * lookup_config(unsigned mac_base);
|
||||
|
||||
//void init_emacps(xemacpsif_s *xemacpsif, struct netif *netif);
|
||||
|
||||
int emacps_check_errors( xemacpsif_s *xemacps );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Xilinx, Inc.
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
|
||||
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
|
||||
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
|
||||
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
|
||||
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XEMACPSIF_HW_H_
|
||||
#define __XEMACPSIF_HW_H_
|
||||
|
||||
#include "Zynq/x_emacpsif.h"
|
||||
//#include "lwip/netif.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
XEmacPs_Config * lookup_config(unsigned mac_base);
|
||||
|
||||
//void init_emacps(xemacpsif_s *xemacpsif, struct netif *netif);
|
||||
|
||||
int emacps_check_errors( xemacpsif_s *xemacps );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,46 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2007-2013 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Xilinx, Inc.
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
|
||||
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
|
||||
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
|
||||
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
|
||||
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XTOPOLOGY_H_
|
||||
#define __XTOPOLOGY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum xemac_types { xemac_type_unknown = -1, xemac_type_xps_emaclite, xemac_type_xps_ll_temac, xemac_type_axi_ethernet, xemac_type_emacps };
|
||||
|
||||
struct xtopology_t {
|
||||
unsigned emac_baseaddr;
|
||||
enum xemac_types emac_type;
|
||||
unsigned intc_baseaddr;
|
||||
unsigned intc_emac_intr; /* valid only for xemac_type_xps_emaclite */
|
||||
unsigned scugic_baseaddr; /* valid only for Zynq */
|
||||
unsigned scugic_emac_intr; /* valid only for GEM */
|
||||
};
|
||||
|
||||
extern int x_topology_n_emacs;
|
||||
extern struct xtopology_t x_topology[];
|
||||
|
||||
int x_topology_find_index(unsigned base);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Copyright (c) 2007-2013 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Xilinx, Inc.
|
||||
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
|
||||
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
|
||||
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
|
||||
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
|
||||
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
|
||||
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XTOPOLOGY_H_
|
||||
#define __XTOPOLOGY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum xemac_types { xemac_type_unknown = -1, xemac_type_xps_emaclite, xemac_type_xps_ll_temac, xemac_type_axi_ethernet, xemac_type_emacps };
|
||||
|
||||
struct xtopology_t {
|
||||
unsigned emac_baseaddr;
|
||||
enum xemac_types emac_type;
|
||||
unsigned intc_baseaddr;
|
||||
unsigned intc_emac_intr; /* valid only for xemac_type_xps_emaclite */
|
||||
unsigned scugic_baseaddr; /* valid only for Zynq */
|
||||
unsigned scugic_emac_intr; /* valid only for GEM */
|
||||
};
|
||||
|
||||
extern int x_topology_n_emacs;
|
||||
extern struct xtopology_t x_topology[];
|
||||
|
||||
int x_topology_find_index(unsigned base);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue