📄 skaddr.c
字号:
pAPort->PermanentMacAddress.a[4], pAPort->PermanentMacAddress.a[5])) SK_DBG_MSG( 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 */{ u32 Crc; Crc = ether_crc_le(SK_MAC_ADDR_LEN, pMc); 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 *//****************************************************************************** * * SkAddrOverride - override a port's MAC address *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -