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

📄 skrlmt.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
				/*				 * Send packet to RLMT multicast address				 * to force switches to learn the new				 * location of the 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;	}	else {		Para.Para32[0] = A;		/*		 * 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 MacActive != SelectedPort,		 *     If old ActivePort is LinkDown,		 *       SwitchHard		 *     else		 *       SwitchSoft		 */		if (pAC->Rlmt.RlmtMode != SK_RLMT_CHECK_LINK) {			if (!PortFound) {				PortFound = SkRlmtSelectBcRx(pAC, IoC,					A, P, &Para.Para32[1]);			}			if (!PortFound) {				PortFound = SkRlmtSelectNotSuspect(pAC, IoC,					A, P, &Para.Para32[1]);			}		}		if (!PortFound) {			PortFound = SkRlmtSelectUp(pAC, IoC,				A, P, &Para.Para32[1], AUTONEG_SUCCESS);		}		if (!PortFound) {			PortFound = SkRlmtSelectUp(pAC, IoC,				A, P, &Para.Para32[1], AUTONEG_FAILED);		}		if (!PortFound) {			PortFound = SkRlmtSelectGoingUp(pAC, IoC,				A, P, &Para.Para32[1], AUTONEG_SUCCESS);		}		if (!PortFound) {			PortFound = SkRlmtSelectGoingUp(pAC, IoC,				A, P,&Para.Para32[1], AUTONEG_FAILED);		}		if (pAC->Rlmt.RlmtMode != SK_RLMT_CHECK_LINK) {			if (!PortFound) {				PortFound = SkRlmtSelectDown(pAC, IoC,					A, P,&Para.Para32[1], AUTONEG_SUCCESS);			}			if (!PortFound) {				PortFound = SkRlmtSelectDown(pAC, IoC,					A, P,&Para.Para32[1], AUTONEG_FAILED);			}		}		if (PortFound) {			if (Para.Para32[1] != A) {				pAC->Rlmt.MacActive = Para.Para32[1];				SK_HWAC_LINK_LED(					pAC,					IoC,					Para.Para32[1],					SK_LED_ACTIVE);				if (pAC->Rlmt.Port[A].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);				}				SkEventQueue(					pAC,					SKGE_PNMI,					SK_PNMI_EVT_RLMT_PORT_SWITCH,					Para);				if ((Para.pParaPtr = SkRlmtBuildPacket(						pAC,						IoC,						Para.Para32[1],						SK_PACKET_ANNOUNCE,						&pAC->Addr.CurrentMacAddress,						&SkRlmtMcAddr)					) != NULL) {					/*					 * Send "new" packet to RLMT multicast					 * address to force switches to learn					 * the new location of the MAC address.					 */					SkEventQueue(						pAC,						SKGE_DRV,						SK_DRV_RLMT_SEND,						Para);				}			}		}		else {			SK_ERR_LOG(				pAC,				SK_ERRCL_SW,				SKERR_RLMT_E004,				SKERR_RLMT_E004_MSG);		}	}	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_BOOL	Equal;	SK_U32	i, j;	pAC->Rlmt.RootIdSet = SK_FALSE;	Equal = SK_TRUE;	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {		if (pAC->Rlmt.Port[i].LinkDown ||			!pAC->Rlmt.Port[i].RootIdSet) {			continue;		}		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_CTRL,			("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n",				i,				pAC->Rlmt.Port[i].Root.Id[0],				pAC->Rlmt.Port[i].Root.Id[1],				pAC->Rlmt.Port[i].Root.Id[2],				pAC->Rlmt.Port[i].Root.Id[3],				pAC->Rlmt.Port[i].Root.Id[4],				pAC->Rlmt.Port[i].Root.Id[5],				pAC->Rlmt.Port[i].Root.Id[6],				pAC->Rlmt.Port[i].Root.Id[7]))		if (!pAC->Rlmt.RootIdSet) {			pAC->Rlmt.Root = pAC->Rlmt.Port[i].Root;			pAC->Rlmt.RootIdSet = SK_TRUE;			continue;		}		for (j = 0; j < 8; j ++) {			Equal &= pAC->Rlmt.Port[i].Root.Id[j] ==				pAC->Rlmt.Root.Id[j];			if (!Equal) {				break;			}		}				if (!Equal) {			SK_ERR_LOG(				pAC,				SK_ERRCL_COMM,				SKERR_RLMT_E005,				SKERR_RLMT_E005_MSG);#ifdef SK_PNMI_EVT_SEGMENTATION			SkEventQueue(				pAC,				SKGE_PNMI,				SK_PNMI_EVT_SEGMENTATION,				Para);#endif	/* SK_PNMI_EVT_SEGMENTATION */			pAC->Rlmt.CheckingState &= ~SK_RLMT_RCS_REPORT_SEG;			break;		}	}}	/* 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	PortIdx)	/* event code */{	SK_EVPARA	Para;	pAC->Rlmt.Port[PortIdx].PortState = SK_RLMT_PS_LINK_DOWN;	pAC->Rlmt.Port[PortIdx].PortStarted = SK_TRUE;	pAC->Rlmt.Port[PortIdx].LinkDown = SK_TRUE;	pAC->Rlmt.Port[PortIdx].PortDown = SK_TRUE;	pAC->Rlmt.Port[PortIdx].CheckingState = 0;	pAC->Rlmt.Port[PortIdx].RootIdSet = SK_FALSE;	Para.Para32[0] = PortIdx;	SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);}	/* SkRlmtPortStart *//****************************************************************************** * *	SkRlmtEvent - a PORT- or an RLMT-specific event happened * * Description: *	This routine handles PORT- and RLMT-specific events. * * Context: *	runtime, pageable? *	may be called after SK_INIT_IO * * Returns: *	0 */int	SkRlmtEvent(SK_AC		*pAC,	/* adapter context */SK_IOC		IoC,	/* I/O context */SK_U32		Event,	/* event code */SK_EVPARA	Para)	/* event-specific parameter */{	SK_U32		i, j;	SK_RLMT_PORT	*pRPort;	SK_EVPARA	Para2;	SK_MBUF		*pMb;	SK_MBUF		*pNextMb;	SK_MAC_ADDR	*pOldMacAddr;	SK_MAC_ADDR	*pNewMacAddr;	SK_U32		Timeout;	SK_U32		NewTimeout;	SK_U32		PrevRlmtMode;	switch (Event) {	case SK_RLMT_PORTSTART_TIM:	/* From RLMT via TIME. */		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_CTRL,			("SK_RLMT_PORTSTART_TIMEOUT Port %d Event (%d) BEGIN.\n", Para.Para32[0], Event))		/*		 * 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 < (SK_U32)pAC->GIni.GIMacsFound; i++) {				if (!pAC->Rlmt.Port[i].PortStarted) {					SkRlmtPortStart(pAC, IoC, i);				}			}		}		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_CTRL,			("SK_RLMT_PORTSTART_TIMEOUT Event (%d) END.\n", Event))		break;	case SK_RLMT_LINK_UP:		/* From SIRQ. */		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_CTRL,			("SK_RLMT_LINK_UP Port %d Event (%d) BEGIN.\n",				Para.Para32[0], Event))		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 (%d) EMPTY.\n", Event))			break;		}		if (!pRPort->LinkDown) {			/* RA;:;: Any better solution? */			SK_DBG_MSG(				pAC,				SK_DBGMOD_RLMT,				SK_DBGCAT_CTRL,				("SK_RLMT_LINK_UP Event (%d) EMPTY.\n", Event))			break;		}		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;		if (pAC->Rlmt.LinksUp == 0) {			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);		}		pAC->Rlmt.LinksUp++;		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {			if (!pAC->Rlmt.Port[i].PortStarted) {				SkRlmtPortStart(pAC, IoC, i);			}		}		SkRlmtCheckSwitch(pAC, IoC);		if (pAC->Rlmt.LinksUp >= 2) {			if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) {				/* Build the check chain. */				SkRlmtBuildCheckChain(pAC);			}		}		/*		 * If the first link comes up, start the periodical		 * RLMT timeout.		 */		if (pAC->GIni.GIMacsFound > 1 && pAC->Rlmt.LinksUp == 1 &&			(pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_OTHERS)) {			SkTimerStart(				pAC,				IoC,				&pAC->Rlmt.LocTimer,				pAC->Rlmt.TimeoutValue,				SKGE_RLMT,				SK_RLMT_TIM,				Para);		}		SkTimerStart(			pAC,			IoC,			&pRPort->UpTimer,			SK_RLMT_PORTUP_TIM_VAL,			SKGE_RLMT,			SK_RLMT_PORTUP_TIM,			Para);		/*		 * Later:		 * if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) &&		 */		if ((pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LINK) &&			(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 (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_SEG) {			if ((Para2.pParaPtr =				SkRlmtBuildSpanningTreePacket(					pAC,					IoC,					Para.Para32[0])				) != NULL) {								pAC->Rlmt.Port[Para.Para32[0]].RootIdSet =					SK_FALSE;				pAC->Rlmt.CheckingState |=					SK_RLMT_RCS_SEG |					SK_RLMT_RCS_REPORT_SEG;								SkEventQueue(					pAC,					SKGE_DRV,					SK_DRV_RLMT_SEND,					Para2);				SkTimerStart(					pAC,					IoC,					&pAC->Rlmt.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 (%d) END.\n", Event))		break;	case SK_RLMT_PORTUP_TIM:	/* From RLMT via TIME. */		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_CTRL,			("SK_RLMT_PORTUP_TIM Port %d Event (%d) BEGIN.\n", Para.Para32[0], Event))		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 (%d) EMPTY.\n",					Para.Para32[0],					Event))			break;		}		pRPort->PortDown = SK_FALSE;                pRPort->PortState = SK_RLMT_PS_UP;		pAC->Rlmt.PortsUp++;		if (pAC->Rlmt.RlmtState != SK_RLMT_RS_INIT) {			SkRlmtCheckSwitch(pAC, IoC);			SkEventQueue(				pAC,				SKGE_PNMI,				SK_PNMI_EVT_RLMT_PORT_UP,				Para);		}		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_CTRL,			("S

⌨️ 快捷键说明

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