/* ======================================================================
 *   Copyright (C) 2022 Texas Instruments Incorporated
 *
 *   All rights reserved. Property of Texas Instruments Incorporated.
 *   Restricted rights to use, duplicate or disclose this code are
 *   granted through contract.
 *
 *   The program may not be used without the written permission
 *   of Texas Instruments Incorporated or against the terms and conditions
 *   stipulated in the agreement under which this program has been
 *   supplied.
 * ==================================================================== */

/**
 *  \file       cpsw_ale.h
 *
 *  \brief      This file contains the function prototypes for the device
 *              contains some abstraction layer for ALE module of CPSW
 *              subsystem.
 */

#ifndef CPSW_ALE_H_
#define CPSW_ALE_H_

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

#ifdef __cplusplus
extern "C" {
#endif
/* ========================================================================== */
/*                                 Macros                                     */
/* ========================================================================== */

/** \brief ALE entry length in words. */
#define CPSW_ALE_ENTRY_MAX                                 (512U)

/** \brief ALE entry length in words. */
#define CPSW_ALE_ENTRY_NUM_WORDS                           (3U)

/** \brief Broadcast MAC address byte mask. */
#define CPSW_ALE_BROADCAST_MAC_ADDR_MASK                   (0xFFU)

/** \brief Multicast MAC address upper byte mask. */
#define CPSW_ALE_MULTICAST_MAC_ADDR_MASK                   (0x01U)

/** \brief Enumerates types of Unicast ALE table entry. */
/**< Unicast address that is not ageable. */
#define  CPSW_ALE_TBL_UNICAST_TYPE_NOT_AGEABLE             (0x0U)

/**< Ageable unicast address that has not been touched. */
#define CPSW_ALE_TBL_UNICAST_TYPE_AGEABLE_UNTOUCH          (0x1U)

/**< Non ageable OUI address. */
#define CPSW_ALE_TBL_UNICAST_TYPE_OUI                      (0x2U)

/**< Ageable unicast address that has been touched. */
#define CPSW_ALE_TBL_UNICAST_TYPE_AGEABLE_TOUCH                (0x3U)

/* ========================================================================== */
/*                         Structures and Enums                               */
/* ========================================================================== */

/** \brief Enumerates types of ALE table entry. */
typedef enum cpswAleTblEntryType
{
    CPSW_ALE_TBL_ENTRY_TYPE_FREE = 0x0U,
    /**< Free entry. */
    CPSW_ALE_TBL_ENTRY_TYPE_ADDR = 0x1U,
    /**< Address type ALE entry. */
    CPSW_ALE_TBL_ENTRY_TYPE_VLAN = 0x2U,
    /**< VLAN type ALE entry. */
    CPSW_ALE_TBL_ENTRY_TYPE_VLAN_ADDR = 0x3U,
    /**< VLAN Address type ALE entry. */
}cpswAleTblEntryType_t;

/** \brief Enumerates port state configuration values in address lookup engine.
**/
typedef enum cpswAlePortState
{
    CPSW_ALE_PORT_STATE_DISABLED = 0x00U,
    /**< Port is disabled in address lookup engine. */
    CPSW_ALE_PORT_STATE_BLOCKED = 0x01U,
    /**< Port is blocked in address lookup engine. */
    CPSW_ALE_PORT_STATE_LEARN = 0x02U,
    /**< Port is configured for learning in address lookup engine. */
    CPSW_ALE_PORT_STATE_FWD = 0x03U
                              /**< Port is configured to forward in address
                               *lookup engine. */
}cpswAlePortState_t;

/** \brief Structure holding the I2C register context .*/
typedef struct cpswAleTblEntry
{
    uint32 word0;
    /**< Pre-scalar register value.*/
    uint32 word1;
    /**< SCL low time register value.*/
    uint32 word2;
    /**< SCL high time register value.*/
}cpswAleTblEntry_t;

/** \brief Structure holding the I2C register context .*/
typedef struct cpswAleVlanConfigParams
{
    uint32 enableUnregMcastFlood;
    /**< Mask used for multicast when the multicast address is not found.*/
    uint32 enableRegMcastFlood;
    /**< Mask used for multicast when the multicast address is found.*/
    uint32 enableForceUntaggedEgress;
    /**< This field causes the packet VLAN tag to be removed on egress (except
     *on port 0).*/
}cpswAleVlanConfigParams_t;

/** \brief Structure holding the I2C register context .*/
typedef struct cpswAleMcastConfigParams
{
    uint32 fwdState;
    /**<
     *  Indicates the port state(s) required for the received port on a
     *  destination address lookup in order for the multicast packet to be
     *  forwarded to the transmit port(s). A transmit port must be in the
     *  Forwarding state in order to forward the packet. If the transmit
     *  port_mask has multiple set bits then each forward decision is
     *  independent of the other transmit port(s) forward decision.
     */
    uint32 enableSuper;
    /**<
     *  This field indicates that the packet with a matching multicast
     *  destination address is a supervisory packet.
     */
}cpswAleMcastConfigParams_t;

/** \brief Structure holding the I2C register context .*/
typedef struct cpswAleUcastConfigParams
{
    uint32 unicastType;
    /**< This field indicates the type of unicast address the table entry
     *contains. */
    uint32 enableSecure;
    /**<
     *  This bit indicates that a packet with a matching source address should
     *  be dropped if the received port number is not equal to the table entry
     *  port_number.
     */
    uint32 enableBlock;
    /**<
     *  The block bit indicates that a packet with a matching source or
     *  destination address should be dropped (block the address).
     */
    uint32 enableDlr;
    /**<
     *  This indicates that the address is a Device Level Ring (DLR) unicast
     *  address. Received packets with a matching destination address will be
     *  flooded to the vlan_member_list (minus the receive port and the host
     *  port).
     */
}cpswAleUcastConfigParams_t;

/* ========================================================================== */
/*                         Global Variables Declarations                      */
/* ========================================================================== */

/* ========================================================================== */
/*                          Function Declarations                             */
/* ========================================================================== */

/**
 * \brief   This API initializes ALE. It clears the ALE table and enables packet
 *          processing by ALE.
 *
 * \param   baseAddr    Base address of the CPSW.
 */
void CPSWAleInit(uint32 baseAddr);

/**
 * \brief   This API checks the MAC address is of the specified type.
 *
 * \param   macAddr   Ethernet MAC address.
 * \param   addrType   Type of address takes values cpswPktType_t.
 *
 * \retval  TRUE       Ethernet MAC address is of the specified type.
 * \retval  FALSE      Ethernet MAC address is not of the specified type.
 */
uint32 CPSWAleValidateMacAddr(const uint8 macAddr[ETH_MAC_ADDR_LEN],
                                     uint32      addrType);
/**
 * \brief   This API removes any ageable ALE table entries that does not have a
 *          touch bit set.
 *
 * \param   baseAddr    Base address of the CPSW.
 */
void CPSWAleAgeOut(uint32 baseAddr);

/**
 * \brief   This API sets the packet rate Limit for given packet type in ALE.
 *
 * \param   baseAddr      Base Address of the ALE module
 * \param   portNum       Port number.
 * \param   pktType       Type of packet takes following values
 *                        -# #ETH_MACADDR_TYPE_MULTICAST
 *                        -# #ETH_MACADDR_TYPE_BROADCAST
 * \param   pktRateLimit  Packet rate limit.
 *
 * \note    Rate limiting is enabled by a non-zero value.
 */
void CPSWAleSetRateLimit(uint32 baseAddr,
                         uint32 portNum,
                         uint32 pktType,
                         uint32 pktRateLimit);
/**
 * \brief   This API enables/disables dropping of packets in ALE module for
 *          given port with unknown (default) or no VLAN ID in ALE module.
 *
 * \param   baseAddr           Base Address of the CPSW.
 * \param   portNum            Port number.
 * \param   enableIngressCheck Configure VLAN ingress check
 *                             -# TRUE  - Enable VLAN ingress check.
 *                             -# FALSE - Disable VLAN ingress check.
 */
void CPSWAleVlanIdIngressCheckEnable(uint32 baseAddr,
                                     uint32 portNum,
                                     uint32 enableIngressCheck);

/**
 * \brief   This API configures the port state for a given port in the ALE.
 *
 * \param   baseAddr    Base address of the CPSW.
 * \param   portNum     The port number
 * \param   portState   The port state takes values #cpswAlePortState_t.
 */
void CPSWAleSetPortState(uint32 baseAddr,
                         uint32 portNum,
                         uint32 portState);

/**
 * \brief   This API configures VLAN Aware in ALE module to determine what
 *          to be done if VLAN is not found.
 *
 * \param   baseAddr        Base Address of the CPSW.
 * \param   enableVlanAware ALE VLAN Aware configuration for packet.
 *                          -# TRUE  - Drop packet if VLAN not found
 *                          -# FALSE - Flood if VLAN not found
 */
void CPSWAleVlanAwareEnable(uint32 baseAddr, uint32 enableVlanAware);

/*!
 * \brief   Sets the Unknown VLAN Force Untagged Egress
 *
 * \param   baseAddr      Base Address of the ALE module
 * \param   ueVal         The Unknown VLAN Fornce Untagged Egress value
 *
 * \return  None
 *
 **/
void CPSWAleUnknownUntaggedEgressSet(uint32 baseAddr, uint32 ueVal);

/*!
 * \brief   Sets the Unknown VLAN Registered Multicast Flood Mask
 *
 * \param   baseAddr      Base Address of the ALE module
 * \param   rfmVal        Unknown VLAN Registered Multicast Flood Mask Value
 *
 * \return  None
 *
 **/
void CPSWAleUnknownRegFloodMaskSet(uint32 baseAddr, uint32 rfmVal);

/*!
 * \brief   Sets the Unknown VLAN UnRegistered Multicast Flood Mask
 *
 * \param   baseAddr      Base Address of the ALE module
 * \param   ufmVal        Unknown VLAN UnRegistered Multicast Flood Mask Value
 *
 * \return  None
 *
 **/
void CPSWAleUnknownUnRegFloodMaskSet(uint32 baseAddr, uint32 ufmVal);

/*!
 * \brief   Sets the Unknown VLAN Member List
 *
 * \param   baseAddr      Base Address of the ALE module
 * \param   mlVal        Unknown VLAN UnRegistered Multicast Flood Mask Value
 *
 * \return  None
 *
 **/
void CPSWAleUnknownMemberListSet(uint32 baseAddr, uint32 mlVal);


/**
 * \brief   This enables broadcast/multicast rate Limit for given transfer mode
 *          in ALE module.
 *
 * \param   baseAddr    Base address of the CPSW.
 * \param   xferMode    Transfer mode to be configured for rate limit and it
 *                      takes values #ethernetXferMode_t.
 */
void CPSWAleRateLimitEnable(uint32 baseAddr, uint32 xferMode);

/**
 * \brief   This disables broadcast/multicast rate Limit in ALE module.
 *
 * \param   baseAddr    Base address of the CPSW.
 */
void CPSWAleRateLimitDisable(uint32 baseAddr);

/**
 * \brief   This enables/disables MAC Authorization Mode of ALE.
 *
 * \details Mac authorization mode requires that all table entries be made by
 *          the host software. There are no learned address in authorization
 *          mode and the packet will be dropped if the source address is not
 *          found (and the destination address is not a multicast address with
 *          the super table entry bit set).
 *
 * \param   baseAddr      Base address of the CPSW.
 * \param   enableMacAuth MAC AUTH configuration takes values
 *                        -# TRUE  - Enable MAC AUTH mode
 *                        -# FALSE - Disable MAC AUTH mode
 */
void CPSWAleAuthModeEnable(uint32 baseAddr, uint32 enableMacAuth);
/**
 * \brief   This API enables/disables the bypassing of the ALE logic for all
 *          packets received on slave ports to the host port.
 *
 * \param   baseAddr     Base Address of the CPSW.
 * \param   enableBypass Bypass ALE logic configuration takes values
 *                       -# TRUE  - Enable bypass mode
 *                       -# FALSE - Disable bypass mode
 */
void CPSWAleBypassEnable(uint32 baseAddr, uint32 enableBypass);
/**
 * \brief   This API reads the prescale value for ALE.
 *
 * \details The input clock is divided by this value to use in the broadcast/
 *          multicast rate limiters. The minimum operating value is 0x10. The
 *          prescaler is off when the value is zero.
 *
 * \param   baseAddr      Base Address of the CPSW.
 */
uint32 CPSWGetAleRateLimitPrescale(uint32 baseAddr);

/**
 * \brief   This API sets the prescale value for ALE.
 *
 * \details The input clock is divided by this value to use in the broadcast/
 *          multicast rate limiters. The minimum operating value is 0x10. The
 *          prescaler is off when the value is zero.
 *
 * \param   baseAddr     Base Address of the CPSW
 * \param   preScalarVal The prescale value.
 */
void CPSWAleSetRateLimitPrescale(uint32 baseAddr, uint32 preScalarVal);

/**
 * \brief Adds an unicast entry in the ALE table.
 *
 * \param baseAddr      Base address of the CPSW.
 * \param pMacAddr      Ethernet address
 * \param vlanId        VLAN ID
 * \param portNum       The port number
 * \param unicastParams VLAN config parameters #cpswAleUcastConfigParams_t
 *
 * \retval index of the ALE entry added
 * \retval CPSW_ALE_ENTRY_MAX if table entry is not free
 */
uint32 CPSWAleUnicastEntryAdd(
    uint32                            baseAddr,
    const uint8                       macAddr[],
    uint32                            vlanId,
    uint32                            portNum,
    const cpswAleUcastConfigParams_t *unicastParams);


/**
 * \brief Deletes an unicast entry in the ALE table.
 *
 * \param baseAddr   Base address of the CPSW.
 * \param pMacAddr   Ethernet address
 * \param vlanId     VLAN ID
 * \param portNum    The port number
 *
 * \retval index of the ALE entry deleted
 * \retval CPSW_ALE_ENTRY_MAX if table entry is not present
 */
uint32 CPSWAleUnicastEntryDel(uint32      baseAddr,
                              const uint8 macAddr[],
                              uint32      vlanId,
                              uint32      portNum);

/**
 * \brief Adds a multicast entry in the ALE table
 *
 * \param baseAddr        Base address of the CPSW.
 * \param pMacAddr        Ethernet Address
 * \param vlanId          VLAN ID
 * \param portNum         The port number
 * \param multicastParams VLAN config parameters #cpswAleVlanConfigParams_t
 *
 * \retval index of the ALE entry added
 * \retval CPSW_ALE_ENTRY_MAX if table entry is not free
 */
uint32 CPSWAleMulticastEntryAdd(
    uint32                            baseAddr,
    const uint8                       macAddr[],
    uint32                            vlanId,
    uint32                            portMask,
    const cpswAleMcastConfigParams_t *multicastParams);

/**
 * \brief Deletes a multicast entry in the ALE table
 *
 * \param baseAddr   Base address of the CPSW.
 * \param pMacAddr   Ethernet Address
 * \param vlanId     VLAN ID
 * \param portNum    The port number
 *
 * \retval index of the ALE entry deleted
 * \retval CPSW_ALE_ENTRY_MAX if table entry is not present
 */
uint32 CPSWAleMulticastEntryPortDel(uint32      baseAddr,
                                    const uint8 macAddr[],
                                    uint32      vlanId,
                                    uint8      portNum);

/**
 * \brief Adds the VLAN entry in ALE table
 *
 * \param baseAddr    Base address of the CPSW.
 * \param vlanId      VLAN ID
 * \param portNum    The port number
 * \param vlanParams  VLAN configuration parameters #cpswAleVlanConfigParams_t
 *
 * \retval index of the ALE entry added
 * \retval CPSW_ALE_ENTRY_MAX if table entry is not free
 */
uint32 CPSWAleVlanEntryPortAdd(uint32                    baseAddr,
                               uint32                    vlanId,
                               uint32                    portNum,
                               cpswAleVlanConfigParams_t vlanParams);

/**
 * \brief Dlelete the VLAN entry in ALE table
 *
 * \param baseAddr   Base address of the CPSW.
 * \param vlanId     VLAN ID
 * \param portNum    The slave port number
 *
 * \retval index of the ALE entry deleted
 * \retval CPSW_ALE_ENTRY_MAX if table entry is not present
 */
uint32 CPSWAleVlanEntryPortDel(uint32 baseAddr,
                               uint32 vlanId,
                               uint32 portNum);

/**
 * \brief   This API clears the entries of address lookup table.
 *
 * \param   baseAddr    Base address of the CPSW.
 */
void CPSWAleClearTable(uint32 baseAddr);

/* ========================================================================== */
/*                        Deprecated Function Declarations                    */
/* ========================================================================== */

#ifdef __cplusplus
}
#endif

#endif /* #ifndef CPSW_ALE_H_ */
