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

📄 skrlmt.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		/* Read physical MAC address for MAC A from Control Register File. */		for (j = 0; j < SK_MAC_ADDR_LEN; j++) {			            SK_IN8(IoC, B2_MAC_2 + j, &PhysicalAMacAddress.a[j]);            PhysicalAMacAddressSet |= PhysicalAMacAddress.a[j];		}        /* check if the two mac addresses contain reasonable values */        if (!VirtualMacAddressSet || !PhysicalAMacAddressSet) {            pAC->Rlmt.RlmtOff = SK_TRUE;        }        /* if the two mac addresses are equal switch off the RLMT_PRE_LOOKAHEAD           and the RLMT_LOOKAHEAD macros */        else if (SK_ADDR_EQUAL(PhysicalAMacAddress.a, VirtualMacAddress.a)) {            pAC->Rlmt.RlmtOff = SK_TRUE;        }		else {			pAC->Rlmt.RlmtOff = SK_FALSE;		}		break;	default:	/* error */		break;	}	return;}	/* SkRlmtInit *//****************************************************************************** * *	SkRlmtBuildCheckChain - build the check chain * * Description: *	This routine builds the local check chain: *	- Each port that is up checks the next port. *	- The last port that is up checks the first port that is up. * * Notes: *	- Currently only local ports are considered when building the chain. *	- Currently the SuspectState is just reset; *	  it would be better to save it ... * * Context: *	runtime, pageable? * * Returns: *	Nothing */RLMT_STATIC void	SkRlmtBuildCheckChain(SK_AC	*pAC,	/* Adapter Context */SK_U32	NetIdx)	/* Net Number */{	SK_U32			i;	SK_U32			NumMacsUp;	SK_RLMT_PORT *	FirstMacUp;	SK_RLMT_PORT *	PrevMacUp;	FirstMacUp	= NULL;	PrevMacUp	= NULL;		if (!(pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {		for (i = 0; i < pAC->Rlmt.Net[i].NumPorts; i++) {			pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;		}		return;	/* Done. */	}				SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,		("SkRlmtBuildCheckChain.\n"))	NumMacsUp = 0;	for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {		pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;		pAC->Rlmt.Net[NetIdx].Port[i]->PortsSuspect = 0;		pAC->Rlmt.Net[NetIdx].Port[i]->CheckingState &=			~(SK_RLMT_PCS_RX | SK_RLMT_PCS_TX);		/*		 * If more than two links are detected we should consider		 * checking at least two other ports:		 * 1. the next port that is not LinkDown and		 * 2. the next port that is not PortDown.		 */		if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {			if (NumMacsUp == 0) {				FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i];			}			else {				PrevMacUp->PortCheck[					pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr =					pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress;				PrevMacUp->PortCheck[					PrevMacUp->PortsChecked].SuspectTx = SK_FALSE;				PrevMacUp->PortsChecked++;			}			PrevMacUp = pAC->Rlmt.Net[NetIdx].Port[i];			NumMacsUp++;		}	}	if (NumMacsUp > 1) {		PrevMacUp->PortCheck[PrevMacUp->PortsChecked].CheckAddr =			FirstMacUp->AddrPort->CurrentMacAddress;		PrevMacUp->PortCheck[PrevMacUp->PortsChecked].SuspectTx =			SK_FALSE;		PrevMacUp->PortsChecked++;	}#ifdef DEBUG	for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,			("Port %d checks %d other ports: %2X.\n", i,				pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked,				pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]))	}#endif	/* DEBUG */	return;}	/* SkRlmtBuildCheckChain *//****************************************************************************** * *	SkRlmtBuildPacket - build an RLMT packet * * Description: *	This routine sets up an RLMT packet. * * Context: *	runtime, pageable? * * Returns: *	NULL or pointer to RLMT mbuf */RLMT_STATIC SK_MBUF	*SkRlmtBuildPacket(SK_AC		*pAC,		/* Adapter Context */SK_IOC		IoC,		/* I/O Context */SK_U32		PortNumber,	/* Sending port */SK_U16		PacketType,	/* RLMT packet type */SK_MAC_ADDR	*SrcAddr,	/* Source address */SK_MAC_ADDR	*DestAddr)	/* Destination address */{	int		i;	SK_U16		Length;	SK_MBUF		*pMb;	SK_RLMT_PACKET	*pPacket;#ifdef DEBUG	SK_U8	CheckSrc  = 0;	SK_U8	CheckDest = 0;		for (i = 0; i < SK_MAC_ADDR_LEN; ++i) {		CheckSrc  |= SrcAddr->a[i];		CheckDest |= DestAddr->a[i];	}	if ((CheckSrc == 0) || (CheckDest == 0)) {		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR,			("SkRlmtBuildPacket: Invalid %s%saddr.\n",			 (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : "")))	}#endif	if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) {		pPacket = (SK_RLMT_PACKET*)pMb->pData;		for (i = 0; i < SK_MAC_ADDR_LEN; i++) {			pPacket->DstAddr[i] = DestAddr->a[i];			pPacket->SrcAddr[i] = SrcAddr->a[i];		}		pPacket->DSap = SK_RLMT_DSAP;		pPacket->SSap = SK_RLMT_SSAP;		pPacket->Ctrl = SK_RLMT_CTRL;		pPacket->Indicator[0] = SK_RLMT_INDICATOR0;		pPacket->Indicator[1] = SK_RLMT_INDICATOR1;		pPacket->Indicator[2] = SK_RLMT_INDICATOR2;		pPacket->Indicator[3] = SK_RLMT_INDICATOR3;		pPacket->Indicator[4] = SK_RLMT_INDICATOR4;		pPacket->Indicator[5] = SK_RLMT_INDICATOR5;		pPacket->Indicator[6] = SK_RLMT_INDICATOR6;		SK_U16_TO_NETWORK_ORDER(PacketType, &pPacket->RlmtPacketType[0]);		for (i = 0; i < 4; i++) {			pPacket->Random[i] = pAC->Rlmt.Port[PortNumber].Random[i];		}				SK_U16_TO_NETWORK_ORDER(			SK_RLMT_PACKET_VERSION, &pPacket->RlmtPacketVersion[0]);		for (i = 0; i < SK_PACKET_DATA_LEN; i++) {			pPacket->Data[i] = 0x00;		}		Length = SK_RLMT_MAX_PACKET_SIZE;	/* Or smaller. */		pMb->Length = Length;		pMb->PortIdx = PortNumber;		Length -= 14;		SK_U16_TO_NETWORK_ORDER(Length, &pPacket->TypeLen[0]);		if (PacketType == SK_PACKET_ALIVE) {			pAC->Rlmt.Port[PortNumber].TxHelloCts++;		}	}	return (pMb);}	/* SkRlmtBuildPacket *//****************************************************************************** * *	SkRlmtBuildSpanningTreePacket - build spanning tree check packet * * Description: *	This routine sets up a BPDU packet for spanning tree check. * * Context: *	runtime, pageable? * * Returns: *	NULL or pointer to RLMT mbuf */RLMT_STATIC SK_MBUF	*SkRlmtBuildSpanningTreePacket(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* I/O Context */SK_U32	PortNumber)	/* Sending port */{	unsigned			i;	SK_U16				Length;	SK_MBUF				*pMb;	SK_SPTREE_PACKET	*pSPacket;	if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) !=		NULL) {		pSPacket = (SK_SPTREE_PACKET*)pMb->pData;		for (i = 0; i < SK_MAC_ADDR_LEN; i++) {			pSPacket->DstAddr[i] = BridgeMcAddr.a[i];			pSPacket->SrcAddr[i] =				pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];		}		pSPacket->DSap = SK_RLMT_SPT_DSAP;		pSPacket->SSap = SK_RLMT_SPT_SSAP;		pSPacket->Ctrl = SK_RLMT_SPT_CTRL;		pSPacket->ProtocolId[0] = SK_RLMT_SPT_PROTOCOL_ID0;		pSPacket->ProtocolId[1] = SK_RLMT_SPT_PROTOCOL_ID1;		pSPacket->ProtocolVersionId = SK_RLMT_SPT_PROTOCOL_VERSION_ID;		pSPacket->BpduType = SK_RLMT_SPT_BPDU_TYPE;		pSPacket->Flags = SK_RLMT_SPT_FLAGS;		pSPacket->RootId[0] = SK_RLMT_SPT_ROOT_ID0;		pSPacket->RootId[1] = SK_RLMT_SPT_ROOT_ID1;		pSPacket->RootPathCost[0] = SK_RLMT_SPT_ROOT_PATH_COST0;		pSPacket->RootPathCost[1] = SK_RLMT_SPT_ROOT_PATH_COST1;		pSPacket->RootPathCost[2] = SK_RLMT_SPT_ROOT_PATH_COST2;		pSPacket->RootPathCost[3] = SK_RLMT_SPT_ROOT_PATH_COST3;		pSPacket->BridgeId[0] = SK_RLMT_SPT_BRIDGE_ID0;		pSPacket->BridgeId[1] = SK_RLMT_SPT_BRIDGE_ID1;		/*		 * Use logical MAC address as bridge ID and filter these packets		 * on receive.		 */		for (i = 0; i < SK_MAC_ADDR_LEN; i++) {			pSPacket->BridgeId[i + 2] = pSPacket->RootId[i + 2] =				pAC->Addr.Net[pAC->Rlmt.Port[PortNumber].Net->NetNumber].					CurrentMacAddress.a[i];		}		pSPacket->PortId[0] = SK_RLMT_SPT_PORT_ID0;		pSPacket->PortId[1] = SK_RLMT_SPT_PORT_ID1;		pSPacket->MessageAge[0] = SK_RLMT_SPT_MSG_AGE0;		pSPacket->MessageAge[1] = SK_RLMT_SPT_MSG_AGE1;		pSPacket->MaxAge[0] = SK_RLMT_SPT_MAX_AGE0;		pSPacket->MaxAge[1] = SK_RLMT_SPT_MAX_AGE1;		pSPacket->HelloTime[0] = SK_RLMT_SPT_HELLO_TIME0;		pSPacket->HelloTime[1] = SK_RLMT_SPT_HELLO_TIME1;		pSPacket->ForwardDelay[0] = SK_RLMT_SPT_FWD_DELAY0;		pSPacket->ForwardDelay[1] = SK_RLMT_SPT_FWD_DELAY1;		Length = SK_RLMT_MAX_PACKET_SIZE;	/* Or smaller. */		pMb->Length = Length;		pMb->PortIdx = PortNumber;		Length -= 14;		SK_U16_TO_NETWORK_ORDER(Length, &pSPacket->TypeLen[0]);		pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++;	}	return (pMb);}	/* SkRlmtBuildSpanningTreePacket *//****************************************************************************** * *	SkRlmtSend - build and send check packets * * Description: *	Depending on the RLMT state and the checking state, several packets *	are sent through the indicated port. * * Context: *	runtime, pageable? * * Returns: *	Nothing. */RLMT_STATIC void	SkRlmtSend(SK_AC	*pAC,		/* Adapter Context */SK_IOC	IoC,		/* I/O Context */SK_U32	PortNumber)	/* Sending port */{	unsigned	j;	SK_EVPARA	Para;	SK_RLMT_PORT	*pRPort;	pRPort = &pAC->Rlmt.Port[PortNumber];	if (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {		if (pRPort->CheckingState & (SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) {			/* Port is suspicious. Send the RLMT packet to the RLMT mc addr. */			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);			}		}		else {			/*			 * Send a directed RLMT packet to all ports that are			 * checked by the indicated port.			 */			for (j = 0; j < pRPort->PortsChecked; j++) {				if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,					SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,					&pRPort->PortCheck[j].CheckAddr)) != NULL) {					SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);				}			}		}	}	if ((pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&		(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEND_SEG)) {		/*		 * Send a BPDU packet to make a connected switch tell us		 * the correct root bridge.		 */		if ((Para.pParaPtr =			SkRlmtBuildSpanningTreePacket(pAC, IoC, PortNumber)) != NULL) {			pAC->Rlmt.Port[PortNumber].Net->CheckingState &= ~SK_RLMT_RCS_SEND_SEG;			pRPort->RootIdSet = SK_FALSE;			SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);			SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX,				("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber))		}	}	return;}	/* SkRlmtSend *//****************************************************************************** * *	SkRlmtPortReceives - check if port is (going) down and bring it up * * Description: *	This routine checks if a port who received a non-BPDU packet *	needs to go up or needs to be stopped going down. * * Context: *	runtime, pageable? * * Returns: *	Nothing. */RLMT_STATIC void	SkRlmtPortReceives(SK_AC	*pAC,			/* Adapter Context */SK_IOC	IoC,			/* I/O Context */SK_U32	PortNumber)		/* Port to check */{	SK_RLMT_PORT	*pRPort;	SK_EVPARA		Para;	pRPort = &pAC->Rlmt.Port[PortNumber];	pRPort->PortNoRx = SK_FALSE;	if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&		!(pRPort->CheckingState & SK_RLMT_PCS_TX)) {		/*		 * Port is marked down (rx), but received a non-BPDU packet.		 * Bring it up.		 */		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,			("SkRlmtPacketReceive: Received on PortDown.\n"))		pRPort->PortState = SK_RLMT_PS_GOING_UP;		pRPort->GuTimeStamp = SkOsGetTime(pAC);		Para.Para32[0] = PortNumber;		Para.Para32[1] = (SK_U32)-1;		SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,			SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para);		pRPort->CheckingState &= ~SK_RLMT_PCS_RX;		/* pAC->Rlmt.CheckSwitch = SK_TRUE; */		SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);	}	/* PortDown && !SuspectTx */	else if (pRPort->CheckingState & SK_RLMT_PCS_RX) {		SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,			("SkRlmtPacketReceive: Stop bringing port down.\n"))		SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);		pRPort->CheckingState &= ~SK_RLMT_PCS_RX;		/* pAC->Rlmt.CheckSwitch = SK_TRUE; */		SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);	}	/* PortGoingDown */	return;}	/* SkRlmtPortReceives *//****************************************************************************** * *	SkRlmtPacketReceive - receive a packet for closer examination * * Description: *	This routine examines a packet more closely than SK_RLMT_LOOKAHEAD. * * Context: *	runtime, pageable? * * Returns: *	Nothing. */RLMT_STATIC void	SkRlmtPacketReceive(SK_AC	*pAC,	/* Adapter Context */SK_IOC	IoC,	/* I/O Context */SK_MBUF	*pMb)	/* Received packet */{#ifdef xDEBUG	extern	void DumpData(char *p, int size);#endif	/* DEBUG */	int					i;	unsigned			j;	SK_U16				PacketType;

⌨️ 快捷键说明

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