📄 miilib.c
字号:
* 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->phyDelayRtn == (FUNCPTR) taskDelay) if (pPhyInfo->phyMaxDelay < (sysClkRateGet() * 5) / pPhyInfo->phyDelayParm) { /* Set max delay porportionally */ pPhyInfo->phyMaxDelay = ((sysClkRateGet() * 5) / pPhyInfo->phyDelayParm) + 1; } /* 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.** RETURNS: OK or ERROR.*/ LOCAL STATUS miiPhyMonitorStart ( ) { netJobAdd ((FUNCPTR) miiPhyMonitor, (int) NULL, 0, 0, 0, 0); return (OK); }/**************************************************************************** miiPhyMonitor - monitor all the PHYs to detect a link down event** This routine monitors all the PHYs to detect a link down event.** RETURNS: OK or ERROR.*/ LOCAL STATUS miiPhyMonitor ( ) { UINT16 phyStatus; /* holder for the PHY status */ int retVal = OK; /* convenient holder for return value */ PHY_INFO * pPhyInfo; /* PHY info pointer */ MII_PHY_NODE * pMiiPhyNode = NULL; /* pointer to phy node */ /* protect it from other MII routines */ MII_SEM_TAKE (WAIT_FOREVER); /* loop through all the PHYs */ for (pMiiPhyNode = (MII_PHY_NODE *) lstFirst (&miiList); pMiiPhyNode != NULL; pMiiPhyNode = (MII_PHY_NODE *) lstNext ((NODE *) pMiiPhyNode)) { pPhyInfo = pMiiPhyNode->pPhyInfo; if ((pPhyInfo != NULL) && (MII_PHY_FLAGS_ARE_SET (MII_PHY_INIT)) && (MII_PHY_FLAGS_ARE_SET (MII_PHY_MONITOR))) { MII_READ (pPhyInfo->phyAddr, MII_STAT_REG, &phyStatus, retVal); if (retVal == ERROR) goto miiMonitorExit; MII_READ (pPhyInfo->phyAddr, MII_STAT_REG, &phyStatus, retVal); if (retVal == ERROR) goto miiMonitorExit; /* is the PHY's status link changed? */ if ((pPhyInfo->miiRegs.phyStatus & MII_SR_LINK_STATUS) != (phyStatus & MII_SR_LINK_STATUS)) { MII_LOG (MII_DBG_ANY, ("miiPhyMonitor link down stat=0x%x\n"), phyStatus, 0, 0, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -