Exemple #1
0
/******************************************************************
 *
 *  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;
}
Exemple #2
0
/*********************************************************************
 * ixEthAccMiiWriteRtn - write a 16 bit value to a PHY
 */
IxEthAccStatus
ixEthAccMiiWriteRtn (UINT8 phyAddr, 
		     UINT8 phyReg, 
		     UINT16 value)
{
    UINT32 mdioCommand;
    UINT32 regval;
    UINT16 readVal;
    UINT32 miiTimeout;

    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
    {
	return (IX_ETH_ACC_FAIL);
    }

    if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR) 
	|| (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
    {
	return (IX_ETH_ACC_FAIL);
    }
   
    /* ensure that a PHY is present at this address */
    if(ixEthAccMiiReadRtn(phyAddr,
                          IX_ETH_ACC_MII_CTRL_REG,
                          &readVal) != IX_ETH_ACC_SUCCESS)
    {
        return (IX_ETH_ACC_FAIL);
    }

    ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
    mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL
	| phyAddr << IX_ETH_ACC_MII_ADDR_SHL ;
    mdioCommand |= IX_ETH_ACC_MII_GO | IX_ETH_ACC_MII_WRITE | value;

    ixEthAccMdioCmdWrite(mdioCommand);
    
    miiTimeout = ixEthAccMiiRetryCount;

    while(miiTimeout)
    {
	
	ixEthAccMdioCmdRead(&regval);

	/*The "GO" bit is reset to 0 when the write completes*/
	if((regval & IX_ETH_ACC_MII_GO) == 0x0)
	{	    	    
	    break;
	}
	/* Sleep for a while */
	ixOsalSleep(ixEthAccMiiAccessTimeout);
        miiTimeout--;
    }
    
    ixOsalMutexUnlock(&miiAccessLock);
    if(miiTimeout == 0)
    {
	return IX_ETH_ACC_FAIL;
    }
    return IX_ETH_ACC_SUCCESS;
}
Exemple #3
0
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;
}
Exemple #4
0
int npe_miiphy_read (const char *devname, unsigned char addr,
		     unsigned char reg, unsigned short *value)
{
	u16 val;

	ixEthAccMiiReadRtn(addr, reg, &val);
	*value = val;

	return 0;
}				/* phy_read */
Exemple #5
0
/*****************************************************************
 *
 *  Phy query functions
 *
 */
IxEthAccStatus
ixEthAccMiiStatsShow (UINT32 phyAddr)
{
    UINT16 regval;
    printf("Regisers on PHY at address 0x%x\n", phyAddr);
    ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_CTRL_REG, &regval);
    printf("    Control Register                  :      0x%4.4x\n", regval);
    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_STAT_REG, &regval);
    printf("    Status Register                   :      0x%4.4x\n", regval);
    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_PHY_ID1_REG, &regval);
    printf("    PHY ID1 Register                  :      0x%4.4x\n", regval);
    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_PHY_ID2_REG, &regval);
    printf("    PHY ID2 Register                  :      0x%4.4x\n", regval);
    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_AN_ADS_REG, &regval);
    printf("    Auto Neg ADS Register             :      0x%4.4x\n", regval);
    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_AN_PRTN_REG, &regval);
    printf("    Auto Neg Partner Ability Register :      0x%4.4x\n", regval);
    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_AN_EXP_REG, &regval);
    printf("    Auto Neg Expansion Register       :      0x%4.4x\n", regval);
    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_AN_NEXT_REG, &regval);
    printf("    Auto Neg Next Register            :      0x%4.4x\n", regval);

    return IX_ETH_ACC_SUCCESS;
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #8
0
/******************************************************************
 *
 *  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;
}
Exemple #9
0
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 > IXP400_ETH_ACC_MII_MAX_ADDR))
    {
	return IX_FAIL;
    }

                /* Gateworks added code to handle KS8995 Switch, Forces Phy 1 and 5 to be associated with
                         NPEA and NPEB respectively. This Code does not actually assign them as such, only tells
                         the calling function that PHY 1 and PHY 5 are available for use
                */
                ixEthAccMiiReadRtn(1,  IX_ETH_MII_PHY_ID1_REG, &regvalId1);
                ixEthAccMiiReadRtn(1,  IX_ETH_MII_PHY_ID1_REG, &regvalId1);
                ixEthAccMiiReadRtn(1,  IX_ETH_MII_PHY_ID2_REG, &regvalId2);
                if (((regvalId1 << IX_ETH_MII_REG_SHL) | regvalId2) == IX_ETH_MII_KS8995_PHY_ID)
                {
                        for (i=0; i <= IXP425_ETH_ACC_MII_MAX_ADDR; i++){
                                phyPresent[i] = FALSE;
                        }
                        ixEthMiiPhyId[1] = (regvalId1 << IX_ETH_MII_REG_SHL) | regvalId2;
                        ixEthMiiPhyId[5] = (regvalId1 << IX_ETH_MII_REG_SHL) | regvalId2;
                        phyPresent[1] = TRUE;
                        phyPresent[5] = TRUE;

                  ixEthAccMiiReadRtn(16,  IX_ETH_MII_PHY_ID1_REG, &regvalId1);
                  ixEthAccMiiReadRtn(16,  IX_ETH_MII_PHY_ID1_REG, &regvalId1);
                  ixEthAccMiiReadRtn(16,  IX_ETH_MII_PHY_ID2_REG, &regvalId2);
                  if (((regvalId1 << IX_ETH_MII_REG_SHL) | regvalId2) == IX_ETH_MII_DP83848_PHY_ID)
                  {
                        ixEthMiiPhyId[5] = FALSE;
                        ixEthMiiPhyId[16] = (regvalId1 << IX_ETH_MII_REG_SHL) | regvalId2;
                        phyPresent[16] = TRUE;
                        phyPresent[5] = FALSE;
                  }
                  return IX_SUCCESS;
                }

                /* End Gateworks Addition */

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

#ifndef IXDPG425
    /* iterate through the PHY addresses */
    for(i=0;
	maxPhyCount > 0 && i<IXP400_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)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_DP83848_PHY_ID)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_IP101A_PHY_ID)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_BCM5221_PHY_ID)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_BCM5241_PHY_ID)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_BCM5241B_PHY_ID)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_BCM5327_PHY_ID)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_RTL8021_PHY_ID)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_MARVELL_PHY_ID)
		    || (ixEthMiiPhyId[i] == IX_ETH_MII_AC101L_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;
		    }
		} 
	    }
	}
    }
#else
    /* RTL8305SB, on IXDPG425, does not have PHY ID registers */
    for(i=0;
        maxPhyCount > 0 && i<IXP400_ETH_ACC_MII_MAX_ADDR;
        i++)
    {
        if (i <= 5) 
        {
           ixEthMiiPhyId[i] = IX_ETH_MII_RTL8305_FAKE_PHY_ID; /* Pseudo PHY IDs */
           phyPresent[i] = TRUE;
        }
        else
        {
           ixEthMiiPhyId[i] = IX_ETH_MII_INVALID_PHY_ID;
        }
    }
#endif

    return IX_SUCCESS;
}
Exemple #10
0
PUBLIC IX_STATUS
ixEthMiiLinkStatus(UINT32 phyAddr,
           BOOL *linkUp,
           BOOL *speed100,
           BOOL *fullDuplex,
           BOOL *autoneg)
{
    UINT16 ctrlRegval, statRegval, regval, regval4, regval5;
	UINT16 K1, K2, K3, K4; /* Gateworks Added Variable to handle KS8995 Switch */
    /* 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 < IXP400_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)       ||
		(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_MARVELL_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;
	}
	else if (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_RTL8021_PHY_ID)
	    {
	    *linkUp=TRUE;
	    *speed100=TRUE;
	    *fullDuplex=TRUE;
	    /*
	    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 = ((regval & IX_ETH_MII_SR_LINK_STATUS) != 0);
	    if (*linkUp)
		{
		*autoneg = TRUE;
		ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_TEST_REG, &statRegval);
		    if ((statRegval & 0x01)!=0)
		    {
			*speed100 = TRUE;
		    }else if ((statRegval & 0x02)!=0)
		    {
			*speed100 = FALSE;
		    }else
		    {
		    *autoneg = FALSE;
		    }
		ixEthAccMiiReadRtn(phyAddr,  IX_ETH_MII_AN_PRTN_REG, &statRegval);
		if (TRUE == *speed100)
		{
		    if ((statRegval & IX_ETH_ACC_MII_AN_PRTN_100_DUP) != 0)
		    {
			*fullDuplex = TRUE;
		    }else
		    {
			*fullDuplex = FALSE;
		    }
		}else
		{
		    if ((statRegval & IX_ETH_ACC_MII_AN_PRTN_10_DUP) != 0)
		    {
			*fullDuplex = TRUE;
		    }else
		    {
			*fullDuplex = FALSE;
		    }
		}
		}    
	    */
	    }    
 /* 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);
                        /* Gateworks added link Status indicator for KS8898 Switch */
                        if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_KS8995_PHY_ID) && (phyAddr == 1))
                        {
                                ixEthAccMiiReadRtn(1, IX_ETH_MII_STAT_REG, &K1);
                                ixEthAccMiiReadRtn(2, IX_ETH_MII_STAT_REG, &K2);
                                ixEthAccMiiReadRtn(3, IX_ETH_MII_STAT_REG, &K3);
                                ixEthAccMiiReadRtn(4, IX_ETH_MII_STAT_REG, &K4);
                                if (((K1 & IX_ETH_MII_SR_LINK_STATUS) != 0) ||
                                        ((K2 & IX_ETH_MII_SR_LINK_STATUS) != 0) ||
                                        ((K3 & IX_ETH_MII_SR_LINK_STATUS) != 0) ||
                                        ((K4 & IX_ETH_MII_SR_LINK_STATUS) != 0))
                                {
                                        *linkUp = 1;
                                }
                                else
                                {
                                        *linkUp = 0;
                                }
                        }
                        /* End Gateworks Addition */	

	    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;
}