mirror of
https://github.com/FreeRTOS/FreeRTOS-Plus-TCP
synced 2025-10-25 04:56:15 +08:00
* Update NetworkInterface.c * Update NetworkInterface.c * Update NetworkInterface.c * Update x_emacpsif_dma.c * Update NetworkInterface.c * Update NetworkInterface_eth.c * Update NetworkInterface.c * Uncrustify: triggered by comment. * Update FreeRTOS_DNS_Cache.c * Update NetworkInterface.c * Update NetworkInterface.c * Update NetworkInterface.c * Update FreeRTOS_DNS_Parser.c * Update FreeRTOS_DNS_Parser.c * Update NetworkInterface.c * Update uncached_memory.c * Update x_emacpsif.h * Update x_emacpsif_dma.c * Update x_emacpsif_hw.c * Update x_emacpsif_physpeed.c * Update x_topology.h --------- Co-authored-by: GitHub Action <action@github.com>
256 lines
7.3 KiB
C
256 lines
7.3 KiB
C
/*
|
|
* 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>
|
|
|
|
/* FreeRTOS includes. */
|
|
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
#include "queue.h"
|
|
|
|
/* FreeRTOS+TCP includes. */
|
|
#include "FreeRTOS_IP.h"
|
|
#include "FreeRTOS_Sockets.h"
|
|
#include "FreeRTOS_IP_Private.h"
|
|
#include "FreeRTOS_Routing.h"
|
|
#include "NetworkBufferManagement.h"
|
|
#include "NetworkInterface.h"
|
|
|
|
#include "Zynq/x_emacpsif.h"
|
|
|
|
extern TaskHandle_t xEMACTaskHandles[ XPAR_XEMACPS_NUM_INSTANCES ];
|
|
|
|
/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
|
|
*** to run it on a PEEP board
|
|
***/
|
|
|
|
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 );
|
|
}
|
|
|
|
|
|
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;
|
|
BaseType_t xEMACIndex;
|
|
|
|
xemacpsif = ( xemacpsif_s * ) ( arg );
|
|
xEMACIndex = xemacpsif->emacps.Config.DeviceId;
|
|
|
|
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( xEMACTaskHandles[ xEMACIndex ] != NULL )
|
|
{
|
|
vTaskNotifyGiveFromISR( xEMACTaskHandles[ xEMACIndex ], &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;
|
|
}
|
|
|
|
static void emacps_handle_error( void * arg,
|
|
u8 Direction,
|
|
u32 ErrorWord )
|
|
{
|
|
xemacpsif_s * xemacpsif;
|
|
XEmacPs * xemacps;
|
|
BaseType_t xEMACIndex;
|
|
|
|
xemacpsif = ( xemacpsif_s * ) ( arg );
|
|
|
|
xemacps = &xemacpsif->emacps;
|
|
xEMACIndex = xemacps->Config.DeviceId;
|
|
|
|
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";
|
|
vInitialiseOnIndex( xEMACIndex );
|
|
}
|
|
|
|
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";
|
|
vInitialiseOnIndex( xEMACIndex );
|
|
}
|
|
|
|
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 ) );
|
|
}
|
|
}
|
|
|
|
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( ); */
|
|
}
|