/*******************************************************************************
 * (c) Copyright 2014-2016 Microsemi SoC Products Group.  All rights reserved.
 *
 * CoreTSE 10/100/1000 Mbps Ethernet MAC bare metal software driver public API.
 *
 * SVN $Revision: 8433 $
 * SVN $Date: 2016-06-20 16:58:52 +0530 (Mon, 20 Jun 2016) $
 */
/*=========================================================================*//**
  @mainpage CoreTSE Bare Metal Driver.

  @section intro_sec Introduction
    This document describes the bare metal software driver for CoreTSE_AHB and
    CoreTSE soft IP. The CoreTSE_AHB/CoreTSE is a hardware soft IP core that
    implements 10/100/1000 Mbps Ethernet MAC. The CoreTSE_AHB/CoreTSE supports
    MII / GMII / TBI interfaces to the physical layer devices (PHY). Only
    difference between CoreTSE_AHB and CoreTSE soft IP is that the CoreTSE_AHB
    has DMA with AHB interface for transmit and receive data packets whereas the
    CoreTSE does not. For CoreTSE no firmware intervention is needed for packet
    transmit/receive DMA operations.  All the other operations are same for
    CoreTSE_AHB and CoreTSE soft IP and this driver can be used to execute them.

    This software driver provides a set of functions for controlling the
    CoreTSE_AHB/CoreTSE as part of a bare metal system where no operating system
    is available. This driver can be adapted for use as part of an operating
    system, but the implementation of the adaptation layer between the driver
    and the operating system's driver model is outside the scope of the driver.

  @section hw_dependencies Hardware Flow Dependencies
    The configuration of all features of the CoreTSE_AHB or CoreTSE soft IP is
    covered by this driver with the exception of the selection of the Ethernet
    PHY, the PHY interface, the size of transmit and receive rings and the MDIO
    address of the “TBI/1000BaseX” module within CoreTSE_AHB/CoreTSE.

    The driver for the Ethernet PHY connected to the CoreTSE_AHB/CoreTSE is
    selected using the Firmware Catalog configuration dialogue window. It gives
    the option of using one of a set of supported PHYs. This choice will affect
    which source file that will be generated by the Firmware Catalog.

    The PHY interface type is selected using the Firmware Catalog configuration
    dialogue window. This driver supports MII, RMII, GMII, RGMII, SGMII and
    1000baseX interface. Refer Table-1 for explanation of PHY interface.

    The number of transmit and receive buffers is also selected using the
    Firmware Catalog configuration dialogue window. The Firmware Catalog generates
    a C header file containing these choices which is used as part of the
    CoreTSE_AHB/CoreTSE implementation. The selected values will be used to
    define the size of the transmit descriptor ring and receive descriptor ring
    within the driver. They define the maximum number of transmit and receive
    packets that can be queued.

    The MDIO address of the “Ten Bit Interface” module within CoreTSE_AHB/CoreTSE
    is also selected using the Firmware Catalog configuration dialogue window.
    Note that this selection is applicable only when CoreTSE_AHB/CoreTSE is
    configured to operate in TBI mode. This selection is ignored when
    CoreTSE_AHB/CoreTSE is configured to operate in G/MII mode.

    The system may use the CoreTSE_AHB/CoreTSE in GMII mode and use an external
    CoreRGMII soft IP to interface with a PHY using RGMII interface type. If the
    CoreRGMII is being used in the system, then the MDIO address of the CoreRGMII
    also needs to be configured here for this driver.

    The Firmware Catalog will generate definitions based on the settings entered
    on this dialogue into the driver’s coretse_user_cfg.h file.

    Your application software should configure the CoreTSE_AHB/CoreTSE driver,
    through calls to the TSE_init() function for each CoreTSE_AHB/CoreTSE
    instance in the hardware design.

                            Table 1 • PHY Interface
            PHY Interface                       Explanation

                MII             CoreTSE_AHB/CoreTSE operates in MII mode and
                                interfaces with MII PHY directly.

                GMII            CoreTSE_AHB/CoreTSE operates in GMII mode and
                                interfaces with GMII PHY directly.

                SGMII           CoreTSE_AHB/CoreTSE operates in TBI mode
                                (Internal TBI/1000BaseX module is enabled).
                                Interfaces with SGMII PHY using SERDES and SGMII
                                type link ANEG.

                1000BaseX       CoreTSE_AHB/CoreTSE operates in TBI mode
                                (Internal TBI/1000BaseX module is enabled).
                                Interfaces with remote partner over fiber link
                                using SERDES and 1000BaseX type link ANEG.

                RGMII           CoreTSE_AHB/CoreTSE operates in MII mode.
                                External CoreRMII is used to interface with
                                RMII PHY.

                RMII            CoreTSE_AHB/CoreTSE operates in GMII mode.
                                External CoreRGMII is used to interface with
                                RGMII PHY.

  @section theory_op Theory of Operation
    The CoreTSE software driver is designed to allow the control of multiple
    instances of CoreTSE_AHB/CoreTSE. Each instance of CoreTSE_AHB/CoreTSE in
    the hardware design is associated with a single instance of the tse_instance_t
    structure in the software. You need to allocate memory for one unique
    tse_instance_t structure instance for each CoreTSE_AHB/CoreTSE hardware
    instance. The contents of these data structures are initialized during calls
    to function TSE_init(). A pointer to this structure is passed to subsequent
    driver functions in order to identify the CoreTSE_AHB/CoreTSE hardware
    instance you wish to perform the requested operation on.

    Note:   Do not attempt to directly manipulate the content of tse_instance_t
    structures. This structure is only intended to be modified by the driver
    function.

    The CoreTSE driver functions are grouped into the following categories:
            •   Initialization and configuration
            •   Transmit operations
            •   Receive operations
            •   Reading link status and statistics
            •   Address based frame filtering
            •   Wake-up on LAN (WoL) with unicast match and AMD magic packet detection
            •   Jumbo Frames

    Initialization and Configuration
    The CoreTSE driver is initialized and configured by calling the TSE_init()
    function. The TSE_init() function takes a pointer to a configuration data
    structure as parameter. This data structure contains all the configuration
    information required to initialize and configure the CoreTSE_AHB/CoreTSE.

    The CoreTSE driver provides the TSE_cfg_struct_def_init() function to
    initialize the configuration data structure to default value. It is
    recommended to use this function to retrieve the default configuration then
    overwrite the defaults with the application specific settings such as PHY
    address, allowed link speeds, link duplex mode and MAC address.

    The TSE_init() function must be called before any other CoreTSE driver
    functions. The TSE_cfg_struct_def_init() is the only function which can be
    called before calling the TSE_init() function.

    The following functions are used as part of the initialization and
    configuration process:
            •   TSE_cfg_struct_def_init()
            •   TSE_init()

    Transmit Operations
    The CoreTSE driver transmit operations are interrupt driven. The application
    must register a transmit call-back function with the driver using the
    TSE_set_tx_callback() function. This call-back function will be called by
    the CoreTSE driver every time a packet has been sent.

    The application must call the TSE_send_pkt() function every time it wants to
    transmit a packet. The application must pass a pointer to the buffer
    containing the packet to send. It is the application’s responsibility to
    manage the memory allocated to store the transmit packets. The CoreTSE
    driver only requires a pointer to the buffer containing the packet and the
    packet size. The CoreTSE driver will call the transmit call-back function
    registered using the TSE_set_tx_callback() function once a packet is sent.
    The transmit call-back function is supplied by the application and can be
    used to release the memory used to store the packet that was sent.

    The following functions are used as part of transmit and receive operations:
            •   TSE_send_pkt()
            •   TSE_set_tx_callback()


    Note: This operation is applicable only for CoreTSE_AHB. This operation is not
    supported on CoreTSE soft IP.

    Receive Operations
    The CoreTSE driver receive operations are interrupt driven. The application
    must first register a receive call-back function using the
    TSE_set_rx_callback() function. The application can then allocate receive
    buffers to the CoreTSE driver by calling the TSE_receive_pkt() function.
    This function can be called multiple times to allocate more than one receive
    buffer. The CoreTSE driver will then call the receive call-back function
    whenever a packet is received into one of the receive buffer. It will hand
    back the receive buffer to the application for packet processing. This
    buffer will not be reused by the CoreTSE driver unless it is re-allocated
    to the driver by a call to TSE_receive_pkt().

    The following functions are used as part of transmit and receive operations:
            •   TSE_receive_pkt()
            •   TSE_set_rx_callback()

    Note: This operation is applicable only for CoreTSE_AHB. This operation is not
    supported on CoreTSE soft IP.

    Reading Status and Statistics
    The CoreTSE driver provides the following functions to retrieve the current
    link status and statistics.
            •   TSE_get_link_status()
            •   TSE_read_stat()

    Address based Frame filtering
    The CoreTSE_AHB/CoreTSE performs frame filtering based on the destination MAC
    address of the received frame. The TSE_init() function initializes the
    CoreTSE_AHB/CoreTSE hardware to a default filtering mode where only broadcast
    frames and frames with a destination address equal to the local base station
    MAC address are passed to the MAC. The Broadcast frames are usually required
    by an application to obtain an IP address. This default configuration does not
    need the frame filtering hash-table to be filled. This default configuration
    is returned with the TSE_cfg_struct_def_init() function. You may change the
    configuration before passing it to the TSE_init() function.

    The application can use the TSE_set_address_filter() function to overwrite
    the frame filter choice which was selected at the initialization time. The
    application must provide the list of MAC addresses from which it actually
    wants to receive frames (allowed MAC addresses list) to this driver using
    the TSE_set_address_filter() function. If a received frame contains one of
    the MAC addresses contained in the allowed MAC addresses list then that
    frame will be passed. The setting of the broadcast, hash-unicast/multicast
    configuration in “Frame Pass Control” register is inferred from the values
    of the MAC addresses passed to the driver in the allowed MAC addresses list.
    If all MAC addresses included in the allowed MAC addresses list are unicast
    then hash-unicast filtering is selected. This results in more unwanted
    frames being rejected. Likewise, if all MAC addresses included in the
    allowed MAC addresses list are multicast then hash-multicast filtering is
    selected. Otherwise, if the allowed MAC addresses list contains a mix of
    unicast and multicast MAC addresses, then hash-unicast and hash-multicast
    filtering is selected. Broadcast filtering is selected if the broadcast MAC
    address (FF:FF:FF:FF:FF:FF) is included in the allowed MAC addresses list.
    If the allowed MAC addresses list contains a mix of broadcast, unicast and
    multicast MAC addresses, then broadcast, hash-unicast and hash-multicast
    filtering is selected. The local base station MAC address must be included
    in the allowed MAC addresses list if the application wants to receive frames
    addressed to it after a call to TSE_set_address_filter().

    The filtering is not perfect since the filtering hardware uses a hash table.
    Therefore, some frames with an address not included in the allowed MAC
    addresses list are still passed because the hash value for their MAC address
    is identical to the hash value for an allowed MAC address. The hash
    unicast/multicast setting allows further reduction of the number of unwanted
    frames passed by both checking the MAC address against the hash table and
    checking the received MAC address unicast/multicast bit against the hash
    unicast/multicast setting of the filtering IP.

    The following functions are used as part of the frame filtering
            •   TSE_set_address_filter()

    Frame drop criterion
    Apart from the address based frame filtering, the CoreTSE_AHB/CoreTSE 
    provides the facility to drop frames based on certain criterion. This 
    criterion for the frame drop logic can be configured using framedrop_mask 
    element of the structure tse_cfg_t. The value of this element is set to 
    TSE_DEFVAL_FRAMEDROP_MASK by function TSE_cfg_struct_def_init(). This 
    configuration value will enable CoreTSE_AHB/CoreTSE to drop frames which 
    have CRC errors, Code errors and frames with unsupported op-code. You may 
    change the configuration before passing it to the TSE_init() function.

    Wake-up on LAN (WoL) with unicast match and AMD magic packet detection  
    The CoreTSE_AHB/CoreTSE supports the Wake on Lan feature with unicast match
    frame and AMD magic packet. The WoL interrupt is generated when this feature
    is enabled and one of the two frames mentioned above is received.

    This feature is disabled by default. This default configuration is returned
    with the TSE_cfg_struct_def_init() function. You may change the configuration
    before passing it to the TSE_init() function.You can enable this feature using
    TSE_WOL_UNICAST_FRAME_DETECT_EN or TSE_WOL_MAGIC_FRAME_DETECT_EN or both the
    constants with logical or operation.

    The callback handler function must be provided to this driver using
    TSE_set_wol_callback() function. A function of type tse_wol_callback_t must
    be provided as a parameter to this function. This function will then be
    called by this driver when the WoL even happens.

    The following functions are used as part of the frame filtering
            •   TSE_set_wol_callback()

    Jumbo frames
    The CoreTSE_AHB/CoreTSE supports Jumbo frames up to 9000 bytes long. This
    driver provides TSE_JUMBO_PACKET_SIZE constant which can be used to define
    the TX-RX buffer size where jumbo frame support is required.

*//*=========================================================================*/
#ifndef CORE_TSE_H_
#define CORE_TSE_H_

#include "coretse_types.h"
#include "coretse_user_config.h"

#ifdef __cplusplus
extern "C" {
#endif

/*******************************************************************************
 * State definitions
 */
#define TSE_DISABLE                             ( (uint8_t)0 )
#define TSE_ENABLE                              ( (uint8_t)1 )

/*******************************************************************************
 * The following definitions are used with functions TSE_send_pkt() and
 * TSE_receive_pkt() to report success or failure in assigning the packet memory
 * buffer to a transmit/receive descriptor.

    TSE_SUCCESS -   The memory buffer was successfully assigned to a
                    transmit/receive descriptor.
    TSE_FAILED  -   The memory buffer was not successfully assigned to a
                    transmit/receive descriptor.
 */
#define TSE_SUCCESS                             TSE_ENABLE
#define TSE_FAILED                              TSE_DISABLE

/*******************************************************************************
  The following definitions are used with function TSE_get_link_status() to
  report the link’s status.
    TSE_LINK_DOWN   -   Ethernet link is down.
                        There is no connection to a remote device.
    TSE_LINK_UP     -   Ethernet link is up.
                        A connection has been established with a remote device.
    TSE_HALF_DUPLEX -   Connection is half duplex.
    TSE_FULL_DUPLEX -   Connection is full duplex.
 */

#define TSE_LINK_DOWN                   0u
#define TSE_LINK_UP                     1u

#define TSE_HALF_DUPLEX                 0u
#define TSE_FULL_DUPLEX                 1u

/*******************************************************************************
 * Maximum MAC frame size (packet size)
 */
#define TSE_MAX_PACKET_SIZE                     1518u
#define TSE_JUMBO_PACKET_SIZE                   9000u

/*******************************************************************************
 * Transmit and receive packet buffer sizes
 */
#define TSE_MAX_TX_BUF_SIZE                     TSE_MAX_PACKET_SIZE
#define TSE_MAX_RX_BUF_SIZE                     TSE_MAX_PACKET_SIZE

/*******************************************************************************
 * Defines for configuration parameters
 */
/* FIFO error detection & correction enable / disable */
#define TSE_ERR_DET_CORR_ENABLE                 TSE_ENABLE
#define TSE_ERR_DET_CORR_DISABLE                TSE_DISABLE

/* Huge frame support enable / disable */
#define TSE_HUGE_FRAME_ENABLE                   TSE_ENABLE
#define TSE_HUGE_FRAME_DISABLE                  TSE_DISABLE

/* Length field checking enable / disable */
#define TSE_LENGTH_FILED_CHECK_ENABLE           TSE_ENABLE
#define TSE_LENGTH_FILED_CHECK_DISABLE          TSE_DISABLE

/* Padding and CRC enable / disable */
#define TSE_PAD_N_CRC_ENABLE                    TSE_ENABLE
#define TSE_PAD_N_CRC_DISABLE                   TSE_DISABLE

/* Append CRC enable / disable */
#define TSE_CRC_ENABLE                          TSE_ENABLE
#define TSE_CRC_DISABLE                         TSE_DISABLE

/* Fullduplex mode enable / disable */
#define TSE_FULLDUPLEX_ENABLE                   TSE_ENABLE
#define TSE_FULLDUPLEX_DISABLE                  TSE_DISABLE

/* Loopback mode enable / disable */
#define TSE_LOOPBACK_ENABLE                     TSE_ENABLE
#define TSE_LOOPBACK_DISABLE                    TSE_DISABLE

/* Receiver flow control enable / disable */
#define TSE_RX_FLOW_CTRL_ENABLE                 TSE_ENABLE
#define TSE_RX_FLOW_CTRL_DISABLE                TSE_DISABLE

/* Transmission flow control enable / disable */
#define TSE_TX_FLOW_CTRL_ENABLE                 TSE_ENABLE
#define TSE_TX_FLOW_CTRL_DISABLE                TSE_DISABLE

/* Excessive defer enable / disable */
#define TSE_EXSS_DEFER_ENABLE                   TSE_ENABLE
#define TSE_EXSS_DEFER_DISABLE                  TSE_DISABLE

/* No-backoff enable / disable */
#define TSE_NO_BACKOFF_ENABLE                   TSE_ENABLE
#define TSE_NO_BACKOFF_DISABLE                  TSE_DISABLE

/* Backpressure no-backoff enable / disable */
#define TSE_BACKPRESS_NO_BACKOFF_ENABLE         TSE_ENABLE
#define TSE_BACKPRESS_NO_BACKOFF_DISABLE        TSE_DISABLE

/* Alternative binary exponential backoff enable / disable */
#define TSE_ABEB_ENABLE                         TSE_ENABLE
#define TSE_ABEB_DISABLE                        TSE_DISABLE

/* Supress preamble enable / disable */
#define TSE_SUPPRESS_PREAMBLE_ENABLE            TSE_ENABLE
#define TSE_SUPPRESS_PREAMBLE_DISABLE           TSE_DISABLE

/* Auto-scan PHYs enable / disable */
#define TSE_PHY_AUTOSCAN_ENABLE                 TSE_ENABLE
#define TSE_PHY_AUTOSCAN_DISABLE                TSE_DISABLE

/* WoL event detect masks */
#define TSE_WOL_UNICAST_FRAME_DETECT_EN         (1u<<0)
#define TSE_WOL_MAGIC_FRAME_DETECT_EN           (1u<<1)
#define TSE_WOL_DETECT_DISABLE                  TSE_DISABLE

/* Preamble length default value and maximum value */
#define TSE_PREAMLEN_DEFVAL                     ( (uint8_t)(0x07) )
#define TSE_PREAMLEN_MAXVAL                     ( (uint8_t)(0x0F) )

/* Byte / Nibble mode  */
#define TSE_NIBBLE_MODE                         ( (uint8_t)(0x00) )
#define TSE_BYTE_MODE                           ( (uint8_t)(0x01) )

/* IPG/IFG values */
#define TSE_MINIFG_MAXVAL                       ( (uint8_t)(0xFF) )
#define TSE_MINIFG_DEFVAL                       ( (uint8_t)(0x50) )
#define TSE_BTBIFG_MAXVAL                       ( (uint8_t)(0x7F) )
#define TSE_BTBIFG_DEFVAL                       ( (uint8_t)(0x60) )
#define TSE_NONBTBIFG_DEFVAL                    ( (uint16_t)((0x4000) | 0x0060) )
#define TSE_NONBTBIFG_MAXVAL                    ( (uint16_t)(0x3FFF) )

/* Number of maximum retransmission tries */
#define TSE_MAXRETX_MAXVAL                      ( (uint8_t)(0x1F) )
#define TSE_MAXRETX_DEFVAL                      ( (uint8_t)(0x0F) )
#define TSE_ABEBTRUNC_MAXVAL                    ( (uint8_t)(0x0F) )
#define TSE_ABEBTRUNC_DEFVAL                    ( (uint8_t)(0x0A) )

/* PHY clock divider values */
#define TSE_DEF_PHY_CLK                         ( (uint8_t)(0x07) )
#define TSE_BY4_PHY_CLK                         ( (uint8_t)(0x01) )
#define TSE_BY6_PHY_CLK                         ( (uint8_t)(0x02) )
#define TSE_BY8_PHY_CLK                         ( (uint8_t)(0x03) )
#define TSE_BY10_PHY_CLK                        ( (uint8_t)(0x04) )
#define TSE_BY14_PHY_CLK                        ( (uint8_t)(0x05) )
#define TSE_BY20_PHY_CLK                        ( (uint8_t)(0x06) )
#define TSE_BY28_PHY_CLK                        ( (uint8_t)(0x07) )

/* Default & Maximum PHY addresses */
#define TSE_DEFAULT_PHY                         ( DP83848 )
#define TSE_PHYADDR_MAXVAL                      ( (uint8_t)(0x1F) )
#define TSE_PHYREGADDR_MAXVAL                   ( (uint8_t)(0x1F) )
#define TSE_PHY_ADDR_DEFVAL                     ( (uint8_t)(0x00) )
#define TSE_PHYREGADDR_DEFVAL                   ( (uint8_t)(0x00) )

/* Maximum frame length default & maximum values */
#define TSE_MAXFRAMELEN_DEFVAL                  ( (uint16_t)(0x0600) )
#define TSE_MAXFRAMELEN_MAXVAL                  ( (uint16_t)(0x0600) )

/* Slottime (Collision window) default & maximum values */
#define TSE_SLOTTIME_DEFVAL                     ( (uint16_t)(0x0037) )
#define TSE_SLOTTIME_MAXVAL                     ( (uint16_t)(0x03FF) )

/* Options for ANEG Enable/Disable.*/
#define TSE_ANEG_ENABLE                         TSE_ENABLE
#define TSE_ANEG_DISABLE                        TSE_DISABLE


/* Options for speed configuration.*/
#define TSE_ANEG_10M_FD                         0x00000001u
#define TSE_ANEG_10M_HD                         0x00000002u
#define TSE_ANEG_100M_FD                        0x00000004u
#define TSE_ANEG_100M_HD                        0x00000008u
#define TSE_ANEG_1000M_FD                       0x00000010u
#define TSE_ANEG_1000M_HD                       0x00000020u
#define TSE_ANEG_ALL_SPEEDS                     (TSE_ANEG_10M_FD |\
                                                 TSE_ANEG_10M_HD |\
                                                 TSE_ANEG_100M_FD |\
                                                 TSE_ANEG_100M_HD |\
                                                 TSE_ANEG_1000M_FD |\
                                                 TSE_ANEG_1000M_HD)

/* Options for Frame Filter configuration.*/
#define TSE_FC_PASS_BROADCAST_MASK              (1u<<0)
#define TSE_FC_PASS_MULTICAST_MASK              (1u<<1)
#define TSE_FC_PASS_UNICAST_MASK                (1u<<2)
#define TSE_FC_PROMISCOUS_MODE_MASK             (1u<<3)
#define TSE_FC_PASS_UNICAST_HASHT_MASK          (1u<<4)
#define TSE_FC_PASS_MULTICAST_HASHT_MASK        (1u<<5)
#define TSE_FC_DEFAULT_MASK                     (TSE_FC_PASS_BROADCAST_MASK | \
                                                 TSE_FC_PASS_UNICAST_MASK)

/*Default framedrop mask: Generic default value applicable to most applications*/
#define TSE_DEFVAL_FRAMEDROP_MASK   (TSE_CRC_ERR_FRAMEDROP_MASK | \
                                     TSE_CODE_ERR_FRAMEDROP_MASK | \
                                     TSE_UNSUPPORTED_OPCODE_FRAMEDROP_MASK)

/*Drop the packet if, IFG is small*/
#define TSE_SMALL_AFG_FRAMEDROP_MASK                   (1u<<0)

/*Drop the packet if, Received short RXDV Event:
Short RXDV event: Indicates that the last receive event seen was not long enough
to be a valid packet.*/
#define TSE_EXDV_EVENT_FRAMEDROP_MASK                  (1u<<1)

