/**
 * cpsw_miimdio.h
 * 
 *
 * Copyright (c) 2012 Texas Instruments Incorporated ALL RIGHTS RESERVED
 *
*/
#ifndef _CPSW_MIIMDIO_H
#define _CPSW_MIIMDIO_H

#include "cpsw_nimu_eth.h"

#ifdef __cplusplus
extern "C" {
#endif

/* Phy Mode Values  */
#define NWAY_AUTOMDIX       (1u << 16u)
#define NWAY_FD1000         (1u<<13u)
#define NWAY_HD1000         (1u<<12u)
#define NWAY_NOPHY          (1u<<10u)
#define NWAY_LPBK           (1u<<9u)
#define NWAY_FD100          (1u<<8u)
#define NWAY_HD100          (1u<<7u)
#define NWAY_FD10           (1u<<6u)
#define NWAY_HD10           (1u<<5u)
#define NWAY_AUTO           (1u<<0u)

#define NWAY_AUTOMDIX_ENABLE (1u<<15)

/* Tic() return values */
#define _MIIMDIO_MDIXFLIP (1u<<28u)
#define _AUTOMDIX_DELAY_MIN  80u  /* milli-seconds*/
#define _AUTOMDIX_DELAY_MAX 200u  /* milli-seconds*/

/*-----------------------------------------------------------------------
 * MDIO Events
 *
 * These events are returned as result param by cpsw_MDIO_Tic() to allow the application
 * (or EMAC) to track MDIO status.
 *-----------------------------------------------------------------------*/
#define MDIO_EVENT_NOCHANGE      0u   /* No change from previous status */
#define MDIO_EVENT_LINKDOWN      1u   /* Link down event                */
#define MDIO_EVENT_LINKUP         2u   /* Link (or re-link) event        */
#define MDIO_EVENT_PHYERROR      3u   /* No PHY connected                */

/*-----------------------------------------------------------------------
 * 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
 *  
 *-----------------------------------------------------------------------*/
#define MDIO_LINKSTATUS_NOLINK     0u
#define MDIO_LINKSTATUS_HD10     2u
#define MDIO_LINKSTATUS_FD10     3u
#define MDIO_LINKSTATUS_HD100     4u
#define MDIO_LINKSTATUS_FD100     5u
#define MDIO_LINKSTATUS_FD1000  7u

typedef struct _cpsw_phy_device
{
   Uint32 miibase;
   Uint32 inst;
   Uint32 PhyState;
   Uint32 MdixMask;
   Uint32 PhyMask;
   Uint32 MLinkMask;
   Uint32 PhyMode;
   Uint32 SPEED_1000; /* set to 1 for gig capable phys */
} CPSW_PHY_DEVICE;

/*Version Information */
void cpsw_MDIO_GetVer(Uint32 miiBase, Uint32 *ModID,  Uint32 *RevMaj,  Uint32 *RevMin);

/*Called once at the begining of time */
int  cpsw_MDIO_GetPhyDevSize(void);  /*Called first to get size of storage needed!*/

int  cpsw_MDIO_Init(CPSW_PHY_DEVICE *PhyDev, Uint32 miibase, Uint32 inst, Uint32 PhyMask,
                        Uint32 MLinkMask, Uint32 MdixMask, Uint32 PhyAddr, Uint32 ResetBit, Uint32 MdioBusFreq,
                        Uint32 MdioClockFreq,int verbose);



/*Called every 100 milli Seconds, returns TRUE if there has been a mode change */
int cpsw_MDIO_Tic(CPSW_PHY_DEVICE *PhyDev, Uint32* mdioStatus);

/*Called to set Phy mode   */
void cpsw_MDIO_SetPhyMode(CPSW_PHY_DEVICE *PhyDev,Uint32 PhyMode);

/*Called to Get Phy mode   */
Uint32 cpsw_MDIO_GetPhyMode(CPSW_PHY_DEVICE *PhyDev);

/*Calls to retreive info after a mode change! */
int  cpsw_MDIO_GetDuplex(CPSW_PHY_DEVICE *PhyDev);
int  cpsw_MDIO_GetSpeed(CPSW_PHY_DEVICE *PhyDev);
int  cpsw_MDIO_GetPhyNum(CPSW_PHY_DEVICE *PhyDev);
int  cpsw_MDIO_GetLinked(CPSW_PHY_DEVICE *PhyDev);
void cpsw_MDIO_LinkChange(CPSW_PHY_DEVICE *PhyDev);
int  cpsw_MDIO_GetLoopback(CPSW_PHY_DEVICE *PhyDev);

/*  Shut Down  */
void cpsw_MDIO_Close(CPSW_PHY_DEVICE *PhyDev, int Full);

/* Expert Use Functions (exported) */
Uint32 _cpsw_MDIO_UserAccessRead (CPSW_PHY_DEVICE *PhyDev, Uint32 regadr, Uint32 phyadr);
void   _cpsw_MDIO_UserAccessWrite(CPSW_PHY_DEVICE *PhyDev, Uint32 regadr, Uint32 phyadr, Uint32 data);

#ifdef __cplusplus
}
#endif

#endif /*_CPSW_MIIMDIO_H*/
