/**
* @file icss_iSwitchDrv.h
*
* @brief Include file for switch RX/TX functions also contains queue structures
*
* \par
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
* \par
*/

#ifndef _ICSS_ISWITCHDRV_H_
#define _ICSS_ISWITCHDRV_H_

/* ========================================================================== */
/*                             Include Files                                  */
/* ========================================================================== */

#include <xdc/std.h>
#include <hw/hw_types.h>

/* ========================================================================== */
/*                           Macros & Typedefs                                */
/* ========================================================================== */
/**
* @def ETHERNET_FRAME_SIZE_60
*      Minimum supported size of Ethernet frame
*/
#define ETHERNET_FRAME_SIZE_60 60
/**
* @def ALE_IMPLEMENT
*      Implement Learning for Ports
*/
#define ALE_IMPLEMENT
/**
* @def QUEPRIO1
*      Priority Queue 1
*/
#define QUEPRIO1 0
/**
* @def QUEPRIO2
*      Priority Queue 2
*/
#define QUEPRIO2 1
/**
* @def QUEPRIO3
*      Priority Queue 3
*/
#define QUEPRIO3 2
/**
* @def QUEPRIO4
*      Priority Queue 4
*/
#define QUEPRIO4 3
/**
* @def INTERFACE
*      Interface MAC
*/
#define INTERFACE 0
/**
* @def USE_RX_TASK
*      Packet handling in  Task mode will be enabled
*/
#define USE_RX_TASK
/**
* @def MAX_NUM_PROTOCOL_IMPLEMENTED
*       Max Number of protocols
*/
#define MAX_NUM_PROTOCOL_IMPLEMENTED   50
/**
* @def NUM_PROTOCOLS_IMPLEMENTED
*      Number of protocols supported
*/
#define NUM_PROTOCOLS_IMPLEMENTED  2
/**
* @def IP4_PROT_TYPE
*      IP4 Protcol type
*/
#define IP4_PROT_TYPE	0x800
/**
* @def ARP_PROT_TYPE
*      ARP protocol type
*/
#define ARP_PROT_TYPE	0x806
/**
* @def NUM_PHY
*      max number of phy supported here
*/
#define NUM_PHY 2
/**
* @def PORT0
*      Port 0: Host side
*/
#define PORT0 0
/**
* @def PORT1
*     Port 1: MII 0 (tx)
*/
#define PORT1 1
/**
* @def PORT2
*      Port 2: MII 1  (tx)
*/
#define PORT2 2
/**
* @def ANYPORT
*      For all port checks
*/
#define ANYPORT 3
/**
* @def MAXMTU
*      Maximum Valid size (incl header + VLAN TAG..., no CRC)
*/
#define MAXMTU	1518
/**
* @def MINMTU
*      Minimum Valid size ( DA + SA + Ethertype)
*/
#define MINMTU	14
/**
* @def L3_OCMC_BASE_ADDRESS
*      OCMC Base Address
*/
#define L3_OCMC_BASE_ADDRESS 			0x40300000
/**
* @def NUMQUEUES
*      Total Queues available
*/
#define NUMQUEUES 5
/**
* @def QUEUE1
*      Priority Queue 1
*/
#define QUEUE1 0
/**
* @def QUEUE2
*      Priority Queue 2
*/
#define QUEUE2 1
/**
* @def QUEUE3
*      OCMC Base Address
*/
#define QUEUE3 2
/**
* @def QUEUE4
*      Priority Queue 4
*/
#define QUEUE4 3
/**
* @def COLQUEUE
*      Collision Queue
*/
#define COLQUEUE 4
/**
* @def RX_INT_CLR_REG
*      Rx Interrupt Clear register
*/
#define RX_INT_CLR_REG  0x4a320280			// todo: get from standard PRU header


/**
* @brief packet IF structures - here for PRU-ICSS switch
*
*/
typedef struct queStats
{
	Uint32 rawCount;		/**queue raw count*/
	Uint32 errCount;		/**queue error count*/
} t_queStats;

/**
* @brief Queue descriptor
*
*/
typedef struct queParams
{
	t_queStats 	qStat;				/**Queue statistics*/
	Uint16 		buffer_offset;		/**buffer  offset*/
	Uint16 		buffer_desc_offset;	/**buffer descriptor offset*/
	Uint16 		queue_desc_offset;	/**queue descriptor offset*/
	Uint16 		queue_size;			/**queue size*/
} t_queParams;

