/**
* @file icss_switch_emac.h
*
* @brief Include file for switch EMAC interface
*
* \par
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
* \par
*/
#ifndef _ICSS_SWITCH_EMAC_H
#define _ICSS_SWITCH_EMAC_H

#ifdef __cplusplus
extern "C" {
#endif

#include "icss_common.h"
#include "icss_miimdio.h"
#include "icss_miimdio_regs.h"
#include "icss_statistics.h"
#include "icss_ioctl.h"

/**
* @def USE_PHY1
*      Compile Time switch for using PHY1 or PHY0
*/
#define USE_PHY1

/**
* @def SWITCH_MAX_INSTANCES
*      Max number of ICSS instances
*/
#define SWITCH_MAX_INSTANCES                1u

/*Use PHY1 or PHY0 on PG2.1*/
#ifdef USE_PHY1
/**
* @def SWITCH_NUM_PORTS
*      Port Count
*/
#define SWITCH_NUM_PORTS                    3u
/**
* @def SWITCH_NUM_MAC_PORTS
*      MAC Port Count
*/
	#define SWITCH_NUM_MAC_PORTS                2u
#else
/**
* @def SWITCH_NUM_PORTS
*      Port Count
*/
	#define SWITCH_NUM_PORTS                    2u
/**
* @def SWITCH_NUM_MAC_PORTS
*      MAC Port Count
*/
	#define SWITCH_NUM_MAC_PORTS                1u
#endif

/**
* @def SWITCH_PORT_STATE_DISABLED
*      Disable Physical Port
*/
#define SWITCH_PORT_STATE_DISABLED          0u
/**
* @def SWITCH_PORT_STATE_BLOCKED
*      Block Physical Port
*/
/**Block Physical Port*/
#define SWITCH_PORT_STATE_BLOCKED           1u
/**
* @def SWITCH_PORT_STATE_LEARN
*      Learning Enable on Physical Port
*/
#define SWITCH_PORT_STATE_LEARN             2u
/**
* @def SWITCH_PORT_STATE_FORWARD
*      Set Port State to Forward
*/
#define SWITCH_PORT_STATE_FORWARD           3u
/**
* @def SWITCH_NUM_STAT_REGS
*      Number of statistics Supported
*/
#define SWITCH_NUM_STAT_REGS                36u
/**
* @def SWITCH_STAT_CLEAR
*      Clear all statistics
*/
#define SWITCH_STAT_CLEAR                   0xFFFFFFFFu
/**
* @def NUMBER_OF_MAC_ADDRESS
*      Number of Emacs
*/
#define NUMBER_OF_MAC_ADDRESS			1
/**
* @def ICSS_PORT1_PHYNUM
*      Phy Address of Port1
*/
#define ICSS_PORT1_PHYNUM				    1
/**
* @def ICSS_PORT2_PHYNUM_ICE2
*      Phy Address of Port2(ICE 2)
*/
#define ICSS_PORT2_PHYNUM_ICE2 			    3
/**
* @def ICSS_PORT2_PHYNUM_ICE
*      Phy Address of Port2
*/
#define ICSS_PORT2_PHYNUM_ICE 				2

/**
* @def EMAC_PKT_FLAGS_SOP
*      Start of packet
*/
#define EMAC_PKT_FLAGS_SOP                  0x80000000u
/**
* @def EMAC_PKT_FLAGS_EOP
*      End of packet
*/
#define EMAC_PKT_FLAGS_EOP                  0x40000000u



/**
* @def EMAC_PKT_FLAGS_HASCRC
*      RxCrc: PKT has 4byte CRC
*/
#define EMAC_PKT_FLAGS_HASCRC               0x04000000u
/**
* @def EMAC_PKT_FLAGS_JABBER
*      RxErr: Jabber
*/
#define EMAC_PKT_FLAGS_JABBER               0x02000000u
/**
* @def EMAC_PKT_FLAGS_OVERSIZE
*      End of  RxErr: Oversize
*/
#define EMAC_PKT_FLAGS_OVERSIZE             0x01000000u
/**
* @def EMAC_PKT_FLAGS_FRAGMENT
*      RxErr: Fragment
*/
#define EMAC_PKT_FLAGS_FRAGMENT             0x00800000u
/**
* @def EMAC_PKT_FLAGS_UNDERSIZED
*      RxErr: Undersized
*/
#define EMAC_PKT_FLAGS_UNDERSIZED           0x00400000u
/**
* @def EMAC_PKT_FLAGS_CONTROL
*      RxCtl: Control Frame
*/
#define EMAC_PKT_FLAGS_CONTROL              0x00200000u
/**
* @def EMAC_PKT_FLAGS_OVERRUN
*      RxErr: Overrun
*/
#define EMAC_PKT_FLAGS_OVERRUN              0x00100000u
/**
* @def EMAC_PKT_FLAGS_CODEERROR
*      RxErr: Code Error
*/
#define EMAC_PKT_FLAGS_CODEERROR            0x00080000u
/**
* @def EMAC_PKT_FLAGS_ALIGNERROR
*       RxErr: Alignment Error
*/
#define EMAC_PKT_FLAGS_ALIGNERROR           0x00040000u
/**
* @def EMAC_PKT_FLAGS_CRCERROR
*      RxErr: Bad CRC
*/
#define EMAC_PKT_FLAGS_CRCERROR             0x00020000u
/**
* @def EMAC_PKT_FLAGS_NOMATCH
*      RxPrm: No Match
*/
#define EMAC_PKT_FLAGS_NOMATCH              0x00010000u


/**
* @def EMAC_CONFIG_MODEFLG_CHPRIORITY
*      Use Tx channel priority
*/
#define EMAC_CONFIG_MODEFLG_CHPRIORITY      0x00001
/**
* @def EMAC_CONFIG_MODEFLG_MACLOOPBACK
*      MAC internal loopback
*/
#define EMAC_CONFIG_MODEFLG_MACLOOPBACK     0x00002
/**
* @def EMAC_CONFIG_MODEFLG_RXCRC
*      Include CRC in RX frames
*/
#define EMAC_CONFIG_MODEFLG_RXCRC           0x00004

/**
* @def EMAC_CONFIG_MODEFLG_TXCRC
*       Tx frames include CRC
*/
#define EMAC_CONFIG_MODEFLG_TXCRC           0x00008
/**
* @def EMAC_CONFIG_MODEFLG_PASSERROR
*      Pass error frames
*/
#define EMAC_CONFIG_MODEFLG_PASSERROR       0x00010
/**
* @def EMAC_CONFIG_MODEFLG_PASSCONTROL
*      Pass control frames
*/
#define EMAC_CONFIG_MODEFLG_PASSCONTROL     0x00020
/**
* @def EMAC_CONFIG_MODEFLG_PASSALL
*      pass all frames
*/
#define EMAC_CONFIG_MODEFLG_PASSALL         0x00040
/**
* @def EMAC_CONFIG_MODEFLG_RXQOS
*      Enable QOS at receive side
*/
#define EMAC_CONFIG_MODEFLG_RXQOS           0x00080
/**
* @def EMAC_CONFIG_MODEFLG_RXNOCHAIN
*      Select no buffer chaining
*/
#define EMAC_CONFIG_MODEFLG_RXNOCHAIN       0x00100
/**
* @def EMAC_CONFIG_MODEFLG_RXOFFLENBLOCK
*      Enable offset/length blocking
*/
#define EMAC_CONFIG_MODEFLG_RXOFFLENBLOCK   0x00200
/**
* @def EMAC_CONFIG_MODEFLG_RXOWNERSHIP
*      Use ownership bit as 1
*/
#define EMAC_CONFIG_MODEFLG_RXOWNERSHIP     0x00400
/**
* @def EMAC_CONFIG_MODEFLG_RXFIFOFLOWCNTL
*      Enable rx fifo flow control
*/
#define EMAC_CONFIG_MODEFLG_RXFIFOFLOWCNTL  0x00800
/**
* @def EMAC_CONFIG_MODEFLG_CMDIDLE
*      Enable IDLE command
*/
#define EMAC_CONFIG_MODEFLG_CMDIDLE         0x01000
/**
* @def EMAC_CONFIG_MODEFLG_TXSHORTGAPEN
*     Enable tx short gap
*/
#define EMAC_CONFIG_MODEFLG_TXSHORTGAPEN    0x02000
/**
* @def EMAC_CONFIG_MODEFLG_TXPACE
*      Enable tx pacing
*/
#define EMAC_CONFIG_MODEFLG_TXPACE          0x04000
/**
* @def EMAC_CONFIG_MODEFLG_TXFLOWCNTL
*      Enable tx flow control
*/
#define EMAC_CONFIG_MODEFLG_TXFLOWCNTL      0x08000
/**
* @def EMAC_CONFIG_MODEFLG_RXBUFFERFLOWCNTL
*      Enable rx buffer flow control
*/
#define EMAC_CONFIG_MODEFLG_RXBUFFERFLOWCNTL    0x10000
/**
* @def EMAC_CONFIG_MODEFLG_FULLDUPLEX
*      Set full duplex mode
*/
#define EMAC_CONFIG_MODEFLG_FULLDUPLEX      0x20000
/**
* @def EMAC_CONFIG_MODEFLG_GIGABIT
*      Set gigabit
*/
#define EMAC_CONFIG_MODEFLG_GIGABIT         0x40000
/**
* @def EMAC_CONFIG_MODEFLG_EXTEN
*      Set external enable bit
*/
#define EMAC_CONFIG_MODEFLG_EXTEN           0x80000
/**
* @def EMAC_CONFIG_MODEFLG_RMII
*      Enable RMII
*/
#define EMAC_CONFIG_MODEFLG_RMII            0x100000
/**
* @def EMAC_CONFIG_MODEFLG_IFCTLA
*      Enable IFCTL_A
*/
#define EMAC_CONFIG_MODEFLG_IFCTLA          0x200000
/**
* @def EMAC_CONFIG_MODEFLG_IFCTLB
*      Enable IFCTL_B
*/
#define EMAC_CONFIG_MODEFLG_IFCTLB          0x400000

/**
* @def EMAC_CONFIG_ALE_ENABLE
*      Enable ALE
*/
#define EMAC_CONFIG_ALE_ENABLE              0x00001
/**
* @def EMAC_CONFIG_ALE_CLRTABLE
*      Clear ALE Address table
*/
#define EMAC_CONFIG_ALE_CLRTABLE            0x00002
/**
* @def EMAC_CONFIG_ALE_AGEOUTNOW
*      Age out address table now
*/
#define EMAC_CONFIG_ALE_AGEOUTNOW           0x00004
/**
* @def EMAC_CONFIG_ALE_LEARNNOVID
*      Learn no VID
*/
#define EMAC_CONFIG_ALE_LEARNNOVID          0x00008
/**
* @def EMAC_CONFIG_ALE_ENVID0MODE
*      Enable VLAN ID = 0 Mode
*/
#define EMAC_CONFIG_ALE_ENVID0MODE          0x00010
/**
* @def EMAC_CONFIG_ALE_ENOUIDENY
*      Enable OUI Deny Mode
*/
#define EMAC_CONFIG_ALE_ENOUIDENY           0x00020
/**
* @def EMAC_CONFIG_ALE_ALEBYPASS
*      ALE bypass mode
*/
#define EMAC_CONFIG_ALE_ALEBYPASS           0x00040
/**
* @def EMAC_CONFIG_ALE_RATELIMITTX
*      Rate limit transmit mode
*/
#define EMAC_CONFIG_ALE_RATELIMITTX         0x00080
/**
* @def EMAC_CONFIG_ALE_ENVLANAWARE
*       ALE Vlan Aware
*/
#define EMAC_CONFIG_ALE_ENVLANAWARE         0x00100
/**
* @def EMAC_CONFIG_ALE_ENAUTHMODE
*      Enable MAC Authorization mode
*/
#define EMAC_CONFIG_ALE_ENAUTHMODE          0x00200
/**
* @def EMAC_CONFIG_ALE_ENRATELIMIT
*      Enable broadcast and multicast rate limit
*/
#define EMAC_CONFIG_ALE_ENRATELIMIT         0x00400

/**
* @def EMAC_CONFIG_ICSS_P2PASSPRITAG
*      Port 2 Pass Priority Tagged
*/
#define EMAC_CONFIG_ICSS_P2PASSPRITAG       0x00001
/**
* @def EMAC_CONFIG_ICSS_P1PASSPRITAG
*      Port 1 Pass Priority Tagged
*/
#define EMAC_CONFIG_ICSS_P1PASSPRITAG       0x00002
/**
* @def EMAC_CONFIG_ICSS_P0PASSPRITAG
*      Port 0 Pass Priority Tagged
*/
#define EMAC_CONFIG_ICSS_P0PASSPRITAG       0x00004
/**
* @def EMAC_CONFIG_ICSS_ENVLANAWARE
*      VLAN aware mode
*/
#define EMAC_CONFIG_ICSS_ENVLANAWARE        0x00008
/**
* @def EMAC_CONFIG_ICSS_RXVLANENCAP
*      Port 2 VLAN Encapsulation
*/
#define EMAC_CONFIG_ICSS_RXVLANENCAP        0x00010
/**
* @def EMAC_CONFIG_ICSS_P2P2RXFLOWEN
*      Port 2 Tx flow enable from Port 2 Rx FIFO
*/
#define EMAC_CONFIG_ICSS_P2P2RXFLOWEN       0x00020
/**
* @def EMAC_CONFIG_ICSS_P2P1TXFLOWEN
*      Port 2 Tx flow enable from Port 1 Tx FIFO
*/
#define EMAC_CONFIG_ICSS_P2P1TXFLOWEN       0x00040
/**
* @def EMAC_CONFIG_ICSS_P2P0TXFLOWEN
*      Port 2 Tx flow enable from Port 0 Tx FIFO
*/
#define EMAC_CONFIG_ICSS_P2P0TXFLOWEN       0x00080
/**
* @def EMAC_CONFIG_ICSS_P1P2TXFLOWEN
*     Port 1 Rx flow enable from Port 2 Tx FIFO
*/
#define EMAC_CONFIG_ICSS_P1P2TXFLOWEN       0x00100
/**
* @def EMAC_CONFIG_ICSS_P1P0TXFLOWEN
*      Port 1 Rx flow enable from Port 0 Tx FIFO
*/
#define EMAC_CONFIG_ICSS_P1P0TXFLOWEN       0x00200
/**
* @def EMAC_CONFIG_ICSS_P0P2TXFLOWEN
*      Port 0 Rx flow enable from Port 2 Tx FIFO
*/
#define EMAC_CONFIG_ICSS_P0P2TXFLOWEN       0x00400
/**
* @def EMAC_CONFIG_ICSS_P0P1TXFLOWEN
*      Port 0 Rx flow enable from Port 1 Tx FIFO
*/
#define EMAC_CONFIG_ICSS_P0P1TXFLOWEN       0x00800
/**
* @def EMAC_CONFIG_ICSS_FIFOLOOPBACK
*      FIFO Loopback mode
*/
#define EMAC_CONFIG_ICSS_FIFOLOOPBACK       0x01000
/**
* @def EMAC_CONFIG_ICSS_DLREN
*      DLR Enable mode for am335x
*/
#define EMAC_CONFIG_ICSS_DLREN 				0x02000

/**
* @def EMAC_CONFIG_PTYPE_P2PTYPEESC
*      Port 2 Priority Type escalate
*/
#define EMAC_CONFIG_PTYPE_P2PTYPEESC       0x00001
/**
* @def EMAC_CONFIG_PTYPE_P1PTYPEESC
*       Port 1 Priority Type escalate
*/
#define EMAC_CONFIG_PTYPE_P1PTYPEESC       0x00002
/**
* @def EMAC_CONFIG_PTYPE_P0PTYPEESC
*      Port 0 Priority Type escalate
*/
#define EMAC_CONFIG_PTYPE_P0PTYPEESC       0x00004


/**
* @def EMAC_CONFIG_STAT_P2STATEN
*      Port 2 statistics enable
*/
#define EMAC_CONFIG_STAT_P2STATEN           0x00001
/**
* @def EMAC_CONFIG_STAT_P1STATEN
*      Port 1 statistics enable
*/
#define EMAC_CONFIG_STAT_P1STATEN           0x00002
/**
* @def EMAC_CONFIG_STAT_P0STATEN
*      Port 0 statistics enable
*/
#define EMAC_CONFIG_STAT_P0STATEN           0x00004

/**
* @def MDIO_MODEFLG_AUTONEG
*       Use Autonegotiation
*/
#define MDIO_MODEFLG_AUTONEG                0x0001


/* The following bits are used for manual and fallback configuration        */
/**
* @def MDIO_MODEFLG_HD10
*      Use 10Mb/s Half Duplex
*/
#define MDIO_MODEFLG_HD10                   0x0002
/**
* @def MDIO_MODEFLG_FD10
*      Use 10Mb/s Full Duplex
*/
#define MDIO_MODEFLG_FD10                   0x0004
/**
* @def MDIO_MODEFLG_HD100
*      Use 100Mb/s Half Duplex
*/
#define MDIO_MODEFLG_HD100                  0x0008
/**
* @def MDIO_MODEFLG_FD100
*      Use 100Mb/s Full Duplex
*/
#define MDIO_MODEFLG_FD100                  0x0010
/**
* @def MDIO_MODEFLG_FD1000
*      Use 1000Mb/s Full Duplex
*/
#define MDIO_MODEFLG_FD1000                 0x0020
/**
* @def MDIO_MODEFLG_LOOPBACK
*     Use internal PHY Loopback
*/
#define MDIO_MODEFLG_LOOPBACK               0x0040
/**
* @def MDIO_MODEFLG_NOPHY
*      Use external SMA connectors instead of PHY
*/
#define MDIO_MODEFLG_NOPHY                  0x0080


/**
* @def EMAC_RXFILTER_NOTHING
*      Receive filter set to Nothing
*/
#define EMAC_RXFILTER_NOTHING               0
/**
* @def EMAC_RXFILTER_DIRECT
*      Receive filter set to Direct
*/
#define EMAC_RXFILTER_DIRECT                1
/**
* @def EMAC_RXFILTER_BROADCAST
*      Receive filter set to Broadcast
*/
#define EMAC_RXFILTER_BROADCAST             2
/**
* @def EMAC_RXFILTER_MULTICAST
*      Receive filter set to Multicast
*/
#define EMAC_RXFILTER_MULTICAST             3
/**
* @def EMAC_RXFILTER_ALLMULTICAST
*      Receive filter set to All Mcast
*/
#define EMAC_RXFILTER_ALLMULTICAST          4
/**
* @def EMAC_RXFILTER_ALL
*      Receive filter set to All
*/
#define EMAC_RXFILTER_ALL                   5

/** Internal functions return error codes */
/**
* @def SWITCH_INSTANCE_CODE
*      Switch Instance Code
*/
#define SWITCH_INSTANCE_CODE                        0u
/**
* @def SWITCH_ERROR_BASE
*     Switch Error Base
*/
#define SWITCH_ERROR_BASE                           (0x200001Fu)
/**
* @def SWITCH_ERROR_CODE
*      Switch Error Code
*/
#define SWITCH_ERROR_CODE                           ((SWITCH_ERROR_BASE | (SWITCH_INSTANCE_CODE << 16)))
/**
* @def SWITCH_ERROR_INFO
*      Switch Error/Informational
*/
#define SWITCH_ERROR_INFO                           (SWITCH_ERROR_CODE)
/**
* @def SWITCH_ERROR_WARNING
*      Switch Error/Warning
*/
#define SWITCH_ERROR_WARNING                        (SWITCH_ERROR_CODE | 0x10000000u)
/**
* @def SWITCH_ERROR_MINOR
*      Switch Error Minor
*/
#define SWITCH_ERROR_MINOR                          (SWITCH_ERROR_CODE | 0x20000000u)
/**
* @def SWITCH_ERROR_MAJOR
*      Switch Error Major
*/
#define SWITCH_ERROR_MAJOR                          (SWITCH_ERROR_CODE | 0x30000000u)
/**
* @def SWITCH_ERROR_CRITICAL
*      Switch Error Critical
*/
#define SWITCH_ERROR_CRITICAL                       (SWITCH_ERROR_CODE | 0x40000000u)

/**
* @def SWITCH_SUCCESS
*      Success code
*/
#define SWITCH_SUCCESS                              0u
/**
* @def SWITCH_ERR_DEV_ALREADY_INSTANTIATED(instID)
*      Device with same instance ID already created
*/
#define SWITCH_ERR_DEV_ALREADY_INSTANTIATED(instID) (0x30000000u + SWITCH_ERROR_BASE + ((instId) << 16) )
/**
* @def SWITCH_ERR_DEV_NOT_INSTANTIATED
*       Device is not instantiated yet
*/
#define SWITCH_ERR_DEV_NOT_INSTANTIATED             (SWITCH_ERROR_MAJOR + 1u)
/**
* @def SWITCH_INVALID_PARAM
*      Function or calling parameter is invalid
*/
#define SWITCH_INVALID_PARAM                        (SWITCH_ERROR_MAJOR + 2u)
/**
* @def SWITCH_ERR_CH_INVALID
*      Channel number invalid
*/
#define SWITCH_ERR_CH_INVALID                       (SWITCH_ERROR_CRITICAL + 3u)
/**
* @def SWITCH_ERR_CH_ALREADY_INIT
*      Channel already initialized and setup
*/
#define SWITCH_ERR_CH_ALREADY_INIT                  (SWITCH_ERROR_MAJOR + 4u)
/**
* @def SWITCH_ERR_TX_CH_ALREADY_CLOSED
*      STx Channel already  closed. Channel close failed
*/
#define SWITCH_ERR_TX_CH_ALREADY_CLOSED             (SWITCH_ERROR_MAJOR + 5u)
/**
* @def SWITCH_ERR_TX_CH_NOT_OPEN
*      Tx Channel not open.
*/
#define SWITCH_ERR_TX_CH_NOT_OPEN                   (SWITCH_ERROR_MAJOR + 6u)
/**
* @def SWITCH_ERR_TX_NO_LINK
*      Tx Link not up.
*/
#define SWITCH_ERR_TX_NO_LINK                       (SWITCH_ERROR_MAJOR + 7u)
/**
* @def SWITCH_ERR_TX_OUT_OF_BD
*      Tx ran out of Buffer descriptors to use.
*/
#define SWITCH_ERR_TX_OUT_OF_BD                     (SWITCH_ERROR_MAJOR + 8u)
/**
* @def SWITCH_ERR_RX_CH_INVALID
*     Rx Channel invalid number.
*/
#define SWITCH_ERR_RX_CH_INVALID                    (SWITCH_ERROR_CRITICAL + 9u)
/**
* @def SWITCH_ERR_RX_CH_ALREADY_INIT
*      Rx Channel already setup
*/
#define SWITCH_ERR_RX_CH_ALREADY_INIT               (SWITCH_ERROR_MAJOR + 10u)
/**
* @def SWITCH_ERR_RX_CH_ALREADY_CLOSED
*      Rx Channel already closed. Channel close failed
*/
#define SWITCH_ERR_RX_CH_ALREADY_CLOSED             (SWITCH_ERROR_MAJOR + 11u)
/**
* @def SWITCH_ERR_RX_CH_NOT_OPEN
*      Rx Channel not open yet
*/
#define SWITCH_ERR_RX_CH_NOT_OPEN                   (SWITCH_ERROR_MAJOR + 12u)
/**
* @def SWITCH_ERR_DEV_ALREADY_CREATED
*      EMAC device already created.
*/
#define SWITCH_ERR_DEV_ALREADY_CREATED              (SWITCH_ERROR_MAJOR + 13u)
/**
* @def SWITCH_ERR_DEV_NOT_OPEN
*      Device is not open or not ready
*/
#define SWITCH_ERR_DEV_NOT_OPEN                     (SWITCH_ERROR_MAJOR + 14u)
/**
* @def SWITCH_ERR_DEV_ALREADY_CLOSED
*      Device close failed. Device already closed
*/
#define SWITCH_ERR_DEV_ALREADY_CLOSED               (SWITCH_ERROR_MAJOR + 15u)
/**
* @def SWITCH_ERR_DEV_ALREADY_OPEN
*      Device open failed. Device already open.l
*/
#define SWITCH_ERR_DEV_ALREADY_OPEN                 (SWITCH_ERROR_MAJOR + 16u)
/**
* @def SWITCH_ERR_RX_BUFFER_ALLOC_FAIL
*      Rx Buffer Descriptor allocation failed
*/
#define SWITCH_ERR_RX_BUFFER_ALLOC_FAIL             (SWITCH_ERROR_CRITICAL +17u)
/**
* @def SWITCH_INTERNAL_FAILURE
*       EMAC Internal failure
*/
#define SWITCH_INTERNAL_FAILURE                     (SWITCH_ERROR_MAJOR + 18u)
/**
* @def SWITCH_VLAN_UNAWARE_MODE
*      VLAN support not enabled in EMAC
*/
#define SWITCH_VLAN_UNAWARE_MODE                    (SWITCH_ERROR_MAJOR + 19u)
/**
* @def SWITCH_ALE_TABLE_FULL
*      ALE Table full.
*/
#define SWITCH_ALE_TABLE_FULL                       (SWITCH_ERROR_MAJOR + 20u)
/**
* @def SWITCH_ADDR_NOTFOUND
*      Multicast/Unicast/OUI Address not found in ALE
*/
#define SWITCH_ADDR_NOTFOUND                        (SWITCH_ERROR_MAJOR + 21u)
/**
* @def SWITCH_INVALID_VLANID
*      Invalid VLAN Id.
*/
#define SWITCH_INVALID_VLANID                       (SWITCH_ERROR_MAJOR + 22u)
/**
* @def SWITCH_INVALID_PORT
*      Invalid Port Specified
*/
#define SWITCH_INVALID_PORT                         (SWITCH_ERROR_MAJOR + 23u)
/**
* @def SWITCH_BD_ALLOC_FAIL
*      Buffer Descriptor Allocation failure. OOM
*/
#define SWITCH_BD_ALLOC_FAIL                        (SWITCH_ERROR_MAJOR + 24u)
/**
* @def SWITCH_ERR_BADPACKET
*      Supplied packet was invalid
*/
#define SWITCH_ERR_BADPACKET                        (SWITCH_ERROR_MAJOR + 25u)
/**
* @def SWITCH_ERR_COLLISION_FAIL
*     Collision queue was full
*/
#define SWITCH_ERR_COLLISION_FAIL                   (SWITCH_ERROR_MAJOR + 26u)
/**
* @def SWITCH_ERR_MACFATAL
*      Fatal Error - EMACClose() requiredl
*/
#define SWITCH_ERR_MACFATAL                         (SWITCH_ERROR_CRITICAL + 26u)


/**
* @def EMAC_DEVMAGIC
*      Device Magic number
*/
#define EMAC_DEVMAGIC                       0x0aceface
/**
* @def ICSS_HANDLE_VALUE
*      Device Handle Value
*/
#define ICSS_HANDLE_VALUE					0x12345678

/** Control Codes for internal control function*/
/**
* @def SWITCH_PHY_STATUS_UPDATE
*
*/
#define SWITCH_PHY_STATUS_UPDATE			0u




/**
 *  @brief  EMAC_Pkt
 *  @details The packet structure defines the basic unit of memory used to hold data
 *  packets for the EMAC device.
 *  A packet is comprised of one or more packet buffers. Each packet buffer
 *  contains a packet buffer header, and a pointer to the buffer data.
 *  The EMAC_Pkt structure defines the packet buffer header.
 *
 *  The pDataBuffer field points to the packet data. This is set when the
 *  buffer is allocated, and is not altered.
 *
 *  BufferLen holds the the total length of the data buffer that is used to
 *  store the packet (or packet fragment). This size is set by the entity
 *  that originally allocates the buffer, and is not altered.
 *
 *  The Flags field contains additional information about the packet
 *
 *  ValidLen holds the length of the valid data currently contained in the
 *  data buffer.
 *
 *  DataOffset is the byte offset from the start of the data buffer to the
 *  first byte of valid data. Thus (ValidLen+DataOffet)<=BufferLen.
 *
 *  Note that for receive buffer packets, the DataOffset field may be
 *  assigned before there is any valid data in the packet buffer. This allows
 *  the application to reserve space at the top of data buffer for private
 *  use. In all instances, the DataOffset field must be valid for all packets
 *  handled by EMAC.
 *
 *  The data portion of the packet buffer represents a packet or a fragment
 *  of a larger packet. This is determined by the Flags parameter. At the
 *  start of every packet, the SOP bit is set in Flags. If the EOP bit is
 *  also set, then the packet is not fragmented. Otherwise; the next packet
 *  structure pointed to by the pNext field will contain the next fragment in
 *  the packet. On either type of buffer, when the SOP bit is set in Flags,
 *  then the PktChannel, PktLength, and PktFrags fields must also be valid.
 *  These fields contain additional information about the packet.
 *
 *  The PktChannel field detetmines what channel the packet has arrived on,
 *  or what channel it should be transmitted on. The EMAC library supports
 *  only a single receive channel, but allows for up to eight transmit
 *  channels. Transmit channels can be treated as round-robin or priority
 *  queues.
 *
 *  The PktLength field holds the size of the entire packet. On single frag
 *  packets (both SOP and EOP set in BufFlags), PktLength and ValidLen will
 *  be equal.
 *
 *  The PktFrags field holds the number of fragments (EMAC_Pkt records) used
 *  to describe the packet. If more than 1 frag is present, the first record
 *  must have EMAC_PKT_FLAGS_SOP flag set, with corresponding fields validated.
 *  Each frag/record must be linked list using the pNext field, and the final
 *  frag/record must have EMAC_PKT_FLAGS_EOP flag set and pNext=0.
 *
 *  In systems where the packet resides in cacheable memory, the data buffer
 *  must start on a cache line boundary and be an even multiple of cache
 *  lines in size. The EMAC_Pkt header must not appear in the same cache line
 *  as the data portion of the packet. On multi-fragment packets, some packet
 *  fragments may reside in cacheable memory where others do not.
 *
 *  It is up to the caller to assure that all packet buffers
 *   residing in cacheable memory are not currently stored in L1 or L2
 *   cache when passed to any EMAC function.
*/
typedef struct _EMAC_Pkt {
    Uint32           AppPrivate;		/**< For use by the application                                         */
    struct _EMAC_Pkt *pPrev;			/**< Previous record                                                    */
    struct _EMAC_Pkt *pNext;			/**< Next record                                                        */
    Uint8            *pDataBuffer;		/**< Pointer to Data Buffer (read only)                                 */
    Uint32           BufferLen;			/**< Physical Length of buffer (read only)                              */
    Uint32           Flags;				/**< Packet Flags                                                       */
    Uint32           ValidLen;			/**< Length of valid data in buffer                                     */
    Uint32           DataOffset;		/**< Byte offset to valid data                                          */
    Uint32           PktChannel;		 /**< Tx/Rx Channel/Priority 0-7 (SOP only)                              */
    Uint32           PktLength;			/**< Length of Packet (SOP only) (same as ValidLen on single frag Pkt)  */
    Uint32           PktFrags;			/**< No of frags in packet (SOP only) frag is EMAC_Pkt record-normally 1*/
} EMAC_Pkt;


/**
 *  @brief  typeOfData
 */
typedef enum
{
        BROADCAST = 0,	/** Type is Broadcast */
        MULTICAST,		/** Type is Multicast */
        UNICAST			/** Type is Unicast */
}typeOfData;


/**
 *  @brief Port structure
 *
 */
typedef struct
{
  Uint32            portNum;		/**< Port number 0-2                                                  */
  Uint32            chNum;			 /**< Ch number 0-7 (currently unused - may not need it)               */
} SwitchPort;

/**
 *  @brief  MAC Info Instance Structure
 *
 */
typedef struct SwitchmacObj_t
{
    PHY_DEVICE      PhyDev;				/**< MII-MDIO module device structure                               */
    Uint32          portState;			/**< State of each port                                             */
    /* Status related fields */
    Uint32          PhyLinked;			/**< Link status: 1=Linked, 0=No link                               */
    Uint32          PhyDuplex;			/**< Duplex status: 1=Full Duplex, 0=Half Duplex                    */
    Uint32          PhySpeed;			/**< Link Speed = 1= 100 mbps, 0= 10 mbps             */
    Uint32          PhyNum;				/**< Phy number - useful if phy number is discovered                */
    /* mode of operation related s/w fields */
    Bool	        intPhy;				/**< Flag to indicate if this is an internal PHY                    */
    Bool	        broadcastEnable;	/**< Flag to indicate if Broadcast is enabled on this port          */
    Bool	        multicastEnable;	/**< Flag to indicate if Multicast is enabled on this port          */
}CpgmacObj;


/**
 *  @brief MAC addresses configuration Structure
 *
 */
typedef struct _EMAC_AddrConfig {
	Uint8 Addr[6];		/** MAC address specific to channel */
} EMAC_AddrConfig;

/**
 *  @brief CPGMAC SL Init Configuration
 *  Configuration information provided during initialization.
 *  The config info can come from various sources - static compiled in info,
 *  boot time (Flash) info etc. Currently static compiled values supported.
 */
typedef struct
{
  Uint32      PhyMask;		/**< Phy Mask for this CPMAC Phy                                          */
  Uint32      MLinkMask;	/**< MLink Mask for this CPMAC Phy                                        */
  Uint32      phyMode;		/**< Phy mode settings - Speed,Duplex                                     */
  Uint32      phyNum;		/**< Phynumber                                                            */
  Uint8       portPri;		/**< Port VLAN priority (7 is highest)                                    */
  Bool        portCfi;		/**< Port CFI bit                                                         */
  Uint32      portVID;		/**< Port VLAN ID                                                         */
  Uint32      macModeFlags;	/**< Configuation Mode Flags                                              */
  Uint32      mdioModeFlags;/**< MDIO configuration flags for this MAC port                           */
} SwitchMacConfig;

/**
 *  @brief CPGMAC_SL PHY Status values
 *  		Provides PHY status of the device.
 *
 */
typedef struct
{
  Uint32      PhyLinked;	/**< Link status: 1=Linked, 0=No link                                     */
  Uint32      PhyDuplex;	/**< Duplex status: 1=Full Duplex, 0=Half Duplex                          */
  Uint32      PhySpeed;		/**< Link Speed = 1= 100 mbps, 0= 10 mbps                                 */
  Uint32      PhyNum;		/**< Phy number - useful if phy number is discovered                      */
} SwitchMacStatus;

/**
 *  @brief  configuration
 *			This data structure contains configuration items related to the
 *  		CONTROL and PTYPE register fields.
 */
typedef struct
{
  Uint32        mdioBusFrequency;	/**< Bus frequency for the MII module                                     */
  Uint32        mdioClockFrequency;	/**< Clock frequency for MDIO link                                        */
} SwitchConfig;

/**
 *  @brief ALE configuration
 *			This data structure contains configuration items related to the
 *  		ALE_CONTROL register fields.
 */
typedef struct
{
  Uint32        aleModeFlags;	/** ALE Control fields                                                     */
} AleConfig;



/**
 *  @brief ALE Port configuration
 *			This data structure contains configuration items related to the
 *  		ALE_Port_Control register fields.
 */
typedef struct
{
  Uint8         bcastLimit;		/**< Broadcast Packet Rate Limit                                          */
  Uint8         mcastLimit;		/**< Multicast Packet Rate Limit                                          */
} AlePortConfig;


/**
 *  @brief  SwitchInitConfig
 *
 *  The config structure defines how the EMAC device should operate. It is
 *  passed to the device when the device is opened, and remains in effect
 *  until the device is closed.
 *  A list of callback functions is used to register callback functions with
 *  a particular instance of the EMAC peripheral. Callback functions are
 *  used by EMAC to communicate with the application. These functions are
 *  REQUIRED for operation. The same callback table can be used for multiple
 *  driver instances.
 *
 *  The callback functions can be used by EMAC during any EMAC function, but
 *  mostly occur during calls to EMAC_statusIsr() and EMAC_statusPoll().
 *
 *  <b>pfcbRxPacket </b>   - Called to give a received data packet to the
 *                   application layer. The applicaiton must accept the packet.
 *                   When the application is finished with the packet, it
 *                   can return it to its own free queue. This function also
 *                   returns a pointer to a free packet to replace the received
 *                   packet on the EMAC free list. It returns NULL when no free
 *                   packets are available. The return packet is the same as
 *                   would be returned by pfcbGetPacket. Thus if a newly
 *                   received packet is not desired, it can simply be returned
 *                   to EMAC via the return value.
 *

 *
 *  The hApplication calling calling argument is the application's handle
 *  as supplied to the EMAC device in the EMACOpen() function.
 */
typedef struct _SwitchInitConfig {
    Uint8               CoreNum;							/**< This member is for core selction to does the EMAC configuration
          	  	  	  	  	  	  	 	 	 	 	 	 	 i.e user can select the specific core to configure EMAC one time  */
    Uint8               DescBase;							/**< Base Addres ICSS module.                                            */
    Uint32              PktMTU;                             /**< MTU for the interfaces.                                            */
    /* Port specific items                                                  */
    SwitchMacConfig     macInitCfg[SWITCH_NUM_MAC_PORTS];	/**< CPGMAC SL Init Configuration                                       */
    /* ALE specific items                                                   */
    AleConfig           aleCfg;								/**< ALE Init Configuration                                             */
    AlePortConfig       alePortCfg[SWITCH_NUM_PORTS];		/**< ALE Port Configuration                                             */
    /* Switch specific items */
    SwitchConfig        switchCfg;							/**< Control register fields                                       */
    Uint32              linkSpeed[SWITCH_NUM_MAC_PORTS];	/**<Link Speed                                                          */
    Uint32              linkMode[SWITCH_NUM_MAC_PORTS];		/**<Link Mode                                                           */
    Uint32              linkStatus[SWITCH_NUM_MAC_PORTS];	/**<Link Status                                                         */
    Uint32		        aleTicks;							/**< Ticks for this timer                                               */
    Uint32 		        aleTimerActive;						/**<ALE ageout timer active?                                            */
	Uint8               TotalNumOfMacAddrs;					/**< Total number of MAC addresses to be assigned for all receive channels */
    EMAC_AddrConfig     **MacAddr;							/**< Mac Addresses structure                                            */
    Uint32              RxFilter;							 /**<Receive Filter settings    */
    EMAC_Pkt *          (*pfcbRxPacket)(Handle hApplication, EMAC_Pkt *pPacket);/**< Receive packet call back                                           */

} SwitchInitConfig;




/**
 *  @brief  EMAC Main Device Instance Structure
 *
 */
typedef struct _SwitchDevice {
    Uint32              DevMagic;							/**< Magic ID for this instance                                         */
    Handle              hApplication;						/**< Calling Application's Handle                                       */
    Uint32              PktMTU;								/**< Max physical packet size                                           */
    Uint32              FatalError;							/**< Fatal Error Code                                                   */
    CpgmacObj		    cpgmacMac[SWITCH_NUM_MAC_PORTS];	/**<CPGMAC MAC Book keeping structures                                  */
    SwitchPort		    switchPort[SWITCH_NUM_PORTS];		/**<Port Mapping structures                                             */
    SwitchInitConfig    Config;								/**< Original User Configuration                                        */
    IcssSwitchStatistics     Stats[SWITCH_NUM_PORTS];		/**< Current running statistics                                         */

} SwitchDevice;

/* @} */

/**
 *  \defgroup   EMACInterfaces   EMAC Interfaces
 *
 *  Interfaces for EMAC module.
 *
 *  \par
 *  <b> Note: </b>The application is charged with verifying that only
 *  one of the following API calls may be executing at a given time across all
 *  threads and all interrupt functions.
 *  \par
 *  Hence, when used in an multitasking environment, no EMAC function may be
 *  called while another EMAC function is operating on the same device
 *  handle in another thread. It is the responsibility of the application
 *  to assure adherence to this restriction.
 *
 *  @{
 */

/**
* @internal
* @brief  Opens the EMAC peripheral at the given physical index and initializes
*     		it to an embryonic state.
* @details	   The calling application must supply a operating configuration that
*     		includes a callback function table. Data from this config structure is
*     		copied into the device's internal instance structure so the structure
*     		may be discarded after EMACOpen() returns. In order to change an item
*     		in the configuration, the EMAC device must be closed and then
*     		re-opened with the new configuration.
*
*     			The application layer may pass in an hApplication callback handle,
*     		that will be supplied by the EMAC device when making calls to the
*     		application callback functions.
*
*     		An EMAC device handle is written to phEMAC. This handle must be saved
*     		by the caller and then passed to other EMAC device functions.
*
*     		The default receive filter prevents normal packets from being received
*     		until the receive filter is specified by calling EMAC_receiveFilter().
*
*     		A device reset is achieved by calling EMACClose() followed by EMACOpen().
*
*     		The function returns zero on success, or an error code on failure.
*
*     		Possible error codes include:
*       		SWITCH_ERR_DEV_ALREADY_OPEN   - The device is already open
*       		SWITCH_INVALID_PARAM   - A calling parameter is invalid
*
* @param physicalIndex   physical index
* @param hApplication    application handle
* @param pEMACConfig     EMAC's configuration structure
* @param phEMAC          handle to the EMAC device
*
* @retval 	Success (0)
*			SWITCH_INVALID_PARAM   - A calling parameter is invalid
*			SWITCH_ERR_DEV_ALREADY_OPEN   - The device is already open
*
*/
Uint32 EMACOpen(int physicalIndex, Handle hApplication,
                 SwitchInitConfig *pEMACConfig, Handle *phEMAC);
/**
* @internal
* @brief Closed the EMAC peripheral indicated by the supplied instance handle.
*     		When called, the EMAC device will shutdown both send and receive
*     		operations, and free all pending transmit and receive packets.
* @details    The function returns zero on success, or an error code on failure.
*     			Possible error code include:
*         		SWITCH_INVALID_PARAM   - A calling parameter is invalid
*
* @param hEMAC   handle to opened the EMAC device
*
* @retval 	Success (0)
*			SWITCH_INVALID_PARAM   - A calling parameter is invalid
* @pre      EMACOpen function must be called before calling this API.
*
*/
Uint32 EMACClose( Handle hEMAC );
/**
* @internal
* @brief 	Called to get the current device statistics. The statistics structure
*     		contains a collection of event counts for various packet sent and
*     		receive properties. Reading the statistics also clears the current
*     		statistic counters, so the values read represent a delta from the last
*     		call.
* @details  The statistics information is copied into the structure pointed to
*     			by the pStatistics argument.
*     			The function returns zero on success, or an error code on failure.
*     			Possible error code include:
*      			SWITCH_INVALID_PARAM   - A calling parameter is invalid
*
* @param  hEMAC       handle to the opened EMAC device
* @param  pStatistics Get the device statistics
*
* @retval 	Success (0)
*			SWITCH_INVALID_PARAM   - A calling parameter is invalid
* @pre      EMAC peripheral instance must be opened before calling this API
*
*/
Uint32 EMACGetStatistics( Handle hEMAC, IcssSwitchStatistics *pStatistics,Uint8 portNo);
/**
* @internal
* @brief 	Called to clear the current device statistics for a particular port
*
* @param  hEMAC       handle to the opened EMAC device
* @param  portNo      port to clear statistics
*
* @retval 	Success (0)
*			SWITCH_INVALID_PARAM   - A calling parameter is invalid
* @pre      EMAC peripheral instance must be opened before calling this API
*
*/
Uint32 EMACClearStatistics(Handle hEMAC,Uint8 portNo);
/**
* @internal
* @brief 	This function is called to perform various get/set operations on the
*     		EMAC ALE table, statistics counters etc.
*
* @param  hEMAC       handle to the opened EMAC device
* @param  pBuf        pointer to the buffer that holds the configuration
                      command and any data required.
* @param  size        size of the buffer
*
* @retval 	Success (0)
*			SWITCH_INVALID_PARAM   - A calling parameter is invalid
* @pre      EMAC peripheral instance must be opened before calling this API
*
*/
Uint32 EMACSetConfig(Handle hEMAC, void* pBuf, Uint32 size);
/**
* @internal
* @brief 	Sends a Ethernet data packet out the EMAC device. On a non-error return,
*     		the EMAC device takes ownership of the packet. The packet is returned
*     		to the application's free pool once it has been transmitted.
*
* @param  hEMAC       handle to the opened EMAC device
* @param  pPkt        EMAC packet structure
*
* @retval 	Success (0)
*			SWITCH_INVALID_PARAM   - A calling parameter is invalid
*			SWITCH_ERR_BADPACKET - The packet structure is invalid
* @pre      EMAC peripheral instance must be opened and get a packet
*     		 buffer from private queue
*
*/
Uint32 EMACSendPacket(Handle hEMAC, EMAC_Pkt *pPkt);
/**
* @internal
* @brief 	This function should be called every time there is an EMAC device Rx
*     		interrupt to process the packet
* @details  Note that the application has the responsibility for mapping the
*     		physical device index to the correct EMAC_serviceCheck() function. If
*     		more than one EMAC device is on the same interrupt, the function must be
*     		called for each device.
*
* @param  hEMAC       handle to the opened EMAC device
*
* @retval 	Success (0)
*			SWITCH_INVALID_PARAM   - A calling parameter is invalid
*			SWITCH_ERR_MACFATAL  - Fatal error in the MAC - Call EMACClose()
* @pre     EMACOpen function must be called before calling this API.
*
*/
Uint32 EMACRxServiceCheck(Handle hEMAC,Int32 prioQueue);
/**
* @internal
* @brief This function configures the MACCONTROL register according to the user
*  			defined PHY speed, duplex link settings
*
* @param gmacObject          GMAC Object whose PHY needs to be updated
* @param instanceNum         MAC port identifier
*
* @retval Always returns SWITCH_SUCCESS
*
*/
Uint32 ICSSUpdatePhystatus(CpgmacObj* gmacObject , Uint32 instanceNum);
/**
* @internal
* @brief 	Function to Update the PHY configuration
*
* @param  phyConfig  	PHY_CONFIG_AUTONEG
*                		PHY_CONFIG_100FD
*                		PHY_CONFIG_10FD
*                		PHY_CONFIG_100HD
*                		PHY_CONFIG_10HD
* @param   portNum 		HWPORT0(0)
*                 		HWPORT1(1)
*
* @retval 	none
*
*/
void EMACUpdatePhyConfig(Uint8 phyConfig,Uint8 portNum);
/**
* @internal
* @brief This function is called to update the local copy of device configuration
*  			with the updated Phy status and parameters
*
* @param devPtr              device pointer to be updated
* @param cmd                 Type of update being received. Currently, only one
*                            supported, i.e. SWITCH_PHY_STATUS_UPDATE
* @param cmdArg              Command argument, pointer to the updated link parameters
* @param param               Pointer to MAC port object to update.
*
* @retval Always returns SWITCH_SUCCESS
*
*/
void ICSSControlCb(SwitchDevice* devPtr,Uint32 cmd,Ptr cmdArg, Ptr param);
/**
* @internal
* @brief The function initialize an EMAC_Pkt to receive packets
*
* @param none
*
* @retval none
*/
void PacketInit();

#ifdef DEBUG_STATS
//Structure for debugging
typedef struct _raweth_stat{
	Uint32 cslRxCnt;
	Uint32 ethRxCnt;
	Uint32 nimuRxCnt;
	Uint32 cslTxCnt;
	Uint32 ethTxCnt;
	Uint32 nimuTxCnt;
	Uint32 retryTxCnt;
	Uint32 notGoCnt;
	Uint32 appRxCnt;
	Uint32 intPktEnq;
}RAWETH_STAT;
extern RAWETH_STAT raweth_stat;
#endif

#ifdef __cplusplus
}
#endif
#endif /* _ICSS_SWITCH_EMAC_H_ */
