From owner-freebsd-current@FreeBSD.ORG Fri Jun 18 23:58:42 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 83A8616A4CE for ; Fri, 18 Jun 2004 23:58:42 +0000 (GMT) Received: from mail-in-06.arcor-online.net (mail-in-06.arcor-online.net [151.189.21.46]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5F8F743D31 for ; Fri, 18 Jun 2004 23:58:41 +0000 (GMT) (envelope-from mailnull@mips.inka.de) Received: from kemoauc.mips.inka.de (dsl-213-023-057-185.arcor-ip.net [213.23.57.185]) by mail-in-06.arcor-online.net (Postfix) with ESMTP id 7D0DFFFC0D for ; Sat, 19 Jun 2004 01:58:09 +0200 (CEST) Received: from kemoauc.mips.inka.de (localhost [127.0.0.1]) i5INbfRt078044 for ; Sat, 19 Jun 2004 01:37:41 +0200 (CEST) (envelope-from mailnull@kemoauc.mips.inka.de) Received: (from mailnull@localhost) by kemoauc.mips.inka.de (8.12.11/8.12.11/Submit) id i5INbedA078043 for freebsd-current@freebsd.org; Sat, 19 Jun 2004 01:37:41 +0200 (CEST) (envelope-from mailnull) From: naddy@mips.inka.de (Christian Weisgerber) Date: Fri, 18 Jun 2004 23:37:40 +0000 (UTC) Message-ID: Originator: naddy@mips.inka.de (Christian Weisgerber) To: freebsd-current@freebsd.org Subject: Optimized ether_crc32_be() X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Jun 2004 23:58:42 -0000 Taken from kern/49957, here's a table-driven implementation of ether_crc32_be() to complement the little-endian one. For 6-byte MAC addresses it's about five times faster than the double loop. Comments? Index: net/if_ethersubr.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.172 diff -u -r1.172 if_ethersubr.c --- net/if_ethersubr.c 15 Jun 2004 23:57:41 -0000 1.172 +++ net/if_ethersubr.c 18 Jun 2004 23:28:37 -0000 @@ -883,9 +883,8 @@ #if 0 /* - * This is for reference. We have a table-driven version - * of the little-endian crc32 generator, which is faster - * than the double-loop. + * This is for reference. We have table-driven versions of the + * crc32 generators, which are faster than the double-loop. */ uint32_t ether_crc32_le(const uint8_t *buf, size_t len) @@ -907,6 +906,28 @@ return (crc); } + +uint32_t +ether_crc32_be(const uint8_t *buf, size_t len) +{ + size_t i; + uint32_t crc, carry; + int bit; + uint8_t data; + + crc = 0xffffffff; /* initial value */ + + for (i = 0; i < len; i++) { + for (data = *buf++, bit = 0; bit < 8; bit++, data >>= 1) { + carry = ((crc & 0x80000000) ? 1 : 0) ^ (data & 0x01); + crc <<= 1; + if (carry) + crc = (crc ^ ETHER_CRC_POLY_BE) | carry; + } + } + + return (crc); +} #else uint32_t ether_crc32_le(const uint8_t *buf, size_t len) @@ -930,29 +951,35 @@ return (crc); } -#endif uint32_t ether_crc32_be(const uint8_t *buf, size_t len) { + static const uint8_t rev[] = { + 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, + 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf + }; + static const uint32_t crctab[] = { + 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, + 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, + 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, + 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd + }; size_t i; - uint32_t crc, carry; - int bit; + uint32_t crc; uint8_t data; crc = 0xffffffff; /* initial value */ for (i = 0; i < len; i++) { - for (data = *buf++, bit = 0; bit < 8; bit++, data >>= 1) { - carry = ((crc & 0x80000000) ? 1 : 0) ^ (data & 0x01); - crc <<= 1; - if (carry) - crc = (crc ^ ETHER_CRC_POLY_BE) | carry; - } + data = buf[i]; + crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data & 0xf]]; + crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data >> 4]]; } return (crc); } +#endif int ether_ioctl(struct ifnet *ifp, int command, caddr_t data) -- Christian "naddy" Weisgerber naddy@mips.inka.de