/**
 * @file IxEthMii.c
 *
 * @author Intel Corporation
 * @date
 *
 * @brief  MII control functions
 *
 * Design Notes:
 *
 * 
 * @par
 * IXP400 SW Release version 2.0
 * 
 * -- Copyright Notice --
 * 
 * @par
 * Copyright 2001-2005, Intel Corporation.
 * All rights reserved.
 * 
 * @par
 * SPDX-License-Identifier:	BSD-3-Clause
 * @par
 * -- End of Copyright Notice --
 */

#include "IxOsal.h"

#include "IxEthAcc.h"
#include "IxEthMii_p.h"

#ifdef __wince
#include "IxOsPrintf.h"
#endif

/* Array to store the phy IDs of the discovered phys */
PRIVATE UINT32 ixEthMiiPhyId[IXP425_ETH_ACC_MII_MAX_ADDR];

/*********************************************************
 *
 * Scan for PHYs on the MII bus. This function returns
 * an array of booleans, one for each PHY address.
 * If a PHY is found at a particular address, the
 * corresponding entry in the array is set to true.
 *
 */

PUBLIC IX_STATUS
ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount)
{
    UINT32 i;
    UINT16 regval, regvalId1, regvalId2;

    /*Search for PHYs on the MII*/
    /*Search for existant phys on the MDIO bus*/

    if ((phyPresent == NULL) || 
	(maxPhyCount > IXP425_ETH_ACC_MII_MAX_ADDR))
    {
	return IX_FAIL;
    }

    /* fill the array */
    for(i=0;
        i<IXP425_ETH_ACC_MII_MAX_ADDR;
	i++)
    {
	phyPresent[i] = false;
    }

    /* iterate through the PHY addresses */
    for(i=0;
	maxPhyCount > 0 && i<IXP425_ETH_ACC_MII_MAX_ADDR;
	i++)
    {
	ixEthMiiPhyId[i] = IX_ETH_MII_INVALID_PHY_ID;
	if(ixEthAccMiiReadRtn(i,
			      IX_ETH_MII_CTRL_REG,
			      &regval) == IX_ETH_ACC_SUCCESS)
	{
	    if((regval & 0xffff) != 0xffff)
	    {
		maxPhyCount--;
		/*Need to read the register twice here to flush PHY*/
		ixEthAccMiiReadRtn(i,  IX_ETH_MII_PHY_ID1_REG, &regvalId1);
		ixEthAccMiiReadRtn(i,  IX_ETH_MII_PHY_ID1_REG, &regvalId1);
		ixEthAccMiiReadRtn(i,  IX_ETH_MII_PHY_ID2_REG, &regvalId2);
		ixEthMiiPhyId[i] = (regvalId1 << IX_ETH_MII_REG_SHL) | regvalId2;
		if ((ixEthMiiPhyId[i] == IX_ETH_MII_KS8995_PHY_ID)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT971_PHY_ID)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT972_PHY_ID)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT973_PHY_ID)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT973A3_PHY_ID)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT9785_PHY_ID)
		    )
		{
		    /* supported phy */
		    phyPresent[i] = true;
		} /* end of if(ixEthMiiPhyId) */
		else
		{
		    if (ixEthMiiPhyId[i] != IX_ETH_MII_INVALID_PHY_ID)
		    {
			/* unsupported phy */
                        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
                                   IX_OSAL_LOG_DEV_STDOUT,
				    "ixEthMiiPhyScan : unexpected Mii PHY ID %8.8x\n", 
				    ixEthMiiPhyId[i], 2, 3, 4, 5, 6);
			ixEthMiiPhyId[i] = IX_ETH_MII_UNKNOWN_PHY_ID;
			phyPresent[i] = true;
		    }
		} 
	    }
	}
    }
    return IX_SUCCESS;
}

/************************************************************
 *
 * Configure the PHY at the specified address
 *
 */
PUBLIC IX_STATUS
ixEthMiiPhyConfig(UINT32 phyAddr,
		  BOOL speed100,
		  BOOL fullDuplex,
		  BOOL autonegotiate)
{
    UINT16 regval=0;

    /* parameter check */
    if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
	(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
    {
    /*
     * set the control register
     */
	if(autonegotiate)
	{
	    regval |= IX_ETH_MII_CR_AUTO_EN | IX_ETH_MII_CR_RESTART;
	}
	else
	{
	    if(speed100)
	    {
		regval |= IX_ETH_MII_CR_100;
	    }
	    if(fullDuplex)
	    {
		regval |= IX_ETH_MII_CR_FDX;
	    }
	} /* end of if-else() */
	if (ixEthAccMiiWriteRtn(phyAddr, 
				IX_ETH_MII_CTRL_REG, 
				regval) == IX_ETH_ACC_SUCCESS)
	{
	    return IX_SUCCESS;
	}
    } /* end of if(phyAddr) */
    return IX_FAIL;
}

/******************************************************************
 *
 *  Enable the PHY Loopback at the specified address
 */
PUBLIC IX_STATUS
ixEthMiiPhyLoopbackEnable (UINT32 phyAddr)
{
  UINT16 regval ;  

  if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) && 
      (IX_ETH_MII_INVALID_PHY_ID != ixEthMiiPhyId[phyAddr]))
  {
      /* read/write the control register */
      if(ixEthAccMiiReadRtn (phyAddr,
			     IX_ETH_MII_CTRL_REG, 
			     &regval) 
	 == IX_ETH_ACC_SUCCESS)
      {
	  if(ixEthAccMiiWriteRtn (phyAddr, 
				  IX_ETH_MII_CTRL_REG, 
				  regval | IX_ETH_MII_CR_LOOPBACK)
	     == IX_ETH_ACC_SUCCESS)
	  {
	      return IX_SUCCESS;
	  }
      }
  }
  return IX_FAIL;
}

/******************************************************************
 *
 *  Disable the PHY Loopback at the specified address
 */
PUBLIC IX_STATUS
ixEthMiiPhyLoopbackDisable (UINT32 phyAddr)
{
  UINT16 regval ;  

  if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) && 
      (IX_ETH_MII_INVALID_PHY_ID != ixEthMiiPhyId[phyAddr]))
  {
      /* read/write the control register */
      if(ixEthAccMiiReadRtn (phyAddr,
			     IX_ETH_MII_CTRL_REG, 
			     &regval) 
	 == IX_ETH_ACC_SUCCESS)
      {
	  if(ixEthAccMiiWriteRtn (phyAddr, 
				  IX_ETH_MII_CTRL_REG, 
				  regval & (~IX_ETH_MII_CR_LOOPBACK))
	     == IX_ETH_ACC_SUCCESS)
	  {
	      return IX_SUCCESS;
	  }
      }
  }
  return IX_FAIL;
}

/******************************************************************
 *
 *  Reset the PHY at the specified address
 */
PUBLIC IX_STATUS
ixEthMiiPhyReset(UINT32 phyAddr)
{
    UINT32 timeout;
    UINT16 regval;

    if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
	(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
    {
	if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID)	||
	    (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID)	||
	    (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973_PHY_ID)	||
	    (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973A3_PHY_ID)	||
		(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID)
	    )
	{
	    /* use the control register to reset the phy */
	    ixEthAccMiiWriteRtn(phyAddr, 
				IX_ETH_MII_CTRL_REG,
				IX_ETH_MII_CR_RESET);
	 
	    /* poll until the reset bit is cleared */
	    timeout = 0;
	    do
	    {
		ixOsalSleep (IX_ETH_MII_RESET_POLL_MS);

		/* read the control register and check for timeout */
		ixEthAccMiiReadRtn(phyAddr, 
				   IX_ETH_MII_CTRL_REG,
				   &regval);
		if ((regval & IX_ETH_MII_CR_RESET) == 0)
		{
		    /* timeout bit is self-cleared */
		    break;
		}
		timeout += IX_ETH_MII_RESET_POLL_MS;
	    }
	    while (timeout < IX_ETH_MII_RESET_DELAY_MS);

	    /* check for timeout */
	    if (timeout >= IX_ETH_MII_RESET_DELAY_MS)
	    {
		ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
				    IX_ETH_MII_CR_NORM_EN);
		return IX_FAIL;
	    }

	    return IX_SUCCESS;
	} /* end of if(ixEthMiiPhyId) */
	else if (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_KS8995_PHY_ID)
	{
	    /* reset bit is reserved, just reset the control register */
	    ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
				IX_ETH_MII_CR_NORM_EN);
	    return IX_SUCCESS;
	}
	else
	{
	    /* unknown PHY, set the control register reset bit,
	     * wait 2 s. and clear the control register.
	     */
	    ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
				IX_ETH_MII_CR_RESET);
	    
	    ixOsalSleep (IX_ETH_MII_RESET_DELAY_MS);
	    
	    ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
				IX_ETH_MII_CR_NORM_EN);
	    return IX_SUCCESS;
	} /* end of if-else(ixEthMiiPhyId) */
    } /* end of if(phyAddr) */
    return IX_FAIL;
}

/*****************************************************************
 *
 *  Link state query functions
 */

PUBLIC IX_STATUS
ixEthMiiLinkStatus(UINT32 phyAddr,
           BOOL *linkUp,
           BOOL *speed100,
           BOOL *fullDuplex,
           BOOL *autoneg)
{
    UINT16 ctrlRegval, statRegval, regval, regval4, regval5;

    /* check the parameters */
    if ((linkUp == NULL) || 
	(speed100 == NULL) || 
	(fullDuplex == NULL) ||
	(autoneg == NULL))
    {
	return IX_FAIL;
    }

    *linkUp = false;
    *speed100 = false;
    *fullDuplex = false;
    *autoneg = false;

    if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
	(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
    {
	if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID)	||
	    (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID)	||
	    (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID)
		)
	{
	    /* --------------------------------------------------*/
	    /* Retrieve information from PHY specific register   */
	    /* --------------------------------------------------*/
	    if (ixEthAccMiiReadRtn(phyAddr, 
				   IX_ETH_MII_STAT2_REG, 
				   &regval) != IX_ETH_ACC_SUCCESS)
	    {
		return IX_FAIL;
	    }
	    *linkUp = ((regval & IX_ETH_MII_SR2_LINK) != 0);
	    *speed100 = ((regval & IX_ETH_MII_SR2_100) != 0);
	    *fullDuplex = ((regval & IX_ETH_MII_SR2_FD) != 0);
	    *autoneg = ((regval & IX_ETH_MII_SR2_AUTO) != 0);
	    return IX_SUCCESS;
	} /* end of if(ixEthMiiPhyId) */
	else
	{    
	    /* ----------------------------------------------------*/
	    /* Retrieve information from status and ctrl registers */
	    /* ----------------------------------------------------*/
	    if (ixEthAccMiiReadRtn(phyAddr,  
				   IX_ETH_MII_CTRL_REG, 
				   &ctrlRegval) != IX_ETH_ACC_SUCCESS)
	    {
		return IX_FAIL;
	    }
	    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_MII_STAT_REG, &statRegval);
	    
	    *linkUp = ((statRegval & IX_ETH_MII_SR_LINK_STATUS) != 0);
	    if (*linkUp)
	    {
		*autoneg = ((ctrlRegval & IX_ETH_MII_CR_AUTO_EN) != 0) &&
		    ((statRegval &  IX_ETH_MII_SR_AUTO_SEL) != 0) &&
		    ((statRegval & IX_ETH_MII_SR_AUTO_NEG) != 0);
		
		if (*autoneg)
		{
		    /* mask the current stat values with the capabilities */
		    ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_ADS_REG, &regval4);
		    ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_PRTN_REG, &regval5);
		    /* merge the flags from the 3 registers */
		    regval = (statRegval & ((regval4 & regval5) << 6));
		    /* initialise from status register values */
		    if ((regval & IX_ETH_MII_SR_TX_FULL_DPX) != 0)
		    {
			/* 100 Base X full dplx */
			*speed100 = true;
			*fullDuplex = true;
			return IX_SUCCESS;
		    }
		    if ((regval & IX_ETH_MII_SR_TX_HALF_DPX) != 0)
		    {
			/* 100 Base X half dplx */
			*speed100 = true;
			return IX_SUCCESS;
		    }
		    if ((regval & IX_ETH_MII_SR_10T_FULL_DPX) != 0)
		    {
			/* 10 mb full dplx */
			*fullDuplex = true;
			return IX_SUCCESS;
		    }
		    if ((regval & IX_ETH_MII_SR_10T_HALF_DPX) != 0)
		    {
			/* 10 mb half dplx */
			return IX_SUCCESS;
		    }
		} /* end of if(autoneg) */
		else
		{
		    /* autonegotiate not complete, return setup parameters */
		    *speed100 = ((ctrlRegval & IX_ETH_MII_CR_100) != 0);
		    *fullDuplex = ((ctrlRegval & IX_ETH_MII_CR_FDX) != 0);
		}
	    } /* end of if(linkUp) */
	} /* end of if-else(ixEthMiiPhyId) */
    } /* end of if(phyAddr) */
    else
    {
	return IX_FAIL;
    } /* end of if-else(phyAddr) */
    return IX_SUCCESS;
}

/*****************************************************************
 *
 *  Link state display functions
 */

PUBLIC IX_STATUS
ixEthMiiPhyShow (UINT32 phyAddr)
{
    BOOL linkUp, speed100, fullDuplex, autoneg;
    UINT16 cregval;
    UINT16 sregval;
    

    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_MII_STAT_REG, &sregval);
    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_MII_CTRL_REG, &cregval);

    /* get link information */
    if (ixEthMiiLinkStatus(phyAddr,
			   &linkUp,
			   &speed100,
			   &fullDuplex,
			   &autoneg) != IX_ETH_ACC_SUCCESS)
    {
	printf("PHY Status unknown\n");
	return IX_FAIL;
    }

    printf("PHY ID [phyAddr]: %8.8x\n",ixEthMiiPhyId[phyAddr]);
    printf( " Status reg:  %4.4x\n",sregval);
    printf( " control reg: %4.4x\n",cregval);
    /* display link information */
    printf("PHY Status:\n");
    printf("    Link is %s\n",
	   (linkUp ? "Up" : "Down"));
    if((sregval & IX_ETH_MII_SR_REMOTE_FAULT) != 0)
    {
	printf("    Remote fault detected\n");
    }
    printf("    Auto Negotiation %s\n",
	   (autoneg ? "Completed" : "Not Completed"));

    printf("PHY Configuration:\n");
    printf("    Speed %sMb/s\n",
	   (speed100 ? "100" : "10"));
    printf("    %s Duplex\n",
	   (fullDuplex ? "Full" : "Half"));
    printf("    Auto Negotiation %s\n",
	   (autoneg ? "Enabled" : "Disabled"));
    return IX_SUCCESS;
}

