/*
 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 
 * 
 *  Redistribution and use in source and binary forms, with or without 
 *  modification, are permitted provided that the following conditions 
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the   
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/**
 *  @file       emac_drv.h
 *
 *  @brief      EMAC Driver Interface between the EMAC CSL and Network Application
 */

#ifndef _EMAC_DRV_H_
#define _EMAC_DRV_H_

/******************************************************************************
 * Type:        Gauss Specific Definitions
 ******************************************************************************/
/**
 * @brief Definitions for Gauss CSL.
 */
#ifdef C6657
#define CSL_SGMII_0_REGS (CSL_EMAC_SS_CFG_REGS + 0x900)
#define CSL_ECTL_0_REGS (CSL_EMAC_SS_CFG_REGS + 0xA00)
#define CSL_EMAC_0_REGS CSL_EMAC_SS_CFG_REGS
#define CSL_MDIO_0_REGS (CSL_EMAC_SS_CFG_REGS + 0x800)
#define CSL_EMAC CSL_EMAC_SS
#define CSL_EMAC_DSC_BASE_ADDR (CSL_EMAC_SS_CFG_REGS + 0x2000)
#endif

/******************************************************************************
 * Type:        EMAC_DRV_ERR_E
 ******************************************************************************/
/**
 * @brief ENUM type of EMAC driver API funciton result.
 */
typedef enum
{
    EMAC_DRV_RESULT_OK              =   0,  
    /**< Success                                                            */
    EMAC_DRV_RESULT_GENERAL_ERR     =  -1,  
    /**< An unspecified error                                               */
    EMAC_DRV_RESULT_INVALID_PORT    =  -2,  
    /**< Invalid EMAC port number error                                     */
    EMAC_DRV_RESULT_NO_CHAN_AVAIL   =  -3,  
    /**< No channel available error                                         */
    EMAC_DRV_RESULT_NO_MEM_AVAIL    =  -4,  
    /**< Out of memory error                                                */
    EMAC_DRV_RESULT_OPEN_PORT_ERR   =  -5,  
    /**< Open EMAC port error                                               */
    EMAC_DRV_RESULT_CLOSE_PORT_ERR  =  -6,  
    /**< Close EMAC port error                                              */
    EMAC_DRV_RESULT_CONFIG_PORT_ERR =  -7,  
    /**< Config EMAC port error                                             */
    EMAC_DRV_RESULT_SEND_ERR        =  -8,  
    /**< Send packet error                                                  */
    EMAC_DRV_RESULT_POLL_ERR        =  -9,  
    /**< Poll link status error                                             */
    EMAC_DRV_RESULT_GET_STATS_ERR   = -10, 
    /**< Poll stats error                                                   */
    EMAC_DRV_RESULT_ISR_ERR         = -11  
    /**< Interrupt service error                                            */

}EMAC_DRV_ERR_E;

/******************************************************************************
 * Type:        EMAC Packet Type
 ******************************************************************************/
typedef Uint32 EMAC_PKT_FLAG_T;
#define EMAC_PKT_FLAG_SOP              0x80000000u
/**< Start of packet                                                        */
#define EMAC_PKT_FLAG_EOP              0x40000000u
/**< End of packet                                                          */

/******************************************************************************
 * Type:        EMAC_PKT_DESC_T
 ******************************************************************************/
/**
 * @brief EMAC packet descriptor data structure
 */
typedef struct EMAC_PKT_DESC_T
{
    Uint32              AppPrivate;
    /**< For use by the application                                         */
    struct EMAC_PKT_DESC_T*    pPrev;
    /**< Previous descriptor pointer                                        */
    struct EMAC_PKT_DESC_T*    pNext;
    /**< Next descriptor pointer                                            */
    Uint8*              pDataBuffer;
    /**< Pointer to Data Buffer (read only)                                 */
    Uint32              BufferLen;
    /**< Physical Length of buffer (read only)                              */
    EMAC_PKT_FLAG_T     Flags;
    /**< Packet Flags, SOP, EOP                                             */
    Uint32              ValidLen;
    /**< Length of valid data in buffer                                     */
    Uint32              DataOffset;
    /**< Byte offset to valid data                                          */
    Uint32              PktChannel;
    /**< Tx/Rx Channel 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), normally 1                       */
} EMAC_PKT_DESC_T;

/******************************************************************************
 * Function: EMAC RX packet call back function
 ******************************************************************************/
/**
 *  @brief  This function is used to call back the network application when a
 *          packet is received.
 */
typedef void EMAC_RX_PKT_CALLBACK_FN_T
(
   Uint32               port_num,   
   /**< EMAC port number                                                    */
   EMAC_PKT_DESC_T*     p_desc      
   /**< Pointer to the received packet descriptor                           */
);

/******************************************************************************
 * Function: EMAC allocate packet call back function
 ******************************************************************************/
/**
 *  @brief  This function is used to call back the network application to 
 *          allocate a packet descriptor with packet buffer allocated from the 
 *          application packet queue.
 */
typedef EMAC_PKT_DESC_T* EMAC_ALLOC_PKT_CALLBACK_FN_T
(
   Uint32               port_num,   
   /**< EMAC port number                                                    */
   Uint32               pkt_size    
   /**< Size of the packet buffer to be allocated                                  */
);

/******************************************************************************
 * Function: EMAC free packet call back function
 ******************************************************************************/
/**
 *  @brief  This function is used to call back the network application to 
 *          free a packet descriptor to the application packet queue.
 */
typedef void EMAC_FREE_PKT_CALLBACK_FN_T
(
   Uint32               port_num,   
   /**< EMAC port number                                                    */
   EMAC_PKT_DESC_T*     p_desc      
   /**< Pointer to the received packet descriptor                           */
);

/******************************************************************************
 * Function: EMAC_MAC_ADDR_T
 ******************************************************************************/
/**
 *  @brief  This structure defines the 6 byte MAC address structure.
 */
#define EMAC_MAC_ADDR_LENTH     6
typedef struct EMAC_MAC_ADDR_tag
{
    Uint8   addr[EMAC_MAC_ADDR_LENTH];        
    /**< MAC address specific to channel                                    */
} EMAC_MAC_ADDR_T;

/******************************************************************************
 * Function: EMAC_CHAN_MAC_ADDR_T
 ******************************************************************************/
/**
 *  @brief  This structure is used to for the driver to return the application
 *          the channel/MAC address configuration when an EMAC port is opened.
 */
typedef struct EMAC_CHAN_MAC_ADDR_tag
{
    Uint32               chan_num;
    /**< channel number configured for this core                            */
    Uint32               num_of_mac_addrs;
   /**< Total number of MAC addresses configured for this channel           */
    EMAC_MAC_ADDR_T*     p_mac_addr;
   /**< Pointer to the MAC addresses configured for this channel            */
} EMAC_CHAN_MAC_ADDR_T;

/**
 * @brief   Maximum number of phy address
 */
#define EMAC_MAX_NUM_PHY_ADDR               32

/******************************************************************************
 * Type:        EMAC_OPEN_CONFIG_INFO_T
 ******************************************************************************/
/**
 * @brief EMAC open configuration data structure
 *
 */
