From owner-freebsd-current@FreeBSD.ORG Tue Jun 22 21:11:21 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 6BFCC16A4CF for ; Tue, 22 Jun 2004 21:11:21 +0000 (GMT) Received: from mail3.speakeasy.net (mail3.speakeasy.net [216.254.0.203]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4569943D1D for ; Tue, 22 Jun 2004 21:11:21 +0000 (GMT) (envelope-from jhb@FreeBSD.org) Received: (qmail 23283 invoked from network); 22 Jun 2004 21:11:17 -0000 Received: from dsl027-160-063.atl1.dsl.speakeasy.net (HELO server.baldwin.cx) ([216.27.160.63]) (envelope-sender ) encrypted SMTP for ; 22 Jun 2004 21:11:17 -0000 Received: from 10.50.41.233 (gw1.twc.weather.com [216.133.140.1]) by server.baldwin.cx (8.12.11/8.12.11) with ESMTP id i5MLBCBN019714; Tue, 22 Jun 2004 17:11:13 -0400 (EDT) (envelope-from jhb@FreeBSD.org) From: John Baldwin To: freebsd-current@FreeBSD.org Date: Tue, 22 Jun 2004 17:12:13 -0400 User-Agent: KMail/1.6 References: In-Reply-To: MIME-Version: 1.0 Content-Disposition: inline Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <200406221712.13015.jhb@FreeBSD.org> X-Spam-Checker-Version: SpamAssassin 2.63 (2004-01-11) on server.baldwin.cx cc: Christian Weisgerber Subject: Re: 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: Tue, 22 Jun 2004 21:11:21 -0000 On Friday 18 June 2004 07:37 pm, Christian Weisgerber wrote: > 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? Doesn't look like anyone responded. Perhaps ask someone on sparc64 to test it along with some simple multicast test? (Use mtest to join a group, turn on bmcastecho and then ping the multicast group to see if it responds?) > 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) -- John Baldwin <>< http://www.FreeBSD.org/~jhb/ "Power Users Use the Power to Serve" = http://www.FreeBSD.org