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

📄 skrlmt.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Returns: *	New timeout value. */RLMT_STATIC SK_U32	SkRlmtCheckPort(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* I/O context */SK_U32	PortIdx)	/* port to check */{	unsigned	i;	SK_U32		NewTimeout;	SK_RLMT_PORT	*pRPort;	SK_EVPARA	Para;	pRPort = &pAC->Rlmt.Port[PortIdx];	if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) {		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_CTRL,			("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n",				PortIdx,				pRPort->PacketsPerTimeSlot))		/*		 * Check segmentation if there was no receive at least twice		 * in a row (PortNoRx is already set) and the segmentation		 * check is not currently running.		 */		if (pRPort->PortNoRx && (pAC->Rlmt.LinksUp > 1) &&			(pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_SEG) &&			!(pAC->Rlmt.CheckingState & SK_RLMT_RCS_SEG)) {			pAC->Rlmt.CheckingState |=				SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;		}		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_CTRL,			("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n",				pRPort->PortsSuspect,				pRPort->CheckingState & SK_RLMT_PCS_RX))		if (pRPort->PortState != SK_RLMT_PS_DOWN) {			NewTimeout = TO_SHORTEN(pAC->Rlmt.TimeoutValue);			if (NewTimeout < SK_RLMT_MIN_TO_VAL) {				NewTimeout = SK_RLMT_MIN_TO_VAL;			}			if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) {				Para.Para32[0] = PortIdx;				pRPort->CheckingState |= SK_RLMT_PCS_RX;				/*				 * What shall we do if the port checked				 * by this one receives our request				 * frames?  What's bad - our rx line				 * or his tx line?				 */				SkTimerStart(					pAC,					IoC,					&pRPort->DownRxTimer,					SK_RLMT_PORTDOWN_TIM_VAL,					SKGE_RLMT,					SK_RLMT_PORTDOWN_RX_TIM,					Para);				for (i = 0; i < pRPort->PortsChecked; i++) {					if (pRPort->PortCheck[i].SuspectTx) {						continue;					}					pRPort->PortCheck[i].SuspectTx = SK_TRUE;					pRPort->PortsSuspect++;					if ((Para.pParaPtr =						SkRlmtBuildPacket(							pAC,							IoC,							PortIdx,							SK_PACKET_CHECK_TX,							&pAC->Addr.Port[PortIdx].CurrentMacAddress,							&pRPort->PortCheck[i].CheckAddr)							) != NULL) {						SkEventQueue(							pAC,							SKGE_DRV,							SK_DRV_RLMT_SEND,							Para);					}				}			}		}		else {	/* PortDown -- or all partners suspect. */			NewTimeout = SK_RLMT_DEF_TO_VAL;		}		pRPort->PortNoRx = SK_TRUE;	}	else {	/* A non-BPDU packet was received. */		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_CTRL,			("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n",				PortIdx,                                pRPort->PacketsPerTimeSlot -					pRPort->BpduPacketsPerTimeSlot,				pRPort->PacketsPerTimeSlot))				SkRlmtPortReceives(pAC, IoC, PortIdx);		NewTimeout = SK_RLMT_DEF_TO_VAL;              	}	return (NewTimeout);       }	/* SkRlmtCheckPort *//****************************************************************************** * *	SkRlmtSelectBcRx - select new active port, criteria 1 (CLP) * * Description: *	This routine selects the port that received a broadcast frame *	substantially later than all other ports. * * Context: *	runtime, pageable? * * Returns: *	SK_BOOL */RLMT_STATIC SK_BOOL	SkRlmtSelectBcRx(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* I/O context */SK_U32	A,	/* active port */SK_U32	P,	/* preferred port */SK_U32	*N)	/* new active port */{	SK_U64		BcTimeStamp;	SK_U32		i;	SK_BOOL		PortFound;        BcTimeStamp = 0;	/* Not totally necessary, but feeling better. */	PortFound = SK_FALSE;		/* Select port with the latest TimeStamp. */	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_CTRL,			("TimeStamp Port %d: %.08x%.08x.\n",			i,			*((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32),			*((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)))		if (!pAC->Rlmt.Port[i].PortDown &&			!pAC->Rlmt.Port[i].PortNoRx) {			if (!PortFound ||				pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) {				BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp;				*N = i;				PortFound = SK_TRUE;			}		}	}	if (PortFound) {		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_CTRL,			("Port %d received the last broadcast.\n", *N))		/* Look if another port's time stamp is similar. */		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {			if (i == *N) {				continue;			}			if (!pAC->Rlmt.Port[i].PortDown &&				!pAC->Rlmt.Port[i].PortNoRx &&				(pAC->Rlmt.Port[i].BcTimeStamp >				BcTimeStamp - SK_RLMT_BC_DELTA ||				pAC->Rlmt.Port[i].BcTimeStamp				+ SK_RLMT_BC_DELTA > BcTimeStamp)) {				PortFound = SK_FALSE;				SK_DBG_MSG(					pAC,					SK_DBGMOD_RLMT,					SK_DBGCAT_CTRL,					("Port %d received a broadcast %s.\n",					i,					"at a similar time"))				break;			}		}	}#ifdef DEBUG	if (PortFound) {		SK_DBG_MSG(			pAC,			SK_DBGMOD_RLMT,			SK_DBGCAT_CTRL,			("SK_RLMT_CHECK_SWITCH found Port %d receiving %s.\n",				*N,				"the substantially latest broadcast"))	}#endif	/* DEBUG */	return (PortFound);}	/* SkRlmtSelectBcRx *//****************************************************************************** * *	SkRlmtSelectNotSuspect - select new active port, criteria 2 (CLP) * * Description: *	This routine selects a good port (it is PortUp && !SuspectRx). * * Context: *	runtime, pageable? * * Returns: *	SK_BOOL */RLMT_STATIC SK_BOOL	SkRlmtSelectNotSuspect(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* I/O context */SK_U32	A,	/* active port */SK_U32	P,	/* preferred port */SK_U32	*N)	/* new active port */{	SK_U32		i;	SK_BOOL		PortFound;	PortFound = SK_FALSE;	/* Select first port that is PortUp && !SuspectRx. */	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {		if (!pAC->Rlmt.Port[i].PortDown &&			!(pAC->Rlmt.Port[i].CheckingState & SK_RLMT_PCS_RX)) {			*N = i;			if (!pAC->Rlmt.Port[A].PortDown &&				!(pAC->Rlmt.Port[A].CheckingState &				SK_RLMT_PCS_RX)) {				*N = A;			}			if (!pAC->Rlmt.Port[P].PortDown &&				!(pAC->Rlmt.Port[P].CheckingState &				SK_RLMT_PCS_RX)) {				*N = P;			}			PortFound = SK_TRUE;			SK_DBG_MSG(				pAC,				SK_DBGMOD_RLMT,				SK_DBGCAT_CTRL,				("SK_RLMT_CHECK_SWITCH found Port %d up and not check RX.\n",					*N))			break;		}	}	return (PortFound);}	/* SkRlmtSelectNotSuspect *//****************************************************************************** * *	SkRlmtSelectUp - select new active port, criteria 3, 4 (CLP) * * Description: *	This routine selects a port that is up. * * Context: *	runtime, pageable? * * Returns: *	SK_BOOL */RLMT_STATIC SK_BOOL	SkRlmtSelectUp(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* I/O context */SK_U32	A,	/* active port */SK_U32	P,	/* preferred port */SK_U32	*N,	/* new active port */SK_BOOL	AutoNegDone)	/* successfully auto-negotiated? */{	SK_U32		i;	SK_BOOL		PortFound;	PortFound = SK_FALSE;	/* Select first port that is PortUp. */	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {		if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_UP &&			pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {			*N = i;			if (pAC->Rlmt.Port[A].PortState == SK_RLMT_PS_UP &&				pAC->GIni.GP[A].PAutoNegFail != AutoNegDone) {				*N = A;			}			if (pAC->Rlmt.Port[P].PortState == SK_RLMT_PS_UP &&				pAC->GIni.GP[P].PAutoNegFail != AutoNegDone) {				*N = P;			}			PortFound = SK_TRUE;			SK_DBG_MSG(				pAC,				SK_DBGMOD_RLMT,				SK_DBGCAT_CTRL,				("SK_RLMT_CHECK_SWITCH found Port %d up.\n",					*N))			break;		}	}	return (PortFound);}	/* SkRlmtSelectUp *//****************************************************************************** * *	SkRlmtSelectGoingUp - select new active port, criteria 5, 6 (CLP) * * Description: *	This routine selects the port that is going up for the longest time. * * Context: *	runtime, pageable? * * Returns: *	SK_BOOL */RLMT_STATIC SK_BOOL	SkRlmtSelectGoingUp(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* I/O context */SK_U32	A,	/* active port */SK_U32	P,	/* preferred port */SK_U32	*N,	/* new active port */SK_BOOL	AutoNegDone)	/* successfully auto-negotiated? */{	SK_U64		GuTimeStamp=0;	SK_U32		i;	SK_BOOL		PortFound;	PortFound = SK_FALSE;	/* Select port that is PortGoingUp for the longest time. */	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {		if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&			pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {                        GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;			*N = i;			PortFound = SK_TRUE;			break;		}	}	if (!PortFound) {		return (SK_FALSE);	}	for (i = *N + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {		if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&                        pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp &&			pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {                        GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;			*N = i;		}	}	SK_DBG_MSG(		pAC,		SK_DBGMOD_RLMT,		SK_DBGCAT_CTRL,		("SK_RLMT_CHECK_SWITCH found Port %d going up.\n", *N))	return (SK_TRUE);}	/* SkRlmtSelectGoingUp *//****************************************************************************** * *	SkRlmtSelectDown - select new active port, criteria 7, 8 (CLP) * * Description: *	This routine selects a port that is down. * * Context: *	runtime, pageable? * * Returns: *	SK_BOOL */RLMT_STATIC SK_BOOL	SkRlmtSelectDown(SK_AC	*pAC,	/* adapter context */SK_IOC	IoC,	/* I/O context */SK_U32	A,	/* active port */SK_U32	P,	/* preferred port */SK_U32	*N,	/* new active port */SK_BOOL	AutoNegDone)	/* successfully auto-negotiated? */{	SK_U32		i;	SK_BOOL		PortFound;	PortFound = SK_FALSE;	/* Select first port that is PortDown. */	for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {		if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_DOWN &&			pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {			*N = i;			if (pAC->Rlmt.Port[A].PortState == SK_RLMT_PS_DOWN &&				pAC->GIni.GP[A].PAutoNegFail != AutoNegDone) {				*N = A;			}			if (pAC->Rlmt.Port[P].PortState == SK_RLMT_PS_DOWN &&				pAC->GIni.GP[P].PAutoNegFail != AutoNegDone) {				*N = P;			}			PortFound = SK_TRUE;			SK_DBG_MSG(				pAC,				SK_DBGMOD_RLMT,				SK_DBGCAT_CTRL,				("SK_RLMT_CHECK_SWITCH found Port %d down.\n",					*N))			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_EVPARA	Para;	SK_U32		A;	SK_U32		P;	SK_U32		i;	SK_BOOL		PortFound;	if (pAC->Rlmt.RlmtState == SK_RLMT_RS_INIT) {		return;	}	A = pAC->Rlmt.MacActive;	/* Index of active port. */	P = pAC->Rlmt.PrefPort;		/* Index of preferred port. */	PortFound = SK_FALSE;	if (pAC->Rlmt.LinksUp == 0) {		/*		 * Last link went down - shut down the net.		 */		pAC->Rlmt.RlmtState = SK_RLMT_RS_NET_DOWN;		Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP;		SkEventQueue(			pAC,			SKGE_DRV,			SK_DRV_NET_DOWN,			Para);		return;	}	else if (pAC->Rlmt.LinksUp == 1 &&		pAC->Rlmt.RlmtState == SK_RLMT_RS_NET_DOWN) {		/* First link came up - get the net up. */		pAC->Rlmt.RlmtState = SK_RLMT_RS_NET_UP;		/*		 * If pAC->Rlmt.MacActive != Para.Para32[0],		 * the DRV switches to the port that came up.		 */		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {			if (!pAC->Rlmt.Port[i].LinkDown) {				if (!pAC->Rlmt.Port[A].LinkDown) {					i = A;				}				if (!pAC->Rlmt.Port[P].LinkDown) {					i = P;				}				PortFound = SK_TRUE;				break;			}		}		if (PortFound) {			Para.Para32[0] = pAC->Rlmt.MacActive;			Para.Para32[1] = i;			SkEventQueue(				pAC,				SKGE_PNMI,				SK_PNMI_EVT_RLMT_PORT_SWITCH,				Para);			pAC->Rlmt.MacActive = i;			Para.Para32[0] = i;			SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para);			if ((Para.pParaPtr = SkRlmtBuildPacket(					pAC,					IoC,					i,					SK_PACKET_ANNOUNCE,					&pAC->Addr.CurrentMacAddress,					&SkRlmtMcAddr)				) != NULL) {

⌨️ 快捷键说明

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