📄 skaddr.c
字号:
default: /* error */ break; } return (SK_ADDR_SUCCESS);} /* SkAddrInit *//****************************************************************************** * * SkAddrMcClear - clear the multicast table * * Description: * This routine clears the multicast table. * * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated * immediately. * * It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according * to the adapter in use. The real work is done there. * * 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 ReturnCode; if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags); } else { ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags); } return (ReturnCode);} /* SkAddrMcClear *//****************************************************************************** * * SkAddrXmacMcClear - 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 SkAddrXmacMcClear(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 (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ /* 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) SkAddrXmacMcUpdate(pAC, IoC, PortNumber); } return (SK_ADDR_SUCCESS);} /* SkAddrXmacMcClear *//****************************************************************************** * * SkAddrGmacMcClear - clear the multicast table * * Description: * This routine clears the multicast hashing table (InexactFilter) * (either the RLMT or the driver bits) 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 SkAddrGmacMcClear(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;#ifdef DEBUG SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n", pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))#endif /* DEBUG */ /* Clear InexactFilter */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; } if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ /* Copy DRV bits to InexactFilter. */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i]; /* Clear InexactRlmtFilter. */ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0; } } else { /* not permanent => DRV */ /* Copy RLMT bits to InexactFilter. */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i]; /* Clear InexactDrvFilter. */ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0; } }#ifdef DEBUG SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n", pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))#endif /* DEBUG */ if (!(Flags & SK_MC_SW_ONLY)) { (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber); } return (SK_ADDR_SUCCESS);} /* SkAddrGmacMcClear */#ifndef SK_ADDR_CHEAT/****************************************************************************** * * SkXmacMcHash - hash multicast address * * Description: * This routine computes the hash value for a multicast address. * A CRC32 algorithm is used. * * Notes: * The code was adapted from the XaQti data sheet. * * Context: * runtime, pageable * * Returns: * Hash value of multicast address. */SK_U32 SkXmacMcHash(unsigned char *pMc) /* Multicast address */{ SK_U32 Idx; SK_U32 Bit; SK_U32 Data; SK_U32 Crc; Crc = 0xFFFFFFFFUL; for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) { Data = *pMc++; for (Bit = 0; Bit < 8; Bit++, Data >>= 1) { Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? XMAC_POLY : 0); } } return (Crc & ((1 << HASH_BITS) - 1));} /* SkXmacMcHash *//****************************************************************************** * * SkGmacMcHash - hash multicast address * * Description: * This routine computes the hash value for a multicast address. * A CRC16 algorithm is used. * * Notes: * * * Context: * runtime, pageable * * Returns: * Hash value of multicast address. */SK_U32 SkGmacMcHash(unsigned char *pMc) /* Multicast address */{ SK_U32 Data; SK_U32 TmpData; SK_U32 Crc; int Byte; int Bit; Crc = 0xFFFFFFFFUL; for (Byte = 0; Byte < 6; Byte++) { /* Get next byte. */ Data = (SK_U32) pMc[Byte]; /* Change bit order in byte. */ TmpData = Data; for (Bit = 0; Bit < 8; Bit++) { if (TmpData & 1L) { Data |= 1L << (7 - Bit); } else { Data &= ~(1L << (7 - Bit)); } TmpData >>= 1; } Crc ^= (Data << 24); for (Bit = 0; Bit < 8; Bit++) { if (Crc & 0x80000000) { Crc = (Crc << 1) ^ GMAC_POLY; } else { Crc <<= 1; } } } return (Crc & ((1 << HASH_BITS) - 1));} /* SkGmacMcHash */#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. * * It calls either SkAddrXmacMcAdd or SkAddrGmacMcAdd, according to the * adapter in use. The real work is done there. * * Notes: * The return code is only valid for SK_PROM_MODE_NONE. * * 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 ReturnCode; if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); } else { ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); } return (ReturnCode);} /* SkAddrMcAdd *//****************************************************************************** * * SkAddrXmacMcAdd - 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. * * 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_RLMT_OVERFLOW */int SkAddrXmacMcAdd(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 SK_U32 HashBit;#endif /* !defined(SK_ADDR_CHEAT) */ if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */#ifdef xDEBUG 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 a RLMT multicast address. */ pAC->Addr.Port[PortNumber].Exact[ pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc; return (SK_MC_FILTERING_EXACT); }#ifdef xDEBUG 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 - SkXmacMcHash(&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); }} /* SkAddrXmacMcAdd *//****************************************************************************** * * SkAddrGmacMcAdd - 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. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -