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

📄 miilib.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    /*      * 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);     /* 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;      /*      * 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;	    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);	/* 	 * 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 (pPhyInfo->phyDelayParm);	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 */    )    {    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	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);    /* find out the max common abilities */    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)	{	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 */    pPhyInfo->miiRegs.phyStatus = phyStatus;    pPhyInfo->miiRegs.phyAds = phyAds;    pPhyInfo->miiRegs.phyPrtn = phyPrtn;    pPhyInfo->miiRegs.phyExp = phyExp;    /* 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.** RETURNS: OK or ERROR.*/LOCAL 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 */    /* 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);    }

⌨️ 快捷键说明

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