📄 skaddr.c
字号:
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 physical MAC address. */ OutAddr = (SK_U16 *) pNewAddr; if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr); } else { GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, 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); } } /* * In case that the physical and the logical MAC addresses are equal * we must also change the physical MAC address here. * In this case we have an adapter which initially was programmed with * two identical MAC addresses. */ if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a, pAC->Addr.Port[PortNumber].Exact[0].a)) { pAC->Addr.Port[PortNumber].PreviousMacAddress = pAC->Addr.Port[PortNumber].CurrentMacAddress; pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr; /* Report address change to RLMT. */ Para.Para32[0] = PortNumber; Para.Para32[0] = -1; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para); } /* 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, ("SkAddrOverride: 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, ("SkAddrOverride: 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 * * It calls either SkAddrXmacPromiscuousChange or * SkAddrGmacPromiscuousChange, according to the adapter in use. * The real work is done there. * * 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 ReturnCode; if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { ReturnCode = SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); } else { ReturnCode = SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); } return (ReturnCode);} /* SkAddrPromiscuousChange *//****************************************************************************** * * SkAddrXmacPromiscuousChange - 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 SkAddrXmacPromiscuousChange(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; /* Read CurPromMode from Hardware. */ XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); if ((LoMode & XM_MD_ENA_PROM) != 0) { /* Promiscuous mode! */ 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 { /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */ XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0; /* Read 64-bit hash register from XMAC */ 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); /* Enable Hashing */ SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); } 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) { /* Disable Hashing */ SkMacHashing(pAC, IoC, PortNumber, SK_FALSE); } else { /* Set 64-bit hash register to InexactFilter. */ XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]); /* Enable Hashing */ SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); } } if ((NewPromMode & SK_PROM_MODE_LLC) && !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */ /* Set the MAC in Promiscuous Mode */ SkMacPromiscMode(pAC, IoC, PortNumber, SK_TRUE); } else if ((CurPromMode & SK_PROM_MODE_LLC) && !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC. */ /* Clear Promiscuous Mode */ SkMacPromiscMode(pAC, IoC, PortNumber, SK_FALSE); } return (SK_ADDR_SUCCESS);} /* SkAddrXmacPromiscuousChange *//****************************************************************************** * * SkAddrGmacPromiscuousChange - 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 SkAddrGmacPromiscuousChange(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* I/O context */SK_U32 PortNumber, /* port whose promiscuous mode changes */int NewPromMode) /* new promiscuous mode */{ SK_U16 ReceiveControl; /* GMAC Receive Control Register */ int CurPromMode = SK_PROM_MODE_NONE; /* Read CurPromMode from Hardware. */ GM_IN16(IoC, PortNumber, GM_RX_CTRL, &ReceiveControl); if ((ReceiveControl & (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)) == 0) { /* Promiscuous mode! */ CurPromMode |= SK_PROM_MODE_LLC; } if ((ReceiveControl & GM_RXCR_MCF_ENA) == 0) { /* All Multicast mode! */ CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & 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. */ GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); /* Enable Hashing */ SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); } if ((CurPromMode & SK_PROM_MODE_ALL_MC) && !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */ /* Set 64-bit hash register to InexactFilter. */ GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]); /* Enable Hashing. */ SkMacHashing(pAC, IoC, PortNumber, SK_TRUE); } if ((NewPromMode & SK_PROM_MODE_LLC) && !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */ /* Set the MAC to Promiscuous Mode. */ SkMacPromiscMode(pAC, IoC, PortNumber, SK_TRUE); } else if ((CurPromMode & SK_PROM_MODE_LLC) && !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC */ /* Clear Promiscuous Mode. */ SkMacPromiscMode(pAC, IoC, PortNumber, SK_FALSE); } return (SK_ADDR_SUCCESS);} /* SkAddrGmacPromiscuousChange *//****************************************************************************** * * 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 (GEnesis and Yukon) * Yukon uses first entry for the logical MAC * address (stored in the second GMAC register). * - FirstExactMatchRlmt (GEnesis only) * - NextExactMatchRlmt (GEnesis only) * - FirstExactMatchDrv (GEnesis only) * - NextExactMatchDrv (GEnesis only) * - 64-bit filter (InexactFilter) * - 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; if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { 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 */#endif /* CONFIG_SK98 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -