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

📄 skaddr.c

📁 上传linux-jx2410的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************** * *	SkAddrOverride - override a port's MAC address * * Description: *	This routine overrides the MAC address of one port. * * Context: *	runtime, pageable *	may be called after SK_INIT_IO * * Returns: *	SK_ADDR_SUCCESS if successful. *	SK_ADDR_DUPLICATE_ADDRESS if duplicate MAC address. *	SK_ADDR_MULTICAST_ADDRESS if multicast or broadcast address. *	SK_ADDR_TOO_EARLY if SK_INIT_IO was not executed before. */int	SkAddrOverride(SK_AC		*pAC,		/* adapter context */SK_IOC		IoC,		/* I/O context */SK_U32		PortNumber,	/* Port Number */SK_MAC_ADDR	*pNewAddr,	/* new MAC address */int			Flags)		/* logical/physical MAC address */{	SK_EVPARA	Para;	SK_U32		NetNumber;	SK_U32		i;	SK_U16		*OutAddr;	NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber;	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {		return (SK_ADDR_ILLEGAL_PORT);	}	if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) {		return (SK_ADDR_MULTICAST_ADDRESS);	}	if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) {		return (SK_ADDR_TOO_EARLY);	}	if (Flags & SK_ADDR_SET_LOGICAL) {	/* Activate logical MAC address. */		/* Parameter *pNewAddr is ignored. */		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {			if (!pAC->Addr.Port[i].CurrentMacAddressSet) {				return (SK_ADDR_TOO_EARLY);			}		}		/* Set PortNumber to number of net's active port. */		PortNumber = pAC->Rlmt.Net[NetNumber].			Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;		pAC->Addr.Port[PortNumber].Exact[0] =			pAC->Addr.Net[NetNumber].CurrentMacAddress;		/* Write address to first exact match entry of active port. */		(void)SkAddrMcUpdate(pAC, IoC, PortNumber);	}	else if (Flags & SK_ADDR_CLEAR_LOGICAL) {		/* Deactivate logical MAC address. */		/* Parameter *pNewAddr is ignored. */		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {			if (!pAC->Addr.Port[i].CurrentMacAddressSet) {				return (SK_ADDR_TOO_EARLY);			}		}		/* Set PortNumber to number of net's active port. */		PortNumber = pAC->Rlmt.Net[NetNumber].			Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;		for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) {			pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0;		}		/* Write address to first exact match entry of active port. */		(void)SkAddrMcUpdate(pAC, IoC, PortNumber);	}	else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) {	/* Physical MAC address. */		if (SK_ADDR_EQUAL(pNewAddr->a,			pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {			return (SK_ADDR_DUPLICATE_ADDRESS);		}		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {			if (!pAC->Addr.Port[i].CurrentMacAddressSet) {				return (SK_ADDR_TOO_EARLY);			}			if (SK_ADDR_EQUAL(pNewAddr->a,				pAC->Addr.Port[i].CurrentMacAddress.a)) {				if (i == PortNumber) {					return (SK_ADDR_SUCCESS);				}				else {					return (SK_ADDR_DUPLICATE_ADDRESS);				}			}		}		pAC->Addr.Port[PortNumber].PreviousMacAddress =			pAC->Addr.Port[PortNumber].CurrentMacAddress;		pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;		/* Change port's address. */		OutAddr = (SK_U16 *)pNewAddr;		XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);		/* Report address change to RLMT. */		Para.Para32[0] = PortNumber;		Para.Para32[0] = -1;		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);	}	else {	/* Logical MAC address. */		if (SK_ADDR_EQUAL(pNewAddr->a,			pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {			return (SK_ADDR_SUCCESS);		}				for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {			if (!pAC->Addr.Port[i].CurrentMacAddressSet) {				return (SK_ADDR_TOO_EARLY);			}			if (SK_ADDR_EQUAL(pNewAddr->a,				pAC->Addr.Port[i].CurrentMacAddress.a)) {				return (SK_ADDR_DUPLICATE_ADDRESS);			}		}		/* Set PortNumber to number of net's active port. */		PortNumber = pAC->Rlmt.Net[NetNumber].			Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;		pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr;		pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr;#ifdef DEBUG		SK_DBG_MSG(			pAC,			SK_DBGMOD_ADDR,			SK_DBGCAT_CTRL,			("Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n",				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0],				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1],				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2],				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3],				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4],				pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5]))		SK_DBG_MSG(			pAC,			SK_DBGMOD_ADDR,			SK_DBGCAT_CTRL,			("New logical MAC Address: %02X %02X %02X %02X %02X %02X\n",				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0],				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1],				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2],				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3],				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4],				pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5]))#endif	/* DEBUG */		/* Write address to first exact match entry of active port. */		(void)SkAddrMcUpdate(pAC, IoC, PortNumber);	}	return (SK_ADDR_SUCCESS);}	/* SkAddrOverride *//****************************************************************************** * *	SkAddrPromiscuousChange - set promiscuous mode for given port * * Description: *	This routine manages promiscuous mode: *	- none *	- all LLC frames *	- all MC frames * * Context: *	runtime, pageable *	may be called after SK_INIT_IO * * Returns: *	SK_ADDR_SUCCESS *	SK_ADDR_ILLEGAL_PORT */int	SkAddrPromiscuousChange(SK_AC	*pAC,			/* adapter context */SK_IOC	IoC,			/* I/O context */SK_U32	PortNumber,		/* port whose promiscuous mode changes */int		NewPromMode)	/* new promiscuous mode */{	int			i;	SK_BOOL		InexactModeBit;	SK_U8		Inexact;	SK_U8		HwInexact;	SK_FILTER64	HwInexactFilter;	SK_U16		LoMode;		/* Lower 16 bits of XMAC Mode Register. */	int			CurPromMode = SK_PROM_MODE_NONE;	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {		return (SK_ADDR_ILLEGAL_PORT);	}	/* Read CurPromMode from Hardware. */	XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);	if (LoMode & XM_MD_ENA_PROM) {		CurPromMode |= SK_PROM_MODE_LLC;	}		for (Inexact = 0xFF, i = 0; i < 8; i++) {		Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];	}	if (Inexact == 0xFF) {		CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);	}	else {		/* Read InexactModeBit (bit 15 in mode register). */		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);				InexactModeBit = (LoMode & XM_MD_ENA_HSH) != 0;		/* Read 64-bit hash register from HW. */		XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]);		for (HwInexact = 0xFF, i = 0; i < 8; i++) {			HwInexact &= HwInexactFilter.Bytes[i];		}		if (InexactModeBit && (HwInexact == 0xFF)) {			CurPromMode |= SK_PROM_MODE_ALL_MC;		}	}	pAC->Addr.Port[PortNumber].PromMode = NewPromMode;	if (NewPromMode == CurPromMode) {		return (SK_ADDR_SUCCESS);	}	if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&		!(CurPromMode & SK_PROM_MODE_ALL_MC)) {	/* All MC. */		/* Set all bits in 64-bit hash register. */		XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);		/* Set bit 15 in mode register. */		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);		LoMode |= XM_MD_ENA_HSH;		XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);	}	else if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&		!(NewPromMode & SK_PROM_MODE_ALL_MC)) {	/* Norm MC. */		for (Inexact = 0, i = 0; i < 8; i++) {			Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];		}		if (Inexact == 0) {			/* Clear bit 15 in mode register. */			XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);			LoMode &= ~XM_MD_ENA_HSH;			XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);		}		else {			/* Set 64-bit hash register to InexactFilter. */			XM_OUTHASH(				IoC,				PortNumber,				XM_HSM,				&pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);			/* Set bit 15 in mode register. */			XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);			LoMode |= XM_MD_ENA_HSH;			XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);		}	}	if ((NewPromMode & SK_PROM_MODE_LLC) &&		!(CurPromMode & SK_PROM_MODE_LLC)) {	/* Prom. LLC */		/* Set promiscuous bit in mode register. */		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);#if 0		/* Receive MAC frames. */		LoMode |= XM_MD_RX_MCTRL;#endif	/* 0 */		LoMode |= XM_MD_ENA_PROM;		XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);	}	else if ((CurPromMode & SK_PROM_MODE_LLC) &&		!(NewPromMode & SK_PROM_MODE_LLC)) {	/* Norm. LLC. */		/* Clear promiscuous bit in mode register. */		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);#if 0		/* Don't receive MAC frames. */		LoMode &= ~XM_MD_RX_MCTRL;#endif	/* 0 */				LoMode &= ~XM_MD_ENA_PROM;		XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);	}		return (SK_ADDR_SUCCESS);}	/* SkAddrPromiscuousChange *//****************************************************************************** * *	SkAddrSwap - swap address info * * Description: *	This routine swaps address info of two ports. * * Context: *	runtime, pageable *	may be called after SK_INIT_IO * * Returns: *	SK_ADDR_SUCCESS *	SK_ADDR_ILLEGAL_PORT */int	SkAddrSwap(SK_AC	*pAC,			/* adapter context */SK_IOC	IoC,			/* I/O context */SK_U32	FromPortNumber,	/* Port1 Index */SK_U32	ToPortNumber)		/* Port2 Index */{	int			i;	SK_U8		Byte;	SK_MAC_ADDR	MacAddr;	SK_U32		DWord;	if (FromPortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {		return (SK_ADDR_ILLEGAL_PORT);	}	if (ToPortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {		return (SK_ADDR_ILLEGAL_PORT);	}	if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) {		return (SK_ADDR_ILLEGAL_PORT);	}	/*	 * Swap	 * - Exact Match Entries	 * - FirstExactMatchRlmt;	 * - NextExactMatchRlmt;	 * - FirstExactMatchDrv;	 * - NextExactMatchDrv;	 * - 64-bit filter	 * - Promiscuous Mode	 * of ports.	 */	for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) {		MacAddr = pAC->Addr.Port[FromPortNumber].Exact[i];		pAC->Addr.Port[FromPortNumber].Exact[i] =			pAC->Addr.Port[ToPortNumber].Exact[i];		pAC->Addr.Port[ToPortNumber].Exact[i] = MacAddr;	}	for (i = 0; i < 8; i++) {		Byte = pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i];		pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i] =			pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i];		pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte;	}	i = pAC->Addr.Port[FromPortNumber].PromMode;	pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode;	pAC->Addr.Port[ToPortNumber].PromMode = i;	DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt;	pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt =		pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt;	pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord;	DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt;	pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt =		pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt;	pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord;	DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv;	pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv =		pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv;	pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord;	DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv;	pAC->Addr.Port[FromPortNumber].NextExactMatchDrv =		pAC->Addr.Port[ToPortNumber].NextExactMatchDrv;	pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord;	/* CAUTION: Solution works if only ports of one adapter are in use. */	for (i = 0; (SK_U32)i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].		Net->NetNumber].NumPorts; i++) {		if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].			Port[i]->PortNumber == ToPortNumber) {			pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].				ActivePort = i;			/* 20001207 RA: Was "ToPortNumber;". */		}	}	(void)SkAddrMcUpdate(pAC, IoC, FromPortNumber);	(void)SkAddrMcUpdate(pAC, IoC, ToPortNumber);	return (SK_ADDR_SUCCESS);}	/* SkAddrSwap */#ifdef __cplusplus}#endif	/* __cplusplus */

⌨️ 快捷键说明

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