1
0
mirror of https://github.com/FreeRTOS/FreeRTOS-Plus-TCP synced 2025-10-25 04:56:15 +08:00
Files
FreeRTOS-Plus-TCP/source/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
kar-rahul-aws ab881bfeac Portable layer changes (#701)
* 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>
2023-02-10 19:14:23 +05:30

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( ); */
}