From owner-freebsd-net@FreeBSD.ORG Tue Jan 13 08:05:37 2004 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DA8C316A4CE for ; Tue, 13 Jan 2004 08:05:37 -0800 (PST) Received: from anuket.mj.niksun.com (gwnew.niksun.com [65.115.46.162]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7C5A243D49 for ; Tue, 13 Jan 2004 08:04:44 -0800 (PST) (envelope-from jkim@niksun.com) Received: from daemon.mj.niksun.com (daemon.mj.niksun.com [10.70.0.244]) by anuket.mj.niksun.com (8.12.6p2/8.12.3) with ESMTP id i0DG3puv037315 for ; Tue, 13 Jan 2004 11:03:51 -0500 (EST) (envelope-from jkim@niksun.com) X-RAV-AntiVirus: This e-mail has been scanned for viruses. From: Jung-uk Kim Organization: Niksun, Inc. To: freebsd-net@freebsd.org Date: Tue, 13 Jan 2004 11:03:49 -0500 User-Agent: KMail/1.5.4 References: <200401131102.41278.jkim@niksun.com> In-Reply-To: <200401131102.41278.jkim@niksun.com> MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_lbBBAdr0ahSZGbv" Message-Id: <200401131103.49767.jkim@niksun.com> Subject: Re: Revised patch for sk driver X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Jan 2004 16:05:38 -0000 --Boundary-00=_lbBBAdr0ahSZGbv Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline On Tuesday 13 January 2004 11:02 am, Jung-uk Kim wrote: > I updated my patch for the lastest src/sys/pci/if_sk.c (Rev. 1.73), > which was originally posted here: > > http://docs.freebsd.org/cgi/mid.cgi?20031215231022.GA15082 > > This also includes Keith Mitchell's patch (with some clean-ups): > > http://docs.freebsd.org/cgi/mid.cgi?20031217145924.GA12258 > > This patch supposedly fixes problems with promiscuous mode, > multicast, and rtsol. My bad. Attachment was missing. Sorry. Jung-uk Kim --Boundary-00=_lbBBAdr0ahSZGbv Content-Type: text/plain; charset="iso-8859-1"; name="sk-20040113.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="sk-20040113.diff" --- src/sys/pci/if_sk.c.orig Sun Dec 14 01:48:11 2003 +++ src/sys/pci/if_sk.c Tue Jan 13 00:40:40 2004 @@ -224,9 +224,11 @@ int); static void sk_marv_miibus_statchg (struct sk_if_softc *); -static uint32_t sk_mchash (const uint8_t *); +static uint32_t sk_xmchash (const uint8_t *); +static uint32_t sk_gmchash (const uint8_t *); static void sk_setfilt (struct sk_if_softc *, caddr_t, int); static void sk_setmulti (struct sk_if_softc *); +static void sk_setpromisc (struct sk_if_softc *); #ifdef SK_USEIOSPACE #define SK_RES SYS_RES_IOPORT @@ -709,11 +711,12 @@ return; } -#define SK_POLY 0xEDB88320 -#define SK_BITS 6 +#define XMAC_POLY 0xEDB88320 +#define GMAC_POLY 0x04C11DB7L +#define HASH_BITS 6 static u_int32_t -sk_mchash(addr) +sk_xmchash(addr) const uint8_t *addr; { uint32_t crc; @@ -725,10 +728,48 @@ for (idx = 0; idx < 6; idx++) { for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) - crc = (crc >> 1) ^ (((crc ^ data) & 1) ? SK_POLY : 0); + crc = (crc >> 1) ^ (((crc ^ data) & 1) ? XMAC_POLY : 0); } - return (~crc & ((1 << SK_BITS) - 1)); + return (~crc & ((1 << HASH_BITS) - 1)); +} + +static u_int32_t +sk_gmchash(addr) + const uint8_t *addr; +{ + u_int32_t crc; + uint idx, bit; + uint8_t tmpData, data; + + /* Compute CRC for the address value. */ + crc = 0xFFFFFFFF; /* initial value */ + + for (idx = 0; idx < 6; idx++) { + data = *addr++; + + /* Change bit order in byte. */ + tmpData = data; + for (bit = 0; bit < 8; bit++) { + if (tmpData & 1) { + data |= 1 << (7 - bit); + } else { + data &= ~(1 << (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)); } static void @@ -755,7 +796,7 @@ struct sk_softc *sc = sc_if->sk_softc; struct ifnet *ifp = &sc_if->arpcom.ac_if; u_int32_t hashes[2] = { 0, 0 }; - int h, i; + int h = 0, i; struct ifmultiaddr *ifma; u_int8_t dummy[] = { 0, 0, 0, 0, 0 ,0 }; @@ -798,8 +839,16 @@ continue; } - h = sk_mchash( - LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); + switch(sc->sk_type) { + case SK_GENESIS: + h = sk_xmchash( + LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); + break; + case SK_YUKON: + h = sk_gmchash( + LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); + break; + } if (h < 32) hashes[0] |= (1 << h); else @@ -825,6 +874,35 @@ return; } +static void +sk_setpromisc(sc_if) + struct sk_if_softc *sc_if; +{ + struct sk_softc *sc = sc_if->sk_softc; + struct ifnet *ifp = &sc_if->arpcom.ac_if; + + switch(sc->sk_type) { + case SK_GENESIS: + if (ifp->if_flags & IFF_PROMISC) { + SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC); + } else { + SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC); + } + break; + case SK_YUKON: + if (ifp->if_flags & IFF_PROMISC) { + SK_YU_CLRBIT_2(sc_if, YUKON_RCR, + YU_RCR_UFLEN | YU_RCR_MUFLEN); + } else { + SK_YU_SETBIT_2(sc_if, YUKON_RCR, + YU_RCR_UFLEN | YU_RCR_MUFLEN); + } + break; + } + + return; +} + static int sk_init_rx_ring(sc_if) struct sk_if_softc *sc_if; @@ -1107,7 +1185,6 @@ caddr_t data; { struct sk_if_softc *sc_if = ifp->if_softc; - struct sk_softc *sc = sc_if->sk_softc; struct ifreq *ifr = (struct ifreq *) data; int error = 0; struct mii_data *mii; @@ -1125,34 +1202,12 @@ break; case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - if (ifp->if_flags & IFF_RUNNING && - ifp->if_flags & IFF_PROMISC && - !(sc_if->sk_if_flags & IFF_PROMISC)) { - switch(sc->sk_type) { - case SK_GENESIS: - SK_XM_SETBIT_4(sc_if, XM_MODE, - XM_MODE_RX_PROMISC); - break; - case SK_YUKON: - SK_YU_CLRBIT_2(sc_if, YUKON_RCR, - YU_RCR_UFLEN | YU_RCR_MUFLEN); - break; - } - sk_setmulti(sc_if); - } else if (ifp->if_flags & IFF_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - sc_if->sk_if_flags & IFF_PROMISC) { - switch(sc->sk_type) { - case SK_GENESIS: - SK_XM_CLRBIT_4(sc_if, XM_MODE, - XM_MODE_RX_PROMISC); - break; - case SK_YUKON: - SK_YU_SETBIT_2(sc_if, YUKON_RCR, - YU_RCR_UFLEN | YU_RCR_MUFLEN); - break; + if (ifp->if_flags & IFF_RUNNING) { + if ((ifp->if_flags ^ sc_if->sk_if_flags) + & IFF_PROMISC) { + sk_setpromisc(sc_if); + sk_setmulti(sc_if); } - sk_setmulti(sc_if); } else sk_init(sc_if); } else { @@ -2258,12 +2313,6 @@ *(u_int16_t *)(&sc_if->arpcom.ac_enaddr[4])); SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_USE_STATION); - if (ifp->if_flags & IFF_PROMISC) { - SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC); - } else { - SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC); - } - if (ifp->if_flags & IFF_BROADCAST) { SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_NOBROAD); } else { @@ -2305,6 +2354,9 @@ */ SK_XM_WRITE_2(sc_if, XM_TX_REQTHRESH, SK_XM_TX_FIFOTHRESH); + /* Set promiscuous mode */ + sk_setpromisc(sc_if); + /* Set multicast filter */ sk_setmulti(sc_if); @@ -2400,8 +2452,7 @@ SK_YU_WRITE_2(sc_if, YUKON_PAR, reg); /* receive control reg */ - SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_UFLEN | YU_RCR_MUFLEN | - YU_RCR_CRCR); + SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_CRCR); /* transmit parameter register */ SK_YU_WRITE_2(sc_if, YUKON_TPR, YU_TPR_JAM_LEN(0x3) | @@ -2425,11 +2476,11 @@ SK_YU_WRITE_2(sc_if, YUKON_SAL2 + i * 4, reg); } - /* clear all Multicast filter hash registers */ - SK_YU_WRITE_2(sc_if, YUKON_MCAH1, 0); - SK_YU_WRITE_2(sc_if, YUKON_MCAH2, 0); - SK_YU_WRITE_2(sc_if, YUKON_MCAH3, 0); - SK_YU_WRITE_2(sc_if, YUKON_MCAH4, 0); + /* Set promiscuous mode */ + sk_setpromisc(sc_if); + + /* Set multicast filter */ + sk_setmulti(sc_if); /* enable interrupt mask for counter overflows */ SK_YU_WRITE_2(sc_if, YUKON_TIMR, 0); --Boundary-00=_lbBBAdr0ahSZGbv--