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

📄 miilib.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
    }/********************************************************************************* miiPhyLinkSet - set the link for a PHY** This routine sets the link for the PHY pointed to by <pPhyInfo>. To do* so, it calls miiPhyBestModeSet (). Upon success it returns OK.* Otherwise, it checks whether other PHYs are on the bus, and attempts at* establishing a link for them starting from the first and scanning the * whole range. In case of failure, ERROR is returned.** SEE ALSO: miiPhyBestModeSet ().* * RETURNS: OK or ERROR.** ERRNO: S_miiLib_PHY_LINK_DOWN**/LOCAL STATUS miiPhyLinkSet    (    PHY_INFO *  pPhyInfo        /* pointer to PHY_INFO structure */    )    {    UINT16	ix;		/* a counter */    UINT8	phyAddr;	/* address of a PHY */    UINT32	phyFlags;	/* default PHY's flags */    /* store the default phy's flags */    phyFlags = pPhyInfo->phyFlags;    for (ix = 0; ix < MII_MAX_PHY_NUM; ix++)	{	phyAddr = (ix + pPhyInfo->phyAddr) % MII_MAX_PHY_NUM;	MII_LOG (MII_DBG_ANY, ("miiPhyLinkSet phyAddr=0x%x \n"),			       phyAddr, 0, 0, 0, 0, 0);	if (* ((BOOL *) pPhyInfo->miiPhyPresent + phyAddr) == FALSE)	    continue;	/* add this PHY to the linked list */	if (miiPhyListAdd (pPhyInfo) == ERROR)	    return (ERROR);	MII_LOG (MII_DBG_ANY, ("miiPhyLinkSet phyAddr=0x%x pres=0x%x \n"),			       phyAddr, 			       (* ((BOOL *) pPhyInfo->miiPhyPresent + phyAddr)),			       0, 0, 0, 0);	/* find out the PHY's abilities and set flags accordingly */	if (miiAbilFlagSet (pPhyInfo, phyAddr) != OK)	    return (ERROR);        /* we need this phyAddr before we call pPhyOptRegsRtn */        pPhyInfo->phyAddr = phyAddr;	/* 	 * check with the BSP if we need to do something else before	 * we try and establish the link 	 */        if (pPhyInfo->pPhyOptRegsRtn != NULL)            (* pPhyInfo->pPhyOptRegsRtn) (pPhyInfo);        else	    if (pPhyOptRegsRtn != NULL)	        (* pPhyOptRegsRtn) (pPhyInfo);        /* initialize phyLinkMethod */        if (pPhyInfo->phyFlags & MII_PHY_GMII_TYPE)            {            pPhyInfo->phyLinkMethod = MII_PHY_LINK_UNKNOWN;            } 	/* establist the link */	if (miiPhyBestModeSet (pPhyInfo, phyAddr) == OK)	    {	    return (OK);	    }	/* restore the default flags, miiAbilFlagSet may have changed them */	pPhyInfo->phyFlags = phyFlags;	}    /* set errno, since we did not establish a valid link */    errnoSet (S_miiLib_PHY_LINK_DOWN);    return (ERROR);    }/********************************************************************************* miiPhyDefModeSet - set the default operating mode for a PHY** This routine sets the default operating mode for a PHY looking at the * parameters in <pPhyInfo>. It calls miiDefForce () for each PHY found.** SEE ALSO: miiDefForce ().* * RETURNS: OK or ERROR.**/LOCAL STATUS miiPhyDefModeSet    (    PHY_INFO *  pPhyInfo        /* pointer to PHY_INFO structure */    )    {    UINT16	ix;		/* a counter */    int		retVal;		/* holder for return value */    UINT8	phyAddr;	/* address of a PHY */    /* try to establish a default operating mode, do not check the link! */    for (ix = 0; ix < MII_MAX_PHY_NUM; ix++)	{	phyAddr = (ix + pPhyInfo->phyAddr) % MII_MAX_PHY_NUM;	/* check the PHY is there */	if (* ((BOOL *) pPhyInfo->miiPhyPresent + phyAddr) == FALSE)	    continue;	/* 	 * Force default parameters: field phyDefMode in the PHY info 	 * structure. Return OK even if the link is not up.	 */	retVal = miiDefForce (pPhyInfo, phyAddr);	if (retVal == OK) 	    {	    /* store this PHY and return */	    pPhyInfo->phyAddr = phyAddr;	    MII_PHY_FLAGS_SET (MII_PHY_INIT);	    return (OK);	    }	/* if the PHY does not have the default abilities... */	if (errno == S_miiLib_PHY_NO_ABLE)	    {	    if (ix == (MII_MAX_PHY_NUM - 1))		return (ERROR);	    errno = 0;	    continue;	    }	}    return (ERROR);    }/********************************************************************************* miiAutoNegotiate - run the auto-negotiation process** This routine runs the auto-negotiation process for the PHY whose* address is specified in the parameter <phyAddr>, without enabling the * next page function. It also calls miiAnCheck() to ensure* a valid link has been established.** RETURNS: OK or ERROR.*/LOCAL STATUS miiAutoNegotiate    (    PHY_INFO *  pPhyInfo,  /* pointer to PHY_INFO structure */    UINT8	phyAddr        /* address of a PHY */    )    {    UINT8	regAddr;       /* PHY register */    UINT16	phyAds;        /* holder for the PHY ads register value */    UINT16	status;        /* PHY auto-negotiation status */    UINT16	ix;            /* a counter */    int		retVal;        /* holder for return value */    UINT16	phyStat;       /* PHY auto-negotiation status */    UINT16  phyMstSlaCtrl; /* PHY Mater-slave Control */    UINT16  phyExtStat;    /* PHY extented status */    /* save phyFlags for phyAutoNegotiateFlags */    if (pPhyInfo->phyFlags & MII_PHY_GMII_TYPE)        {        pPhyInfo->phyAutoNegotiateFlags = pPhyInfo->phyFlags;         }    /* Read ANER to clear status from previous operations */      regAddr = MII_AN_EXP_REG;    MII_READ (phyAddr, regAddr, &status, retVal);    if (retVal != OK)	return (ERROR);    /*      * copy the abilities in ANSR to ANAR. This is necessary because     * according to the 802.3 standard, the technology ability     * field in ANAR "is set based on the value in the MII status     * register or equivalent". What does "equivalent" mean?     */     regAddr = MII_AN_ADS_REG;    MII_READ (phyAddr, regAddr, &phyAds, retVal);    if (retVal != OK)	return (ERROR);    MII_LOG (MII_DBG_ANY, ("miiAutoNegotiate phyAds=0x%x expStat=0x%x \n"),			   phyAds, status, 0, 0, 0, 0);    regAddr = MII_STAT_REG;    MII_READ (phyAddr, regAddr, &phyStat, retVal);    if (retVal != OK)        return (ERROR);     MII_FROM_ANSR_TO_ANAR (phyStat, phyAds);    /* also disable the next page function */    phyAds &= (~MII_NP_NP);    MII_LOG (MII_DBG_ANY, ("miiAutoNegotiate write to ANAR=0x%x\n"),                           phyAds, 0, 0, 0, 0, 0);     /* configure flow control */    /* MII defines symmetric PAUSE ability */     if ((MII_PHY_FLAGS_ARE_SET (MII_PHY_TX_FLOW_CTRL)) &&                (MII_PHY_FLAGS_ARE_SET (MII_PHY_RX_FLOW_CTRL)))        phyAds |= MII_ANAR_PAUSE;    else        phyAds &= ~MII_ANAR_PAUSE;    if (pPhyInfo->phyFlags & MII_PHY_GMII_TYPE)        {        /* GMII also defines asymmetric PAUSE ability */        if (!(MII_PHY_FLAGS_ARE_SET (MII_PHY_TX_FLOW_CTRL)) &&                !(MII_PHY_FLAGS_ARE_SET (MII_PHY_RX_FLOW_CTRL)))             {             /* not flow control */             phyAds &= ~MII_ANAR_ASM_PAUSE;             phyAds &= ~MII_ANAR_PAUSE;             }         else if ((MII_PHY_FLAGS_ARE_SET (MII_PHY_TX_FLOW_CTRL)) &&                     !(MII_PHY_FLAGS_ARE_SET (MII_PHY_RX_FLOW_CTRL)))             {             /* TX flow control */             phyAds |= MII_ANAR_ASM_PAUSE;             phyAds &= ~MII_ANAR_PAUSE;             }         else                 {             /* RX flow control */             phyAds |= MII_ANAR_ASM_PAUSE;             phyAds |= MII_ANAR_PAUSE;             }         }    /* write ANAR */    regAddr = MII_AN_ADS_REG;    MII_WRITE (phyAddr, regAddr, phyAds, retVal);    if (retVal != OK)	return (ERROR);     /* store the current registers values */    pPhyInfo->miiRegs.phyAds = phyAds;        if (pPhyInfo->phyFlags & MII_PHY_GMII_TYPE)        {        /* get Master-Slave Control (MSC) Register */        regAddr =  MII_MASSLA_CTRL_REG;        MII_READ (phyAddr, regAddr, &phyMstSlaCtrl, retVal);        if (retVal != OK)            return (ERROR);        /* get extended status register */        regAddr = MII_EXT_STAT_REG;        MII_READ (phyAddr, regAddr, &phyExtStat, retVal);        if (retVal != OK)            return (ERROR);             /* set MSC register value based on PHY ability on EXTS */           phyMstSlaCtrl = (phyExtStat & MII_EXT_STAT_1000T_HD) ?                        (phyMstSlaCtrl | MII_MASSLA_CTRL_1000T_HD) :                        (phyMstSlaCtrl & ~MII_MASSLA_CTRL_1000T_HD);        phyMstSlaCtrl = (phyExtStat & MII_EXT_STAT_1000T_FD) ?                        (phyMstSlaCtrl | MII_MASSLA_CTRL_1000T_FD) :                        (phyMstSlaCtrl & ~MII_MASSLA_CTRL_1000T_FD);                                           /* write MSC register value */        regAddr = MII_MASSLA_CTRL_REG;        MII_WRITE (phyAddr, regAddr, phyMstSlaCtrl, retVal);        if (retVal != OK)            return (ERROR);        /* store the current registers values */        pPhyInfo->miiGRegs.phyMSCtrl = phyMstSlaCtrl;        }    /*      * start the auto-negotiation process, possibly     * following the order the user dictated.     */    for (ix = 0; ; ix++)	{	if (MII_PHY_FLAGS_ARE_SET (MII_PHY_TBL))	    {	    if (pPhyInfo->phyAnOrderTbl == NULL)		{		MII_LOG (MII_DBG_ANY, ("miiAutoNegotiate no auto-neg table\n"),				       0, 0, 0, 0, 0, 0);		return (ERROR);		}	    /* check we're not at the end of the user table */	    if (*((INT16*) pPhyInfo->phyAnOrderTbl + ix) == -1)		return (ERROR);	    /* just negotiate one ability at a time */	    phyAds &= ~MII_ADS_TECH_MASK;	    /* translate user settings */	    phyAds |= *((INT16*) pPhyInfo->phyAnOrderTbl + ix);	    /* check the PHY has the desidered ability */	    if (!(phyAds & pPhyInfo->miiRegs.phyAds))		continue;	    }	else	    {	    /* check the PHY flags and possibly mask some abilities off */	    if (!(MII_PHY_FLAGS_ARE_SET (MII_PHY_FD)))		phyAds &= ~(MII_TECH_10BASE_FD | MII_TECH_100BASE_TX_FD);	    if (!(MII_PHY_FLAGS_ARE_SET (MII_PHY_HD)))		phyAds &= ~(MII_TECH_10BASE_T | MII_TECH_100BASE_TX 			    | MII_TECH_100BASE_T4);	    if (!(MII_PHY_FLAGS_ARE_SET (MII_PHY_100)))		phyAds &= ~(MII_TECH_100BASE_TX | MII_TECH_100BASE_TX_FD			    | MII_TECH_100BASE_T4);	    if (!(MII_PHY_FLAGS_ARE_SET (MII_PHY_10)))		phyAds &= ~(MII_TECH_10BASE_T | MII_TECH_10BASE_FD);	    /* store the current registers values */	    pPhyInfo->miiRegs.phyAds = phyAds;	    if (pPhyInfo->phyFlags & MII_PHY_GMII_TYPE)	        {	        /* check phyFlags with 1000T FD mode */	        if (!(MII_PHY_FLAGS_ARE_SET (MII_PHY_1000T_FD)))	            phyMstSlaCtrl &= ~MII_MASSLA_CTRL_1000T_FD;	        /* check phyFlags with 1000T HD mode */	        if (!(MII_PHY_FLAGS_ARE_SET (MII_PHY_1000T_HD)))	            phyMstSlaCtrl &= ~MII_MASSLA_CTRL_1000T_HD;	       /* store the current registers values */	        pPhyInfo->miiGRegs.phyMSCtrl = phyMstSlaCtrl;;	        MII_LOG (MII_DBG_ANY, ("miiAutoNegotiate phyMSCtrl=0x%x\n"),					   phyMstSlaCtrl, 0, 0, 0, 0, 0);	        }	    MII_LOG (MII_DBG_ANY, ("miiAutoNegotiate phyAds=0x%x\n"),				   phyAds, 0, 0, 0, 0, 0);	    }	/* set the ANAR accordingly */	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);

⌨️ 快捷键说明

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