📄 skaddr.c
字号:
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 *//****************************************************************************** * * 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 PortIdx, /* Port Index */SK_MAC_ADDR *pNewAddr, /* new MAC address */int Flags) /* logical/physical MAC address */{ 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) { return (SK_ADDR_ILLEGAL_PORT); } if (pNewAddr->a[0] & SK_MC_BIT) { return (SK_ADDR_MULTICAST_ADDRESS); }#if 0DANGEROUS! 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); } } else { if (!pAC->Addr.CurrentMacAddressSet) { pAC->Addr.CurrentMacAddress = *pNewAddr; pAC->Addr.CurrentMacAddressSet = SK_TRUE; return (SK_ADDR_SUCCESS); } }DANGEROUS!#endif /* 0 */ if (!pAC->Addr.CurrentMacAddressSet) { return (SK_ADDR_TOO_EARLY); } if (Flags & SK_ADDR_PHYSICAL_ADDRESS) { /* Physical MAC address. */ if (SK_ADDR_EQUAL(pNewAddr->a, pAC->Addr.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 == PortIdx) { return (SK_ADDR_SUCCESS); } else { return (SK_ADDR_DUPLICATE_ADDRESS); } } } pAC->Addr.Port[PortIdx].PreviousMacAddress = pAC->Addr.Port[PortIdx].CurrentMacAddress; pAC->Addr.Port[PortIdx].CurrentMacAddress = *pNewAddr; /* Change port's address. */ OutAddr = (SK_U16 *)pNewAddr; XM_OUTADDR(IoC, PortIdx, XM_SA, OutAddr); /* Report address change to RLMT. */ Para.Para32[0] = PortIdx; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para); } else { /* Logical MAC address. */ if (SK_ADDR_EQUAL(pNewAddr->a, pAC->Addr.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); } } pAC->Addr.CurrentMacAddress = *pNewAddr; pAC->Addr.Port[PortIdx].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.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])) 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]))#endif /* DEBUG */ /* Write address to first exact match entry of active port. */ (void)SkAddrMcUpdate(pAC, IoC, PortIdx); } 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 PortIdx, /* 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 (PortIdx >= (SK_U32)pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } /* Read CurPromMode from Hardware. */ XM_IN16(IoC, PortIdx, 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]; } if (Inexact == 0xFF) { CurPromMode |= (pAC->Addr.Port[PortIdx].PromMode & SK_PROM_MODE_ALL_MC); } else { /* Read InexactModeBit (bit 15 in mode register). */ XM_IN16(IoC, PortIdx, 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]); 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[PortIdx].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, PortIdx, XM_HSM, &OnesHash); /* Set bit 15 in mode register. */ XM_IN16(IoC, PortIdx, XM_MODE, &LoMode); LoMode |= XM_MD_ENA_HSH; XM_OUT16(IoC, PortIdx, 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]; } if (Inexact == 0) { /* Clear bit 15 in mode register. */ XM_IN16(IoC, PortIdx, XM_MODE, &LoMode); LoMode &= ~XM_MD_ENA_HSH; XM_OUT16(IoC, PortIdx, XM_MODE, LoMode); } else { /* Set 64-bit hash register to InexactFilter. */ XM_OUTHASH( IoC, PortIdx, XM_HSM, &pAC->Addr.Port[PortIdx].InexactFilter.Bytes[0]); /* Set bit 15 in mode register. */ XM_IN16(IoC, PortIdx, XM_MODE, &LoMode); LoMode |= XM_MD_ENA_HSH; XM_OUT16(IoC, PortIdx, 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);#if 0 /* Receive MAC frames. */ LoMode |= XM_MD_RX_MCTRL;#endif /* 0 */ LoMode |= XM_MD_ENA_PROM; XM_OUT16(IoC, PortIdx, 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);#if 0 /* Don't receive MAC frames. */ LoMode &= ~XM_MD_RX_MCTRL;#endif /* 0 */ LoMode &= ~XM_MD_ENA_PROM; XM_OUT16(IoC, PortIdx, 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 FromPortIdx, /* Port1 Index */SK_U32 ToPortIdx) /* Port2 Index */{ int i; SK_U8 Byte; SK_MAC_ADDR MacAddr; SK_U32 DWord; if (FromPortIdx >= (SK_U32)pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } if (ToPortIdx >= (SK_U32)pAC->GIni.GIMacsFound) { 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[FromPortIdx].Exact[i]; pAC->Addr.Port[FromPortIdx].Exact[i] = pAC->Addr.Port[ToPortIdx].Exact[i]; pAC->Addr.Port[ToPortIdx].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; (void)SkAddrMcUpdate(pAC, IoC, FromPortIdx); (void)SkAddrMcUpdate(pAC, IoC, ToPortIdx); return (SK_ADDR_SUCCESS);} /* SkAddrSwap */#ifdef __cplusplus}#endif /* __cplusplus */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -