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