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

📄 skrlmt.c

📁 u-boot 源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			break;		case SK_PACKET_CHECK_TX:			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,				("SkRlmtPacketReceive: Check your tx line.\n"))			/* A port checking us requests us to check our tx line. */			pRPort->CheckingState |= SK_RLMT_PCS_TX;			/* Start PortDownTx timer. */			Para.Para32[0] = PortNumber;			Para.Para32[1] = (SK_U32)-1;			SkTimerStart(pAC, IoC, &pRPort->DownTxTimer,				SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,				SK_RLMT_PORTDOWN_TX_TIM, Para);			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);			if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,				SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,				&SkRlmtMcAddr)) != NULL) {				SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);			}			break;		case SK_PACKET_ADDR_CHANGED:			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,				("SkRlmtPacketReceive: Address Change.\n"))			/* Build the check chain. */			SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);			break;		default:			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,				("SkRlmtPacketReceive: Unknown RLMT packet.\n"))			/* RA;:;: ??? */			SkDrvFreeRlmtMbuf(pAC, IoC, pMb);		}	}	else if (pSPacket->DSap == SK_RLMT_SPT_DSAP &&		pSPacket->Ctrl == SK_RLMT_SPT_CTRL &&		(pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) {		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,			("SkRlmtPacketReceive: BPDU Packet.\n"))		/* Spanning Tree packet. */		pRPort->RxSpHelloCts++;		if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pAC->Addr.Net[pAC->Rlmt.			Port[PortNumber].Net->NetNumber].CurrentMacAddress.a[0])) {			/*			 * Check segmentation if a new root bridge is set and			 * the segmentation check is not currently running.			 */			if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pRPort->Root.Id[2]) &&				(pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&				(pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG)				!= 0 && (pAC->Rlmt.Port[PortNumber].Net->CheckingState &				SK_RLMT_RCS_SEG) == 0) {				pAC->Rlmt.Port[PortNumber].Net->CheckingState |=					SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;			}			/* Store tree view of this port. */			for (i = 0; i < 8; i++) {				pRPort->Root.Id[i] = pSPacket->RootId[i];			}			pRPort->RootIdSet = SK_TRUE;			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,				("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n",					PortNumber,					pRPort->Root.Id[0], pRPort->Root.Id[1],					pRPort->Root.Id[2], pRPort->Root.Id[3],					pRPort->Root.Id[4], pRPort->Root.Id[5],					pRPort->Root.Id[6], pRPort->Root.Id[7]))		}		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);		if ((pAC->Rlmt.Port[PortNumber].Net->CheckingState &			SK_RLMT_RCS_REPORT_SEG) != 0) {			SkRlmtCheckSeg(pAC, IoC, pAC->Rlmt.Port[PortNumber].Net->NetNumber);		}	}	else {		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,			("SkRlmtPacketReceive: Unknown Packet Type.\n"))		/* Unknown packet. */		SkDrvFreeRlmtMbuf(pAC, IoC, pMb);	}	return;}	/* SkRlmtPacketReceive *//****************************************************************************** * *	SkRlmtCheckPort - check if a port works * * Description: *	This routine checks if a port whose link is up received something *	and if it seems to transmit successfully. * *	# PortState: PsInit, PsLinkDown, PsDown, PsGoingUp, PsUp *	# PortCheckingState (Bitfield): ChkTx, ChkRx, ChkSeg *	# RlmtCheckingState (Bitfield): ChkSeg, StartChkSeg, ReportSeg * *	if (Rx - RxBpdu == 0) {	# No rx. *		if (state == PsUp) { *			PortCheckingState |= ChkRx *		} *		if (ModeCheckSeg && (Timeout == *			TO_SHORTEN(RLMT_DEFAULT_TIMEOUT))) { *			RlmtCheckingState |= ChkSeg) *			PortCheckingState |= ChkSeg *		} *		NewTimeout = TO_SHORTEN(Timeout) *		if (NewTimeout < RLMT_MIN_TIMEOUT) { *			NewTimeout = RLMT_MIN_TIMEOUT *			PortState = PsDown *			... *		} *	} *	else {	# something was received *		# Set counter to 0 at LinkDown? *		#   No - rx may be reported after LinkDown ??? *		PortCheckingState &= ~ChkRx *		NewTimeout = RLMT_DEFAULT_TIMEOUT *		if (RxAck == 0) { *			possible reasons: *			is my tx line bad? -- *				send RLMT multicast and report *				back internally? (only possible *				between ports on same adapter) *		} *		if (RxChk == 0) { *			possible reasons: *			- tx line of port set to check me *			  maybe bad *			- no other port/adapter available or set *			  to check me *			- adapter checking me has a longer *			  timeout *			??? anything that can be done here? *		} *	} * * Context: *	runtime, pageable? * * Returns: *	New timeout value. */RLMT_STATIC SK_U32	SkRlmtCheckPort(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* I/O Context */SK_U32	PortNumber)	/* Port to check */{	unsigned		i;	SK_U32			NewTimeout;	SK_RLMT_PORT	*pRPort;	SK_EVPARA		Para;	pRPort = &pAC->Rlmt.Port[PortNumber];	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",				PortNumber, 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.Port[PortNumber].Net->LinksUp > 1) &&			(pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&			!(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG)) {			pAC->Rlmt.Port[PortNumber].Net->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.Port[PortNumber].Net->TimeoutValue);			if (NewTimeout < SK_RLMT_MIN_TO_VAL) {				NewTimeout = SK_RLMT_MIN_TO_VAL;			}			if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) {				Para.Para32[0] = PortNumber;				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?				 */				Para.Para32[1] = (SK_U32)-1;				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, PortNumber, SK_PACKET_CHECK_TX,							&pAC->Addr.Port[PortNumber].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",				PortNumber,				pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot,				pRPort->PacketsPerTimeSlot))		SkRlmtPortReceives(pAC, IoC, PortNumber);		if (pAC->Rlmt.CheckSwitch) {			SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);		}		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	Active,		/* Active port */SK_U32	PrefPort,	/* Preferred port */SK_U32	*pSelect)	/* 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 (Down: %d, NoRx: %d): %08x %08x.\n",				i,				pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx,				*((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;				*pSelect = i;				PortFound = SK_TRUE;			}		}	}	if (PortFound) {		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,			("Port %d received the last broadcast.\n", *pSelect))		/* Look if another port's time stamp is similar. */		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {			if (i == *pSelect) {				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 at a similar time.\n", i))				break;			}		}	}#ifdef DEBUG	if (PortFound) {		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,			("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially "			 "latest broadcast (%u).\n",				*pSelect,				BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp))	}#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	Active,		/* Active port */SK_U32	PrefPort,	/* Preferred port */SK_U32	*pSelect)	/* 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)) {			*pSelect = i;			if (!pAC->Rlmt.Port[Active].PortDown &&				!(pAC->Rlmt.Port[Active].CheckingState & SK_RLMT_PCS_RX)) {				*pSelect = Active;			}			if (!pAC->Rlmt.Port[PrefPort].PortDown &&				!(pAC->Rlmt.Port[PrefPort].CheckingState & SK_RLMT_PCS_RX)) {				*pSelect = PrefPort;			}			PortFound = SK_TRUE;			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,				("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n",					*pSelect))			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	Active,			/* Active port */SK_U32	PrefPort,		/* Preferred port */SK_U32	*pSelect,		/* 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) {			*pSelect = i;			if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_UP &&				pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {				*pSelect = Active;			}			if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_UP &&				pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {				*pSelect = PrefPort;			}			PortFound = SK_TRUE;			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,				("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect))			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. *

⌨️ 快捷键说明

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