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

📄 skaddr.c

📁 MIZI Research, Inc.发布的嵌入式Linux内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
				pAC,				SK_DBGMOD_ADDR,				SK_DBGCAT_INIT,				("Phsical MAC Address: %02X %02X %02X %02X %02X %02X\n",					pAPort->CurrentMacAddress.a[0],					pAPort->CurrentMacAddress.a[1],					pAPort->CurrentMacAddress.a[2],					pAPort->CurrentMacAddress.a[3],					pAPort->CurrentMacAddress.a[4],					pAPort->CurrentMacAddress.a[5]))#endif	/* DEBUG */		}		/* pAC->Addr.InitDone = SK_INIT_IO; */		break;	case SK_INIT_RUN:#ifdef DEBUG		for (i = 0; i < SK_MAX_MACS; i++) {			if (pAC->Addr.Port[i].NextExactMatchRlmt <				SK_ADDR_FIRST_MATCH_RLMT) {				Next0[i] |= 16;			}		}#endif	/* DEBUG */		/* pAC->Addr.InitDone = SK_INIT_RUN; */		break;	default:	/* error */		break;	}	return (SK_ADDR_SUCCESS);}	/* SkAddrInit *//****************************************************************************** * *	SkAddrMcClear - clear the multicast table * * Description: *	This routine clears the multicast table *	(either entry 2 or entries 3-16 and InexactFilter) of the given port. *	If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated *	immediately. * * Context: *	runtime, pageable *	may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY *	may be called after SK_INIT_IO without limitation * * Returns: *	SK_ADDR_SUCCESS *	SK_ADDR_ILLEGAL_PORT */int	SkAddrMcClear(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* I/O context */SK_U32	PortNumber,	/* Index of affected port */int		Flags)		/* permanent/non-perm, sw-only */{	int i;	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {		return (SK_ADDR_ILLEGAL_PORT);	}	if (Flags & SK_ADDR_PERMANENT) {		/* Clear RLMT multicast addresses. */		pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;	}	else {	/* not permanent => DRV */		/* Clear InexactFilter. */		for (i = 0; i < 8; i++) {			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;		}		/* Clear DRV multicast addresses. */		pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;	}	if (!(Flags & SK_MC_SW_ONLY)) {		(void)SkAddrMcUpdate(pAC, IoC, PortNumber);	}	return (SK_ADDR_SUCCESS);}	/* SkAddrMcClear */#ifndef SK_ADDR_CHEAT/****************************************************************************** * *	SkCrc32McHash - hash multicast address * * Description: *	This routine computes the hash value for a multicast address. * * Notes: *	The code was adapted from the XaQti data sheet. * * Context: *	runtime, pageable * * Returns: *	Hash value of multicast address. */unsigned SkCrc32McHash(unsigned char *pMc)	/* Multicast address */{	unsigned Idx;	unsigned Bit;	unsigned Data;	unsigned Crc;	Crc = 0xFFFFFFFFUL;	for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) {		Data = *pMc++;		for (Bit = 0; Bit < 8; Bit++, Data >>= 1) {			Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? CRC32_POLY : 0);		}	}	return (Crc & ((1 << HASH_BITS) - 1));}	/* SkCrc32McHash */#endif	/* not SK_ADDR_CHEAT *//****************************************************************************** * *	SkAddrMcAdd - add a multicast address to a port * * Description: *	This routine enables reception for a given address on the given port. * * Notes: *	The return code is only valid for SK_PROM_MODE_NONE. * *	In the current version, only RLMT may add addresses to the non-active *	port. * *	The multicast bit is only checked if there are no free exact match *	entries. * * Context: *	runtime, pageable *	may be called after SK_INIT_DATA * * Returns: *	SK_MC_FILTERING_EXACT *	SK_MC_FILTERING_INEXACT *	SK_MC_ILLEGAL_ADDRESS *	SK_MC_ILLEGAL_PORT *	SK_MC_RLMT_OVERFLOW */int	SkAddrMcAdd(SK_AC		*pAC,		/* adapter context */SK_IOC		IoC,		/* I/O context */SK_U32		PortNumber,	/* Port Number */SK_MAC_ADDR	*pMc,		/* multicast address to be added */int			Flags)		/* permanent/non-permanent */{	int	i;	SK_U8	Inexact;#ifndef SK_ADDR_CHEAT	unsigned HashBit;#endif	/* !defined(SK_ADDR_CHEAT) */	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {		return (SK_ADDR_ILLEGAL_PORT);	}	if (Flags & SK_ADDR_PERMANENT) {#ifdef DEBUG		if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt <			SK_ADDR_FIRST_MATCH_RLMT) {			Next0[PortNumber] |= 1;			return (SK_MC_RLMT_OVERFLOW);		}#endif	/* DEBUG */				if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt >			SK_ADDR_LAST_MATCH_RLMT) {			return (SK_MC_RLMT_OVERFLOW);		}		/* Set an RLMT multicast address. */		pAC->Addr.Port[PortNumber].Exact[			pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc;		return (SK_MC_FILTERING_EXACT);	}#if 0	/* Not PERMANENT => DRV */	if (PortNumber != pAC->Addr.ActivePort) {		/* Only RLMT is allowed to do this. */		return (SK_MC_ILLEGAL_PORT);	}#endif	/* 0 */#ifdef DEBUG	if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <		SK_ADDR_FIRST_MATCH_DRV) {			Next0[PortNumber] |= 2;		return (SK_MC_RLMT_OVERFLOW);	}#endif	/* DEBUG */		if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {		/* Set exact match entry. */		pAC->Addr.Port[PortNumber].Exact[			pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc;		/* Clear InexactFilter. */		for (i = 0; i < 8; i++) {			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;		}	}	else {		if (!(pMc->a[0] & SK_MC_BIT)) {			/*			 * Hashing only possible with			 * multicast addresses.			 */			return (SK_MC_ILLEGAL_ADDRESS);		}#ifndef SK_ADDR_CHEAT		/* Compute hash value of address. */		HashBit = 63 - SkCrc32McHash(&pMc->a[0]);		/* Add bit to InexactFilter. */		pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |=			1 << (HashBit % 8);#else	/* SK_ADDR_CHEAT */		/* Set all bits in InexactFilter. */		for (i = 0; i < 8; i++) {			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;		}#endif	/* SK_ADDR_CHEAT */	}	for (Inexact = 0, i = 0; i < 8; i++) {		Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];	}	if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) {		return (SK_MC_FILTERING_EXACT);	}	else {		return (SK_MC_FILTERING_INEXACT);	}}	/* SkAddrMcAdd *//****************************************************************************** * *	SkAddrMcUpdate - update the HW MC address table and set the MAC address * * Description: *	This routine enables reception of the addresses contained in a local *	table for a given port. *	It also programs the port's current physical MAC address. * * Notes: *	The return code is only valid for SK_PROM_MODE_NONE. * * Context: *	runtime, pageable *	may be called after SK_INIT_IO * * Returns: *	SK_MC_FILTERING_EXACT *	SK_MC_FILTERING_INEXACT *	SK_ADDR_ILLEGAL_PORT */int	SkAddrMcUpdate(SK_AC	*pAC,		/* adapter context */SK_IOC	IoC,		/* I/O context */SK_U32	PortNumber)	/* Port Number */{	SK_U32			i;	SK_U8			Inexact;	SK_U16			*OutAddr;	SK_U16			LoMode;		/* Lower 16 bits of XMAC Mode Reg. */	SK_ADDR_PORT	*pAPort;	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {		return (SK_ADDR_ILLEGAL_PORT);	}	SK_DBG_MSG(		pAC,		SK_DBGMOD_ADDR,		SK_DBGCAT_CTRL,		("SkAddrMcUpdate on Port %u.\n", PortNumber))		pAPort = &pAC->Addr.Port[PortNumber];#ifdef DEBUG		SK_DBG_MSG(			pAC,			SK_DBGMOD_ADDR,			SK_DBGCAT_CTRL,			("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))#endif	/* DEBUG */	/* Start with 0 to also program the logical MAC address. */	for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {		/* Set exact match address i on HW. */		OutAddr = (SK_U16 *)&pAPort->Exact[i].a[0];		XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);	}	/* Clear other permanent exact match addresses on HW. */	if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) {		SkXmClrExactAddr(			pAC,			IoC,			PortNumber,			pAPort->NextExactMatchRlmt,			SK_ADDR_LAST_MATCH_RLMT);	}	for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) {		OutAddr = (SK_U16 *)&pAPort->Exact[i].a[0];		XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);	}	/* Clear other non-permanent exact match addresses on HW. */	if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {		SkXmClrExactAddr(			pAC,			IoC,			PortNumber,			pAPort->NextExactMatchDrv,			SK_ADDR_LAST_MATCH_DRV);	}	for (Inexact = 0, i = 0; i < 8; i++) {		Inexact |= pAPort->InexactFilter.Bytes[i];	}	if (pAPort->PromMode & SK_PROM_MODE_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 (Inexact != 0) {		/* Set 64-bit hash register to InexactFilter. */		XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->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);	}	else {		/* 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);	}	if (pAPort->PromMode != SK_PROM_MODE_NONE) {		(void)SkAddrPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);	}	/* Set port's current MAC address. */	OutAddr = (SK_U16 *)&pAPort->CurrentMacAddress.a[0];	XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);#ifdef xDEBUG	for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {		SK_U8		InAddr8[6];		SK_U16		*InAddr;		/* Get exact match address i from port PortNumber. */		InAddr = (SK_U16 *)&InAddr8[0];		XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr);		SK_DBG_MSG(			pAC,			SK_DBGMOD_ADDR,			SK_DBGCAT_CTRL,			("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x --  %02x %02x %02x %02x %02x %02x.\n",				i,				PortNumber,				InAddr8[0],				InAddr8[1],				InAddr8[2],				InAddr8[3],				InAddr8[4],				InAddr8[5],				pAPort->Exact[i].a[0],				pAPort->Exact[i].a[1],				pAPort->Exact[i].a[2],				pAPort->Exact[i].a[3],				pAPort->Exact[i].a[4],				pAPort->Exact[i].a[5]))	}#endif	/* DEBUG */			/* Determine return value. */	if (Inexact == 0 && pAPort->PromMode == 0) {		return (SK_MC_FILTERING_EXACT);	}	else {		return (SK_MC_FILTERING_INEXACT);	}}	/* SkAddrMcUpdate *//****************************************************************************** *

⌨️ 快捷键说明

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