/**
* @file icss_statistics.h
*
* @brief Include file for Statistics implementation
*        Contains Statistics getter functions declarations
*
* \par
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
* \par
*/
#ifndef _ICSS_STATISTICS_H_
#define _ICSS_STATISTICS_H_

/* ========================================================================== */
/*                             Include Files                                  */
/* ========================================================================== */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <soc_AM335x.h>
#include "osdrv_prussdefs.h"
#include "icss_common.h"
#include "pruss_register.h"
#include "icss_iSwitchDrv.h"
#include "icss_pruInit.h"

/**
* @def NUM_PORTS
*		Number of ports in the device
*/
#define NUM_PORTS  2

/**
* @def SWITCH_STAT_DISABLED_MASK
*
*/
#define SWITCH_STAT_DISABLED_MASK   0x8
//#define DEBUG_STATS

/* ========================================================================== */
/*                           Macros & Typedefs                                */
/* ========================================================================== */

/**
* @brief Statistics structure for capturing statistics on PRU
*
*/
typedef struct {
    /*The fields here are aligned here so that it's consistent
	with the memory layout in PRU DRAM, this is to facilitate easy 
	memcpy or DMA transfer. Don't change the order of fields without
	modifying the order of fields in PRU DRAM. For details refer to guide*/
	
	volatile UInt32 txBcast;				/**Number of broadcast packets sent*/
	volatile UInt32 txMcast;				/**Number of multicast packets sent*/
	volatile UInt32 txUcast;				/**Number of unicast packets sent*/
	volatile UInt32 txOctets;				/**Number of undersized frames rcvd*/
	volatile UInt32 rxBcast;				/**Number of broadcast packets rcvd*/
	volatile UInt32 rxMcast;				/**Number of multicast packets rcvd*/
	volatile UInt32 rxUcast;				/**Number of unicast packets rcvd*/
	volatile UInt32 rxOctets;				/**Number of Rx packets*/
	volatile UInt32 lateColl;				/**Number of late collisions(Half Duplex)*/
	volatile UInt32 singleColl;				/**Number of single collisions (Half Duplex)*/
	volatile UInt32 multiColl;				/**Number of multiple collisions (Half Duplex)*/
	volatile UInt32 excessColl;				/**Number of excess collisions(Half Duplex)*//**Number of excess collisions(Half Duplex)*/
	volatile UInt32 txOverFlow;				/**Tx Queue over flow count*/
	volatile UInt32 rxMisAlignmentFrames;	/**Number of non multiple of 8 byte frames rcvd*/
	volatile UInt32 stormPrevCounter;		/**Number of packets dropped because of Storm Prevention*/
	volatile UInt32 macRxError;				/**Number of MAC receive errors*/
	volatile UInt32 SFDError;				/**Number of invalid SFD*/
	volatile UInt32 defTx;					/**Number of transmissions deferred*/
	volatile UInt32 macTxError;				/**Number of MAC transmit errors*/
	volatile UInt32 rxOverSizedFrames;		/**Number of oversized frames rcvd*/
	volatile UInt32 rxUnderSizedFrames;		/**Number of undersized frames rcvd*/
	volatile UInt32 rxCRCFrames;			/**Number of CRC error frames rcvd*/
	volatile UInt32 droppedPackets;			/**Number of packets dropped due to a link down on opposite port*/
	volatile UInt32 tx64byte;				/**Number of 64 byte packets sent*/
	volatile UInt32 tx65_127byte;			/**Number of 65-127 byte packets sent*/
	volatile UInt32 tx128_255byte;			/**Number of 128-255 byte packets sent*/
	volatile UInt32 tx256_511byte;			/**Number of 256-511 byte packets sent*/
	volatile UInt32 tx512_1023byte;			/**Number of 512-1023 byte packets sent*/
	volatile UInt32 tx1024byte;				/**Number of 1024 and larger size packets sent*/
	volatile UInt32 rx64byte;				/**Number of 64 byte packets rcvd*/
	volatile UInt32 rx65_127byte;			/**Number of 65-127 byte packets rcvd*/
	volatile UInt32 rx128_255byte;			/**Number of 128-255 byte packets rcvd*/
	volatile UInt32 rx256_511byte;			/**Number of 256-511 byte packets rcvd*/
	volatile UInt32 rx512_1023byte;			/**Number of 512-1023 byte packets rcvd*/
	volatile UInt32 rx1024byte;				/**Number of 1024 and larger size packets rcvd*/
	
	/*
	 * Debug variables, these are not part of standard MIB. Useful for debugging
	 */
	volatile UInt32 RXqueueLevel;			/**Current Rx queue level*/

	/*Reserved for future Use*/
	volatile UInt32 sqeTestError;			/**Number of MAC receive errors*/
	volatile UInt32 TXqueueLevel;			/**Current Tx queue level*/
	volatile UInt32 CSError;				/**Number of carrier sense errors*/

}pruStatistics;


/**
* @brief Stats structure for statistics on Host (ARM)
*
*/
typedef struct {
	volatile UInt32 txUcast;			/**Number of unicast packets sent*/
	volatile UInt32 txBcast;			/**Number of broadcast packets sent*/
	volatile UInt32 txMcast;			/**Number of multicast packets sent*/
	volatile UInt32 txOctets;			/**Number of bytes sent*/
	volatile UInt32 rxUcast;			/**Number of unicast packets rcvd*/
	volatile UInt32 rxBcast;			/**Number of broadcast packets rcvd*/
	volatile UInt32 rxMcast;			/**Number of multicast packets rcvd*/
	volatile UInt32 rxOctets;			/**Number of Rx packets*/
	volatile UInt32 rxUnknownProtocol;	/**Number of packets with unknown protocol*/
	/*
	* Debug variables, these are not part of standard MIB. Useful for debugging
	*/
	volatile UInt32 linkBreak;			/**Number of link breaks*/

}hostStatistics;

/* ========================================================================== */
/*                          Function Definitions                              */
/* ========================================================================== */
/**
* @brief   Read statistics from PRU DRAM Memory into structure
*
* @retval none
*/
void ReadStatsFromPRU(void);

/**
* @brief   compute secondary statistics from basic counters
*
*
* @retval none
*/
void ConsolidateStats(void);

/**
 * @brief returns true if stats are enabled for a port
 * @param  portNum 0/1 2 is not defined
 * @retval Status 1 if storm prevention is enabled on any port
 */
Uint8 ifStatisticsEnabled(Uint8 portNum);
/**
* @brief   clear switch statistics
*
* @retval none
*/
void PurgeStats(void);


/**
* @brief   Do the stats initialization, call at the beginning of the frame
*
* @retval none
*/
void InitStats(void);

/**
* @brief   Call every time a packet is received, updates Rx related statistics
*
* @param macAddr pointer to mac address, stored in 8 bit locations
* @param packet_len packet length in bytes
* @param protIdent Protocol Type
* @param portNum incoming port number
*
* @retval none
*/
void UpdateRxstats(Uint8* macAddr,UInt32 packet_len,Uint16 protIdent, UInt32 portNum);
/**
* @brief   Call every time a packet is transmitted, updates Tx related statistics
*
* @param macAddr pointer to mac address, stored in 8 bit locations
* @param packet_len packet length in bytes
* @param portNum incoming port number
*
* @retval none
*/
void UpdateTxstats(Uint8 *macAddr,UInt32 packet_len, UInt32 portNum);

/**
* @brief   Enable Statistics on Switch
*
*
* @retval none
*/
void EnableStatistics(void);

/**
* @brief   Disable Statistics on Switch
*
* @retval none
*/
void DisableStatistics(void);

#endif //_ICSS_STATISTICS_H_