typedef struct EMAC_OPEN_CONFIG_INFO_tag
{
    Bool                            master_core_flag;
    /**< True: master core configuration                                    */
    Bool                            mdio_flag;
    /**< True: configure MDIO                                               */
    Uint32                          phy_addr;
    /**< Physical layer transceiver address mapped to the EMAC port
         valid address range is 0 - (EMAC_MAX_NUM_PHY_ADDR-1).
         if a valid address is specified, EMAC driver will check the link
         status only on the application specifid phy address; if an invalid 
         phy_addr is specified, EMAC driver will search the phy address that 
         can be used by itself                                              */
    Bool                            loop_back;
    /**< True: packets loop back                                            */
    Uint32                          num_of_tx_pkt_desc;
    /**< Total # of pkt desc initialized for all the TX chans in TX queues  */
    Uint32                          num_of_rx_pkt_desc;
    /**< Total # of pkt desc initialized for all the RX chans in RX queues  */
    Uint32                          max_pkt_size;
    /**< Maximum size of the packet in bytes                                */
    Uint32                          num_of_chans;
   /**< Total number of TX/RX channels configured for this core             */
    EMAC_CHAN_MAC_ADDR_T*           p_chan_mac_addr;
   /**< Application needs to provide the MAC address configurations; 
        EMAC driver will allocate the channels if available and 
        return the channel info to the application                          */
    EMAC_RX_PKT_CALLBACK_FN_T*      rx_pkt_cb;
    /**< EMAC RX call back function                                         */
    EMAC_ALLOC_PKT_CALLBACK_FN_T*   alloc_pkt_cb;
    /**< EMAC allocate packet call back function                            */
    EMAC_FREE_PKT_CALLBACK_FN_T*    free_pkt_cb;
    /**< EMAC free packet call back function                                */

} EMAC_OPEN_CONFIG_INFO_T;

/**
 *  @brief Packet Filtering
 *
 *  Receive Packet Filtering Settings 
 *
 */
typedef Uint32 EMAC_PKT_FILTER_T;
#define EMAC_PKTFLT_NOTHING           0
/**< Receive filter set to receive no packets                           */
#define EMAC_PKTFLT_DIRECT            1
/**< Receive filter set to receive direct unitcast packets              */
#define EMAC_PKTFLT_BROADCAST         2
/**< Receive filter set to receive broadcast/unitcast packets           */
#define EMAC_PKTFLT_MULTICAST         3
/**< Receive filter set to receive multicast/broadcast/unitcast packets */
#define EMAC_PKTFLT_ALLMULTICAST      4
/**< Receive filter set to receive alll Mcast/Bcast/Ucast packets       */
#define EMAC_PKTFLT_ALL               5
/**< Receive filter set to receive All packets                          */

/******************************************************************************
 * Type:        EMAC_CONFIG_INFO_T
 ******************************************************************************/
/**
 * @brief EMAC configuration data structure
 *
 */
typedef struct EMAC_CONFIG_INFO_tag
{
    EMAC_PKT_FILTER_T   rx_filter;
    /**< EMAC RX filter, e.g. broadcast, multicast, etc.                    */
    Uint32              mcast_cnt;   
    /**< Multicast address count, if mcast_cnt=0, p_mcast_list can be NULL  */
    Uint8*              p_mcast_list;
    /**< Pointer to the multicast list of which size is mcast_cnt*6 in bytes*/
} EMAC_CONFIG_INFO_T;

/******************************************************************************
 * Type:        EMAC_STATISTICS_T
 ******************************************************************************/
/**
 * @brief  
 *  The statistics structure is used to retrieve the current count
 *  of various packet events in the system. These values represent the
 *  delta values from the last time the statistics were read.
 */
 typedef struct EMAC_STATISTICS_tag 
 {
    Uint32      RxGoodFrames;     
    /**< Good Frames Received                                               */
    Uint32      RxBCastFrames;    
    /**< Good Broadcast Frames Received                                     */
    Uint32      RxMCastFrames;    
    /**< Good Multicast Frames Received                                     */
    Uint32      RxPauseFrames;    
    /**< PauseRx Frames Received                                            */
    Uint32      RxCRCErrors;      
    /**< Frames Received with CRC Errors                                    */
    Uint32      RxAlignCodeErrors;
    /**< Frames Received with Alignment/Code Errors                         */
    Uint32      RxOversized;      
    /**< Oversized Frames Received                                          */
    Uint32      RxJabber;         
    /**< Jabber Frames Received                                             */
    Uint32      RxUndersized;     
    /**< Undersized Frames Received                                         */
    Uint32      RxFragments;      
    /**< Rx Frame Fragments Received                                        */
    Uint32      RxFiltered;       
    /**< Rx Frames Filtered Based on Address                                */
    Uint32      RxQOSFiltered;    
    /**< Rx Frames Filtered Based on QoS Filtering                          */
    Uint32      RxOctets;         
    /**< Total Received Bytes in Good Frames                                */
    Uint32      TxGoodFrames;     
    /**< Good Frames Sent                                                   */
    Uint32      TxBCastFrames;    
    /**< Good Broadcast Frames Sent                                         */
    Uint32      TxMCastFrames;    
    /**< Good Multicast Frames Sent                                         */
    Uint32      TxPauseFrames;    
    /**< PauseTx Frames Sent                                                */
    Uint32      TxDeferred;       
    /**< Frames Where Transmission was Deferred                             */
    Uint32      TxCollision;      
    /**< Total Frames Sent With Collision                                   */
    Uint32      TxSingleColl;     
    /**< Frames Sent with Exactly One Collision                             */
    Uint32      TxMultiColl;      
    /**< Frames Sent with Multiple Colisions                                */
    Uint32      TxExcessiveColl;  
    /**< Tx Frames Lost Due to Excessive Collisions                         */
    Uint32      TxLateColl;       
    /**< Tx Frames Lost Due to a Late Collision                             */
    Uint32      TxUnderrun;       
    /**< Tx Frames Lost with Tx Underrun Error                              */
    Uint32      TxCarrierSLoss;   
    /**< Tx Frames Lost Due to Carrier Sense Loss                           */
    Uint32      TxOctets;         
    /**< Total Transmitted Bytes in Good Frames                             */
    Uint32      Frame64;          
    /**< Total Tx&Rx with Octet Size of 64                                  */
    Uint32      Frame65t127;      
    /**< Total Tx&Rx with Octet Size of 65 to 127                           */
    Uint32      Frame128t255;     
    /**< Total Tx&Rx with Octet Size of 128 to 255                          */
    Uint32      Frame256t511;     
    /**< Total Tx&Rx with Octet Size of 256 to 511                          */
    Uint32      Frame512t1023;    
    /**< Total Tx&Rx with Octet Size of 512 to 1023                         */
    Uint32      Frame1024tUp;     
    /**< Total Tx&Rx with Octet Size of >=1024                              */
    Uint32      NetOctets;        
    /**< Sum of all Octets Tx or Rx on the Network                          */
    Uint32      RxSOFOverruns;    
    /**< Total Rx Start of Frame Overruns                                   */
    Uint32      RxMOFOverruns;    
    /**< Total Rx Middle of Frame Overruns                                  */
    Uint32      RxDMAOverruns;    
    /**< Total Rx DMA Overruns                                              */
} EMAC_STATISTICS_T;

/******************************************************************************
 * Type:        EMAC_LINK_STATUS_E
 ******************************************************************************/
/**
 * @brief ENUM type of EMAC port link status
 */
typedef Uint32 EMAC_LINK_STATUS_T;
#define EMAC_LINKSTATUS_NOLINK          0
/**< Link Status: No Link                                                   */
#define EMAC_LINKSTATUS_HD10            1
/**< Link Status: Half Duplex 10Mbps                                        */
#define EMAC_LINKSTATUS_FD10            2
/**< Link Status: Full Duplex 10Mbps                                        */
#define EMAC_LINKSTATUS_HD100           3
/**< Link Status: Half Duplex 100Mbps                                       */
#define EMAC_LINKSTATUS_FD100           4
/**< Link Status: Full Duplex 100Mbps                                       */
#define EMAC_LINKSTATUS_FD1000          5
/**< Link Status: Full Duplex 1000Mbps                                      */

/******************************************************************************
 * Type:        EMAC_LINK_INFO_T
 ******************************************************************************/
/**
 * @brief EMAC statistics and link status data structure
 *
 */
typedef struct EMAC_LINK_INFO_tag
{
    Bool                    link_status_change;
    /**< True: link status changed, False: link status is not changed       */
    EMAC_LINK_STATUS_T      link_status;
    /**< PHY link status, only valid when link_status_change is TRUE        */

} EMAC_LINK_INFO_T;


/** @addtogroup EMAC_DRV */
/**@{*/

/** ============================================================================
 *  @n@b  emac_get_version()
 *
 *  @b Description
 *  @n Retrieves the version ID string.
 *
 *     The function returns zero on success, or an error code on failure.
 *
 *  @b Arguments
 *  @verbatim
 *      void
 *  @endverbatim
 *
 *  <b> Return Value </b>
 *  @n  Pointer of the version ID string
 *
 * ============================================================================
 */
/**
  @brief    Retrieves the version string
*/
const char*
emac_get_version
(
    void
);

/** ============================================================================
 *  @n@b  emac_open()
 *
 *  @b Description
 *  @n Opens and configures an EMAC port.
 *
 *     The calling application must supply a valid port number and open configuration
 *     data. After the port is opened successfully, the application will need to set 
 *     the RX filter configuration.
 *
 *     When a core is MASTER_CORE, the driver will do the common configurations
 *     of the port only when the port is first opened. The driver will do the channel 
 *     specific configurations for all the cores. 
 *
 *     In the open configuration, the alloc_pkt call back function will allow the 
 *     application to get a packet descriptor with allocated packet buffer, the 
 *     rx_pkt call back function will allow the application to enqueue received 
 *     packet to the application RX queue for post processing. The free_pkt 
 *     call back function will allow the application to free the packet buffer 
 *     when a packet is sent successfully .
 *
 *     The driver passes the channels assigned to the port to the
 *     application layer when the port is opened successfully.
 *
 *     The function returns zero on success, or an error code on failure.
 *
 *  @b Arguments
 *  @verbatim
 *      port_num         EMAC port number.
 *      p_config         Pointer to EMAC configuration data
 *  @endverbatim
 *
 *  <b> Return Value </b>
 *  @n  Return code of EMAC_DRV_ERR_E type
 *
 * ============================================================================
 */
EMAC_DRV_ERR_E
emac_open
(
    Uint32                      port_num,
    EMAC_OPEN_CONFIG_INFO_T*    p_config
);

/** ============================================================================
 *  @n@b  emac_close()
 *
 *  @b Description
 *  @n Closes an opend EMAC port.
 *
 *     The driver closes the opened port and disables the RX/TX interrupts.
 *     The driver needs to close all the TX/RX channels allocated for this port
 *
 *     The calling application must supply a valid port number
 *
 *     The function returns zero on success, or an error code on failure.
 *
 *  @b Arguments
 *  @verbatim
 *      port_num         EMAC port number.
 *  @endverbatim
 *
 *  <b> Return Value </b>
 *  @n  Return code of EMAC_DRV_ERR_E type
 *
 * ============================================================================
 */
EMAC_DRV_ERR_E
emac_close
(
    Uint32                  port_num
);

/** ============================================================================
 *  @n@b  emac_config()
 *
 *  @b Description
 *  @n Configures an opend EMAC port.
 *
 *     The driver configures the opened port, e.g. RX filter, etc.
 *
 *     For RX multicast configuration, this API is called to install a list 
 *     of multicast addresses for use in multicast address filtering. The new
 *     multicast list will replace the old multicast configuration. Thus
 *     a set with a list size of zero will remove all multicast addresses from 
 *     the device.
 *
 *     Note that the multicast list configuration is stateless in that the
 *     list of multicast addresses used to build the configuration is not
 *     retained. Thus it is impossible to examine a list of currently installed
 *     addresses.
 *
 *     The calling application must supply a valid port number
 *
 *     The function returns zero on success, or an error code on failure.
 *
 *  @b Arguments
 *  @verbatim
 *      port_num         EMAC port number.
 *      p_config         pointer to configuration
 *  @endverbatim
 *
 *  <b> Return Value </b>
 *  @n  Return code of EMAC_DRV_ERR_E type
 *
 * ============================================================================
 */
EMAC_DRV_ERR_E
emac_config
(
    Uint32                  port_num,
    EMAC_CONFIG_INFO_T*     p_config
);

/** ============================================================================
 *  @n@b  emac_send()
 *
 *  @b Description
 *  @n Sends a packet on an opened EMAC port.
 *
 *     The calling application must supply a valid port number. The free_pkt 
 *     call back function will allow the application to free the packet buffer 
 *     when a packet is sent successfully .
 *
 *     The function returns zero on success, or an error code on failure.
 *
 *  @b Arguments
 *  @verbatim
 *      port_num         EMAC port number.
 *      p_desc           Pointer to a TX packet descriptor
 *  @endverbatim
 *
 *  <b> Return Value </b>
 *  @n  Return code of EMAC_DRV_ERR_E type
 *
 * ============================================================================
 */
EMAC_DRV_ERR_E
emac_send
(
    Uint32                  port_num,
    EMAC_PKT_DESC_T*        p_desc
);

/** ============================================================================
 *  @n@b  emac_poll()
 *
 *  @b Description
 *  @n Polls the ink status infomation on an opened EMAC port.
 *
 *     The calling application must supply a valid port number and the driver
 *     will return the link info to the application when called successfully .
 *
 *     The function returns zero on success, or an error code on failure.
 *
 *  @b Arguments
 *  @verbatim
 *      port_num         EMAC port number.
 *      p_info           Pointer to the returned link status info
 *  @endverbatim
 *
 *  <b> Return Value </b>
 *  @n  Return code of EMAC_DRV_ERR_E type
 *
 * ============================================================================
 */
EMAC_DRV_ERR_E
emac_poll
(
    Uint32                  port_num,
    EMAC_LINK_INFO_T*       p_info
);

/** ============================================================================
 *  @n@b  emac_get_stats()
 *
 *  @b Description
 *  @n Retrieve the statistics on an opened EMAC port.
 *
 *     The calling application must supply a valid port number and the driver
 *     will return the stats to the application when called successfully .
 *
 *     The function returns zero on success, or an error code on failure.
 *
 *  @b Arguments
 *  @verbatim
 *      port_num         EMAC port number.
 *      p_stats          Pointer to the returned stats info
 *  @endverbatim
 *
 *  <b> Return Value </b>
 *  @n  Return code of EMAC_DRV_ERR_E type
 *
 * ============================================================================
 */
EMAC_DRV_ERR_E
emac_get_stats
(
    Uint32                  port_num,
    EMAC_STATISTICS_T*      p_stats
);

/** ============================================================================
 *  @n@b  emac_int_service()
 *
 *  @b Description
 *  @n Services RX or TX interrupt for an opened EMAC port.
 *
 *     The calling application must supply a valid port number and RX/TX flag.
 *     The driver will service the interrupt and call back to application layer
 *     when there is a packet received.
 *
 *     The function returns zero on success, or an error code on failure.
 *
 *  @b Arguments
 *  @verbatim
 *      port_num         EMAC port number.
 *      rx_flag          TURE: RX interrupt; FALSE: TX interrupt
 *  @endverbatim
 *
 *  <b> Return Value </b>
 *  @n  Return code of EMAC_DRV_ERR_E type
 *
 * ============================================================================
 */
EMAC_DRV_ERR_E
emac_int_service
(
    Uint32                  port_num,
    Bool                    rx_flag
);

/**@}*/  /* end addtogroup EMAC_DRV */

#endif /* _EMAC_DRV_H_ */
