📄 skrlmt.c
字号:
PortFound = SK_TRUE; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_CHECK_SWITCH found Port %d down.\n", *pSelect)) break; } } return (PortFound);} /* SkRlmtSelectDown *//****************************************************************************** * * SkRlmtCheckSwitch - select new active port and switch to it * * Description: * This routine decides which port should be the active one and queues * port switching if necessary. * * Context: * runtime, pageable? * * Returns: * Nothing. */RLMT_STATIC void SkRlmtCheckSwitch(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */SK_U32 NetIdx) /* Net index */{ SK_EVPARA Para; SK_U32 Active; SK_U32 PrefPort; SK_U32 i; SK_BOOL PortFound; Active = pAC->Rlmt.Net[NetIdx].ActivePort; /* Index of active port. */ PrefPort = pAC->Rlmt.Net[NetIdx].PrefPort; /* Index of preferred port. */ PortFound = SK_FALSE; pAC->Rlmt.CheckSwitch = SK_FALSE; if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) { /* Last link went down - shut down the net. */ pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN; Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP; Para.Para32[1] = NetIdx; SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para); Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber; Para.Para32[1] = NetIdx; SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para); return; } /* pAC->Rlmt.LinksUp == 0 */ else if (pAC->Rlmt.Net[NetIdx].LinksUp == 1 && pAC->Rlmt.Net[NetIdx].RlmtState == SK_RLMT_RS_NET_DOWN) { /* First link came up - get the net up. */ pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_UP; /* * If pAC->Rlmt.ActivePort != Para.Para32[0], * the DRV switches to the port that came up. */ for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) { if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) { if (!pAC->Rlmt.Net[NetIdx].Port[Active]->LinkDown) { i = Active; } if (!pAC->Rlmt.Net[NetIdx].Port[PrefPort]->LinkDown) { i = PrefPort; } PortFound = SK_TRUE; break; } } if (PortFound) { Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber; Para.Para32[1] = NetIdx; SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para); pAC->Rlmt.Net[NetIdx].ActivePort = i; Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber; Para.Para32[1] = NetIdx; SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para); if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 && (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber, 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); } } else { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E007, SKERR_RLMT_E007_MSG); } return; } /* LinksUp == 1 && RlmtState == SK_RLMT_RS_NET_DOWN */ else { /* Cannot be reached in dual-net mode. */ Para.Para32[0] = Active; /* * Preselection: * If RLMT Mode != CheckLinkState * select port that received a broadcast frame substantially later * than all other ports * else select first port that is not SuspectRx * else select first port that is PortUp * else select port that is PortGoingUp for the longest time * else select first port that is PortDown * else stop. * * For the preselected port: * If ActivePort is equal in quality, select ActivePort. * * If PrefPort is equal in quality, select PrefPort. * * If ActivePort != SelectedPort, * If old ActivePort is LinkDown, * SwitchHard * else * SwitchSoft */ if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) { if (!PortFound) { PortFound = SkRlmtSelectBcRx( pAC, IoC, Active, PrefPort, &Para.Para32[1]); } if (!PortFound) { PortFound = SkRlmtSelectNotSuspect( pAC, IoC, Active, PrefPort, &Para.Para32[1]); } } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ if (!PortFound) { PortFound = SkRlmtSelectUp( pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS); } if (!PortFound) { PortFound = SkRlmtSelectUp( pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED); } if (!PortFound) { PortFound = SkRlmtSelectGoingUp( pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS); } if (!PortFound) { PortFound = SkRlmtSelectGoingUp( pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED); } 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -