📄 skaddr.c
字号:
/****************************************************************************** * * 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 + -