patch-2.4.7 linux/drivers/net/sk98lin/skaddr.c

Next file: linux/drivers/net/sk98lin/skcsum.c
Previous file: linux/drivers/net/sk98lin/h/xmac_ii.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.6/linux/drivers/net/sk98lin/skaddr.c linux/drivers/net/sk98lin/skaddr.c
@@ -2,16 +2,15 @@
  *
  * Name:	skaddr.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.36 $
- * Date:	$Date: 2000/08/07 11:10:39 $
+ * Version:	$Revision: 1.40 $
+ * Date:	$Date: 2001/02/14 14:04:59 $
  * Purpose:	Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2000 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
+ *	(C)Copyright 1998-2001 SysKonnect GmbH.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -27,6 +26,18 @@
  * History:
  *
  *	$Log: skaddr.c,v $
+ *	Revision 1.40  2001/02/14 14:04:59  rassmann
+ *	Editorial changes.
+ *	
+ *	Revision 1.39  2001/01/30 10:30:04  rassmann
+ *	Editorial changes.
+ *	
+ *	Revision 1.38  2001/01/25 16:26:52  rassmann
+ *	Ensured that logical address overrides are done on net's active port.
+ *	
+ *	Revision 1.37  2001/01/22 13:41:34  rassmann
+ *	Supporting two nets on dual-port adapters.
+ *	
  *	Revision 1.36  2000/08/07 11:10:39  rassmann
  *	Editorial changes.
  *	
@@ -172,7 +183,7 @@
 
 #ifndef	lint
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skaddr.c,v 1.36 2000/08/07 11:10:39 rassmann Exp $ (C) SysKonnect.";
+	"@(#) $Id: skaddr.c,v 1.40 2001/02/14 14:04:59 rassmann Exp $ (C) SysKonnect.";
 #endif	/* !defined(lint) */
 
 #define __SKADDR_C
@@ -300,7 +311,9 @@
 		break;
 
 	case SK_INIT_IO:
-		pAC->Addr.ActivePort = pAC->Rlmt.MacActive;
+		for (i = 0; i < SK_MAX_NETS; i++) {
+			pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort;
+		}
 		
 #ifdef DEBUG
 		for (i = 0; i < SK_MAX_MACS; i++) {
@@ -313,23 +326,33 @@
 
 		/* Read permanent logical MAC address from Control Register File. */
 		for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
-			InAddr = (SK_U8 *)&pAC->Addr.PermanentMacAddress.a[j];
+			InAddr = (SK_U8 *)&pAC->Addr.Net[0].PermanentMacAddress.a[j];
 			SK_IN8(IoC, B2_MAC_1 + j, InAddr);
 		}
 
-		if (!pAC->Addr.CurrentMacAddressSet) {
-			/*
-			 * Set the current logical MAC address
-			 * to the permanent one.
-			 */
-			pAC->Addr.CurrentMacAddress =
-				pAC->Addr.PermanentMacAddress;
-			pAC->Addr.CurrentMacAddressSet = SK_TRUE;
+		if (!pAC->Addr.Net[0].CurrentMacAddressSet) {
+			/* Set the current logical MAC address to the permanent one. */
+			pAC->Addr.Net[0].CurrentMacAddress =
+				pAC->Addr.Net[0].PermanentMacAddress;
+			pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE;
 		}
 
 		/* Set the current logical MAC address. */
-		pAC->Addr.Port[pAC->Addr.ActivePort].Exact[0] =
-			pAC->Addr.CurrentMacAddress;
+		pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] =
+			pAC->Addr.Net[0].CurrentMacAddress;
+
+#if SK_MAX_NETS > 1
+		/* Set logical MAC address for net 2 to (log | 3). */
+		if (!pAC->Addr.Net[1].CurrentMacAddressSet) {
+			pAC->Addr.Net[1].PermanentMacAddress =
+				pAC->Addr.Net[0].PermanentMacAddress;
+			pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3;
+			/* Set the current logical MAC address to the permanent one. */
+			pAC->Addr.Net[1].CurrentMacAddress =
+				pAC->Addr.Net[1].PermanentMacAddress;
+			pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE;
+		}
+#endif	/* SK_MAX_NETS > 1 */
 
 #ifdef xDEBUG
 		SK_DBG_MSG(
@@ -365,10 +388,7 @@
 		for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
 			pAPort = &pAC->Addr.Port[i];
 
-			/*
-			 * Read permanent port addresses from
-			 * Control Register File.
-			 */
+			/* Read permanent port addresses from Control Register File. */
 			for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
 				InAddr = (SK_U8 *)&pAPort->PermanentMacAddress.a[j];
 				SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr);
@@ -376,9 +396,8 @@
 
 			if (!pAPort->CurrentMacAddressSet) {
 				/*
-				 * Set the current and previous physical
-				 * MAC address of this port to its permanent
-				 * MAC address.
+				 * Set the current and previous physical MAC address
+				 * of this port to its permanent MAC address.
 				 */
 				pAPort->CurrentMacAddress = pAPort->PermanentMacAddress;
 				pAPort->PreviousMacAddress = pAPort->PermanentMacAddress;
@@ -460,35 +479,35 @@
 int	SkAddrMcClear(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* I/O context */
-SK_U32	PortIdx,	/* Index of affected port */
+SK_U32	PortNumber,	/* Index of affected port */
 int		Flags)		/* permanent/non-perm, sw-only */
 {
 	int i;
 
-	if (PortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {
 		return (SK_ADDR_ILLEGAL_PORT);
 	}
 
 	if (Flags & SK_ADDR_PERMANENT) {
 
 		/* Clear RLMT multicast addresses. */
-		pAC->Addr.Port[PortIdx].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
+		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[PortIdx].InexactFilter.Bytes[i] = 0;
+			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
 		}
 
 		/* Clear DRV multicast addresses. */
 
-		pAC->Addr.Port[PortIdx].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
+		pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
 	}
 
 	if (!(Flags & SK_MC_SW_ONLY)) {
-		(void)SkAddrMcUpdate(pAC, IoC, PortIdx);
+		(void)SkAddrMcUpdate(pAC, IoC, PortNumber);
 	}
 
 	return (SK_ADDR_SUCCESS);
@@ -563,7 +582,7 @@
 int	SkAddrMcAdd(
 SK_AC		*pAC,		/* adapter context */
 SK_IOC		IoC,		/* I/O context */
-SK_U32		PortIdx,	/* Port Index */
+SK_U32		PortNumber,	/* Port Number */
 SK_MAC_ADDR	*pMc,		/* multicast address to be added */
 int			Flags)		/* permanent/non-permanent */
 {
@@ -573,56 +592,57 @@
 	unsigned HashBit;
 #endif	/* !defined(SK_ADDR_CHEAT) */
 
-	if (PortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {
 		return (SK_ADDR_ILLEGAL_PORT);
 	}
 
 	if (Flags & SK_ADDR_PERMANENT) {
 #ifdef DEBUG
-		if (pAC->Addr.Port[PortIdx].NextExactMatchRlmt <
+		if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt <
 			SK_ADDR_FIRST_MATCH_RLMT) {
-			Next0[PortIdx] |= 1;
+			Next0[PortNumber] |= 1;
 			return (SK_MC_RLMT_OVERFLOW);
 		}
 #endif	/* DEBUG */
 		
-		if (pAC->Addr.Port[PortIdx].NextExactMatchRlmt >
+		if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt >
 			SK_ADDR_LAST_MATCH_RLMT) {
 			return (SK_MC_RLMT_OVERFLOW);
 		}
 
 		/* Set an RLMT multicast address. */
 
-		pAC->Addr.Port[PortIdx].Exact[
-			pAC->Addr.Port[PortIdx].NextExactMatchRlmt++] = *pMc;
+		pAC->Addr.Port[PortNumber].Exact[
+			pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc;
 
 		return (SK_MC_FILTERING_EXACT);
 	}
 
+#if 0
 	/* Not PERMANENT => DRV */
-	if (PortIdx != pAC->Addr.ActivePort) {
-
+	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[PortIdx].NextExactMatchDrv <
+	if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <
 		SK_ADDR_FIRST_MATCH_DRV) {
-			Next0[PortIdx] |= 2;
+			Next0[PortNumber] |= 2;
 		return (SK_MC_RLMT_OVERFLOW);
 	}
 #endif	/* DEBUG */
 	
-	if (pAC->Addr.Port[PortIdx].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
+	if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
 
 		/* Set exact match entry. */
-		pAC->Addr.Port[PortIdx].Exact[
-			pAC->Addr.Port[PortIdx].NextExactMatchDrv++] = *pMc;
+		pAC->Addr.Port[PortNumber].Exact[
+			pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc;
 
 		/* Clear InexactFilter. */
 		for (i = 0; i < 8; i++) {
-			pAC->Addr.Port[PortIdx].InexactFilter.Bytes[i] = 0;
+			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
 		}
 	}
 	else {
@@ -638,21 +658,21 @@
 		HashBit = 63 - SkCrc32McHash(&pMc->a[0]);
 
 		/* Add bit to InexactFilter. */
-		pAC->Addr.Port[PortIdx].InexactFilter.Bytes[HashBit / 8] |=
+		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[PortIdx].InexactFilter.Bytes[i] = 0xFF;
+			pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
 		}
 #endif	/* SK_ADDR_CHEAT */
 	}
 
 	for (Inexact = 0, i = 0; i < 8; i++) {
-		Inexact |= pAC->Addr.Port[PortIdx].InexactFilter.Bytes[i];
+		Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
 	}
 
-	if (Inexact == 0 && pAC->Addr.Port[PortIdx].PromMode == 0) {
+	if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) {
 		return (SK_MC_FILTERING_EXACT);
 	}
 	else {
@@ -685,7 +705,7 @@
 int	SkAddrMcUpdate(
 SK_AC	*pAC,		/* adapter context */
 SK_IOC	IoC,		/* I/O context */
-SK_U32	PortIdx)	/* Port Index */
+SK_U32	PortNumber)	/* Port Number */
 {
 	SK_U32			i;
 	SK_U8			Inexact;
@@ -693,7 +713,7 @@
 	SK_U16			LoMode;		/* Lower 16 bits of XMAC Mode Reg. */
 	SK_ADDR_PORT	*pAPort;
 
-	if (PortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {
 		return (SK_ADDR_ILLEGAL_PORT);
 	}
 
@@ -701,25 +721,23 @@
 		pAC,
 		SK_DBGMOD_ADDR,
 		SK_DBGCAT_CTRL,
-		("SkAddrMcUpdate on Port %u.\n", PortIdx))
+		("SkAddrMcUpdate on Port %u.\n", PortNumber))
 	
-	pAPort = &pAC->Addr.Port[PortIdx];
+	pAPort = &pAC->Addr.Port[PortNumber];
 
 #ifdef DEBUG
 		SK_DBG_MSG(
 			pAC,
 			SK_DBGMOD_ADDR,
 			SK_DBGCAT_CTRL,
-			("Next0 on Port %d: %d\n", PortIdx, Next0[PortIdx]))
+			("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
 #endif	/* DEBUG */
 
-	for (i = 0;		/* Also program the logical MAC address. */
-		i < pAPort->NextExactMatchRlmt;
-		i++) {
-
+	/* 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, PortIdx, XM_EXM(i), OutAddr);
+		XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
 	}
 
 	/* Clear other permanent exact match addresses on HW. */
@@ -727,14 +745,14 @@
 		SkXmClrExactAddr(
 			pAC,
 			IoC,
-			PortIdx,
+			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, PortIdx, XM_EXM(i), OutAddr);
+		XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
 	}
 
 	/* Clear other non-permanent exact match addresses on HW. */
@@ -742,7 +760,7 @@
 		SkXmClrExactAddr(
 			pAC,
 			IoC,
-			PortIdx,
+			PortNumber,
 			pAPort->NextExactMatchDrv,
 			SK_ADDR_LAST_MATCH_DRV);
 	}
@@ -753,54 +771,52 @@
 
 	if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
 		/* Set all bits in 64-bit hash register. */
-		XM_OUTHASH(IoC, PortIdx, XM_HSM, &OnesHash);
+		XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
 
 		/* Set bit 15 in mode register. */
-		XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 		LoMode |= XM_MD_ENA_HSH;
-		XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+		XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);
 	}
 	else if (Inexact != 0) {
 		/* Set 64-bit hash register to InexactFilter. */
-		XM_OUTHASH(IoC, PortIdx, XM_HSM, &pAPort->InexactFilter.Bytes[0]);
+		XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]);
 
 		/* Set bit 15 in mode register. */
-		XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 		LoMode |= XM_MD_ENA_HSH;
-		XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+		XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);
 	}
 	else {
 		/* Clear bit 15 in mode register. */
-		XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 		LoMode &= ~XM_MD_ENA_HSH;
-		XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+		XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);
 	}
 
 	if (pAPort->PromMode != SK_PROM_MODE_NONE) {
-		(void)SkAddrPromiscuousChange(pAC, IoC, PortIdx, pAPort->PromMode);
+		(void)SkAddrPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
 	}
 
 	/* Set port's current MAC address. */
 	OutAddr = (SK_U16 *)&pAPort->CurrentMacAddress.a[0];
-	XM_OUTADDR(IoC, PortIdx, XM_SA, OutAddr);
+	XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
 
-#ifdef DEBUG
-	for (i = 0;		/* Also program the logical MAC address. */
-		i < pAPort->NextExactMatchRlmt;
-		i++) {
+#ifdef xDEBUG
+	for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
 		SK_U8		InAddr8[6];
 		SK_U16		*InAddr;
 
-		/* Get exact match address i from port PortIdx. */
+		/* Get exact match address i from port PortNumber. */
 		InAddr = (SK_U16 *)&InAddr8[0];
-		XM_INADDR(IoC, PortIdx, XM_EXM(i), InAddr);
+		XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr);
 		SK_DBG_MSG(
 			pAC,
-			SK_DBGMOD_RLMT,
+			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,
-				PortIdx,
+				PortNumber,
 				InAddr8[0],
 				InAddr8[1],
 				InAddr8[2],
@@ -846,52 +862,70 @@
 int	SkAddrOverride(
 SK_AC		*pAC,		/* adapter context */
 SK_IOC		IoC,		/* I/O context */
-SK_U32		PortIdx,	/* Port Index */
+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;
-	SK_EVPARA	Para;
-#if 0
-	SK_MAC_ADDR	NewAddr;	/* new MAC address */
-	SK_U8		AddrBits;
-#endif	/* 0 */
 
-	if (PortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber;
+
+	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {
 		return (SK_ADDR_ILLEGAL_PORT);
 	}
 
-	if (pNewAddr->a[0] & SK_MC_BIT) {
+	if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) {
 		return (SK_ADDR_MULTICAST_ADDRESS);
 	}
 
-#if 0
-DANGEROUS!
-	if (Flags & SK_ADDR_PHYSICAL_ADDRESS) {	/* Physical address. */
-		if (!pAC->Addr.Port[PortIdx].CurrentMacAddressSet) {
-			pAC->Addr.Port[PortIdx].PreviousMacAddress = *pNewAddr;
-			pAC->Addr.Port[PortIdx].CurrentMacAddress = *pNewAddr;
-			pAC->Addr.Port[PortIdx].CurrentMacAddressSet = SK_TRUE;
-			return (SK_ADDR_SUCCESS);
-		}
+	if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) {
+		return (SK_ADDR_TOO_EARLY);
 	}
-	else {
-		if (!pAC->Addr.CurrentMacAddressSet) {
-			pAC->Addr.CurrentMacAddress = *pNewAddr;
-			pAC->Addr.CurrentMacAddressSet = SK_TRUE;
-			return (SK_ADDR_SUCCESS);
+
+	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);
+			}
 		}
-	}
-DANGEROUS!
-#endif	/* 0 */
 
-	if (!pAC->Addr.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;
+		}
 
-	if (Flags & SK_ADDR_PHYSICAL_ADDRESS) {	/* Physical MAC address. */
-		if (SK_ADDR_EQUAL(pNewAddr->a, pAC->Addr.CurrentMacAddress.a)) {
+		/* 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);
 		}
 
@@ -900,10 +934,9 @@
 				return (SK_ADDR_TOO_EARLY);
 			}
 
-			if (SK_ADDR_EQUAL(
-				pNewAddr->a,
+			if (SK_ADDR_EQUAL(pNewAddr->a,
 				pAC->Addr.Port[i].CurrentMacAddress.a)) {
-				if (i == PortIdx) {
+				if (i == PortNumber) {
 					return (SK_ADDR_SUCCESS);
 				}
 				else {
@@ -912,20 +945,22 @@
 			}
 		}
 
-		pAC->Addr.Port[PortIdx].PreviousMacAddress =
-			pAC->Addr.Port[PortIdx].CurrentMacAddress;
-		pAC->Addr.Port[PortIdx].CurrentMacAddress = *pNewAddr;
+		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, PortIdx, XM_SA, OutAddr);
+		XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
 
 		/* Report address change to RLMT. */
-		Para.Para32[0] = PortIdx;
+		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.CurrentMacAddress.a)) {
+		if (SK_ADDR_EQUAL(pNewAddr->a,
+			pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
 			return (SK_ADDR_SUCCESS);
 		}
 		
@@ -934,15 +969,18 @@
 				return (SK_ADDR_TOO_EARLY);
 			}
 
-			if (SK_ADDR_EQUAL(
-				pNewAddr->a,
+			if (SK_ADDR_EQUAL(pNewAddr->a,
 				pAC->Addr.Port[i].CurrentMacAddress.a)) {
 				return (SK_ADDR_DUPLICATE_ADDRESS);
 			}
 		}
 
-		pAC->Addr.CurrentMacAddress = *pNewAddr;
-		pAC->Addr.Port[PortIdx].Exact[0] = *pNewAddr;
+		/* 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(
@@ -950,27 +988,27 @@
 			SK_DBGMOD_ADDR,
 			SK_DBGCAT_CTRL,
 			("Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n",
-				pAC->Addr.PermanentMacAddress.a[0],
-				pAC->Addr.PermanentMacAddress.a[1],
-				pAC->Addr.PermanentMacAddress.a[2],
-				pAC->Addr.PermanentMacAddress.a[3],
-				pAC->Addr.PermanentMacAddress.a[4],
-				pAC->Addr.PermanentMacAddress.a[5]))
+				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.CurrentMacAddress.a[0],
-				pAC->Addr.CurrentMacAddress.a[1],
-				pAC->Addr.CurrentMacAddress.a[2],
-				pAC->Addr.CurrentMacAddress.a[3],
-				pAC->Addr.CurrentMacAddress.a[4],
-				pAC->Addr.CurrentMacAddress.a[5]))
+				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, PortIdx);
+		(void)SkAddrMcUpdate(pAC, IoC, PortNumber);
 	}
 
 	return (SK_ADDR_SUCCESS);
@@ -998,7 +1036,7 @@
 int	SkAddrPromiscuousChange(
 SK_AC	*pAC,			/* adapter context */
 SK_IOC	IoC,			/* I/O context */
-SK_U32	PortIdx,		/* port whose promiscuous mode changes */
+SK_U32	PortNumber,		/* port whose promiscuous mode changes */
 int		NewPromMode)	/* new promiscuous mode */
 {
 	int			i;
@@ -1009,31 +1047,31 @@
 	SK_U16		LoMode;		/* Lower 16 bits of XMAC Mode Register. */
 	int			CurPromMode = SK_PROM_MODE_NONE;
 
-	if (PortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	if (PortNumber >= (SK_U32)pAC->GIni.GIMacsFound) {
 		return (SK_ADDR_ILLEGAL_PORT);
 	}
 
 	/* Read CurPromMode from Hardware. */
-	XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+	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[PortIdx].InexactFilter.Bytes[i];
+		Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
 	}
 	if (Inexact == 0xFF) {
-		CurPromMode |= (pAC->Addr.Port[PortIdx].PromMode & SK_PROM_MODE_ALL_MC);
+		CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
 	}
 	else {
 		/* Read InexactModeBit (bit 15 in mode register). */
-		XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 		
 		InexactModeBit = (LoMode & XM_MD_ENA_HSH) != 0;
 
 		/* Read 64-bit hash register from HW. */
-		XM_INHASH(IoC, PortIdx, XM_HSM, &HwInexactFilter.Bytes[0]);
+		XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]);
 
 		for (HwInexact = 0xFF, i = 0; i < 8; i++) {
 			HwInexact &= HwInexactFilter.Bytes[i];
@@ -1044,7 +1082,7 @@
 		}
 	}
 
-	pAC->Addr.Port[PortIdx].PromMode = NewPromMode;
+	pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
 
 	if (NewPromMode == CurPromMode) {
 		return (SK_ADDR_SUCCESS);
@@ -1053,43 +1091,43 @@
 	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, PortIdx, XM_HSM, &OnesHash);
+		XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
 
 		/* Set bit 15 in mode register. */
-		XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 		LoMode |= XM_MD_ENA_HSH;
-		XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+		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[PortIdx].InexactFilter.Bytes[i];
+			Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
 		}
 		if (Inexact == 0) {
 			/* Clear bit 15 in mode register. */
-			XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+			XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 			LoMode &= ~XM_MD_ENA_HSH;
-			XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+			XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);
 		}
 		else {
 			/* Set 64-bit hash register to InexactFilter. */
 			XM_OUTHASH(
 				IoC,
-				PortIdx,
+				PortNumber,
 				XM_HSM,
-				&pAC->Addr.Port[PortIdx].InexactFilter.Bytes[0]);
+				&pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
 
 			/* Set bit 15 in mode register. */
-			XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+			XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 			LoMode |= XM_MD_ENA_HSH;
-			XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+			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, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 
 #if 0
 		/* Receive MAC frames. */
@@ -1097,12 +1135,12 @@
 #endif	/* 0 */
 
 		LoMode |= XM_MD_ENA_PROM;
-		XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+		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, PortIdx, XM_MODE, &LoMode);
+		XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
 
 #if 0
 		/* Don't receive MAC frames. */
@@ -1110,7 +1148,7 @@
 #endif	/* 0 */
 		
 		LoMode &= ~XM_MD_ENA_PROM;
-		XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
+		XM_OUT16(IoC, PortNumber, XM_MODE, LoMode);
 	}
 	
 	return (SK_ADDR_SUCCESS);
@@ -1135,19 +1173,23 @@
 int	SkAddrSwap(
 SK_AC	*pAC,			/* adapter context */
 SK_IOC	IoC,			/* I/O context */
-SK_U32	FromPortIdx,	/* Port1 Index */
-SK_U32	ToPortIdx)		/* Port2 Index */
+SK_U32	FromPortNumber,	/* Port1 Index */
+SK_U32	ToPortNumber)		/* Port2 Index */
 {
 	int			i;
 	SK_U8		Byte;
 	SK_MAC_ADDR	MacAddr;
 	SK_U32		DWord;
 
-	if (FromPortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	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 (ToPortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
+	if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) {
 		return (SK_ADDR_ILLEGAL_PORT);
 	}
 
@@ -1164,47 +1206,56 @@
 	 */
 
 	for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) {
-		MacAddr = pAC->Addr.Port[FromPortIdx].Exact[i];
-		pAC->Addr.Port[FromPortIdx].Exact[i] =
-			pAC->Addr.Port[ToPortIdx].Exact[i];
-		pAC->Addr.Port[ToPortIdx].Exact[i] = MacAddr;
+		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[FromPortIdx].InexactFilter.Bytes[i];
-		pAC->Addr.Port[FromPortIdx].InexactFilter.Bytes[i] =
-			pAC->Addr.Port[ToPortIdx].InexactFilter.Bytes[i];
-		pAC->Addr.Port[ToPortIdx].InexactFilter.Bytes[i] = Byte;
-	}
-
-	i = pAC->Addr.Port[FromPortIdx].PromMode;
-	pAC->Addr.Port[FromPortIdx].PromMode = pAC->Addr.Port[ToPortIdx].PromMode;
-	pAC->Addr.Port[ToPortIdx].PromMode = i;
-
-	DWord = pAC->Addr.Port[FromPortIdx].FirstExactMatchRlmt;
-	pAC->Addr.Port[FromPortIdx].FirstExactMatchRlmt =
-		pAC->Addr.Port[ToPortIdx].FirstExactMatchRlmt;
-	pAC->Addr.Port[ToPortIdx].FirstExactMatchRlmt = DWord;
-
-	DWord = pAC->Addr.Port[FromPortIdx].NextExactMatchRlmt;
-	pAC->Addr.Port[FromPortIdx].NextExactMatchRlmt =
-		pAC->Addr.Port[ToPortIdx].NextExactMatchRlmt;
-	pAC->Addr.Port[ToPortIdx].NextExactMatchRlmt = DWord;
-
-	DWord = pAC->Addr.Port[FromPortIdx].FirstExactMatchDrv;
-	pAC->Addr.Port[FromPortIdx].FirstExactMatchDrv =
-		pAC->Addr.Port[ToPortIdx].FirstExactMatchDrv;
-	pAC->Addr.Port[ToPortIdx].FirstExactMatchDrv = DWord;
-
-	DWord = pAC->Addr.Port[FromPortIdx].NextExactMatchDrv;
-	pAC->Addr.Port[FromPortIdx].NextExactMatchDrv =
-		pAC->Addr.Port[ToPortIdx].NextExactMatchDrv;
-	pAC->Addr.Port[ToPortIdx].NextExactMatchDrv = DWord;
-
-	pAC->Addr.ActivePort = ToPortIdx;
+		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, FromPortIdx);
-	(void)SkAddrMcUpdate(pAC, IoC, ToPortIdx);
+		}
+	}
+	(void)SkAddrMcUpdate(pAC, IoC, FromPortNumber);
+	(void)SkAddrMcUpdate(pAC, IoC, ToPortNumber);
 
 	return (SK_ADDR_SUCCESS);
 }	/* SkAddrSwap */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)