/**
* @file icss_miimdio.h
*
* @brief Contains MDIO reg offsets and function definitions
*
* \par
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
* \par
*/

#ifndef _ICSS_MIIMDIO_H
#define _ICSS_MIIMDIO_H

#ifdef __cplusplus
extern "C" {
#endif
/**
* @def PHYCR_REG_OFFSET
*      Phy Control register offset
*/
#define PHYCR_REG_OFFSET 0x19
/**
* @def NWAY_AUTOMDIX
*      Auoto MDIX
*/
#define NWAY_AUTOMDIX       (1u << 16u)
/**
* @def NWAY_FD1000
*      Full Duplex 1Gbps
*/
#define NWAY_FD1000         (1u<<13u)
/**
* @def NWAY_HD1000
*      Half Duplex 1Gbps
*/
#define NWAY_HD1000         (1u<<12u)
/**
* @def NWAY_NOPHY
*      No phy
*/
#define NWAY_NOPHY          (1u<<10u)
/**
* @def NWAY_LPBK
*      Loop back mode
*/
#define NWAY_LPBK           (1u<<9u)
/**
* @def NWAY_FD100
*      Full Duplex 100 Mbps
*/
#define NWAY_FD100          (1u<<8u)
/**
* @def NWAY_HD100
*      Half Duplex 100 Mbps
*/
#define NWAY_HD100          (1u<<7u)
/**
* @def NWAY_FD10
*      Full Duplex 10 Mbps
*/
#define NWAY_FD10           (1u<<6u)
/**
* @def NWAY_HD10
*      Half Duplex 10 Mbps
*/
#define NWAY_HD10           (1u<<5u)
/**
* @def NWAY_AUTO
*      Autonegotiate
*/
#define NWAY_AUTO           (1u<<0u)
/**
* @def NWAY_AUTOMDIX_ENABLE
*      Auto MDIX Enable
*/
#define NWAY_AUTOMDIX_ENABLE (1u<<15)
/**
* @def NWAY_FORCEMDIX_ENABLE
*      Force MDIX enable
*/
#define NWAY_FORCEMDIX_ENABLE (1u<<14)


/* Tic() return values */
/**
* @def _MIIMDIO_MDIXFLIP
*      MDIX Flip
*/
#define _MIIMDIO_MDIXFLIP (1u<<28u)
/**
* @def _AUTOMDIX_DELAY_MIN
*      Auto MDIX Minimum Delay
*/
#define _AUTOMDIX_DELAY_MIN  80u  /* milli-seconds*/
/**
* @def _AUTOMDIX_DELAY_MAX
*      Auto MDIX Maximum Delay
*/
#define _AUTOMDIX_DELAY_MAX 200u  /* milli-seconds*/


/*-----------------------------------------------------------------------
 * MDIO Events
 *
 * These events are returned as result param by icss_MDIO_Tic() to allow the application
 * (or EMAC) to track MDIO status.
 *-----------------------------------------------------------------------*/

/**
* @def MDIO_EVENT_NOCHANGE
*      No change from previous status
*/
#define MDIO_EVENT_NOCHANGE      0u
/**
* @def MDIO_EVENT_LINKDOWN
*     	Link down event
*/
#define MDIO_EVENT_LINKDOWN      1u
/**
* @def MDIO_EVENT_LINKUP
*      Link (or re-link) event
*/
#define MDIO_EVENT_LINKUP        2u
/**
* @def MDIO_EVENT_PHYERROR
*      No PHY connected
*/
#define MDIO_EVENT_PHYERROR      3u

/*-----------------------------------------------------------------------
 * MDIO Link Status Values
 *
 * These values indicate current PHY link status. 
 * Codes are constructed as follows
 * Bit0: 0  for HD, 1 for FullDuplex
 * Bit[2:1]: 10Mbps- 1, 100Mbps - 2, 1000Mbps - 3
 *  
 *-----------------------------------------------------------------------*/
/**
* @def MDIO_LINKSTATUS_NOLINK
*      No Link
*/
#define MDIO_LINKSTATUS_NOLINK     	0u
/**
* @def MDIO_LINKSTATUS_HD10
*      Link Status Half duplex 10 Mbps
*/
#define MDIO_LINKSTATUS_HD10     	2u
/**
* @def MDIO_LINKSTATUS_FD10
*      Link Status Full duplex 10 Mbps
*/
#define MDIO_LINKSTATUS_FD10     	3u
/**
* @def MDIO_LINKSTATUS_HD100
*      Link Status Half duplex 100 Mbps
*/
#define MDIO_LINKSTATUS_HD100     	4u
/**
* @def MDIO_LINKSTATUS_FD100
*      Link Status Full duplex 100 Mbps
*/
#define MDIO_LINKSTATUS_FD100     	5u
/**
* @def MDIO_LINKSTATUS_FD1000
*      Link Status Full duplex 1 Gbps
*/
#define MDIO_LINKSTATUS_FD1000  	7u
/**
* @def MDIO_ENABLE_AUTO_MDIX
*       Enable AutoMDI/X
*/
#define MDIO_ENABLE_AUTO_MDIX  0u
/**
* @def MDIO_ENABLE_FORCE_MDI
*      Force MDI mode
*/
#define MDIO_ENABLE_FORCE_MDI  1u
/**
* @def MDIO_ENABLE_FORCE_MDIX
*      Force MDIX mode
*/
#define MDIO_ENABLE_FORCE_MDIX  2u
/**
* @def MDIO_POWERMODE_NORMAL
*      Enable Normal Power mode
*/
#define MDIO_POWERMODE_NORMAL 0u
/**
* @def MDIO_POWERMODE_DOWN
*      Enable Normal down mode
*/
#define MDIO_POWERMODE_DOWN 1u
/**
* @def MDIO_POWERMODE_ACTIVE_SLEEP
*      Enable Active Sleep  Power mode
*/
#define MDIO_POWERMODE_ACTIVE_SLEEP 2u
/**
* @def MDIO_POWERMODE_PASSIVE_SLEEP
*      Enable Passive Sleep Power mode
*/
#define MDIO_POWERMODE_PASSIVE_SLEEP 3u
/**
* @def PHY_CONFIG_AUTONEG
*      Configure PHY in AutoNeg mode
*/
#define  PHY_CONFIG_AUTONEG 0u
/**
* @def PHY_CONFIG_100FD
*      Force PHY to 100 FullDuplex
*/
#define  PHY_CONFIG_100FD 1u
/**
* @def PHY_CONFIG_10FD
*      Force PHY to 10 FullDuplex
*/
#define  PHY_CONFIG_10FD 2u
/**
* @def PHY_CONFIG_100HD
*      Force PHY to 100 halfDuplex
*/
#define  PHY_CONFIG_100HD 3u
/**
* @def PHY_CONFIG_10HD
*      Force PHY to 100 halfDuplex
*/
#define  PHY_CONFIG_10HD 4u

/**
* @brief Representation of PHY device
*
*/
typedef struct _phy_device
{
   Uint32 miibase;		/**MII Base address*/
   Uint32 inst;			/**Instances*/
   Uint32 PhyState;		/**Phy State*/
   Uint32 MdixMask;		/**MDIO Mask*/
   Uint32 PhyMask;		/**PHY mask*/
   Uint32 MLinkMask;	/**Link Mask*/
   Uint32 PhyMode;		/**PHY mode*/
} PHY_DEVICE;

/**
* @internal
* @brief Updates book-keeping with info provided, programs ControlReg with clkdiv,enable bits
*
* @param PhyDev	pointer to the structure which represents the PHY and it's attributes
* @param miibase  32 bit offset to the MII Base address in the subsystem
* @param inst
* @param PhyMask
* @param MLinkMask
* @param MdixMask
* @param PhyNUM	     Phy Number
* @param ResetBit
* @param MdioBusFreq   Bus frequency in KHz
* @param MdioClockFreq Clock frequency in KHz
* @param verbose
*
* @retval success or failure
*/
int  ICSSMDIOInit(PHY_DEVICE *PhyDev, Uint32 miibase, Uint32 inst, Uint32 PhyMask,
                        Uint32 MLinkMask, Uint32 MdixMask, Uint32 ResetBase, Uint32 ResetBit, Uint32 MdioBusFreq,
                        Uint32 MdioClockFreq,int verbose);
/**
* @internal
* @brief icss_MDIO_Tic is called every 10 mili seconds to process Phy states
*
* @param PhyDev	pointer to the structure which represents the PHY and it's attributes
* @param mdioStatus pointer to the mdio status, this is updated with the current mdio status value
*
* @retval status unsigned word indicating whether the polling was successful or not
*/
int ICSSMDIOTic(PHY_DEVICE *PhyDev, Uint32* mdioStatus);
/**
* @internal
* @brief Sets the PHY mode (Manual or Auto Negotiate)
*
* @param PhyDev	pointer to the structure which represents the PHY and it's attributes
* @param PhyMode  32 bit offset to the MII Base address in the subsystem
*
* @retval none
*/
void ICSSMDIOSetPhyMode(PHY_DEVICE *PhyDev,Uint32 PhyMode);
/**
* @internal
* @brief Sets the PHY mode (Manual or Auto Negotiate)
*
* @param PhyDev	pointer to the structure which represents the PHY and it's attributes
*
* @retval PhyMode unsigned 32 bit value indicating the phy mode
*/
Uint32 ICSSMDIOGetPhyMode(PHY_DEVICE *PhyDev);

/*Calls to retreive info after a mode change! */

/**
* @internal
* @brief Simple Query Functions for reporting speed,duplex
*
* @param PhyDev	pointer to the structure which represents the PHY and it's attributes
*
* @retval returns the duplex status information
*/
int  ICSSMDIOGetDuplex(PHY_DEVICE *PhyDev);
/**
* @internal
* @brief ICSSMDIOGetSpeed is called to retrieve the Speed info
*
* @param PhyDev	pointer to the structure which represents the PHY and it's attributes
*
* @retval  returns the speed of PHY. Speed can be set to 10 or 100 Mbps
*/
int  ICSSMDIOGetSpeed(PHY_DEVICE *PhyDev);
/**
* @internal
* @brief Is called to retreive the Phy Device Address info
*
* @param PhyDev	pointer to the structure which represents the PHY and it's attributes
*
* @retval  PHY number
*/
int  ICSSMDIOGetPhyNum(PHY_DEVICE *PhyDev);
/**
* @internal
* @brief ICSSMDIOGetLinked is called to determine if the LINKED state has been reached
*
* @param PhyDev	pointer to the structure which represents the PHY and it's attributes
*
* @retval  Linked state
*/
int  ICSSMDIOGetLinked(PHY_DEVICE *PhyDev);
/**
* @internal
* @brief Change the MDIO link status
*
* @param PhyDev	pointer to the structure which represents the PHY and it's attributes
*
* @retval none
*/
void ICSSMDIOLinkChange(PHY_DEVICE *PhyDev);
/**
* @internal
* @brief ICSSMDIOGetLoopback is called to Determine if the LOOPBACK state has been reached
*
* @param PhyDev	pointer to the structure which represents the PHY and it's attributes
*
* @retval  PHY loop back state
*/
int  ICSSMDIOGetLoopback(PHY_DEVICE *PhyDev);

/**
* @internal
* @brief brief Waits for MDIO_USERACCESS to be ready and reads data
* @details  If 'WaitForData' set, waits for read to complete and returns Data,
*  			otherwise returns 0
*  			Note: 'data' is 16 bits but we use 32 bits to be consistent with rest of the code.
*
* @param PhyDev	pointer to the structure which represents the PHY and it's attributes
* @param regadr 32bit offset to the register address space
* @param phyadr 32bit offset to the phy address
*
* @retval data from teh register
*/
Uint32 ICSSMDIOUserAccessRead (PHY_DEVICE *PhyDev, Uint32 regadr, Uint32 phyadr);
/**
* @internal
* @brief Function to write to MDIO Register
*
* @param PhyDev	pointer to the structure which represents the PHY and it's attributes
* @param regadr 32bit offset to the register address space
* @param phyadr 32bit offset to the phy address
* @param data data that is to be written
*
* @retval none
*/
void   ICSSMDIOUserAccessWrite(PHY_DEVICE *PhyDev, Uint32 regadr, Uint32 phyadr, Uint32 data);


#ifdef __cplusplus
}
#endif

#endif /*_ICSS_MIIMDIO_H*/