/**
* @brief Port parameters
*
*/
typedef struct portParams
{
	Uint8*			ptcpPktBuff;		/**pointer to PTCP packet mem*/
	Uint32			rawCount;			/**statistics   - raw*/
	Uint32			errCount;			/**Error count*/
	t_queParams		queue[NUMQUEUES];	/**Queues per port*/
} t_portParams;


typedef void (*icssCallBack_t)(void* arg, void* arg2);
typedef uint8_t (*icssCallBackRet_t)(void* arg, void* arg2);
typedef uint8_t (*icssCallBackLinkStat)(Int32 arg);
/**
* @internal
* @brief Function to initialize all Port Queue params
*
* @param none
*
* @retval 0 on success
*/
Int32 PortInit(void);
/**
* @internal
* @brief Main Rx interrupt service routine
*
* @param args arguments if any
*
* @retval none
*/
void RxInterruptHandler(void *);
/**
* @brief Function which does learning for Tx packets and puts it into TxQueues
*
* @param srcAddress	   memory address to copy packet data from
* @param portNumber	   port from which data will be transmitted
* @param queuePriority	   which queue to write data to
* @param lengthOfPacket	length of the packet
*
* @retval Success -   0
*         Failure -  -1
*/
Int32 TxPacket(const Uint8* srcAddress, Int32 portNumber, Int32 queuePriority, Int32 lengthOfPacket);
/**
* @internal
* @brief Function to enqueue packet for transmission
*
* @param src_address	   memory address to copy packet data from
* @param port_number	   port from which data will be transmitted
* @param queue_priority	   which queue to write data to
* @param length_of_packet	length of the packet
*
* @retval Success -   0
*         Failure -  -1
*/
Int32 TxPacketEnqueue (const Uint8* srcAddress,Int32 portNumber, Int32 queuePriority, Int32 lengthOfPacket);
/**
* @brief Function which copy a packet to ndk buffer/destiantion packet structure
*
* @param destAddress	  ndk packet buffer  address to copy packet data
* @param queueNumber	  Rx queue from which packet data is to be copyied
* @param port	          Rx port number
* @param more	          set to one if more packets in queue already
*
* @retval rd_packet_length length of the packet received
*/
Int32 RxPktGet(Uint32 destAddress, Int32 queueNumber, Int32* port, Int32* more);
/**
* @brief Function to get the Rx packet info
*
* @param portNumber	   port number of Rx packet
* @param queueNumber	   queue number of Rx packet
*
* @retval rd_packet_length length of the packet received
*/
Int32 RxPktInfo(Int32* portNumber, Int32* queueNumber);
/**
* @internal
* @brief Function to create Rx task (to receive packet)
*
* @param none
*
* @retval Success -   0
*         Error   -   <0
*/
Int8 CreateRXtask();
/**
* @internal
* @brief Function to delete Rx task (to receive packet)
*
* @param none
*
* @retval Success -   0
*         Error   -   <0
*/
Int8 DeleteRXtask();
/**
* @internal
* @brief ISR for Pacing DM Timer
*
* @param none
*
* @retval none
*/
void pacingISR(void *);
/**
* @internal
* @brief disables Rx Interrupt
*
* @param none
*
* @retval none
*/
inline void disableRxInterrupt(void);
/**
* @internal
* @brief Enables Rx Interrupt
*
* @param none
*
* @retval none
*/
/*inline */void enableRxInterrupt(void);

/**
* @brief Function to register callback function for TX exception
*
* @param callBack	  Callback function pointer
*
* @retval none
*/
void RegisterTxExceptionCallback(icssCallBackRet_t callBack);
/**
* @brief Function to register callback function to process protocol specific packets
*
* @param callBack	  Callback function pointer
* @param userArg	  user argument if any
*
* @retval none
*/
void RegisterProtocolCallback(icssCallBack_t callBack, void *userArg);
/**
* @brief Function to find the max fill level of a queue
*
* @param portNumber	  port on which the queue belongs
* @param queuePriority	  priority of queue
* @param queueOverflowCount	    number of times queue has overflown
*
* @retval queueMaxFillLevel max fill level of the queue in terms of 32 byte blocks
*/
Int32 GetMaxQueueFillLevel(Int32 portNumber, Int32 queuePriority, Int32* queueOverflowCount);

void addWord(Uint8 *src, Uint32 word);


void addMACID(Uint8 *src, Uint8 * macID);

void addProtocolToList(uint16_t protocolType);
#endif /* _ICSS_ISWITCHDRV_H_ */
