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

📄 miilib.c

📁 au1500开发的应用程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	{
	MII_PHY_FLAGS_CLEAR (MII_PHY_FD);
	MII_PHY_FLAGS_CLEAR (MII_PHY_100); 
	}
    else
	{
	MII_LOG (MII_DBG_ANY, ("miiPhyUpdate fail!\n"),
			       0, 0, 0, 0, 0, 0);
	return (ERROR);
	}

    /* store the current registers values */

exitPhyUpdate:

    pPhyInfo->miiRegs.phyStatus = phyStatus;
    pPhyInfo->miiRegs.phyAds = phyAds;
    pPhyInfo->miiRegs.phyPrtn = phyPrtn;
    pPhyInfo->miiRegs.phyExp = phyExp;

    if (pPhyInfo->phyFlags & MII_PHY_GMII_TYPE)
        {    
        pPhyInfo->miiGRegs.phyMSStatus = phyMstSlaStat;
        pPhyInfo->miiGRegs.phyMSCtrl = phyMstSlaCtrl;
        }

    /* handle some flags */

    if (miiFlagsHandle (pPhyInfo, phyAddr) != OK)
	return (ERROR);

    return (OK);
    }

/*******************************************************************************
*
* miiAnCheck - check the auto-negotiation process result
*
* This routine checks the auto-negotiation process has completed
* successfully and no faults have been detected by any of the PHYs 
* engaged in the process.
*
* NOTE: 
* In case the cable is pulled out and reconnect to the same/different 
* hub/switch again. PHY probably starts a new auto-negotiation process and 
* get different negotiation results. User should call this routine to check 
* link status and update phyFlags. pPhyInfo should include a valid 
* PHY bus number (phyAddr), and include the phyFlags that was used last time 
* to configure auto-negotiation process.
*
* RETURNS: OK or ERROR.
*/

STATUS miiAnCheck
    (
    PHY_INFO *  pPhyInfo,       /* pointer to PHY_INFO structure */
    UINT8	phyAddr		/* address of a PHY */
    )
    {
    UINT8	regAddr;	/* PHY register */
    UINT16	phyPrtn;	/* PHY partner ability register value */
    UINT16	phyExp;		/* PHY expansion register value */
    int		retVal;		/* convenient holder for return value */


    /* 
     * The sysClkRate could have changed since  the link was lost. 
     * Ensure that pPhyInfo->phyMaxDelay is at lease 5 seconds. 
     */

    if (pPhyInfo->phyMaxDelay < (sysClkRateGet() * 5))
        {
        /* Set max delay porportionally */

        pPhyInfo->phyMaxDelay = sysClkRateGet() * 5;
        }

    /* run a check on the status bits of basic registers only */

    retVal = miiBasicCheck (pPhyInfo, phyAddr);
    if (retVal != OK)
	return (retVal);

    /* we know the auto-negotiation process has finished */

    regAddr = MII_AN_EXP_REG;

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

    /* check for faults detected by the parallel function */

    if ((phyExp & MII_EXP_FAULT) == MII_EXP_FAULT)
	{
	MII_LOG (MII_DBG_ANY, ("miiAnCheck: fault expStat=0x%x\n"),
			       phyExp, 0, 0, 0, 0, 0);

	/*
	 * Don't fail here as some PHY devices don't support this register,
	 * but seem to return 0xffff when it is read (jgn - 5/8/00)
	 */

	/* return (ERROR); */
	}

    /* check for remote faults */

    regAddr = MII_AN_PRTN_REG;

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

    if ((phyPrtn & MII_BP_FAULT) == MII_BP_FAULT)
	{
	MII_LOG (MII_DBG_ANY, ("miiAnCheck partner stat=0x%x\n"),
			       phyPrtn, 0, 0, 0, 0, 0);

	return (ERROR);
	}

    if (miiPhyUpdate (pPhyInfo, phyAddr) == ERROR)
	{
	MII_LOG (MII_DBG_ANY, "miiPhyUpdate error\n",0,0,0,0,0,0);
	return (ERROR);
	}

    MII_LOG (MII_DBG_ANY, ("miiAnCheck OK\n"),
			   0, 0, 0, 0, 0, 0);

    return (OK);
    }

/*******************************************************************************
*
* miiModeForce - force an operating mode for the PHY
*
* This routine forces an operating mode for the PHY whose address is 
* specified in the parameter <phyAddr>. It also calls miiBasicCheck() 
* to ensure a valid link has been established.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS miiModeForce
    (
    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 */
    int		retVal;		/* convenient holder for return value */

    MII_LOG (MII_DBG_ANY, ("miiModeForce \n"),
			   0, 0, 0, 0, 0, 0);

    /*
     * force as a high priority as possible operating
     * mode, not overlooking what the user dictated.
     */
 
    data = MII_CR_NORM_EN;
 
    if (MII_PHY_FLAGS_ARE_SET (MII_PHY_100))
        {
        data |= MII_CR_100;
        }
 
    if (MII_PHY_FLAGS_ARE_SET (MII_PHY_FD))
        {
        data |= MII_CR_FDX;
        }
 
    pPhyInfo->miiRegs.phyCtrl = data;
 
    regAddr = MII_CTRL_REG;
 
    /* try to establish the link */

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

    /* run a check on the status bits of basic registers only */

    if (miiBasicCheck (pPhyInfo, phyAddr) != OK)
	return (ERROR);

    /* handle some flags */

    if (miiFlagsHandle (pPhyInfo, phyAddr) != OK)
	return (ERROR);

    return (OK);
    }

/*******************************************************************************
*
* miiDefForce - force a default operating mode for the PHY
*
* This routine forces a default operating mode for the PHY whose address is 
* specified in the parameter <phyAddr>. It also calls miiBasicCheck() 
* to ensure a valid link has been established.
*
* RETURNS: OK or ERROR.
*
* ERRNO: S_miiLib_PHY_NO_ABLE
*
*/

LOCAL STATUS miiDefForce
    (
    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 */
    int		retVal;		/* convenient holder for return value */
    UINT16	phyStatus;	/* holder for the PHY status */

    MII_LOG (MII_DBG_ANY, ("miiDefForce \n"),
			   0, 0, 0, 0, 0, 0);

    /* translate user settings */

    data = miiDefLookupTbl [(pPhyInfo->phyDefMode)];

    /* find out what abilities the PHY features */
 
    regAddr = MII_STAT_REG;
    MII_READ (phyAddr, regAddr, &phyStatus, retVal);
    if (retVal == ERROR)
	return (ERROR);

    if (data & MII_CR_100) 
	{
	if (!(phyStatus & (MII_SR_TX_HALF_DPX
			   | MII_SR_TX_FULL_DPX
			   | MII_SR_T4)))
	    {
	    errnoSet (S_miiLib_PHY_NO_ABLE);
	    return (ERROR); 
	    }

	MII_PHY_FLAGS_SET (MII_PHY_100);
	}
    else
	{
	if (!(phyStatus & (MII_SR_10T_HALF_DPX 
			 | MII_SR_10T_FULL_DPX)))
	    {
	    errnoSet (S_miiLib_PHY_NO_ABLE);
	    return (ERROR); 
	    }
	MII_PHY_FLAGS_CLEAR (MII_PHY_100);
	}

    if (data & MII_CR_FDX)
	{
	if (!(phyStatus & (MII_SR_10T_FULL_DPX 
			 | MII_SR_TX_FULL_DPX)))
	    {
	    errnoSet (S_miiLib_PHY_NO_ABLE);
	    return (ERROR); 
	    }

	MII_PHY_FLAGS_SET (MII_PHY_FD);
	}
    else
	{
	if (!(phyStatus & (MII_SR_10T_HALF_DPX 
			 | MII_SR_TX_HALF_DPX)))
	    {
	    errnoSet (S_miiLib_PHY_NO_ABLE);
	    return (ERROR); 
	    }
	MII_PHY_FLAGS_CLEAR (MII_PHY_FD); 
	}

    pPhyInfo->miiRegs.phyCtrl = data;

    regAddr = MII_CTRL_REG;

    /* force this specific operating mode, but do not check the link */

    MII_WRITE (phyAddr, regAddr, data, retVal);

    /* handle some flags */

    if (miiFlagsHandle (pPhyInfo, phyAddr) != OK)
	return (ERROR);

    return (OK);
    }

/**************************************************************************
*
* miiAbilFlagSet - set some ability flags 
*
* This routine sets some ability flags for a later use.
*
* RETURNS: OK, always.
*/

LOCAL STATUS miiAbilFlagSet
    (
    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	phyExtStat;     /* holder for the PHY Extended status */
    int		retVal;		/* convenient holder for return value */

    /* find out what abilities the PHY features */
 
    regAddr = MII_STAT_REG;
    MII_READ (phyAddr, regAddr, &phyStatus, retVal);
    if (retVal == ERROR)
	return (ERROR);

    /* handle phy flags */

    if (!(phyStatus & (MII_SR_TX_HALF_DPX 
		       | MII_SR_TX_FULL_DPX
		       | MII_SR_T4)))
	{
	MII_PHY_FLAGS_CLEAR (MII_PHY_100);
	}

    if (!(phyStatus & (MII_SR_10T_FULL_DPX 
		     | MII_SR_TX_FULL_DPX)))
	{
	MII_PHY_FLAGS_CLEAR (MII_PHY_FD);
	}

    if (!(phyStatus & (MII_SR_10T_HALF_DPX 
		     | MII_SR_10T_FULL_DPX)))
	{
	MII_PHY_FLAGS_CLEAR (MII_PHY_10);
	}

    if (!(phyStatus & (MII_SR_TX_HALF_DPX 
		     | MII_SR_10T_HALF_DPX)))
	{
	MII_PHY_FLAGS_CLEAR (MII_PHY_HD);
	}

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

	MII_PHY_FLAGS_CLEAR (MII_PHY_AUTO);
	}

    if (pPhyInfo->phyFlags & MII_PHY_GMII_TYPE)
        {
        regAddr = MII_EXT_STAT_REG;
        MII_READ (phyAddr, regAddr, &phyExtStat, retVal);
        if (retVal != OK)
            return (ERROR);
 
        /* mask off 1000T FD if PHY not supported */

        if (!(phyExtStat & MII_EXT_STAT_1000T_HD))
             MII_PHY_FLAGS_CLEAR (MII_PHY_1000T_HD);

        /* mask off 1000T HD if PHY not supported */

        if (!(phyExtStat & MII_EXT_STAT_1000T_FD))
             MII_PHY_FLAGS_CLEAR (MII_PHY_1000T_FD);
        }

    return (OK);
    }

/**************************************************************************
*
* miiPhyOptFuncMultiSet - set pointers to MII optional registers handlers
*
* This routine sets the function pointers in <pPhyInfo->optRegsFunc> to the 
* MII optional, PHY-specific registers handler. The handler will be executed
* before the PHY's technology abilities are negotiated. If a system employees
* more than on type of network device requiring a PHY-specific registers 
* handler use this routine instead of miiPhyOptFuncSet() to ensure device
* specific handlers and to avoid overwritting one's with the other's. 
*
* PROTECTION DOMAINS
* (VxAE) This function can only be called from within the kernel protection
* domain. The argument optRegsFunc MUST be a pointer to function in the kernel
* protection domain.
*
* RETURNS: N/A.
*/

void miiPhyOptFuncMultiSet
    (
    PHY_INFO * pPhyInfo,	/* device specific pPhyInfo pointer */ 
    FUNCPTR    optRegsFunc      /* function pointer */
    )
    {
    if (optRegsFunc != NULL)
        pPhyInfo->pPhyOptRegsRtn = optRegsFunc;
    else
        pPhyInfo->pPhyOptRegsRtn = NULL;

    }

/**************************************************************************
*
* miiPhyOptFuncSet - set the pointer to the MII optional registers handler
*
* This routine sets the function pointer in <optRegsFunc> to the MII 
* optional, PHY-specific registers handler. The handler will be executed 
* before the PHY's technology abilities are negotiated.
*
* PROTECTION DOMAINS
* (VxAE) This function can only be called from within the kernel protection
* domain. The argument optRegsFunc MUST be a pointer to function in the kernel
* protection domain.
*
* RETURNS: N/A.
*/
 
void miiPhyOptFuncSet
    (
    FUNCPTR    optRegsFunc      /* function pointer */
    )
    {
    if (optRegsFunc != NULL)
	pPhyOptRegsRtn = optRegsFunc;
    else
	pPhyOptRegsRtn = NULL;

    }

/**************************************************************************
*
* miiPhyMonitorStart - monitor all the PHYs to detect a status change
*
* This routine monitors all the PHYs to detect a status change.
*

⌨️ 快捷键说明

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