From owner-freebsd-current@FreeBSD.ORG Thu Jun 3 12:50:40 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 7833A16A4CF for ; Thu, 3 Jun 2004 12:50:40 -0700 (PDT) Received: from mail-in-02.arcor-online.net (mail-in-02.arcor-online.net [151.189.21.42]) by mx1.FreeBSD.org (Postfix) with ESMTP id AF66443D3F for ; Thu, 3 Jun 2004 12:50:39 -0700 (PDT) (envelope-from mailnull@mips.inka.de) Received: from kemoauc.mips.inka.de (dsl-213-023-058-089.arcor-ip.net [213.23.58.89]) by mail-in-02.arcor-online.net (Postfix) with ESMTP id 2B7FABBA95F for ; Thu, 3 Jun 2004 21:50:38 +0200 (CEST) Received: from kemoauc.mips.inka.de (localhost [127.0.0.1]) i53JobJt094294 for ; Thu, 3 Jun 2004 21:50:37 +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 i53JobFM094293 for freebsd-current@freebsd.org; Thu, 3 Jun 2004 21:50:37 +0200 (CEST) (envelope-from mailnull) From: naddy@mips.inka.de (Christian Weisgerber) Date: Thu, 3 Jun 2004 19:50:36 +0000 (UTC) Message-ID: Originator: naddy@mips.inka.de (Christian Weisgerber) To: freebsd-current@freebsd.org Subject: xe(4) multicast filter fix 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: Thu, 03 Jun 2004 19:50:40 -0000 Our xe(4) multicast hash filter setup is particularly convoluted. First a big-endian ethernet CRC is calculated, then the top six bits are taken and reversed--i.e., we really just want the six lower bits of a little-endian CRC. On top of that, a drunken commit in revision 1.45 of if_xe.c broke the CRC calculation. The patch below cuts through the whole mess by calling ether_crc32_le() directly. PLEASE TEST. I don't have access to xe(4) hardware. Index: dev/xe/if_xe.c =================================================================== RCS file: /home/ncvs/src/sys/dev/xe/if_xe.c,v retrieving revision 1.50 diff -u -r1.50 if_xe.c --- dev/xe/if_xe.c 23 May 2004 16:11:53 -0000 1.50 +++ dev/xe/if_xe.c 3 Jun 2004 19:33:12 -0000 @@ -143,11 +143,6 @@ #define XE_AUTONEG_FAIL 4 /* Autonegotiation failed */ /* - * Multicast hashing CRC constants - */ -#define XE_CRC_POLY 0x04c11db6 - -/* * Prototypes start here */ static void xe_init (void *xscp); @@ -1409,49 +1404,19 @@ */ static void xe_mchash(struct xe_softc* scp, const uint8_t *addr) { - uint32_t crc = 0xffffffff; - int idx, bit; - uint8_t carry, byte, data, crc31, hash; - - /* Compute CRC of the address -- standard Ethernet CRC function */ - for (data = *addr++, idx = 0; idx < 6; idx++, data >>= 1) { - for (bit = 1; bit <= 8; bit++) { - if (crc & 0x80000000) - crc31 = 0x01; - else - crc31 = 0; - carry = crc31 ^ (data & 0x01); - crc <<= 1; - data >>= 1; - crc = (crc ^ XE_CRC_POLY) | (carry|0x1); - } - } + int bit; + uint8_t byte, hash; - DEVPRINTF(3, (scp->dev, "set_hash: CRC = 0x%08x\n", crc)); - - /* - * Convert a CRC into an index into the multicast hash table. What we do is - * take the most-significant 6 bits of the CRC, reverse them, and use that as - * the bit number in the hash table. Bits 5:3 of the result give the byte - * within the table (0-7); bits 2:0 give the bit number within that byte (also - * 0-7), ie. the number of shifts needed to get it into the lsb position. - */ - for (idx = 0, hash = 0; idx < 6; idx++) { - hash >>= 1; - if (crc & 0x80000000) { - hash |= 0x20; - } - crc <<= 1; - } + hash = ether_crc32_le(addr, ETHER_ADDR_LEN) & 0x3F; /* Top 3 bits of hash give register - 8, bottom 3 give bit within register */ byte = hash >> 3 | 0x08; - carry = 0x01 << (hash & 0x07); + bit = 0x01 << (hash & 0x07); - DEVPRINTF(3, (scp->dev, "set_hash: hash = 0x%02x, byte = 0x%02x, carry = 0x%02x\n", hash, byte, carry)); + DEVPRINTF(3, (scp->dev, "set_hash: hash = 0x%02x, byte = 0x%02x, bit = 0x%02x\n", hash, byte, bit)); XE_SELECT_PAGE(0x58); - XE_OUTB(byte, XE_INB(byte) | carry); + XE_OUTB(byte, XE_INB(byte) | bit); } -- Christian "naddy" Weisgerber naddy@mips.inka.de