⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 miilib.c

📁 au1500开发的应用程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	regAddr = MII_AN_ADS_REG;

	MII_WRITE (phyAddr, regAddr, phyAds, retVal);
	if (retVal != OK)
	    return (ERROR);

	    MII_LOG (MII_DBG_ANY, ("miiAutoNegotiate phyAds=0x%x\n"),
				   phyAds, 0, 0, 0, 0, 0);

    /* set MSC register accordingly */

    if (pPhyInfo->phyFlags & MII_PHY_GMII_TYPE)
        {
        regAddr = MII_MASSLA_CTRL_REG;
        MII_WRITE (phyAddr, regAddr, phyMstSlaCtrl, retVal);
        if (retVal != OK)
            return (ERROR);
        }

	/* 
	 * start the auto-negotiation process: return
	 * only in case of fatal error.
	 */

	retVal = miiAutoNegStart (pPhyInfo, phyAddr);

	/* 
	 * in case of fatal error, we return immediately; otherwise,
	 * we try to recover from the failure, if we're not using 
	 * the standard auto-negotiation process.
	 */

	if (retVal == ERROR)
	    {
	    if (errno != S_miiLib_PHY_AN_FAIL)
		return (ERROR);

	    else
		{
		if (!(MII_PHY_FLAGS_ARE_SET (MII_PHY_TBL)))
		    return (ERROR);
		else
		    {
		    /* let's try the next entry in the table */

		    errno = 0;
		    continue;
		    }
		}
	    }

	/* check the negotiation was successful */

	if (miiAnCheck (pPhyInfo, phyAddr) == OK)
	    return (OK);

	/* 
	 * we are here if the negotiation went wong:
	 * if the auto-negotiation order table was not 
	 * used, we return ERROR, as all the PHY abilities
	 * were negotiated at once.
	 */

	if (!(MII_PHY_FLAGS_ARE_SET (MII_PHY_TBL)))
	    return (ERROR);
	}

    return (OK);
    }

/*******************************************************************************
*
* miiAutoNegStart - start the auto-negotiation process
*
* This routine starts the auto-negotiation process for the PHY whose
* address is specified in the parameter <phyAddr>.
*
* RETURNS: OK or ERROR.
*
* ERRNO: S_miiLib_PHY_AN_FAIL
*
*/

LOCAL STATUS miiAutoNegStart
    (
    PHY_INFO *  pPhyInfo,       /* pointer to PHY_INFO structure */
    UINT8	phyAddr		/* address of a PHY */
    )
    {
    UINT16	data;		/* data to be written to the control reg */
    UINT8	regAddr;	/* PHY register */
    UINT16	phyStatus;	/* holder for the PHY status */
    UINT16	ix = 0;		/* a counter */
    int		retVal;		/* convenient holder for return value */

    regAddr = MII_STAT_REG;

    MII_READ (phyAddr, regAddr, &phyStatus, retVal);
    if (retVal != OK)
	return (ERROR);

    MII_LOG (MII_DBG_ANY, ("miiAutoNegStart phy=0x%x reg=0x%x status=0x%x\n"),
			   phyAddr, regAddr, phyStatus, 0, 0, 0);

    /* check the PHY has this ability */

    if ((phyStatus & MII_SR_AUTO_SEL) != MII_SR_AUTO_SEL)
	{
	MII_LOG (MII_DBG_ANY, ("miiAutoNegStart phy not 
			       auto neg capable\n"), 
			       0, 0, 0, 0, 0, 0);

	return (ERROR);
	}

    /* restart the auto-negotiation process */

    regAddr = MII_CTRL_REG;
    data = (MII_CR_RESTART | MII_CR_AUTO_EN);

    MII_WRITE (phyAddr, regAddr, data, retVal);
    if (retVal != OK)
	return (ERROR);

    /* save status info */

    pPhyInfo->miiRegs.phyCtrl = data;

    /* let's check the PHY status for completion */

    regAddr = MII_STAT_REG;

    /* spin until it is done */

    do
	{
	MII_SYS_DELAY (pPhyInfo->phyDelayParm);

	if (ix++ == pPhyInfo->phyMaxDelay)
	    break;

	MII_READ (phyAddr, regAddr, &phyStatus, retVal);
	if (retVal != OK)
	    return (ERROR);

	} while ((phyStatus & MII_SR_AUTO_NEG) != MII_SR_AUTO_NEG);

    MII_LOG (MII_DBG_ANY, ("miiAutoNegStart auto neg attempts=%d \n"),
			   ix, 0, 0, 0, 0, 0);

    if (ix >= pPhyInfo->phyMaxDelay)
	{
	MII_LOG (MII_DBG_ANY, ("miiAutoNegStart auto neg fail\n"),
			       0, 0, 0, 0, 0, 0);
	errnoSet (S_miiLib_PHY_AN_FAIL);
	return (ERROR);
	}
    else
	{
	MII_LOG (MII_DBG_ANY, ("miiAutoNegStart auto neg done phyStat=0x%x\n"),
			       phyStatus, 0, 0, 0, 0, 0);
	}

    return (OK);
    }

/*******************************************************************************
*
* miiBasicCheck - run a basic check on the PHY status register
*
* This routine runs a basic check on the PHY status register to
* ensure a valid link has been established and no faults have been 
* detected.
*
* RETURNS: OK or ERROR.
*
*/

LOCAL STATUS miiBasicCheck
    (
    PHY_INFO *  pPhyInfo,       /* pointer to PHY_INFO structure */
    UINT8	phyAddr		/* address of a PHY */
    )
    {
    UINT8	regAddr;	/* PHY register */
    UINT16	phyStatus;	/* holder for the PHY status */
    UINT16	ix = 0;		/* a counter */
    int		retVal;		/* convenient holder for return value */
    /* let's check the PHY status for completion */

    regAddr = MII_STAT_REG;

    /* spin until it is done */

    do
	{
 	MII_SYS_DELAY (sysClkRateGet());
        ix += sysClkRateGet(); 

	if (ix >= pPhyInfo->phyMaxDelay)
	    break;

	MII_READ (phyAddr, regAddr, &phyStatus, retVal); 
	   if (retVal != OK)
	    return (ERROR);

	} while ((phyStatus & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS); 

    if (ix >= pPhyInfo->phyMaxDelay)
	{
	MII_LOG (MII_DBG_ANY, ("miiBasicCheck fail\n"),
			       0, 0, 0, 0, 0, 0);
	return (ERROR);
	}

    MII_LOG (MII_DBG_ANY, ("miiBasicCheck Link up! status=0x%x\n"),
			   phyStatus, 0, 0, 0, 0, 0);

    /* check for remote fault condition, read twice */

    MII_READ (phyAddr, regAddr, &phyStatus, retVal);
    if (retVal != OK)
	return (ERROR);

    MII_READ (phyAddr, regAddr, &phyStatus, retVal);
    if (retVal != OK)
	return (ERROR);

    if ((phyStatus & MII_SR_REMOTE_FAULT) == MII_SR_REMOTE_FAULT)
	{
	MII_LOG (MII_DBG_ANY, ("miiBasicCheck remote fault\n"),
			       0, 0, 0, 0, 0, 0);
	return (ERROR);
	}

    /* store the current registers values */

    pPhyInfo->miiRegs.phyStatus = phyStatus;

    return (OK);
    }

/*******************************************************************************
*
* miiFlagsHandle - handle some flags
*
* This routine sets some fields in the PHY_INFO structure according to the
* values of the related flags.
*
* RETURNS: OK, always.
*/

LOCAL STATUS miiFlagsHandle
    (
    PHY_INFO *  pPhyInfo,       /* pointer to PHY_INFO structure */
    UINT8	phyAddr		/* address of a PHY */
    )
    {

    /* check speed ... */ 

    if (MII_PHY_FLAGS_ARE_SET (MII_PHY_1000T_FD) || 
        MII_PHY_FLAGS_ARE_SET (MII_PHY_1000T_HD))
        pPhyInfo->phySpeed = MII_1000MBS;

    else if (MII_PHY_FLAGS_ARE_SET (MII_PHY_100))
	pPhyInfo->phySpeed = MII_100MBS;
    else
	pPhyInfo->phySpeed = MII_10MBS;
 

    if (MII_PHY_FLAGS_ARE_SET (MII_PHY_FD))
        {
        bcopy (MII_FDX_STR, (char *) pPhyInfo->phyMode, MII_FDX_LEN);
        }
    else
        {
        bcopy (MII_HDX_STR, (char *) pPhyInfo->phyMode, MII_HDX_LEN);
        }

    MII_LOG (MII_DBG_ANY, ("miiFlagsHandle speed=%d mode=%s\n"),
			   pPhyInfo->phySpeed, 
			   (char *) pPhyInfo->phyMode, 0, 0, 0, 0);

    return (OK);
    }

/*******************************************************************************
*
* miiPhyUpdate - update the phyInfo structure to the latest PHY status
*
* This routine updates the phyInfo structure to the latest PHY status.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS miiPhyUpdate
    (
    PHY_INFO *  pPhyInfo,       /* pointer to PHY_INFO structure */
    UINT8	phyAddr		/* address of a PHY */
    )
    {
    UINT16	phyStatus;	/* holder for the PHY status */
    UINT16	phyAds;		/* PHY advertisement register value */
    UINT16	phyPrtn;	/* PHY partner ability register value */
    UINT16	phyExp;		/* PHY expansion register value */
    UINT16  phyMstSlaCtrl; /* PHY Master-slave Control value */
    UINT16  phyMstSlaStat; /* PHY Master-slave Status value */
    UINT16	negAbility;	/* abilities after negotiation */
    int		retVal;		/* convenient holder for return value */

    MII_READ (phyAddr, MII_STAT_REG, &phyStatus, retVal);
    if (retVal == ERROR)
	return (ERROR);

    /* does the PHY support the extended registers set? */

    if (!(phyStatus & MII_SR_EXT_CAP))
	return (OK);

    MII_READ (phyAddr, MII_AN_ADS_REG, &phyAds, retVal);
    if (retVal == ERROR)
	return (ERROR);

    MII_READ (phyAddr, MII_AN_PRTN_REG, &phyPrtn, retVal);
    if (retVal == ERROR)
	return (ERROR);

    MII_READ (phyAddr, MII_AN_EXP_REG, &phyExp, retVal);
    if (retVal == ERROR)
	return (ERROR);

    /* flow control configuration */

    /* MII defines symmetric PAUSE ability */

    if ((!(phyAds & MII_ANAR_PAUSE)) || (!(phyPrtn & MII_TECH_PAUSE)))
        pPhyInfo->phyFlags &= ~(MII_PHY_TX_FLOW_CTRL | MII_PHY_RX_FLOW_CTRL); 
    else
        pPhyInfo->phyFlags |= (MII_PHY_TX_FLOW_CTRL | MII_PHY_RX_FLOW_CTRL); 

    if (pPhyInfo->phyFlags & MII_PHY_GMII_TYPE)
        {

        /* GMII also defines asymmetric PAUSE ability */

        /* Advertises transmitter but no receiver */

        if (((phyAds & MII_ANAR_PAUSE_MASK) == MII_ANAR_ASM_PAUSE) &&
             ((phyPrtn & MII_TECH_PAUSE_MASK) == MII_TECH_PAUSE_MASK))
            {
            pPhyInfo->phyFlags |= MII_PHY_TX_FLOW_CTRL;
            }

        /* Advertises receiver but no transmitter */

        else if (((phyAds & MII_ANAR_PAUSE_MASK) == MII_ANAR_PAUSE_MASK) &&
            ((phyPrtn & MII_TECH_PAUSE_MASK) == MII_TECH_ASM_PAUSE))
            {
            pPhyInfo->phyFlags |= MII_PHY_RX_FLOW_CTRL;
            }

        /* no flow control */

        else if ((!(phyAds & MII_ANAR_PAUSE)) || (!(phyPrtn & MII_TECH_PAUSE)))
            {
            pPhyInfo->phyFlags &= ~(MII_PHY_TX_FLOW_CTRL | 
                                       MII_PHY_RX_FLOW_CTRL);
            }
        /* TX and RX flow control */

        else
            {
            pPhyInfo->phyFlags |= (MII_PHY_TX_FLOW_CTRL | MII_PHY_RX_FLOW_CTRL);
            }
        }

    /* find out the max common abilities */

    if (pPhyInfo->phyFlags & MII_PHY_GMII_TYPE)
        {
        /* search for 1000T capbility */

        /* get MASTER-SLAVE control register */

        MII_READ (phyAddr, MII_MASSLA_CTRL_REG, &phyMstSlaCtrl, retVal);
        if (retVal == ERROR)
            return (ERROR);

        /* get MASTER-SLAVE status register */

        MII_READ (phyAddr, MII_MASSLA_STAT_REG, &phyMstSlaStat, retVal);
        if (retVal == ERROR)
            return (ERROR);

        MII_READ (phyAddr, MII_MASSLA_STAT_REG, &phyMstSlaStat, retVal);
        if (retVal == ERROR)
            return (ERROR);

        if ((phyMstSlaStat & MII_MASSLA_STAT_LP1000T_FD) && 
            (phyMstSlaCtrl & MII_MASSLA_CTRL_1000T_FD))
            {
            /* 1000T FD supported */
             
            MII_PHY_FLAGS_SET (MII_PHY_FD);
            goto exitPhyUpdate;
            }
        else if ((phyMstSlaStat & MII_MASSLA_STAT_LP1000T_HD) && 
                 (phyMstSlaCtrl & MII_MASSLA_CTRL_1000T_HD))
            {
               /* 1000T HD supported */
                 
            MII_PHY_FLAGS_SET (MII_PHY_HD);
            MII_PHY_FLAGS_CLEAR (MII_PHY_1000T_FD);
            goto exitPhyUpdate;
            }
        else
            {
            /* 1000T not supported, go check other abilities */

            MII_PHY_FLAGS_CLEAR (MII_PHY_1000T_FD); 
            MII_PHY_FLAGS_CLEAR (MII_PHY_1000T_HD);
            }
        }


    negAbility = phyPrtn & phyAds & MII_ADS_TECH_MASK;

    MII_LOG (MII_DBG_ANY, ("miiPhyUpdate phyAds=0x%x
			   phyPrtn=0x%x common=0x%x phyExp=0x%x\n"),
			   phyAds, 
			   phyPrtn, 
			   negAbility, 
			   phyExp, 0, 0);

    if (negAbility & MII_TECH_100BASE_TX_FD)
	{
	}
    else if ((negAbility & MII_TECH_100BASE_TX) ||
	 (negAbility & MII_TECH_100BASE_T4))
	{
	MII_PHY_FLAGS_CLEAR (MII_PHY_FD);
	}
    else if (negAbility & MII_TECH_10BASE_FD)
	{
	MII_PHY_FLAGS_CLEAR (MII_PHY_100); 
	}
    else if (negAbility & MII_TECH_10BASE_T)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -