📄 skrlmt.c
字号:
} if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) { if (!PortFound) { PortFound = SkRlmtSelectDown(pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS); } if (!PortFound) { PortFound = SkRlmtSelectDown(pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED); } } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ if (PortFound) { if (Para.Para32[1] != Active) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Active: %d, Para1: %d.\n", Active, Para.Para32[1])) pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1]; Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. Port[Para.Para32[0]]->PortNumber; Para.Para32[1] = pAC->Rlmt.Net[NetIdx]. Port[Para.Para32[1]]->PortNumber; SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[1], SK_LED_ACTIVE); if (pAC->Rlmt.Port[Active].LinkDown) { SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_HARD, Para); } else { SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY); SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_SOFT, Para); } Para.Para32[1] = NetIdx; Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[Para.Para32[0]]->PortNumber; SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para); Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber; SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para); if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 && (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].CurrentMacAddress, &SkRlmtMcAddr)) != NULL) { /* * Send announce packet to RLMT multicast address to force * switches to learn the new location of the logical * MAC address. */ SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); } /* (Para.pParaPtr = SkRlmtBuildPacket(...)) != NULL */ } /* Para.Para32[1] != Active */ } /* PortFound */ else { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E004, SKERR_RLMT_E004_MSG); } } /* LinksUp > 1 || LinksUp == 1 && RlmtState != SK_RLMT_RS_NET_DOWN */ return;} /* SkRlmtCheckSwitch *//****************************************************************************** * * SkRlmtCheckSeg - Report if segmentation is detected * * Description: * This routine checks if the ports see different root bridges and reports * segmentation in such a case. * * Context: * runtime, pageable? * * Returns: * Nothing. */RLMT_STATIC void SkRlmtCheckSeg(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */SK_U32 NetIdx) /* Net number */{ SK_EVPARA Para; SK_RLMT_NET *pNet; SK_U32 i, j; SK_BOOL Equal; pNet = &pAC->Rlmt.Net[NetIdx]; pNet->RootIdSet = SK_FALSE; Equal = SK_TRUE; for (i = 0; i < pNet->NumPorts; i++) { if (pNet->Port[i]->LinkDown || !pNet->Port[i]->RootIdSet) { continue; } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP, ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", i, pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1], pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3], pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5], pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7])) if (!pNet->RootIdSet) { pNet->Root = pNet->Port[i]->Root; pNet->RootIdSet = SK_TRUE; continue; } for (j = 0; j < 8; j ++) { Equal &= pNet->Port[i]->Root.Id[j] == pNet->Root.Id[j]; if (!Equal) { break; } } if (!Equal) { SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E005, SKERR_RLMT_E005_MSG); Para.Para32[0] = NetIdx; Para.Para32[1] = (SK_U32)-1; SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SEGMENTATION, Para); pNet->CheckingState &= ~SK_RLMT_RCS_REPORT_SEG; /* 2000-03-06 RA: New. */ Para.Para32[0] = NetIdx; Para.Para32[1] = (SK_U32)-1; SkTimerStart(pAC, IoC, &pNet->SegTimer, SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para); break; } } /* for (i = 0; i < pNet->NumPorts; i++) */ /* 2000-03-06 RA: Moved here. */ /* Segmentation check not running anymore. */ pNet->CheckingState &= ~SK_RLMT_RCS_SEG;} /* SkRlmtCheckSeg *//****************************************************************************** * * SkRlmtPortStart - initialize port variables and start port * * Description: * This routine initializes a port's variables and issues a PORT_START * to the HWAC module. This handles retries if the start fails or the * link eventually goes down. * * Context: * runtime, pageable? * * Returns: * Nothing */RLMT_STATIC void SkRlmtPortStart(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */SK_U32 PortNumber) /* Port number */{ SK_EVPARA Para; pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_LINK_DOWN; pAC->Rlmt.Port[PortNumber].PortStarted = SK_TRUE; pAC->Rlmt.Port[PortNumber].LinkDown = SK_TRUE; pAC->Rlmt.Port[PortNumber].PortDown = SK_TRUE; pAC->Rlmt.Port[PortNumber].CheckingState = 0; pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE; Para.Para32[0] = PortNumber; Para.Para32[1] = (SK_U32)-1; SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);} /* SkRlmtPortStart *//****************************************************************************** * * SkRlmtEvtPortStartTim - PORT_START_TIM * * Description: * This routine handles PORT_START_TIM events. * * Context: * runtime, pageable? * may be called after SK_INIT_IO * * Returns: * Nothing */RLMT_STATIC void SkRlmtEvtPortStartTim(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */{ SK_U32 i; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0])) if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Bad Parameter.\n")) SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n")) return; } /* * Used to start non-preferred ports if the preferred one * does not come up. * This timeout needs only be set when starting the first * (preferred) port. */ if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) { /* PORT_START failed. */ for (i = 0; i < pAC->Rlmt.Port[Para.Para32[0]].Net->NumPorts; i++) { if (!pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortStarted) { SkRlmtPortStart(pAC, IoC, pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortNumber); } } } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"))} /* SkRlmtEvtPortStartTim *//****************************************************************************** * * SkRlmtEvtLinkUp - LINK_UP * * Description: * This routine handles LLINK_UP events. * * Context: * runtime, pageable? * may be called after SK_INIT_IO * * Returns: * Nothing */RLMT_STATIC void SkRlmtEvtLinkUp(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */{ SK_U32 i; SK_RLMT_PORT *pRPort; SK_EVPARA Para2; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0])) pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; if (!pRPort->PortStarted) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_LINK_UP Event EMPTY.\n")) return; } if (!pRPort->LinkDown) { /* RA;:;: Any better solution? */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_LINK_UP Event EMPTY.\n")) return; } SkTimerStop(pAC, IoC, &pRPort->UpTimer); SkTimerStop(pAC, IoC, &pRPort->DownRxTimer); SkTimerStop(pAC, IoC, &pRPort->DownTxTimer); /* Do something if timer already fired? */ pRPort->LinkDown = SK_FALSE; pRPort->PortState = SK_RLMT_PS_GOING_UP; pRPort->GuTimeStamp = SkOsGetTime(pAC); pRPort->BcTimeStamp = 0; pRPort->Net->LinksUp++; if (pRPort->Net->LinksUp == 1) { SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_ACTIVE); } else { SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY); } for (i = 0; i < pRPort->Net->NumPorts; i++) { if (!pRPort->Net->Port[i]->PortStarted) { SkRlmtPortStart(pAC, IoC, pRPort->Net->Port[i]->PortNumber); } } SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); if (pRPort->Net->LinksUp >= 2) { if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) { /* Build the check chain. */ SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber); } } /* If the first link comes up, start the periodical RLMT timeout. */ if (pRPort->Net->NumPorts > 1 && pRPort->Net->LinksUp == 1 && (pRPort->Net->RlmtMode & SK_RLMT_CHECK_OTHERS) != 0) { Para2.Para32[0] = pRPort->Net->NetNumber; Para2.Para32[1] = (SK_U32)-1; SkTimerStart(pAC, IoC, &pRPort->Net->LocTimer, pRPort->Net->TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, Para2); } Para2 = Para; Para2.Para32[1] = (SK_U32)-1; SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2); /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */ if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 && (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 && (Para2.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE, &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr) ) != NULL) { /* Send "new" packet to RLMT multicast address. */ SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); } if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) { if ((Para2.pParaPtr = SkRlmtBuildSpanningTreePacket(pAC, IoC, Para.Para32[0])) != NULL) { pAC->Rlmt.Port[Para.Para32[0]].RootIdSet = SK_FALSE; pRPort->Net->CheckingState |= SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG; SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); Para.Para32[1] = (SK_U32)-1; SkTimerStart(pAC, IoC, &pRPort->Net->SegTimer, SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para); } } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_LINK_UP Event END.\n"))} /* SkRlmtEvtLinkUp *//****************************************************************************** * * SkRlmtEvtPortUpTim - PORT_UP_TIM * * Description: * This routine handles PORT_UP_TIM events. * * Context: * runtime, pageable? * may be called after SK_INIT_IO * * Returns: * Nothing */RLMT_STATIC void SkRlmtEvtPortUpTim(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */{ SK_RLMT_PORT *pRPort; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0])) if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Bad Parameter.\n")) SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTUP_TIM Event EMPTY.\n")) return; } pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0])) return; } pRPort->PortDown = SK_FALSE; pRPort->PortState = SK_RLMT_PS_UP; pRPort->Net->PortsUp++; if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) { if (pAC->Rlmt.NumNets <= 1) { SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); } SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_UP, Para); } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTUP_TIM Event END.\n"))} /* SkRlmtEvtPortUpTim *//****************************************************************************** * * SkRlmtEvtPortDownTim - PORT_DOWN_* * * Description: * This routine handles PORT_DOWN_* events. * * Context: * runtime, pageable? * may be called after SK_INIT_IO * * Returns: * Nothing */RLMT_STATIC void SkRlmtEvtPortDownX(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */SK_U32 Event, /* Event code */SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */{ SK_RLMT_PORT *pRPort; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n", Para.Para32[0], Event)) if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Bad Parameter.\n")) SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTDOWN* Event EMPTY.\n")) return; } pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM && !(pRPort->CheckingState & SK_RLMT_PCS_TX))) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event)) return; } /* Stop port's timers. */ SkTimerStop(pAC,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -