#include <Copyright.h>
/********************************************************************************
* ev96122mii.c
*
* DESCRIPTION:
*       SMI access routines for EV-96122 board
*
* DEPENDENCIES:   Platform.
*
* FILE REVISION NUMBER:
*
*******************************************************************************/

#include <msSample.h>

/*
 * For each platform, all we need is
 * 1) Assigning functions into
 *         fgtReadMii : to read MII registers, and
 *         fgtWriteMii : to write MII registers.
 *
 * 2) Register Interrupt (Not Defined Yet.)
*/

/*
 *  EV-96122 Specific Definition
*/

#define SMI_OP_CODE_BIT_READ                    1
#define SMI_OP_CODE_BIT_WRITE                   0
#define SMI_BUSY                                1<<28
#define READ_VALID                              1<<27

#ifdef FIREFOX
#define ETHER_SMI_REG                   0x10
#define internalRegBaseAddr 0x80008000
#define NONE_CACHEABLE        0x00000000
#define CACHEABLE            0x00000000
#define SMI_RX_TIMEOUT        1000
#else
#define ETHER_SMI_REG                   0x080810
#define internalRegBaseAddr 0x14000000
#define NONE_CACHEABLE        0xa0000000
#define CACHEABLE            0x80000000
#define SMI_RX_TIMEOUT        10000000
#endif

typedef unsigned int              SMI_REG;

#ifdef LE /* Little Endian */
#define SHORT_SWAP(X) (X)
#define WORD_SWAP(X) (X)
#define LONG_SWAP(X) ((l64)(X))

#else    /* Big Endian */
#define SHORT_SWAP(X) ((X <<8 ) | (X >> 8))

#define WORD_SWAP(X) (((X)&0xff)<<24)+      \
                    (((X)&0xff00)<<8)+      \
                    (((X)&0xff0000)>>8)+    \
                    (((X)&0xff000000)>>24)

#define LONG_SWAP(X) ( (l64) (((X)&0xffULL)<<56)+               \
                            (((X)&0xff00ULL)<<40)+              \
                            (((X)&0xff0000ULL)<<24)+            \
                            (((X)&0xff000000ULL)<<8)+           \
                            (((X)&0xff00000000ULL)>>8)+         \
                            (((X)&0xff0000000000ULL)>>24)+      \
                            (((X)&0xff000000000000ULL)>>40)+    \
                            (((X)&0xff00000000000000ULL)>>56))

#endif

#define GT_REG_READ(offset, pData)                                          \
*pData = ( (volatile unsigned int)*((unsigned int *)                        \
           (NONE_CACHEABLE | internalRegBaseAddr | (offset))) );            \
*pData = WORD_SWAP(*pData)

#define GT_REG_WRITE(offset, data)                                          \
(volatile unsigned int)*((unsigned int *)(NONE_CACHEABLE |                  \
          internalRegBaseAddr | (offset))) = WORD_SWAP(data)

typedef enum _bool{false,true} bool;

/*****************************************************************************
*
* bool etherReadMIIReg (unsigned int portNumber , unsigned int MIIReg,
* unsigned int* value)
*
* Description
* This function will access the MII registers and will read the value of
* the MII register , and will retrieve the value in the pointer.
* Inputs
* portNumber - one of the 2 possiable Ethernet ports (0-1).
* MIIReg - the MII register offset.
* Outputs
* value - pointer to unsigned int which will receive the value.
* Returns Value
* true if success.
* false if fail to make the assignment.
* Error types (and exceptions if exist)
*/

GT_BOOL gtBspReadMii (GT_QD_DEV* dev, unsigned int portNumber , unsigned int MIIReg,
                        unsigned int* value)
{
SMI_REG smiReg;
unsigned int phyAddr;
unsigned int timeOut = 10; /* in 100MS units */
int i;

/* first check that it is not busy */
    GT_REG_READ (ETHER_SMI_REG,(unsigned int*)&smiReg);
    if(smiReg & SMI_BUSY)
    {
        for(i = 0 ; i < SMI_RX_TIMEOUT ; i++);
        do {
            GT_REG_READ (ETHER_SMI_REG,(unsigned int*)&smiReg);
            if(timeOut-- < 1 ) {
                return false;
            }
        } while (smiReg & SMI_BUSY);
    }
/* not busy */

    phyAddr = portNumber;

    smiReg =  (phyAddr << 16) | (SMI_OP_CODE_BIT_READ << 26) | (MIIReg << 21) |
         SMI_OP_CODE_BIT_READ<<26;

    GT_REG_WRITE (ETHER_SMI_REG,*((unsigned int*)&smiReg));
    timeOut = 10; /* initialize the time out var again */
    GT_REG_READ (ETHER_SMI_REG,(unsigned int*)&smiReg);
    if(!(smiReg & READ_VALID))
        {
            i=0;
            while(i < SMI_RX_TIMEOUT)
            {
                i++;
            }
        {
        }
        do {
            GT_REG_READ (ETHER_SMI_REG,(unsigned int*)&smiReg);
            if(timeOut-- < 1 ) {
                return false;
            }
        } while (!(smiReg & READ_VALID));
     }
    *value = (unsigned int)(smiReg & 0xffff);

    return true;


}

/*****************************************************************************
*
* bool etherWriteMIIReg (unsigned int portNumber , unsigned int MIIReg,
* unsigned int value)
*
* Description
* This function will access the MII registers and will write the value
* to the MII register.
* Inputs
* portNumber - one of the 2 possiable Ethernet ports (0-1).
* MIIReg - the MII register offset.
* value -the value that will be written.
* Outputs
* Returns Value
* true if success.
* false if fail to make the assignment.
* Error types (and exceptions if exist)
*/

GT_BOOL gtBspWriteMii (GT_QD_DEV* dev, unsigned int portNumber , unsigned int MIIReg,
                       unsigned int value)
{
SMI_REG smiReg;
unsigned int phyAddr;
unsigned int timeOut = 10; /* in 100MS units */
int i;

/* first check that it is not busy */
    GT_REG_READ (ETHER_SMI_REG,(unsigned int*)&smiReg);
    if(smiReg & SMI_BUSY)
    {
        for(i = 0 ; i < SMI_RX_TIMEOUT ; i++);
        do {
            GT_REG_READ (ETHER_SMI_REG,(unsigned int*)&smiReg);
            if(timeOut-- < 1 ) {
                return false;
            }
        } while (smiReg & SMI_BUSY);
    }
/* not busy */

    phyAddr = portNumber;

    smiReg = 0; /* make sure no garbage value in reserved bits */
    smiReg = smiReg | (phyAddr << 16) | (SMI_OP_CODE_BIT_WRITE << 26) |
             (MIIReg << 21) | (value & 0xffff);

    GT_REG_WRITE (ETHER_SMI_REG,*((unsigned int*)&smiReg));

    return(true);
}


void gtBspMiiInit(GT_QD_DEV* dev)
{
    return;
}