/* Drop the packet if, Received False Carrier.
Receive False Carrier: Indicates that at some time since the last receive
statistics vector, a false carrier was detected, noted, and reported with the
next receive statistics. The false carrier is not associated with this packet.
False carrier is an activity on the receive channel that does not result in a
packet receive attempt being made.
Defined to be RXER = 1, RXDV = 0, RXD[3:0] = 0xE (RXD[7:0] = 0x0E)*/
#define TSE_FALSE_CARRIER_FRAMEDROP_MASK               (1u<<2)

/* Drop the packet if Code error is Received.
Code Error: One or more nibbles were signalled as errors during the reception
of the packet.*/
#define TSE_CODE_ERR_FRAMEDROP_MASK                    (1u<<3)

/* Drop the packet if CRC Error is Received.
CRC Error: Packet’s CRC did not match the internally generated CRC.*/
#define TSE_CRC_ERR_FRAMEDROP_MASK                     (1u<<4)

/*Drop the frame if Length check error is Received.
Length Check Error: Indicates that frame length field value in the packet does
not match the actual data byte length and is not a type field.*/
#define TSE_LEN_CHKERR_FRAMEDROP_MASK                  (1u<<5)

/*Drop the frame if frame with Length Out of Range is Received.
Length Out of Range: Indicates that frame’s length was larger than 1,518 bytes
but smaller than the host’s maximum frame length value(type field)*/
#define TSE_OUTOFRANGE_LEN_FRAMEDROP_MASK              (1u<<6)

/*Drop the frame if, an OK frame is Received.
Receive OK: Frame contained a valid CRC and did not have a code error.*/
#define TSE_OK_FRAME_FRAMEDROP_MASK                    (1u<<7)

/*Drop the frame if Multicast frame is Received.
Receive Multicast: Packet’s destination address contained a multicast address.*/
#define TSE_MULTICAST_FRAMEDROP_MASK                   (1u<<8)

/*Drop the frame if Broadcast frame is Received.
Receive Broadcast: Packet’s destination address contained
the broadcast address.*/
#define TSE_BROADCAST_FRAMEDROP_MASK                   (1u<<9)

/*Drop the frame if Dribble Nibble is Received.
Dribble Nibble: Indicates that after the end of the packet an additional 1 to 7
bits were received. A single nibble, called the dribble nibble, is formed but
not sent to the system (10/100 Mbps only).*/
#define TSE_DRIBBLE_NIBBLE_FRAMEDROP_MASK              (1u<<10)

/*Drop the frame if Control Frame is Received.
Receive Control Frame: Current Frame was recognized as a Control frame for
having a valid Type-Length designation.*/
#define TSE_CONTROL_FRAME_FRAMEDROP_MASK               (1u<<11)

/*Drop the frame if PAUSE Control Frame is Received.
Receive PAUSE Control Frame: Current frame was recognized as a Control frame
containing a valid PAUSE Frame Op-code and a valid address.*/
#define TSE_PAUSE_FRAME_FRAMEDROP_MASK                 (1u<<12)

/*Drop the frame if Unsupported Op-code is Received.
Receive Unsupported Op-code: Current Frame was recognized as a Control frame by
the PEMCS, but it contains an unknown Op-code.*/
#define TSE_UNSUPPORTED_OPCODE_FRAMEDROP_MASK          (1u<<13)

/*
Drop the frame if VLAN Tag is Detected
VLAN Tag: Received Frame’s length/type field contained 0x8100 which is the VLAN
Protocol Identifier.
*/
#define TSE_VLAN_TAG_FRAMEDROP_MASK                    (1u<<14)

/*Drop the frame if a Long Event is Received. */
#define TSE_LONG_EVENT_FRAMEDROP_MASK                  (1u<<15)

/*Drop the frame if a Truncated frame is Received.*/
#define TSE_TRUNCKATED_FRAME_FRAMEDROP_MASK            (1u<<16)

/*Drop the frame if Unicast frame detected but did not match configured station
address */
#define TSE_UNICAST_NO_SAMATCH_FRAMEDROP_MASK          (1u<<17)

/*Drop the frame if a short frame less than 64 bytes in length is received */
#define TSE_SHORT_FRAME_FRAMEDROP_MASK                 (1u<<18)

/***************************************************************************//**
 Application can use this constant to indicate to the driver to probe the PHY
 and auto-detect the PHY address that it is configured with. If you already
 know the PHY address configured in your hardware system, you can provide that
 address to the driver instead of this constant.That way the TSE_init() function
 would be faster because the AUTO detection process of the PHY address is now
 avoided.

 Note: To auto detect the PHY address, this drivers scans the valid MDIO
 addresses starting from ‘0’ for valid data.
 If CoreRGMII and PHY are connected to the MAC’s management interface,
 then you must make sure that the PHY device MDIO address is less than the
 CoreRGMII MDIO address.

*/
#define TSE_PHY_ADDRESS_AUTO_DETECT                 255

/*******************************************************************************
 * Per Packet Overrides masks in descriptor packet size parameters
 */
#define TSE_FIFO_TX_CTRL_FRAME                  ( (uint32_t)0x00100000 )
#define TSE_FIFO_TX_NO_CTRL_FRAME               ( ~TSE_FIFO_TX_CTRL_FRAME )
#define TSE_FIFO_TX_PERPKT_PAD_FCS              ( (uint32_t)0x00040000 )
#define TSE_FIFO_TX_PERPKT_NO_PAD_FCS           ( ~TSE_FIFO_TX_PERPKT_PAD_FCS )
#define TSE_FIFO_TX_PERPKT_FCS                  ( (uint32_t)0x00020000 )
#define TSE_FIFO_TX_PERPKT_NO_FCS               ( ~TSE_FIFO_TX_PERPKT_FCS )
#define TSE_FIFO_TX_PERPKT_ENABLE               ( (uint32_t)0x00010000 )
#define TSE_FIFO_TX_PERPKT_DISABLE              ( ~TSE_FIFO_TX_PERPKT_ENABLE )

/**************************************************************************/
/* Public Function declarations                                           */
/**************************************************************************/

/***************************************************************************//**
  @brief TSE_cfg_struct_def_init()
    The TSE_cfg_struct_def_init() function initializes a tse_cfg_t configuration
    data structure to default values. The default configuration uses the MII
    interface connected to a PHY at address 0x00 which is set to auto-negotiate
    at all available speeds up to 1000Mbps. This default configuration can then
    be used as parameter to TSE_init(). Typically the default configuration
    would be modified to suit the application before being passed to TSE_init().

  @param cfg
    The cfg parameter is a pointer to a tse_cfg_t data structure that will be
    used as parameter to function TSE_init().

  @return
  This function does not return a value.

  Example:
    The example below demonstrates the use of the TSE_cfg_struct_def_init()
    function. It retrieves the default MAC configuration and modifies it to
    connect through an MII Ethernet PHY at MII management interface address 0x01.

    This example also demonstrates how to assign the device's MAC address and
    force a 100Mbps full duplex link.

  @code
    #define TSEMAC_BASE  0x30000000
    tse_cfg_t g_tse_config;
    tse_instance_t g_tse;

    TSE_cfg_struct_def_init(&g_tse_config);

    g_tse_config.phy_addr = TSE_PHY_ADDRESS_AUTO_DETECT;
    g_tse_config.speed_duplex_select = TSE_ANEG_100M_FD;
    g_tse_config.mac_addr[0] = 0xC0;
    g_tse_config.mac_addr[1] = 0xB1;
    g_tse_config.mac_addr[2] = 0x3C;
    g_tse_config.mac_addr[3] = 0x60;
    g_tse_config.mac_addr[4] = 0x60;
    g_tse_config.mac_addr[5] = 0x60;

    TSE_init(&g_tse, TSEMAC_BASE, &g_tse_config);

  @endcode
 */

void
TSE_cfg_struct_def_init
(
    tse_cfg_t * cfg
);

/***************************************************************************//**
  @brief TSE_init()
    The TSE_init() function initializes the CoreTSE_AHB/CoreTSE hardware and
    driver internal data structures. The TSE_init() function takes a pointer to
    a configuration data structure of type tse_cfg_t as parameter. This
    configuration data structure contains all the information required to
    configure the CoreTSE_AHB/CoreTSE. The TSE_init() function initializes the
    descriptor rings and their pointers to initial values. The TSE_init()
    function enables DMA Rx packet received and Tx packet sent interrupts.

    The configuration passed to the TSE_init() function specifies the type of
    interface used to connect the CoreTSE_AHB/CoreTSE and Ethernet PHY as well
    as the PHY MII management interface address. The application may pass the
    TSE_PHY_ADDRESS_AUTO_DETECT constant as configuration parameter to indicate to
    this driver to probe for the PHY address. If you know the hardware
    configuration PHY address of the on-board PHY in your system, you may choose
    to provide that instead. When the user supplied, PHY address value is other
    than the TSE_PHY_ADDRESS_AUTO_DETECT, this driver uses that value directly,
    provided it is within the valid PHY address range (31u).

    The TSE_init() function also specifies the allowed link speed and duplex
    mode. It is at this point that the application chooses if the link speed and
    duplex mode will be auto-negotiate with the link partner or forced to a
    specific speed and duplex mode.

  @param this_tse
    The this_tse parameter is a pointer to the tse_instance_t data structure
    instance holding all data regarding the CoreTSE_AHB/CoreTSE hardware instance
    being initialized. A pointer to the same data structure must be provided in
    subsequent calls to the various CoreTSE driver functions in order to
    identify the CoreTSE_AHB/CoreTSE instance that should perform the operation
    implemented by the called driver function.

  @param base_addr
    The base_addr parameter is the base address in the processor's memory map
    for the registers of the CoreTSE_AHB/CoreTSE instance being initialized.

  @param cfg
    The cfg parameter is a pointer to a data structure of type tse_cfg_t
    containing the CoreTSE_AHB/CoreTSE’s requested configuration. You must
    initialize this data structure by first calling the TSE_cfg_struct_def_init()
    function to fill the configuration data structure with default values. You
    can then overwrite some of the default settings with the ones specific to your
    application before passing this data structure as parameter to the call to
    the TSE_init() function. You must at a minimum overwrite the mac_addr[6]
    array of the configuration data structure to contain a unique value used as
    the device’s MAC address.

  @return
    This function does not return a value.

  Example:
    This example demonstrates the use of the TSE_init() function to configure
    the CoreTSE_AHB/CoreTSE with the default configuration. Please note a unique
    MAC address must always be assigned through the configuration data passed as
    parameter to the TSE_init() function.

  @code
    #define TSEMAC_BASE  0x30000000
    tse_cfg_t g_tse_config;
    tse_instance_t g_tse;

    TSE_cfg_struct_def_init(&g_tse_config);

    g_tse_config.phy_addr = TSE_PHY_ADDRESS_AUTO_DETECT;
    g_tse_config.speed_duplex_select = TSE_ANEG_100M_FD;
    g_tse_config.mac_addr[0] = 0xC0;
    g_tse_config.mac_addr[1] = 0xB1;
    g_tse_config.mac_addr[2] = 0x3C;
    g_tse_config.mac_addr[3] = 0x60;
    g_tse_config.mac_addr[4] = 0x60;
    g_tse_config.mac_addr[5] = 0x60;

    TSE_init(&g_tse, TSEMAC_BASE, &g_tse_config);

  @endcode

 */

void
TSE_init
(
    tse_instance_t * this_tse,
    uint32_t base_addr,
    tse_cfg_t * cfg
);

/***************************************************************************//**
  @brief TSE_set_tx_callback()
    The TSE_set_tx_callback() function registers the function that will be called
    by the CoreTSE driver when a packet has been sent.

    Note: This function is applicable only for CoreTSE_AHB.

  @param this_tse
    The this_tse parameter is a pointer to the tse_instance_t structure holding
    all data regarding the CoreTSE_AHB/CoreTSE instance controlled through this
    function call.

  @param tx_complete_handler
    The tx_complete_handler parameter is a pointer to the call-back function
    that will be called when a packet is sent by the CoreTSE_AHB/CoreTSE.

  @return
    This function does not return a value.

  Example:
    This example demonstrates the use of the TSE_set_tx_callback() function.
    The application registers the tx_complete_callback() transmit completion
    callback function with the CoreTSE driver by a call to TSE_set_tx_callback().
    The application dynamically allocates memory for an application defined
    packet_t data structure, builds a packet and calls send_packet().
    The send_packet() function extracts the pointer to the buffer containing the
    data to transmit and its length from the tx_packet data structure and passes
    these to TSE_send_pkt(). It also passes the pointer to tx_packet as the
    p_user_data parameter. The CoreTSE driver call tx_complete_callback() once
    the packet is sent. The tx_complete_callback() function uses the p_user_data,
    which points to tx_packet, to release memory allocated by the application
    to stored the transmit packet.

  @code
    void tx_complete_handler(void * p_user_data);
    tse_instance_t g_tse;

    void init(void)
    {
        TSE_set_tx_callback((&g_tse, tx_complete_handler);
    }

    void tx_complete_callback (void * p_user_data)
    {
        release_packet_memory(p_user_data);
    }

    void send_packet(packet_t * tx_packet)
    {
        TSE_send_pkt(&g_tse, tx_packet->buffer, tx_packet->length, tx_packet);
    }
  @endcode
 */

void TSE_set_tx_callback
(
    tse_instance_t * this_tse,
    tse_transmit_callback_t tx_complete_handler
);

/***************************************************************************//**
  @brief TSE_set_rx_callback()
    The TSE_set_rx_callback() function registers the function that will be
    called by the CoreTSE driver when a packet is received.

    Note: This function is applicable only for CoreTSE_AHB.

  @param this_tse
    The this_tse parameter is a pointer to the tse_instance_t structure holding
    all data regarding the CoreTSE_AHB/CoreTSE instance controlled through this
    function call.

  @param rx_callback
    The rx_callback parameter is a pointer to the function that will be called
    when the packet is received by CoreTSE_AHB/CoreTSE.

  Example:
    The example below demonstrates the use of the TSE_set_rx_callback() function.
    The init() function calls the TSE_set_rx_callback() function to register
    the rx_callback() receive callback function with the CoreTSE driver. The
    TSE_receive_pkt() function is then called to assign the rx_buffer to an
    CoreTSE_AHB descriptor for packet reception. The rx_callback function will be
    called by the CoreTSE driver once a packet has been received into rx_buffer.
    The rx_callback() function calls the process_rx_packet() application
    function to process the received packet then calls TSE_receive_pkt() to
    reallocate rx_buffer to receive another packet. The rx_callback() function
    will be called again every time a packet is received to process the received
    packet and reallocate rx_buffer for packet reception.

  @code
    uint8_t rx_buffer[TSE_MAX_RX_BUF_SIZE];

    void rx_callback
    (
        uint8_t * p_rx_packet,
        uint32_t pckt_length,
        void * p_user_data
    )
    {
        process_rx_packet(p_rx_packet, pckt_length);
        TSE_receive_pkt(rx_buffer, (void *)0);
    }

    void init(void)
    {
        TSE_set_rx_callback(rx_callback);
        TSE_receive_pkt(rx_buffer, (void *)0);
    }
  @endcode
 */

void TSE_set_rx_callback
(
    tse_instance_t * this_tse,
    tse_receive_callback_t rx_callback
);

/***************************************************************************//**
  @brief TSE_set_wol_callback()
    The TSE_set_wol_callback() function registers the function that will be
    called by the CoreTSE driver when Wake on Lan (WoL) feature is enabled and
    WoL even is detected. The WoL event happens when either a Unicast match frame
    or AMD magic packet frame is detected by CoreTSE_AHB/CoreTSE. The wol_enable
    parameter in tse_cfg_t structure decides which type of packets can cause WoL
    event.

  @param this_tse
    The this_tse parameter is a pointer to the tse_instance_t structure holding
    all data regarding the CoreTSE_AHB/CoreTSE instance controlled through this
    function call.

  @param wol_callback
    The wol_callback parameter is a pointer to the function that will be called
    when Wake on Lan (WoL) feature is enabled and WoL event happens.

  @return
    This function does not return a value.

  Example
    The example below demonstrates the use of the TSE_set_wol_callback() function.
    The init() function calls the TSE_set_wol_callback() function to register the
    wol_callback() receive callback function with the CoreTSE driver. The wol_callback
    function will be called by the CoreTSE driver once a WoL event is detected.
    The wol_callback() function can implement the application specific action on
    detecting the WoL event.

  @code
    tse_instance_t g_tse;

    void wol_callback
    (
        void * p_user_data
    )
    {
        //Process WoL interrupt here.
    }
    void init(void)
    {
        TSE_set_wol_callback(&g_tse, wol_callback);
    }
 */
void TSE_set_wol_callback
(
    tse_instance_t * this_tse,
    tse_wol_callback_t wol_callback
);

/***************************************************************************//**
  @brief TSE_send_pkt()
    The TSE_send_pkt()function initiates the transmission of a packet. It places
    the buffer containing the packet to send into one of the CoreTSE_AHB’s transmit
    descriptors. This function is non-blocking. It will return immediately
    without waiting for the packet to be sent. The CoreTSE driver indicates that
    the packet is sent by calling the transmit completion handler registered by
    a call to TSE_set_tx_callback().

    Note: This function is applicable only for CoreTSE_AHB.

  @param this_tse
    The this_tse parameter is a pointer to the tse_instance_t structure holding
    all data regarding the CoreTSE_AHB instance controlled through this function
    call.

  @param tx_buffer
    The tx_buffer parameter is a pointer to the buffer containing the packet to
    send.

  @param tx_length
    The tx_length parameter specifies the length in bytes of the packet to send.

  @param p_user_data
    This parameter is a pointer to an optional application defined data
    structure. Its usage is left to the application. It is intended to help the
    application manage memory allocated to store packets. The CoreTSE driver
    does not make use of this pointer. The CoreTSE driver will pass back this
    pointer to the application as part of the call to the transmit completion
    handler registered by the application.

  @return
    This function returns 1 on successfully assigning the packet to a transmit
    descriptor. It returns 0 otherwise.

  Example:
    This example demonstrates the use of the TSE_send_pkt() function. The
    application registers the tx_complete_callback() transmit completion
    callback function with the CoreTSE driver by a call to TSE_set_tx_callback().
    The application dynamically allocates memory for an application defined
    packet_t data structure, builds a packet and calls send_packet(). The
    send_packet() function extracts the pointer to the buffer containing the
    data to transmit and its length from the tx_packet data structure and passes
    these to TSE_send_pkt(). It also passes the pointer to tx_packet as the
    p_user_data parameter. The CoreTSE driver call tx_complete_callback() once
    the packet is sent. The tx_complete_callback() function uses the p_user_data,
    which points to tx_packet, to release memory allocated by the application
    to stored the transmit packet.
  @code
    void tx_complete_handler(void * p_user_data);
    tse_instance_t g_tse;

    void init(void)
    {
        TSE_set_tx_callback((&g_tse, tx_complete_handler);
    }

    void tx_complete_callback (void * p_user_data)
    {
        release_packet_memory(p_user_data);
    }

    void send_packet(packet_t * tx_packet)
    {
        TSE_send_pkt(&g_tse, tx_packet->buffer, tx_packet->length, tx_packet);
    }
  @endcode

 */
uint8_t
TSE_send_pkt
(
    tse_instance_t * this_tse,
    uint8_t const * tx_buffer,
    uint32_t    tx_length,
    void *      p_user_data
);

/***************************************************************************//**
  @brief TSE_receive_pkt()
    The TSE_receive_pkt() function assigns a buffer to one of  the CoreTSE_AHB’s
    receive descriptors. The receive buffer specified as parameter will be used
    to receive one single packet. The receive buffer will be handed back to the
    application via a call to the receive callback function assigned through a
    call to TSE_set_rx_callback(). The TSE_receive_pkt() function will need to
    be called again pointing to the same buffer if more packets are to be
    received into this same buffer after the packet has been processed by the
    application.

    The TSE_receive_pkt() function is non-blocking. It will return immediately
    and does not wait for a packet to be received. The application needs to
    implement a receive callback function to be notified that a packet has been
    received.

    The p_user_data parameter can be optionally used to point to a memory
    management data structure managed by the application.

    Note: This function is applicable only for CoreTSE_AHB.

  @param this_tse
    The this_tse parameter is a pointer to the tse_instance_t structure holding
    all data regarding the CoreTSE_AHB instance controlled through this function
    call.

  @param rx_pkt_buffer
    The rx_pkt_buffer parameter is a pointer to a memory buffer. It points to
    the memory that will be assigned to one of the CoreTSE_AHB’s receive
    descriptors. It must point to a buffer large enough to contain the largest
    possible packet.

  @param p_user_data
    The p_user_data parameter is intended to help the application manage memory.
    Its usage is left to the application. The CoreTSE driver does not make use
    of this pointer. The CoreTSE driver will pass this pointer back to the
    application as part of the call to the application’s receive callback
    function to help the application associate the received packet with the
    memory it allocated prior to the call to TSE_receive_pkt().

  @return
    This function returns 1 on successfully assigning the buffer to a receive
    descriptor. It returns 0 otherwise.

  Example:
    The example below demonstrates the use of the TSE_receive_pkt() function to
    handle packet reception using two receive buffers. The init() function calls
    the TSE_set_rx_callback() function to register the rx_callback() receive
    callback function with the CoreTSE driver. The TSE_receive_pkt() function
    is then called twice to assign rx_buffer_1 and rx_buffer_2 to CoreTSE
    descriptors for packet reception. The rx_callback function will be called
    by the CoreTSE driver once a packet has been received into one of the
    receive buffers. The rx_callback() function calls the process_rx_packet()
    application function to process the received packet then calls
    TSE_receive_pkt() to reallocate the receive buffer to receive another packet.
    The rx_callback() function will be called again every time a packet is
    received to process the received packet and reallocate rx_buffer for packet
    reception.

    Please note the use of the p_user_data parameter to handle the buffer
    reassignment to the CoreTSE_AHB as part of the rx_callback() function. This
    is a simplistic use of p_user_data. It is more likely that p_user_data would
    be useful to keep track of a pointer to a TCP/IP stack packet container data
    structure dynamically allocated. In this more complex use case, the first
    parameter of TSE_receive_pkt() would point to the actual receive buffer and
    the second parameter would point to a data structure used to free the
    receive buffer memory once the packet has been consumed by the TCP/IP stack.

  @code
    uint8_t rx_buffer_1[TSE_MAX_RX_BUF_SIZE];
    uint8_t rx_buffer_2[TSE_MAX_RX_BUF_SIZE];
    tse_instance_t g_tse;

    void rx_callback
    (
        uint8_t * p_rx_packet,
        uint32_t pckt_length,
        void * p_user_data
    )
    {
        process_rx_packet(p_rx_packet, pckt_length);
        TSE_receive_pkt((&g_tse, (uint8_t *)p_user_data, p_user_data);
    }

    void init(void)
    {
        TSE_set_rx_callback((&g_tse, rx_callback);
        TSE_receive_pkt(rx_buffer_1, (void *)rx_buffer_1);
        TSE_receive_pkt(rx_buffer_2, (void *)rx_buffer_2);
    }
  @endcode

 */
uint8_t
TSE_receive_pkt
(
    tse_instance_t * this_tse,
    uint8_t * rx_pkt_buffer,
    void * p_user_data
);

/***************************************************************************//**
  @brief TSE_get_link_status()
    The TSE_get_link_status () function retrieves the status of the link from
    the Ethernet PHY. It returns the current state of the Ethernet link. The
    speed and duplex mode of the link is also returned via the two pointers
    passed as parameter if the link is up.

    This function also adjusts the CoreTSE_AHB/CoreTSE’s internal configuration
    if some of the link characteristics have changed since the previous call to
    this function.

  @param this_tse
    The this_tse parameter is a pointer to the tse_instance_t structure holding
    all data regarding the CoreTSE_AHB/CoreTSE instance controlled through this
    function call.

  @param speed
    The speed parameter is a pointer to variable of type tse_speed_t where the
    current link speed will be stored if the link is up. This variable is not
    updated if the link is down. This parameter can be set to zero if the caller
    does not need to find out the link speed.

  @param fullduplex
    The fullduplex parameter is a pointer to an unsigned character where the
    current link duplex mode will be stored if the link is up. This variable is
    not updated if the link is down.

  @return
    This function returns 1 if the link is up. It returns 0 if the link is down.

  Example:

  @code
    uint8_t link_up;
    tse_speed_t speed;
    uint8_t full_duplex
    tse_instance_t g_tse;

    link_up = TSE_get_link_status(&g_tse, &speed, &full_duplex);
  @endcode

 */
uint8_t TSE_get_link_status
(
    tse_instance_t * this_tse,
    tse_speed_t * speed,
    uint8_t *     fullduplex
);

/***************************************************************************//**
  @brief TSE_read_stat()
    The TSE_read_stat()  function reads the transmit and receive statistics of
    the CoreTSE_AHB/CoreTSE. This function can be used to read one of 17 receiver
    statistics, 20 transmitter statistics and 7 frame type statistics as defined
    in the tse_stat_t enumeration.

  @param this_tse
    The this_tse parameter is a pointer to the tse_instance_t structure holding
    all data regarding the CoreTSE_AHB/CoreTSE instance controlled through this
    function call.

  @param stat
    This parameter of type tse_stat_t identifies the statistic that will be read.

  @return
    This function returns the value of the requested statistic.

  Example:
  @code
    uint32_t tx_pkts_cnt = 0;
    tse_instance_t g_tse;

    tx_pkts_cnt = TSE_read_stat(&g_tse, TSE_TX_PKT_CNT);

  @endcode
 */
uint32_t
TSE_read_stat
(
    tse_instance_t * this_tse,
    tse_stat_t stat
);

/***************************************************************************//**
  @brief TSE_clear_statistics()
    The TSE_clear_statistics() function clears all the 44 statistics counter
    registers.

  @param this_tse
    The this_tse parameter is a pointer to the tse_instance_t structure holding
    all data regarding the CoreTSE_AHB/CoreTSE instance controlled through this
    function call.

  @return
    This function does not return a value.

  Example:
  @code
    uint32_t tx_pkts_cnt = 0;

    tx_pkts_cnt = TSE_clear_statistics(&g_tse);

  @endcode
 */
void TSE_clear_statistics
(
    tse_instance_t * instance
);

/***************************************************************************//**
  @brief TSE_read_phy_reg()
    The TSE_read_phy_reg() function reads the Ethernet PHY register specified as
    parameter. It uses the MII management interface to communicate with the
    Ethernet PHY. This function is used as part of the Ethernet PHY drivers
    provided alongside the CoreTSE driver. You only need to use this function
    if writing your own Ethernet PHY driver.

  @param this_tse
    The this_tse parameter is a pointer to the tse_instance_t structure holding
    all data regarding the CoreTSE_AHB/CoreTSE instance controlled through this
    function call.

  @param phyaddr
    The phyaddr parameter is the 5-bit address of the Ethernet PHY on the MII
    management interface. This address is typically defined through Ethernet PHY
    hardware configuration signals. Please refer to the Ethernet PHY’s datasheet
    for details of how this address is assigned.

  @param regaddr
    The regaddr parameter is the address of the Ethernet register that will be
    read. This address is the offset of the register within the Ethernet PHY’s
    register map.

  @return
    This function returns the 16-bit value of the requested register.

  Example:
  @code
    #include “phy.h”
    tse_instance_t g_tse;

    uint16_t read_phy_status(uint8_t phy_addr)
    {
        uint16_t phy_status = TSE_read_phy_reg(&g_tse, phy_addr , MII_BMSR);
        return phy_status;
    }
  @endcode

 */
uint16_t
TSE_read_phy_reg
(
    tse_instance_t * this_tse,
    uint8_t phyaddr,
    uint8_t regaddr
);

/***************************************************************************//**
  @brief TSE_write_phy_reg()
    The TSE_write_phy_reg() function writes a 16-bit value to the specified
    Ethernet PHY register. . It uses the MII management interface to communicate
    with the Ethernet PHY. This function is used as part of the Ethernet PHY
    drivers provided alongside the CoreTSE driver. You only need to use this
    function if writing your own Ethernet PHY driver.

  @param this_tse
    The this_tse parameter is a pointer to the tse_instance_t structure holding
    all data regarding the CoreTSE_AHB/CoreTSE instance controlled through this
    function call.

  @param phyaddr
    The phyaddr parameter is the 5-bit address of the Ethernet PHY on the MII
    management interface. This address is typically defined through Ethernet PHY
    hardware configuration signals. Please refer to the Ethernet PHY’s datasheet
    for details of how this address is assigned.

  @param regaddr
    The regaddr parameter is the address of the Ethernet register that will be
    written. This address is the offset of the register within the Ethernet
    PHY’s register map.

  @param regval
    The regval parameter is the 16-bit value that will be written into the
    specified PHY register.

  @return
    This function does not return a value.

  Example:
  @code
    #include "phy.h"
    tse_instance_t g_tse;

    void rest_sgmii_phy(void)
    {
        TSE_write_phy_reg(&g_tse, SGMII_PHY_ADDR, MII_BMCR, 0x8000);
    }
  @endcode

 */
void
TSE_write_phy_reg
(
    tse_instance_t * this_tse,
    uint8_t phyaddr,
    uint8_t regaddr,
    uint16_t regval
);

/***************************************************************************//**
  @brief TSE_isr()
    The TSE_isr() function is the top level interrupt handler function for the
    CoreTSE driver. You must call TSE_isr() from the system level
    (CoreInterrupt and NVIC level) interrupt handler assigned to the interrupt
    triggered by the CoreTSE_AHB/CoreTSE INTR signal. Your system level interrupt
    handler must also clear the system level interrupt triggered by the
    CoreTSE_AHB/CoreTSE INTR signal before returning, to prevent a re-assertion
    of the same interrupt.

  @param this_tse
    The this_tse parameter is a pointer to the tse_instance_t structure holding
    all data regarding the CoreTSE_AHB/CoreTSE instance controlled through this
    function call.

  @return
  This function does not return a value.

  Example:
  @code

    tse_instance_t g_tse;

    void FabricIrq0_IRQHandler
    (
        void
    )
    {
        TSE_isr(&g_tse);
    }


  @endcode
 */
void
TSE_isr
(
    tse_instance_t * this_tse
);

/***************************************************************************//**
  @brief TSE_set_address_filter()
    The TSE_set_address_filter() function implements the frame filtering
    functionality of the driver. This function is used to specify the list of
    destination MAC addresses of received frames that will be passed to the MAC
    This function takes an array of MAC addresses as parameter and generates the
    correct hash table for that list of addresses. It also
    manages the setting of the Broadcast-DA, Multicast-DA/Unicast-DA hardware IP
    configuration bits based on the value of the MAC addresses passed as
    parameter. i.e. if the list contains one or more unicast address then
    unicast hash match filtering is enabled. Likewise, multicast hash match
    filtering is enabled if the list contains one or more multicast address.
    It enables broadcast filtering if the broadcast address is included in the
    allowed MAC addresses list passed as parameter. It also enables passing
    frames addressed to the local MAC address (perfect unicast match) if the
    local MAC address is included in the allowed MAC addresses list.

    Note:     The address filtering choice can also be selected using
    TSE_cfg_struct_def_init() function. The configuration value returned by this
    function can be modified and then passed on to the TSE_init() function. If
    The TSE_set_address_filter() function is used, the original filter setting
    chosen at the initialization time gets overwritten.

  @param this_tse
    The this_tse parameter is a pointer to the tse_instance_t structure holding
    all data regarding the CoreTSE_AHB/CoreTSE instance controlled through this
    function call.

  @param  mac_addresses
    The mac_addresses parameter is a pointer to the buffer containing the MAC
    addresses that are used to generate the MAC address hash table.

  @param nb_addresses
    The nb_addresses parameter specifies the number of mac addresses being
    passed in the buffer pointed by the mac_addresses buffer pointer. Note that
    each MAC address consists of 6 octets. Each MAC address must be placed in
    the buffer starting with the first octet of the MAC address.

    Note: Each MAC address consists of 6 octets and must be placed in the
    buffer starting with the first (most significant) octet of the MAC address.

  @return
  This function does not return a value.

  Example:
  This example demonstrates the use of the TSE_set_address_filter() function to
  handle frame filtering. The list of MAC addresses passed to
  TSE_set_address_filter() function includes unicast, multicast, local base
  station and broadcast MAC addresses. The TSE_set_address_filter() function
  sets up the hash-unicast, hash-multicast, broadcast and perfect unicast match
  (local base station address) filtering to pass frames with these destination
  addressed to the MAC.

  @code
    #define TSEMAC_BASE  0x30000000
    tse_instance_t g_tse;
    tse_cfg_t g_tse_config;

    uint8_t mac_data[4][6] = {{0x10, 0x10, 0x10, 0x10, 0x10, 0x10},
                            {0x43, 0x40, 0x40, 0x40, 0x40, 0x43},
                            {0xC0, 0xB1, 0x3C, 0x60, 0x60, 0x60},
                            {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};

    g_tse_config.phy_addr = TSE_PHY_ADDRESS_AUTO_DETECT;
    g_tse_config.speed_duplex_select = TSE_ANEG_100M_FD;
    g_tse_config.mac_addr[0] = 0xC0;
    g_tse_config.mac_addr[1] = 0xB1;
    g_tse_config.mac_addr[2] = 0x3C;
    g_tse_config.mac_addr[3] = 0x60;
    g_tse_config.mac_addr[4] = 0x60;
    g_tse_config.mac_addr[5] = 0x60;

    TSE_init(&g_tse, TSEMAC_BASE, &g_tse_config);

    TSE_set_address_filter(&g_tse, mac_data[0], 4);
  @endcode
 */
void
TSE_set_address_filter
(
    tse_instance_t * this_tse,
    const uint8_t * mac_addresses,
    uint32_t nb_addresses
);

#ifdef __cplusplus
}
#endif

#endif /* CORE_TSE_H_ */
